From 7e8238be90138b35ba25db8eb4407d766a529a14 Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Thu, 8 Mar 2018 11:28:26 -0500 Subject: [PATCH] Doc restructuring - added preface section/part - moved Quick Start and What's New into preface --- .../src/main/asciidoc/index.adoc | 3 + .../src/main/asciidoc/preface.adoc | 197 ++++++++++++++++++ .../spring-cloud-stream-overview.adoc | 195 ----------------- 3 files changed, 200 insertions(+), 195 deletions(-) create mode 100644 spring-cloud-stream-core-docs/src/main/asciidoc/preface.adoc diff --git a/spring-cloud-stream-core-docs/src/main/asciidoc/index.adoc b/spring-cloud-stream-core-docs/src/main/asciidoc/index.adoc index 564353e00..b3ef2400f 100644 --- a/spring-cloud-stream-core-docs/src/main/asciidoc/index.adoc +++ b/spring-cloud-stream-core-docs/src/main/asciidoc/index.adoc @@ -21,6 +21,9 @@ Sabby Anandan; Marius Bogoevici; Eric Bottard; Mark Fisher; Ilayaperumal Gopinat :sc-ext: java // ====================================================================================== += Preface +include::preface.adoc[] + = Reference Guide include::spring-cloud-stream-overview.adoc[] diff --git a/spring-cloud-stream-core-docs/src/main/asciidoc/preface.adoc b/spring-cloud-stream-core-docs/src/main/asciidoc/preface.adoc new file mode 100644 index 000000000..278a75e59 --- /dev/null +++ b/spring-cloud-stream-core-docs/src/main/asciidoc/preface.adoc @@ -0,0 +1,197 @@ + + +== Quick Start + +You can try Spring Cloud Stream in less then 5 min even before you jump into any details and the following _three-step guide_ will help. + +We'll create a simple Spring Cloud Stream application which receives messages coming from the messaging middleware of your choice (more on this later) and +logs received messages to the console. We'll call it _LoggingConsumer_. While not very practical it will certainly provide a good introduction to some of the main concepts +and abstractions, making it easier to digest the rest of this user guide. + +So let's get started. . . + +==== Step One - Create sample Application using Spring Initilaizer +Visit the https://start.spring.io[Spring Initializr]. This is where we'll generate our _LoggingConsumer_ application. + +In the _Dependencies_ start typing 'stream' and _Cloud Stream_ option should pop up. Select it. Now start typing either 'kafka' or 'rabbit'. Basically this is where you are choosing +what messaging midleware this application will be bound to. Choose the one you have already installed and/or feel more comfortable with installing/running. +Also, as you can see from the Initilaizer screen there are few other options you can choose. For example, you can choose Gradle as your build tool instead of the default Maven. +With the _Dependencies_ selected the only other thing you have to identify is the application name - _logging-consumer_. +Your configuration screeen should now contain the following: + + Dependencies: Cloud Stream, RabbitMQ (or Kafka) + Group: com.example - default + Artifact: logging-consumer + Spring Boot Version: 2.0.0 (or above) - default + +Click on _Generate Project_ button. This will donwload the zipped version of the generated project to your hard drive. Unzip it and you're ready for Step Two. + +==== Step Two - Import project into the IDE +Here you simply import the project into your IDE of choice. +Please keep in mind that dependening on the IDE you may need to follow a specific import procedures. For example depending on how the project was generated (Maven or Gradle) +you may need to follow specific import procedure (e.g., in Eclipse/STS: `File -> Import -> Maven -> Existing Maven Project`). + +Ones imported the project must have no errors of any kind and `src/main/java` should also contain `com.example.loggingconsumer.LoggingConsumerApplication`. + +Technically at this point you can just run the application's main class since it's already a valid _Spring Boot_ application, but it does not do anything, so let's add some code. + +==== Step Three - Add message handler, build and run +Modify the `com.example.loggingconsumer.LoggingConsumerApplication` to look as follows: + +[source, java] +---- +@SpringBootApplication +@EnableBinding(Sink.class) +public class LoggingConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(LoggingConsumerApplication.class, args); + } + + @StreamListener(Sink.INPUT) + public void handle(Person person) { + System.out.println("Received: " + person); + } + + public static class Person { + private String name; + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String toString() { + return this.name; + } + } +} +---- + +As you can see from the above: + +* We've enabled `Sink` binding (input-no-output) via `@EnableBinding(Sink.class)`. This will signal to the framework to initiate binding to the messaging middleware where +it will auto-create the destination (i.e., queue, topic) which will be bound to `Sink.INPUT` channel. +* We've added handler method to receive incoming Message as type `Person`. What this means is that here youcan already observe one of the core features of the framework where +it will attempt to automatically convert incoming message's payload to type `Person`. + +This is it, we now have a fully functional Spring Cloud Stream application that does something. From here for simplicity we'll assume RabbitMQ was selected in _step one_. +Assuming you have RabbitMQ installed and running, start the application by simply running its `main` method. + +You should see following output: + + --- [ main] c.s.b.r.p.RabbitExchangeQueueProvisioner : declaring queue for inbound: input.anonymous.CbMIwdkJSBO1ZoPDOtHtCg, bound to: input + --- [ main] o.s.a.r.c.CachingConnectionFactory : Attempting to connect to: [localhost:5672] + --- [ main] o.s.a.r.c.CachingConnectionFactory : Created new connection: rabbitConnectionFactory#2a3a299:0/SimpleConnection@66c83fc8. . . + . . . + --- [ main] o.s.i.a.i.AmqpInboundChannelAdapter : started inbound.input.anonymous.CbMIwdkJSBO1ZoPDOtHtCg + . . . + --- [ main] c.e.l.LoggingConsumerApplication : Started LoggingConsumerApplication in 2.531 seconds (JVM running for 2.897) + +Go to RabbitMQ management console or any other RabbitMQ client and simply send message to `input.anonymous.CbMIwdkJSBO1ZoPDOtHtCg` +(NOTE: the `anonymous.CbMIwdkJSBO1ZoPDOtHtCg` part represents the group name and is generated and will be different in your environment. For something more +predictable you can use explicit group name via `spring.cloud.stream.bindings.input.group=hello`). + +The contents of the message should be JSON representation of `Person` class, so let's send this: + + {"name":"Turd Ferguson"} + +And in your console you should see: + + Received: Turd Ferguson + +You can also build/package your application into a boot jar (i.e., `./mvnw clean install`) and run the built JAR using `java -jar` command. + +That is all! + +== What's New in 2.0? +Spring Cloud Stream introduces quite a number of new features, enhancements and changes. The following sections outline most notable ones. + +=== New Features and Components + +==== Polling Consumer +Introduction of _polled consumers_, where the application can control message processing rates. Please refer to the appropriate section for more details. +You can also read this blog for more details https://spring.io/blog/2018/02/27/spring-cloud-stream-2-0-polled-consumers + +==== Micrometer support + +Metrics has been switched to use https://micrometer.io/[Micrometer]. `MeterRegistry` is also provided as a bean so custom application can autowire it to capture custom metrics. +Please refer to the appropriate section for more details + +==== New Actuator Binding controls +There are now new new Actuator binding controls to both visualize as well as control Bindings lifecycle. For more details please visit <> + +==== Configurable RetryTemplate +Aside from providing properties to configure `RetryTemplate` we now allow you to provide your own effectively overriding the one provided by the framework. Simply configure +it as a `@Bean` in your application. + +=== Notable changes and enhancements + +==== Both Actuator and Web dependencies are now optional + +This helps to slim down the footprint of the deployed application in the event neither of the functionality is required. +It also allows one to swicth between the reactive and conventional web paradigms by adding one of the following dependencies manually: +[source,xml] +---- + + org.springframework.boot + spring-boot-starter-web + +---- +or +[source,xml] +---- + + org.springframework.boot + spring-boot-starter-webflux + +---- + +Actuator dependency can be added as follows: +[source,xml] +---- + + org.springframework.boot + spring-boot-starter-actuator + +---- + +==== Content-type negotiation improvenents +One of the core themes for 2.0 is improvements (both consistency and performance) around content-type negotiation and message conversion. +The following summary outlines notable changes and improvements. Please refer to the appropriate section for more details as well as this blog +https://spring.io/blog/2018/02/26/spring-cloud-stream-2-0-content-type-negotiation-and-transformation. + +* All message conversion is now handled *only* by `MessageConverters`. +* Introduction of `@StreamMessageConverter` annotation to provide custom `MessageConverters`. +* Introduction of the default _Content Type_ as `application/json` which needs to be taken into consideration when migrating 1.3 +application and/or operating in the mixed mode (i.e., 1.3 producer -> 2.0 consumer). +* Messages with textual payloads and _contentType_ `text/...` or `.../json` are no longer converted to `Message` for cases where argument type of the provided `MessageHandler` +can not be determnied (i.e., `public void handle(Message message)` or `public void handle(Object payload)`). Further more, a strong argument type may not be enough +to properly convert messages, so `contentType` header is may be used as supplement by some `MessageConverters`. + +=== Notable Deprecations +==== Java serialization (Java native and Kryo) +* `JavaSerializationMessageConverter` and `KryoMessageConverter`. While these two converters remain for now, they will be moved out of the core packages and support in the future. +The main reason for this deprecation is to signal the issue _type-based language-specific_ serialization couuld cause in the distributed environments, where Producers and Consumers +may not only depend on different JVM versions or have different versions of supporting libraries (i.e., Kryo), but to also draw the attention to the fact that Consumers and Producers +may and in a lot of cases are non-Java based. + +==== Deprecated classes and methods +Following is a quick summary of notable deprecations. See corresponding javadocs fort more details. + +* `SharedChannelRegistry` in favor of `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 Foo { + String OUTPUT = "fooOutput"; + + @Output(Foo.OUTPUT) + MessageChannel output(); +} +---- +* `HeaderMode.raw`. Use `none`, `headers` or `embeddedHeaders` +* `ProducerProperties.partitionKeyExtractorClass` in favor of `partitionKeyExtractorName` and `ProducerProperties.partitionSelectorClass` in favor of `partitionSelectorName`. +This is to ensure that both components are Spring configured/managed and referenced in Spring-friendly way. +* `BinderAwareRouterBeanPostProcessor` - while the component exists it is no longer a Bean Post Processor and will be renamed in the future. +* `BinderProperties.setEnvironment(Properties environment)` in favor of `BinderProperties.setEnvironment(Map environment)`. diff --git a/spring-cloud-stream-core-docs/src/main/asciidoc/spring-cloud-stream-overview.adoc b/spring-cloud-stream-core-docs/src/main/asciidoc/spring-cloud-stream-overview.adoc index 35191d356..2de3220b9 100644 --- a/spring-cloud-stream-core-docs/src/main/asciidoc/spring-cloud-stream-overview.adoc +++ b/spring-cloud-stream-core-docs/src/main/asciidoc/spring-cloud-stream-overview.adoc @@ -4,201 +4,6 @@ This section goes into more detail about how you can work with Spring Cloud Stre It covers topics such as creating and running stream applications. -- -== What's New in 2.0? -Spring Cloud Stream introduces quite a number of new features, enhancements and changes. The following sections outline most notable ones. - -=== New Features and Components - -==== Polling Consumer -Introduction of _polled consumers_, where the application can control message processing rates. Please refer to the appropriate section for more details. -You can also read this blog for more details https://spring.io/blog/2018/02/27/spring-cloud-stream-2-0-polled-consumers - -==== Micrometer support - -Metrics has been switched to use https://micrometer.io/[Micrometer]. `MeterRegistry` is also provided as a bean so custom application can autowire it to capture custom metrics. -Please refer to the appropriate section for more details - -==== New Actuator Binding controls -There are now new new Actuator binding controls to both visualize as well as control Bindings lifecycle. For more details please visit <> - -==== Configurable RetryTemplate -Aside from providing properties to configure `RetryTemplate` we now allow you to provide your own effectively overriding the one provided by the framework. Simply configure -it as a `@Bean` in your application. - -=== Notable changes and enhancements - -==== Both Actuator and Web dependencies are now optional - -This helps to slim down the footprint of the deployed application in the event neither of the functionality is required. -It also allows one to swicth between the reactive and conventional web paradigms by adding one of the following dependencies manually: -[source,xml] ----- - - org.springframework.boot - spring-boot-starter-web - ----- -or -[source,xml] ----- - - org.springframework.boot - spring-boot-starter-webflux - ----- - -Actuator dependency can be added as follows: -[source,xml] ----- - - org.springframework.boot - spring-boot-starter-actuator - ----- - -==== Content-type negotiation improvenents -One of the core themes for 2.0 is improvements (both consistency and performance) around content-type negotiation and message conversion. -The following summary outlines notable changes and improvements. Please refer to the appropriate section for more details as well as this blog -https://spring.io/blog/2018/02/26/spring-cloud-stream-2-0-content-type-negotiation-and-transformation. - -* All message conversion is now handled *only* by `MessageConverters`. -* Introduction of `@StreamMessageConverter` annotation to provide custom `MessageConverters`. -* Introduction of the default _Content Type_ as `application/json` which needs to be taken into consideration when migrating 1.3 -application and/or operating in the mixed mode (i.e., 1.3 producer -> 2.0 consumer). -* Messages with textual payloads and _contentType_ `text/...` or `.../json` are no longer converted to `Message` for cases where argument type of the provided `MessageHandler` -can not be determnied (i.e., `public void handle(Message message)` or `public void handle(Object payload)`). Further more, a strong argument type may not be enough -to properly convert messages, so `contentType` header is may be used as supplement by some `MessageConverters`. - -=== Notable Deprecations -==== Java serialization (Java native and Kryo) -* `JavaSerializationMessageConverter` and `KryoMessageConverter`. While these two converters remain for now, they will be moved out of the core packages and support in the future. -The main reason for this deprecation is to signal the issue _type-based language-specific_ serialization couuld cause in the distributed environments, where Producers and Consumers -may not only depend on different JVM versions or have different versions of supporting libraries (i.e., Kryo), but to also draw the attention to the fact that Consumers and Producers -may and in a lot of cases are non-Java based. - -==== Deprecated classes and methods -Following is a quick summary of notable deprecations. See corresponding javadocs fort more details. - -* `SharedChannelRegistry` in favor of `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 Foo { - String OUTPUT = "fooOutput"; - - @Output(Foo.OUTPUT) - MessageChannel output(); -} ----- -* `HeaderMode.raw`. Use `none`, `headers` or `embeddedHeaders` -* `ProducerProperties.partitionKeyExtractorClass` in favor of `partitionKeyExtractorName` and `ProducerProperties.partitionSelectorClass` in favor of `partitionSelectorName`. -This is to ensure that both components are Spring configured/managed and referenced in Spring-friendly way. -* `BinderAwareRouterBeanPostProcessor` - while the component exists it is no longer a Bean Post Processor and will be renamed in the future. -* `BinderProperties.setEnvironment(Properties environment)` in favor of `BinderProperties.setEnvironment(Map environment)`. - -== Quick Start - -You can try Spring Cloud Stream in less then 5 min even before you jump into any details and the following _three-step guide_ will help. - -We'll create a simple Spring Cloud Stream application which receives messages coming from the messaging middleware of your choice (more on this later) and -logs them to the console. We'll call it _LoggingConsumer_. While not very practical it will certainly provide a good introduction to some of the main concepts -and abstractions, making it easier to digest the rest of this user guide. - -So let's get started. . . - -==== Step One - Create sample Application using Spring Initilaizer -Visit the https://start.spring.io[Spring Initializr]. Tis is where we'll generate our _LoggingConsumer_ application. - -In _Dependencies_ start typing 'stream' and _Cloud Stream_ option should pop up. Select it. Now start typing either 'kafka' or 'rabbit'. Basically this is where you are choosing -what messaging midleware this application will be bound to. Choose the one you have already installed and/or feel more comfortable with installing/running. -Also, as you can see from the Initilaizer screen there are few other options you can choose. For example, you can choose Gradle as your build tool instead of the default Maven. -With the _Dependencies_ selected the only other thing you have to identify is the application name - _logging-consumer_. -Your configuration screeen should now contain the following: - - Dependencies: Cloud Stream, RabbitMQ (or Kafka) - Group: com.example - default - Artifact: logging-consumer - Spring Boot Version: 2.0.0 (or above) - default - -Click on _Generate Project_ button. This will donwload the zipped version of the generated project to your hard drive. Unzip it and you're ready for Step Two. - -==== Step Two - Import project into the IDE -Here you simply import the project into your IDE of choice. -Please keep in mind that dependening on the IDE you may need to follow a specific import procedures. For example depending on how the project was generated (Maven or Gradle) -you may need to follow specific import procedure (e.g., in Eclipse/STS: `File -> Import -> Maven -> Existing Maven Project`). - -Ones imported the project must have no errors of any kind and `src/main/java` should also contain `com.example.loggingconsumer.LoggingConsumerApplication`. - -Technically at this point you can just run the application's main class since it's already a valid _Spring Boot_ application, but it does not do anything, so let's add some code. - -==== Step Three - Add message handler, build and run -Modify the `com.example.loggingconsumer.LoggingConsumerApplication` to look as follows: - -[source, java] ----- -@SpringBootApplication -@EnableBinding(Sink.class) -public class LoggingConsumerApplication { - - public static void main(String[] args) { - SpringApplication.run(LoggingConsumerApplication.class, args); - } - - @StreamListener(Sink.INPUT) - public void handle(Person person) { - System.out.println("Received: " + person); - } - - public static class Person { - private String name; - public String getName() { - return name; - } - public void setName(String name) { - this.name = name; - } - public String toString() { - return this.name; - } - } -} ----- - -As you can see from the above: - -* We've enabled `Sink` binding (input-no-output) via `@EnableBinding(Sink.class)`. This will signal to the framework to initiate binding to the messaging middleware where -it will auto-create the destination which will be bound to `Sink.INPUT` channel. -* We've added handler method to receive incoming Message as type `Person`. What this means is that the framework will attempt to automatically convert incoming message to `Person` type. - -This is it, we now have a fully functional Spring Cloud Stream application. From here for simplicity we'll assume RabbitMQ was selected in step one. -Assuming you have RabbitMQ installed and running, start the application by simply running its `main` method. - -You should see following output: - - --- [ main] c.s.b.r.p.RabbitExchangeQueueProvisioner : declaring queue for inbound: input.anonymous.CbMIwdkJSBO1ZoPDOtHtCg, bound to: input - --- [ main] o.s.a.r.c.CachingConnectionFactory : Attempting to connect to: [localhost:5672] - --- [ main] o.s.a.r.c.CachingConnectionFactory : Created new connection: rabbitConnectionFactory#2a3a299:0/SimpleConnection@66c83fc8. . . - . . . - --- [ main] o.s.i.a.i.AmqpInboundChannelAdapter : started inbound.input.anonymous.CbMIwdkJSBO1ZoPDOtHtCg - . . . - --- [ main] c.e.l.LoggingConsumerApplication : Started LoggingConsumerApplication in 2.531 seconds (JVM running for 2.897) - -Go to RabbitMQ management console or any other RabbitMQ client and simply send message to `input.anonymous.CbMIwdkJSBO1ZoPDOtHtCg` -(NOTE: the `anonymous.CbMIwdkJSBO1ZoPDOtHtCg` part represents the group name and is generated and will be different in your environment. For something more -predictable you can use explicit group name via `spring.cloud.stream.bindings.input.group=hello`). - -The contents of the message should be JSON representation of `Person` class, so let's send this: - - {"name":"Turd Ferguson"} - -And in your console you should see: - - Received: Turd Ferguson - -You can also build/package your application into a boot jar (i.e., `./mvnw clean install`) and run the built JAR using `java -jar` command. - -That is all! - == Introducing Spring Cloud Stream Spring Cloud Stream is a framework for building message-driven microservice applications. Spring Cloud Stream builds upon Spring Boot to create standalone, production-grade Spring applications, and uses Spring Integration to provide connectivity to message brokers.