si4demo Spring Integration 4.0 Demo

https://spring.io/blog/2014/05/15/webinar-replay-spring-integration-4-0-the-new-frontier
This commit is contained in:
Gary Russell
2014-05-12 11:21:48 -04:00
parent cc579226d6
commit 148e7b52c2
7 changed files with 443 additions and 0 deletions

View File

@@ -13,6 +13,7 @@ Welcome to the **Spring Integration Samples** repository which provides **50+ sa
* Intermediate
* Advanced
* Applications
* DSL
Inside of each category you'll find a **README.md** file, which will contain a more detailed description of that category. Each sample also comes with its own **README.md** file explaining further details, e.g. how to run the respective sample.
@@ -33,6 +34,10 @@ Inside of each category you'll find a **README.md** file, which will contain a m
Below is a short description of each category.
## DSL
This directory holds demos/samples for Spring Integration 4.0 Java Configuration as well as the Java DSL Extension.
## Basic
This is a good place to get started. The samples here are technically motivated and demonstrate the bare minimum with regard to configuration and code to help you to get introduced to the basic concepts, API and configuration of Spring Integration. For example, if you are looking for an answer on how to wire a **Service Activator** to a **Channel** or how to apply a **Gateway** to your message exchange or how to get started with using the **MAIL** or **XML** module, this would be the right place to find a relevant sample. The bottom line is that this is a good starting point.

37
dsl/si4demo/README.md Normal file
View File

