Skip to content

Commit 2034dbb

Browse files
garyrussellghillert
authored andcommitted
INTEXT-24 Lightweight WebSocket Server
* Add Lightweight WebSocket Server Support * Run WebSocketServerTests and open ws.html in a browser. - Sending 'start' begins sending an incrementing # once per second. - 'stop' stops the stream (leaving the socket open), 'start' resumes again. - Test terminates after 60 seconds. * Fixes and Improvements for WebSocket Server - fix masking - fix bytes sent - add error handling to remove dead sockets - create new web page instead of using vert.x example - add status box - automatically update message to send to start/stop appropriately - update SI to 2.2.0.RELEASE - change test to a main() * Use Interceptor for Handshake * Move handshake to an interceptor instead of doing it in the SI flow. * Add close button to web page. * Add code to remove state from deserializer on close. * Implement Orderly Close Per RFC6455 * Rename Packages - org.springframework.integration.x.* * Change Version to 0.1.0. * Autbahn Test Suite - All Tests Pass - 1.1.x tests from the Autobahn Test Suite. - Autobahn 1.2.x Tests (Binary) - Autobahn Test 2.* (Ping/Pong) - Autobahn Tests 3.* (Reserved Bits) - Autobahn Tests 4.* (Invalid Opcodes) - Autobahn 5.* (Fragmentation) - Autobahn 6.* (UTF-8 Handling) - Autobahn Tests 7.* (Close Handling) * "non-strict" results - fast fail on bad UTF-8. We currently don't detect the bad UTF-8 until all fragments are received. * Run AutobahnTests.java and add the following to fuzzingclient.json... {"agent": "SIServer", "url": "ws://localhost:18080", "options": {"version": 18}} * Remove sysout * Replace with logger.debug(). * Remove SockJS Dependencies - Project started as a SockJS client; WebSocket classes were incorrectly dependent on some SockJS code. * Extracted the WebSocket code to its own class hierarchy. * Test Autobahn with SSL (wss://...) - Add trust store and key store. - Add config to listen for wss: as well as ws: connections * To test Autobahn for both ws and wss - In the wstest config file use: "servers": [ {"agent": "SIServer", "url": "ws://localhost:18080", "options": {"version": 18}}, {"agent": "SIServerSSL", "url": "wss://localhost:28080", "options": {"version": 18}} ], * Polishing + Resequence when Using NIO - Improve debug logging - Clear fragments - Add ResequencingMessageHandler to resequence messages when using NIO (frames can arrive on different threads, out of order; this causes issues with the Autobahn tests. * Reject Non WS Connections - only apply Resequencer if NIO Connection factory is configured with apply-sequence. - check protocol version - only 13 is supported.
1 parent bbf5621 commit 2034dbb

29 files changed

