You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by cm...@apache.org on 2012/01/06 11:24:36 UTC
svn commit: r1228060 [1/2] - in /camel/trunk/components/camel-websocket: ./
src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/camel/ src/main/java/org/apache/camel/component/
src/main/java/org/apache/ca...
Author: cmoulliard
Date: Fri Jan 6 10:24:34 2012
New Revision: 1228060
URL: http://svn.apache.org/viewvc?rev=1228060&view=rev
Log:
CAMEL-4498 : Add new camel component for websockets
Added:
camel/trunk/components/camel-websocket/
camel/trunk/components/camel-websocket/pom.xml
camel/trunk/components/camel-websocket/src/
camel/trunk/components/camel-websocket/src/main/
camel/trunk/components/camel-websocket/src/main/java/
camel/trunk/components/camel-websocket/src/main/java/org/
camel/trunk/components/camel-websocket/src/main/java/org/apache/
camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/
camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/
camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/
camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/DefaultWebsocket.java
camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/MemoryWebsocketStore.java
camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/NodeSynchronization.java
camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/NodeSynchronizationImpl.java
camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketComponent.java
camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketComponentServlet.java
camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketConfiguration.java
camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketConstants.java
camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketConsumer.java
camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketEndpoint.java
camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketProducer.java
camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketStore.java
camel/trunk/components/camel-websocket/src/main/resources/
camel/trunk/components/camel-websocket/src/main/resources/META-INF/
camel/trunk/components/camel-websocket/src/main/resources/META-INF/services/
camel/trunk/components/camel-websocket/src/main/resources/META-INF/services/org/
camel/trunk/components/camel-websocket/src/main/resources/META-INF/services/org/apache/
camel/trunk/components/camel-websocket/src/main/resources/META-INF/services/org/apache/camel/
camel/trunk/components/camel-websocket/src/main/resources/META-INF/services/org/apache/camel/component/
camel/trunk/components/camel-websocket/src/main/resources/META-INF/services/org/apache/camel/component/websocket
camel/trunk/components/camel-websocket/src/main/resources/index.html
camel/trunk/components/camel-websocket/src/main/resources/log4j.properties
camel/trunk/components/camel-websocket/src/test/
camel/trunk/components/camel-websocket/src/test/integration/
camel/trunk/components/camel-websocket/src/test/integration/org/
camel/trunk/components/camel-websocket/src/test/integration/org/apache/
camel/trunk/components/camel-websocket/src/test/integration/org/apache/camel/
camel/trunk/components/camel-websocket/src/test/integration/org/apache/camel/WebsocketComponentTest.java
camel/trunk/components/camel-websocket/src/test/integration/org/apache/camel/component/
camel/trunk/components/camel-websocket/src/test/integration/org/apache/camel/component/websocket/
camel/trunk/components/camel-websocket/src/test/integration/org/apache/camel/component/websocket/ProducerOnlyTest.java
camel/trunk/components/camel-websocket/src/test/integration/org/apache/camel/component/websocket/WebsocketComponentLiveTest.java
camel/trunk/components/camel-websocket/src/test/java/
camel/trunk/components/camel-websocket/src/test/java/org/
camel/trunk/components/camel-websocket/src/test/java/org/apache/
camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/
camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/
camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/
camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/DefaultWebsocketTest.java
camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/MemoryWebsocketStoreTest.java
camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/NodeSynchronizationImplTest.java
camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/WebsocketComponentServletTest.java
camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/WebsocketComponentTest.java
camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/WebsocketConfigurationTest.java
camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/WebsocketConsumerTest.java
camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/WebsocketEndpointTest.java
camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/WebsocketProducerTest.java
camel/trunk/components/camel-websocket/src/test/resources/
camel/trunk/components/camel-websocket/src/test/resources/index.html
camel/trunk/components/camel-websocket/src/test/resources/producer-only.html
Added: camel/trunk/components/camel-websocket/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/pom.xml?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/pom.xml (added)
+++ camel/trunk/components/camel-websocket/pom.xml Fri Jan 6 10:24:34 2012
@@ -0,0 +1,76 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-parent</artifactId>
+ <version>2.10-SNAPSHOT</version>
+ <relativePath>../../parent</relativePath>
+ </parent>
+
+ <artifactId>camel-websocket</artifactId>
+ <packaging>bundle</packaging>
+ <name>Camel :: WebSocket</name>
+ <description>Camel WebSocket</description>
+
+ <properties>
+ <camel.osgi.export.pkg>
+ org.apache.camel.component.websocket.*;${camel.osgi.version}
+ </camel.osgi.export.pkg>
+ <camel.osgi.import.pkg>
+ !org.apache.camel.component.websocket.*,
+ ${camel.osgi.import.defaults},
+ *
+ </camel.osgi.import.pkg>
+ </properties>
+
+ <dependencies>
+ <!-- Camel -->
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-core</artifactId>
+ </dependency>
+ <!-- Jetty -->
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-websocket</artifactId>
+ <version>${jetty-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-servlet</artifactId>
+ <version>${jetty-version}</version>
+ </dependency>
+ <!-- Unit test -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
Added: camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/DefaultWebsocket.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/DefaultWebsocket.java?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/DefaultWebsocket.java (added)
+++ camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/DefaultWebsocket.java Fri Jan 6 10:24:34 2012
@@ -0,0 +1,82 @@
+/**
+ * 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 org.apache.camel.component.websocket;
+
+import java.io.Serializable;
+import java.util.UUID;
+
+import org.eclipse.jetty.websocket.WebSocket;
+import org.eclipse.jetty.websocket.WebSocket.OnTextMessage;
+
+public class DefaultWebsocket implements WebSocket, OnTextMessage, Serializable {
+
+ private static final long serialVersionUID = -575701599776801400L;
+ private Connection connection;
+ private String connectionKey;
+ private NodeSynchronization sync;
+
+ private transient WebsocketConsumer consumer;
+
+ public DefaultWebsocket(NodeSynchronization sync, WebsocketConsumer consumer) {
+ this.sync = sync;
+ this.consumer = consumer;
+ }
+
+ @Override
+ public void onClose(int closeCode, String message) {
+ sync.removeSocket(this);
+ }
+
+ @Override
+ public void onOpen(Connection connection) {
+ this.connection = connection;
+
+ this.connectionKey = UUID.randomUUID().toString();
+ sync.addSocket(this);
+ }
+
+ @Override
+ public void onMessage(String message) {
+ if (this.consumer != null) {
+ this.consumer.sendExchange(this.connectionKey, message);
+ }
+ // consumer is not set, this is produce only websocket
+ // TODO - 06.06.2011, LK - deliver exchange to dead letter channel
+ }
+
+ // getters and setters
+ public Connection getConnection() {
+ return connection;
+ }
+
+ public void setConnection(Connection connection) {
+ this.connection = connection;
+ }
+
+ public String getConnectionKey() {
+ return connectionKey;
+ }
+
+ public void setConnectionKey(String connectionKey) {
+ this.connectionKey = connectionKey;
+ }
+
+ public void setConsumer(WebsocketConsumer consumer) {
+ this.consumer = consumer;
+ }
+
+}
Added: camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/MemoryWebsocketStore.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/MemoryWebsocketStore.java?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/MemoryWebsocketStore.java (added)
+++ camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/MemoryWebsocketStore.java Fri Jan 6 10:24:34 2012
@@ -0,0 +1,51 @@
+/**
+ * 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 org.apache.camel.component.websocket;
+
+import java.util.Collection;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class MemoryWebsocketStore extends ConcurrentHashMap<String, DefaultWebsocket> implements WebsocketStore {
+
+ private static final long serialVersionUID = -2826843758230613922L;
+
+ @Override
+ public void add(DefaultWebsocket ws) {
+ super.put(ws.getConnectionKey(), ws);
+ }
+
+ @Override
+ public void remove(DefaultWebsocket ws) {
+ super.remove(ws.getConnectionKey());
+ }
+
+ @Override
+ public void remove(String key) {
+ super.remove(key);
+ }
+
+ @Override
+ public DefaultWebsocket get(String key) {
+ return super.get(key);
+ }
+
+ @Override
+ public Collection<DefaultWebsocket> getAll() {
+ return super.values();
+ }
+
+}
Added: camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/NodeSynchronization.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/NodeSynchronization.java?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/NodeSynchronization.java (added)
+++ camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/NodeSynchronization.java Fri Jan 6 10:24:34 2012
@@ -0,0 +1,30 @@
+/**
+ * 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 org.apache.camel.component.websocket;
+
+public interface NodeSynchronization {
+
+ /** adds the Websocket to both (always if present) stores */
+ void addSocket(DefaultWebsocket socket);
+
+ /** deletes the Websocket from both stores */
+ void removeSocket(String id);
+
+ /** deletes the Websocket from both stores */
+ void removeSocket(DefaultWebsocket socket);
+
+}
Added: camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/NodeSynchronizationImpl.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/NodeSynchronizationImpl.java?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/NodeSynchronizationImpl.java (added)
+++ camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/NodeSynchronizationImpl.java Fri Jan 6 10:24:34 2012
@@ -0,0 +1,58 @@
+/**
+ * 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 org.apache.camel.component.websocket;
+
+public class NodeSynchronizationImpl implements NodeSynchronization {
+
+ private WebsocketStore memoryStore;
+
+ private WebsocketStore globalStore;
+
+ public NodeSynchronizationImpl(WebsocketStore memoryStore, WebsocketStore globalStore) {
+ this.memoryStore = memoryStore;
+ this.globalStore = globalStore;
+ }
+
+ public NodeSynchronizationImpl(WebsocketStore memoryStore) {
+ this.memoryStore = memoryStore;
+ }
+
+ @Override
+ public void addSocket(DefaultWebsocket socket) {
+ memoryStore.add(socket);
+ if (this.globalStore != null) {
+ globalStore.add(socket);
+ }
+ }
+
+ @Override
+ public void removeSocket(String id) {
+ memoryStore.remove(id);
+ if (this.globalStore != null) {
+ globalStore.remove(id);
+ }
+ }
+
+ @Override
+ public void removeSocket(DefaultWebsocket socket) {
+ memoryStore.remove(socket);
+ if (this.globalStore != null) {
+ globalStore.remove(socket);
+ }
+ }
+
+}
Added: camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketComponent.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketComponent.java?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketComponent.java (added)
+++ camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketComponent.java Fri Jan 6 10:24:34 2012
@@ -0,0 +1,184 @@
+/**
+ * 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 org.apache.camel.component.websocket;
+
+import java.net.InetSocketAddress;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.impl.DefaultComponent;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.SessionManager;
+import org.eclipse.jetty.server.session.HashSessionManager;
+import org.eclipse.jetty.server.session.SessionHandler;
+import org.eclipse.jetty.servlet.DefaultServlet;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class WebsocketComponent extends DefaultComponent {
+
+ private static final Logger LOG = LoggerFactory.getLogger(WebsocketComponent.class);
+
+ private ServletContextHandler context;
+ private Server server;
+
+ /** Host name for server. */
+ private String host = WebsocketConstants.DEFAULT_HOST;
+
+ /** Port for server. */
+ private int port = WebsocketConstants.DEFAULT_PORT;
+
+ /** Server static content location. */
+ private String staticResources;
+
+ /**
+ * Map for storing endpoints. Endpoint is identified by remaining part from endpoint URI. Eg. <tt>ws://foo?bar=123</tt> and <tt>ws://foo</tt> are referring to the same endpoint.
+ */
+ private Map<String, WebsocketEndpoint> endpoints = new HashMap<String, WebsocketEndpoint>();
+
+ /**
+ * Map for storing servlets. {@link WebsocketComponentServlet} is identified by pathSpec {@link String}.
+ */
+ private Map<String, WebsocketComponentServlet> servlets = new HashMap<String, WebsocketComponentServlet>();
+
+ public WebsocketComponent() {
+ }
+
+ @Override
+ /**
+ * uri --> websocket://foo?storeImplementationClass=org.apache.camel.hazelcast.HazelcastWebsocketStore&storeName=foo
+ */
+ protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
+ WebsocketEndpoint endpoint = endpoints.get(remaining);
+ if (endpoint == null) {
+ WebsocketConfiguration websocketConfiguration = new WebsocketConfiguration();
+ setProperties(websocketConfiguration, parameters);
+ endpoint = new WebsocketEndpoint(uri, this, remaining, websocketConfiguration);
+ endpoints.put(remaining, endpoint);
+ }
+ return endpoint;
+ }
+
+ /**
+ * @param host
+ * the host to set
+ */
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ /**
+ * @param port
+ * the port to set
+ */
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ /**
+ * @param staticResources
+ * the staticResources to set
+ */
+ public void setStaticResources(String staticResources) {
+ this.staticResources = staticResources;
+ }
+
+ ServletContextHandler createContext() {
+ return new ServletContextHandler(ServletContextHandler.SESSIONS);
+ }
+
+ protected Server createServer(ServletContextHandler context, String host, int port, String home) {
+ InetSocketAddress address = new InetSocketAddress(host, port);
+ Server server = new Server(address);
+
+ context.setContextPath("/");
+
+ SessionManager sm = new HashSessionManager();
+ SessionHandler sh = new SessionHandler(sm);
+ context.setSessionHandler(sh);
+
+ if (home != null) {
+ context.setResourceBase(home);
+ DefaultServlet defaultServlet = new DefaultServlet();
+ ServletHolder holder = new ServletHolder(defaultServlet);
+
+ // avoid file locking on windows
+ // http://stackoverflow.com/questions/184312/how-to-make-jetty-dynamically-load-static-pages
+ holder.setInitParameter("useFileMappedBuffer", "false");
+ context.addServlet(holder, "/");
+ }
+
+ server.setHandler(context);
+
+ return server;
+ }
+
+ public WebsocketComponentServlet addServlet(NodeSynchronization sync, WebsocketConsumer consumer, String remaining) {
+
+ String pathSpec = createPathSpec(remaining);
+ WebsocketComponentServlet servlet = servlets.get(pathSpec);
+ if (servlet == null) {
+ servlet = createServlet(sync, pathSpec, servlets, context);
+ }
+ setServletConsumer(servlet, consumer);
+ return servlet;
+ }
+
+ String createPathSpec(String remaining) {
+ return String.format("/%s/*", remaining);
+ }
+
+ void setServletConsumer(WebsocketComponentServlet servlet, WebsocketConsumer consumer) {
+ if (servlet.getConsumer() == null && consumer != null) {
+ servlet.setConsumer(consumer);
+ }
+ }
+
+ WebsocketComponentServlet createServlet(NodeSynchronization sync, String pathSpec, Map<String, WebsocketComponentServlet> servlets, ServletContextHandler handler) {
+
+ WebsocketComponentServlet servlet = new WebsocketComponentServlet(sync);
+ servlets.put(pathSpec, servlet);
+ handler.addServlet(new ServletHolder(servlet), pathSpec);
+ return servlet;
+ }
+
+ /**
+ * @see org.apache.camel.impl.DefaultComponent#doStart()
+ */
+ @Override
+ protected void doStart() throws Exception {
+ super.doStart();
+ LOG.info("Staring server {}:{}; static resources: {}", new Object[] {host, port, staticResources});
+ context = createContext();
+ server = createServer(context, host, port, staticResources);
+ server.start();
+ }
+
+ /**
+ * @see org.apache.camel.impl.DefaultComponent#doStop()
+ */
+ @Override
+ public void doStop() throws Exception {
+ if (server != null) {
+ server.stop();
+ }
+ }
+
+}
Added: camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketComponentServlet.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketComponentServlet.java?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketComponentServlet.java (added)
+++ camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketComponentServlet.java Fri Jan 6 10:24:34 2012
@@ -0,0 +1,65 @@
+/**
+ * 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 org.apache.camel.component.websocket;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.websocket.WebSocket;
+import org.eclipse.jetty.websocket.WebSocketServlet;
+
+public class WebsocketComponentServlet extends WebSocketServlet {
+
+ private static final long serialVersionUID = 207837507742337364L;
+
+ private WebsocketConsumer consumer;
+ private NodeSynchronization sync;
+
+ public WebsocketComponentServlet(NodeSynchronization sync) {
+ this.sync = sync;
+ }
+
+ /**
+ * @return the consumer
+ */
+ public WebsocketConsumer getConsumer() {
+ return consumer;
+ }
+
+ /**
+ * @param consumer
+ * the consumer to set
+ */
+ public void setConsumer(WebsocketConsumer consumer) {
+ this.consumer = consumer;
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+
+ getServletContext().getNamedDispatcher("default").forward(request, response);
+ }
+
+ @Override
+ public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) {
+ return new DefaultWebsocket(sync, consumer);
+ }
+
+}
Added: camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketConfiguration.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketConfiguration.java?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketConfiguration.java (added)
+++ camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketConfiguration.java Fri Jan 6 10:24:34 2012
@@ -0,0 +1,31 @@
+/**
+ * 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 org.apache.camel.component.websocket;
+
+public class WebsocketConfiguration {
+
+ private String globalStore;
+
+ public String getGlobalStore() {
+ return globalStore;
+ }
+
+ public void setGlobalStore(String globalStore) {
+ this.globalStore = globalStore;
+ }
+
+}
Added: camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketConstants.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketConstants.java?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketConstants.java (added)
+++ camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketConstants.java Fri Jan 6 10:24:34 2012
@@ -0,0 +1,27 @@
+/**
+ * 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 org.apache.camel.component.websocket;
+
+public class WebsocketConstants {
+
+ public static final String CONNECTION_KEY = "websocket.connectionKey";
+ public static final String SEND_TO_ALL = "websocket.sendToAll";
+
+ public static final String DEFAULT_HOST = "0.0.0.0";
+ public static final int DEFAULT_PORT = 9292;
+
+}
Added: camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketConsumer.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketConsumer.java?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketConsumer.java (added)
+++ camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketConsumer.java Fri Jan 6 10:24:34 2012
@@ -0,0 +1,47 @@
+/**
+ * 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 org.apache.camel.component.websocket;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.impl.DefaultConsumer;
+
+public class WebsocketConsumer extends DefaultConsumer {
+
+ public WebsocketConsumer(Endpoint endpoint, Processor processor) {
+ super(endpoint, processor);
+ }
+
+ public void sendExchange(String connectionKey, String message) {
+ Exchange exchange = this.getEndpoint().createExchange();
+
+ // set header and body
+ exchange.getIn().setHeader(WebsocketConstants.CONNECTION_KEY, connectionKey);
+ exchange.getIn().setBody(message);
+
+ // send exchange
+ try {
+ this.getProcessor().process(exchange);
+ } catch (Exception e) {
+ if (exchange.getException() != null) {
+ this.getExceptionHandler().handleException(String.format("Error processing exchange for websocket consumer on message '%s'.", message), exchange, exchange.getException());
+ }
+ }
+ }
+
+}
Added: camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketEndpoint.java?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketEndpoint.java (added)
+++ camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketEndpoint.java Fri Jan 6 10:24:34 2012
@@ -0,0 +1,92 @@
+/**
+ * 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 org.apache.camel.component.websocket;
+
+import org.apache.camel.Consumer;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.impl.DefaultEndpoint;
+import org.apache.camel.util.ObjectHelper;
+
+public class WebsocketEndpoint extends DefaultEndpoint {
+
+ // Todo: Change to Options
+ private NodeSynchronization sync;
+ private String remaining;
+
+ private WebsocketStore memoryStore;
+ private WebsocketStore globalStore;
+
+ private WebsocketConfiguration websocketConfiguration;
+
+ public WebsocketEndpoint() {
+
+ }
+
+ public WebsocketEndpoint(String uri, WebsocketComponent component, String remaining, WebsocketConfiguration websocketConfiguration) throws InstantiationException, IllegalAccessException {
+ super(uri, component);
+ this.remaining = remaining;
+
+ this.memoryStore = new MemoryWebsocketStore();
+ // TODO: init globalStore
+
+ this.websocketConfiguration = websocketConfiguration;
+
+ if (websocketConfiguration.getGlobalStore() != null) {
+ this.globalStore = (WebsocketStore) ObjectHelper.loadClass(this.websocketConfiguration.getGlobalStore()).newInstance();
+ }
+
+ // this.sync = new NodeSynchronizationImpl(this.memoryStore, null);
+ this.sync = new NodeSynchronizationImpl(this.memoryStore, this.globalStore);
+ }
+
+ public WebsocketStore getMemoryStore() {
+ return memoryStore;
+ }
+
+ public WebsocketStore getGlobalStore() {
+ return globalStore;
+ }
+
+ @Override
+ public Consumer createConsumer(Processor processor) throws Exception {
+
+ // init consumer
+ WebsocketConsumer consumer = new WebsocketConsumer(this, processor);
+
+ // register servlet
+ ((WebsocketComponent) super.getComponent()).addServlet(this.sync, consumer, this.remaining);
+
+ return consumer;
+ }
+
+ @Override
+ public Producer createProducer() throws Exception {
+
+ // register servlet without consumer
+ ((WebsocketComponent) super.getComponent()).addServlet(this.sync, null, this.remaining);
+
+ return new WebsocketProducer(this, this.memoryStore);
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return true;
+ }
+
+ // TODO --> implement store factory
+}
Added: camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketProducer.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketProducer.java?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketProducer.java (added)
+++ camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketProducer.java Fri Jan 6 10:24:34 2012
@@ -0,0 +1,90 @@
+/**
+ * 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 org.apache.camel.component.websocket;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.impl.DefaultProducer;
+
+public class WebsocketProducer extends DefaultProducer {
+
+ private WebsocketStore store;
+
+ public WebsocketProducer(Endpoint endpoint) {
+ super(endpoint);
+ }
+
+ public WebsocketProducer(Endpoint endpoint, WebsocketStore store) {
+ super(endpoint);
+ this.store = store;
+ }
+
+ @Override
+ public void process(Exchange exchange) throws Exception {
+
+ Message in = exchange.getIn();
+ String message = in.getBody(String.class);
+
+ if (isSendToAllSet(in)) {
+ sendToAll(this.store, message);
+ } else {
+ // look for connection key and get Websocket
+ String connectionKey = in.getHeader(WebsocketConstants.CONNECTION_KEY, String.class);
+ if (connectionKey != null) {
+ DefaultWebsocket websocket = store.get(connectionKey);
+ sendMessage(websocket, message);
+ } else {
+ throw new IllegalArgumentException("Failed to send message to single connection; connetion key not set.");
+ }
+ }
+ }
+
+ boolean isSendToAllSet(Message in) {
+ // header may be null; have to be careful here
+ Object value = in.getHeader(WebsocketConstants.SEND_TO_ALL);
+ return value == null ? false : (Boolean) value;
+ }
+
+ void sendToAll(WebsocketStore store, String message) throws Exception {
+ Collection<DefaultWebsocket> websockets = store.getAll();
+ Exception exception = null;
+ for (DefaultWebsocket websocket : websockets) {
+ try {
+ sendMessage(websocket, message);
+ } catch (Exception e) {
+ if (exception == null) {
+ exception = new Exception("Failed to deliver message to one or more recipients.", e);
+ }
+ }
+ }
+ if (exception != null) {
+ throw exception;
+ }
+ }
+
+ void sendMessage(DefaultWebsocket websocket, String message) throws IOException {
+ // in case there is web socket and socket connection is open - send
+ // message
+ if (websocket != null && websocket.getConnection().isOpen()) {
+ websocket.getConnection().sendMessage(message);
+ }
+ }
+}
Added: camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketStore.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketStore.java?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketStore.java (added)
+++ camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketStore.java Fri Jan 6 10:24:34 2012
@@ -0,0 +1,32 @@
+/**
+ * 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 org.apache.camel.component.websocket;
+
+import java.util.Collection;
+
+public interface WebsocketStore {
+
+ void add(DefaultWebsocket ws);
+
+ void remove(DefaultWebsocket ws);
+
+ void remove(String key);
+
+ DefaultWebsocket get(String key);
+
+ Collection<DefaultWebsocket> getAll();
+}
Added: camel/trunk/components/camel-websocket/src/main/resources/META-INF/services/org/apache/camel/component/websocket
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/main/resources/META-INF/services/org/apache/camel/component/websocket?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/main/resources/META-INF/services/org/apache/camel/component/websocket (added)
+++ camel/trunk/components/camel-websocket/src/main/resources/META-INF/services/org/apache/camel/component/websocket Fri Jan 6 10:24:34 2012
@@ -0,0 +1,17 @@
+#
+# 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.
+#
+class=org.apache.camel.component.websocket.WebsocketComponent
Added: camel/trunk/components/camel-websocket/src/main/resources/index.html
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/main/resources/index.html?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/main/resources/index.html (added)
+++ camel/trunk/components/camel-websocket/src/main/resources/index.html Fri Jan 6 10:24:34 2012
@@ -0,0 +1,109 @@
+<html><head>
+ <title>WebSocket Chat</title>
+ <script type='text/javascript'>
+
+ if (!window.WebSocket)
+ alert("WebSocket not supported by this browser");
+
+ function $() { return document.getElementById(arguments[0]); }
+ function $F() { return document.getElementById(arguments[0]).value; }
+
+ function getKeyCode(ev) { if (window.event) return window.event.keyCode; return ev.keyCode; }
+
+ var room = {
+ join: function(name) {
+ this._username=name;
+ var location = "ws://localhost:1989/foo/";
+ this._ws=new WebSocket(location);
+ this._ws.onopen=this._onopen;
+ this._ws.onmessage=this._onmessage;
+ this._ws.onclose=this._onclose;
+ },
+
+ _onopen: function(){
+ $('join').className='hidden';
+ $('joined').className='';
+ $('phrase').focus();
+ room._send(room._username,'has joined!');
+ },
+
+ _send: function(user,message){
+ user=user.replace(':','_');
+ if (this._ws)
+ this._ws.send(user+':'+message);
+ },
+
+ chat: function(text) {
+ if (text != null && text.length>0 )
+ room._send(room._username,text);
+ },
+
+ _onmessage: function(m) {
+ if (m.data){
+ var c=m.data.indexOf(':');
+ var from=m.data.substring(0,c).replace('<','<').replace('>','>');
+ var text=m.data.substring(c+1).replace('<','<').replace('>','>');
+
+ var chat=$('chat');
+ var spanFrom = document.createElement('span');
+ spanFrom.className='from';
+ spanFrom.innerHTML=from+': ';
+ var spanText = document.createElement('span');
+ spanText.className='text';
+ spanText.innerHTML=text;
+ var lineBreak = document.createElement('br');
+ chat.appendChild(spanFrom);
+ chat.appendChild(spanText);
+ chat.appendChild(lineBreak);
+ chat.scrollTop = chat.scrollHeight - chat.clientHeight;
+ }
+ },
+
+ _onclose: function(m) {
+ this._ws=null;
+ $('join').className='';
+ $('joined').className='hidden';
+ $('username').focus();
+ $('chat').innerHTML='';
+ }
+
+ };
+
+ </script>
+ <style type='text/css'>
+ div { border: 0px solid black; }
+ div#chat { clear: both; width: 40em; height: 20ex; overflow: auto; background-color: #f0f0f0; padding: 4px; border: 1px solid black; }
+ div#input { clear: both; width: 40em; padding: 4px; background-color: #e0e0e0; border: 1px solid black; border-top: 0px }
+ input#phrase { width:30em; background-color: #e0f0f0; }
+ input#username { width:14em; background-color: #e0f0f0; }
+ div.hidden { display: none; }
+ span.from { font-weight: bold; }
+ span.alert { font-style: italic; }
+ </style>
+</head><body>
+<div id='chat'></div>
+<div id='input'>
+ <div id='join' >
+ Username: <input id='username' type='text'/><input id='joinB' class='button' type='submit' name='join' value='Join'/>
+ </div>
+ <div id='joined' class='hidden'>
+ Chat: <input id='phrase' type='text'/>
+ <input id='sendB' class='button' type='submit' name='join' value='Send'/>
+ </div>
+</div>
+<script type='text/javascript'>
+$('username').setAttribute('autocomplete','OFF');
+$('username').onkeyup = function(ev) { var keyc=getKeyCode(ev); if (keyc==13 || keyc==10) { room.join($F('username')); return false; } return true; } ;
+$('joinB').onclick = function(event) { room.join($F('username')); return false; };
+$('phrase').setAttribute('autocomplete','OFF');
+$('phrase').onkeyup = function(ev) { var keyc=getKeyCode(ev); if (keyc==13 || keyc==10) { room.chat($F('phrase')); $('phrase').value=''; return false; } return true; };
+$('sendB').onclick = function(event) { room.chat($F('phrase')); $('phrase').value=''; return false; };
+</script>
+
+<p>
+This is a demonstration of the Jetty websocket server.
+</p>
+</body></html>
+
+
+
\ No newline at end of file
Added: camel/trunk/components/camel-websocket/src/main/resources/log4j.properties
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/main/resources/log4j.properties?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/main/resources/log4j.properties (added)
+++ camel/trunk/components/camel-websocket/src/main/resources/log4j.properties Fri Jan 6 10:24:34 2012
@@ -0,0 +1,37 @@
+/**
+ * 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.
+ */
+#
+# The logging properties used for eclipse testing, We want to see debug output on the console.
+#
+log4j.rootLogger=INFO, out
+
+# uncomment the following line to turn on Camel debugging
+#log4j.logger.org.apache.camel=DEBUG
+
+# uncomment the following line to turn on ActiveMQ debugging
+#log4j.logger.org.apache.activemq=DEBUG
+
+log4j.logger.org.springframework=WARN
+
+
+# CONSOLE appender not used by default
+log4j.appender.out=org.apache.log4j.ConsoleAppender
+log4j.appender.out.layout=org.apache.log4j.PatternLayout
+log4j.appender.out.layout.ConversionPattern=[%30.30t] %-30.30c{1} %-5p %m%n
+#log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
+
+log4j.throwableRenderer=org.apache.log4j.EnhancedThrowableRenderer
\ No newline at end of file
Added: camel/trunk/components/camel-websocket/src/test/integration/org/apache/camel/WebsocketComponentTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/test/integration/org/apache/camel/WebsocketComponentTest.java?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/test/integration/org/apache/camel/WebsocketComponentTest.java (added)
+++ camel/trunk/components/camel-websocket/src/test/integration/org/apache/camel/WebsocketComponentTest.java Fri Jan 6 10:24:34 2012
@@ -0,0 +1,44 @@
+/**
+ * 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 org.apache.camel;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+public class WebsocketComponentTest extends CamelTestSupport {
+
+ @Test
+ public void testWebsocketCall() throws Exception {
+ Thread.sleep(15 * 60 * 1000);
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ public void configure() {
+
+ from("websocket://foo").log("received message: ").log(" --> ${body}").choice().when(body(Integer.class).isGreaterThan(500)).to("seda://greater500")
+ .when(body(Integer.class).isLessThan(500)).to("seda://less500").otherwise().setBody(constant("request failed...")).to("websocket://foo");
+
+ from("seda://greater500").setBody(constant("forms/c.xml")).log("C --> ${body}").to("websocket://foo");
+
+ from("seda://less500").setBody(constant("forms/b.xml")).log("B --> ${body}").to("websocket://foo");
+ }
+ };
+ }
+}
Added: camel/trunk/components/camel-websocket/src/test/integration/org/apache/camel/component/websocket/ProducerOnlyTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/test/integration/org/apache/camel/component/websocket/ProducerOnlyTest.java?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/test/integration/org/apache/camel/component/websocket/ProducerOnlyTest.java (added)
+++ camel/trunk/components/camel-websocket/src/test/integration/org/apache/camel/component/websocket/ProducerOnlyTest.java Fri Jan 6 10:24:34 2012
@@ -0,0 +1,67 @@
+/**
+ * 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 org.apache.camel.component.websocket;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ */
+public class ProducerOnlyTest extends CamelTestSupport {
+
+ private static final Logger LOG = LoggerFactory.getLogger(WebsocketComponentLiveTest.class);
+
+ @Test
+ public void liveTest() throws Exception {
+ LOG.info("*** open URL http://localhost:1989/producer-only.html ***");
+ Thread.sleep(1 * 60 * 1000);
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+
+ return new RouteBuilder() {
+
+ private Counter counter = new Counter();
+
+ public void configure() {
+
+ WebsocketComponent component = getContext().getComponent("websocket", WebsocketComponent.class);
+ component.setHost("localhost");
+ component.setPort(1989);
+ component.setStaticResources("src/test/resources");
+
+ from("timer://foo?fixedRate=true&period=1000").bean(counter).setHeader(WebsocketConstants.SEND_TO_ALL, constant(true)).to("websocket://counter");
+ }
+ };
+ }
+
+ public class Counter {
+
+ //private int counter = 0;
+
+ private int counter;
+
+ public int next() {
+ return ++counter;
+ }
+ }
+}
Added: camel/trunk/components/camel-websocket/src/test/integration/org/apache/camel/component/websocket/WebsocketComponentLiveTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/test/integration/org/apache/camel/component/websocket/WebsocketComponentLiveTest.java?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/test/integration/org/apache/camel/component/websocket/WebsocketComponentLiveTest.java (added)
+++ camel/trunk/components/camel-websocket/src/test/integration/org/apache/camel/component/websocket/WebsocketComponentLiveTest.java Fri Jan 6 10:24:34 2012
@@ -0,0 +1,57 @@
+/**
+ * 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 org.apache.camel.component.websocket;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ *
+ */
+public class WebsocketComponentLiveTest extends CamelTestSupport {
+
+ private static final Logger LOG = LoggerFactory.getLogger(WebsocketComponentLiveTest.class);
+
+ @Test
+ public void liveTest() throws Exception {
+ LOG.info("*** open URL http://localhost:1989 and start chating ***");
+ Thread.sleep(1 * 60 * 1000);
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ public void configure() {
+
+ WebsocketComponent component = getContext().getComponent("websocket", WebsocketComponent.class);
+ component.setHost("localhost");
+ component.setPort(1989);
+ component.setStaticResources("src/test/resources");
+
+ from("websocket://foo")
+ .log("${body}")
+ .setHeader(WebsocketConstants.SEND_TO_ALL, constant(true))
+ .to("websocket://foo");
+ }
+ };
+ }
+
+}
Added: camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/DefaultWebsocketTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/DefaultWebsocketTest.java?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/DefaultWebsocketTest.java (added)
+++ camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/DefaultWebsocketTest.java Fri Jan 6 10:24:34 2012
@@ -0,0 +1,161 @@
+/**
+ * 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 org.apache.camel.component.websocket;
+
+import org.eclipse.jetty.websocket.WebSocket.Connection;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.times;
+
+/**
+ *
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class DefaultWebsocketTest {
+
+ private static final int CLOSE_CODE = -1;
+ private static final String MESSAGE = "message";
+ private static final String CONNECTION_KEY = "random-connection-key";
+
+ @Mock
+ private Connection connection;
+
+ @Mock
+ private WebsocketConsumer consumer;
+
+ @Mock
+ private NodeSynchronization sync;
+
+ private DefaultWebsocket defaultWebsocket;
+
+ /**
+ * @throws Exception
+ */
+ @Before
+ public void setUp() throws Exception {
+ // sync = new NodeSynchronizationImpl(new MemoryWebsocketStore());
+ defaultWebsocket = new DefaultWebsocket(sync, consumer);
+ defaultWebsocket.setConnectionKey(CONNECTION_KEY);
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.DefaultWebsocket#onClose(int, String)} .
+ */
+ @Test
+ public void testOnClose() {
+ defaultWebsocket.onClose(CLOSE_CODE, MESSAGE);
+ InOrder inOrder = inOrder(connection, consumer, sync);
+ inOrder.verify(sync, times(1)).removeSocket(defaultWebsocket);
+ inOrder.verifyNoMoreInteractions();
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.DefaultWebsocket#onOpen(org.eclipse.jetty.websocket.WebSocket.Connection)} .
+ */
+ @Test
+ public void testOnOpen() {
+ defaultWebsocket.onOpen(connection);
+
+ /*
+ * keyCaptor not functional anymore, because addSocket cannot be called with connectionKey
+ *
+ * InOrder inOrder = inOrder(connection, consumer, sync); ArgumentCaptor<String> keyCaptor = ArgumentCaptor.forClass(String.class); inOrder.verify(sync,
+ * times(1)).addSocket((eq(defaultWebsocket))); inOrder.verifyNoMoreInteractions();
+ */
+
+ assertEquals(connection, defaultWebsocket.getConnection());
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.DefaultWebsocket#onMessage(String)} .
+ */
+ @Test
+ public void testOnMessage() {
+ defaultWebsocket.setConnectionKey(CONNECTION_KEY);
+ defaultWebsocket.onMessage(MESSAGE);
+ InOrder inOrder = inOrder(connection, consumer, sync);
+ inOrder.verify(consumer, times(1)).sendExchange(CONNECTION_KEY, MESSAGE);
+ inOrder.verifyNoMoreInteractions();
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.DefaultWebsocket#onMessage(String)} .
+ */
+ @Test
+ public void testOnMessageWithNullConsumer() {
+ defaultWebsocket = new DefaultWebsocket(sync, null);
+ defaultWebsocket.setConnectionKey(CONNECTION_KEY);
+ defaultWebsocket.onMessage(MESSAGE);
+ InOrder inOrder = inOrder(connection, consumer, sync);
+ inOrder.verify(consumer, times(0)).sendExchange(CONNECTION_KEY, MESSAGE);
+ inOrder.verifyNoMoreInteractions();
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.DefaultWebsocket#getConnection()} .
+ */
+ @Test
+ public void testGetConnection() {
+ assertNull(defaultWebsocket.getConnection());
+ defaultWebsocket.onOpen(connection);
+ assertEquals(connection, defaultWebsocket.getConnection());
+ defaultWebsocket.setConnection(null);
+ assertNull(defaultWebsocket.getConnection());
+ defaultWebsocket.setConnection(connection);
+ assertEquals(connection, defaultWebsocket.getConnection());
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.DefaultWebsocket#setConnection(org.eclipse.jetty.websocket.WebSocket.Connection)} .
+ */
+ @Test
+ public void testSetConnection() {
+ testGetConnection();
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.DefaultWebsocket#getConnectionKey()} .
+ */
+ @Test
+ public void testGetConnectionKey() {
+ defaultWebsocket.setConnectionKey(null);
+ assertNull(defaultWebsocket.getConnectionKey());
+ defaultWebsocket.onOpen(connection);
+ assertNotNull(defaultWebsocket.getConnectionKey());
+ defaultWebsocket.setConnectionKey(CONNECTION_KEY);
+ assertEquals(CONNECTION_KEY, defaultWebsocket.getConnectionKey());
+ defaultWebsocket.setConnectionKey(null);
+ assertNull(defaultWebsocket.getConnectionKey());
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.DefaultWebsocket#setConnectionKey(String)} .
+ */
+ @Test
+ public void testSetConnectionKey() {
+ testGetConnectionKey();
+ }
+}
Added: camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/MemoryWebsocketStoreTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/MemoryWebsocketStoreTest.java?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/MemoryWebsocketStoreTest.java (added)
+++ camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/MemoryWebsocketStoreTest.java Fri Jan 6 10:24:34 2012
@@ -0,0 +1,216 @@
+/**
+ * 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 org.apache.camel.component.websocket;
+
+import java.util.Collection;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.when;
+
+/**
+ *
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class MemoryWebsocketStoreTest {
+
+ private static final String KEY_1 = "one";
+ private static final String KEY_2 = "two";
+
+ @Mock
+ private WebsocketConsumer consumer;
+
+ @Mock
+ private NodeSynchronization sync;
+
+ @Mock
+ private DefaultWebsocket websocket1 = new DefaultWebsocket(sync, consumer);;
+
+ @Mock
+ private DefaultWebsocket websocket2 = new DefaultWebsocket(sync, consumer);;
+
+ private MemoryWebsocketStore store;
+
+ /**
+ * @throws Exception
+ */
+ @Before
+ public void setUp() throws Exception {
+ store = new MemoryWebsocketStore();
+ when(websocket1.getConnectionKey()).thenReturn(KEY_1);
+ when(websocket2.getConnectionKey()).thenReturn(KEY_2);
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.MemoryWebsocketStore#add(String, org.apache.camel.component.websocket.DefaultWebsocket)} .
+ */
+ @Test
+ public void testAdd() {
+ assertNotNull(websocket1.getConnectionKey());
+
+ store.add(websocket1);
+ assertEquals(websocket1, store.get(KEY_1));
+
+ store.add(websocket2);
+ assertEquals(websocket2, store.get(KEY_2));
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.MemoryWebsocketStore#add(org.apache.camel.component.websocket.DefaultWebsocket)} .
+ */
+ @Test(expected = NullPointerException.class)
+ public void testAddNullValue() {
+ store.add(null);
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.MemoryWebsocketStore#remove(org.apache.camel.component.websocket.DefaultWebsocket)} .
+ */
+ @Test
+ public void testRemoveDefaultWebsocket() {
+ // first call of websocket1.getConnectionKey()
+ store.add(websocket1);
+ assertEquals(websocket1, store.get(KEY_1));
+ // second call of websocket1.getConnectionKey()
+ store.remove(websocket1);
+ assertNull(store.get(KEY_1));
+
+ InOrder inOrder = inOrder(websocket1, websocket2);
+ inOrder.verify(websocket1, times(2)).getConnectionKey();
+ inOrder.verifyNoMoreInteractions();
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.MemoryWebsocketStore#remove(org.apache.camel.component.websocket.DefaultWebsocket)} .
+ */
+ @Test
+ public void testRemoveDefaultWebsocketKeyNotSet() {
+ // first call of websocket1.getConnectionKey()
+ store.add(websocket1);
+
+ // overload getConnectionKey() after store.add() - otherwise npe
+ when(websocket1.getConnectionKey()).thenReturn(null);
+
+ assertEquals(websocket1, store.get(KEY_1));
+
+ try {
+ store.remove(websocket1);
+ fail("Exception expected");
+ } catch (Exception e) {
+ assertEquals(NullPointerException.class, e.getClass());
+ }
+
+ InOrder inOrder = inOrder(websocket1, websocket2);
+ inOrder.verify(websocket1, times(2)).getConnectionKey();
+ inOrder.verifyNoMoreInteractions();
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.MemoryWebsocketStore#remove(org.apache.camel.component.websocket.DefaultWebsocket)} .
+ */
+ @Test
+ public void testRemoveNotExisting() {
+ websocket1.setConnectionKey(KEY_1);
+ store.add(websocket1);
+ assertEquals(websocket1, store.get(KEY_1));
+ assertNull(store.get(KEY_2));
+ store.remove(websocket2);
+ assertEquals(websocket1, store.get(KEY_1));
+ assertNull(store.get(KEY_2));
+
+ InOrder inOrder = inOrder(websocket1, websocket2);
+ inOrder.verify(websocket2, times(1)).getConnectionKey();
+ inOrder.verifyNoMoreInteractions();
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.MemoryWebsocketStore#remove(String)} .
+ */
+ @Test
+ public void testRemoveString() {
+ websocket1.setConnectionKey(KEY_1);
+ store.add(websocket1);
+ assertEquals(websocket1, store.get(KEY_1));
+ store.remove(KEY_1);
+ assertNull(store.get(KEY_1));
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.MemoryWebsocketStore#remove(String)} .
+ */
+ @Test
+ public void testRemoveStringNotExisting() {
+ websocket1.setConnectionKey(KEY_1);
+ store.add(websocket1);
+ assertEquals(websocket1, store.get(KEY_1));
+ assertNull(store.get(KEY_2));
+ store.remove(KEY_2);
+ assertEquals(websocket1, store.get(KEY_1));
+ assertNull(store.get(KEY_2));
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.MemoryWebsocketStore#get(String)} .
+ */
+ @Test
+ public void testGetString() {
+ websocket1.setConnectionKey(KEY_1);
+ store.add(websocket1);
+ assertEquals(websocket1, store.get(KEY_1));
+ assertNull(store.get(KEY_2));
+ websocket2.setConnectionKey(KEY_2);
+ store.add(websocket2);
+ assertEquals(websocket1, store.get(KEY_1));
+ assertEquals(websocket2, store.get(KEY_2));
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.MemoryWebsocketStore#getAll()} .
+ */
+ @Test
+ public void testGetAll() {
+ Collection<DefaultWebsocket> sockets = store.getAll();
+ assertNotNull(sockets);
+ assertEquals(0, sockets.size());
+
+ websocket1.setConnectionKey(KEY_1);
+ store.add(websocket1);
+ sockets = store.getAll();
+ assertNotNull(sockets);
+ assertEquals(1, sockets.size());
+ assertTrue(sockets.contains(websocket1));
+
+ websocket2.setConnectionKey(KEY_2);
+ store.add(websocket2);
+ sockets = store.getAll();
+ assertNotNull(sockets);
+ assertEquals(2, sockets.size());
+ assertTrue(sockets.contains(websocket1));
+ assertTrue(sockets.contains(websocket2));
+ }
+}
Added: camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/NodeSynchronizationImplTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/NodeSynchronizationImplTest.java?rev=1228060&view=auto
==============================================================================
--- camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/NodeSynchronizationImplTest.java (added)
+++ camel/trunk/components/camel-websocket/src/test/java/org/apache/camel/component/websocket/NodeSynchronizationImplTest.java Fri Jan 6 10:24:34 2012
@@ -0,0 +1,235 @@
+/**
+ * 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 org.apache.camel.component.websocket;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+/**
+ *
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class NodeSynchronizationImplTest {
+
+ private static final String KEY_1 = "one";
+ private static final String KEY_2 = "two";
+ private static final String KEY_3 = "three";
+
+ @Mock
+ private WebsocketConsumer consumer;
+
+ private DefaultWebsocket websocket1;
+ private DefaultWebsocket websocket2;
+
+ private NodeSynchronization sync;
+
+ private MemoryWebsocketStore store1;
+ private MemoryWebsocketStore store2;
+
+ /**
+ * @throws Exception
+ */
+ @Before
+ public void setUp() throws Exception {
+
+ store1 = new MemoryWebsocketStore();
+ store2 = new MemoryWebsocketStore();
+
+ websocket1 = new DefaultWebsocket(sync, consumer);
+ websocket1.setConnectionKey(KEY_1);
+
+ websocket2 = new DefaultWebsocket(sync, consumer);
+ websocket2.setConnectionKey(KEY_2);
+
+ // when(websocket1.getConnectionKey()).thenReturn(KEY_1);
+ // when(websocket2.getConnectionKey()).thenReturn(KEY_2);
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.NodeSynchronization#addSocket(org.apache.camel.component.websocket.DefaultWebsocket)} .
+ */
+ @Test
+ public void testAddSocketMemoryAndGlobal() {
+ sync = new NodeSynchronizationImpl(store1, store2);
+
+ sync.addSocket(websocket1);
+ assertEquals(websocket1, store1.get(KEY_1));
+ assertEquals(store1.get(KEY_1), store2.get(KEY_1));
+
+ sync.addSocket(websocket2);
+ assertEquals(websocket2, store1.get(KEY_2));
+ assertEquals(store1.get(KEY_2), store2.get(KEY_2));
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.NodeSynchronization#addSocket(org.apache.camel.component.websocket.DefaultWebsocket)} .
+ */
+ @Test
+ public void testAddSocketMemoryOnly() {
+ sync = new NodeSynchronizationImpl(store1);
+
+ sync.addSocket(websocket1);
+ assertEquals(websocket1, store1.get(KEY_1));
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.NodeSynchronization#addSocket(org.apache.camel.component.websocket.DefaultWebsocket)} .
+ */
+ @Test
+ public void testAddSocketMemoryAndNullGlobal() {
+ sync = new NodeSynchronizationImpl(store1, null);
+
+ sync.addSocket(websocket1);
+ assertEquals(websocket1, store1.get(KEY_1));
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.NodeSynchronization#addSocket(org.apache.camel.component.websocket.DefaultWebsocket)} .
+ */
+ @Test(expected = NullPointerException.class)
+ public void testAddNullValue() {
+ sync.addSocket(null);
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.NodeSynchronization#removeSocket(org.apache.camel.component.websocket.DefaultWebsocket)} .
+ */
+ @Test
+ public void testRemoveDefaultWebsocket() {
+ sync = new NodeSynchronizationImpl(store1, store2);
+
+ // first call of websocket1.getConnectionKey()
+ sync.addSocket(websocket1);
+ assertEquals(websocket1, store1.get(KEY_1));
+ assertEquals(store1.get(KEY_1), store2.get(KEY_1));
+
+ sync.addSocket(websocket2);
+ assertEquals(websocket2, store1.get(KEY_2));
+ assertEquals(store1.get(KEY_2), store2.get(KEY_2));
+
+ // second call of websocket1.getConnectionKey()
+ sync.removeSocket(websocket1);
+ assertNull(store1.get(KEY_1));
+ assertNull(store2.get(KEY_1));
+
+ assertNotNull(store1.get(KEY_2));
+ assertNotNull(store2.get(KEY_2));
+
+ sync.removeSocket(websocket2);
+ assertNull(store1.get(KEY_2));
+ assertNull(store2.get(KEY_2));
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.NodeSynchronization#removeSocket(org.apache.camel.component.websocket.DefaultWebsocket)} .
+ */
+ @Test
+ public void testRemoveDefaultWebsocketKeyNotSet() {
+ sync = new NodeSynchronizationImpl(store1);
+
+ // first call of websocket1.getConnectionKey()
+ sync.addSocket(websocket1);
+ assertEquals(websocket1, store1.get(KEY_1));
+
+ // setConnectionKey(null) after sync.addSocket()- otherwise npe
+ websocket1.setConnectionKey(null);
+
+ try {
+ // second call of websocket1.getConnectionKey()
+ sync.removeSocket(websocket1);
+ fail("Exception expected");
+ } catch (Exception e) {
+ assertEquals(NullPointerException.class, e.getClass());
+ }
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.NodeSynchronization#removeSocket(org.apache.camel.component.websocket.DefaultWebsocket)} .
+ */
+ @Test
+ public void testRemoveNotExisting() {
+ sync = new NodeSynchronizationImpl(store1);
+
+ // first call of websocket1.getConnectionKey()
+ sync.addSocket(websocket1);
+ assertEquals(websocket1, store1.get(KEY_1));
+
+ assertNull(store1.get(KEY_2));
+ sync.removeSocket(websocket2);
+
+ assertEquals(websocket1, store1.get(KEY_1));
+ assertNull(store1.get(KEY_2));
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.NodeSynchronization#removeSocket(String)} .
+ */
+ @Test
+ public void testRemoveString() {
+ sync = new NodeSynchronizationImpl(store1, store2);
+
+ // first call of websocket1.getConnectionKey()
+ sync.addSocket(websocket1);
+ assertEquals(websocket1, store1.get(KEY_1));
+ assertEquals(store1.get(KEY_1), store2.get(KEY_1));
+
+ sync.addSocket(websocket2);
+ assertEquals(websocket2, store1.get(KEY_2));
+ assertEquals(store1.get(KEY_2), store2.get(KEY_2));
+
+ // second call of websocket1.getConnectionKey()
+ sync.removeSocket(KEY_1);
+ assertNull(store1.get(KEY_1));
+ assertNull(store2.get(KEY_1));
+
+ assertNotNull(store1.get(KEY_2));
+ assertNotNull(store2.get(KEY_2));
+
+ sync.removeSocket(KEY_2);
+ assertNull(store1.get(KEY_2));
+ assertNull(store2.get(KEY_2));
+ }
+
+ /**
+ * Test method for {@link org.apache.camel.component.websocket.NodeSynchronization#removeSocket(String)} .
+ */
+ @Test
+ public void testRemoveStringNotExisting() {
+
+ sync = new NodeSynchronizationImpl(store1);
+
+ // first call of websocket1.getConnectionKey()
+ sync.addSocket(websocket1);
+ assertEquals(websocket1, store1.get(KEY_1));
+
+ assertNull(store1.get(KEY_3));
+ sync.removeSocket(KEY_3);
+
+ assertEquals(websocket1, store1.get(KEY_1));
+ assertNull(store1.get(KEY_3));
+
+ }
+
+}