@@ -0,0 +1,37 @@
#Spring Integration 4.0 Java Config/DSL Demo
This sample is the demo used in the [Spring Integration 4.0 Webinar](https://spring.io/blog/2014/05/15/webinar-replay-spring-integration-4-0-the-new-frontier)
It's currently using the spring-boot 1.1.0.M1 milestone so you may have to add the __repo.spring.io/repo__ repository to your settings.xml.
There are two demo applications:
__demo.Application__ is a Spring Boot application using Spring Integration 4.0 Java configuration features.
__dsl.Application__ is the equivalent application using the new Java DSL that is currently being developed in the [extensions github repository](https://github.com/spring-projects/spring-integration-extensions/tree/master/spring-integration-java-dsl)
In both cases, you can use Telnet or curl to search twitter
$ telnet localhost 9876
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
#springintegration
[{"extraData":{},"id":461548132401438720,"text":"RT @gprussell: Spring Integration 4.0.0.RELEASE is out! ...
$ curl http://localhost:8080/foo -H"content-type:text/plain" -d '#springintegration'
[{"extraData":{},"id":461548132401438720,"text":"RT @gprussell: Spring Integration 4.0.0.RELEASE is out! ...
The DSL version also accepts typing in a hashtag for the search in the console. The DSL version also adds a filter to only allow hashtags starting with `#spring`, and only returns the first tweet.
Twitter now requires authentication to perform searches; visit the [twitter developer site](http://dev.twitter.com) to set up the application and enter the keys/secrets in _application.yml_ on the classpath. An 'empty' yaml file is provided in _src/main/resources:
twitter:
oauth:
consumerKey:
consumerSecret:
accessToken:
accessTokenSecret:

61
dsl/si4demo/pom.xml Normal file
View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.integration</groupId>
<artifactId>si4demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.1.0.M1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-twitter</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-java-dsl</artifactId>
<version>1.0.0.M1</version>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>demo.Application</start-class>
<java.version>1.7</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,159 @@
/*
* Copyright 2014 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 demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpMethod;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.annotation.Transformer;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.http.inbound.HttpRequestHandlingMessagingGateway;
import org.springframework.integration.http.inbound.RequestMapping;
import org.springframework.integration.ip.tcp.TcpInboundGateway;
import org.springframework.integration.ip.tcp.connection.TcpNetServerConnectionFactory;
import org.springframework.integration.json.ObjectToJsonTransformer;
import org.springframework.integration.transformer.ObjectToStringTransformer;
import org.springframework.integration.twitter.outbound.TwitterSearchOutboundGateway;
import org.springframework.messaging.MessageChannel;
import org.springframework.social.twitter.api.Twitter;
import org.springframework.social.twitter.api.impl.TwitterTemplate;
/**
*
* Spring Boot app offering telnet and http access to twitter search. Uses
* Spring Integration 4.0 Java Configuration.
*
* <pre class=code>
* $ telnet localhost 9876
* Trying 127.0.0.1...
* Connected to localhost.
* Escape character is '^]'.
* #springintegration
* [{"extraData":{},"id":461548132401438720,"text":"RT @gprussell: Spring Integration 4.0.0.RELEASE is out! ...
* </pre>
*
* <pre class=code>
* $ curl http://localhost:8080/foo -H"content-type:text/plain" -d '#springintegration'
* [{"extraData":{},"id":461548132401438720,"text":"RT @gprussell: Spring Integration 4.0.0.RELEASE is out! ...
* </pre>
*
* @author Gary Russell
* @since 4.0
*
*/
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext ctx = SpringApplication.run(Application.class);
System.in.read();
ctx.close();
}
@Autowired
private Environment env;
@Bean
TcpNetServerConnectionFactory cf() {
return new TcpNetServerConnectionFactory(9876);
}
@Bean
TcpInboundGateway tcpGate() {
TcpInboundGateway gateway = new TcpInboundGateway();
gateway.setConnectionFactory(cf());
gateway.setRequestChannel(requestChannel());
return gateway;
}
@Bean
public HttpRequestHandlingMessagingGateway httpGate() {
HttpRequestHandlingMessagingGateway gateway = new HttpRequestHandlingMessagingGateway(true);
RequestMapping mapping = new RequestMapping();
mapping.setMethods(HttpMethod.POST);
mapping.setPathPatterns("/foo");
gateway.setRequestMapping(mapping);
gateway.setRequestChannel(requestChannel());
gateway.setRequestPayloadType(byte[].class);
return gateway;
}
@Bean
public MessageChannel requestChannel() {
return new DirectChannel();
}
/*
* This was the first demonstration - an echo service before
* we added twitter.
*/
// @MessageEndpoint
// public static class Echo {
//
// @ServiceActivator(inputChannel="requestChannel")
// public String echo(byte[] in) {
// return "echo:" + new String(in);
// }
// }
@Bean
@Transformer(inputChannel="requestChannel", outputChannel="searchChannel")
public org.springframework.integration.transformer.Transformer converttoString() {
return new ObjectToStringTransformer();
}
@Bean
public MessageChannel searchChannel() {
return new DirectChannel();
}
@Bean
@ServiceActivator(inputChannel="searchChannel")
public TwitterSearchOutboundGateway twitterGate() {
TwitterSearchOutboundGateway gateway = new TwitterSearchOutboundGateway(twitter());
gateway.setOutputChannel(toJsonChannel());
return gateway;
}
@Bean
public MessageChannel toJsonChannel() {
return new DirectChannel();
}
@Bean
@Transformer(inputChannel="toJsonChannel")
public org.springframework.integration.transformer.Transformer converttoJson() {
return new ObjectToJsonTransformer();
}
@Bean
public Twitter twitter() {
return new TwitterTemplate(env.getProperty("twitter.oauth.consumerKey"),
env.getProperty("twitter.oauth.consumerSecret"),
env.getProperty("twitter.oauth.accessToken"),
env.getProperty("twitter.oauth.accessTokenSecret"));
}
}

View File

@@ -0,0 +1,157 @@
/*
* Copyright 2014 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 dsl;
import java.util.Scanner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpMethod;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.IntegrationFlows;
import org.springframework.integration.http.inbound.HttpRequestHandlingMessagingGateway;
import org.springframework.integration.http.inbound.RequestMapping;
import org.springframework.integration.ip.tcp.TcpInboundGateway;
import org.springframework.integration.ip.tcp.connection.TcpNetServerConnectionFactory;
import org.springframework.integration.json.ObjectToJsonTransformer;
import org.springframework.integration.transformer.ObjectToStringTransformer;
import org.springframework.integration.twitter.outbound.TwitterSearchOutboundGateway;
import org.springframework.messaging.MessageChannel;
import org.springframework.social.twitter.api.Twitter;
import org.springframework.social.twitter.api.impl.TwitterTemplate;
/**
*
* Spring Boot app offering telnet and http access to twitter search. Uses the Spring Integration 4.0 Java DSL extension.
* Adds a filter and only returns the first tweet.
*
* <pre class=code>
* $ telnet localhost 9876
* Trying 127.0.0.1...
* Connected to localhost.
* Escape character is '^]'.
* #springintegration
* [{"extraData":{},"id":461548132401438720,"text":"RT @gprussell: Spring Integration 4.0.0.RELEASE is out! ...
* </pre>
*
* <pre class=code>
* $ curl http://localhost:8080/foo -H"content-type:text/plain" -d '#springintegration'
* [{"extraData":{},"id":461548132401438720,"text":"RT @gprussell: Spring Integration 4.0.0.RELEASE is out! ...
* </pre>
*
* It also supports typing a hashtag into the console.
* @author Gary Russell
* @since 4.0
*
*/
@Configuration
@ComponentScan
@IntegrationComponentScan
@EnableAutoConfiguration
public class Application {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext ctx = SpringApplication.run(Application.class);
Scanner scanner = new Scanner(System.in);
String hashTag = scanner.nextLine();
System.out.println(ctx.getBean(Gateway.class).sendReceive(hashTag));
scanner.close();
ctx.close();
}
@MessagingGateway(defaultRequestChannel="requestChannel")
public interface Gateway {
String sendReceive(String in);
}
@Autowired
private Environment env;
@Bean
TcpNetServerConnectionFactory cf() {
return new TcpNetServerConnectionFactory(9876);
}
@Bean
TcpInboundGateway tcpGate() {
TcpInboundGateway gateway = new TcpInboundGateway();
gateway.setConnectionFactory(cf());
gateway.setRequestChannel(requestChannel());
return gateway;
}
@Bean
public HttpRequestHandlingMessagingGateway httpGate() {
HttpRequestHandlingMessagingGateway gateway = new HttpRequestHandlingMessagingGateway(true);
RequestMapping mapping = new RequestMapping();
mapping.setMethods(HttpMethod.POST);
mapping.setPathPatterns("/foo");
gateway.setRequestMapping(mapping);
gateway.setRequestChannel(requestChannel());
gateway.setRequestPayloadType(byte[].class);
return gateway;
}
@Bean
public MessageChannel requestChannel() {
return new DirectChannel();
}
@Bean
public IntegrationFlow flow() {
return IntegrationFlows.from("requestChannel")
.transform(new ObjectToStringTransformer())
.filter((String p) -> p.startsWith("#spring"),
f -> f.discardChannel("rejected"))
.handle(twitterGate())
.transform("payload[0]")
.transform(new ObjectToJsonTransformer())
.get();
}
@Bean
public IntegrationFlow errorFlow() {
return IntegrationFlows.from("rejected")
.transform("'Error: hashtag must start with #spring; got' + payload")
.get();
}
@Bean
public TwitterSearchOutboundGateway twitterGate() {
TwitterSearchOutboundGateway gateway = new TwitterSearchOutboundGateway(twitter());
return gateway;
}
@Bean
public Twitter twitter() {
return new TwitterTemplate(env.getProperty("twitter.oauth.consumerKey"),
env.getProperty("twitter.oauth.consumerSecret"),
env.getProperty("twitter.oauth.accessToken"),
env.getProperty("twitter.oauth.accessTokenSecret"));
}
}

View File

@@ -0,0 +1,6 @@
twitter:
oauth:
consumerKey:
consumerSecret:
accessToken:
accessTokenSecret:

View File

@@ -0,0 +1,18 @@
package demo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class ApplicationTests {
@Test
public void contextLoads() {
}
}