Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ will go through the same routine when sending output as if it was from any Funct
of consistency as with functions. This means the output type conversion, partitioning etc are honored as if it was from the output produced by functions.

IMPORTANT: Unlike it is explained in xref:spring-cloud-stream/explicit-binding-creation.adoc[Explicit Binding Creation], _StreamBridge_ was designed with both performance in mind and ability to create as many bindings on the fly as necessary. To achieve that the actual bindings created by the _StreamBridge_ are not cached in the application context and therefore can not be managed as explained in xref:spring-cloud-stream/binding_visualization_control.adoc[Binding visualization and control].
However if it is still your desire to use _StreamBridge_ to create bindings dynamically and manage them after, please use the following mechanism to create binding explicitly before using _StreamBridge_ - ref:spring-cloud-stream/binding_visualization_control.adocl#_define_new_and_manage_existing_bindings[Define New Binding Programmatically]
However if it is still your desire to use _StreamBridge_ to create bindings dynamically and manage them after, please use the following mechanism to create binding explicitly before using _StreamBridge_ - xref:spring-cloud-stream/binding_visualization_control.adoc#_define_new_and_manage_existing_bindings[Define New Binding Programmatically]



Expand Down Expand Up @@ -383,7 +383,7 @@ the dynamic features of `StreamBridge` where if `myBinding` doesn't exist it wil
NOTE: Caching dynamic destinations (bindings) could result in memory leaks in the event there are many dynamic destinations. To have some level of control
we provide a self-evicting caching mechanism for output bindings with default cache size of 10. This means that if your dynamic destination size goes above that number, there is a possibility that an existing binding will be evicted and thus would need to be recreated which could cause minor performance degradation. You can increase the cache size via `spring.cloud.stream.dynamic-destination-cache-size` property setting it to the desired value.


[source,bash]
----
curl -H "Content-Type: text/plain" -X POST -d "hello from the other side" http://localhost:8080/
----
Expand All @@ -405,27 +405,27 @@ Spring Cloud Stream supports multiple binder scenarios. For example you may be r

For more information on multiple binders scenarios, please see xref:spring-cloud-stream/binders.adoc#binders[Binders] section and specifically xref:spring-cloud-stream/multiple-binders.adoc#multiple-binders[Multiple Binders on the Classpath]

In the event you are planning to use StreamBridge and have more then one binder configured in your application you must also tell StreamBridge
In the event you are planning to use StreamBridge and have more than one binder configured in your application you must also tell StreamBridge
which binder to use. And for that there are two more variations of `send` method:

[source, java]
----
public boolean send(String bindingName, @Nullable String binderType, Object data)
public boolean send(String bindingName, @Nullable String binderName, Object data);

public boolean send(String bindingName, @Nullable String binderType, Object data, MimeType outputContentType)
public boolean send(String bindingName, @Nullable String binderName, Object data, MimeType outputContentType);
----

As you can see there is one additional argument that you can provide - `binderType`, telling BindingService which binder to use when creating dynamic binding.
As you can see there is one additional argument that you can provide - `binderName`, telling BindingService which binder to use when creating dynamic binding.

NOTE: For cases where `spring.cloud.stream.output-bindings` property is used or the binding was already created under different binder, the `binderType`
NOTE: For cases where `spring.cloud.stream.output-bindings` property is used or the binding was already created under different binder, the `binderName`
argument will have no effect.

[[using-channel-interceptors-with-streambridge]]
==== Using channel interceptors with StreamBridge

Since `StreamBridge` uses a `MessageChannel` to establish the output binding, you can activate channel interceptors when sending data through `StreamBridge`.
It is up to the application to decide which channel interceptors to apply on `StreamBridge`.
Spring Cloud Stream does not inject all the channel interceptors detected into `StreamBridge` unless they are annoatated with `@GlobalChannelInterceptor(patterns = "*")`.
Spring Cloud Stream does not inject all the channel interceptors detected into `StreamBridge` unless they are annotated with `@GlobalChannelInterceptor(patterns = "*")`.

Let us assume that you have the following two different `StreamBridge` bindings in the application.

Expand All @@ -437,7 +437,8 @@ and

Now, if you want a channel interceptor applied on both the `StreamBridge` bindings, then you can declare the following `GlobalChannelInterceptor` bean.

```
[source,java]
----
@Bean
@GlobalChannelInterceptor(patterns = "*")
public ChannelInterceptor customInterceptor() {
Expand All @@ -448,11 +449,12 @@ public ChannelInterceptor customInterceptor() {
}
};
}
```
----

