Add tcp-with-headers sample\
* Fix http/https in license; skip hidden files in project scan.
This commit is contained in:
committed by
Artem Bilan
parent
cb052d2d98
commit
8eb85d29b3
@@ -70,6 +70,7 @@ This is a good place to get started. The samples here are technically motivated
|
||||
* **tcp-amqp** - Demonstrates basic functionality of bridging the **Spring Integration TCP Adapters** with **Spring Integration AMQP Adapters**
|
||||
* **tcp-broadcast** - Demonstrates broadcasting a message to multiple connected TCP clients.
|
||||
* **tcp-client-server** - Demonstrates socket communication using **TcpOutboundGateway**, **TcpInboundGateway** and also uses a **Gateway** and a **Service Activator**
|
||||
* **tcp-with-headers** - Demonstrates sending headers along with the payload over TCP using JSON.
|
||||
* **testing-examples** - A series of test cases that show techniques to **test** Spring Integration applications.
|
||||
* **twitter** - Illustrates Twitter support using the **Twitter Inbound Channel Adapter**, **Twitter Inbound Search Channel Adapter**, **Twitter Outbound Channel Adapter**
|
||||
* **ws-inbound-gateway** - Example showing basic functionality of the **Web Service Gateway**
|
||||
|
||||
24
basic/tcp-with-headers/.gitignore
vendored
Normal file
24
basic/tcp-with-headers/.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
target/
|
||||
.mvn
|
||||
mvn*
|
||||
|
||||
### STS ###
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
nbproject/private/
|
||||
build/
|
||||
nbbuild/
|
||||
dist/
|
||||
nbdist/
|
||||
.nb-gradle/
|
||||
32
basic/tcp-with-headers/README.adoc
Normal file
32
basic/tcp-with-headers/README.adoc
Normal file
@@ -0,0 +1,32 @@
|
||||
= TCP With Headers
|
||||
|
||||
There is no standard way to convey message headers over raw TCP; they need to be encoded into the payload on the sending side and decoded on the receiving side.
|
||||
|
||||
This example demonstrates how to use standard framework components to encode the payload and certain headers using JSON.
|
||||
It takes console input and, if the input starts with a lower case, uppercases it and vice versa.
|
||||
Whether to upper case or lower case the input is conveyed in a header 'type'.
|
||||
|
||||
Run from your favorite IDE, or from the command line `./gradlew :dynamic-tcp-client:run`.
|
||||
|
||||
Here is an example run...
|
||||
|
||||
```
|
||||
. ____ _ __ _ _
|
||||
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
|
||||
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
|
||||
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
|
||||
' |____| .__|_| |_|_| |_\__, | / / / /
|
||||
=========|_|==============|___/=/_/_/_/
|
||||
:: Spring Boot :: (v2.1.3.RELEASE)
|
||||
|
||||
Enter some text; if it starts with a lower case character,
|
||||
it will be uppercased by the server; otherwise it will be lowercased;
|
||||
enter 'quit' to end
|
||||
this should be uppercased
|
||||
10:54:39.259 [pool-1-thread-2] INFO exampleLogger - Received type header:upper
|
||||
THIS SHOULD BE UPPERCASED
|
||||
This should be lowercased
|
||||
10:54:49.266 [pool-1-thread-2] INFO exampleLogger - Received type header:lower
|
||||
this should be lowercased
|
||||
quit
|
||||
```
|
||||
206
basic/tcp-with-headers/pom.xml
Normal file
206
basic/tcp-with-headers/pom.xml
Normal file
@@ -0,0 +1,206 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.2.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
<groupId>org.springframework.integration.samples</groupId>
|
||||
<artifactId>tcp-with-headers</artifactId>
|
||||
<version>5.2.0.BUILD-SNAPSHOT</version>
|
||||
<name>TCP Send/Receive with headers</name>
|
||||
<description>TCP Send/Receive with headers</description>
|
||||
<url>https://projects.spring.io/spring-integration</url>
|
||||
<organization>
|
||||
<name>SpringIO</name>
|
||||
<url>https://spring.io</url>
|
||||
</organization>
|
||||
<licenses>
|
||||
<license>
|
||||
<name>The Apache Software License, Version 2.0</name>
|
||||
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
<developers>
|
||||
<developer>
|
||||
<id>garyrussell</id>
|
||||
<name>Gary Russell</name>
|
||||
<email>grussell@pivotal.io</email>
|
||||
<roles>
|
||||
<role>project lead</role>
|
||||
</roles>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>markfisher</id>
|
||||
<name>Mark Fisher</name>
|
||||
<email>mfisher@pivotal.io</email>
|
||||
<roles>
|
||||
<role>project founder and lead emeritus</role>
|
||||
</roles>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>ghillert</id>
|
||||
<name>Gunnar Hillert</name>
|
||||
<email>ghillert@pivotal.io</email>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>abilan</id>
|
||||
<name>Artem Bilan</name>
|
||||
<email>abilan@pivotal.io</email>
|
||||
</developer>
|
||||
</developers>
|
||||
<scm>
|
||||
<connection>scm:git:scm:git:git://github.com/spring-projects/spring-integration-samples.git</connection>
|
||||
<developerConnection>scm:git:scm:git:ssh://git@github.com:spring-projects/spring-integration-samples.git</developerConnection>
|
||||
<url>https://github.com/spring-projects/spring-integration-samples</url>
|
||||
</scm>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-integration</artifactId>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>jackson-module-kotlin</artifactId>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-ip</artifactId>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>jackson-module-kotlin</artifactId>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.9.8</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>jackson-module-kotlin</artifactId>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>jackson-module-kotlin</artifactId>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>*</artifactId>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-all</artifactId>
|
||||
<version>1.3</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>jackson-module-kotlin</artifactId>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>2.24.0</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>jackson-module-kotlin</artifactId>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>*</artifactId>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>jackson-module-kotlin</artifactId>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>jackson-module-kotlin</artifactId>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>repo.spring.io.milestone</id>
|
||||
<name>Spring Framework Maven Milestone Repository</name>
|
||||
<url>https://repo.spring.io/libs-milestone</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>repo.spring.io.snapshot</id>
|
||||
<name>Spring Framework Maven Snapshot Repository</name>
|
||||
<url>https://repo.spring.io/libs-snapshot</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>2.2.0.BUILD-SNAPSHOT</version>
|
||||
<scope>import</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>5.2.0.BUILD-SNAPSHOT</version>
|
||||
<scope>import</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-bom</artifactId>
|
||||
<version>5.2.0.BUILD-SNAPSHOT</version>
|
||||
<scope>import</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
</project>
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2019 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
|
||||
*
|
||||
* https://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.tcpheaders;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.integration.dsl.IntegrationFlow;
|
||||
import org.springframework.integration.dsl.IntegrationFlows;
|
||||
import org.springframework.integration.handler.LoggingHandler.Level;
|
||||
import org.springframework.integration.ip.dsl.Tcp;
|
||||
import org.springframework.integration.ip.tcp.connection.MessageConvertingTcpMessageMapper;
|
||||
import org.springframework.integration.ip.tcp.serializer.MapJsonSerializer;
|
||||
import org.springframework.integration.support.converter.MapMessageConverter;
|
||||
import org.springframework.messaging.handler.annotation.Header;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@SpringBootApplication
|
||||
public class TcpWithHeadersApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(TcpWithHeadersApplication.class, args);
|
||||
}
|
||||
|
||||
// Client side
|
||||
|
||||
public interface TcpExchanger {
|
||||
|
||||
public String exchange(String data, @Header("type") String type);
|
||||
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IntegrationFlow client(@Value("${tcp.port:1234}") int port) {
|
||||
return IntegrationFlows.from(TcpExchanger.class)
|
||||
.handle(Tcp.outboundGateway(Tcp.netClient("localhost", port)
|
||||
.deserializer(jsonMapping())
|
||||
.serializer(jsonMapping())
|
||||
.mapper(mapper())))
|
||||
.get();
|
||||
}
|
||||
|
||||
// Server side
|
||||
|
||||
@Bean
|
||||
public IntegrationFlow server(@Value("${tcp.port:1234}") int port) {
|
||||
return IntegrationFlows.from(Tcp.inboundGateway(Tcp.netServer(port)
|
||||
.deserializer(jsonMapping())
|
||||
.serializer(jsonMapping())
|
||||
.mapper(mapper())))
|
||||
.log(Level.INFO, "exampleLogger", "'Received type header:' + headers['type']")
|
||||
.route("headers['type']", r -> r
|
||||
.subFlowMapping("upper",
|
||||
subFlow -> subFlow.transform(String.class, p -> p.toUpperCase()))
|
||||
.subFlowMapping("lower",
|
||||
subFlow -> subFlow.transform(String.class, p -> p.toLowerCase())))
|
||||
.get();
|
||||
}
|
||||
|
||||
// Common
|
||||
|
||||
@Bean
|
||||
public MessageConvertingTcpMessageMapper mapper() {
|
||||
MapMessageConverter converter = new MapMessageConverter();
|
||||
converter.setHeaderNames("type");
|
||||
return new MessageConvertingTcpMessageMapper(converter);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MapJsonSerializer jsonMapping() {
|
||||
return new MapJsonSerializer();
|
||||
}
|
||||
|
||||
// Console
|
||||
|
||||
@Bean
|
||||
@DependsOn("client")
|
||||
public ApplicationRunner runner(TcpExchanger exchanger,
|
||||
ConfigurableApplicationContext context) {
|
||||
|
||||
return args -> {
|
||||
System.out.println("Enter some text; if it starts with a lower case character,\n"
|
||||
+ "it will be uppercased by the server; otherwise it will be lowercased;\n"
|
||||
+ "enter 'quit' to end");
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
String request;
|
||||
if (scanner.hasNextLine()) {
|
||||
request = scanner.nextLine();
|
||||
while (!"quit".equals(request.toLowerCase())) {
|
||||
if (StringUtils.hasText(request)) {
|
||||
String result = exchanger.exchange(request,
|
||||
Character.isLowerCase(request.charAt(0)) ? "upper" : "lower");
|
||||
System.out.println(result);
|
||||
}
|
||||
if (scanner.hasNextLine()) {
|
||||
request = scanner.nextLine();
|
||||
}
|
||||
else {
|
||||
request = "quit";
|
||||
}
|
||||
}
|
||||
}
|
||||
scanner.close();
|
||||
context.close();
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
19
basic/tcp-with-headers/src/main/resources/logback.xml
Normal file
19
basic/tcp-with-headers/src/main/resources/logback.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<configuration>
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<!-- encoders are assigned the type
|
||||
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="warn">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
<logger name="org.springframework" level="WARN" />
|
||||
<logger name="org.springframework.integration" level="WARN" />
|
||||
<logger name="exampleLogger" level="INFO" />
|
||||
|
||||
</configuration>
|
||||
25
build.gradle
25
build.gradle
@@ -1445,6 +1445,31 @@ project('dynamic-tcp-client') {
|
||||
}
|
||||
}
|
||||
|
||||
project('tcp-with-headers') {
|
||||
description = 'TCP Send/Receive with headers'
|
||||
|
||||
apply plugin: 'org.springframework.boot'
|
||||
|
||||
dependencies {
|
||||
compile 'org.springframework.boot:spring-boot-starter-integration'
|
||||
compile "org.springframework.integration:spring-integration-ip"
|
||||
compile "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion"
|
||||
|
||||
testCompile 'org.springframework.boot:spring-boot-starter-test'
|
||||
}
|
||||
|
||||
bootRun {
|
||||
main = 'org.springframework.integration.samples.tcpheaders.TcpWithHeadersApplication'
|
||||
standardInput = System.in
|
||||
}
|
||||
|
||||
task run(type: JavaExec) {
|
||||
main 'org.springframework.integration.samples.tcpheaders.TcpWithHeadersApplication'
|
||||
classpath = sourceSets.main.runtimeClasspath
|
||||
standardInput = System.in
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sonarqube {
|
||||
properties {
|
||||
|
||||
@@ -4,12 +4,14 @@ rootProject.name = 'spring-integration-samples'
|
||||
def projectDir = new File(rootDir, it)
|
||||
include ":${it}"
|
||||
projectDir.eachDir { dir ->
|
||||
include ":${dir.name}"
|
||||
project(":${dir.name}").projectDir = new File(projectDir.absolutePath, dir.name)
|
||||
if ('cafe' == dir.name) {
|
||||
dir.eachDir { cafe ->
|
||||
include ":${cafe.name}"
|
||||
project(":${cafe.name}").projectDir = new File(dir.absolutePath, cafe.name)
|
||||
if (!dir.name.startsWith('.')) {
|
||||
include ":${dir.name}"
|
||||
project(":${dir.name}").projectDir = new File(projectDir.absolutePath, dir.name)
|
||||
if ('cafe' == dir.name) {
|
||||
dir.eachDir { cafe ->
|
||||
include ":${cafe.name}"
|
||||
project(":${cafe.name}").projectDir = new File(dir.absolutePath, cafe.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user