Spring STOMP: no way of using full featured broker and simple at the same time withou...
authorGustavo Martin Morcuende <gu.martinm@gmail.com>
Sun, 8 May 2016 20:18:34 +0000 (22:18 +0200)
committerGustavo Martin Morcuende <gu.martinm@gmail.com>
Sun, 8 May 2016 20:18:34 +0000 (22:18 +0200)
69 files changed:
SpringJava/STOMP/pom.xml [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-bom/pom.xml [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/pom.xml [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/controllers/MessageGreetingController.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/controllers/UserMessageTradeController.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/handlers/CustomHandshakeHandler.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/interceptors/CustomChannelInterceptor.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/interceptors/CustomHttpHandshakeInterceptor.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/listeners/BrokerAvailabilityListener.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/listeners/SessionConnectListener.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/listeners/SessionConnectedListener.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/listeners/SessionDisconnectListener.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/listeners/SessionSubscribeListener.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/listeners/SessionUnsubscribeListener.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/services/RestGreetingService.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/services/UserTradeService.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/services/impl/RestGreetingServiceImpl.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/services/impl/UserTradeServiceImpl.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/webservices/rest/controller/RestGreetingController.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/webservices/rest/controller/UserTradeController.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/resources/log4j2.xml [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/resources/spring-configuration/mvc/rest/rest-config.xml [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/resources/spring-configuration/spring-configuration.xml [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-full/src/main/webapp/WEB-INF/web.xml [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/pom.xml [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/controllers/MessageGreetingController.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/controllers/UserMessageTradeController.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/handlers/CustomHandshakeHandler.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/interceptors/CustomChannelInterceptor.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/interceptors/CustomHttpHandshakeInterceptor.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/listeners/BrokerAvailabilityListener.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/listeners/SessionConnectListener.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/listeners/SessionConnectedListener.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/listeners/SessionDisconnectListener.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/listeners/SessionSubscribeListener.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/listeners/SessionUnsubscribeListener.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/services/RestGreetingService.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/services/UserTradeService.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/services/impl/RestGreetingServiceImpl.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/services/impl/UserTradeServiceImpl.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/webservices/rest/controller/RestGreetingController.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/webservices/rest/controller/UserTradeController.java [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/resources/log4j2.xml [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/resources/spring-configuration/mvc/rest/rest-config.xml [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/resources/spring-configuration/spring-configuration.xml [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server-simple/src/main/webapp/WEB-INF/web.xml [new file with mode: 0644]
SpringJava/STOMP/spring-stomp-server/pom.xml [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/controllers/MessageGreetingController.java [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/controllers/UserMessageTradeController.java [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/handlers/CustomHandshakeHandler.java [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/interceptors/CustomChannelInterceptor.java [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/interceptors/CustomHttpHandshakeInterceptor.java [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/listeners/BrokerAvailabilityListener.java [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/listeners/SessionConnectListener.java [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/listeners/SessionConnectedListener.java [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/listeners/SessionDisconnectListener.java [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/listeners/SessionSubscribeListener.java [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/listeners/SessionUnsubscribeListener.java [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/services/RestGreetingService.java [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/services/UserTradeService.java [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/services/impl/RestGreetingServiceImpl.java [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/services/impl/UserTradeServiceImpl.java [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/webservices/rest/controller/RestGreetingController.java [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/webservices/rest/controller/UserTradeController.java [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/resources/log4j2.xml [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/resources/spring-configuration/mvc/rest/rest-config.xml [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/resources/spring-configuration/spring-configuration.xml [deleted file]
SpringJava/STOMP/spring-stomp-server/src/main/webapp/WEB-INF/web.xml [deleted file]
SpringJava/STOMP/spring-stomp/pom.xml [deleted file]

diff --git a/SpringJava/STOMP/pom.xml b/SpringJava/STOMP/pom.xml
new file mode 100644 (file)
index 0000000..01fa86d
--- /dev/null
@@ -0,0 +1,28 @@
+<?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>de.spring.stomp</groupId>
+       <artifactId>spring-stomp</artifactId>
+       <version>1.0-SNAPSHOT</version>
+       <packaging>pom</packaging>
+    <name>SPRING STOMP</name>
+    <url>http://gumartinm.name</url>
+    <description>
+        Spring Websockets. STOMP protocol.
+    </description>
+    <organization>
+        <name>Gustavo Martin Morcuende</name>
+        <url>https://www.gumartinm.name</url>
+    </organization>
+    <scm>
+        <developerConnection>scm:git:http://git.gumartinm.name/JavaForFun</developerConnection>
+        <url>https://git.gumartinm.name/JavaForFun</url>
+    </scm>
+
+       <modules>
+               <module>spring-stomp-bom</module>
+       </modules>
+
+</project>
diff --git a/SpringJava/STOMP/spring-stomp-bom/pom.xml b/SpringJava/STOMP/spring-stomp-bom/pom.xml
new file mode 100644 (file)
index 0000000..d802535
--- /dev/null
@@ -0,0 +1,329 @@
+<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/maven-v4_0_0.xsd">
+
+       <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>de.spring.stomp</groupId>
+        <artifactId>spring-stomp</artifactId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+
+       <artifactId>spring-stomp-bom</artifactId>
+       <packaging>pom</packaging>
+       <name>SPRING STOMP BOM</name>
+       <url>http://gumartinm.name</url>
+       <description>
+        Spring Websockets. STOMP protocol.
+    </description>
+       <organization>
+               <name>Gustavo Martin Morcuende</name>
+               <url>http://www.gumartinm.name</url>
+       </organization>
+       <scm>
+               <developerConnection>scm:git:http://git.gumartinm.name/JavaForFun</developerConnection>
+               <url>http://git.gumartinm.name/JavaForFun</url>
+       </scm>
+
+       <properties>
+               <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+               <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+               <spring.version>4.2.5.RELEASE</spring.version>
+       </properties>
+
+       <profiles>
+               <profile>
+                       <id>release</id>
+                       <properties>
+                               <environment.profile>release</environment.profile>
+                       </properties>
+                       <activation>
+                               <activeByDefault>true</activeByDefault>
+                       </activation>
+               </profile>
+       </profiles>
+
+    <modules>
+        <module>../spring-stomp-server-simple</module>
+        <module>../spring-stomp-server-full</module>
+    </modules>
+
+       <dependencies>
+               <!--
+                       1/3 Required dependency for log4j 2 with slf4j: binding between log4j 
+                       2 and slf4j
+               -->
+               <dependency>
+                       <groupId>org.apache.logging.log4j</groupId>
+                       <artifactId>log4j-slf4j-impl</artifactId>
+                       <version>2.3</version>
+               </dependency>
+               <!--
+                       2/3 Required dependency for log4j 2 with slf4j: log4j 2 maven plugin 
+                       (it is the log4j 2 implementation)
+               -->
+               <dependency>
+                       <groupId>org.apache.logging.log4j</groupId>
+                       <artifactId>log4j-core</artifactId>
+                       <version>2.3</version>
+               </dependency>
+               <!--
+                       3/3 Required dependency for getting rid of commons logging. This is 
+                       the BRIDGE (no binding) between Jakarta Commons Logging (used by Spring) 
+                       and whatever I am using for logging (in this case I am using log4j 2)
+                       See: http://www.slf4j.org/legacy.html We need exclusions in every dependency using 
+                       Jakarta Commons Logging (see Spring dependencies below)
+               -->
+               <dependency>
+                       <groupId>org.slf4j</groupId>
+                       <artifactId>jcl-over-slf4j</artifactId>
+                       <version>1.7.12</version>
+               </dependency>
+
+
+               <dependency>
+                       <groupId>cglib</groupId>
+                       <artifactId>cglib</artifactId>
+                       <version>2.2.2</version>
+               </dependency>
+               
+               <!-- Unitary and integration tests -->
+                       <dependency>
+                               <groupId>junit</groupId>
+                               <artifactId>junit</artifactId>
+                               <version>4.12</version>
+                               <scope>test</scope>
+                       </dependency>
+                       <dependency>
+                               <groupId>org.mockito</groupId>
+                               <artifactId>mockito-core</artifactId>
+                               <version>2.0.43-beta</version>
+                               <scope>test</scope>
+                       </dependency>
+       </dependencies>
+       <dependencyManagement>
+               <dependencies>
+                       <dependency>
+                               <groupId>org.springframework</groupId>
+                               <artifactId>spring-context</artifactId>
+                               <version>${spring.version}</version>
+                               <!--
+                                       Required dependency for getting rid of commons logging and use my
+                                       own logging library (in my case I decided to use log4j 2 under slf4j)
+                               -->
+                               <exclusions>
+                                       <exclusion>
+                                               <groupId>commons-logging</groupId>
+                                               <artifactId>commons-logging</artifactId>
+                                       </exclusion>
+                               </exclusions>
+                       </dependency>
+                       
+                       <!-- Required for WebSockets -->
+                       <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>spring-websocket</artifactId>
+                       <version>${spring.version}</version>
+                               <!--
+                                       Required dependency for getting rid of commons logging and use my
+                                       own logging library (in my case I decided to use log4j 2 under slf4j)
+                               -->
+                               <exclusions>
+                                       <exclusion>
+                                               <groupId>commons-logging</groupId>
+                                               <artifactId>commons-logging</artifactId>
+                                       </exclusion>
+                               </exclusions>
+                       </dependency>
+                       
+                       <!--  Required for STOMP -->
+                       <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>spring-messaging</artifactId>
+                       <version>${spring.version}</version>
+                               <!--
+                                       Required dependency for getting rid of commons logging and use my
+                                       own logging library (in my case I decided to use log4j 2 under slf4j)
+                               -->
+                               <exclusions>
+                                       <exclusion>
+                                               <groupId>commons-logging</groupId>
+                                               <artifactId>commons-logging</artifactId>
+                                       </exclusion>
+                               </exclusions>                           
+                       </dependency>
+                       
+                       <!-- REST API -->
+                       <dependency>
+                               <groupId>org.springframework</groupId>
+                               <artifactId>spring-webmvc</artifactId>
+                               <version>${spring.version}</version>
+                               <!--
+                                       Required dependency for getting rid of commons logging and use my
+                                       own logging library (in my case I decided to use log4j 2 under slf4j)
+                               -->
+                               <exclusions>
+                                       <exclusion>
+                                               <groupId>commons-logging</groupId>
+                                               <artifactId>commons-logging</artifactId>
+                                       </exclusion>
+                               </exclusions>
+                       </dependency>
+                       <dependency>
+                               <groupId>org.springframework</groupId>
+                               <artifactId>spring-oxm</artifactId>
+                               <version>${spring.version}</version>
+                               <!--
+                                       Required dependency for getting rid of commons logging and use my
+                                       own logging library (in my case I decided to use log4j 2 under slf4j)
+                               -->
+                               <exclusions>
+                                       <exclusion>
+                                               <groupId>commons-logging</groupId>
+                                               <artifactId>commons-logging</artifactId>
+                                       </exclusion>
+                               </exclusions>
+                       </dependency>
+                       
+                       
+                       <!-- Required by spring-webmvc -->
+                       <dependency>
+                               <groupId>javax.servlet</groupId>
+                               <artifactId>javax.servlet-api</artifactId>
+                               <version>4.0.0-b01</version>
+                               <scope>provided</scope>
+                       </dependency>
+
+                       <!--
+                               Jackson JSON Processor, required by spring-webmvc. See messageConverters 
+                               in rest-config.xml
+                       -->
+                       <dependency>
+                               <groupId>com.fasterxml.jackson.core</groupId>
+                               <artifactId>jackson-databind</artifactId>
+                               <version>2.6.4</version>
+                       </dependency>
+
+                       <!--
+                               Required by spring-context for using JSR-303. See LocalValidatorFactoryBean 
+                               in rest-config.xml
+                       -->
+                       <dependency>
+                               <groupId>javax.validation</groupId>
+                               <artifactId>validation-api</artifactId>
+                               <version>1.1.0.Final</version>
+                       </dependency>
+                       <dependency>
+                               <groupId>org.hibernate</groupId>
+                               <artifactId>hibernate-validator</artifactId>
+                               <version>5.2.2.Final</version>
+                       </dependency>
+
+
+                       <!-- Unitary and integration tests -->
+                       <dependency>
+                               <groupId>org.springframework</groupId>
+                               <artifactId>spring-test</artifactId>
+                               <version>${spring.version}</version>
+                               <scope>test</scope>
+                               <!--
+                                       Required dependency for getting rid of commons logging and use my
+                                       own logging library (in my case I decided to use log4j 2 under slf4j)
+                               -->
+                               <exclusions>
+                                       <exclusion>
+                                               <groupId>commons-logging</groupId>
+                                               <artifactId>commons-logging</artifactId>
+                                       </exclusion>
+                               </exclusions>
+                       </dependency>
+                       <dependency>
+                       <groupId>com.icegreen</groupId>
+                       <artifactId>greenmail</artifactId>
+                       <version>1.5.0</version>
+                       <scope>test</scope>
+                       </dependency>
+               </dependencies>
+       </dependencyManagement>
+       <build>
+
+               <pluginManagement>
+                       <plugins>
+                               <plugin>
+                                       <groupId>org.apache.maven.plugins</groupId>
+                                       <artifactId>maven-surefire-plugin</artifactId>
+                                       <version>2.19.1</version>
+                               </plugin>
+                               <plugin>
+                                       <groupId>org.apache.maven.plugins</groupId>
+                                       <artifactId>maven-failsafe-plugin</artifactId>
+                                       <version>2.19.1</version>
+                               </plugin>
+                       </plugins>
+               </pluginManagement>
+
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-compiler-plugin</artifactId>
+                               <version>3.1</version>
+                               <configuration>
+                                       <source>1.8</source>
+                                       <target>1.8</target>
+                                       <encoding>${project.build.sourceEncoding}</encoding>
+                               </configuration>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-resources-plugin</artifactId>
+                               <version>2.7</version>
+                               <configuration>
+                                       <encoding>${project.build.sourceEncoding}</encoding>
+                               </configuration>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-jar-plugin</artifactId>
+                               <version>2.6</version>
+                               <configuration>
+                                       <archive>
+                                               <manifestEntries>
+                                                       <Specification-Title>${project.description}</Specification-Title>
+                                                       <Specification-Version>${project.version}</Specification-Version>
+                                                       <Specification-Vendor>${project.organization.name}</Specification-Vendor>
+                                                       <Implementation-Title>${project.description}</Implementation-Title>
+                                                       <Implementation-Version>${project.version}</Implementation-Version>
+                                                       <Implementation-Vendor>${project.organization.name}</Implementation-Vendor>
+                                               </manifestEntries>
+                                       </archive>
+                               </configuration>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-surefire-plugin</artifactId>
+                               <configuration>
+                                       <excludes>
+                                               <exclude>**/*IntegrationTest.java</exclude>
+                                       </excludes>
+                               </configuration>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-failsafe-plugin</artifactId>
+                               <executions>
+                                       <execution>
+                                               <goals>
+                                                       <goal>integration-test</goal>
+                                                       <goal>verify</goal>
+                                               </goals>
+                                       </execution>
+                               </executions>
+                               <configuration>
+                                       <includes>
+                                               <include>**/*IntegrationTest.java</include>
+                                       </includes>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </build>
+</project>
diff --git a/SpringJava/STOMP/spring-stomp-server-full/pom.xml b/SpringJava/STOMP/spring-stomp-server-full/pom.xml
new file mode 100644 (file)
index 0000000..21ba678
--- /dev/null
@@ -0,0 +1,134 @@
+<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/maven-v4_0_0.xsd">
+
+       <modelVersion>4.0.0</modelVersion>
+
+       <parent>
+               <groupId>de.spring.stomp</groupId>
+               <artifactId>spring-stomp-bom</artifactId>
+               <version>1.0-SNAPSHOT</version>
+       </parent>
+
+       <artifactId>spring-stomp-server-full</artifactId>
+       <packaging>war</packaging>
+       <name>SPRING STOMP SERVER. FULL FEATURED BROKER.</name>
+       <url>https://gumartinm.name</url>
+       <description>
+        STOMP with Spring Framework. Full featured broker.
+    </description>
+       <organization>
+               <name>Gustavo Martin Morcuende</name>
+               <url>https://www.gumartinm.name</url>
+       </organization>
+       <scm>
+               <developerConnection>scm:git:http://git.gumartinm.name/JavaForFun</developerConnection>
+               <url>https://git.gumartinm.name/JavaForFun</url>
+       </scm>
+
+
+       <dependencies>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>spring-context</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>spring-webmvc</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>spring-oxm</artifactId>
+               </dependency>
+
+               <!-- Required for WebSockets -->
+               <dependency>
+               <groupId>org.springframework</groupId>
+               <artifactId>spring-websocket</artifactId>
+       </dependency>
+       
+       <!--  Required for STOMP -->
+               <dependency>
+               <groupId>org.springframework</groupId>
+               <artifactId>spring-messaging</artifactId>
+       </dependency>
+
+               <!-- Required by spring-webmvc -->
+               <dependency>
+                       <groupId>javax.servlet</groupId>
+                       <artifactId>javax.servlet-api</artifactId>
+                       <scope>provided</scope>
+               </dependency>
+
+               <!--
+                       Jackson JSON Processor, required by spring-webmvc. See messageConverters
+                       in rest-config.xml
+               -->
+               <dependency>
+                       <groupId>com.fasterxml.jackson.core</groupId>
+                       <artifactId>jackson-databind</artifactId>
+               </dependency>
+
+
+               <!--
+                       Required by spring-context for using JSR-303. See LocalValidatorFactoryBean
+                       in rest-config.xml
+               -->
+               <dependency>
+                       <groupId>javax.validation</groupId>
+                       <artifactId>validation-api</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.hibernate</groupId>
+                       <artifactId>hibernate-validator</artifactId>
+               </dependency>
+               
+               
+               <!-- Full-featured broker, TCP connection management. -->
+               <dependency>
+                   <groupId>io.projectreactor</groupId>
+                   <artifactId>reactor-net</artifactId>
+                   <version>2.0.8.RELEASE</version>
+               </dependency>
+               <dependency>
+                       <groupId>io.netty</groupId>
+                       <artifactId>netty-all</artifactId>
+                       <version>4.0.36.Final</version>
+               </dependency>
+
+       </dependencies>
+       <build>
+               <finalName>${project.artifactId}</finalName>
+               <resources>
+                       <resource>
+                               <directory>${basedir}/src/main/webapp</directory>
+                               <excludes>
+                                       <exclude>**/*.*</exclude>
+                               </excludes>
+                       </resource>
+                       <resource>
+                               <directory>${basedir}/src/main/resources/</directory>
+                               <includes>
+                                       <include>**/*.*</include>
+                               </includes>
+                       </resource>
+               </resources>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-war-plugin</artifactId>
+                               <version>2.6</version>
+                               <configuration>
+                                       <webResources>
+                                               <resource>
+                                                       <filtering>true</filtering>
+                                                       <directory>src/main/webapp</directory>
+                                                       <includes>
+                                                               <include>WEB-INF/web.xml</include>
+                                                       </includes>
+                                               </resource>
+                                       </webResources>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </build>
+</project>
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/controllers/MessageGreetingController.java b/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/controllers/MessageGreetingController.java
new file mode 100644 (file)
index 0000000..982b6ff
--- /dev/null
@@ -0,0 +1,26 @@
+package de.spring.stomp.controllers;
+
+import java.time.LocalDateTime;
+
+import org.springframework.messaging.handler.annotation.MessageMapping;
+import org.springframework.messaging.handler.annotation.SendTo;
+import org.springframework.stereotype.Controller;
+
+@Controller
+public class MessageGreetingController {
+
+       // Sending data to /app/greeting from STOMP client (client must first connect to endpoint, in my case portfolio)
+       // connecting to this URL -> http://172.17.0.3/spring-stomp-server/portfolio
+       // sending data to /app/greeting
+       
+       // The data sent to /app/greeting will be retrieved by this method.
+       @MessageMapping("/greeting")
+       @SendTo("/topic/greeting")
+       public String handle(String greeting) {
+               // STOMP clients subscribed to /topic/greeting will receive the returned data from this method.
+               // Destination is selected based on a convention but can be overridden via @SendTo
+               // I will be using @SendTo. In my case, it is not required (because it is the same as the destination selected
+               // based on the convention) but I will be using it just for fun.
+               return "[" + LocalDateTime.now() + "]: " + greeting;
+       }
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/controllers/UserMessageTradeController.java b/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/controllers/UserMessageTradeController.java
new file mode 100644 (file)
index 0000000..d98b36b
--- /dev/null
@@ -0,0 +1,19 @@
+package de.spring.stomp.controllers;
+
+import java.security.Principal;
+import java.time.LocalDateTime;
+
+import org.springframework.messaging.handler.annotation.MessageMapping;
+import org.springframework.messaging.simp.annotation.SendToUser;
+import org.springframework.stereotype.Controller;
+
+@Controller
+public class UserMessageTradeController {
+
+    @MessageMapping("/trade")
+    @SendToUser(destinations="/topic/position-updates", broadcast=false /* No idea what is this for */)
+    public String executeTrade(String trade, Principal principal) {
+
+       return "[" + LocalDateTime.now() + "]: " + trade;
+    }
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/handlers/CustomHandshakeHandler.java b/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/handlers/CustomHandshakeHandler.java
new file mode 100644 (file)
index 0000000..a633f75
--- /dev/null
@@ -0,0 +1,35 @@
+package de.spring.stomp.handlers;
+
+import java.security.Principal;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.web.socket.WebSocketHandler;
+import org.springframework.web.socket.server.support.DefaultHandshakeHandler;
+
+/**
+ * In some cases it may be useful to assign an identity to a WebSocket session even when
+ * the user has not been formally authenticated. For example, a mobile app might assign some
+ * identity to anonymous users, perhaps based on geographical location. The do that currently,
+ * an application can sub-class DefaultHandshakeHandler and override the determineUser method.
+ * The custom handshake handler can then be plugged in (see examples in
+ * Section 25.2.4, “Deployment Considerations”)
+ */
+public class CustomHandshakeHandler extends DefaultHandshakeHandler {
+       private static final Logger LOGGER = LoggerFactory.getLogger(CustomHandshakeHandler.class);
+
+       @Override
+       protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler,
+                       Map<String, Object> attributes) {
+
+               Principal principal = request.getPrincipal();
+               if (principal != null) {
+                       LOGGER.info("CustomHandshakeHandler: " + principal.getName());
+               }
+               
+               return super.determineUser(request, wsHandler, attributes);             
+       }
+
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/interceptors/CustomChannelInterceptor.java b/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/interceptors/CustomChannelInterceptor.java
new file mode 100644 (file)
index 0000000..7936bf8
--- /dev/null
@@ -0,0 +1,40 @@
+package de.spring.stomp.interceptors;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.messaging.Message;
+import org.springframework.messaging.MessageChannel;
+import org.springframework.messaging.simp.stomp.StompCommand;
+import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
+import org.springframework.messaging.support.ChannelInterceptorAdapter;
+
+public class CustomChannelInterceptor extends ChannelInterceptorAdapter {
+       private static final Logger LOGGER = LoggerFactory.getLogger(CustomChannelInterceptor.class);
+
+         @Override
+         public Message<?> preSend(Message<?> message, MessageChannel channel) {
+           StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
+           StompCommand command = accessor.getCommand();
+
+           LOGGER.info("CustomChannelInterceptor preSend, StompCommand: " + command);
+           LOGGER.info("CustomChannelInterceptor preSend, login: " + accessor.getLogin());
+           LOGGER.info("CustomChannelInterceptor preSend, heartBeat: " + accessor.getHeartbeat());
+           LOGGER.info("CustomChannelInterceptor preSend, destination: " + accessor.getDestination());
+           LOGGER.info("CustomChannelInterceptor preSend, host: " + accessor.getHost());
+           
+           return message;
+         }
+         
+         @Override
+         public void postSend(Message<?> message, MessageChannel channel, boolean sent) {
+           StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
+           StompCommand command = accessor.getCommand();
+
+           LOGGER.info("CustomChannelInterceptor postSend, StompCommand: " + command);
+           LOGGER.info("CustomChannelInterceptor postSend, login: " + accessor.getLogin());
+           LOGGER.info("CustomChannelInterceptor postSend, heartBeat: " + accessor.getHeartbeat());
+           LOGGER.info("CustomChannelInterceptor postSend, destination: " + accessor.getDestination());
+           LOGGER.info("CustomChannelInterceptor postSend, host: " + accessor.getHost());
+           
+         }
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/interceptors/CustomHttpHandshakeInterceptor.java b/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/interceptors/CustomHttpHandshakeInterceptor.java
new file mode 100644 (file)
index 0000000..784ab6a
--- /dev/null
@@ -0,0 +1,26 @@
+package de.spring.stomp.interceptors;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.web.socket.WebSocketHandler;
+import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
+
+public class CustomHttpHandshakeInterceptor extends HttpSessionHandshakeInterceptor {
+       private static final Logger LOGGER = LoggerFactory.getLogger(CustomHttpHandshakeInterceptor.class);
+
+
+       @Override
+       public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
+                       WebSocketHandler wsHandler, Exception ex) {
+               super.afterHandshake(request, response, wsHandler, ex);
+               
+               LOGGER.info("Request URI:" + request.getURI());
+               LOGGER.info("Request remote address:" + request.getRemoteAddress());
+               LOGGER.info("Request local address:" + request.getLocalAddress());
+               LOGGER.info("Request headers:" + request.getHeaders());
+               
+               LOGGER.info("Response headers:" + response.getHeaders());               
+       }
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/listeners/BrokerAvailabilityListener.java b/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/listeners/BrokerAvailabilityListener.java
new file mode 100644 (file)
index 0000000..b6e3619
--- /dev/null
@@ -0,0 +1,19 @@
+package de.spring.stomp.listeners;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationListener;
+import org.springframework.messaging.simp.broker.BrokerAvailabilityEvent;
+
+public class BrokerAvailabilityListener implements ApplicationListener<BrokerAvailabilityEvent> {
+       private static final Logger LOGGER = LoggerFactory.getLogger(BrokerAvailabilityListener.class);
+
+       @Override
+       public void onApplicationEvent(BrokerAvailabilityEvent event) {
+               
+               LOGGER.info("BrokerAvailabilityEvent timestamp: " + event.getTimestamp());
+               LOGGER.info("BrokerAvailabilityEvent brokerAvailable: " + event.isBrokerAvailable());
+               LOGGER.info("BrokerAvailabilityEvent: " + event.toString());
+       }
+
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/listeners/SessionConnectListener.java b/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/listeners/SessionConnectListener.java
new file mode 100644 (file)
index 0000000..da374e5
--- /dev/null
@@ -0,0 +1,18 @@
+package de.spring.stomp.listeners;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationListener;
+import org.springframework.web.socket.messaging.SessionConnectEvent;
+
+public class SessionConnectListener implements ApplicationListener<SessionConnectEvent> {
+       private static final Logger LOGGER = LoggerFactory.getLogger(SessionConnectListener.class);
+       
+       @Override
+       public void onApplicationEvent(SessionConnectEvent event) {
+               LOGGER.info("SessionConnectEvent timestamp: " + event.getTimestamp());
+               LOGGER.info("SessionConnectEvent user: " + event.getUser());
+               LOGGER.info("SessionConnectEvent: " + event.toString());
+       }
+
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/listeners/SessionConnectedListener.java b/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/listeners/SessionConnectedListener.java
new file mode 100644 (file)
index 0000000..b0444f3
--- /dev/null
@@ -0,0 +1,18 @@
+package de.spring.stomp.listeners;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationListener;
+import org.springframework.web.socket.messaging.SessionConnectedEvent;
+
+public class SessionConnectedListener implements ApplicationListener<SessionConnectedEvent> {
+       private static final Logger LOGGER = LoggerFactory.getLogger(SessionConnectedListener.class);
+
+       @Override
+       public void onApplicationEvent(SessionConnectedEvent event) {
+               LOGGER.info("SessionConnectedEvent timestamp: " + event.getTimestamp());
+               LOGGER.info("SessionConnectedEvent user: " + event.getUser());
+               LOGGER.info("SessionConnectedEvent: " + event.toString());
+       }
+
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/listeners/SessionDisconnectListener.java b/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/listeners/SessionDisconnectListener.java
new file mode 100644 (file)
index 0000000..59ff3e4
--- /dev/null
@@ -0,0 +1,20 @@
+package de.spring.stomp.listeners;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationListener;
+import org.springframework.web.socket.messaging.SessionDisconnectEvent;
+
+public class SessionDisconnectListener implements ApplicationListener<SessionDisconnectEvent> {
+       private static final Logger LOGGER = LoggerFactory.getLogger(SessionUnsubscribeListener.class);
+
+       @Override
+       public void onApplicationEvent(SessionDisconnectEvent event) {
+               LOGGER.info("SessionDisconnectEvent timestamp: " + event.getTimestamp());
+               LOGGER.info("SessionDisconnectEvent user: " + event.getUser());
+               LOGGER.info("SessionDisconnectEvent sessionId: " + event.getSessionId());
+               LOGGER.info("SessionDisconnectEvent close status: " + event.getCloseStatus());
+               LOGGER.info("SessionDisconnectEvent: " + event.toString());
+       }
+
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/listeners/SessionSubscribeListener.java b/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/listeners/SessionSubscribeListener.java
new file mode 100644 (file)
index 0000000..90ee1da
--- /dev/null
@@ -0,0 +1,18 @@
+package de.spring.stomp.listeners;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationListener;
+import org.springframework.web.socket.messaging.SessionSubscribeEvent;
+
+public class SessionSubscribeListener implements ApplicationListener<SessionSubscribeEvent> {
+       private static final Logger LOGGER = LoggerFactory.getLogger(SessionSubscribeListener.class);
+
+       @Override
+       public void onApplicationEvent(SessionSubscribeEvent event) {
+               LOGGER.info("SessionSubscribeEvent timestamp: " + event.getTimestamp());
+               LOGGER.info("SessionSubscribeEvent user: " + event.getUser());
+               LOGGER.info("SessionSubscribeEvent: " + event.toString());
+       }
+
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/listeners/SessionUnsubscribeListener.java b/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/listeners/SessionUnsubscribeListener.java
new file mode 100644 (file)
index 0000000..142bde9
--- /dev/null
@@ -0,0 +1,18 @@
+package de.spring.stomp.listeners;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationListener;
+import org.springframework.web.socket.messaging.SessionUnsubscribeEvent;
+
+public class SessionUnsubscribeListener implements ApplicationListener<SessionUnsubscribeEvent> {
+       private static final Logger LOGGER = LoggerFactory.getLogger(SessionUnsubscribeListener.class);
+
+       @Override
+       public void onApplicationEvent(SessionUnsubscribeEvent event) {
+               LOGGER.info("SessionUnsubscribeEvent timestamp: " + event.getTimestamp());
+               LOGGER.info("SessionUnsubscribeEvent user: " + event.getUser());
+               LOGGER.info("SessionUnsubscribeEvent: " + event.toString());
+       }
+
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/services/RestGreetingService.java b/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/services/RestGreetingService.java
new file mode 100644 (file)
index 0000000..69db326
--- /dev/null
@@ -0,0 +1,6 @@
+package de.spring.stomp.services;
+
+public interface RestGreetingService {
+
+       void doGreetings(String greeting);
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/services/UserTradeService.java b/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/services/UserTradeService.java
new file mode 100644 (file)
index 0000000..1d6bc34
--- /dev/null
@@ -0,0 +1,6 @@
+package de.spring.stomp.services;
+
+public interface UserTradeService {
+
+       void doTrade(String user);
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/services/impl/RestGreetingServiceImpl.java b/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/services/impl/RestGreetingServiceImpl.java
new file mode 100644 (file)
index 0000000..b518e76
--- /dev/null
@@ -0,0 +1,43 @@
+package de.spring.stomp.services.impl;
+
+import java.time.LocalDateTime;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationListener;
+import org.springframework.messaging.simp.SimpMessagingTemplate;
+import org.springframework.messaging.simp.broker.BrokerAvailabilityEvent;
+import org.springframework.stereotype.Service;
+
+import de.spring.stomp.services.RestGreetingService;
+
+@Service("restGreetingService")
+public class RestGreetingServiceImpl
+               implements RestGreetingService, ApplicationListener<BrokerAvailabilityEvent> {
+       private final SimpMessagingTemplate template;
+       
+       private volatile boolean isBrokerAvailable = true;
+
+    @Autowired
+    public RestGreetingServiceImpl(SimpMessagingTemplate template) {
+        this.template = template;
+    }
+
+       @Override
+       public void doGreetings(String greeting) {
+               String text = "[" + LocalDateTime.now() + "]:" + greeting;
+               
+               if (isBrokerAvailable) {
+                       // STOMP clients subscribed to /topic/greeting will receive the data sent by the convertAndSend method.
+                       template.convertAndSend("/topic/greeting", text);
+               }
+       }
+
+       @Override
+       public void onApplicationEvent(BrokerAvailabilityEvent event) {
+               // Components using the SimpMessagingTemplate should subscribe to this event
+               // and avoid sending messages at times when the broker is not available.
+               // In any case they should be prepared to handle MessageDeliveryException
+               // when sending a message.
+               isBrokerAvailable = event.isBrokerAvailable();
+       }
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/services/impl/UserTradeServiceImpl.java b/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/stomp/services/impl/UserTradeServiceImpl.java
new file mode 100644 (file)
index 0000000..e0d63e2
--- /dev/null
@@ -0,0 +1,44 @@
+package de.spring.stomp.services.impl;
+
+import java.time.LocalDateTime;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationListener;
+import org.springframework.messaging.simp.SimpMessagingTemplate;
+import org.springframework.messaging.simp.broker.BrokerAvailabilityEvent;
+import org.springframework.stereotype.Service;
+
+import de.spring.stomp.services.UserTradeService;
+
+@Service("userTradeService")
+public class UserTradeServiceImpl
+               implements UserTradeService, ApplicationListener<BrokerAvailabilityEvent> {
+       private final SimpMessagingTemplate template;
+       
+       private volatile boolean isBrokerAvailable = true;
+
+    @Autowired
+    public UserTradeServiceImpl(SimpMessagingTemplate template) {
+        this.template = template;
+    }
+    
+       @Override
+       public void doTrade(String user) {
+               String text = "[" + LocalDateTime.now() + "]:" + user;
+               
+               if (isBrokerAvailable) {
+                       // STOMP clients subscribed to /topic/position-updates will receive the data sent by the convertAndSend method.
+                       template.convertAndSendToUser(user, "/topic/position-updates", text);
+               }
+       }
+
+       @Override
+       public void onApplicationEvent(BrokerAvailabilityEvent event) {
+               // Components using the SimpMessagingTemplate should subscribe to this event
+               // and avoid sending messages at times when the broker is not available.
+               // In any case they should be prepared to handle MessageDeliveryException
+               // when sending a message.
+               isBrokerAvailable = event.isBrokerAvailable();
+       }
+
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/webservices/rest/controller/RestGreetingController.java b/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/webservices/rest/controller/RestGreetingController.java
new file mode 100644 (file)
index 0000000..ebb32ed
--- /dev/null
@@ -0,0 +1,31 @@
+package de.spring.webservices.rest.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import de.spring.stomp.services.RestGreetingService;
+
+
+@RestController
+public class RestGreetingController {
+       private final RestGreetingService restGreetingService;
+
+    @Autowired
+    public RestGreetingController(RestGreetingService restGreetingService) {
+        this.restGreetingService = restGreetingService;
+    }
+
+    // Sending data to /topic/greeting from REST service.
+       // POST http://localhost:8080/spring-stomp-server/greetings
+    
+       @RequestMapping(path="/greetings", method=RequestMethod.POST)
+    public void handle(@RequestBody String greeting) {
+               
+               // STOMP clients subscribed to /topic/greeting will receive the data sent by the convertAndSend method.
+               restGreetingService.doGreetings(greeting);
+    }
+
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/webservices/rest/controller/UserTradeController.java b/SpringJava/STOMP/spring-stomp-server-full/src/main/java/de/spring/webservices/rest/controller/UserTradeController.java
new file mode 100644 (file)
index 0000000..718a8bd
--- /dev/null
@@ -0,0 +1,27 @@
+package de.spring.webservices.rest.controller;
+
+import java.time.LocalDateTime;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import de.spring.stomp.services.UserTradeService;
+
+public class UserTradeController {
+       private final UserTradeService userTradeService;
+
+    @Autowired
+    public UserTradeController(UserTradeService userTradeService) {
+        this.userTradeService = userTradeService;
+    }
+
+    // Sending data to /topic/greeting from REST service.
+       // POST http://localhost:8080/spring-stomp-server/trade
+    
+       @RequestMapping(path="/trade", method=RequestMethod.POST)
+    public void handle(@RequestBody String user) {
+               userTradeService.doTrade(user);
+    }
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/resources/log4j2.xml b/SpringJava/STOMP/spring-stomp-server-full/src/main/resources/log4j2.xml
new file mode 100644 (file)
index 0000000..281da4f
--- /dev/null
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- 
+       status: The level of internal Log4j events that should be logged to the console.
+       Valid values for this attribute are "trace", "debug", "info", "warn", "error" and "fatal".
+       
+       monitorInterval: The minimum amount of time, in seconds, that must elapse before the file configuration is checked for changes.
+       
+       
+       see https://logging.apache.org/log4j/2.x/manual/configuration.html
+ -->
+<Configuration status="error" strict="true" monitorInterval="30"
+                name="XMLConfigTest" packages="org.apache.logging.log4j.test">
+                
+       <!--
+               ALL > TRACE > DEBUG > INFO > WARN > ERROR > OFF
+               
+               ERROR by default.
+       -->
+                
+    <Appenders>
+        <Appender type="Console" name="STDOUT">
+            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
+        </Appender>
+    </Appenders>
+    <Loggers>
+    
+        <!-- 
+               SockJS client disconnects. Requires TRACE level always.
+               It works because I know for sure I will be using WebSockets when using SockJS.
+        -->
+        <Logger
+               name="org.springframework.web.socket.sockjs.transport.session.WebSocketServerSockJsSession"
+                       level="TRACE" additivity="false">
+            <AppenderRef ref="STDOUT" />
+        </Logger>
+    
+               <!-- 
+               General logging Spring.
+        -->
+        <Logger name="org.springframework" level="INFO" additivity="false">
+            <AppenderRef ref="STDOUT" />
+        </Logger>
+    
+
+               <!-- 
+                       Anything else will be using TRACE logging level.
+                -->        
+        <Root level="INFO">
+            <AppenderRef ref="STDOUT"/>
+        </Root>
+    </Loggers>
+</Configuration>
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/resources/spring-configuration/mvc/rest/rest-config.xml b/SpringJava/STOMP/spring-stomp-server-full/src/main/resources/spring-configuration/mvc/rest/rest-config.xml
new file mode 100644 (file)
index 0000000..5ce72ef
--- /dev/null
@@ -0,0 +1,93 @@
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:mvc="http://www.springframework.org/schema/mvc"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xmlns:p="http://www.springframework.org/schema/p"
+       xsi:schemaLocation="
+               http://www.springframework.org/schema/beans
+               http://www.springframework.org/schema/beans/spring-beans.xsd
+        http://www.springframework.org/schema/mvc
+        http://www.springframework.org/schema/mvc/spring-mvc.xsd
+        http://www.springframework.org/schema/context
+        http://www.springframework.org/schema/context/spring-context.xsd
+        http://www.springframework.org/schema/util
+        http://www.springframework.org/schema/util/spring-util.xsd">
+   
+       <!--
+               I am declaring my beans without the automatic annotation. :/
+               Better because we are saving memory but it requires more configuration.
+               
+               See: org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser
+               <mvc:annotation-driven/>
+        -->
+        
+   
+       <context:annotation-config />
+   
+       <context:component-scan base-package="de.spring.webservices.rest"/>
+       
+       <!--
+               Required beans for generating XML responses from Java objects using JAXB annotations
+               Jackson also works but it doesn't generate XML with namespaces... O.o
+               
+               This implementation will be slower than the one using Jackson :( but I am going to use it just for WADL generation :)
+       -->    
+    <bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
+        <property name="packagesToScan" value="org.jvnet.ws.wadl"/>
+    </bean>
+       <bean id="jaxbConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
+       <constructor-arg ref="jaxbMarshaller" />
+       </bean>
+    
+       <!-- Required beans for generating JSON responses from Java objects -->
+    <bean id="jsonObjectMapperFactory" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
+       p:indentOutput="true" p:failOnEmptyBeans="false">
+        <property name="featuresToDisable">
+            <array>
+                <util:constant static-field="com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES"/>
+                <util:constant static-field="com.fasterxml.jackson.databind.MapperFeature.DEFAULT_VIEW_INCLUSION"/>
+            </array>
+        </property>
+    </bean>
+    
+    <util:list id="messageConverters">
+        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" p:objectMapper-ref="jsonObjectMapperFactory"/>
+               <ref bean="jaxbConverter" />
+        <bean class="org.springframework.http.converter.StringHttpMessageConverter" />
+    </util:list>
+
+
+       <bean name="handlerAdapter"
+               class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
+               <property name="webBindingInitializer">
+                       <bean
+                               class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
+                               <!-- It enables us to use JSR-303 -->
+                               <property name="validator">
+                                       <bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
+                               </property>
+                       </bean>
+               </property>
+               <property name="messageConverters" ref="messageConverters" />
+               
+               
+               <property name="requestBodyAdvice">
+                       <util:list>
+                               <bean id="requestBodyAdvice" class="org.springframework.web.servlet.mvc.method.annotation.JsonViewRequestBodyAdvice"/>
+                       </util:list>
+               </property>
+               
+               
+               <property name="responseBodyAdvice">
+                       <util:list>
+                               <bean id="responseBodyAdvice" class="org.springframework.web.servlet.mvc.method.annotation.JsonViewResponseBodyAdvice"/>
+                       </util:list>
+               </property>
+       </bean>
+    
+       <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
+
+       <mvc:default-servlet-handler />
+       
+</beans>
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/resources/spring-configuration/spring-configuration.xml b/SpringJava/STOMP/spring-stomp-server-full/src/main/resources/spring-configuration/spring-configuration.xml
new file mode 100644 (file)
index 0000000..27771f3
--- /dev/null
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xmlns:context="http://www.springframework.org/schema/context"
+  xmlns:websocket="http://www.springframework.org/schema/websocket"
+
+  xsi:schemaLocation="http://www.springframework.org/schema/beans 
+                      http://www.springframework.org/schema/beans/spring-beans.xsd
+                      http://www.springframework.org/schema/context 
+                      http://www.springframework.org/schema/context/spring-context.xsd
+                      http://www.springframework.org/schema/websocket
+                                 http://www.springframework.org/schema/websocket/spring-websocket.xsd">
+
+    <!--
+       Searches for beans in packages (instead of XML configuration we can use
+       in this way annotations like @Service, @Endpoint, etc, etc)
+    -->
+    <context:component-scan base-package="de.spring.stomp"/>
+
+
+    <bean class="org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean">
+        <property name="maxTextMessageBufferSize" value="8192"/>
+        <property name="maxBinaryMessageBufferSize" value="8192"/>
+    </bean>
+    
+    <!--
+       Note that even though the STOMP CONNECT frame has "login" and "passcode" headers that can be used for
+       authentication, Spring’s STOMP WebSocket support ignores them and currently expects users to have been
+       authenticated already via HTTP.
+       
+       In some cases it may be useful to assign an identity to a WebSocket session even when the user has not
+       been formally authenticated. For example, a mobile app might assign some identity to anonymous users,
+       perhaps based on geographical location. The do that currently, an application can sub-class DefaultHandshakeHandler
+       and override the determineUser method. The custom handshake handler can then be plugged in
+       (see examples in Section 25.2.4, “Deployment Considerations”).
+    -->
+    <bean id="customHandshakeHandler" class="de.spring.stomp.handlers.CustomHandshakeHandler"/>
+    
+    <!-- Interceptors -->
+    <bean id="customChannelInterceptor" class="de.spring.stomp.interceptors.CustomChannelInterceptor"/>
+    <bean id="customHttpHandshakeInterceptor" class="de.spring.stomp.interceptors.CustomHttpHandshakeInterceptor"/>
+    
+    <!-- Listeners -->
+    <bean id="brokerAvailabilityListener" class="de.spring.stomp.listeners.BrokerAvailabilityListener"/>
+    <bean id="sessionConnectedListener" class="de.spring.stomp.listeners.SessionConnectedListener"/>
+    <bean id="sessionConnectListener" class="de.spring.stomp.listeners.SessionConnectListener"/>
+    <bean id="sessionDisconnectListener" class="de.spring.stomp.listeners.SessionDisconnectListener"/>    
+    <bean id="sessionSubscribeListener" class="de.spring.stomp.listeners.SessionSubscribeListener"/>    
+    <bean id="sessionUnsubscribeListener" class="de.spring.stomp.listeners.SessionUnsubscribeListener"/>
+        
+    <!-- STOMP -->
+    <!-- Full-featured broker -->
+    <websocket:message-broker application-destination-prefix="/app">
+       <websocket:transport send-timeout="15000" send-buffer-size="524288" message-size="131072" />
+        <websocket:stomp-endpoint path="/fullportfolio" allowed-origins="*">
+               <websocket:handshake-handler ref="customHandshakeHandler" />
+               <websocket:handshake-interceptors>
+               <ref bean="customHttpHandshakeInterceptor"/>
+               </websocket:handshake-interceptors>
+            <websocket:sockjs/>
+        </websocket:stomp-endpoint>
+        <!--
+               Full-featured broker
+        -->
+        <websocket:stomp-broker-relay prefix="/topic, /queue"
+        relay-host="localhost" relay-port="61612" auto-startup="true"
+        heartbeat-send-interval="20000" heartbeat-receive-interval="20000" />
+        <!--
+        <websocket:stomp-broker-relay prefix="/topic, /queue"
+        client-login="" system-login="" client-passcode=""  system-passcode=""
+        virtual-host=""/>
+        -->
+        
+        <websocket:client-inbound-channel>
+                       <websocket:executor core-pool-size="100" max-pool-size="200" keep-alive-seconds="600"/>
+                       <websocket:interceptors>
+                               <ref bean="customChannelInterceptor"/>
+                       </websocket:interceptors>
+               </websocket:client-inbound-channel>
+               <websocket:client-outbound-channel>
+                       <websocket:executor core-pool-size="101" max-pool-size="201" keep-alive-seconds="601"/>
+                       <websocket:interceptors>
+                               <ref bean="customChannelInterceptor"/>
+                       </websocket:interceptors>
+               </websocket:client-outbound-channel>
+    </websocket:message-broker>
+
+</beans>
diff --git a/SpringJava/STOMP/spring-stomp-server-full/src/main/webapp/WEB-INF/web.xml b/SpringJava/STOMP/spring-stomp-server-full/src/main/webapp/WEB-INF/web.xml
new file mode 100644 (file)
index 0000000..45d6ebc
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+         version="2.4">
+
+    <display-name>Spring STOMP: example full featured broker</display-name>
+
+    <listener>
+        <listener-class>
+            org.springframework.web.context.ContextLoaderListener
+        </listener-class>
+    </listener>
+
+    <context-param>
+        <param-name>spring.profiles.default</param-name>
+        <param-value>${environment.profile}</param-value>
+        <param-name>contextConfigLocation</param-name>
+        <param-value>
+            classpath*:spring-configuration/*.xml
+        </param-value>
+    </context-param>
+    
+    <!-- Spring REST support -->
+    <servlet>
+        <servlet-name>spring-rest</servlet-name>
+        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
+        <load-on-startup>1</load-on-startup>
+        <async-supported>true</async-supported>
+        <init-param>
+           <param-name>contextConfigLocation</param-name>
+           <param-value>classpath*:spring-configuration/mvc/rest/*.xml</param-value>
+        </init-param>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>spring-rest</servlet-name>
+        <!-- REQUIRED PATTERN BY swagger-ui. IT DOESN'T WORK WITH ANY OTHER o.O -->
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+
+</web-app>
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/pom.xml b/SpringJava/STOMP/spring-stomp-server-simple/pom.xml
new file mode 100644 (file)
index 0000000..3a78248
--- /dev/null
@@ -0,0 +1,121 @@
+<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/maven-v4_0_0.xsd">
+
+       <modelVersion>4.0.0</modelVersion>
+
+       <parent>
+               <groupId>de.spring.stomp</groupId>
+               <artifactId>spring-stomp-bom</artifactId>
+               <version>1.0-SNAPSHOT</version>
+       </parent>
+
+       <artifactId>spring-stomp-server-simple</artifactId>
+       <packaging>war</packaging>
+       <name>SPRING STOMP SERVER. SIMPLE BROKER.</name>
+       <url>https://gumartinm.name</url>
+       <description>
+        STOMP with Spring Framework. Simple broker.
+    </description>
+       <organization>
+               <name>Gustavo Martin Morcuende</name>
+               <url>https://www.gumartinm.name</url>
+       </organization>
+       <scm>
+               <developerConnection>scm:git:http://git.gumartinm.name/JavaForFun</developerConnection>
+               <url>https://git.gumartinm.name/JavaForFun</url>
+       </scm>
+
+
+       <dependencies>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>spring-context</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>spring-webmvc</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>spring-oxm</artifactId>
+               </dependency>
+
+               <!-- Required for WebSockets -->
+               <dependency>
+               <groupId>org.springframework</groupId>
+               <artifactId>spring-websocket</artifactId>
+       </dependency>
+       
+       <!--  Required for STOMP -->
+               <dependency>
+               <groupId>org.springframework</groupId>
+               <artifactId>spring-messaging</artifactId>
+       </dependency>
+
+               <!-- Required by spring-webmvc -->
+               <dependency>
+                       <groupId>javax.servlet</groupId>
+                       <artifactId>javax.servlet-api</artifactId>
+                       <scope>provided</scope>
+               </dependency>
+
+               <!--
+                       Jackson JSON Processor, required by spring-webmvc. See messageConverters
+                       in rest-config.xml
+               -->
+               <dependency>
+                       <groupId>com.fasterxml.jackson.core</groupId>
+                       <artifactId>jackson-databind</artifactId>
+               </dependency>
+
+
+               <!--
+                       Required by spring-context for using JSR-303. See LocalValidatorFactoryBean
+                       in rest-config.xml
+               -->
+               <dependency>
+                       <groupId>javax.validation</groupId>
+                       <artifactId>validation-api</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.hibernate</groupId>
+                       <artifactId>hibernate-validator</artifactId>
+               </dependency>
+               
+       </dependencies>
+       <build>
+               <finalName>${project.artifactId}</finalName>
+               <resources>
+                       <resource>
+                               <directory>${basedir}/src/main/webapp</directory>
+                               <excludes>
+                                       <exclude>**/*.*</exclude>
+                               </excludes>
+                       </resource>
+                       <resource>
+                               <directory>${basedir}/src/main/resources/</directory>
+                               <includes>
+                                       <include>**/*.*</include>
+                               </includes>
+                       </resource>
+               </resources>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-war-plugin</artifactId>
+                               <version>2.6</version>
+                               <configuration>
+                                       <webResources>
+                                               <resource>
+                                                       <filtering>true</filtering>
+                                                       <directory>src/main/webapp</directory>
+                                                       <includes>
+                                                               <include>WEB-INF/web.xml</include>
+                                                       </includes>
+                                               </resource>
+                                       </webResources>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </build>
+</project>
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/controllers/MessageGreetingController.java b/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/controllers/MessageGreetingController.java
new file mode 100644 (file)
index 0000000..982b6ff
--- /dev/null
@@ -0,0 +1,26 @@
+package de.spring.stomp.controllers;
+
+import java.time.LocalDateTime;
+
+import org.springframework.messaging.handler.annotation.MessageMapping;
+import org.springframework.messaging.handler.annotation.SendTo;
+import org.springframework.stereotype.Controller;
+
+@Controller
+public class MessageGreetingController {
+
+       // Sending data to /app/greeting from STOMP client (client must first connect to endpoint, in my case portfolio)
+       // connecting to this URL -> http://172.17.0.3/spring-stomp-server/portfolio
+       // sending data to /app/greeting
+       
+       // The data sent to /app/greeting will be retrieved by this method.
+       @MessageMapping("/greeting")
+       @SendTo("/topic/greeting")
+       public String handle(String greeting) {
+               // STOMP clients subscribed to /topic/greeting will receive the returned data from this method.
+               // Destination is selected based on a convention but can be overridden via @SendTo
+               // I will be using @SendTo. In my case, it is not required (because it is the same as the destination selected
+               // based on the convention) but I will be using it just for fun.
+               return "[" + LocalDateTime.now() + "]: " + greeting;
+       }
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/controllers/UserMessageTradeController.java b/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/controllers/UserMessageTradeController.java
new file mode 100644 (file)
index 0000000..d98b36b
--- /dev/null
@@ -0,0 +1,19 @@
+package de.spring.stomp.controllers;
+
+import java.security.Principal;
+import java.time.LocalDateTime;
+
+import org.springframework.messaging.handler.annotation.MessageMapping;
+import org.springframework.messaging.simp.annotation.SendToUser;
+import org.springframework.stereotype.Controller;
+
+@Controller
+public class UserMessageTradeController {
+
+    @MessageMapping("/trade")
+    @SendToUser(destinations="/topic/position-updates", broadcast=false /* No idea what is this for */)
+    public String executeTrade(String trade, Principal principal) {
+
+       return "[" + LocalDateTime.now() + "]: " + trade;
+    }
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/handlers/CustomHandshakeHandler.java b/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/handlers/CustomHandshakeHandler.java
new file mode 100644 (file)
index 0000000..a633f75
--- /dev/null
@@ -0,0 +1,35 @@
+package de.spring.stomp.handlers;
+
+import java.security.Principal;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.web.socket.WebSocketHandler;
+import org.springframework.web.socket.server.support.DefaultHandshakeHandler;
+
+/**
+ * In some cases it may be useful to assign an identity to a WebSocket session even when
+ * the user has not been formally authenticated. For example, a mobile app might assign some
+ * identity to anonymous users, perhaps based on geographical location. The do that currently,
+ * an application can sub-class DefaultHandshakeHandler and override the determineUser method.
+ * The custom handshake handler can then be plugged in (see examples in
+ * Section 25.2.4, “Deployment Considerations”)
+ */
+public class CustomHandshakeHandler extends DefaultHandshakeHandler {
+       private static final Logger LOGGER = LoggerFactory.getLogger(CustomHandshakeHandler.class);
+
+       @Override
+       protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler,
+                       Map<String, Object> attributes) {
+
+               Principal principal = request.getPrincipal();
+               if (principal != null) {
+                       LOGGER.info("CustomHandshakeHandler: " + principal.getName());
+               }
+               
+               return super.determineUser(request, wsHandler, attributes);             
+       }
+
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/interceptors/CustomChannelInterceptor.java b/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/interceptors/CustomChannelInterceptor.java
new file mode 100644 (file)
index 0000000..7936bf8
--- /dev/null
@@ -0,0 +1,40 @@
+package de.spring.stomp.interceptors;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.messaging.Message;
+import org.springframework.messaging.MessageChannel;
+import org.springframework.messaging.simp.stomp.StompCommand;
+import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
+import org.springframework.messaging.support.ChannelInterceptorAdapter;
+
+public class CustomChannelInterceptor extends ChannelInterceptorAdapter {
+       private static final Logger LOGGER = LoggerFactory.getLogger(CustomChannelInterceptor.class);
+
+         @Override
+         public Message<?> preSend(Message<?> message, MessageChannel channel) {
+           StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
+           StompCommand command = accessor.getCommand();
+
+           LOGGER.info("CustomChannelInterceptor preSend, StompCommand: " + command);
+           LOGGER.info("CustomChannelInterceptor preSend, login: " + accessor.getLogin());
+           LOGGER.info("CustomChannelInterceptor preSend, heartBeat: " + accessor.getHeartbeat());
+           LOGGER.info("CustomChannelInterceptor preSend, destination: " + accessor.getDestination());
+           LOGGER.info("CustomChannelInterceptor preSend, host: " + accessor.getHost());
+           
+           return message;
+         }
+         
+         @Override
+         public void postSend(Message<?> message, MessageChannel channel, boolean sent) {
+           StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
+           StompCommand command = accessor.getCommand();
+
+           LOGGER.info("CustomChannelInterceptor postSend, StompCommand: " + command);
+           LOGGER.info("CustomChannelInterceptor postSend, login: " + accessor.getLogin());
+           LOGGER.info("CustomChannelInterceptor postSend, heartBeat: " + accessor.getHeartbeat());
+           LOGGER.info("CustomChannelInterceptor postSend, destination: " + accessor.getDestination());
+           LOGGER.info("CustomChannelInterceptor postSend, host: " + accessor.getHost());
+           
+         }
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/interceptors/CustomHttpHandshakeInterceptor.java b/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/interceptors/CustomHttpHandshakeInterceptor.java
new file mode 100644 (file)
index 0000000..784ab6a
--- /dev/null
@@ -0,0 +1,26 @@
+package de.spring.stomp.interceptors;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.web.socket.WebSocketHandler;
+import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
+
+public class CustomHttpHandshakeInterceptor extends HttpSessionHandshakeInterceptor {
+       private static final Logger LOGGER = LoggerFactory.getLogger(CustomHttpHandshakeInterceptor.class);
+
+
+       @Override
+       public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
+                       WebSocketHandler wsHandler, Exception ex) {
+               super.afterHandshake(request, response, wsHandler, ex);
+               
+               LOGGER.info("Request URI:" + request.getURI());
+               LOGGER.info("Request remote address:" + request.getRemoteAddress());
+               LOGGER.info("Request local address:" + request.getLocalAddress());
+               LOGGER.info("Request headers:" + request.getHeaders());
+               
+               LOGGER.info("Response headers:" + response.getHeaders());               
+       }
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/listeners/BrokerAvailabilityListener.java b/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/listeners/BrokerAvailabilityListener.java
new file mode 100644 (file)
index 0000000..b6e3619
--- /dev/null
@@ -0,0 +1,19 @@
+package de.spring.stomp.listeners;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationListener;
+import org.springframework.messaging.simp.broker.BrokerAvailabilityEvent;
+
+public class BrokerAvailabilityListener implements ApplicationListener<BrokerAvailabilityEvent> {
+       private static final Logger LOGGER = LoggerFactory.getLogger(BrokerAvailabilityListener.class);
+
+       @Override
+       public void onApplicationEvent(BrokerAvailabilityEvent event) {
+               
+               LOGGER.info("BrokerAvailabilityEvent timestamp: " + event.getTimestamp());
+               LOGGER.info("BrokerAvailabilityEvent brokerAvailable: " + event.isBrokerAvailable());
+               LOGGER.info("BrokerAvailabilityEvent: " + event.toString());
+       }
+
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/listeners/SessionConnectListener.java b/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/listeners/SessionConnectListener.java
new file mode 100644 (file)
index 0000000..da374e5
--- /dev/null
@@ -0,0 +1,18 @@
+package de.spring.stomp.listeners;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationListener;
+import org.springframework.web.socket.messaging.SessionConnectEvent;
+
+public class SessionConnectListener implements ApplicationListener<SessionConnectEvent> {
+       private static final Logger LOGGER = LoggerFactory.getLogger(SessionConnectListener.class);
+       
+       @Override
+       public void onApplicationEvent(SessionConnectEvent event) {
+               LOGGER.info("SessionConnectEvent timestamp: " + event.getTimestamp());
+               LOGGER.info("SessionConnectEvent user: " + event.getUser());
+               LOGGER.info("SessionConnectEvent: " + event.toString());
+       }
+
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/listeners/SessionConnectedListener.java b/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/listeners/SessionConnectedListener.java
new file mode 100644 (file)
index 0000000..b0444f3
--- /dev/null
@@ -0,0 +1,18 @@
+package de.spring.stomp.listeners;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationListener;
+import org.springframework.web.socket.messaging.SessionConnectedEvent;
+
+public class SessionConnectedListener implements ApplicationListener<SessionConnectedEvent> {
+       private static final Logger LOGGER = LoggerFactory.getLogger(SessionConnectedListener.class);
+
+       @Override
+       public void onApplicationEvent(SessionConnectedEvent event) {
+               LOGGER.info("SessionConnectedEvent timestamp: " + event.getTimestamp());
+               LOGGER.info("SessionConnectedEvent user: " + event.getUser());
+               LOGGER.info("SessionConnectedEvent: " + event.toString());
+       }
+
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/listeners/SessionDisconnectListener.java b/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/listeners/SessionDisconnectListener.java
new file mode 100644 (file)
index 0000000..59ff3e4
--- /dev/null
@@ -0,0 +1,20 @@
+package de.spring.stomp.listeners;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationListener;
+import org.springframework.web.socket.messaging.SessionDisconnectEvent;
+
+public class SessionDisconnectListener implements ApplicationListener<SessionDisconnectEvent> {
+       private static final Logger LOGGER = LoggerFactory.getLogger(SessionUnsubscribeListener.class);
+
+       @Override
+       public void onApplicationEvent(SessionDisconnectEvent event) {
+               LOGGER.info("SessionDisconnectEvent timestamp: " + event.getTimestamp());
+               LOGGER.info("SessionDisconnectEvent user: " + event.getUser());
+               LOGGER.info("SessionDisconnectEvent sessionId: " + event.getSessionId());
+               LOGGER.info("SessionDisconnectEvent close status: " + event.getCloseStatus());
+               LOGGER.info("SessionDisconnectEvent: " + event.toString());
+       }
+
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/listeners/SessionSubscribeListener.java b/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/listeners/SessionSubscribeListener.java
new file mode 100644 (file)
index 0000000..90ee1da
--- /dev/null
@@ -0,0 +1,18 @@
+package de.spring.stomp.listeners;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationListener;
+import org.springframework.web.socket.messaging.SessionSubscribeEvent;
+
+public class SessionSubscribeListener implements ApplicationListener<SessionSubscribeEvent> {
+       private static final Logger LOGGER = LoggerFactory.getLogger(SessionSubscribeListener.class);
+
+       @Override
+       public void onApplicationEvent(SessionSubscribeEvent event) {
+               LOGGER.info("SessionSubscribeEvent timestamp: " + event.getTimestamp());
+               LOGGER.info("SessionSubscribeEvent user: " + event.getUser());
+               LOGGER.info("SessionSubscribeEvent: " + event.toString());
+       }
+
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/listeners/SessionUnsubscribeListener.java b/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/listeners/SessionUnsubscribeListener.java
new file mode 100644 (file)
index 0000000..142bde9
--- /dev/null
@@ -0,0 +1,18 @@
+package de.spring.stomp.listeners;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationListener;
+import org.springframework.web.socket.messaging.SessionUnsubscribeEvent;
+
+public class SessionUnsubscribeListener implements ApplicationListener<SessionUnsubscribeEvent> {
+       private static final Logger LOGGER = LoggerFactory.getLogger(SessionUnsubscribeListener.class);
+
+       @Override
+       public void onApplicationEvent(SessionUnsubscribeEvent event) {
+               LOGGER.info("SessionUnsubscribeEvent timestamp: " + event.getTimestamp());
+               LOGGER.info("SessionUnsubscribeEvent user: " + event.getUser());
+               LOGGER.info("SessionUnsubscribeEvent: " + event.toString());
+       }
+
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/services/RestGreetingService.java b/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/services/RestGreetingService.java
new file mode 100644 (file)
index 0000000..69db326
--- /dev/null
@@ -0,0 +1,6 @@
+package de.spring.stomp.services;
+
+public interface RestGreetingService {
+
+       void doGreetings(String greeting);
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/services/UserTradeService.java b/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/services/UserTradeService.java
new file mode 100644 (file)
index 0000000..1d6bc34
--- /dev/null
@@ -0,0 +1,6 @@
+package de.spring.stomp.services;
+
+public interface UserTradeService {
+
+       void doTrade(String user);
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/services/impl/RestGreetingServiceImpl.java b/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/services/impl/RestGreetingServiceImpl.java
new file mode 100644 (file)
index 0000000..b518e76
--- /dev/null
@@ -0,0 +1,43 @@
+package de.spring.stomp.services.impl;
+
+import java.time.LocalDateTime;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationListener;
+import org.springframework.messaging.simp.SimpMessagingTemplate;
+import org.springframework.messaging.simp.broker.BrokerAvailabilityEvent;
+import org.springframework.stereotype.Service;
+
+import de.spring.stomp.services.RestGreetingService;
+
+@Service("restGreetingService")
+public class RestGreetingServiceImpl
+               implements RestGreetingService, ApplicationListener<BrokerAvailabilityEvent> {
+       private final SimpMessagingTemplate template;
+       
+       private volatile boolean isBrokerAvailable = true;
+
+    @Autowired
+    public RestGreetingServiceImpl(SimpMessagingTemplate template) {
+        this.template = template;
+    }
+
+       @Override
+       public void doGreetings(String greeting) {
+               String text = "[" + LocalDateTime.now() + "]:" + greeting;
+               
+               if (isBrokerAvailable) {
+                       // STOMP clients subscribed to /topic/greeting will receive the data sent by the convertAndSend method.
+                       template.convertAndSend("/topic/greeting", text);
+               }
+       }
+
+       @Override
+       public void onApplicationEvent(BrokerAvailabilityEvent event) {
+               // Components using the SimpMessagingTemplate should subscribe to this event
+               // and avoid sending messages at times when the broker is not available.
+               // In any case they should be prepared to handle MessageDeliveryException
+               // when sending a message.
+               isBrokerAvailable = event.isBrokerAvailable();
+       }
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/services/impl/UserTradeServiceImpl.java b/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/stomp/services/impl/UserTradeServiceImpl.java
new file mode 100644 (file)
index 0000000..e0d63e2
--- /dev/null
@@ -0,0 +1,44 @@
+package de.spring.stomp.services.impl;
+
+import java.time.LocalDateTime;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationListener;
+import org.springframework.messaging.simp.SimpMessagingTemplate;
+import org.springframework.messaging.simp.broker.BrokerAvailabilityEvent;
+import org.springframework.stereotype.Service;
+
+import de.spring.stomp.services.UserTradeService;
+
+@Service("userTradeService")
+public class UserTradeServiceImpl
+               implements UserTradeService, ApplicationListener<BrokerAvailabilityEvent> {
+       private final SimpMessagingTemplate template;
+       
+       private volatile boolean isBrokerAvailable = true;
+
+    @Autowired
+    public UserTradeServiceImpl(SimpMessagingTemplate template) {
+        this.template = template;
+    }
+    
+       @Override
+       public void doTrade(String user) {
+               String text = "[" + LocalDateTime.now() + "]:" + user;
+               
+               if (isBrokerAvailable) {
+                       // STOMP clients subscribed to /topic/position-updates will receive the data sent by the convertAndSend method.
+                       template.convertAndSendToUser(user, "/topic/position-updates", text);
+               }
+       }
+
+       @Override
+       public void onApplicationEvent(BrokerAvailabilityEvent event) {
+               // Components using the SimpMessagingTemplate should subscribe to this event
+               // and avoid sending messages at times when the broker is not available.
+               // In any case they should be prepared to handle MessageDeliveryException
+               // when sending a message.
+               isBrokerAvailable = event.isBrokerAvailable();
+       }
+
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/webservices/rest/controller/RestGreetingController.java b/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/webservices/rest/controller/RestGreetingController.java
new file mode 100644 (file)
index 0000000..ebb32ed
--- /dev/null
@@ -0,0 +1,31 @@
+package de.spring.webservices.rest.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import de.spring.stomp.services.RestGreetingService;
+
+
+@RestController
+public class RestGreetingController {
+       private final RestGreetingService restGreetingService;
+
+    @Autowired
+    public RestGreetingController(RestGreetingService restGreetingService) {
+        this.restGreetingService = restGreetingService;
+    }
+
+    // Sending data to /topic/greeting from REST service.
+       // POST http://localhost:8080/spring-stomp-server/greetings
+    
+       @RequestMapping(path="/greetings", method=RequestMethod.POST)
+    public void handle(@RequestBody String greeting) {
+               
+               // STOMP clients subscribed to /topic/greeting will receive the data sent by the convertAndSend method.
+               restGreetingService.doGreetings(greeting);
+    }
+
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/webservices/rest/controller/UserTradeController.java b/SpringJava/STOMP/spring-stomp-server-simple/src/main/java/de/spring/webservices/rest/controller/UserTradeController.java
new file mode 100644 (file)
index 0000000..718a8bd
--- /dev/null
@@ -0,0 +1,27 @@
+package de.spring.webservices.rest.controller;
+
+import java.time.LocalDateTime;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import de.spring.stomp.services.UserTradeService;
+
+public class UserTradeController {
+       private final UserTradeService userTradeService;
+
+    @Autowired
+    public UserTradeController(UserTradeService userTradeService) {
+        this.userTradeService = userTradeService;
+    }
+
+    // Sending data to /topic/greeting from REST service.
+       // POST http://localhost:8080/spring-stomp-server/trade
+    
+       @RequestMapping(path="/trade", method=RequestMethod.POST)
+    public void handle(@RequestBody String user) {
+               userTradeService.doTrade(user);
+    }
+}
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/resources/log4j2.xml b/SpringJava/STOMP/spring-stomp-server-simple/src/main/resources/log4j2.xml
new file mode 100644 (file)
index 0000000..281da4f
--- /dev/null
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- 
+       status: The level of internal Log4j events that should be logged to the console.
+       Valid values for this attribute are "trace", "debug", "info", "warn", "error" and "fatal".
+       
+       monitorInterval: The minimum amount of time, in seconds, that must elapse before the file configuration is checked for changes.
+       
+       
+       see https://logging.apache.org/log4j/2.x/manual/configuration.html
+ -->
+<Configuration status="error" strict="true" monitorInterval="30"
+                name="XMLConfigTest" packages="org.apache.logging.log4j.test">
+                
+       <!--
+               ALL > TRACE > DEBUG > INFO > WARN > ERROR > OFF
+               
+               ERROR by default.
+       -->
+                
+    <Appenders>
+        <Appender type="Console" name="STDOUT">
+            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
+        </Appender>
+    </Appenders>
+    <Loggers>
+    
+        <!-- 
+               SockJS client disconnects. Requires TRACE level always.
+               It works because I know for sure I will be using WebSockets when using SockJS.
+        -->
+        <Logger
+               name="org.springframework.web.socket.sockjs.transport.session.WebSocketServerSockJsSession"
+                       level="TRACE" additivity="false">
+            <AppenderRef ref="STDOUT" />
+        </Logger>
+    
+               <!-- 
+               General logging Spring.
+        -->
+        <Logger name="org.springframework" level="INFO" additivity="false">
+            <AppenderRef ref="STDOUT" />
+        </Logger>
+    
+
+               <!-- 
+                       Anything else will be using TRACE logging level.
+                -->        
+        <Root level="INFO">
+            <AppenderRef ref="STDOUT"/>
+        </Root>
+    </Loggers>
+</Configuration>
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/resources/spring-configuration/mvc/rest/rest-config.xml b/SpringJava/STOMP/spring-stomp-server-simple/src/main/resources/spring-configuration/mvc/rest/rest-config.xml
new file mode 100644 (file)
index 0000000..5ce72ef
--- /dev/null
@@ -0,0 +1,93 @@
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:mvc="http://www.springframework.org/schema/mvc"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xmlns:p="http://www.springframework.org/schema/p"
+       xsi:schemaLocation="
+               http://www.springframework.org/schema/beans
+               http://www.springframework.org/schema/beans/spring-beans.xsd
+        http://www.springframework.org/schema/mvc
+        http://www.springframework.org/schema/mvc/spring-mvc.xsd
+        http://www.springframework.org/schema/context
+        http://www.springframework.org/schema/context/spring-context.xsd
+        http://www.springframework.org/schema/util
+        http://www.springframework.org/schema/util/spring-util.xsd">
+   
+       <!--
+               I am declaring my beans without the automatic annotation. :/
+               Better because we are saving memory but it requires more configuration.
+               
+               See: org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser
+               <mvc:annotation-driven/>
+        -->
+        
+   
+       <context:annotation-config />
+   
+       <context:component-scan base-package="de.spring.webservices.rest"/>
+       
+       <!--
+               Required beans for generating XML responses from Java objects using JAXB annotations
+               Jackson also works but it doesn't generate XML with namespaces... O.o
+               
+               This implementation will be slower than the one using Jackson :( but I am going to use it just for WADL generation :)
+       -->    
+    <bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
+        <property name="packagesToScan" value="org.jvnet.ws.wadl"/>
+    </bean>
+       <bean id="jaxbConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
+       <constructor-arg ref="jaxbMarshaller" />
+       </bean>
+    
+       <!-- Required beans for generating JSON responses from Java objects -->
+    <bean id="jsonObjectMapperFactory" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
+       p:indentOutput="true" p:failOnEmptyBeans="false">
+        <property name="featuresToDisable">
+            <array>
+                <util:constant static-field="com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES"/>
+                <util:constant static-field="com.fasterxml.jackson.databind.MapperFeature.DEFAULT_VIEW_INCLUSION"/>
+            </array>
+        </property>
+    </bean>
+    
+    <util:list id="messageConverters">
+        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" p:objectMapper-ref="jsonObjectMapperFactory"/>
+               <ref bean="jaxbConverter" />
+        <bean class="org.springframework.http.converter.StringHttpMessageConverter" />
+    </util:list>
+
+
+       <bean name="handlerAdapter"
+               class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
+               <property name="webBindingInitializer">
+                       <bean
+                               class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
+                               <!-- It enables us to use JSR-303 -->
+                               <property name="validator">
+                                       <bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
+                               </property>
+                       </bean>
+               </property>
+               <property name="messageConverters" ref="messageConverters" />
+               
+               
+               <property name="requestBodyAdvice">
+                       <util:list>
+                               <bean id="requestBodyAdvice" class="org.springframework.web.servlet.mvc.method.annotation.JsonViewRequestBodyAdvice"/>
+                       </util:list>
+               </property>
+               
+               
+               <property name="responseBodyAdvice">
+                       <util:list>
+                               <bean id="responseBodyAdvice" class="org.springframework.web.servlet.mvc.method.annotation.JsonViewResponseBodyAdvice"/>
+                       </util:list>
+               </property>
+       </bean>
+    
+       <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
+
+       <mvc:default-servlet-handler />
+       
+</beans>
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/resources/spring-configuration/spring-configuration.xml b/SpringJava/STOMP/spring-stomp-server-simple/src/main/resources/spring-configuration/spring-configuration.xml
new file mode 100644 (file)
index 0000000..8c036bc
--- /dev/null
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xmlns:context="http://www.springframework.org/schema/context"
+  xmlns:websocket="http://www.springframework.org/schema/websocket"
+
+  xsi:schemaLocation="http://www.springframework.org/schema/beans 
+                      http://www.springframework.org/schema/beans/spring-beans.xsd
+                      http://www.springframework.org/schema/context 
+                      http://www.springframework.org/schema/context/spring-context.xsd
+                      http://www.springframework.org/schema/websocket
+                                 http://www.springframework.org/schema/websocket/spring-websocket.xsd">
+
+    <!--
+       Searches for beans in packages (instead of XML configuration we can use
+       in this way annotations like @Service, @Endpoint, etc, etc)
+    -->
+    <context:component-scan base-package="de.spring.stomp"/>
+
+
+    <bean class="org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean">
+        <property name="maxTextMessageBufferSize" value="8192"/>
+        <property name="maxBinaryMessageBufferSize" value="8192"/>
+    </bean>
+    
+    <!--
+       Note that even though the STOMP CONNECT frame has "login" and "passcode" headers that can be used for
+       authentication, Spring’s STOMP WebSocket support ignores them and currently expects users to have been
+       authenticated already via HTTP.
+       
+       In some cases it may be useful to assign an identity to a WebSocket session even when the user has not
+       been formally authenticated. For example, a mobile app might assign some identity to anonymous users,
+       perhaps based on geographical location. The do that currently, an application can sub-class DefaultHandshakeHandler
+       and override the determineUser method. The custom handshake handler can then be plugged in
+       (see examples in Section 25.2.4, “Deployment Considerations”).
+    -->
+    <bean id="customHandshakeHandler" class="de.spring.stomp.handlers.CustomHandshakeHandler"/>
+    
+    <!-- Interceptors -->
+    <bean id="customChannelInterceptor" class="de.spring.stomp.interceptors.CustomChannelInterceptor"/>
+    <bean id="customHttpHandshakeInterceptor" class="de.spring.stomp.interceptors.CustomHttpHandshakeInterceptor"/>
+    
+    <!-- Listeners -->
+    <bean id="brokerAvailabilityListener" class="de.spring.stomp.listeners.BrokerAvailabilityListener"/>
+    <bean id="sessionConnectedListener" class="de.spring.stomp.listeners.SessionConnectedListener"/>
+    <bean id="sessionConnectListener" class="de.spring.stomp.listeners.SessionConnectListener"/>
+    <bean id="sessionDisconnectListener" class="de.spring.stomp.listeners.SessionDisconnectListener"/>    
+    <bean id="sessionSubscribeListener" class="de.spring.stomp.listeners.SessionSubscribeListener"/>    
+    <bean id="sessionUnsubscribeListener" class="de.spring.stomp.listeners.SessionUnsubscribeListener"/>
+        
+    <!-- Scheduler --> 
+    <bean id="simpleBrokerScheduler" class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler" />   
+     
+    <!-- STOMP -->
+    <!-- Simple broker -->
+    <websocket:message-broker application-destination-prefix="/app">
+       <websocket:transport send-timeout="15000" send-buffer-size="524288" message-size="131072" />
+        <websocket:stomp-endpoint path="/portfolio" allowed-origins="*">
+            <websocket:handshake-handler ref="customHandshakeHandler" />
+               <websocket:handshake-interceptors>
+               <ref bean="customHttpHandshakeInterceptor"/>
+               </websocket:handshake-interceptors>
+               <websocket:sockjs/>    
+        </websocket:stomp-endpoint>
+        <!--
+               In memory broker.
+
+               hearbeat: Configure the value for the heartbeat settings. The first number represents how often the server will
+                       write or send a heartbeat. The second is how often the client should write. 0 means no heartbeats.
+                       By default this is set to "0, 0" unless the scheduler attribute is also set in which case the
+                       default becomes "10000,10000" (in milliseconds).
+                       
+                       Matching the value used by client.
+        -->
+        <websocket:simple-broker prefix="/topic, /queue"
+               scheduler="simpleBrokerScheduler" heartbeat="0,20000" />
+        
+        <websocket:client-inbound-channel>
+                       <websocket:executor core-pool-size="100" max-pool-size="200" keep-alive-seconds="600"/>
+                       <websocket:interceptors>
+                               <ref bean="customChannelInterceptor"/>
+                       </websocket:interceptors>
+               </websocket:client-inbound-channel>
+               <websocket:client-outbound-channel>
+                       <websocket:executor core-pool-size="101" max-pool-size="201" keep-alive-seconds="601"/>
+                       <websocket:interceptors>
+                               <ref bean="customChannelInterceptor"/>
+                       </websocket:interceptors>
+               </websocket:client-outbound-channel>
+    </websocket:message-broker>
+    
+</beans>
diff --git a/SpringJava/STOMP/spring-stomp-server-simple/src/main/webapp/WEB-INF/web.xml b/SpringJava/STOMP/spring-stomp-server-simple/src/main/webapp/WEB-INF/web.xml
new file mode 100644 (file)
index 0000000..4ed5845
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+         version="2.4">
+
+    <display-name>Spring STOMP: example simple broker</display-name>
+
+    <listener>
+        <listener-class>
+            org.springframework.web.context.ContextLoaderListener
+        </listener-class>
+    </listener>
+
+    <context-param>
+        <param-name>spring.profiles.default</param-name>
+        <param-value>${environment.profile}</param-value>
+        <param-name>contextConfigLocation</param-name>
+        <param-value>
+            classpath*:spring-configuration/*.xml
+        </param-value>
+    </context-param>
+    
+    <!-- Spring REST support -->
+    <servlet>
+        <servlet-name>spring-rest</servlet-name>
+        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
+        <load-on-startup>1</load-on-startup>
+        <async-supported>true</async-supported>
+        <init-param>
+           <param-name>contextConfigLocation</param-name>
+           <param-value>classpath*:spring-configuration/mvc/rest/*.xml</param-value>
+        </init-param>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>spring-rest</servlet-name>
+        <!-- REQUIRED PATTERN BY swagger-ui. IT DOESN'T WORK WITH ANY OTHER o.O -->
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+
+</web-app>
diff --git a/SpringJava/STOMP/spring-stomp-server/pom.xml b/SpringJava/STOMP/spring-stomp-server/pom.xml
deleted file mode 100644 (file)
index 55274b2..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-<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/maven-v4_0_0.xsd">
-       <modelVersion>4.0.0</modelVersion>
-       <parent>
-               <groupId>de.spring.stomp</groupId>
-               <artifactId>spring-stomp</artifactId>
-               <version>1.0-SNAPSHOT</version>
-       </parent>
-
-       <artifactId>spring-stomp-server</artifactId>
-       <packaging>war</packaging>
-       <name>spring-stomp-server</name>
-       <url>http://gumartinm.name</url>
-       <description>STOMP with Spring Framework.</description>
-       <organization>
-               <name>Gustavo Martin Morcuende</name>
-               <url>http://www.gumartinm.name</url>
-       </organization>
-       <scm>
-               <developerConnection>scm:git:http://git.gumartinm.name/JavaForFun</developerConnection>
-               <url>http://git.gumartinm.name/JavaForFun</url>
-       </scm>
-
-
-       <dependencies>
-               <dependency>
-                       <groupId>org.springframework</groupId>
-                       <artifactId>spring-context</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.springframework</groupId>
-                       <artifactId>spring-webmvc</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.springframework</groupId>
-                       <artifactId>spring-oxm</artifactId>
-               </dependency>
-
-               <!-- Required for WebSockets -->
-               <dependency>
-               <groupId>org.springframework</groupId>
-               <artifactId>spring-websocket</artifactId>
-       </dependency>
-       
-       <!--  Required for STOMP -->
-               <dependency>
-               <groupId>org.springframework</groupId>
-               <artifactId>spring-messaging</artifactId>
-       </dependency>
-
-               <!-- Required by spring-webmvc -->
-               <dependency>
-                       <groupId>javax.servlet</groupId>
-                       <artifactId>javax.servlet-api</artifactId>
-                       <scope>provided</scope>
-               </dependency>
-
-               <!--
-                       Jackson JSON Processor, required by spring-webmvc. See messageConverters
-                       in rest-config.xml
-               -->
-               <dependency>
-                       <groupId>com.fasterxml.jackson.core</groupId>
-                       <artifactId>jackson-databind</artifactId>
-               </dependency>
-
-
-               <!--
-                       Required by spring-context for using JSR-303. See LocalValidatorFactoryBean
-                       in rest-config.xml
-               -->
-               <dependency>
-                       <groupId>javax.validation</groupId>
-                       <artifactId>validation-api</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.hibernate</groupId>
-                       <artifactId>hibernate-validator</artifactId>
-               </dependency>
-               
-               
-               <!-- Full-featured broker, TCP connection management. -->
-               <dependency>
-                   <groupId>org.projectreactor</groupId>
-                   <artifactId>reactor-net</artifactId>
-                   <version>1.1.6.RELEASE</version>
-               </dependency>
-
-       </dependencies>
-       <build>
-               <finalName>${project.artifactId}</finalName>
-               <resources>
-                       <resource>
-                               <directory>${basedir}/src/main/webapp</directory>
-                               <excludes>
-                                       <exclude>**/*.*</exclude>
-                               </excludes>
-                       </resource>
-                       <resource>
-                               <directory>${basedir}/src/main/resources/</directory>
-                               <includes>
-                                       <include>**/*.*</include>
-                               </includes>
-                       </resource>
-               </resources>
-               <plugins>
-                       <plugin>
-                               <groupId>org.apache.maven.plugins</groupId>
-                               <artifactId>maven-war-plugin</artifactId>
-                               <version>2.6</version>
-                               <configuration>
-                                       <webResources>
-                                               <resource>
-                                                       <filtering>true</filtering>
-                                                       <directory>src/main/webapp</directory>
-                                                       <includes>
-                                                               <include>WEB-INF/web.xml</include>
-                                                       </includes>
-                                               </resource>
-                                       </webResources>
-                               </configuration>
-                       </plugin>
-               </plugins>
-       </build>
-</project>
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/controllers/MessageGreetingController.java b/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/controllers/MessageGreetingController.java
deleted file mode 100644 (file)
index 982b6ff..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package de.spring.stomp.controllers;
-
-import java.time.LocalDateTime;
-
-import org.springframework.messaging.handler.annotation.MessageMapping;
-import org.springframework.messaging.handler.annotation.SendTo;
-import org.springframework.stereotype.Controller;
-
-@Controller
-public class MessageGreetingController {
-
-       // Sending data to /app/greeting from STOMP client (client must first connect to endpoint, in my case portfolio)
-       // connecting to this URL -> http://172.17.0.3/spring-stomp-server/portfolio
-       // sending data to /app/greeting
-       
-       // The data sent to /app/greeting will be retrieved by this method.
-       @MessageMapping("/greeting")
-       @SendTo("/topic/greeting")
-       public String handle(String greeting) {
-               // STOMP clients subscribed to /topic/greeting will receive the returned data from this method.
-               // Destination is selected based on a convention but can be overridden via @SendTo
-               // I will be using @SendTo. In my case, it is not required (because it is the same as the destination selected
-               // based on the convention) but I will be using it just for fun.
-               return "[" + LocalDateTime.now() + "]: " + greeting;
-       }
-}
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/controllers/UserMessageTradeController.java b/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/controllers/UserMessageTradeController.java
deleted file mode 100644 (file)
index d98b36b..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-package de.spring.stomp.controllers;
-
-import java.security.Principal;
-import java.time.LocalDateTime;
-
-import org.springframework.messaging.handler.annotation.MessageMapping;
-import org.springframework.messaging.simp.annotation.SendToUser;
-import org.springframework.stereotype.Controller;
-
-@Controller
-public class UserMessageTradeController {
-
-    @MessageMapping("/trade")
-    @SendToUser(destinations="/topic/position-updates", broadcast=false /* No idea what is this for */)
-    public String executeTrade(String trade, Principal principal) {
-
-       return "[" + LocalDateTime.now() + "]: " + trade;
-    }
-}
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/handlers/CustomHandshakeHandler.java b/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/handlers/CustomHandshakeHandler.java
deleted file mode 100644 (file)
index 452c7f0..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-package de.spring.stomp.handlers;
-
-import java.security.Principal;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.http.server.ServerHttpRequest;
-import org.springframework.web.socket.WebSocketHandler;
-import org.springframework.web.socket.server.support.DefaultHandshakeHandler;
-
-/**
- * In some cases it may be useful to assign an identity to a WebSocket session even when
- * the user has not been formally authenticated. For example, a mobile app might assign some
- * identity to anonymous users, perhaps based on geographical location. The do that currently,
- * an application can sub-class DefaultHandshakeHandler and override the determineUser method.
- * The custom handshake handler can then be plugged in (see examples in
- * Section 25.2.4, “Deployment Considerations”)
- */
-public class CustomHandshakeHandler extends DefaultHandshakeHandler {
-       private static final Logger LOGGER = LoggerFactory.getLogger(CustomHandshakeHandler.class);
-
-       @Override
-       protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler,
-                       Map<String, Object> attributes) {
-
-               Principal principal = request.getPrincipal();
-               LOGGER.info("CustomHandshakeHandler: " + principal.getName());
-               
-               return super.determineUser(request, wsHandler, attributes);             
-       }
-
-}
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/interceptors/CustomChannelInterceptor.java b/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/interceptors/CustomChannelInterceptor.java
deleted file mode 100644 (file)
index 7936bf8..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-package de.spring.stomp.interceptors;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.messaging.Message;
-import org.springframework.messaging.MessageChannel;
-import org.springframework.messaging.simp.stomp.StompCommand;
-import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
-import org.springframework.messaging.support.ChannelInterceptorAdapter;
-
-public class CustomChannelInterceptor extends ChannelInterceptorAdapter {
-       private static final Logger LOGGER = LoggerFactory.getLogger(CustomChannelInterceptor.class);
-
-         @Override
-         public Message<?> preSend(Message<?> message, MessageChannel channel) {
-           StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
-           StompCommand command = accessor.getCommand();
-
-           LOGGER.info("CustomChannelInterceptor preSend, StompCommand: " + command);
-           LOGGER.info("CustomChannelInterceptor preSend, login: " + accessor.getLogin());
-           LOGGER.info("CustomChannelInterceptor preSend, heartBeat: " + accessor.getHeartbeat());
-           LOGGER.info("CustomChannelInterceptor preSend, destination: " + accessor.getDestination());
-           LOGGER.info("CustomChannelInterceptor preSend, host: " + accessor.getHost());
-           
-           return message;
-         }
-         
-         @Override
-         public void postSend(Message<?> message, MessageChannel channel, boolean sent) {
-           StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
-           StompCommand command = accessor.getCommand();
-
-           LOGGER.info("CustomChannelInterceptor postSend, StompCommand: " + command);
-           LOGGER.info("CustomChannelInterceptor postSend, login: " + accessor.getLogin());
-           LOGGER.info("CustomChannelInterceptor postSend, heartBeat: " + accessor.getHeartbeat());
-           LOGGER.info("CustomChannelInterceptor postSend, destination: " + accessor.getDestination());
-           LOGGER.info("CustomChannelInterceptor postSend, host: " + accessor.getHost());
-           
-         }
-}
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/interceptors/CustomHttpHandshakeInterceptor.java b/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/interceptors/CustomHttpHandshakeInterceptor.java
deleted file mode 100644 (file)
index 784ab6a..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package de.spring.stomp.interceptors;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.http.server.ServerHttpRequest;
-import org.springframework.http.server.ServerHttpResponse;
-import org.springframework.web.socket.WebSocketHandler;
-import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
-
-public class CustomHttpHandshakeInterceptor extends HttpSessionHandshakeInterceptor {
-       private static final Logger LOGGER = LoggerFactory.getLogger(CustomHttpHandshakeInterceptor.class);
-
-
-       @Override
-       public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
-                       WebSocketHandler wsHandler, Exception ex) {
-               super.afterHandshake(request, response, wsHandler, ex);
-               
-               LOGGER.info("Request URI:" + request.getURI());
-               LOGGER.info("Request remote address:" + request.getRemoteAddress());
-               LOGGER.info("Request local address:" + request.getLocalAddress());
-               LOGGER.info("Request headers:" + request.getHeaders());
-               
-               LOGGER.info("Response headers:" + response.getHeaders());               
-       }
-}
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/listeners/BrokerAvailabilityListener.java b/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/listeners/BrokerAvailabilityListener.java
deleted file mode 100644 (file)
index b6e3619..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-package de.spring.stomp.listeners;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.ApplicationListener;
-import org.springframework.messaging.simp.broker.BrokerAvailabilityEvent;
-
-public class BrokerAvailabilityListener implements ApplicationListener<BrokerAvailabilityEvent> {
-       private static final Logger LOGGER = LoggerFactory.getLogger(BrokerAvailabilityListener.class);
-
-       @Override
-       public void onApplicationEvent(BrokerAvailabilityEvent event) {
-               
-               LOGGER.info("BrokerAvailabilityEvent timestamp: " + event.getTimestamp());
-               LOGGER.info("BrokerAvailabilityEvent brokerAvailable: " + event.isBrokerAvailable());
-               LOGGER.info("BrokerAvailabilityEvent: " + event.toString());
-       }
-
-}
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/listeners/SessionConnectListener.java b/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/listeners/SessionConnectListener.java
deleted file mode 100644 (file)
index da374e5..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-package de.spring.stomp.listeners;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.ApplicationListener;
-import org.springframework.web.socket.messaging.SessionConnectEvent;
-
-public class SessionConnectListener implements ApplicationListener<SessionConnectEvent> {
-       private static final Logger LOGGER = LoggerFactory.getLogger(SessionConnectListener.class);
-       
-       @Override
-       public void onApplicationEvent(SessionConnectEvent event) {
-               LOGGER.info("SessionConnectEvent timestamp: " + event.getTimestamp());
-               LOGGER.info("SessionConnectEvent user: " + event.getUser());
-               LOGGER.info("SessionConnectEvent: " + event.toString());
-       }
-
-}
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/listeners/SessionConnectedListener.java b/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/listeners/SessionConnectedListener.java
deleted file mode 100644 (file)
index b0444f3..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-package de.spring.stomp.listeners;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.ApplicationListener;
-import org.springframework.web.socket.messaging.SessionConnectedEvent;
-
-public class SessionConnectedListener implements ApplicationListener<SessionConnectedEvent> {
-       private static final Logger LOGGER = LoggerFactory.getLogger(SessionConnectedListener.class);
-
-       @Override
-       public void onApplicationEvent(SessionConnectedEvent event) {
-               LOGGER.info("SessionConnectedEvent timestamp: " + event.getTimestamp());
-               LOGGER.info("SessionConnectedEvent user: " + event.getUser());
-               LOGGER.info("SessionConnectedEvent: " + event.toString());
-       }
-
-}
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/listeners/SessionDisconnectListener.java b/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/listeners/SessionDisconnectListener.java
deleted file mode 100644 (file)
index 59ff3e4..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-package de.spring.stomp.listeners;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.ApplicationListener;
-import org.springframework.web.socket.messaging.SessionDisconnectEvent;
-
-public class SessionDisconnectListener implements ApplicationListener<SessionDisconnectEvent> {
-       private static final Logger LOGGER = LoggerFactory.getLogger(SessionUnsubscribeListener.class);
-
-       @Override
-       public void onApplicationEvent(SessionDisconnectEvent event) {
-               LOGGER.info("SessionDisconnectEvent timestamp: " + event.getTimestamp());
-               LOGGER.info("SessionDisconnectEvent user: " + event.getUser());
-               LOGGER.info("SessionDisconnectEvent sessionId: " + event.getSessionId());
-               LOGGER.info("SessionDisconnectEvent close status: " + event.getCloseStatus());
-               LOGGER.info("SessionDisconnectEvent: " + event.toString());
-       }
-
-}
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/listeners/SessionSubscribeListener.java b/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/listeners/SessionSubscribeListener.java
deleted file mode 100644 (file)
index 90ee1da..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-package de.spring.stomp.listeners;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.ApplicationListener;
-import org.springframework.web.socket.messaging.SessionSubscribeEvent;
-
-public class SessionSubscribeListener implements ApplicationListener<SessionSubscribeEvent> {
-       private static final Logger LOGGER = LoggerFactory.getLogger(SessionSubscribeListener.class);
-
-       @Override
-       public void onApplicationEvent(SessionSubscribeEvent event) {
-               LOGGER.info("SessionSubscribeEvent timestamp: " + event.getTimestamp());
-               LOGGER.info("SessionSubscribeEvent user: " + event.getUser());
-               LOGGER.info("SessionSubscribeEvent: " + event.toString());
-       }
-
-}
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/listeners/SessionUnsubscribeListener.java b/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/listeners/SessionUnsubscribeListener.java
deleted file mode 100644 (file)
index 142bde9..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-package de.spring.stomp.listeners;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.ApplicationListener;
-import org.springframework.web.socket.messaging.SessionUnsubscribeEvent;
-
-public class SessionUnsubscribeListener implements ApplicationListener<SessionUnsubscribeEvent> {
-       private static final Logger LOGGER = LoggerFactory.getLogger(SessionUnsubscribeListener.class);
-
-       @Override
-       public void onApplicationEvent(SessionUnsubscribeEvent event) {
-               LOGGER.info("SessionUnsubscribeEvent timestamp: " + event.getTimestamp());
-               LOGGER.info("SessionUnsubscribeEvent user: " + event.getUser());
-               LOGGER.info("SessionUnsubscribeEvent: " + event.toString());
-       }
-
-}
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/services/RestGreetingService.java b/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/services/RestGreetingService.java
deleted file mode 100644 (file)
index 69db326..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-package de.spring.stomp.services;
-
-public interface RestGreetingService {
-
-       void doGreetings(String greeting);
-}
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/services/UserTradeService.java b/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/services/UserTradeService.java
deleted file mode 100644 (file)
index 1d6bc34..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-package de.spring.stomp.services;
-
-public interface UserTradeService {
-
-       void doTrade(String user);
-}
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/services/impl/RestGreetingServiceImpl.java b/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/services/impl/RestGreetingServiceImpl.java
deleted file mode 100644 (file)
index b518e76..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-package de.spring.stomp.services.impl;
-
-import java.time.LocalDateTime;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationListener;
-import org.springframework.messaging.simp.SimpMessagingTemplate;
-import org.springframework.messaging.simp.broker.BrokerAvailabilityEvent;
-import org.springframework.stereotype.Service;
-
-import de.spring.stomp.services.RestGreetingService;
-
-@Service("restGreetingService")
-public class RestGreetingServiceImpl
-               implements RestGreetingService, ApplicationListener<BrokerAvailabilityEvent> {
-       private final SimpMessagingTemplate template;
-       
-       private volatile boolean isBrokerAvailable = true;
-
-    @Autowired
-    public RestGreetingServiceImpl(SimpMessagingTemplate template) {
-        this.template = template;
-    }
-
-       @Override
-       public void doGreetings(String greeting) {
-               String text = "[" + LocalDateTime.now() + "]:" + greeting;
-               
-               if (isBrokerAvailable) {
-                       // STOMP clients subscribed to /topic/greeting will receive the data sent by the convertAndSend method.
-                       template.convertAndSend("/topic/greeting", text);
-               }
-       }
-
-       @Override
-       public void onApplicationEvent(BrokerAvailabilityEvent event) {
-               // Components using the SimpMessagingTemplate should subscribe to this event
-               // and avoid sending messages at times when the broker is not available.
-               // In any case they should be prepared to handle MessageDeliveryException
-               // when sending a message.
-               isBrokerAvailable = event.isBrokerAvailable();
-       }
-}
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/services/impl/UserTradeServiceImpl.java b/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/stomp/services/impl/UserTradeServiceImpl.java
deleted file mode 100644 (file)
index e0d63e2..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-package de.spring.stomp.services.impl;
-
-import java.time.LocalDateTime;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationListener;
-import org.springframework.messaging.simp.SimpMessagingTemplate;
-import org.springframework.messaging.simp.broker.BrokerAvailabilityEvent;
-import org.springframework.stereotype.Service;
-
-import de.spring.stomp.services.UserTradeService;
-
-@Service("userTradeService")
-public class UserTradeServiceImpl
-               implements UserTradeService, ApplicationListener<BrokerAvailabilityEvent> {
-       private final SimpMessagingTemplate template;
-       
-       private volatile boolean isBrokerAvailable = true;
-
-    @Autowired
-    public UserTradeServiceImpl(SimpMessagingTemplate template) {
-        this.template = template;
-    }
-    
-       @Override
-       public void doTrade(String user) {
-               String text = "[" + LocalDateTime.now() + "]:" + user;
-               
-               if (isBrokerAvailable) {
-                       // STOMP clients subscribed to /topic/position-updates will receive the data sent by the convertAndSend method.
-                       template.convertAndSendToUser(user, "/topic/position-updates", text);
-               }
-       }
-
-       @Override
-       public void onApplicationEvent(BrokerAvailabilityEvent event) {
-               // Components using the SimpMessagingTemplate should subscribe to this event
-               // and avoid sending messages at times when the broker is not available.
-               // In any case they should be prepared to handle MessageDeliveryException
-               // when sending a message.
-               isBrokerAvailable = event.isBrokerAvailable();
-       }
-
-}
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/webservices/rest/controller/RestGreetingController.java b/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/webservices/rest/controller/RestGreetingController.java
deleted file mode 100644 (file)
index ebb32ed..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-package de.spring.webservices.rest.controller;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RestController;
-
-import de.spring.stomp.services.RestGreetingService;
-
-
-@RestController
-public class RestGreetingController {
-       private final RestGreetingService restGreetingService;
-
-    @Autowired
-    public RestGreetingController(RestGreetingService restGreetingService) {
-        this.restGreetingService = restGreetingService;
-    }
-
-    // Sending data to /topic/greeting from REST service.
-       // POST http://localhost:8080/spring-stomp-server/greetings
-    
-       @RequestMapping(path="/greetings", method=RequestMethod.POST)
-    public void handle(@RequestBody String greeting) {
-               
-               // STOMP clients subscribed to /topic/greeting will receive the data sent by the convertAndSend method.
-               restGreetingService.doGreetings(greeting);
-    }
-
-}
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/webservices/rest/controller/UserTradeController.java b/SpringJava/STOMP/spring-stomp-server/src/main/java/de/spring/webservices/rest/controller/UserTradeController.java
deleted file mode 100644 (file)
index 718a8bd..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-package de.spring.webservices.rest.controller;
-
-import java.time.LocalDateTime;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-
-import de.spring.stomp.services.UserTradeService;
-
-public class UserTradeController {
-       private final UserTradeService userTradeService;
-
-    @Autowired
-    public UserTradeController(UserTradeService userTradeService) {
-        this.userTradeService = userTradeService;
-    }
-
-    // Sending data to /topic/greeting from REST service.
-       // POST http://localhost:8080/spring-stomp-server/trade
-    
-       @RequestMapping(path="/trade", method=RequestMethod.POST)
-    public void handle(@RequestBody String user) {
-               userTradeService.doTrade(user);
-    }
-}
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/resources/log4j2.xml b/SpringJava/STOMP/spring-stomp-server/src/main/resources/log4j2.xml
deleted file mode 100644 (file)
index 281da4f..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!-- 
-       status: The level of internal Log4j events that should be logged to the console.
-       Valid values for this attribute are "trace", "debug", "info", "warn", "error" and "fatal".
-       
-       monitorInterval: The minimum amount of time, in seconds, that must elapse before the file configuration is checked for changes.
-       
-       
-       see https://logging.apache.org/log4j/2.x/manual/configuration.html
- -->
-<Configuration status="error" strict="true" monitorInterval="30"
-                name="XMLConfigTest" packages="org.apache.logging.log4j.test">
-                
-       <!--
-               ALL > TRACE > DEBUG > INFO > WARN > ERROR > OFF
-               
-               ERROR by default.
-       -->
-                
-    <Appenders>
-        <Appender type="Console" name="STDOUT">
-            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
-        </Appender>
-    </Appenders>
-    <Loggers>
-    
-        <!-- 
-               SockJS client disconnects. Requires TRACE level always.
-               It works because I know for sure I will be using WebSockets when using SockJS.
-        -->
-        <Logger
-               name="org.springframework.web.socket.sockjs.transport.session.WebSocketServerSockJsSession"
-                       level="TRACE" additivity="false">
-            <AppenderRef ref="STDOUT" />
-        </Logger>
-    
-               <!-- 
-               General logging Spring.
-        -->
-        <Logger name="org.springframework" level="INFO" additivity="false">
-            <AppenderRef ref="STDOUT" />
-        </Logger>
-    
-
-               <!-- 
-                       Anything else will be using TRACE logging level.
-                -->        
-        <Root level="INFO">
-            <AppenderRef ref="STDOUT"/>
-        </Root>
-    </Loggers>
-</Configuration>
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/resources/spring-configuration/mvc/rest/rest-config.xml b/SpringJava/STOMP/spring-stomp-server/src/main/resources/spring-configuration/mvc/rest/rest-config.xml
deleted file mode 100644 (file)
index 5ce72ef..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:mvc="http://www.springframework.org/schema/mvc"
-       xmlns:context="http://www.springframework.org/schema/context"
-       xmlns:util="http://www.springframework.org/schema/util"
-       xmlns:p="http://www.springframework.org/schema/p"
-       xsi:schemaLocation="
-               http://www.springframework.org/schema/beans
-               http://www.springframework.org/schema/beans/spring-beans.xsd
-        http://www.springframework.org/schema/mvc
-        http://www.springframework.org/schema/mvc/spring-mvc.xsd
-        http://www.springframework.org/schema/context
-        http://www.springframework.org/schema/context/spring-context.xsd
-        http://www.springframework.org/schema/util
-        http://www.springframework.org/schema/util/spring-util.xsd">
-   
-       <!--
-               I am declaring my beans without the automatic annotation. :/
-               Better because we are saving memory but it requires more configuration.
-               
-               See: org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser
-               <mvc:annotation-driven/>
-        -->
-        
-   
-       <context:annotation-config />
-   
-       <context:component-scan base-package="de.spring.webservices.rest"/>
-       
-       <!--
-               Required beans for generating XML responses from Java objects using JAXB annotations
-               Jackson also works but it doesn't generate XML with namespaces... O.o
-               
-               This implementation will be slower than the one using Jackson :( but I am going to use it just for WADL generation :)
-       -->    
-    <bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
-        <property name="packagesToScan" value="org.jvnet.ws.wadl"/>
-    </bean>
-       <bean id="jaxbConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
-       <constructor-arg ref="jaxbMarshaller" />
-       </bean>
-    
-       <!-- Required beans for generating JSON responses from Java objects -->
-    <bean id="jsonObjectMapperFactory" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
-       p:indentOutput="true" p:failOnEmptyBeans="false">
-        <property name="featuresToDisable">
-            <array>
-                <util:constant static-field="com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES"/>
-                <util:constant static-field="com.fasterxml.jackson.databind.MapperFeature.DEFAULT_VIEW_INCLUSION"/>
-            </array>
-        </property>
-    </bean>
-    
-    <util:list id="messageConverters">
-        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" p:objectMapper-ref="jsonObjectMapperFactory"/>
-               <ref bean="jaxbConverter" />
-        <bean class="org.springframework.http.converter.StringHttpMessageConverter" />
-    </util:list>
-
-
-       <bean name="handlerAdapter"
-               class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
-               <property name="webBindingInitializer">
-                       <bean
-                               class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
-                               <!-- It enables us to use JSR-303 -->
-                               <property name="validator">
-                                       <bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
-                               </property>
-                       </bean>
-               </property>
-               <property name="messageConverters" ref="messageConverters" />
-               
-               
-               <property name="requestBodyAdvice">
-                       <util:list>
-                               <bean id="requestBodyAdvice" class="org.springframework.web.servlet.mvc.method.annotation.JsonViewRequestBodyAdvice"/>
-                       </util:list>
-               </property>
-               
-               
-               <property name="responseBodyAdvice">
-                       <util:list>
-                               <bean id="responseBodyAdvice" class="org.springframework.web.servlet.mvc.method.annotation.JsonViewResponseBodyAdvice"/>
-                       </util:list>
-               </property>
-       </bean>
-    
-       <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
-
-       <mvc:default-servlet-handler />
-       
-</beans>
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/resources/spring-configuration/spring-configuration.xml b/SpringJava/STOMP/spring-stomp-server/src/main/resources/spring-configuration/spring-configuration.xml
deleted file mode 100644 (file)
index 620323b..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans"
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xmlns:context="http://www.springframework.org/schema/context"
-  xmlns:websocket="http://www.springframework.org/schema/websocket"
-
-  xsi:schemaLocation="http://www.springframework.org/schema/beans 
-                      http://www.springframework.org/schema/beans/spring-beans.xsd
-                      http://www.springframework.org/schema/context 
-                      http://www.springframework.org/schema/context/spring-context.xsd
-                      http://www.springframework.org/schema/websocket
-                                 http://www.springframework.org/schema/websocket/spring-websocket.xsd">
-
-    <!--
-       Searches for beans in packages (instead of XML configuration we can use
-       in this way annotations like @Service, @Endpoint, etc, etc)
-    -->
-    <context:component-scan base-package="de.spring.stomp"/>
-
-
-    <bean class="org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean">
-        <property name="maxTextMessageBufferSize" value="8192"/>
-        <property name="maxBinaryMessageBufferSize" value="8192"/>
-    </bean>
-    
-    <!--
-       Note that even though the STOMP CONNECT frame has "login" and "passcode" headers that can be used for
-       authentication, Spring’s STOMP WebSocket support ignores them and currently expects users to have been
-       authenticated already via HTTP.
-       
-       In some cases it may be useful to assign an identity to a WebSocket session even when the user has not
-       been formally authenticated. For example, a mobile app might assign some identity to anonymous users,
-       perhaps based on geographical location. The do that currently, an application can sub-class DefaultHandshakeHandler
-       and override the determineUser method. The custom handshake handler can then be plugged in
-       (see examples in Section 25.2.4, “Deployment Considerations”).
-    -->
-    <bean id="customHandshakeHandler" class="de.spring.stomp.handlers.CustomHandshakeHandler"/>
-    
-    <!-- Interceptors -->
-    <bean id="customChannelInterceptor" class="de.spring.stomp.interceptors.CustomChannelInterceptor"/>
-    <bean id="customHttpHandshakeInterceptor" class="de.spring.stomp.interceptors.CustomHttpHandshakeInterceptor"/>
-    
-    <!-- Listeners -->
-    <bean id="brokerAvailabilityListener" class="de.spring.stomp.listeners.BrokerAvailabilityListener"/>
-    <bean id="sessionConnectedListener" class="de.spring.stomp.listeners.SessionConnectedListener"/>
-    <bean id="sessionConnectListener" class="de.spring.stomp.listeners.SessionConnectListener"/>
-    <bean id="sessionDisconnectListener" class="de.spring.stomp.listeners.SessionDisconnectListener"/>    
-    <bean id="sessionSubscribeListener" class="de.spring.stomp.listeners.SessionSubscribeListener"/>    
-    <bean id="sessionUnsubscribeListener" class="de.spring.stomp.listeners.SessionUnsubscribeListener"/>
-        
-    <!-- STOMP -->
-    <!-- Simple broker -->
-    <websocket:message-broker application-destination-prefix="/app">
-       <websocket:transport send-timeout="15000" send-buffer-size="524288" message-size="131072" />
-        <websocket:stomp-endpoint path="/portfolio" allowed-origins="*">
-            <websocket:handshake-handler ref="customHandshakeHandler" />
-               <websocket:handshake-interceptors>
-               <ref bean="customHttpHandshakeInterceptor"/>
-               </websocket:handshake-interceptors>
-               <websocket:sockjs/>    
-        </websocket:stomp-endpoint>
-        <!--
-               In memory broker.
-
-               hearbeat: Configure the value for the heartbeat settings. The first number represents how often the server will
-                       write or send a heartbeat. The second is how often the client should write. 0 means no heartbeats.
-                       By default this is set to "0, 0" unless the scheduler attribute is also set in which case the
-                       default becomes "10000,10000" (in milliseconds).
-                       
-                       Matching the value used by client.
-        -->
-        <websocket:simple-broker prefix="/topic, /queue"
-        heartbeat="0,20000" />
-        
-        <websocket:client-inbound-channel>
-                       <websocket:executor core-pool-size="100" max-pool-size="200" keep-alive-seconds="600"/>
-                       <websocket:interceptors>
-                               <ref bean="customChannelInterceptor"/>
-                       </websocket:interceptors>
-               </websocket:client-inbound-channel>
-               <websocket:client-outbound-channel>
-                       <websocket:executor core-pool-size="101" max-pool-size="201" keep-alive-seconds="601"/>
-                       <websocket:interceptors>
-                               <ref bean="customChannelInterceptor"/>
-                       </websocket:interceptors>
-               </websocket:client-outbound-channel>
-    </websocket:message-broker>
-    
-    <!-- Full-featured broker -->
-    <websocket:message-broker application-destination-prefix="/app">
-       <websocket:transport send-timeout="15000" send-buffer-size="524288" message-size="131072" />
-        <websocket:stomp-endpoint path="/fullportfolio" allowed-origins="*">
-               <websocket:handshake-handler ref="customHandshakeHandler" />
-               <websocket:handshake-interceptors>
-               <ref bean="customHttpHandshakeInterceptor"/>
-               </websocket:handshake-interceptors>
-            <websocket:sockjs/>
-        </websocket:stomp-endpoint>
-        <!--
-               Full-featured broker
-        -->
-        <websocket:stomp-broker-relay prefix="/topic, /queue"
-        relay-host="" relay-port="" client-login="" client-passcode="" system-login="" system-passcode=""
-        heartbeat-send-interval="" heartbeat-receive-interval="" auto-startup="true" virtual-host=""/>
-        
-        <websocket:client-inbound-channel>
-                       <websocket:executor core-pool-size="100" max-pool-size="200" keep-alive-seconds="600"/>
-                       <websocket:interceptors>
-                               <ref bean="customChannelInterceptor"/>
-                       </websocket:interceptors>
-               </websocket:client-inbound-channel>
-               <websocket:client-outbound-channel>
-                       <websocket:executor core-pool-size="101" max-pool-size="201" keep-alive-seconds="601"/>
-                       <websocket:interceptors>
-                               <ref bean="customChannelInterceptor"/>
-                       </websocket:interceptors>
-               </websocket:client-outbound-channel>
-    </websocket:message-broker>
-
-</beans>
diff --git a/SpringJava/STOMP/spring-stomp-server/src/main/webapp/WEB-INF/web.xml b/SpringJava/STOMP/spring-stomp-server/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644 (file)
index 00d1c2e..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
-         version="2.4">
-
-    <display-name>Spring STOMP: example</display-name>
-
-    <listener>
-        <listener-class>
-            org.springframework.web.context.ContextLoaderListener
-        </listener-class>
-    </listener>
-
-    <context-param>
-        <param-name>spring.profiles.active</param-name>
-        <param-value>${environment.profile}</param-value>
-        <param-name>contextConfigLocation</param-name>
-        <param-value>
-            classpath*:spring-configuration/*.xml
-        </param-value>
-    </context-param>
-    
-    <!-- Spring REST support -->
-    <servlet>
-        <servlet-name>spring-rest</servlet-name>
-        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
-        <load-on-startup>1</load-on-startup>
-        <async-supported>true</async-supported>
-        <init-param>
-           <param-name>contextConfigLocation</param-name>
-           <param-value>classpath*:spring-configuration/mvc/rest/*.xml</param-value>
-        </init-param>
-    </servlet>
-
-    <servlet-mapping>
-        <servlet-name>spring-rest</servlet-name>
-        <!-- REQUIRED PATTERN BY swagger-ui. IT DOESN'T WORK WITH ANY OTHER o.O -->
-        <url-pattern>/*</url-pattern>
-    </servlet-mapping>
-
-</web-app>
diff --git a/SpringJava/STOMP/spring-stomp/pom.xml b/SpringJava/STOMP/spring-stomp/pom.xml
deleted file mode 100644 (file)
index 8630bf6..0000000
+++ /dev/null
@@ -1,316 +0,0 @@
-<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/maven-v4_0_0.xsd">
-       <modelVersion>4.0.0</modelVersion>
-       <groupId>de.spring.stomp</groupId>
-       <artifactId>spring-stomp</artifactId>
-       <packaging>pom</packaging>
-       <version>1.0-SNAPSHOT</version>
-       <name>spring-stomp</name>
-       <url>http://gumartinm.name</url>
-       <description>Emails with Spring Framework</description>
-       <organization>
-               <name>Gustavo Martin Morcuende</name>
-               <url>http://www.gumartinm.name</url>
-       </organization>
-       <scm>
-               <developerConnection>scm:git:http://git.gumartinm.name/JavaForFun</developerConnection>
-               <url>http://git.gumartinm.name/JavaForFun</url>
-       </scm>
-
-       <properties>
-               <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-               <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-               <spring.version>4.2.5.RELEASE</spring.version>
-       </properties>
-
-       <profiles>
-               <profile>
-                       <id>release</id>
-                       <properties>
-                               <environment.profile>release</environment.profile>
-                       </properties>
-                       <activation>
-                               <activeByDefault>true</activeByDefault>
-                       </activation>
-               </profile>
-       </profiles>
-
-       <dependencies>
-               <!--
-                       1/3 Required dependency for log4j 2 with slf4j: binding between log4j 
-                       2 and slf4j
-               -->
-               <dependency>
-                       <groupId>org.apache.logging.log4j</groupId>
-                       <artifactId>log4j-slf4j-impl</artifactId>
-                       <version>2.3</version>
-               </dependency>
-               <!--
-                       2/3 Required dependency for log4j 2 with slf4j: log4j 2 maven plugin 
-                       (it is the log4j 2 implementation)
-               -->
-               <dependency>
-                       <groupId>org.apache.logging.log4j</groupId>
-                       <artifactId>log4j-core</artifactId>
-                       <version>2.3</version>
-               </dependency>
-               <!--
-                       3/3 Required dependency for getting rid of commons logging. This is 
-                       the BRIDGE (no binding) between Jakarta Commons Logging (used by Spring) 
-                       and whatever I am using for logging (in this case I am using log4j 2)
-                       See: http://www.slf4j.org/legacy.html We need exclusions in every dependency using 
-                       Jakarta Commons Logging (see Spring dependencies below)
-               -->
-               <dependency>
-                       <groupId>org.slf4j</groupId>
-                       <artifactId>jcl-over-slf4j</artifactId>
-                       <version>1.7.12</version>
-               </dependency>
-
-
-               <dependency>
-                       <groupId>cglib</groupId>
-                       <artifactId>cglib</artifactId>
-                       <version>2.2.2</version>
-               </dependency>
-               
-               <!-- Unitary and integration tests -->
-                       <dependency>
-                               <groupId>junit</groupId>
-                               <artifactId>junit</artifactId>
-                               <version>4.12</version>
-                               <scope>test</scope>
-                       </dependency>
-                       <dependency>
-                               <groupId>org.mockito</groupId>
-                               <artifactId>mockito-core</artifactId>
-                               <version>2.0.43-beta</version>
-                               <scope>test</scope>
-                       </dependency>
-       </dependencies>
-       <dependencyManagement>
-               <dependencies>
-                       <dependency>
-                               <groupId>org.springframework</groupId>
-                               <artifactId>spring-context</artifactId>
-                               <version>${spring.version}</version>
-                               <!--
-                                       Required dependency for getting rid of commons logging and use my
-                                       own logging library (in my case I decided to use log4j 2 under slf4j)
-                               -->
-                               <exclusions>
-                                       <exclusion>
-                                               <groupId>commons-logging</groupId>
-                                               <artifactId>commons-logging</artifactId>
-                                       </exclusion>
-                               </exclusions>
-                       </dependency>
-                       
-                       <!-- Required for WebSockets -->
-                       <dependency>
-                       <groupId>org.springframework</groupId>
-                       <artifactId>spring-websocket</artifactId>
-                       <version>${spring.version}</version>
-                               <!--
-                                       Required dependency for getting rid of commons logging and use my
-                                       own logging library (in my case I decided to use log4j 2 under slf4j)
-                               -->
-                               <exclusions>
-                                       <exclusion>
-                                               <groupId>commons-logging</groupId>
-                                               <artifactId>commons-logging</artifactId>
-                                       </exclusion>
-                               </exclusions>
-                       </dependency>
-                       
-                       <!--  Required for STOMP -->
-                       <dependency>
-                       <groupId>org.springframework</groupId>
-                       <artifactId>spring-messaging</artifactId>
-                       <version>${spring.version}</version>
-                               <!--
-                                       Required dependency for getting rid of commons logging and use my
-                                       own logging library (in my case I decided to use log4j 2 under slf4j)
-                               -->
-                               <exclusions>
-                                       <exclusion>
-                                               <groupId>commons-logging</groupId>
-                                               <artifactId>commons-logging</artifactId>
-                                       </exclusion>
-                               </exclusions>                           
-                       </dependency>
-                       
-                       <!-- REST API -->
-                       <dependency>
-                               <groupId>org.springframework</groupId>
-                               <artifactId>spring-webmvc</artifactId>
-                               <version>${spring.version}</version>
-                               <!--
-                                       Required dependency for getting rid of commons logging and use my
-                                       own logging library (in my case I decided to use log4j 2 under slf4j)
-                               -->
-                               <exclusions>
-                                       <exclusion>
-                                               <groupId>commons-logging</groupId>
-                                               <artifactId>commons-logging</artifactId>
-                                       </exclusion>
-                               </exclusions>
-                       </dependency>
-                       <dependency>
-                               <groupId>org.springframework</groupId>
-                               <artifactId>spring-oxm</artifactId>
-                               <version>${spring.version}</version>
-                               <!--
-                                       Required dependency for getting rid of commons logging and use my
-                                       own logging library (in my case I decided to use log4j 2 under slf4j)
-                               -->
-                               <exclusions>
-                                       <exclusion>
-                                               <groupId>commons-logging</groupId>
-                                               <artifactId>commons-logging</artifactId>
-                                       </exclusion>
-                               </exclusions>
-                       </dependency>
-                       
-                       
-                       <!-- Required by spring-webmvc -->
-                       <dependency>
-                               <groupId>javax.servlet</groupId>
-                               <artifactId>javax.servlet-api</artifactId>
-                               <version>4.0.0-b01</version>
-                               <scope>provided</scope>
-                       </dependency>
-
-                       <!--
-                               Jackson JSON Processor, required by spring-webmvc. See messageConverters 
-                               in rest-config.xml
-                       -->
-                       <dependency>
-                               <groupId>com.fasterxml.jackson.core</groupId>
-                               <artifactId>jackson-databind</artifactId>
-                               <version>2.6.4</version>
-                       </dependency>
-
-                       <!--
-                               Required by spring-context for using JSR-303. See LocalValidatorFactoryBean 
-                               in rest-config.xml
-                       -->
-                       <dependency>
-                               <groupId>javax.validation</groupId>
-                               <artifactId>validation-api</artifactId>
-                               <version>1.1.0.Final</version>
-                       </dependency>
-                       <dependency>
-                               <groupId>org.hibernate</groupId>
-                               <artifactId>hibernate-validator</artifactId>
-                               <version>5.2.2.Final</version>
-                       </dependency>
-
-
-                       <!-- Unitary and integration tests -->
-                       <dependency>
-                               <groupId>org.springframework</groupId>
-                               <artifactId>spring-test</artifactId>
-                               <version>${spring.version}</version>
-                               <scope>test</scope>
-                               <!--
-                                       Required dependency for getting rid of commons logging and use my
-                                       own logging library (in my case I decided to use log4j 2 under slf4j)
-                               -->
-                               <exclusions>
-                                       <exclusion>
-                                               <groupId>commons-logging</groupId>
-                                               <artifactId>commons-logging</artifactId>
-                                       </exclusion>
-                               </exclusions>
-                       </dependency>
-                       <dependency>
-                       <groupId>com.icegreen</groupId>
-                       <artifactId>greenmail</artifactId>
-                       <version>1.5.0</version>
-                       <scope>test</scope>
-                       </dependency>
-               </dependencies>
-       </dependencyManagement>
-       <build>
-
-               <pluginManagement>
-                       <plugins>
-                               <plugin>
-                                       <groupId>org.apache.maven.plugins</groupId>
-                                       <artifactId>maven-surefire-plugin</artifactId>
-                                       <version>2.19.1</version>
-                               </plugin>
-                               <plugin>
-                                       <groupId>org.apache.maven.plugins</groupId>
-                                       <artifactId>maven-failsafe-plugin</artifactId>
-                                       <version>2.19.1</version>
-                               </plugin>
-                       </plugins>
-               </pluginManagement>
-
-               <plugins>
-                       <plugin>
-                               <groupId>org.apache.maven.plugins</groupId>
-                               <artifactId>maven-compiler-plugin</artifactId>
-                               <version>3.1</version>
-                               <configuration>
-                                       <source>1.8</source>
-                                       <target>1.8</target>
-                                       <encoding>${project.build.sourceEncoding}</encoding>
-                               </configuration>
-                       </plugin>
-                       <plugin>
-                               <groupId>org.apache.maven.plugins</groupId>
-                               <artifactId>maven-resources-plugin</artifactId>
-                               <version>2.7</version>
-                               <configuration>
-                                       <encoding>${project.build.sourceEncoding}</encoding>
-                               </configuration>
-                       </plugin>
-                       <plugin>
-                               <groupId>org.apache.maven.plugins</groupId>
-                               <artifactId>maven-jar-plugin</artifactId>
-                               <version>2.6</version>
-                               <configuration>
-                                       <archive>
-                                               <manifestEntries>
-                                                       <Specification-Title>${project.description}</Specification-Title>
-                                                       <Specification-Version>${project.version}</Specification-Version>
-                                                       <Specification-Vendor>${project.organization.name}</Specification-Vendor>
-                                                       <Implementation-Title>${project.description}</Implementation-Title>
-                                                       <Implementation-Version>${project.version}</Implementation-Version>
-                                                       <Implementation-Vendor>${project.organization.name}</Implementation-Vendor>
-                                               </manifestEntries>
-                                       </archive>
-                               </configuration>
-                       </plugin>
-                       <plugin>
-                               <groupId>org.apache.maven.plugins</groupId>
-                               <artifactId>maven-surefire-plugin</artifactId>
-                               <configuration>
-                                       <excludes>
-                                               <exclude>**/*IntegrationTest.java</exclude>
-                                       </excludes>
-                               </configuration>
-                       </plugin>
-                       <plugin>
-                               <groupId>org.apache.maven.plugins</groupId>
-                               <artifactId>maven-failsafe-plugin</artifactId>
-                               <executions>
-                                       <execution>
-                                               <goals>
-                                                       <goal>integration-test</goal>
-                                                       <goal>verify</goal>
-                                               </goals>
-                                       </execution>
-                               </executions>
-                               <configuration>
-                                       <includes>
-                                               <include>**/*IntegrationTest.java</include>
-                                       </includes>
-                               </configuration>
-                       </plugin>
-               </plugins>
-       </build>
-</project>