diff --git a/build.gradle b/build.gradle index a0a870844..6e2a550ae 100644 --- a/build.gradle +++ b/build.gradle @@ -734,6 +734,33 @@ project('cafe-dsl') { } } +project('webflux') { + description = 'Webflux DSL Sample' + + apply plugin: 'org.springframework.boot' + + dependencies { + compile 'org.springframework.boot:spring-boot-starter-integration' + compile "org.springframework.boot:spring-boot-starter-webflux" + compile "org.springframework.integration:spring-integration-core" + compile "org.springframework.integration:spring-integration-webflux" + + testCompile 'org.springframework.boot:spring-boot-starter-test' + } + bootRun { + main = 'org.springframework.integration.samples.dsl.webflux.WebFluxApplication' + } + + task run(type: JavaExec) { + main 'org.springframework.integration.samples.dsl.webflux.WebFluxApplication' + classpath = sourceSets.main.runtimeClasspath + } + + tasks.withType(JavaExec) { + standardInput = System.in + } +} + project('jdbc') { description = 'JDBC Basic Sample' diff --git a/dsl/webflux/README.md b/dsl/webflux/README.md new file mode 100644 index 000000000..1afe72f3f --- /dev/null +++ b/dsl/webflux/README.md @@ -0,0 +1,31 @@ +# WebFlux: Spring Integration Java DSL + +This sample demonstrates the usage of the WebFlux protocol adapter to split incoming messages to different routes and provide the results as SSE events. + +NOTE: at the time of this writing, [the WebFlux integration drops POST messages with empty request body](https://jira.spring.io/browse/INT-4462) + +## Run the Sample + +* You need Java 8 to run this sample, because it is based on Lambdas. +* running the `WebFluxApplication` class from within STS (Right-click on +Main class --> Run As --> Java Application) +* or from the command line in the _webflux_ folder: + + $ mvn spring-boot:run + +## Interact with the Sample + +The sample expects messages containing a JSON array where possible items are `"latte macchiato""` or `"caffe"`. + + $ curl -v -d "[\"latte macchiato\", \"caffe\"]" -H "Content-Type: application/json" http://localhost:8080/messages + +To listen for SSE events: + + $ curl localhost:8080/events + +Whenever a message is processed, a corresponding event will be sent to the _/events_ resource. + + data:"latte macchiato" + + data:"caffe" + diff --git a/dsl/webflux/pom.xml b/dsl/webflux/pom.xml new file mode 100644 index 000000000..cb0e407e6 --- /dev/null +++ b/dsl/webflux/pom.xml @@ -0,0 +1,59 @@ + + + 4.0.0 + + org.springframework.integration.samples + webflux + 0.0.1-SNAPSHOT + jar + + webflux + Demo project for Spring Integration Webflux + + + org.springframework.boot + spring-boot-starter-parent + 2.0.1.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-integration + + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.integration + spring-integration-webflux + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + diff --git a/dsl/webflux/src/main/java/org/springframework/integration/samples/dsl/webflux/WebFluxApplication.java b/dsl/webflux/src/main/java/org/springframework/integration/samples/dsl/webflux/WebFluxApplication.java new file mode 100644 index 000000000..27fb20355 --- /dev/null +++ b/dsl/webflux/src/main/java/org/springframework/integration/samples/dsl/webflux/WebFluxApplication.java @@ -0,0 +1,74 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.integration.samples.dsl.webflux; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.TextNode; +import org.reactivestreams.Publisher; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.integration.dsl.IntegrationFlow; +import org.springframework.integration.dsl.IntegrationFlows; +import org.springframework.integration.dsl.channel.MessageChannels; +import org.springframework.integration.webflux.dsl.WebFlux; +import org.springframework.messaging.Message; +import reactor.core.publisher.Flux; + +/** + * @author Dietrich Schulten + * @since 5.0.4 + */ +@SpringBootApplication +public class WebFluxApplication { + + public static void main(String[] args) { + SpringApplication.run(WebFluxApplication.class, args); + } + + @Bean + public Publisher> reactiveSource() { + return IntegrationFlows. + from(WebFlux.inboundChannelAdapter("/messages") + .requestMapping(r -> r + .methods(HttpMethod.POST) + ) + .requestPayloadType(JsonNode.class) + ) + .split() + .channel(MessageChannels.flux()) + .route(o -> o.asText(), + m -> m.defaultOutputToParentFlow() + .subFlowMapping("latte macchiato", f -> f.handle((p, h) -> p)) + .subFlowMapping("caffe", f -> f.handle((p, h) -> p))) + .toReactivePublisher(); + } + + + @Bean + public IntegrationFlow eventMessages() { + return IntegrationFlows + .from(WebFlux.inboundGateway("/events") + .requestMapping(m -> m.produces(MediaType.TEXT_EVENT_STREAM_VALUE))) + .handle((p, h) -> Flux.from(reactiveSource()) + .map(Message::getPayload)) + .get(); + } + +} diff --git a/dsl/webflux/src/main/resources/application.properties b/dsl/webflux/src/main/resources/application.properties new file mode 100644 index 000000000..ea33ef9be --- /dev/null +++ b/dsl/webflux/src/main/resources/application.properties @@ -0,0 +1,2 @@ +logging.level.org.springframework.web: DEBUG +logging.level.org.springframework.integration: DEBUG \ No newline at end of file diff --git a/dsl/webflux/src/test/java/org/springframework/integration/samples/dsl/webflux/WebfluxApplicationTests.java b/dsl/webflux/src/test/java/org/springframework/integration/samples/dsl/webflux/WebfluxApplicationTests.java new file mode 100644 index 000000000..74332b286 --- /dev/null +++ b/dsl/webflux/src/test/java/org/springframework/integration/samples/dsl/webflux/WebfluxApplicationTests.java @@ -0,0 +1,36 @@ +/* + * Copyright 2014-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.integration.samples.dsl.webflux; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * @author Dietrich Schulten + * @since 5.0.4 + */ +@RunWith(SpringRunner.class) +@SpringBootTest +public class WebfluxApplicationTests { + + @Test + public void contextLoads() { + } + +}