From adff24f54e0939a6e1dc284f0e507b509177daa0 Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Wed, 2 Jan 2019 15:49:47 +0100 Subject: [PATCH] GH-1431,GH-1524,GH-1381 Documentation updates Documented new Test Binder capabilities Created initila version of migration guide Added StreamRetryTemplate to migration guide Updates doc with 2.1 updates Resolves #1431 Resolves #1524 Resolves #1381 --- README.adoc | 133 +++++------------- docs/src/main/asciidoc/preface.adoc | 129 +++++------------ .../main/asciidoc/spring-cloud-stream.adoc | 110 +++++++++++++++ 3 files changed, 178 insertions(+), 194 deletions(-) diff --git a/README.adoc b/README.adoc index c8991dbd6..f72efaa07 100644 --- a/README.adoc +++ b/README.adoc @@ -167,8 +167,12 @@ You can also build and package your application into a boot jar (by using `./mvn Now you have a working (albeit very basic) Spring Cloud Stream application. -== What's New in 2.0? -Spring Cloud Stream introduces a number of new features, enhancements, and changes. The following sections outline the most notable ones: +== What's New in 2.1? +Spring Cloud Stream introduces a number of new features, enhancements, and changes in addition to the once already introduced in +https://docs.spring.io/spring-cloud-stream/docs/Elmhurst.SR2/reference/htmlsingle/#_what_s_new_in_2_0[version 2.0] + + +The following sections outline the most notable ones: * <> * <> @@ -176,113 +180,46 @@ Spring Cloud Stream introduces a number of new features, enhancements, and chang [[spring-cloud-stream-preface-new-features]] === New Features and Components -* *Polling Consumers*: Introduction of polled consumers, which lets the application control message processing rates. -See "`<>`" for more details. -You can also read https://spring.io/blog/2018/02/27/spring-cloud-stream-2-0-polled-consumers[this blog post] for more details. +* *Spring Cloud Function*: One of the core themes of the 2.1.x release is the introduction of programming model based on https://cloud.spring.io/spring-cloud-function/[Spring Cloud Function] project. +For more details you can jump right into the <>. +You can also read https://spring.io/blog/2018/10/30/spring-cloud-stream-fishtown-rc1-2-1-0-rc1-release-announcement[this blog post] for more details. -* *Micrometer Support*: Metrics has been switched to use https://micrometer.io/[Micrometer]. -`MeterRegistry` is also provided as a bean so that custom applications can autowire it to capture custom metrics. -See "`<>`" for more details. - -* *New Actuator Binding Controls*: New actuator binding controls let you both visualize and control the Bindings lifecycle. -For more details, see <>. - -* *Configurable RetryTemplate*: Aside from providing properties to configure `RetryTemplate`, we now let you provide your own template, effectively overriding the one provided by the framework. -To use it, configure it as a `@Bean` in your application. +* *Simplified Test Binder*: In addition to an already existing testing support via `spring-cloud-stream-test-support`, this release also introduces a simpler implementation of a test binder that is +more aligned with the current binder API providing for a better integration testing as it is touches on all aspects of binding API. +This binder was primarily designed for internal use, but found its usages outside. For more information on how to use it and how it can help you please refer to <> of user guide. [[spring-cloud-stream-preface-notable-enhancements]] === Notable Enhancements -This version includes the following notable enhancements: +* *Improved Reactive Support*: Given that https://projectreactor.io/[Project Reactor] primitives such as `Flux` and `Mono` are at the core +of https://cloud.spring.io/spring-cloud-function/[Spring Cloud Function] project, you no longer +have to use or draw any distinction between _reactive_ and _conventional_ stream handler design, +hence you no longer need to explicitly rely on `spring-cloud-stream-reactive` module, which we're now +considering for deprecation. For more details please refer to <> section of this user guide. -* <> -* <> -* <> +* *Enhanced properties binding support*: This version of Spring Cloud Stream introduces significant +enhancements to configuration properties bindings primarily to ensure consistency between the default and binding specific properties. +A particular emphasis was given to maintaining the _precedence_ and _inheritance_ aspects where: + - _precedence_ - binding specific properties always take precedence over the default properties, effectively allowing binding specific properties to override the default ones + - _inheritance_ - default will propagate to individual binding properties unless explicitly overriden by the binding specific properties -[[spring-cloud-stream-preface-actuator-web-dependencies]] -==== Both Actuator and Web Dependencies Are Now Optional - -This change slims down the footprint of the deployed application in the event neither actuator nor web dependencies required. -It also lets you switch between the reactive and conventional web paradigms by manually adding one of the following dependencies. - -The following listing shows how to add the conventional web framework: -[source,xml] ----- - - org.springframework.boot - spring-boot-starter-web - ----- - -The following listing shows how to add the reactive web framework: - -[source,xml] ----- - - org.springframework.boot - spring-boot-starter-webflux - ----- - -The following list shows how to add the actuator dependency: -[source,xml] ----- - - org.springframework.boot - spring-boot-starter-actuator - ----- - -[[spring-cloud-stream-preface-content-type-negotiation-improvements]] -==== Content-type Negotiation Improvements - -One of the core themes for verion 2.0 is improvements (in both consistency and performance) around content-type negotiation and message conversion. -The following summary outlines the notable changes and improvements in this area. -See the "`<>`" section for more details. -Also https://spring.io/blog/2018/02/26/spring-cloud-stream-2-0-content-type-negotiation-and-transformation[this blog post] contains more detail. - -* All message conversion is now handled *only* by `MessageConverter` objects. -* We introduced the `@StreamMessageConverter` annotation to provide custom `MessageConverter` objects. -* We introduced the default `Content Type` as `application/json`, which needs to be taken into consideration when migrating 1.3 application or operating in the mixed mode (that is, 1.3 producer -> 2.0 consumer). -* Messages with textual payloads and a `contentType` of `text/...` or `.../json` are no longer converted to `Message` for cases where the argument type of the provided `MessageHandler` can not be determined (that is, `public void handle(Message message)` or `public void handle(Object payload)`). -Furthermore, a strong argument type may not be enough to properly convert messages, so the `contentType` header may be used as a supplement by some `MessageConverters`. +* *Additional Content-Type Negotiation Improvements*: One of the core themes for 2.0.x release was an improved content-type negotiation. +This release introduces few more significant enhancements to introduce more consistency. One such enhancement is +the delegation of type conversion to MessageConverters in _all_ cases, including the ones where the target type of the handler method is not known. +To you (the end user) it simply means that starting with this release extending content-type negotiation via `@StreamMessageConverter` is available for all type conversion cases. +NOTE: Keep in mind that most of the content-type work at the moment also preserves compatibility with 1.3.x version of Spring Cloud Stream, thus will be further simplified once 1.3.x line goes EOL. [[spring-cloud-stream-preface-notable-deprecations]] === Notable Deprecations -As of version 2.0, the following items have been deprecated: +As of version 2.1, the following items have been deprecated: -* <> -* <> +- Aggregator Builder support is deprecated in favor of application composition via <> programming model. +- As mentioned earlier we're also considering the deprecation of `spring-cloud-stream-reactive` module in favor of the adequate support already provided by <>. -[[spring-cloud-stream-preface-deprecation-java-serialization]] -==== Java Serialization (Java Native and Kryo) - -`JavaSerializationMessageConverter` and `KryoMessageConverter` remain for now. However, we plan to move them out of the core packages and support in the future. -The main reason for this deprecation is to flag the issue that type-based, language-specific serialization could cause in distributed environments, where Producers and Consumers may depend on different JVM versions or have different versions of supporting libraries (that is, Kryo). -We also wanted to draw the attention to the fact that Consumers and Producers may not even be Java-based, so polyglot style serialization (i.e., JSON) is better suited. - -[[spring-cloud-stream-preface-deprecation-classes-methods]] -==== Deprecated Classes and Methods -The following is a quick summary of notable deprecations. See the corresponding {spring-cloud-stream-javadoc-current}[javadoc] for more details. - -* `SharedChannelRegistry`. Use `SharedBindingTargetRegistry`. -* `Bindings`. -Beans qualified by it are already uniquely identified by their type -- for example, provided `Source`, `Processor`, or custom bindings: -[source,java] ----- -public interface Sample { - String OUTPUT = "sampleOutput"; - - @Output(Sample.OUTPUT) - MessageChannel output(); -} ----- -* `HeaderMode.raw`. Use `none`, `headers` or `embeddedHeaders` -* `ProducerProperties.partitionKeyExtractorClass` in favor of `partitionKeyExtractorName` and `ProducerProperties.partitionSelectorClass` in favor of `partitionSelectorName`. -This change ensures that both components are Spring configured and managed and are referenced in a Spring-friendly way. -* `BinderAwareRouterBeanPostProcessor`. While the component remains, it is no longer a `BeanPostProcessor` and will be renamed in the future. -* `BinderProperties.setEnvironment(Properties environment)`. Use `BinderProperties.setEnvironment(Map environment)`. +== Notes on migrating from 1.x to 2.x? +- Due to the improvements in content-type negotiation, the `originalContentType` header is not used (ignored) since 2.x and only exists for maintaining compatibility with 1.x versions +- Introduction of `@StreamRetryTemplate` qualifier. While configuring custom instance of the `RetryTemplate` and to avoid conflicts you must qualify the instance of such `RetryTemplate` with this qualifier. See <> for more details. = Appendices [appendix] @@ -392,7 +329,7 @@ added after the original pull request but before a merge. * Use the Spring Framework code format conventions. If you use Eclipse you can import formatter settings using the `eclipse-code-formatter.xml` file from the - https://github.com/spring-cloud/spring-cloud-build/blob/master/spring-cloud-dependencies-parent/eclipse-code-formatter.xml[Spring + https://github.com/spring-cloud/build/tree/master/eclipse-coding-conventions.xml[Spring Cloud Build] project. If using IntelliJ, you can use the http://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter Plugin] to import the same file. @@ -411,4 +348,4 @@ added after the original pull request but before a merge. if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit message (where XXXX is the issue number). -// ====================================================================================== +// ====================================================================================== \ No newline at end of file diff --git a/docs/src/main/asciidoc/preface.adoc b/docs/src/main/asciidoc/preface.adoc index d307cbf35..4a3b22d8b 100644 --- a/docs/src/main/asciidoc/preface.adoc +++ b/docs/src/main/asciidoc/preface.adoc @@ -151,8 +151,12 @@ You can also build and package your application into a boot jar (by using `./mvn Now you have a working (albeit very basic) Spring Cloud Stream application. -== What's New in 2.0? -Spring Cloud Stream introduces a number of new features, enhancements, and changes. The following sections outline the most notable ones: +== What's New in 2.1? +Spring Cloud Stream introduces a number of new features, enhancements, and changes in addition to the once already introduced in +https://docs.spring.io/spring-cloud-stream/docs/Elmhurst.SR2/reference/htmlsingle/#_what_s_new_in_2_0[version 2.0] + + +The following sections outline the most notable ones: * <> * <> @@ -160,110 +164,43 @@ Spring Cloud Stream introduces a number of new features, enhancements, and chang [[spring-cloud-stream-preface-new-features]] === New Features and Components -* *Polling Consumers*: Introduction of polled consumers, which lets the application control message processing rates. -See "`<>`" for more details. -You can also read https://spring.io/blog/2018/02/27/spring-cloud-stream-2-0-polled-consumers[this blog post] for more details. +* *Spring Cloud Function*: One of the core themes of the 2.1.x release is the introduction of programming model based on https://cloud.spring.io/spring-cloud-function/[Spring Cloud Function] project. +For more details you can jump right into the <>. +You can also read https://spring.io/blog/2018/10/30/spring-cloud-stream-fishtown-rc1-2-1-0-rc1-release-announcement[this blog post] for more details. -* *Micrometer Support*: Metrics has been switched to use https://micrometer.io/[Micrometer]. -`MeterRegistry` is also provided as a bean so that custom applications can autowire it to capture custom metrics. -See "`<>`" for more details. - -* *New Actuator Binding Controls*: New actuator binding controls let you both visualize and control the Bindings lifecycle. -For more details, see <>. - -* *Configurable RetryTemplate*: Aside from providing properties to configure `RetryTemplate`, we now let you provide your own template, effectively overriding the one provided by the framework. -To use it, configure it as a `@Bean` in your application. +* *Simplified Test Binder*: In addition to an already existing testing support via `spring-cloud-stream-test-support`, this release also introduces a simpler implementation of a test binder that is +more aligned with the current binder API providing for a better integration testing as it is touches on all aspects of binding API. +This binder was primarily designed for internal use, but found its usages outside. For more information on how to use it and how it can help you please refer to <> of user guide. [[spring-cloud-stream-preface-notable-enhancements]] === Notable Enhancements -This version includes the following notable enhancements: +* *Improved Reactive Support*: Given that https://projectreactor.io/[Project Reactor] primitives such as `Flux` and `Mono` are at the core +of https://cloud.spring.io/spring-cloud-function/[Spring Cloud Function] project, you no longer +have to use or draw any distinction between _reactive_ and _conventional_ stream handler design, +hence you no longer need to explicitly rely on `spring-cloud-stream-reactive` module, which we're now +considering for deprecation. For more details please refer to <> section of this user guide. -* <> -* <> -* <> +* *Enhanced properties binding support*: This version of Spring Cloud Stream introduces significant +enhancements to configuration properties bindings primarily to ensure consistency between the default and binding specific properties. +A particular emphasis was given to maintaining the _precedence_ and _inheritance_ aspects where: + - _precedence_ - binding specific properties always take precedence over the default properties, effectively allowing binding specific properties to override the default ones + - _inheritance_ - default will propagate to individual binding properties unless explicitly overriden by the binding specific properties -[[spring-cloud-stream-preface-actuator-web-dependencies]] -==== Both Actuator and Web Dependencies Are Now Optional - -This change slims down the footprint of the deployed application in the event neither actuator nor web dependencies required. -It also lets you switch between the reactive and conventional web paradigms by manually adding one of the following dependencies. - -The following listing shows how to add the conventional web framework: -[source,xml] ----- - - org.springframework.boot - spring-boot-starter-web - ----- - -The following listing shows how to add the reactive web framework: - -[source,xml] ----- - - org.springframework.boot - spring-boot-starter-webflux - ----- - -The following list shows how to add the actuator dependency: -[source,xml] ----- - - org.springframework.boot - spring-boot-starter-actuator - ----- - -[[spring-cloud-stream-preface-content-type-negotiation-improvements]] -==== Content-type Negotiation Improvements - -One of the core themes for verion 2.0 is improvements (in both consistency and performance) around content-type negotiation and message conversion. -The following summary outlines the notable changes and improvements in this area. -See the "`<>`" section for more details. -Also https://spring.io/blog/2018/02/26/spring-cloud-stream-2-0-content-type-negotiation-and-transformation[this blog post] contains more detail. - -* All message conversion is now handled *only* by `MessageConverter` objects. -* We introduced the `@StreamMessageConverter` annotation to provide custom `MessageConverter` objects. -* We introduced the default `Content Type` as `application/json`, which needs to be taken into consideration when migrating 1.3 application or operating in the mixed mode (that is, 1.3 producer -> 2.0 consumer). -* Messages with textual payloads and a `contentType` of `text/...` or `.../json` are no longer converted to `Message` for cases where the argument type of the provided `MessageHandler` can not be determined (that is, `public void handle(Message message)` or `public void handle(Object payload)`). -Furthermore, a strong argument type may not be enough to properly convert messages, so the `contentType` header may be used as a supplement by some `MessageConverters`. +* *Additional Content-Type Negotiation Improvements*: One of the core themes for 2.0.x release was an improved content-type negotiation. +This release introduces few more significant enhancements to introduce more consistency. One such enhancement is +the delegation of type conversion to MessageConverters in _all_ cases, including the ones where the target type of the handler method is not known. +To you (the end user) it simply means that starting with this release extending content-type negotiation via `@StreamMessageConverter` is available for all type conversion cases. +NOTE: Keep in mind that most of the content-type work at the moment also preserves compatibility with 1.3.x version of Spring Cloud Stream, thus will be further simplified once 1.3.x line goes EOL. [[spring-cloud-stream-preface-notable-deprecations]] === Notable Deprecations -As of version 2.0, the following items have been deprecated: +As of version 2.1, the following items have been deprecated: -* <> -* <> +- Aggregator Builder support is deprecated in favor of application composition via <> programming model. +- As mentioned earlier we're also considering the deprecation of `spring-cloud-stream-reactive` module in favor of the adequate support already provided by <>. -[[spring-cloud-stream-preface-deprecation-java-serialization]] -==== Java Serialization (Java Native and Kryo) - -`JavaSerializationMessageConverter` and `KryoMessageConverter` remain for now. However, we plan to move them out of the core packages and support in the future. -The main reason for this deprecation is to flag the issue that type-based, language-specific serialization could cause in distributed environments, where Producers and Consumers may depend on different JVM versions or have different versions of supporting libraries (that is, Kryo). -We also wanted to draw the attention to the fact that Consumers and Producers may not even be Java-based, so polyglot style serialization (i.e., JSON) is better suited. - -[[spring-cloud-stream-preface-deprecation-classes-methods]] -==== Deprecated Classes and Methods -The following is a quick summary of notable deprecations. See the corresponding {spring-cloud-stream-javadoc-current}[javadoc] for more details. - -* `SharedChannelRegistry`. Use `SharedBindingTargetRegistry`. -* `Bindings`. -Beans qualified by it are already uniquely identified by their type -- for example, provided `Source`, `Processor`, or custom bindings: -[source,java] ----- -public interface Sample { - String OUTPUT = "sampleOutput"; - - @Output(Sample.OUTPUT) - MessageChannel output(); -} ----- -* `HeaderMode.raw`. Use `none`, `headers` or `embeddedHeaders` -* `ProducerProperties.partitionKeyExtractorClass` in favor of `partitionKeyExtractorName` and `ProducerProperties.partitionSelectorClass` in favor of `partitionSelectorName`. -This change ensures that both components are Spring configured and managed and are referenced in a Spring-friendly way. -* `BinderAwareRouterBeanPostProcessor`. While the component remains, it is no longer a `BeanPostProcessor` and will be renamed in the future. -* `BinderProperties.setEnvironment(Properties environment)`. Use `BinderProperties.setEnvironment(Map environment)`. +== Notes on migrating from 1.x to 2.x? +- Due to the improvements in content-type negotiation, the `originalContentType` header is not used (ignored) since 2.x and only exists for maintaining compatibility with 1.x versions +- Introduction of `@StreamRetryTemplate` qualifier. While configuring custom instance of the `RetryTemplate` and to avoid conflicts you must qualify the instance of such `RetryTemplate` with this qualifier. See <> for more details. \ No newline at end of file diff --git a/docs/src/main/asciidoc/spring-cloud-stream.adoc b/docs/src/main/asciidoc/spring-cloud-stream.adoc index b26b628ef..f585780c7 100644 --- a/docs/src/main/asciidoc/spring-cloud-stream.adoc +++ b/docs/src/main/asciidoc/spring-cloud-stream.adoc @@ -2461,6 +2461,116 @@ The bound interface is injected into the test so that we can have access to both We send a message on the input channel, and we use the `MessageCollector` provided by Spring Cloud Stream's test support to capture that the message has been sent to the output channel as a result. Once we have received the message, we can validate that the component functions correctly. +[[spring_integration_test_binder]] +=== Spring Integration test binder +Current test binder was specifically designed to facilitate _unit testing_ and thus bypasses some of the core functionality of the binder API and strictly concentrates on validating user code. +While such light-weight approach is sufficient for most cases, it usually requires additional _integration testing_ with real binders (e.g., Rabbit, Kafka etc). + +To begin bridging the gap between _unit_ and _integration_ testing we've developed a new test binder which uses https://spring.io/projects/spring-integration[Spring Integration] framework +as an in-JVM Message Broker essentially giving you the best of both worlds - a real binder without the networking. + +Also, this binder is implemented as part of the +`spring-cloud-stream` module, however it does require some additional Maven/Gradle entries before you can use it. So let's take a look. + +To enable Spring Integration Test Binder you must + +- Add required dependencies +- Remove the dependency for `spring-cloud-stream-test-support` + +***Add required dependencies*** + +Below is the example of the required Maven POM entries which could be easily retrofitted into Gradle. + +[source,xml] +---- + + org.springframework.cloud + spring-cloud-stream + ${spring.cloud.strea.version} + test-jar + test + test-binder + +. . . + + + org.apache.maven.plugins + maven-jar-plugin + + + + + **/integration/* + + test-binder + + + test-jar + + + + + +---- + +***Remove the dependency for `spring-cloud-stream-test-support`*** + +To avoid conflicts with the existing test binder you must eremove the following entry + +[source,xml] +---- + + org.springframework.cloud + spring-cloud-stream-test-support + test + +---- + +Now you can test your microservice as a simple unit test + + +[source,java] +---- +@SpringBootApplication +@EnableBinding(Processor.class) +public class DemoTestBinderApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoTestBinderApplication.class, args); + } + + @StreamListener(Processor.INPUT) + @SendTo(Processor.OUTPUT) + public String echo(String value) { + return value; + } +} + +. . . + +@Test +public void sampleTest() { + ApplicationContext context = new SpringApplicationBuilder( + TestChannelBinderConfiguration.class, + DemoTestBinderApplication.class) + .web(WebApplicationType.NONE).run(); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + source.send(new GenericMessage("hello".getBytes())); + System.out.println("Result: " + new String(target.receive().getPayload())); +} +---- + +In the above you simply create an ApplicationContext with yoru configuration (your application) while additionally supplying `TestChannelBinderConfiguration` +provided by the framework. Then you access `InputDestination` and `OutputDestination` beans to send/receive messages. In the context of this binder +`InputDestination` and `OutputDestination` emulate remote destinations such as Rabbit _exchange/queue_ or Kafka _topic_. + +In the future we plan to simplify the API. + +NOTE: In its current state Spring Integration Test Binder only supports the three bindings provided by the framework (Source, Processor, Sink) specifically to promote +light-weight microservices architectures rather then general purpose messaging applications. + + === Disabling the Test Binder Autoconfiguration The intent behind the test binder superseding all the other binders on the classpath is to make it easy to test your applications without making changes to your production dependencies.