+2611
-0
lines changed
+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
Spring Integration IP Extensions
2+
=================================================
3+
4+
Welcome to the Spring Integration IP Extensions project. It is intended to supplement the spring-integration-ip module with, for example, custom serializers/deserializers.
5+
6+
7+
# Building
8+
9+
If you encounter out of memory errors during the build, increase available heap and permgen for Gradle:
10+
11+
GRADLE_OPTS='-XX:MaxPermSize=1024m -Xmx1024m'
12+
13+
To build and install jars into your local Maven cache:
14+
15+
./gradlew install
16+
17+
To build api Javadoc (results will be in `build/api`):
18+
19+
./gradlew api
20+
21+
To build reference documentation (results will be in `build/reference`):
22+
23+
./gradlew reference
24+
25+
To build complete distribution including `-dist`, `-docs`, and `-schema` zip files (results will be in `build/distributions`)
26+
27+
./gradlew dist
28+
29+
# Using SpringSource Tool Suite
30+
31+
Gradle projects can be directly imported into STS
32+
33+
# Using PLain Eclipse
34+
35+
To generate Eclipse metadata (.classpath and .project files), do the following:
36+
37+
./gradlew eclipse
38+
39+
Once complete, you may then import the projects into Eclipse as usual:
40+
41+
*File -> Import -> Existing projects into workspace*
42+
43+
Browse to the *'spring-integration'* root directory. All projects should import
44+
free of errors.
45+
46+
# Using IntelliJ IDEA
47+
48+
To generate IDEA metadata (.iml and .ipr files), do the following:
49+
50+
./gradlew idea
51+
52+
For more information, please visit the Spring Integration website at:
53+
[http://www.springsource.org/spring-integration](http://www.springsource.org/spring-integration)
54+
55+
56+
WebSocket Server Demo
57+
=====================
58+
59+
This demonstrates how to use the TCP adapters to provide a very lightweight websocket server.
60+
61+
Run WebSocketServerTests as a Java Application (main) and open
62+
63+
file:///.../spring-integration-extensions/spring-integration-ip-extensions/src/test/java/org/springframework/integration/ip/extensions/sockjs/ws.html
64+
65+
in a browser.
66+
67+
Opening the page opens the WebSocket.
68+
69+
Sending 'start' begins sending an incrementing # once per second.
70+
'stop' stops the stream (leaving the socket open), 'start' resumes
71+
again. Multiple browser instances get their own sequence #.
72+
73+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
description = 'Spring Integration IP Extensions'
2+
3+
buildscript {
4+
repositories {
5+
maven { url 'https://repo.springsource.org/plugins-snapshot' }
6+
}
7+
dependencies {
8+
classpath 'org.springframework.build.gradle:docbook-reference-plugin:0.1.5'
9+
}
10+
}
11+
12+
apply plugin: 'java'
13+
apply from: "${rootProject.projectDir}/publish-maven.gradle"
14+
apply plugin: 'eclipse'
15+
apply plugin: 'idea'
16+
17+
group = 'org.springintegration.ip.extensions'
18+
19+
repositories {
20+
maven { url 'http://repo.springsource.org/libs-milestone' }
21+
maven { url 'http://repo.springsource.org/plugins-release' } // for bundlor
22+
}
23+
24+
sourceCompatibility=1.6
25+
targetCompatibility=1.6
26+
27+
ext {
28+
aspectjVersion = '1.6.8'
29+
cglibVersion = '2.2'
30+
commonsNetVersion = '3.0.1'
31+
javaxActivationVersion = '1.1.1'
32+
junitVersion = '4.10'
33+
log4jVersion = '1.2.12'
34+
mockitoVersion = '1.9.0'
35+
springVersion = '3.1.3.RELEASE'
36+
springIntegrationVersion = '2.2.0.RELEASE'
37+
}
38+
39+
eclipse {
40+
project {
41+
natures += 'org.springframework.ide.eclipse.core.springnature'
42+
}
43+
}
44+
45+
sourceSets {
46+
test {
47+
resources {
48+
srcDirs = ['src/test/resources', 'src/test/java']
49+
}
50+
}
51+
}
52+
53+
// See http://www.gradle.org/docs/current/userguide/dependency_management.html#sub:configurations
54+
// and http://www.gradle.org/docs/current/dsl/org.gradle.api.artifacts.ConfigurationContainer.html
55+
configurations {
56+
jacoco //Configuration Group used by Sonar to provide Code Coverage using JaCoCo
57+
}
58+
59+
dependencies {
60+
compile "org.springframework.integration:spring-integration-ip:$springIntegrationVersion"
61+
compile "commons-codec:commons-codec:1.5"
62+
testCompile "org.springframework.integration:spring-integration-test:$springIntegrationVersion"
63+
testCompile "junit:junit-dep:$junitVersion"
64+
testCompile "log4j:log4j:$log4jVersion"
65+
testCompile "org.mockito:mockito-all:$mockitoVersion"
66+
testCompile "org.springframework:spring-test:$springVersion"
67+
jacoco group: "org.jacoco", name: "org.jacoco.agent", version: "0.5.6.201201232323", classifier: "runtime"
68+
}
69+
70+
// enable all compiler warnings; individual projects may customize further
71+
ext.xLintArg = '-Xlint:all'
72+
[compileJava, compileTestJava]*.options*.compilerArgs = [xLintArg]
73+
74+
test {
75+
// suppress all console output during testing unless running `gradle -i`
76+
logging.captureStandardOutput(LogLevel.INFO)
77+
jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=*"
78+
}
79+
80+
task sourcesJar(type: Jar) {
81+
classifier = 'sources'
82+
from sourceSets.main.allJava
83+
}
84+
85+
task javadocJar(type: Jar) {
86+
classifier = 'javadoc'
87+
from javadoc
88+
}
89+
90+
artifacts {
91+
archives sourcesJar
92+
archives javadocJar
93+
}
94+
95+
apply plugin: 'sonar'
96+
97+
sonar {
98+
99+
if (rootProject.hasProperty('sonarHostUrl')) {
100+
server.url = rootProject.sonarHostUrl
101+
}
102+
103+
database {
104+
if (rootProject.hasProperty('sonarJdbcUrl')) {
105+
url = rootProject.sonarJdbcUrl
106+
}
107+
if (rootProject.hasProperty('sonarJdbcDriver')) {
108+
driverClassName = rootProject.sonarJdbcDriver
109+
}
110+
if (rootProject.hasProperty('sonarJdbcUsername')) {
111+
username = rootProject.sonarJdbcUsername
112+
}
113+
if (rootProject.hasProperty('sonarJdbcPassword')) {
114+
password = rootProject.sonarJdbcPassword
115+
}
116+
}
117+
118+
project {
119+
dynamicAnalysis = "reuseReports"
120+
withProjectProperties { props ->
121+
props["sonar.core.codeCoveragePlugin"] = "jacoco"
122+
props["sonar.jacoco.reportPath"] = "${buildDir.name}/jacoco.exec"
123+
}
124+
}
125+
126+
logger.info("Sonar parameters used: server.url='${server.url}'; database.url='${database.url}'; database.driverClassName='${database.driverClassName}'; database.username='${database.username}'")
127+
}
128+
129+
task api(type: Javadoc) {
130+
group = 'Documentation'
131+
description = 'Generates aggregated Javadoc API documentation.'
132+
title = "${rootProject.description} ${version} API"
133+
options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED
134+
options.author = true
135+
options.header = rootProject.description
136+
options.overview = 'src/api/overview.html'
137+
138+
source = sourceSets.main.allJava
139+
classpath = project.sourceSets.main.compileClasspath
140+
destinationDir = new File(buildDir, "api")
141+
}
142+
143+
task docsZip(type: Zip) {
144+
group = 'Distribution'
145+
classifier = 'docs'
146+
description = "Builds -${classifier} archive containing api and reference " +
147+
"for deployment at static.springframework.org/spring-integration/docs."
148+
149+
from (api) {
150+
into 'api'
151+
}
152+
153+
}
154+
155+
task distZip(type: Zip, dependsOn: [docsZip]) {
156+
group = 'Distribution'
157+
classifier = 'dist'
158+
description = "Builds -${classifier} archive, containing all jars and docs, " +
159+
"suitable for community download page."
160+
161+
ext.baseDir = "${project.name}-${project.version}";
162+
163+
from('src/dist') {
164+
include 'readme.txt'
165+
include 'license.txt'
166+
include 'notice.txt'
167+
into "${baseDir}"
168+
}
169+
170+
from(zipTree(docsZip.archivePath)) {
171+
into "${baseDir}/docs"
172+
}
173+
174+
into ("${baseDir}/libs") {
175+
from project.jar
176+
from project.sourcesJar
177+
from project.javadocJar
178+
}
179+
}
180+
181+
// Create an optional "with dependencies" distribution.
182+
// Not published by default; only for use when building from source.
183+
task depsZip(type: Zip, dependsOn: distZip) { zipTask ->
184+
group = 'Distribution'
185+
classifier = 'dist-with-deps'
186+
description = "Builds -${classifier} archive, containing everything " +
187+
"in the -${distZip.classifier} archive plus all dependencies."
188+
189+
from zipTree(distZip.archivePath)
190+
191+
gradle.taskGraph.whenReady { taskGraph ->
192+
if (taskGraph.hasTask(":${zipTask.name}")) {
193+
def projectName = rootProject.name
194+
def artifacts = new HashSet()
195+
196+
rootProject.configurations.runtime.resolvedConfiguration.resolvedArtifacts.each { artifact ->
197+
def dependency = artifact.moduleVersion.id
198+
if (!projectName.equals(dependency.name)) {
199+
artifacts << artifact.file
200+
}
201+
}
202+
203+
zipTask.from(artifacts) {
204+
into "${distZip.baseDir}/deps"
205+
}
206+
}
207+
}
208+
}
209+
210+
artifacts {
211+
archives distZip
212+
archives docsZip
213+
}
214+
215+
task dist(dependsOn: assemble) {
216+
group = 'Distribution'
217+
description = 'Builds -dist, -docs and -schema distribution archives.'
218+
}
219+
220+
task wrapper(type: Wrapper) {
221+
description = 'Generates gradlew[.bat] scripts'
222+
gradleVersion = '1.3'
223+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
version=0.1.0.BUILD-SNAPSHOT
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#Mon Jan 07 15:58:18 EST 2013
2+
distributionBase=GRADLE_USER_HOME
3+
distributionPath=wrapper/dists
4+
zipStoreBase=GRADLE_USER_HOME
5+
zipStorePath=wrapper/dists
6+
distributionUrl=http\://services.gradle.org/distributions/gradle-1.3-bin.zip

0 commit comments

Comments
 (0)