However, if you don't like the global approach above and want to have a dedicated interceptor for each binding, then you can do the following.

```
[source,java]
----
@Bean
@GlobalChannelInterceptor(patterns = "foo-*")
public ChannelInterceptor fooInterceptor() {
Expand All @@ -463,11 +465,12 @@ public ChannelInterceptor fooInterceptor() {
}
};
}
```
----

and

```
[source,java]
----
@Bean
@GlobalChannelInterceptor(patterns = "bar-*")
public ChannelInterceptor barInterceptor() {
Expand All @@ -478,7 +481,7 @@ public ChannelInterceptor barInterceptor() {
}
};
}
```
----

You have the flexibility to make the patterns more strict or customized to your business needs.

Expand Down Expand Up @@ -540,7 +543,7 @@ public Function<String, String> wrapInQuotes() {
and modify the `spring.cloud.function.definition` property to reflect your intention to compose a new function from both ‘toUpperCase’ and ‘wrapInQuotes’.
To do so Spring Cloud Function relies on `|` (pipe) symbol. So, to finish our example our property will now look like this:

[source,java]
[source,properties]
----
--spring.cloud.function.definition=toUpperCase|wrapInQuotes
----
Expand Down Expand Up @@ -668,6 +671,7 @@ output binding also follows the same convention and is named `gather-out-0`.
Knowing that will allow you to set binding specific properties.
For example, the following will override content-type for `gather-in-0` binding:

[source,properties]
----
--spring.cloud.stream.bindings.gather-in-0.content-type=text/plain
----
Expand All @@ -693,7 +697,7 @@ public class SampleApplication {
}
----

The above example is somewhat of a the opposite from the previous sample and demonstrates function which
The above example is somewhat of the opposite from the previous sample and demonstrates function which
takes single input of type `Integer` and produces two outputs (both of type `String`).

So, for the above example the input binding is `scatter-in-0` and the
Expand Down Expand Up @@ -751,12 +755,12 @@ public class SampleApplication {
----

In the above example we have configuration which defines two functions `uppercase` and `reverse`.
So first, as mentioned before, we need to notice that there is a a conflict (more then one function) and therefore
So first, as mentioned before, we need to notice that there is a conflict (more than one function) and therefore
we need to resolve it by providing `spring.cloud.function.definition` property pointing to the actual function
we want to bind. Except here we will use `;` delimiter to point to both functions (see test case below).


IMPORTANT: As with functions with multiple inputs/outputs, please refer to <<Binding and Binding names>> section to understand the naming
IMPORTANT: As with functions with multiple inputs/outputs, please refer to xref:spring-cloud-stream/binding-names.adoc[Binding and Binding names] section to understand the naming
convention used to establish _binding names_ used by such application.

And you test it with the following code:
Expand Down Expand Up @@ -878,7 +882,7 @@ of https://www.enterpriseintegrationpatterns.com[Enterprise Integration Patterns
framework such as https://spring.io/projects/spring-integration[Spring Integration] (SI), which is a reference implementation of EIP.

Thankfully SI already provides support for exposing integration flows as functions via
https://docs.spring.io/spring-integration/docs/current/reference/html/#java-dsl-gateway[Integration flow as gateway]
https://docs.spring.io/spring-integration/reference/dsl/integration-flow-as-gateway.html[Integration flow as gateway]
Consider the following sample:

[source, java]
Expand Down Expand Up @@ -914,7 +918,7 @@ To receive raw input you can use `from(Function.class, ...)`.

The resulting function is bound to the input and output destinations exposed by the target binder.

IMPORTANT: Please refer to <<Binding and Binding names>> section to understand the naming
IMPORTANT: Please refer to xref:spring-cloud-stream/binding-names.adoc[Binding and Binding names] section to understand the naming
convention used to establish _binding names_ used by such application.

For more details on interoperability of Spring Integration and Spring Cloud Stream specifically around functional programming model
Expand All @@ -933,7 +937,7 @@ To define binding for polled consumer you need to provide `spring.cloud.stream.p

Consider the following example of a polled consumer binding:

[source,text]
[source,properties]
----
--spring.cloud.stream.pollable-source=myDestination
----
Expand Down Expand Up @@ -1018,7 +1022,7 @@ There is also an overloaded `poll` method, for which the definition is as follow

[source,java]
----
poll(MessageHandler handler, ParameterizedTypeReference<?> type)
boolean poll(MessageHandler handler, ParameterizedTypeReference<?> type);
----

The `type` is a conversion hint that allows the incoming message payload to be converted, as shown in the following example:
Expand Down