You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by ay...@apache.org on 2016/04/05 14:35:10 UTC
[1/8] cxf git commit: add the stacktrace output in CustomerService
for CXF-5855
Repository: cxf
Updated Branches:
refs/heads/3.1.x-fixes 91197fdb2 -> 75edfe9d2
add the stacktrace output in CustomerService for CXF-5855
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/f12eb1a2
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/f12eb1a2
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/f12eb1a2
Branch: refs/heads/3.1.x-fixes
Commit: f12eb1a2a2eb2220550cb25dcc54d62127d55244
Parents: 35f01c9
Author: Akitoshi Yoshida <ay...@apache.org>
Authored: Thu Mar 17 10:08:25 2016 +0100
Committer: Akitoshi Yoshida <ay...@apache.org>
Committed: Tue Apr 5 13:36:57 2016 +0200
----------------------------------------------------------------------
.../src/main/java/demo/jaxrs/server/CustomerService.java | 4 ++++
1 file changed, 4 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/f12eb1a2/distribution/src/main/release/samples/jax_rs/websocket/src/main/java/demo/jaxrs/server/CustomerService.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket/src/main/java/demo/jaxrs/server/CustomerService.java b/distribution/src/main/release/samples/jax_rs/websocket/src/main/java/demo/jaxrs/server/CustomerService.java
index cc039ff..f77f8aa 100644
--- a/distribution/src/main/release/samples/jax_rs/websocket/src/main/java/demo/jaxrs/server/CustomerService.java
+++ b/distribution/src/main/release/samples/jax_rs/websocket/src/main/java/demo/jaxrs/server/CustomerService.java
@@ -186,6 +186,8 @@ public class CustomerService {
} catch (IOException e) {
System.out.println("----error writing to " + wh.getValue() + " " + wh.get());
if (wh.increment()) {
+ // the max error count reached; purging the output resource
+ e.printStackTrace();
try {
wh.getValue().close();
} catch (IOException e2) {
@@ -205,6 +207,8 @@ public class CustomerService {
} catch (IOException e) {
System.out.println("----error writing to " + wh.getValue() + " " + wh.get());
if (wh.increment()) {
+ // the max error count reached; purging the output resource
+ e.printStackTrace();
try {
wh.getValue().getOutputStream().close();
} catch (IOException e2) {
[6/8] cxf git commit: use a non-empty context-path for
samples/jax_rs/websocket sample
Posted by ay...@apache.org.
use a non-empty context-path for samples/jax_rs/websocket sample
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/b52157a3
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/b52157a3
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/b52157a3
Branch: refs/heads/3.1.x-fixes
Commit: b52157a330d9ef4daab8d2826579cb68ca171c69
Parents: f12eb1a
Author: Akitoshi Yoshida <ay...@apache.org>
Authored: Wed Mar 23 14:23:03 2016 +0100
Committer: Akitoshi Yoshida <ay...@apache.org>
Committed: Tue Apr 5 13:36:58 2016 +0200
----------------------------------------------------------------------
.../release/samples/jax_rs/websocket/README.txt | 26 ++++++++---------
.../src/main/java/demo/jaxrs/client/Client.java | 29 ++++++++-----------
.../src/main/java/demo/jaxrs/server/Server.java | 4 ++-
.../websocket/src/main/resources/index.html | 4 +--
.../websocket/src/test/resources/client.js | 30 +++++++++++---------
5 files changed, 46 insertions(+), 47 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/b52157a3/distribution/src/main/release/samples/jax_rs/websocket/README.txt
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket/README.txt b/distribution/src/main/release/samples/jax_rs/websocket/README.txt
index f1d3455..8df709e 100644
--- a/distribution/src/main/release/samples/jax_rs/websocket/README.txt
+++ b/distribution/src/main/release/samples/jax_rs/websocket/README.txt
@@ -3,7 +3,7 @@ JAX-RS WebSocket Demo
This is a websocket transport version of JAX-RS Basic Demo.
-A RESTful customer service is provided on URL ws://localhost:9000/customers.
+A RESTful customer service is provided on URL ws://localhost:9000/demo
Users access this URI to operate on customer.
This sample includes two convenient clients: a plain javascript browser client
@@ -13,12 +13,12 @@ and a node.js client based on atmosphere.
Connecting to the server
---------------------------------------
-Open a websocket to ws://localhost:9000/ and send requests over the websocket.
+Open a websocket to ws://localhost:9000/demo and send requests over the websocket.
-A GET request to path /customerservice/customers/123
+A GET request to path /demo/customerservice/customers/123
------------------------------------------------------------------------
-GET /customerservice/customers/123
+GET /demo/customerservice/customers/123
------------------------------------------------------------------------
returns a customer instance whose id is 123. The XML document returned:
@@ -30,10 +30,10 @@ returns a customer instance whose id is 123. The XML document returned:
</Customer>
------------------------------------------------------------------------
-A GET request to path /customerservice/orders/223/products/323
+A GET request to path /demo/customerservice/orders/223/products/323
------------------------------------------------------------------------
-GET /customerservice/orders/223/products/323
+GET /demo/customerservice/orders/223/products/323
------------------------------------------------------------------------
returns product 323 that belongs to order 223. The XML document returned:
@@ -48,7 +48,7 @@ returns product 323 that belongs to order 223. The XML document returned:
A POST request to path /customerservice/customers
------------------------------------------------------------------------
-POST /customerservice/customers
+POST /demo/customerservice/customers
Content-Type: text/xml; charset="utf-8"
------------------------------------------------------------------------
@@ -63,7 +63,7 @@ with the data:
adds a customer whose name is Jack
-A PUT request to path /customerservice/customers
+A PUT request to path /demo/customerservice/customers
------------------------------------------------------------------------
PUT /customerservice/customers
@@ -82,20 +82,20 @@ with the data:
updates the customer instance whose id is 123
-A GET request to path /monitor with id monitor-12345
+A GET request to path /demo/monitor with id monitor-12345
------------------------------------------------------------------------
-GET /customerservice/monitor
+GET /demo/customerservice/monitor
requestId: monitor-12345
------------------------------------------------------------------------
returns a continuous event stream on the customer
activities. Try invoking some customer related operations.
-A GET request to path /unmonitor with id monitor-12345
+A GET request to path /demo/unmonitor with id monitor-12345
------------------------------------------------------------------------
-GET /customerservice/unmonitor/monitor-12345
+GET /demo/customerservice/unmonitor/monitor-12345
------------------------------------------------------------------------
unregisters the event stream and returns its status.
@@ -141,7 +141,7 @@ the content. For example, the above POST example should use the Request
value:
------------------------------------------------------------------------
-POST /customerservice/customers
+POST /demo/customerservice/customers
Content-Type: text/xml; charset="utf-8"
<Customer>
http://git-wip-us.apache.org/repos/asf/cxf/blob/b52157a3/distribution/src/main/release/samples/jax_rs/websocket/src/main/java/demo/jaxrs/client/Client.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket/src/main/java/demo/jaxrs/client/Client.java b/distribution/src/main/release/samples/jax_rs/websocket/src/main/java/demo/jaxrs/client/Client.java
index dbdc589..1b91019 100644
--- a/distribution/src/main/release/samples/jax_rs/websocket/src/main/java/demo/jaxrs/client/Client.java
+++ b/distribution/src/main/release/samples/jax_rs/websocket/src/main/java/demo/jaxrs/client/Client.java
@@ -19,6 +19,8 @@
package demo.jaxrs.client;
+import demo.jaxrs.server.Server;
+
import java.io.InputStream;
import java.util.List;
@@ -31,21 +33,14 @@ public final class Client {
}
public static void main(String args[]) throws Exception {
- // Sent HTTP GET request to query all customer info
- /*
- * URL url = new URL("http://localhost:9000/customers");
- * System.out.println("Invoking server through HTTP GET to query all
- * customer info"); InputStream in = url.openStream(); StreamSource
- * source = new StreamSource(in); printSource(source);
- */
// Create a websocket client and connect to the target service
- WebSocketTestClient client = new WebSocketTestClient("ws://localhost:9000/");
+ WebSocketTestClient client = new WebSocketTestClient(Server.HOST_URL + Server.CONTEXT_PATH);
client.connect();
// Sent GET request to query customer info
System.out.println("Sent GET request to query customer info");
- client.sendTextMessage("GET /customerservice/customers/123");
+ client.sendTextMessage("GET " + Server.CONTEXT_PATH + "/customerservice/customers/123");
client.await(5);
List<WebSocketTestClient.Response> responses = client.getReceivedResponses();
System.out.println(responses.get(0));
@@ -53,7 +48,7 @@ public final class Client {
// Sent GET request to query sub resource product info
client.reset(1);
System.out.println("Sent GET request to query sub resource product info");
- client.sendTextMessage("GET /customerservice/orders/223/products/323");
+ client.sendTextMessage("GET " + Server.CONTEXT_PATH + "/customerservice/orders/223/products/323");
client.await(5);
responses = client.getReceivedResponses();
System.out.println(responses.get(0));
@@ -62,8 +57,8 @@ public final class Client {
client.reset(1);
System.out.println("Sent PUT request to update customer info");
String inputData = getStringFromInputStream(Client.class.getResourceAsStream("/update_customer.xml"));
- client.sendTextMessage("PUT /customerservice/customers\r\nContent-Type: text/xml;"
- + " charset=ISO-8859-1\r\n\r\n"
+ client.sendTextMessage("PUT " + Server.CONTEXT_PATH + "/customerservice/customers\r\n"
+ + "Content-Type: text/xml; charset=ISO-8859-1\r\n\r\n"
+ inputData);
client.await(5);
responses = client.getReceivedResponses();
@@ -73,20 +68,20 @@ public final class Client {
client.reset(1);
System.out.println("Sent POST request to add customer");
inputData = getStringFromInputStream(Client.class.getResourceAsStream("/add_customer.xml"));
- client.sendTextMessage("POST /customerservice/customers\r\nContent-Type: text/xml; "
+ client.sendTextMessage("POST " + Server.CONTEXT_PATH + "/customerservice/customers\r\nContent-Type: text/xml; "
+ "charset=ISO-8859-1\r\nAccept: text/xml\r\n\r\n" + inputData);
client.await(5);
responses = client.getReceivedResponses();
System.out.println(responses.get(0));
// Create another websocket client and connect to the target service
- WebSocketTestClient client2 = new WebSocketTestClient("ws://localhost:9000/");
+ WebSocketTestClient client2 = new WebSocketTestClient(Server.HOST_URL + Server.CONTEXT_PATH);
client2.connect();
// Sent GET request to monitor the customer activities
client2.reset(1);
System.out.println("Sent GET request to monitor activities");
- client2.sendTextMessage("GET /customerservice/monitor");
+ client2.sendTextMessage("GET " + Server.CONTEXT_PATH + "/customerservice/monitor");
client2.await(5);
responses = client2.getReceivedResponses();
System.out.println(responses.get(0));
@@ -94,8 +89,8 @@ public final class Client {
// one retrieval, one delete
client2.reset(2);
client.reset(2);
- client.sendTextMessage("GET /customerservice/customers/123");
- client.sendTextMessage("DELETE /customerservice/customers/235");
+ client.sendTextMessage("GET " + Server.CONTEXT_PATH + "/customerservice/customers/123");
+ client.sendTextMessage("DELETE " + Server.CONTEXT_PATH + "/customerservice/customers/235");
client2.await(5);
responses = client2.getReceivedResponses();
http://git-wip-us.apache.org/repos/asf/cxf/blob/b52157a3/distribution/src/main/release/samples/jax_rs/websocket/src/main/java/demo/jaxrs/server/Server.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket/src/main/java/demo/jaxrs/server/Server.java b/distribution/src/main/release/samples/jax_rs/websocket/src/main/java/demo/jaxrs/server/Server.java
index fe59dd0..851a512 100644
--- a/distribution/src/main/release/samples/jax_rs/websocket/src/main/java/demo/jaxrs/server/Server.java
+++ b/distribution/src/main/release/samples/jax_rs/websocket/src/main/java/demo/jaxrs/server/Server.java
@@ -23,13 +23,15 @@ import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
public class Server {
+ public static final String HOST_URL = "ws://localhost:9000";
+ public static final String CONTEXT_PATH = "/demo";
protected Server() throws Exception {
JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
sf.setResourceClasses(CustomerService.class);
sf.setResourceProvider(CustomerService.class,
new SingletonResourceProvider(new CustomerService()));
- sf.setAddress("ws://localhost:9000/");
+ sf.setAddress(HOST_URL + CONTEXT_PATH);
sf.create();
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/b52157a3/distribution/src/main/release/samples/jax_rs/websocket/src/main/resources/index.html
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket/src/main/resources/index.html b/distribution/src/main/release/samples/jax_rs/websocket/src/main/resources/index.html
index 87c8eaf..e7d81f4 100644
--- a/distribution/src/main/release/samples/jax_rs/websocket/src/main/resources/index.html
+++ b/distribution/src/main/release/samples/jax_rs/websocket/src/main/resources/index.html
@@ -29,14 +29,14 @@
<div id="output">
<div id="config" style="float: left;">
<strong>Service Endpoint URL:</strong><br />
- <input id="wsUri" size="72" style="width: 100%" value="ws://localhost:9000/"/>
+ <input id="wsUri" size="72" style="width: 100%" value="ws://localhost:9000/demo"/>
<br/>
<button id="connect">Connect</button>
<button id="disconnect">Disconnect</button>
<br />
<br />
<strong>Request:</strong><br />
- <textarea id="request" rows="10" cols="72" style="width: 100%;">GET /customerservice/customers/123</textarea>
+ <textarea id="request" rows="10" cols="72" style="width: 100%;">GET /demo/customerservice/customers/123</textarea>
<br/>
<button id="send">Send</button>
</div>
http://git-wip-us.apache.org/repos/asf/cxf/blob/b52157a3/distribution/src/main/release/samples/jax_rs/websocket/src/test/resources/client.js
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket/src/test/resources/client.js b/distribution/src/main/release/samples/jax_rs/websocket/src/test/resources/client.js
index 8e8d653..2df8d30 100644
--- a/distribution/src/main/release/samples/jax_rs/websocket/src/test/resources/client.js
+++ b/distribution/src/main/release/samples/jax_rs/websocket/src/test/resources/client.js
@@ -8,14 +8,16 @@
"use strict";
-var HOST_URL = 'http://localhost:9000/';
+// set the host url and path if the service runs at a different location
+var HOST_URL = 'http://localhost:9000';
+var CONTEXT_PATH = "/demo"
var reader = require('readline');
var prompt = reader.createInterface(process.stdin, process.stdout);
var atmosphere = require('atmosphere.js');
-var request = { url: HOST_URL,
+var request = { url: HOST_URL + CONTEXT_PATH,
transport : 'websocket',
trackMessageLength: false,
dropHeaders: false,
@@ -75,10 +77,10 @@ function doHelp() {
function doAdd(v) {
var req;
if (transport == 'websocket') {
- req = "POST /customerservice/customers\r\nContent-Type: text/xml; charset='utf-8'\r\nAccept: text/xml\r\n\r\n"
+ req = "POST " + CONTEXT_PATH + "/customerservice/customers\r\nContent-Type: text/xml; charset='utf-8'\r\nAccept: text/xml\r\n\r\n"
+ createAddCustomerPayload(v[0]);
} else if (transport == 'sse') {
- req = {"method": "POST", "url": HOST_URL + "customerservice/customers", "headers": {"content-type": "text/xml; charset=utf-8", "accept": "text/xml"}, "data": createAddCustomerPayload(v[0])}
+ req = {"method": "POST", "url": HOST_URL + CONTEXT_PATH + "/customerservice/customers", "headers": {"content-type": "text/xml; charset=utf-8", "accept": "text/xml"}, "data": createAddCustomerPayload(v[0])}
}
console.log("TRACE: sending ", req);
subSocket.push(req);
@@ -87,9 +89,9 @@ function doAdd(v) {
function doDelete(v) {
var req;
if (transport == 'websocket') {
- req = "DELETE /customerservice/customers/" + v[0];
+ req = "DELETE" + CONTEXT_PATH + "/customerservice/customers/" + v[0];
} else if (transport == 'sse') {
- req = {"method": "DELETE", "url": HOST_URL + "customerservice/customers/" + v[0]}
+ req = {"method": "DELETE", "url": HOST_URL + CONTEXT_PATH + "/customerservice/customers/" + v[0]}
}
console.log("TRACE: sending ", req);
subSocket.push(req);
@@ -98,9 +100,9 @@ function doDelete(v) {
function doGet(v) {
var req;
if (transport == 'websocket') {
- req = "GET /customerservice/customers/" + v[0];
+ req = "GET " + CONTEXT_PATH + "/customerservice/customers/" + v[0];
} else if (transport == 'sse') {
- req = {"method": "GET", "url": HOST_URL + "customerservice/customers/" + v[0]}
+ req = {"method": "GET", "url": HOST_URL + CONTEXT_PATH + "/customerservice/customers/" + v[0]}
}
console.log("TRACE: sending ", req);
subSocket.push(req);
@@ -109,9 +111,9 @@ function doGet(v) {
function doSubscribe() {
var req;
if (transport == 'websocket') {
- req = "GET /customerservice/monitor\r\nAccept: text/plain\r\n";
+ req = "GET " + CONTEXT_PATH + "/customerservice/monitor\r\nAccept: text/plain\r\n";
} else if (transport == 'sse') {
- req = {"method": "GET", "url": HOST_URL + "customerservice/monitor2", "headers": {"accept": "text/plain"}}
+ req = {"method": "GET", "url": HOST_URL + CONTEXT_PATH + "/customerservice/monitor", "headers": {"accept": "text/plain"}}
}
console.log("TRACE: sending ", req);
subSocket.push(req);
@@ -120,9 +122,9 @@ function doSubscribe() {
function doUnsubscribe() {
var req;
if (transport == 'websocket') {
- req = "GET /customerservice/unmonitor/*\r\nAccept: text/plain\r\n";
+ req = "GET " + CONTEXT_PATH + "/customerservice/unmonitor/*\r\nAccept: text/plain\r\n";
} else if (transport == 'sse') {
- req = {"method": "GET", "url": HOST_URL + "customerservice/unmonitor2/*", "headers": {"accept": "text/plain"}}
+ req = {"method": "GET", "url": HOST_URL + CONTEXT_PATH + "/customerservice/unmonitor/*", "headers": {"accept": "text/plain"}}
}
console.log("TRACE: sending ", req);
subSocket.push(req);
@@ -131,10 +133,10 @@ function doUnsubscribe() {
function doUpdate(v) {
var req;
if (transport == 'websocket') {
- req = "PUT /customerservice/customers\r\nContent-Type: text/xml; charset='utf-8'\r\nAccept: text/xml\r\n\r\n"
+ req = "PUT " + CONTEXT_PATH + "/customerservice/customers\r\nContent-Type: text/xml; charset='utf-8'\r\nAccept: text/xml\r\n\r\n"
+ createUpdateCustomerPayload(v[0], v[1]);
} else if (transport == 'sse') {
- req = {"method": "PUT", "url": HOST_URL + "customerservice/customers", "headers": {"content-type": "text/xml; charset=utf-8", "accept": "text/xml"}, "data": createUpdateCustomerPayload(v[0], v[1])}
+ req = {"method": "PUT", "url": HOST_URL + CONTEXT_PATH + "/customerservice/customers", "headers": {"content-type": "text/xml; charset=utf-8", "accept": "text/xml"}, "data": createUpdateCustomerPayload(v[0], v[1])}
}
console.log("TRACE: sending ", req);
subSocket.push(req);
[4/8] cxf git commit: [CXF-5855] enable atmosphere's sse handling;
update the sample
Posted by ay...@apache.org.
[CXF-5855] enable atmosphere's sse handling; update the sample
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/a529d270
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/a529d270
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/a529d270
Branch: refs/heads/3.1.x-fixes
Commit: a529d270668dabd1cfa6b040769cb25af97973db
Parents: 91197fd
Author: Akitoshi Yoshida <ay...@apache.org>
Authored: Thu Mar 17 00:11:58 2016 +0100
Committer: Akitoshi Yoshida <ay...@apache.org>
Committed: Tue Apr 5 13:36:57 2016 +0200
----------------------------------------------------------------------
.../release/samples/jax_rs/websocket/README.txt | 26 ++-
.../release/samples/jax_rs/websocket/pom.xml | 10 +-
.../java/demo/jaxrs/server/CustomerService.java | 105 ++++++++-
.../websocket/src/test/resources/client.js | 232 +++++++++++++++++++
.../websocket/atmosphere/AtmosphereUtils.java | 18 ++
.../AtmosphereWebSocketJettyDestination.java | 3 +-
.../AtmosphereWebSocketServletDestination.java | 3 +-
.../atmosphere/DefaultProtocolInterceptor.java | 90 ++++++-
8 files changed, 463 insertions(+), 24 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/a529d270/distribution/src/main/release/samples/jax_rs/websocket/README.txt
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket/README.txt b/distribution/src/main/release/samples/jax_rs/websocket/README.txt
index 09c43e8..f1d3455 100644
--- a/distribution/src/main/release/samples/jax_rs/websocket/README.txt
+++ b/distribution/src/main/release/samples/jax_rs/websocket/README.txt
@@ -6,6 +6,13 @@ This is a websocket transport version of JAX-RS Basic Demo.
A RESTful customer service is provided on URL ws://localhost:9000/customers.
Users access this URI to operate on customer.
+This sample includes two convenient clients: a plain javascript browser client
+and a node.js client based on atmosphere.
+
+
+Connecting to the server
+---------------------------------------
+
Open a websocket to ws://localhost:9000/ and send requests over the websocket.
A GET request to path /customerservice/customers/123
@@ -102,7 +109,6 @@ Please review the README in the samples directory before
continuing.
-
Building and running the demo using maven
---------------------------------------
@@ -118,6 +124,8 @@ Using either UNIX or Windows:
To remove the target dir, run mvn clean".
+Using Javascript client in Browser
+--------
Using a web browser that natively supports WebSocket (Safari, Chrome, Firefox):
After starting the server (see above), open the index.html page located at
@@ -140,3 +148,19 @@ Content-Type: text/xml; charset="utf-8"
<name>Jack</name>
</Customer>
------------------------------------------------------------------------
+
+
+Using Node.js client
+--------
+
+Go to samples/jax_rs/websocket/src/test/resources and at the console
+
+Assuming node (>=v4) and npm are installed, execute the following shell commands.
+
+% npm install atmosphere.js
+% node client.js
+
+This client program supports websocket and sse and allows
+you to choose your preferred protocol.
+
+
http://git-wip-us.apache.org/repos/asf/cxf/blob/a529d270/distribution/src/main/release/samples/jax_rs/websocket/pom.xml
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket/pom.xml b/distribution/src/main/release/samples/jax_rs/websocket/pom.xml
index abe9d3b..353e544 100644
--- a/distribution/src/main/release/samples/jax_rs/websocket/pom.xml
+++ b/distribution/src/main/release/samples/jax_rs/websocket/pom.xml
@@ -32,6 +32,7 @@
<cxf.version>${project.version}</cxf.version>
<!-- TODO remove these local entries after making the referenced dependency managed in parent/pom.xml -->
<cxf.ahc.version>1.8.5</cxf.ahc.version>
+ <cxf.atmosphere.version>2.3.7</cxf.atmosphere.version>
<cxf.jetty8.version>8.1.15.v20140411</cxf.jetty8.version>
<cxf.jetty9.version>9.2.2.v20140723</cxf.jetty9.version>
<cxf.jetty.version>${cxf.jetty8.version}</cxf.jetty.version>
@@ -207,6 +208,13 @@
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
-
+
+ <!-- add atmosphere -->
+ <dependency>
+ <groupId>org.atmosphere</groupId>
+ <artifactId>atmosphere-runtime</artifactId>
+ <version>${cxf.atmosphere.version}</version>
+ </dependency>
+
</dependencies>
</project>
http://git-wip-us.apache.org/repos/asf/cxf/blob/a529d270/distribution/src/main/release/samples/jax_rs/websocket/src/main/java/demo/jaxrs/server/CustomerService.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket/src/main/java/demo/jaxrs/server/CustomerService.java b/distribution/src/main/release/samples/jax_rs/websocket/src/main/java/demo/jaxrs/server/CustomerService.java
index 967e978..cc039ff 100644
--- a/distribution/src/main/release/samples/jax_rs/websocket/src/main/java/demo/jaxrs/server/CustomerService.java
+++ b/distribution/src/main/release/samples/jax_rs/websocket/src/main/java/demo/jaxrs/server/CustomerService.java
@@ -25,6 +25,9 @@ import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
@@ -43,13 +46,15 @@ import org.apache.cxf.transport.websocket.WebSocketConstants;
@Path("/customerservice/")
@Produces("text/xml")
public class CustomerService {
+ private static final int MAX_ERROR_COUNT = 5;
private static ExecutorService executor = Executors.newSingleThreadExecutor();
long currentId = 123;
Map<Long, Customer> customers = new HashMap<Long, Customer>();
Map<Long, Order> orders = new HashMap<Long, Order>();
- Map<String, OutputStream> monitors = new HashMap<String, OutputStream>();
-
+ Map<String, WriterHolder<OutputStream>> monitors = new HashMap<String, WriterHolder<OutputStream>>();
+ Map<String, WriterHolder<HttpServletResponse>> monitors2 = new HashMap<String, WriterHolder<HttpServletResponse>>();
+
public CustomerService() {
init();
}
@@ -60,7 +65,9 @@ public class CustomerService {
System.out.println("----invoking getCustomer, Customer id is: " + id);
long idNumber = Long.parseLong(id);
Customer customer = customers.get(idNumber);
- sendCustomerEvent("retrieved", customer);
+ if (customer != null) {
+ sendCustomerEvent("retrieved", customer);
+ }
return customer;
}
@@ -129,35 +136,83 @@ public class CustomerService {
final String key = reqid == null ? "*" : reqid;
return new StreamingOutput() {
public void write(final OutputStream out) throws IOException, WebApplicationException {
- monitors.put(key, out);
+ monitors.put(key, new WriterHolder(out, MAX_ERROR_COUNT));
out.write(("Subscribed at " + new java.util.Date()).getBytes());
}
+
};
}
@GET
+ @Path("/monitor2")
+ @Produces("text/*")
+ public void monitorCustomers2(
+ final @javax.ws.rs.core.Context HttpServletResponse httpResponse,
+ @HeaderParam(WebSocketConstants.DEFAULT_REQUEST_ID_KEY) String reqid) {
+ final String key = reqid == null ? "*" : reqid;
+ monitors2.put(key, new WriterHolder(httpResponse, MAX_ERROR_COUNT));
+ try {
+ httpResponse.getOutputStream().write(("Subscribed at " + new java.util.Date()).getBytes());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @GET
@Path("/unmonitor/{key}")
@Produces("text/*")
public String unmonitorCustomers(@PathParam("key") String key) {
return (monitors.remove(key) != null ? "Removed: " : "Already removed: ") + key;
}
+ @GET
+ @Path("/unmonitor2/{key}")
+ @Produces("text/*")
+ public String unmonitorCustomers2(@PathParam("key") String key) {
+ return (monitors2.remove(key) != null ? "Removed: " : "Already removed: ") + key;
+ }
+
private void sendCustomerEvent(final String msg, final Customer customer) {
executor.execute(new Runnable() {
public void run() {
try {
String t = msg + ": " + customer.getId() + "/" + customer.getName();
- for (Iterator<OutputStream> it = monitors.values().iterator(); it.hasNext();) {
- OutputStream out = it.next();
+ for (Iterator<WriterHolder<OutputStream>> it = monitors.values().iterator(); it.hasNext();) {
+ WriterHolder<OutputStream> wh = it.next();
try {
- out.write(t.getBytes());
+ wh.getValue().write(t.getBytes());
+ wh.getValue().flush();
+ wh.reset();
} catch (IOException e) {
- try {
- out.close();
- } catch (IOException e2) {
- // ignore;
+ System.out.println("----error writing to " + wh.getValue() + " " + wh.get());
+ if (wh.increment()) {
+ try {
+ wh.getValue().close();
+ } catch (IOException e2) {
+ // ignore;
+ }
+ it.remove();
+ System.out.println("----purged " + wh.getValue());
+ }
+ }
+ }
+ for (Iterator<WriterHolder<HttpServletResponse>> it = monitors2.values().iterator(); it.hasNext();) {
+ WriterHolder<HttpServletResponse> wh = it.next();
+ try {
+ wh.getValue().getOutputStream().write(t.getBytes());
+ wh.getValue().getOutputStream().flush();
+ wh.reset();
+ } catch (IOException e) {
+ System.out.println("----error writing to " + wh.getValue() + " " + wh.get());
+ if (wh.increment()) {
+ try {
+ wh.getValue().getOutputStream().close();
+ } catch (IOException e2) {
+ // ignore;
+ }
+ it.remove();
+ System.out.println("----purged " + wh.getValue());
}
- it.remove();
}
}
} catch (Exception e) {
@@ -183,4 +238,30 @@ public class CustomerService {
orders.put(o.getId(), o);
}
+ private static class WriterHolder<T> {
+ final private T value;
+ final private int max;
+ final private AtomicInteger errorCount;
+
+ public WriterHolder(T object, int max) {
+ this.value = object;
+ this.max = max;
+ this.errorCount = new AtomicInteger();
+ }
+
+ public T getValue() {
+ return value;
+ }
+
+ public int get() {
+ return errorCount.get();
+ }
+ public boolean increment() {
+ return max < errorCount.getAndIncrement();
+ }
+
+ public void reset() {
+ errorCount.getAndSet(0);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/a529d270/distribution/src/main/release/samples/jax_rs/websocket/src/test/resources/client.js
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket/src/test/resources/client.js b/distribution/src/main/release/samples/jax_rs/websocket/src/test/resources/client.js
new file mode 100644
index 0000000..7eb55f3
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/websocket/src/test/resources/client.js
@@ -0,0 +1,232 @@
+/**
+ * client.js
+ *
+ * A client program to interact with samples/jax_rs/websocket's server.
+ *
+ *
+ */
+
+"use strict";
+
+var HOST_URL = 'http://localhost:9100/';
+
+var reader = require('readline');
+var prompt = reader.createInterface(process.stdin, process.stdout);
+
+var atmosphere = require('atmosphere.js');
+
+var request = { url: HOST_URL,
+ transport : 'websocket',
+ trackMessageLength: false,
+ dropHeaders: false,
+ reconnectInterval : 5000};
+var isopen = false;
+
+const TRANSPORT_NAMES = ["websocket", "sse"];
+
+const COMMAND_LIST =
+ [["add name", "Add a new consumer and return the customer instance."],
+ ["delete id", "Delete the customer."],
+ ["get id", "Return the customere."],
+ ["quit", "Quit the application."],
+ ["subscribe", "Subscribe to the customer updatese."],
+ ["unsubscribe", "Unsubscribe from the customer updatese."],
+ ["update id name", "Update the customer."]];
+
+function selectOption(c, opts) {
+ var i = parseInt(c);
+ if (!(i >= 0 && i < opts.length)) {
+ console.log('Invalid selection: ' + c + '; Using ' + opts[0]);
+ i = 0;
+ }
+ return opts[i];
+}
+
+function getArgs(name, msg) {
+ var sp = name.length;
+ if (msg.length > name.length && msg.charAt(name.length) != ' ') {
+ // remove the command suffix
+ sp = msg.indexOf(' ', name.length);
+ if (sp < 0) {
+ sp = msg.length;
+ }
+ }
+ return msg.substring(sp).trim().split(' ');
+}
+
+function createAddCustomerPayload(name) {
+ return "<?xml version=\"1.0\"?>\n<Customer>\n <name>" + name + "</name>\n</Customer>\n";
+}
+
+function createUpdateCustomerPayload(id, name) {
+ return "<?xml version=\"1.0\"?>\n<Customer>\n <name>" + name + "</name>\n <id>" + id + "</id>\n</Customer>\n";
+}
+
+///
+
+function doHelp() {
+ console.log('Available commands');
+ for (var i = 0; i < COMMAND_LIST.length; i++) {
+ var c = COMMAND_LIST[i][0];
+ console.log(c + " ".substring(0, 20 - c.length) + COMMAND_LIST[i][1]);
+ }
+}
+
+function doAdd(v) {
+ var req;
+ if (transport == 'websocket') {
+ req = "POST /customerservice/customers\r\nContent-Type: text/xml; charset='utf-8'\r\nAccept: text/xml\r\n\r\n"
+ + createAddCustomerPayload(v[0]);
+ } else if (transport == 'sse') {
+ req = {"method": "POST", "url": HOST_URL + "customerservice/customers", "headers": {"content-type": "text/xml; charset=utf-8", "accept": "text/xml"}, "data": createAddCustomerPayload(v[0])}
+ }
+ console.log("TRACE: sending ", req);
+ subSocket.push(req);
+}
+
+function doDelete(v) {
+ var req;
+ if (transport == 'websocket') {
+ req = "DELETE /customerservice/customers/" + v[0];
+ } else if (transport == 'sse') {
+ req = {"method": "DELETE", "url": HOST_URL + "customerservice/customers/" + v[0]}
+ }
+ console.log("TRACE: sending ", req);
+ subSocket.push(req);
+}
+
+function doGet(v) {
+ var req;
+ if (transport == 'websocket') {
+ req = "GET /customerservice/customers/" + v[0];
+ } else if (transport == 'sse') {
+ req = {"method": "GET", "url": HOST_URL + "customerservice/customers/" + v[0]}
+ }
+ console.log("TRACE: sending ", req);
+ subSocket.push(req);
+}
+
+function doSubscribe() {
+ var req;
+ if (transport == 'websocket') {
+ req = "GET /customerservice/monitor\r\nAccept: text/plain\r\n";
+ } else if (transport == 'sse') {
+ req = {"method": "GET", "url": HOST_URL + "customerservice/monitor2", "headers": {"accept": "text/plain"}}
+ }
+ console.log("TRACE: sending ", req);
+ subSocket.push(req);
+}
+
+function doUnsubscribe() {
+ var req;
+ if (transport == 'websocket') {
+ req = "GET /customerservice/unmonitor/*\r\nAccept: text/plain\r\n";
+ } else if (transport == 'sse') {
+ req = {"method": "GET", "url": HOST_URL + "customerservice/unmonitor2/*", "headers": {"accept": "text/plain"}}
+ }
+ console.log("TRACE: sending ", req);
+ subSocket.push(req);
+}
+
+function doUpdate(v) {
+ var req;
+ if (transport == 'websocket') {
+ req = "PUT /customerservice/customers\r\nContent-Type: text/xml; charset='utf-8'\r\nAccept: text/xml\r\n\r\n"
+ + createUpdateCustomerPayload(v[0], v[1]);
+ } else if (transport == 'sse') {
+ req = {"method": "PUT", "url": HOST_URL + "customerservice/customers", "headers": {"content-type": "text/xml; charset=utf-8", "accept": "text/xml"}, "data": createUpdateCustomerPayload(v[0], v[1])}
+ }
+ console.log("TRACE: sending ", req);
+ subSocket.push(req);
+}
+
+function doQuit() {
+ subSocket.close();
+ process.exit(0);
+}
+
+///
+
+request.onOpen = function(response) {
+ isopen = true;
+ console.log('Connected using ' + response.transport);
+ prompt.setPrompt("> ", 2);
+ prompt.prompt();
+};
+
+request.onMessage = function (response) {
+ var message = response.responseBody;
+ console.log('Received: ', message);
+ console.log('------------------------------------------------------------------------');
+ prompt.setPrompt("> ", 2);
+ prompt.prompt();
+};
+
+request.onReconnect = function(response) {
+ console.log('Reconnecting ...');
+}
+
+request.onReopen = function(response) {
+ isopen = true;
+ console.log('Reconnected using ' + response.transport);
+ prompt.setPrompt("> ", 2);
+ prompt.prompt();
+}
+
+request.onClose = function(response) {
+ isopen = false;
+}
+
+request.onError = function(response) {
+ console.log("Sorry, something went wrong: " + response.responseBody);
+};
+
+var transport = null;
+var subSocket = null;
+var author = null;
+
+console.log("Select transport ...");
+for (var i = 0; i < TRANSPORT_NAMES.length; i++) {
+ console.log(i + ": " + TRANSPORT_NAMES[i]);
+}
+prompt.setPrompt("select: ", 6);
+prompt.prompt();
+
+prompt.
+on('line', function(line) {
+ var msg = line.trim();
+ if (transport == null) {
+ transport = selectOption(msg, TRANSPORT_NAMES);
+ request.transport = transport;
+ subSocket = atmosphere.subscribe(request);
+ console.log("Connecting using " + transport);
+ setTimeout(function() {
+ if (!isopen) {
+ console.log("Unable to open a connection. Terminated.");
+ process.exit(0);
+ }
+ }, 3000);
+ } else if (msg.length == 0) {
+ doHelp();
+ } else if (msg.indexOf("add") == 0) {
+ doAdd(getArgs("add", msg));
+ } else if (msg.indexOf("del") == 0) {
+ doDelete(getArgs("del", msg));
+ } else if (msg.indexOf("get") == 0) {
+ doGet(getArgs("get", msg));
+ } else if (msg.indexOf("quit") == 0) {
+ doQuit();
+ } else if (msg.indexOf("sub") == 0) {
+ doSubscribe(getArgs("sub", msg));
+ } else if (msg.indexOf("unsub") == 0) {
+ doUnsubscribe(getArgs("unsub", msg));
+ } else if (msg.indexOf("update") == 0) {
+ doUpdate(getArgs("update", msg));
+ }
+ prompt.setPrompt("> ", 2);
+ prompt.prompt();
+}).
+on('close', function() {
+ console.log("close");
+ process.exit(0);
+});
http://git-wip-us.apache.org/repos/asf/cxf/blob/a529d270/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/atmosphere/AtmosphereUtils.java
----------------------------------------------------------------------
diff --git a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/atmosphere/AtmosphereUtils.java b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/atmosphere/AtmosphereUtils.java
index 1a4a9b5..079792c 100644
--- a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/atmosphere/AtmosphereUtils.java
+++ b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/atmosphere/AtmosphereUtils.java
@@ -21,10 +21,18 @@ package org.apache.cxf.transport.websocket.atmosphere;
import java.util.List;
+import javax.servlet.http.HttpServletRequest;
+
import org.apache.cxf.Bus;
import org.apache.cxf.helpers.CastUtils;
import org.atmosphere.cpr.AtmosphereFramework;
import org.atmosphere.cpr.AtmosphereInterceptor;
+import org.atmosphere.cpr.HeaderConfig;
+import org.atmosphere.interceptor.CacheHeadersInterceptor;
+import org.atmosphere.interceptor.HeartbeatInterceptor;
+import org.atmosphere.interceptor.JavaScriptProtocol;
+import org.atmosphere.interceptor.SSEAtmosphereInterceptor;
+import org.atmosphere.util.Utils;
/**
*
@@ -36,6 +44,10 @@ public final class AtmosphereUtils {
public static void addInterceptors(AtmosphereFramework framework, Bus bus) {
Object ais = bus.getProperty("atmosphere.interceptors");
+ // pre-install those atmosphere default interceptors before the custom interceptors.
+ framework.interceptor(new CacheHeadersInterceptor()).interceptor(new HeartbeatInterceptor())
+ .interceptor(new SSEAtmosphereInterceptor()).interceptor(new JavaScriptProtocol());
+
if (ais == null || ais instanceof AtmosphereInterceptor) {
framework.interceptor(ais == null
? new DefaultProtocolInterceptor() : (AtmosphereInterceptor)ais);
@@ -43,9 +55,15 @@ public final class AtmosphereUtils {
}
if (ais instanceof List<?>) {
List<AtmosphereInterceptor> icps = CastUtils.cast((List<?>)ais);
+ // add the custom interceptors
for (AtmosphereInterceptor icp : icps) {
framework.interceptor(icp);
}
}
}
+
+ public static boolean useAtmosphere(HttpServletRequest req) {
+ return Utils.webSocketEnabled(req)
+ || req.getParameter(HeaderConfig.X_ATMOSPHERE_TRANSPORT) != null;
+ }
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/a529d270/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/atmosphere/AtmosphereWebSocketJettyDestination.java
----------------------------------------------------------------------
diff --git a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/atmosphere/AtmosphereWebSocketJettyDestination.java b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/atmosphere/AtmosphereWebSocketJettyDestination.java
index 0e02923..d0cc806 100644
--- a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/atmosphere/AtmosphereWebSocketJettyDestination.java
+++ b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/atmosphere/AtmosphereWebSocketJettyDestination.java
@@ -45,7 +45,6 @@ import org.atmosphere.cpr.AtmosphereRequest;
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.AtmosphereResponse;
import org.atmosphere.handler.AbstractReflectorAtmosphereHandler;
-import org.atmosphere.util.Utils;
import org.eclipse.jetty.server.Request;
@@ -119,7 +118,7 @@ public class AtmosphereWebSocketJettyDestination extends JettyHTTPDestination im
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
- if (Utils.webSocketEnabled(request)) {
+ if (AtmosphereUtils.useAtmosphere(request)) {
try {
framework.doCometSupport(AtmosphereRequest.wrap(request),
AtmosphereResponse.wrap(response));
http://git-wip-us.apache.org/repos/asf/cxf/blob/a529d270/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/atmosphere/AtmosphereWebSocketServletDestination.java
----------------------------------------------------------------------
diff --git a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/atmosphere/AtmosphereWebSocketServletDestination.java b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/atmosphere/AtmosphereWebSocketServletDestination.java
index 6459150..a4e702c 100644
--- a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/atmosphere/AtmosphereWebSocketServletDestination.java
+++ b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/atmosphere/AtmosphereWebSocketServletDestination.java
@@ -41,7 +41,6 @@ import org.atmosphere.cpr.AtmosphereRequest;
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.AtmosphereResponse;
import org.atmosphere.handler.AbstractReflectorAtmosphereHandler;
-import org.atmosphere.util.Utils;
/**
*
@@ -69,7 +68,7 @@ public class AtmosphereWebSocketServletDestination extends ServletDestination im
@Override
public void invoke(ServletConfig config, ServletContext context, HttpServletRequest req,
HttpServletResponse resp) throws IOException {
- if (Utils.webSocketEnabled(req)) {
+ if (AtmosphereUtils.useAtmosphere(req)) {
try {
framework.doCometSupport(AtmosphereRequest.wrap(req),
AtmosphereResponse.wrap(resp));
http://git-wip-us.apache.org/repos/asf/cxf/blob/a529d270/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/atmosphere/DefaultProtocolInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/atmosphere/DefaultProtocolInterceptor.java b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/atmosphere/DefaultProtocolInterceptor.java
index 1a2cd9a..2631d51 100644
--- a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/atmosphere/DefaultProtocolInterceptor.java
+++ b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/atmosphere/DefaultProtocolInterceptor.java
@@ -37,8 +37,8 @@ import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.transport.websocket.InvalidPathException;
import org.apache.cxf.transport.websocket.WebSocketConstants;
import org.apache.cxf.transport.websocket.WebSocketUtils;
-import org.atmosphere.config.service.AtmosphereInterceptorService;
import org.atmosphere.cpr.Action;
+import org.atmosphere.cpr.ApplicationConfig;
import org.atmosphere.cpr.AsyncIOInterceptor;
import org.atmosphere.cpr.AsyncIOInterceptorAdapter;
import org.atmosphere.cpr.AsyncIOWriter;
@@ -48,20 +48,24 @@ import org.atmosphere.cpr.AtmosphereInterceptorAdapter;
import org.atmosphere.cpr.AtmosphereInterceptorWriter;
import org.atmosphere.cpr.AtmosphereRequest;
import org.atmosphere.cpr.AtmosphereResource;
+import org.atmosphere.cpr.AtmosphereResourceEvent;
+import org.atmosphere.cpr.AtmosphereResourceEventListenerAdapter;
import org.atmosphere.cpr.AtmosphereResponse;
import org.atmosphere.cpr.FrameworkConfig;
/**
* DefaultProtocolInterceptor provides the default CXF's WebSocket protocol that uses.
*
+ * This interceptor is automatically engaged when no atmosphere interceptor is configured.
*/
-@AtmosphereInterceptorService
public class DefaultProtocolInterceptor extends AtmosphereInterceptorAdapter {
private static final Logger LOG = LogUtils.getL7dLogger(DefaultProtocolInterceptor.class);
private static final String REQUEST_DISPATCHED = "request.dispatched";
private static final String RESPONSE_PARENT = "response.parent";
+ private Map<String, AtmosphereResponse> suspendedResponses = new HashMap<String, AtmosphereResponse>();
+
private final AsyncIOInterceptor interceptor = new Interceptor();
private Pattern includedheaders;
@@ -102,10 +106,77 @@ public class DefaultProtocolInterceptor extends AtmosphereInterceptorAdapter {
this.excludedheaders = excludedheaders;
}
- @SuppressWarnings("deprecation")
@Override
public Action inspect(final AtmosphereResource r) {
LOG.log(Level.FINE, "inspect");
+ if (AtmosphereResource.TRANSPORT.WEBSOCKET != r.transport()
+ && AtmosphereResource.TRANSPORT.SSE != r.transport()
+ && AtmosphereResource.TRANSPORT.POLLING != r.transport()) {
+ LOG.fine("Skipping ignorable request");
+ return Action.CONTINUE;
+ }
+ if (AtmosphereResource.TRANSPORT.POLLING == r.transport()) {
+ final String saruuid = (String)r.getRequest()
+ .getAttribute(ApplicationConfig.SUSPENDED_ATMOSPHERE_RESOURCE_UUID);
+ final AtmosphereResponse suspendedResponse = suspendedResponses.get(saruuid);
+ LOG.fine("Attaching a proxy writer to suspended response");
+ r.getResponse().asyncIOWriter(new AtmosphereInterceptorWriter() {
+ @Override
+ public AsyncIOWriter write(AtmosphereResponse r, String data) throws IOException {
+ suspendedResponse.write(data);
+ suspendedResponse.flushBuffer();
+ return this;
+ }
+
+ @Override
+ public AsyncIOWriter write(AtmosphereResponse r, byte[] data) throws IOException {
+ suspendedResponse.write(data);
+ suspendedResponse.flushBuffer();
+ return this;
+ }
+
+ @Override
+ public AsyncIOWriter write(AtmosphereResponse r, byte[] data, int offset, int length)
+ throws IOException {
+ suspendedResponse.write(data, offset, length);
+ suspendedResponse.flushBuffer();
+ return this;
+ }
+ });
+ // REVISIT we need to keep this response's asyncwriter alive so that data can be written to the
+ // suspended response, but investigate if there is a better alternative.
+ r.getResponse().destroyable(false);
+ return Action.CONTINUE;
+ }
+
+ r.addEventListener(new AtmosphereResourceEventListenerAdapter() {
+ @Override
+ public void onSuspend(AtmosphereResourceEvent event) {
+ final String srid = (String)event.getResource().getRequest()
+ .getAttribute(ApplicationConfig.SUSPENDED_ATMOSPHERE_RESOURCE_UUID);
+ LOG.log(Level.FINE, "Registrering suspended resource: {}", srid);
+ suspendedResponses.put(srid, event.getResource().getResponse());
+
+ AsyncIOWriter writer = event.getResource().getResponse().getAsyncIOWriter();
+ if (writer == null) {
+ writer = new AtmosphereInterceptorWriter();
+ r.getResponse().asyncIOWriter(writer);
+ }
+ if (writer instanceof AtmosphereInterceptorWriter) {
+ ((AtmosphereInterceptorWriter)writer).interceptor(interceptor);
+ }
+ }
+
+ @Override
+ public void onDisconnect(AtmosphereResourceEvent event) {
+ super.onDisconnect(event);
+ final String srid = (String)event.getResource().getRequest()
+ .getAttribute(ApplicationConfig.SUSPENDED_ATMOSPHERE_RESOURCE_UUID);
+ LOG.log(Level.FINE, "Unregistrering suspended resource: {}", srid);
+ suspendedResponses.remove(srid);
+ }
+
+ });
AtmosphereRequest request = r.getRequest();
if (request.getAttribute(REQUEST_DISPATCHED) == null) {
@@ -115,6 +186,11 @@ public class DefaultProtocolInterceptor extends AtmosphereInterceptorAdapter {
try {
byte[] data = WebSocketUtils.readBody(request.getInputStream());
if (data.length == 0) {
+ if (AtmosphereResource.TRANSPORT.WEBSOCKET == r.transport()
+ || AtmosphereResource.TRANSPORT.SSE == r.transport()) {
+ r.suspend();
+ return Action.SUSPEND;
+ }
return Action.CANCELLED;
}
@@ -124,10 +200,10 @@ public class DefaultProtocolInterceptor extends AtmosphereInterceptorAdapter {
try {
AtmosphereRequest ar = createAtmosphereRequest(request, data);
response = new WrappedAtmosphereResponse(r.getResponse(), ar);
- ar.attributes().put(REQUEST_DISPATCHED, "true");
+ ar.localAttributes().put(REQUEST_DISPATCHED, "true");
String refid = ar.getHeader(WebSocketConstants.DEFAULT_REQUEST_ID_KEY);
if (refid != null) {
- ar.attributes().put(WebSocketConstants.DEFAULT_REQUEST_ID_KEY, refid);
+ ar.localAttributes().put(WebSocketConstants.DEFAULT_REQUEST_ID_KEY, refid);
}
// This is a new request, we must clean the Websocket AtmosphereResource.
request.removeAttribute(FrameworkConfig.INJECTED_ATMOSPHERE_RESOURCE);
@@ -156,7 +232,6 @@ public class DefaultProtocolInterceptor extends AtmosphereInterceptorAdapter {
return Action.CANCELLED;
} catch (IOException e) {
LOG.log(Level.WARNING, "Error during protocol processing", e);
- return Action.CONTINUE;
}
} else {
request.destroyable(false);
@@ -229,6 +304,9 @@ public class DefaultProtocolInterceptor extends AtmosphereInterceptorAdapter {
AtmosphereRequest request = response.request();
String refid = (String)request.getAttribute(WebSocketConstants.DEFAULT_REQUEST_ID_KEY);
+ if (AtmosphereResource.TRANSPORT.WEBSOCKET != response.resource().transport()) {
+ return payload;
+ }
Map<String, String> headers = new HashMap<String, String>();
if (refid != null) {
response.addHeader(WebSocketConstants.DEFAULT_RESPONSE_ID_KEY, refid);
[7/8] cxf git commit: add a blueprint version of websocket sample for
karaf
Posted by ay...@apache.org.
add a blueprint version of websocket sample for karaf
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/5ce68277
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/5ce68277
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/5ce68277
Branch: refs/heads/3.1.x-fixes
Commit: 5ce682771ae91eab61e25eaa90ef416168eb4402
Parents: de9b793
Author: Akitoshi Yoshida <ay...@apache.org>
Authored: Tue Apr 5 10:38:42 2016 +0200
Committer: Akitoshi Yoshida <ay...@apache.org>
Committed: Tue Apr 5 13:36:58 2016 +0200
----------------------------------------------------------------------
.../samples/jax_rs/websocket_osgi/README.txt | 94 +++++++
.../samples/jax_rs/websocket_osgi/pom.xml | 94 +++++++
.../main/java/demo/jaxrs/server/Customer.java | 43 +++
.../java/demo/jaxrs/server/CustomerService.java | 271 +++++++++++++++++++
.../src/main/java/demo/jaxrs/server/Order.java | 69 +++++
.../main/java/demo/jaxrs/server/Product.java | 43 +++
.../resources/OSGI-INF/blueprint/context.xml | 47 ++++
.../websocket_osgi/src/test/resources/client.js | 234 ++++++++++++++++
8 files changed, 895 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/5ce68277/distribution/src/main/release/samples/jax_rs/websocket_osgi/README.txt
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket_osgi/README.txt b/distribution/src/main/release/samples/jax_rs/websocket_osgi/README.txt
new file mode 100644
index 0000000..60d7705
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/websocket_osgi/README.txt
@@ -0,0 +1,94 @@
+JAX-RS WebSocket OSGi Blueprint Demo
+=================
+
+This is an OSGi Blueprint version of JAX-RS WebSocket Demo.
+
+Building and running the demo using maven
+---------------------------------------
+
+From the base directory of this sample (i.e., where this README file is
+located), the maven pom.xml file can be used to build and run the demo.
+
+
+Using either UNIX or Windows:
+
+ mvn install
+
+This will produce a war file in the target folder.
+
+
+Starting Karaf (refer to http://karaf.apache.org/manual/latest-3.0.x/quick-start.html)
+
+ bin/karaf
+
+
+ __ __ ____
+ / //_/____ __________ _/ __/
+ / ,< / __ `/ ___/ __ `/ /_
+ / /| |/ /_/ / / / /_/ / __/
+ /_/ |_|\__,_/_/ \__,_/_/
+
+ Apache Karaf (3.0.4)
+
+ Hit '<tab>' for a list of available commands
+ and '[cmd] --help' for help on a specific command.
+ Hit '<ctrl-d>' or type 'system:shutdown' or 'logout' to shutdown Karaf.
+
+
+In order to install CXF's features, you need to add the CXF's features repo using
+
+ feature:repo-add cxf 3.n.m
+
+ where 3.n.m corresponds to a valid CXF version number
+
+Install CXF's cxf-jaxrs and cxf-transports-websocket-server features that installs all the required bundles
+for this demo bundle.
+
+ feature:install cxf-jaxrs cxf-transports-websocket-server
+
+Install this demo bundle (using the appropriate bundle version number)
+
+ install -s mvn:org.apache.cxf.samples/jax_rs_websocket_osgi/3.n.m
+
+And verify the bundles are installed.
+
+karaf@root()> feature:repo-add cxf 3.2.0-SNAPSHOT
+Adding feature url mvn:org.apache.cxf.karaf/apache-cxf/3.2.0-SNAPSHOT/xml/features
+karaf@root()> feature:install cxf-jaxrs cxf-transports-websocket-server
+karaf@root()> list -t 0 | grep CXF
+ 80 | Active | 40 | 3.2.0.SNAPSHOT | Apache CXF Core
+ 81 | Active | 40 | 3.2.0.SNAPSHOT | Apache CXF Runtime Management
+100 | Active | 40 | 3.2.0.SNAPSHOT | Apache CXF Runtime HTTP Transport
+102 | Active | 40 | 3.2.0.SNAPSHOT | Apache CXF JAX-RS Extensions: Providers
+103 | Active | 40 | 3.2.0.SNAPSHOT | Apache CXF JAX-RS Extensions: Search
+104 | Active | 40 | 3.2.0.SNAPSHOT | Apache CXF JAX-RS Service Description
+105 | Active | 40 | 3.2.0.SNAPSHOT | Apache CXF Runtime JAX-RS Frontend
+106 | Active | 40 | 3.2.0.SNAPSHOT | Apache CXF JAX-RS Client
+108 | Active | 40 | 3.2.0.SNAPSHOT | Apache CXF Runtime WebSocket Transport
+karaf@root()> install -s mvn:org.apache.cxf.samples/jax_rs_websocket_osgi
+Bundle ID: 109
+karaf@root()> list
+START LEVEL 100 , List Threshold: 50
+ ID | State | Lvl | Version | Name
+---------------------------------------------------------------------
+107 | Active | 80 | 2.4.3 | atmosphere-runtime
+109 | Active | 80 | 3.2.0.SNAPSHOT | JAX-RS WebSocket Blueprint Demo
+karaf@root()>
+
+
+Visit http://localhost:8181/cxf/ to see if this RESTful service is registered.
+
+Using Node.js client to test the service
+--------
+
+Go to samples/jax_rs/websocket_osgi/src/test/resources and at the console
+
+Assuming node (>=v4) and npm are installed, execute the following shell commands.
+
+% npm install atmosphere.js
+% node client.js
+
+This client program supports websocket and sse and allows
+you to choose your preferred protocol.
+
+
http://git-wip-us.apache.org/repos/asf/cxf/blob/5ce68277/distribution/src/main/release/samples/jax_rs/websocket_osgi/pom.xml
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket_osgi/pom.xml b/distribution/src/main/release/samples/jax_rs/websocket_osgi/pom.xml
new file mode 100644
index 0000000..e0d1234
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/websocket_osgi/pom.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<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>
+ <artifactId>jax_rs_websocket_osgi</artifactId>
+ <packaging>bundle</packaging>
+ <name>JAX-RS WebSocket Blueprint Demo</name>
+ <description>JAX-RS WebSocket Demo</description>
+
+ <parent>
+ <groupId>org.apache.cxf.samples</groupId>
+ <artifactId>cxf-samples</artifactId>
+ <version>3.2.0-SNAPSHOT</version>
+ <relativePath>../..</relativePath>
+ </parent>
+ <properties>
+ <cxf.version>${project.version}</cxf.version>
+ <!-- TODO remove these local entries after making the referenced dependency managed in parent/pom.xml -->
+ <cxf.atmosphere.version>2.4.3</cxf.atmosphere.version>
+ <cxf.jetty92.version>9.2.15.v20160210</cxf.jetty92.version>
+ <cxf.jetty93.version>9.3.5.v20151012</cxf.jetty93.version>
+ <cxf.jetty.version>${cxf.jetty93.version}</cxf.jetty.version>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>${project.groupId}.${project.artifactId};blueprint.aries.xml-validation:=false</Bundle-SymbolicName>
+ <Import-Package>
+ javax.ws.rs,
+ javax.ws.rs.core,
+ org.apache.cxf.jaxrs.provider,
+ org.osgi.service.blueprint,
+ *
+ </Import-Package>
+ <Export-Package>
+ </Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <!-- cxt et al -->
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-transports-http</artifactId>
+ <version>3.2.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-transports-websocket</artifactId>
+ <version>3.2.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+ <version>3.2.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>javax.ws.rs-api</artifactId>
+ </dependency>
+
+ <!-- add atmosphere -->
+ <dependency>
+ <groupId>org.atmosphere</groupId>
+ <artifactId>atmosphere-runtime</artifactId>
+ <version>${cxf.atmosphere.version}</version>
+ </dependency>
+
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/cxf/blob/5ce68277/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/main/java/demo/jaxrs/server/Customer.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/main/java/demo/jaxrs/server/Customer.java b/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/main/java/demo/jaxrs/server/Customer.java
new file mode 100644
index 0000000..44025f0
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/main/java/demo/jaxrs/server/Customer.java
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package demo.jaxrs.server;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "Customer")
+public class Customer {
+ private long id;
+ private String name;
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5ce68277/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/main/java/demo/jaxrs/server/CustomerService.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/main/java/demo/jaxrs/server/CustomerService.java b/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/main/java/demo/jaxrs/server/CustomerService.java
new file mode 100644
index 0000000..f77f8aa
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/main/java/demo/jaxrs/server/CustomerService.java
@@ -0,0 +1,271 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package demo.jaxrs.server;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.servlet.http.HttpServletResponse;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.StreamingOutput;
+
+import org.apache.cxf.transport.websocket.WebSocketConstants;
+
+@Path("/customerservice/")
+@Produces("text/xml")
+public class CustomerService {
+ private static final int MAX_ERROR_COUNT = 5;
+ private static ExecutorService executor = Executors.newSingleThreadExecutor();
+
+ long currentId = 123;
+ Map<Long, Customer> customers = new HashMap<Long, Customer>();
+ Map<Long, Order> orders = new HashMap<Long, Order>();
+ Map<String, WriterHolder<OutputStream>> monitors = new HashMap<String, WriterHolder<OutputStream>>();
+ Map<String, WriterHolder<HttpServletResponse>> monitors2 = new HashMap<String, WriterHolder<HttpServletResponse>>();
+
+ public CustomerService() {
+ init();
+ }
+
+ @GET
+ @Path("/customers/{id}/")
+ public Customer getCustomer(@PathParam("id") String id) {
+ System.out.println("----invoking getCustomer, Customer id is: " + id);
+ long idNumber = Long.parseLong(id);
+ Customer customer = customers.get(idNumber);
+ if (customer != null) {
+ sendCustomerEvent("retrieved", customer);
+ }
+ return customer;
+ }
+
+ @PUT
+ @Path("/customers/")
+ public Response updateCustomer(Customer customer) {
+ System.out.println("----invoking updateCustomer, Customer name is: " + customer.getName());
+ Customer c = customers.get(customer.getId());
+ Response r;
+ if (c != null) {
+ customers.put(customer.getId(), customer);
+ r = Response.ok().build();
+ sendCustomerEvent("updated", customer);
+ } else {
+ r = Response.notModified().build();
+ }
+
+ return r;
+ }
+
+ @POST
+ @Path("/customers/")
+ public Response addCustomer(Customer customer) {
+ System.out.println("----invoking addCustomer, Customer name is: " + customer.getName());
+ customer.setId(++currentId);
+
+ customers.put(customer.getId(), customer);
+ sendCustomerEvent("added", customer);
+ return Response.ok(customer).build();
+ }
+
+ @DELETE
+ @Path("/customers/{id}/")
+ public Response deleteCustomer(@PathParam("id") String id) {
+ System.out.println("----invoking deleteCustomer, Customer id is: " + id);
+ long idNumber = Long.parseLong(id);
+ Customer c = customers.get(idNumber);
+
+ Response r;
+ if (c != null) {
+ r = Response.ok().build();
+ Customer customer = customers.remove(idNumber);
+ if (customer != null) {
+ sendCustomerEvent("deleted", customer);
+ }
+ } else {
+ r = Response.notModified().build();
+ }
+
+ return r;
+ }
+
+ @Path("/orders/{orderId}/")
+ public Order getOrder(@PathParam("orderId") String orderId) {
+ System.out.println("----invoking getOrder, Order id is: " + orderId);
+ long idNumber = Long.parseLong(orderId);
+ Order c = orders.get(idNumber);
+ return c;
+ }
+
+ @GET
+ @Path("/monitor")
+ @Produces("text/*")
+ public StreamingOutput monitorCustomers(
+ @HeaderParam(WebSocketConstants.DEFAULT_REQUEST_ID_KEY) String reqid) {
+ final String key = reqid == null ? "*" : reqid;
+ return new StreamingOutput() {
+ public void write(final OutputStream out) throws IOException, WebApplicationException {
+ monitors.put(key, new WriterHolder(out, MAX_ERROR_COUNT));
+ out.write(("Subscribed at " + new java.util.Date()).getBytes());
+ }
+
+ };
+ }
+
+ @GET
+ @Path("/monitor2")
+ @Produces("text/*")
+ public void monitorCustomers2(
+ final @javax.ws.rs.core.Context HttpServletResponse httpResponse,
+ @HeaderParam(WebSocketConstants.DEFAULT_REQUEST_ID_KEY) String reqid) {
+ final String key = reqid == null ? "*" : reqid;
+ monitors2.put(key, new WriterHolder(httpResponse, MAX_ERROR_COUNT));
+ try {
+ httpResponse.getOutputStream().write(("Subscribed at " + new java.util.Date()).getBytes());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @GET
+ @Path("/unmonitor/{key}")
+ @Produces("text/*")
+ public String unmonitorCustomers(@PathParam("key") String key) {
+ return (monitors.remove(key) != null ? "Removed: " : "Already removed: ") + key;
+ }
+
+ @GET
+ @Path("/unmonitor2/{key}")
+ @Produces("text/*")
+ public String unmonitorCustomers2(@PathParam("key") String key) {
+ return (monitors2.remove(key) != null ? "Removed: " : "Already removed: ") + key;
+ }
+
+ private void sendCustomerEvent(final String msg, final Customer customer) {
+ executor.execute(new Runnable() {
+ public void run() {
+ try {
+ String t = msg + ": " + customer.getId() + "/" + customer.getName();
+ for (Iterator<WriterHolder<OutputStream>> it = monitors.values().iterator(); it.hasNext();) {
+ WriterHolder<OutputStream> wh = it.next();
+ try {
+ wh.getValue().write(t.getBytes());
+ wh.getValue().flush();
+ wh.reset();
+ } catch (IOException e) {
+ System.out.println("----error writing to " + wh.getValue() + " " + wh.get());
+ if (wh.increment()) {
+ // the max error count reached; purging the output resource
+ e.printStackTrace();
+ try {
+ wh.getValue().close();
+ } catch (IOException e2) {
+ // ignore;
+ }
+ it.remove();
+ System.out.println("----purged " + wh.getValue());
+ }
+ }
+ }
+ for (Iterator<WriterHolder<HttpServletResponse>> it = monitors2.values().iterator(); it.hasNext();) {
+ WriterHolder<HttpServletResponse> wh = it.next();
+ try {
+ wh.getValue().getOutputStream().write(t.getBytes());
+ wh.getValue().getOutputStream().flush();
+ wh.reset();
+ } catch (IOException e) {
+ System.out.println("----error writing to " + wh.getValue() + " " + wh.get());
+ if (wh.increment()) {
+ // the max error count reached; purging the output resource
+ e.printStackTrace();
+ try {
+ wh.getValue().getOutputStream().close();
+ } catch (IOException e2) {
+ // ignore;
+ }
+ it.remove();
+ System.out.println("----purged " + wh.getValue());
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ });
+
+ }
+ final void init() {
+ Customer c = new Customer();
+ c.setName("John");
+ c.setId(123);
+ customers.put(c.getId(), c);
+ c = new Customer();
+ c.setName("Homer");
+ c.setId(235);
+ customers.put(c.getId(), c);
+
+ Order o = new Order();
+ o.setDescription("order 223");
+ o.setId(223);
+ orders.put(o.getId(), o);
+ }
+
+ private static class WriterHolder<T> {
+ final private T value;
+ final private int max;
+ final private AtomicInteger errorCount;
+
+ public WriterHolder(T object, int max) {
+ this.value = object;
+ this.max = max;
+ this.errorCount = new AtomicInteger();
+ }
+
+ public T getValue() {
+ return value;
+ }
+
+ public int get() {
+ return errorCount.get();
+ }
+ public boolean increment() {
+ return max < errorCount.getAndIncrement();
+ }
+
+ public void reset() {
+ errorCount.getAndSet(0);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5ce68277/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/main/java/demo/jaxrs/server/Order.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/main/java/demo/jaxrs/server/Order.java b/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/main/java/demo/jaxrs/server/Order.java
new file mode 100644
index 0000000..a06b68b
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/main/java/demo/jaxrs/server/Order.java
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package demo.jaxrs.server;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "Order")
+public class Order {
+ private long id;
+ private String description;
+ private Map<Long, Product> products = new HashMap<Long, Product>();
+
+ public Order() {
+ init();
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String d) {
+ this.description = d;
+ }
+
+ @GET
+ @Path("products/{productId}/")
+ public Product getProduct(@PathParam("productId")int productId) {
+ System.out.println("----invoking getProduct with id: " + productId);
+ Product p = products.get(new Long(productId));
+ return p;
+ }
+
+ final void init() {
+ Product p = new Product();
+ p.setId(323);
+ p.setDescription("product 323");
+ products.put(p.getId(), p);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5ce68277/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/main/java/demo/jaxrs/server/Product.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/main/java/demo/jaxrs/server/Product.java b/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/main/java/demo/jaxrs/server/Product.java
new file mode 100644
index 0000000..4452ec5
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/main/java/demo/jaxrs/server/Product.java
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package demo.jaxrs.server;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "Product")
+public class Product {
+ private long id;
+ private String description;
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String d) {
+ this.description = d;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5ce68277/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/main/resources/OSGI-INF/blueprint/context.xml
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/main/resources/OSGI-INF/blueprint/context.xml b/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/main/resources/OSGI-INF/blueprint/context.xml
new file mode 100644
index 0000000..9bd1cdf
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/main/resources/OSGI-INF/blueprint/context.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<!-- START SNIPPET: blueprint -->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:cxf="http://cxf.apache.org/blueprint/core"
+ xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
+
+ xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
+ http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
+ http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd">
+
+
+ <!-- Application resources -->
+ <bean id="sampleResource" class="demo.jaxrs.server.CustomerService" />
+
+ <cxf:bus>
+ <cxf:features>
+ <cxf:logging />
+ </cxf:features>
+ </cxf:bus>
+
+ <jaxrs:server id="websocketSampleService" address="/websocketSample" transportId="http://cxf.apache.org/transports/websocket">
+ <jaxrs:serviceBeans>
+ <ref component-id="sampleResource" />
+ </jaxrs:serviceBeans>
+ </jaxrs:server>
+
+</blueprint>
+<!-- END SNIPPET: blueprint -->
http://git-wip-us.apache.org/repos/asf/cxf/blob/5ce68277/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/test/resources/client.js
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/test/resources/client.js b/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/test/resources/client.js
new file mode 100644
index 0000000..492d520
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/websocket_osgi/src/test/resources/client.js
@@ -0,0 +1,234 @@
+/**
+ * client.js
+ *
+ * A client program to interact with samples/jax_rs/websocket_osgi service
+ *
+ *
+ */
+
+"use strict";
+
+// set the host url and path if the service runs at a different location
+var HOST_URL = 'http://localhost:8181';
+var CONTEXT_PATH = "/cxf/websocketSample"
+
+var reader = require('readline');
+var prompt = reader.createInterface(process.stdin, process.stdout);
+
+var atmosphere = require('atmosphere.js');
+
+var request = { url: HOST_URL + CONTEXT_PATH,
+ transport : 'websocket',
+ trackMessageLength: false,
+ dropHeaders: false,
+ reconnectInterval : 5000};
+var isopen = false;
+
+const TRANSPORT_NAMES = ["websocket", "sse"];
+
+const COMMAND_LIST =
+ [["add name", "Add a new consumer and return the customer instance. (e.g., add green)"],
+ ["delete id", "Delete the customer. (e.g., delete 124)"],
+ ["get id", "Return the customere. (e.g., get 123)"],
+ ["quit", "Quit the application."],
+ ["subscribe", "Subscribe to the customer queries."],
+ ["unsubscribe", "Unsubscribe from the customer queries."],
+ ["update id name", "Update the customer. (e.g., update 125 red)"]];
+
+function selectOption(c, opts) {
+ var i = parseInt(c);
+ if (!(i >= 0 && i < opts.length)) {
+ console.log('Invalid selection: ' + c + '; Using ' + opts[0]);
+ i = 0;
+ }
+ return opts[i];
+}
+
+function getArgs(name, msg) {
+ var sp = name.length;
+ if (msg.length > name.length && msg.charAt(name.length) != ' ') {
+ // remove the command suffix
+ sp = msg.indexOf(' ', name.length);
+ if (sp < 0) {
+ sp = msg.length;
+ }
+ }
+ return msg.substring(sp).trim().split(' ');
+}
+
+function createAddCustomerPayload(name) {
+ return "<?xml version=\"1.0\"?>\n<Customer>\n <name>" + name + "</name>\n</Customer>\n";
+}
+
+function createUpdateCustomerPayload(id, name) {
+ return "<?xml version=\"1.0\"?>\n<Customer>\n <name>" + name + "</name>\n <id>" + id + "</id>\n</Customer>\n";
+}
+
+///
+
+function doHelp() {
+ console.log('Available commands');
+ for (var i = 0; i < COMMAND_LIST.length; i++) {
+ var c = COMMAND_LIST[i][0];
+ console.log(c + " ".substring(0, 20 - c.length) + COMMAND_LIST[i][1]);
+ }
+}
+
+function doAdd(v) {
+ var req;
+ if (transport == 'websocket') {
+ req = "POST " + CONTEXT_PATH + "/customerservice/customers\r\nContent-Type: text/xml; charset='utf-8'\r\nAccept: text/xml\r\n\r\n"
+ + createAddCustomerPayload(v[0]);
+ } else if (transport == 'sse') {
+ req = {"method": "POST", "url": HOST_URL + CONTEXT_PATH + "/customerservice/customers", "headers": {"content-type": "text/xml; charset=utf-8", "accept": "text/xml"}, "data": createAddCustomerPayload(v[0])}
+ }
+ console.log("TRACE: sending ", req);
+ subSocket.push(req);
+}
+
+function doDelete(v) {
+ var req;
+ if (transport == 'websocket') {
+ req = "DELETE" + CONTEXT_PATH + "/customerservice/customers/" + v[0];
+ } else if (transport == 'sse') {
+ req = {"method": "DELETE", "url": HOST_URL + CONTEXT_PATH + "/customerservice/customers/" + v[0]}
+ }
+ console.log("TRACE: sending ", req);
+ subSocket.push(req);
+}
+
+function doGet(v) {
+ var req;
+ if (transport == 'websocket') {
+ req = "GET " + CONTEXT_PATH + "/customerservice/customers/" + v[0];
+ } else if (transport == 'sse') {
+ req = {"method": "GET", "url": HOST_URL + CONTEXT_PATH + "/customerservice/customers/" + v[0]}
+ }
+ console.log("TRACE: sending ", req);
+ subSocket.push(req);
+}
+
+function doSubscribe() {
+ var req;
+ if (transport == 'websocket') {
+ req = "GET " + CONTEXT_PATH + "/customerservice/monitor\r\nAccept: text/plain\r\n";
+ } else if (transport == 'sse') {
+ req = {"method": "GET", "url": HOST_URL + CONTEXT_PATH + "/customerservice/monitor", "headers": {"accept": "text/plain"}}
+ }
+ console.log("TRACE: sending ", req);
+ subSocket.push(req);
+}
+
+function doUnsubscribe() {
+ var req;
+ if (transport == 'websocket') {
+ req = "GET " + CONTEXT_PATH + "/customerservice/unmonitor/*\r\nAccept: text/plain\r\n";
+ } else if (transport == 'sse') {
+ req = {"method": "GET", "url": HOST_URL + CONTEXT_PATH + "/customerservice/unmonitor/*", "headers": {"accept": "text/plain"}}
+ }
+ console.log("TRACE: sending ", req);
+ subSocket.push(req);
+}
+
+function doUpdate(v) {
+ var req;
+ if (transport == 'websocket') {
+ req = "PUT " + CONTEXT_PATH + "/customerservice/customers\r\nContent-Type: text/xml; charset='utf-8'\r\nAccept: text/xml\r\n\r\n"
+ + createUpdateCustomerPayload(v[0], v[1]);
+ } else if (transport == 'sse') {
+ req = {"method": "PUT", "url": HOST_URL + CONTEXT_PATH + "/customerservice/customers", "headers": {"content-type": "text/xml; charset=utf-8", "accept": "text/xml"}, "data": createUpdateCustomerPayload(v[0], v[1])}
+ }
+ console.log("TRACE: sending ", req);
+ subSocket.push(req);
+}
+
+function doQuit() {
+ subSocket.close();
+ process.exit(0);
+}
+
+///
+
+request.onOpen = function(response) {
+ isopen = true;
+ console.log('Connected using ' + response.transport);
+ prompt.setPrompt("> ", 2);
+ prompt.prompt();
+};
+
+request.onMessage = function (response) {
+ var message = response.responseBody;
+ console.log('Received: ', message);
+ console.log('------------------------------------------------------------------------');
+ prompt.setPrompt("> ", 2);
+ prompt.prompt();
+};
+
+request.onReconnect = function(response) {
+ console.log('Reconnecting ...');
+}
+
+request.onReopen = function(response) {
+ isopen = true;
+ console.log('Reconnected using ' + response.transport);
+ prompt.setPrompt("> ", 2);
+ prompt.prompt();
+}
+
+request.onClose = function(response) {
+ isopen = false;
+}
+
+request.onError = function(response) {
+ console.log("Sorry, something went wrong: " + response.responseBody);
+};
+
+var transport = null;
+var subSocket = null;
+var author = null;
+
+console.log("Select transport ...");
+for (var i = 0; i < TRANSPORT_NAMES.length; i++) {
+ console.log(i + ": " + TRANSPORT_NAMES[i]);
+}
+prompt.setPrompt("select: ", 6);
+prompt.prompt();
+
+prompt.
+on('line', function(line) {
+ var msg = line.trim();
+ if (transport == null) {
+ transport = selectOption(msg, TRANSPORT_NAMES);
+ request.transport = transport;
+ subSocket = atmosphere.subscribe(request);
+ console.log("Connecting using " + transport);
+ setTimeout(function() {
+ if (!isopen) {
+ console.log("Unable to open a connection. Terminated.");
+ process.exit(0);
+ }
+ }, 3000);
+ } else if (msg.length == 0) {
+ doHelp();
+ } else if (msg.indexOf("add") == 0) {
+ doAdd(getArgs("add", msg));
+ } else if (msg.indexOf("del") == 0) {
+ doDelete(getArgs("del", msg));
+ } else if (msg.indexOf("get") == 0) {
+ doGet(getArgs("get", msg));
+ } else if (msg.indexOf("quit") == 0) {
+ doQuit();
+ } else if (msg.indexOf("sub") == 0) {
+ doSubscribe(getArgs("sub", msg));
+ } else if (msg.indexOf("unsub") == 0) {
+ doUnsubscribe(getArgs("unsub", msg));
+ } else if (msg.indexOf("update") == 0) {
+ doUpdate(getArgs("update", msg));
+ }
+ prompt.setPrompt("> ", 2);
+ prompt.prompt();
+}).
+on('close', function() {
+ console.log("close");
+ process.exit(0);
+});
[8/8] cxf git commit: make websocket_osgi sample also work for both
karaf 4.0.x (for cxf-3.1.x)
Posted by ay...@apache.org.
make websocket_osgi sample also work for both karaf 4.0.x (for cxf-3.1.x)
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/75edfe9d
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/75edfe9d
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/75edfe9d
Branch: refs/heads/3.1.x-fixes
Commit: 75edfe9d21fd654d844e24038a72206b4e15457d
Parents: 5ce6827
Author: Akitoshi Yoshida <ay...@apache.org>
Authored: Tue Apr 5 10:38:42 2016 +0200
Committer: Akitoshi Yoshida <ay...@apache.org>
Committed: Tue Apr 5 14:33:29 2016 +0200
----------------------------------------------------------------------
.../samples/jax_rs/websocket_osgi/README.txt | 58 ++++++++++----------
.../samples/jax_rs/websocket_osgi/pom.xml | 10 ++--
2 files changed, 35 insertions(+), 33 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/75edfe9d/distribution/src/main/release/samples/jax_rs/websocket_osgi/README.txt
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket_osgi/README.txt b/distribution/src/main/release/samples/jax_rs/websocket_osgi/README.txt
index 60d7705..09cf100 100644
--- a/distribution/src/main/release/samples/jax_rs/websocket_osgi/README.txt
+++ b/distribution/src/main/release/samples/jax_rs/websocket_osgi/README.txt
@@ -16,23 +16,22 @@ Using either UNIX or Windows:
This will produce a war file in the target folder.
+Starting Karaf (refer to http://karaf.apache.org/manual/latest-3.0.x/quick-start.html.
+You can also use Karaf 4.0.x for this demo.)
-Starting Karaf (refer to http://karaf.apache.org/manual/latest-3.0.x/quick-start.html)
+$ bin/karaf
+ __ __ ____
+ / //_/____ __________ _/ __/
+ / ,< / __ `/ ___/ __ `/ /_
+ / /| |/ /_/ / / / /_/ / __/
+ /_/ |_|\__,_/_/ \__,_/_/
- bin/karaf
+ Apache Karaf (3.0.4)
+Hit '<tab>' for a list of available commands
+and '[cmd] --help' for help on a specific command.
+Hit '<ctrl-d>' or type 'system:shutdown' or 'logout' to shutdown Karaf.
- __ __ ____
- / //_/____ __________ _/ __/
- / ,< / __ `/ ___/ __ `/ /_
- / /| |/ /_/ / / / /_/ / __/
- /_/ |_|\__,_/_/ \__,_/_/
-
- Apache Karaf (3.0.4)
-
- Hit '<tab>' for a list of available commands
- and '[cmd] --help' for help on a specific command.
- Hit '<ctrl-d>' or type 'system:shutdown' or 'logout' to shutdown Karaf.
In order to install CXF's features, you need to add the CXF's features repo using
@@ -52,28 +51,29 @@ Install this demo bundle (using the appropriate bundle version number)
And verify the bundles are installed.
-karaf@root()> feature:repo-add cxf 3.2.0-SNAPSHOT
-Adding feature url mvn:org.apache.cxf.karaf/apache-cxf/3.2.0-SNAPSHOT/xml/features
+
+karaf@root()> feature:repo-add cxf 3.1.7-SNAPSHOT
+Adding feature url mvn:org.apache.cxf.karaf/apache-cxf/3.1.7-SNAPSHOT/xml/features
karaf@root()> feature:install cxf-jaxrs cxf-transports-websocket-server
-karaf@root()> list -t 0 | grep CXF
- 80 | Active | 40 | 3.2.0.SNAPSHOT | Apache CXF Core
- 81 | Active | 40 | 3.2.0.SNAPSHOT | Apache CXF Runtime Management
-100 | Active | 40 | 3.2.0.SNAPSHOT | Apache CXF Runtime HTTP Transport
-102 | Active | 40 | 3.2.0.SNAPSHOT | Apache CXF JAX-RS Extensions: Providers
-103 | Active | 40 | 3.2.0.SNAPSHOT | Apache CXF JAX-RS Extensions: Search
-104 | Active | 40 | 3.2.0.SNAPSHOT | Apache CXF JAX-RS Service Description
-105 | Active | 40 | 3.2.0.SNAPSHOT | Apache CXF Runtime JAX-RS Frontend
-106 | Active | 40 | 3.2.0.SNAPSHOT | Apache CXF JAX-RS Client
-108 | Active | 40 | 3.2.0.SNAPSHOT | Apache CXF Runtime WebSocket Transport
-karaf@root()> install -s mvn:org.apache.cxf.samples/jax_rs_websocket_osgi
+karaf@root()> install -s mvn:org.apache.cxf.samples/jax_rs_websocket_osgi/3.1.7-SNAPSHOT
Bundle ID: 109
+karaf@root()> list -t 0 | grep CXF
+ 80 | Active | 40 | 3.1.7.SNAPSHOT | Apache CXF Core
+ 81 | Active | 40 | 3.1.7.SNAPSHOT | Apache CXF Runtime Management
+100 | Active | 40 | 3.1.7.SNAPSHOT | Apache CXF Runtime HTTP Transport
+102 | Active | 40 | 3.1.7.SNAPSHOT | Apache CXF JAX-RS Extensions: Providers
+103 | Active | 40 | 3.1.7.SNAPSHOT | Apache CXF JAX-RS Extensions: Search
+104 | Active | 40 | 3.1.7.SNAPSHOT | Apache CXF JAX-RS Service Description
+105 | Active | 40 | 3.1.7.SNAPSHOT | Apache CXF Runtime JAX-RS Frontend
+106 | Active | 40 | 3.1.7.SNAPSHOT | Apache CXF JAX-RS Client
+108 | Active | 40 | 3.1.7.SNAPSHOT | Apache CXF Runtime WebSocket Transport
karaf@root()> list
START LEVEL 100 , List Threshold: 50
ID | State | Lvl | Version | Name
---------------------------------------------------------------------
-107 | Active | 80 | 2.4.3 | atmosphere-runtime
-109 | Active | 80 | 3.2.0.SNAPSHOT | JAX-RS WebSocket Blueprint Demo
-karaf@root()>
+107 | Active | 80 | 2.3.7 | atmosphere-runtime
+109 | Active | 80 | 3.1.7.SNAPSHOT | JAX-RS WebSocket Blueprint Demo
+karaf@root()>
Visit http://localhost:8181/cxf/ to see if this RESTful service is registered.
http://git-wip-us.apache.org/repos/asf/cxf/blob/75edfe9d/distribution/src/main/release/samples/jax_rs/websocket_osgi/pom.xml
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket_osgi/pom.xml b/distribution/src/main/release/samples/jax_rs/websocket_osgi/pom.xml
index e0d1234..16e1988 100644
--- a/distribution/src/main/release/samples/jax_rs/websocket_osgi/pom.xml
+++ b/distribution/src/main/release/samples/jax_rs/websocket_osgi/pom.xml
@@ -27,7 +27,7 @@
<parent>
<groupId>org.apache.cxf.samples</groupId>
<artifactId>cxf-samples</artifactId>
- <version>3.2.0-SNAPSHOT</version>
+ <version>3.1.7-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<properties>
@@ -48,6 +48,8 @@
<instructions>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId};blueprint.aries.xml-validation:=false</Bundle-SymbolicName>
<Import-Package>
+ javax.servlet;version="[2.6,4)",
+ javax.servlet.http;version="[2.6,4)",
javax.ws.rs,
javax.ws.rs.core,
org.apache.cxf.jaxrs.provider,
@@ -66,17 +68,17 @@
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
- <version>3.2.0-SNAPSHOT</version>
+ <version>3.1.7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-websocket</artifactId>
- <version>3.2.0-SNAPSHOT</version>
+ <version>3.1.7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
- <version>3.2.0-SNAPSHOT</version>
+ <version>3.1.7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
[2/8] cxf git commit: [CXF-5855] enable atmosphere's sse handling;
update the sample
Posted by ay...@apache.org.
[CXF-5855] enable atmosphere's sse handling; update the sample
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/35f01c94
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/35f01c94
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/35f01c94
Branch: refs/heads/3.1.x-fixes
Commit: 35f01c94841870afa8331e0591aec8a3bc4ca94d
Parents: 897d81d
Author: Akitoshi Yoshida <ay...@apache.org>
Authored: Thu Mar 17 00:11:58 2016 +0100
Committer: Akitoshi Yoshida <ay...@apache.org>
Committed: Tue Apr 5 13:36:57 2016 +0200
----------------------------------------------------------------------
.../jax_rs/websocket/src/test/resources/client.js | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/35f01c94/distribution/src/main/release/samples/jax_rs/websocket/src/test/resources/client.js
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket/src/test/resources/client.js b/distribution/src/main/release/samples/jax_rs/websocket/src/test/resources/client.js
index 7eb55f3..8e8d653 100644
--- a/distribution/src/main/release/samples/jax_rs/websocket/src/test/resources/client.js
+++ b/distribution/src/main/release/samples/jax_rs/websocket/src/test/resources/client.js
@@ -8,7 +8,7 @@
"use strict";
-var HOST_URL = 'http://localhost:9100/';
+var HOST_URL = 'http://localhost:9000/';
var reader = require('readline');
var prompt = reader.createInterface(process.stdin, process.stdout);
@@ -25,13 +25,13 @@ var isopen = false;
const TRANSPORT_NAMES = ["websocket", "sse"];
const COMMAND_LIST =
- [["add name", "Add a new consumer and return the customer instance."],
- ["delete id", "Delete the customer."],
- ["get id", "Return the customere."],
+ [["add name", "Add a new consumer and return the customer instance. (e.g., add green)"],
+ ["delete id", "Delete the customer. (e.g., delete 124)"],
+ ["get id", "Return the customere. (e.g., get 123)"],
["quit", "Quit the application."],
- ["subscribe", "Subscribe to the customer updatese."],
- ["unsubscribe", "Unsubscribe from the customer updatese."],
- ["update id name", "Update the customer."]];
+ ["subscribe", "Subscribe to the customer queries."],
+ ["unsubscribe", "Unsubscribe from the customer queries."],
+ ["update id name", "Update the customer. (e.g., update 125 red)"]];
function selectOption(c, opts) {
var i = parseInt(c);
[5/8] cxf git commit: add a webapp version of
samples/jax_rs/websocket (for cxf-3.1.x)
Posted by ay...@apache.org.
add a webapp version of samples/jax_rs/websocket (for cxf-3.1.x)
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/de9b7936
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/de9b7936
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/de9b7936
Branch: refs/heads/3.1.x-fixes
Commit: de9b7936156d622c284df7f055acac80b920b7d0
Parents: b52157a
Author: Akitoshi Yoshida <ay...@apache.org>
Authored: Wed Mar 23 14:40:00 2016 +0100
Committer: Akitoshi Yoshida <ay...@apache.org>
Committed: Tue Apr 5 13:36:58 2016 +0200
----------------------------------------------------------------------
.../samples/jax_rs/websocket_web/README.txt | 32 +++
.../samples/jax_rs/websocket_web/pom.xml | 123 +++++++++
.../main/java/demo/jaxrs/server/Customer.java | 43 +++
.../java/demo/jaxrs/server/CustomerService.java | 271 +++++++++++++++++++
.../src/main/java/demo/jaxrs/server/Order.java | 69 +++++
.../main/java/demo/jaxrs/server/Product.java | 43 +++
.../src/main/webapp/WEB-INF/beans.xml | 46 ++++
.../src/main/webapp/WEB-INF/web.xml | 42 +++
8 files changed, 669 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/de9b7936/distribution/src/main/release/samples/jax_rs/websocket_web/README.txt
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket_web/README.txt b/distribution/src/main/release/samples/jax_rs/websocket_web/README.txt
new file mode 100644
index 0000000..36008ed
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/websocket_web/README.txt
@@ -0,0 +1,32 @@
+JAX-RS WebSocket WebApp Demo
+=================
+
+This is an WebApp version of JAX-RS WebSocket Demo.
+
+Building and running the demo using maven
+---------------------------------------
+
+From the base directory of this sample (i.e., where this README file is
+located), the maven pom.xml file can be used to build and run the demo.
+
+
+Using either UNIX or Windows:
+
+ mvn install
+
+This will produce a war file in the target folder.
+
+To run the war file using jetty9
+
+ mvn jetty:run-war (from one command line window)
+
+To run the war file using tomcat7
+
+ mvn tomcat7:run-war (from one command line window)
+
+To remove the target dir, run mvn clean".
+
+
+You can use the same clients included in JAX-RS WebSockt Demo.
+Refer to samples/jax_rs/websocket/README.txt for more information.
+
http://git-wip-us.apache.org/repos/asf/cxf/blob/de9b7936/distribution/src/main/release/samples/jax_rs/websocket_web/pom.xml
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket_web/pom.xml b/distribution/src/main/release/samples/jax_rs/websocket_web/pom.xml
new file mode 100644
index 0000000..7b76bbc
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/websocket_web/pom.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<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>
+ <artifactId>jax_rs_websocket_web</artifactId>
+ <name>JAX-RS WebSocket Demo</name>
+ <description>JAX-RS WebSocket WebApp Demo</description>
+ <packaging>war</packaging>
+ <parent>
+ <groupId>org.apache.cxf.samples</groupId>
+ <artifactId>cxf-samples</artifactId>
+ <version>3.1.7-SNAPSHOT</version>
+ <relativePath>../..</relativePath>
+ </parent>
+ <properties>
+ <cxf.version>${project.version}</cxf.version>
+ <!-- TODO remove these local entries after making the referenced dependency managed in parent/pom.xml -->
+ <cxf.atmosphere.version>2.3.7</cxf.atmosphere.version>
+ <cxf.jetty92.version>9.2.15.v20160210</cxf.jetty92.version>
+ <cxf.jetty93.version>9.3.5.v20151012</cxf.jetty93.version>
+ <cxf.jetty.version>${cxf.jetty92.version}</cxf.jetty.version>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-maven-plugin</artifactId>
+ <version>${cxf.jetty.version}</version>
+ <configuration>
+ <webAppSourceDirectory>${project.build.directory}/${project.name}</webAppSourceDirectory>
+ <scanIntervalSeconds>1</scanIntervalSeconds>
+ <httpConnector>
+ <port>9000</port>
+ </httpConnector>
+ <webAppConfig>
+ <contextPath>/</contextPath>
+ </webAppConfig>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.tomcat.maven</groupId>
+ <artifactId>tomcat7-maven-plugin</artifactId>
+ <version>2.2</version>
+ <configuration>
+ <warSourceDirectory>${project.build.directory}/${project.artifactId}</warSourceDirectory>
+ <port>9000</port>
+ <path>/</path>
+ </configuration>
+ <executions>
+ <execution>
+ <id>run-tomcat</id>
+ <configuration>
+ <fork>true</fork>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <!-- cxt et al -->
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-transports-http</artifactId>
+ <version>3.1.7-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-transports-websocket</artifactId>
+ <version>3.1.7-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+ <version>3.1.7-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>javax.ws.rs-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ </dependency>
+
+ <!-- add atmosphere -->
+ <dependency>
+ <groupId>org.atmosphere</groupId>
+ <artifactId>atmosphere-runtime</artifactId>
+ <version>${cxf.atmosphere.version}</version>
+ </dependency>
+
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/cxf/blob/de9b7936/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/java/demo/jaxrs/server/Customer.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/java/demo/jaxrs/server/Customer.java b/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/java/demo/jaxrs/server/Customer.java
new file mode 100644
index 0000000..44025f0
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/java/demo/jaxrs/server/Customer.java
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package demo.jaxrs.server;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "Customer")
+public class Customer {
+ private long id;
+ private String name;
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/de9b7936/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/java/demo/jaxrs/server/CustomerService.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/java/demo/jaxrs/server/CustomerService.java b/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/java/demo/jaxrs/server/CustomerService.java
new file mode 100644
index 0000000..f77f8aa
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/java/demo/jaxrs/server/CustomerService.java
@@ -0,0 +1,271 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package demo.jaxrs.server;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.servlet.http.HttpServletResponse;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.StreamingOutput;
+
+import org.apache.cxf.transport.websocket.WebSocketConstants;
+
+@Path("/customerservice/")
+@Produces("text/xml")
+public class CustomerService {
+ private static final int MAX_ERROR_COUNT = 5;
+ private static ExecutorService executor = Executors.newSingleThreadExecutor();
+
+ long currentId = 123;
+ Map<Long, Customer> customers = new HashMap<Long, Customer>();
+ Map<Long, Order> orders = new HashMap<Long, Order>();
+ Map<String, WriterHolder<OutputStream>> monitors = new HashMap<String, WriterHolder<OutputStream>>();
+ Map<String, WriterHolder<HttpServletResponse>> monitors2 = new HashMap<String, WriterHolder<HttpServletResponse>>();
+
+ public CustomerService() {
+ init();
+ }
+
+ @GET
+ @Path("/customers/{id}/")
+ public Customer getCustomer(@PathParam("id") String id) {
+ System.out.println("----invoking getCustomer, Customer id is: " + id);
+ long idNumber = Long.parseLong(id);
+ Customer customer = customers.get(idNumber);
+ if (customer != null) {
+ sendCustomerEvent("retrieved", customer);
+ }
+ return customer;
+ }
+
+ @PUT
+ @Path("/customers/")
+ public Response updateCustomer(Customer customer) {
+ System.out.println("----invoking updateCustomer, Customer name is: " + customer.getName());
+ Customer c = customers.get(customer.getId());
+ Response r;
+ if (c != null) {
+ customers.put(customer.getId(), customer);
+ r = Response.ok().build();
+ sendCustomerEvent("updated", customer);
+ } else {
+ r = Response.notModified().build();
+ }
+
+ return r;
+ }
+
+ @POST
+ @Path("/customers/")
+ public Response addCustomer(Customer customer) {
+ System.out.println("----invoking addCustomer, Customer name is: " + customer.getName());
+ customer.setId(++currentId);
+
+ customers.put(customer.getId(), customer);
+ sendCustomerEvent("added", customer);
+ return Response.ok(customer).build();
+ }
+
+ @DELETE
+ @Path("/customers/{id}/")
+ public Response deleteCustomer(@PathParam("id") String id) {
+ System.out.println("----invoking deleteCustomer, Customer id is: " + id);
+ long idNumber = Long.parseLong(id);
+ Customer c = customers.get(idNumber);
+
+ Response r;
+ if (c != null) {
+ r = Response.ok().build();
+ Customer customer = customers.remove(idNumber);
+ if (customer != null) {
+ sendCustomerEvent("deleted", customer);
+ }
+ } else {
+ r = Response.notModified().build();
+ }
+
+ return r;
+ }
+
+ @Path("/orders/{orderId}/")
+ public Order getOrder(@PathParam("orderId") String orderId) {
+ System.out.println("----invoking getOrder, Order id is: " + orderId);
+ long idNumber = Long.parseLong(orderId);
+ Order c = orders.get(idNumber);
+ return c;
+ }
+
+ @GET
+ @Path("/monitor")
+ @Produces("text/*")
+ public StreamingOutput monitorCustomers(
+ @HeaderParam(WebSocketConstants.DEFAULT_REQUEST_ID_KEY) String reqid) {
+ final String key = reqid == null ? "*" : reqid;
+ return new StreamingOutput() {
+ public void write(final OutputStream out) throws IOException, WebApplicationException {
+ monitors.put(key, new WriterHolder(out, MAX_ERROR_COUNT));
+ out.write(("Subscribed at " + new java.util.Date()).getBytes());
+ }
+
+ };
+ }
+
+ @GET
+ @Path("/monitor2")
+ @Produces("text/*")
+ public void monitorCustomers2(
+ final @javax.ws.rs.core.Context HttpServletResponse httpResponse,
+ @HeaderParam(WebSocketConstants.DEFAULT_REQUEST_ID_KEY) String reqid) {
+ final String key = reqid == null ? "*" : reqid;
+ monitors2.put(key, new WriterHolder(httpResponse, MAX_ERROR_COUNT));
+ try {
+ httpResponse.getOutputStream().write(("Subscribed at " + new java.util.Date()).getBytes());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @GET
+ @Path("/unmonitor/{key}")
+ @Produces("text/*")
+ public String unmonitorCustomers(@PathParam("key") String key) {
+ return (monitors.remove(key) != null ? "Removed: " : "Already removed: ") + key;
+ }
+
+ @GET
+ @Path("/unmonitor2/{key}")
+ @Produces("text/*")
+ public String unmonitorCustomers2(@PathParam("key") String key) {
+ return (monitors2.remove(key) != null ? "Removed: " : "Already removed: ") + key;
+ }
+
+ private void sendCustomerEvent(final String msg, final Customer customer) {
+ executor.execute(new Runnable() {
+ public void run() {
+ try {
+ String t = msg + ": " + customer.getId() + "/" + customer.getName();
+ for (Iterator<WriterHolder<OutputStream>> it = monitors.values().iterator(); it.hasNext();) {
+ WriterHolder<OutputStream> wh = it.next();
+ try {
+ wh.getValue().write(t.getBytes());
+ wh.getValue().flush();
+ wh.reset();
+ } catch (IOException e) {
+ System.out.println("----error writing to " + wh.getValue() + " " + wh.get());
+ if (wh.increment()) {
+ // the max error count reached; purging the output resource
+ e.printStackTrace();
+ try {
+ wh.getValue().close();
+ } catch (IOException e2) {
+ // ignore;
+ }
+ it.remove();
+ System.out.println("----purged " + wh.getValue());
+ }
+ }
+ }
+ for (Iterator<WriterHolder<HttpServletResponse>> it = monitors2.values().iterator(); it.hasNext();) {
+ WriterHolder<HttpServletResponse> wh = it.next();
+ try {
+ wh.getValue().getOutputStream().write(t.getBytes());
+ wh.getValue().getOutputStream().flush();
+ wh.reset();
+ } catch (IOException e) {
+ System.out.println("----error writing to " + wh.getValue() + " " + wh.get());
+ if (wh.increment()) {
+ // the max error count reached; purging the output resource
+ e.printStackTrace();
+ try {
+ wh.getValue().getOutputStream().close();
+ } catch (IOException e2) {
+ // ignore;
+ }
+ it.remove();
+ System.out.println("----purged " + wh.getValue());
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ });
+
+ }
+ final void init() {
+ Customer c = new Customer();
+ c.setName("John");
+ c.setId(123);
+ customers.put(c.getId(), c);
+ c = new Customer();
+ c.setName("Homer");
+ c.setId(235);
+ customers.put(c.getId(), c);
+
+ Order o = new Order();
+ o.setDescription("order 223");
+ o.setId(223);
+ orders.put(o.getId(), o);
+ }
+
+ private static class WriterHolder<T> {
+ final private T value;
+ final private int max;
+ final private AtomicInteger errorCount;
+
+ public WriterHolder(T object, int max) {
+ this.value = object;
+ this.max = max;
+ this.errorCount = new AtomicInteger();
+ }
+
+ public T getValue() {
+ return value;
+ }
+
+ public int get() {
+ return errorCount.get();
+ }
+ public boolean increment() {
+ return max < errorCount.getAndIncrement();
+ }
+
+ public void reset() {
+ errorCount.getAndSet(0);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/de9b7936/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/java/demo/jaxrs/server/Order.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/java/demo/jaxrs/server/Order.java b/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/java/demo/jaxrs/server/Order.java
new file mode 100644
index 0000000..a06b68b
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/java/demo/jaxrs/server/Order.java
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package demo.jaxrs.server;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "Order")
+public class Order {
+ private long id;
+ private String description;
+ private Map<Long, Product> products = new HashMap<Long, Product>();
+
+ public Order() {
+ init();
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String d) {
+ this.description = d;
+ }
+
+ @GET
+ @Path("products/{productId}/")
+ public Product getProduct(@PathParam("productId")int productId) {
+ System.out.println("----invoking getProduct with id: " + productId);
+ Product p = products.get(new Long(productId));
+ return p;
+ }
+
+ final void init() {
+ Product p = new Product();
+ p.setId(323);
+ p.setDescription("product 323");
+ products.put(p.getId(), p);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/de9b7936/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/java/demo/jaxrs/server/Product.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/java/demo/jaxrs/server/Product.java b/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/java/demo/jaxrs/server/Product.java
new file mode 100644
index 0000000..4452ec5
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/java/demo/jaxrs/server/Product.java
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package demo.jaxrs.server;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "Product")
+public class Product {
+ private long id;
+ private String description;
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String d) {
+ this.description = d;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/de9b7936/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/webapp/WEB-INF/beans.xml
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/webapp/WEB-INF/beans.xml b/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/webapp/WEB-INF/beans.xml
new file mode 100644
index 0000000..b6ffaa1
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/webapp/WEB-INF/beans.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<!-- START SNIPPET: beans -->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:http="http://cxf.apache.org/transports/http/configuration"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:jaxrs="http://cxf.apache.org/jaxrs"
+ xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
+ xmlns:cxf="http://cxf.apache.org/core"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
+ http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
+ http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
+ http://cxf.apache.org/transports/http-jetty/configuration http://cxf.apache.org/schemas/configuration/http-jetty.xsd
+ http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
+ <import resource="classpath:META-INF/cxf/cxf.xml"/>
+ <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
+
+ <bean class="demo.jaxrs.server.CustomerService" id="serviceBean"/>
+
+ <jaxrs:server id="websocketService" address="/demo" transportId="http://cxf.apache.org/transports/websocket">
+ <jaxrs:serviceBeans>
+ <ref bean="serviceBean"/>
+ </jaxrs:serviceBeans>
+ </jaxrs:server>
+
+</beans>
+<!-- END SNIPPET: beans -->
http://git-wip-us.apache.org/repos/asf/cxf/blob/de9b7936/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/webapp/WEB-INF/web.xml b/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..b9f5299
--- /dev/null
+++ b/distribution/src/main/release/samples/jax_rs/websocket_web/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<!-- START SNIPPET: webxml -->
+<web-app>
+ <context-param>
+ <param-name>contextConfigLocation</param-name>
+ <param-value>WEB-INF/beans.xml</param-value>
+ </context-param>
+ <listener>
+ <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+ </listener>
+ <servlet>
+ <servlet-name>CXFServlet</servlet-name>
+ <display-name>CXF Servlet</display-name>
+ <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ <async-supported>true</async-supported>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CXFServlet</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+</web-app>
+<!-- END SNIPPET: webxml -->
[3/8] cxf git commit: fix the test error by adjusting its setup for
CXF-5855
Posted by ay...@apache.org.
fix the test error by adjusting its setup for CXF-5855
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/897d81dc
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/897d81dc
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/897d81dc
Branch: refs/heads/3.1.x-fixes
Commit: 897d81dc292eb6159aab96390cb3fbfed1c34a6b
Parents: a529d27
Author: Akitoshi Yoshida <ay...@apache.org>
Authored: Thu Mar 17 11:17:57 2016 +0100
Committer: Akitoshi Yoshida <ay...@apache.org>
Committed: Tue Apr 5 13:36:57 2016 +0200
----------------------------------------------------------------------
.../websocket/atmosphere/DefaultProtocolInterceptorTest.java | 6 ++++++
1 file changed, 6 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/897d81dc/rt/transports/websocket/src/test/java/org/apache/cxf/transport/websocket/atmosphere/DefaultProtocolInterceptorTest.java
----------------------------------------------------------------------
diff --git a/rt/transports/websocket/src/test/java/org/apache/cxf/transport/websocket/atmosphere/DefaultProtocolInterceptorTest.java b/rt/transports/websocket/src/test/java/org/apache/cxf/transport/websocket/atmosphere/DefaultProtocolInterceptorTest.java
index e6b70af..1dee1de 100644
--- a/rt/transports/websocket/src/test/java/org/apache/cxf/transport/websocket/atmosphere/DefaultProtocolInterceptorTest.java
+++ b/rt/transports/websocket/src/test/java/org/apache/cxf/transport/websocket/atmosphere/DefaultProtocolInterceptorTest.java
@@ -25,7 +25,10 @@ import java.util.Map;
import org.apache.cxf.transport.websocket.WebSocketUtils;
import org.atmosphere.cpr.AtmosphereRequest;
+import org.atmosphere.cpr.AtmosphereResource;
+import org.atmosphere.cpr.AtmosphereResourceImpl;
import org.atmosphere.cpr.AtmosphereResponse;
+import org.atmosphere.cpr.FrameworkConfig;
import org.junit.Assert;
import org.junit.Test;
@@ -40,6 +43,9 @@ public class DefaultProtocolInterceptorTest extends Assert {
DefaultProtocolInterceptor dpi = new DefaultProtocolInterceptor();
AtmosphereRequest request = AtmosphereRequest.newInstance();
AtmosphereResponse response = AtmosphereResponse.newInstance();
+ AtmosphereResourceImpl resource = new AtmosphereResourceImpl();
+ resource.transport(AtmosphereResource.TRANSPORT.WEBSOCKET);
+ request.localAttributes().put(FrameworkConfig.ATMOSPHERE_RESOURCE, resource);
response.request(request);
String payload = "hello cxf";
String contentType = "text/plain";