You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@curator.apache.org by ra...@apache.org on 2014/03/22 14:35:20 UTC
[05/10] git commit: wip
wip
Project: http://git-wip-us.apache.org/repos/asf/curator/repo
Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/0910d482
Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/0910d482
Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/0910d482
Branch: refs/heads/websockets
Commit: 0910d4821f09bf1d965c8547ef82b1516976a6b8
Parents: 20d8c06
Author: randgalt <ra...@apache.org>
Authored: Fri Jan 10 18:44:13 2014 -0500
Committer: randgalt <ra...@apache.org>
Committed: Fri Jan 10 18:44:13 2014 -0500
----------------------------------------------------------------------
curator-x-websockets/pom.xml | 71 ++++++++++++
.../curator/x/websockets/ClientCreator.java | 27 +++++
.../x/websockets/CuratorWebsocketsConfig.java | 68 ++++++++++++
.../x/websockets/CuratorWebsocketsServer.java | 77 +++++++++++++
.../x/websockets/DefaultClientCreator.java | 45 ++++++++
.../curator/x/websockets/api/ApiCommand.java | 30 ++++++
.../x/websockets/api/CommandManager.java | 49 +++++++++
.../curator/x/websockets/api/JsonUtils.java | 56 ++++++++++
.../x/websockets/api/zookeeper/Create.java | 46 ++++++++
.../x/websockets/details/CuratorEndpoint.java | 107 +++++++++++++++++++
.../details/CuratorWebsocketsSession.java | 53 +++++++++
.../x/websockets/details/SessionManager.java | 64 +++++++++++
.../apache/curator/x/websockets/TestServer.java | 30 ++++++
pom.xml | 1 +
14 files changed, 724 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/curator/blob/0910d482/curator-x-websockets/pom.xml
----------------------------------------------------------------------
diff --git a/curator-x-websockets/pom.xml b/curator-x-websockets/pom.xml
new file mode 100644
index 0000000..95803c1
--- /dev/null
+++ b/curator-x-websockets/pom.xml
@@ -0,0 +1,71 @@
+<?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/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>apache-curator</artifactId>
+ <groupId>org.apache.curator</groupId>
+ <version>2.3.2-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>curator-x-websockets</artifactId>
+ <version>2.3.2-SNAPSHOT</version>
+
+ <properties>
+ <tyrus.version>1.3.3</tyrus.version>
+
+ <osgi.import.package>
+ *
+ </osgi.import.package>
+ <osgi.export.package>
+ org.apache.curator.x.websockets*;version="${project.version}";-noimport:=true
+ </osgi.export.package>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-recipes</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.glassfish.tyrus</groupId>
+ <artifactId>tyrus-server</artifactId>
+ <version>${tyrus.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.glassfish.tyrus</groupId>
+ <artifactId>tyrus-container-grizzly-server</artifactId>
+ <version>${tyrus.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-mapper-asl</artifactId>
+ <version>1.9.2</version>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/curator/blob/0910d482/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/ClientCreator.java
----------------------------------------------------------------------
diff --git a/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/ClientCreator.java b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/ClientCreator.java
new file mode 100644
index 0000000..65b8fe0
--- /dev/null
+++ b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/ClientCreator.java
@@ -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.curator.x.websockets;
+
+import org.apache.curator.framework.CuratorFramework;
+
+public interface ClientCreator
+{
+ public CuratorFramework newClient() throws Exception;
+}
http://git-wip-us.apache.org/repos/asf/curator/blob/0910d482/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/CuratorWebsocketsConfig.java
----------------------------------------------------------------------
diff --git a/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/CuratorWebsocketsConfig.java b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/CuratorWebsocketsConfig.java
new file mode 100644
index 0000000..c7227c4
--- /dev/null
+++ b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/CuratorWebsocketsConfig.java
@@ -0,0 +1,68 @@
+/**
+ * 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.curator.x.websockets;
+
+public class CuratorWebsocketsConfig
+{
+ private String bindHost = "localhost";
+ private int port = 8080;
+ private String rootPath = "/websockets";
+ private String websocketPath = "/curator";
+
+ public String getBindHost()
+ {
+ return bindHost;
+ }
+
+ public void setBindHost(String bindHost)
+ {
+ this.bindHost = bindHost;
+ }
+
+ public int getPort()
+ {
+ return port;
+ }
+
+ public void setPort(int port)
+ {
+ this.port = port;
+ }
+
+ public String getRootPath()
+ {
+ return rootPath;
+ }
+
+ public void setRootPath(String rootPath)
+ {
+ this.rootPath = rootPath;
+ }
+
+ public String getWebsocketPath()
+ {
+ return websocketPath;
+ }
+
+ public void setWebsocketPath(String websocketPath)
+ {
+ this.websocketPath = websocketPath;
+ }
+}
http://git-wip-us.apache.org/repos/asf/curator/blob/0910d482/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/CuratorWebsocketsServer.java
----------------------------------------------------------------------
diff --git a/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/CuratorWebsocketsServer.java b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/CuratorWebsocketsServer.java
new file mode 100644
index 0000000..3bc8ff2
--- /dev/null
+++ b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/CuratorWebsocketsServer.java
@@ -0,0 +1,77 @@
+/**
+ * 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.curator.x.websockets;
+
+import com.google.common.base.Preconditions;
+import org.apache.curator.x.websockets.api.CommandManager;
+import org.apache.curator.x.websockets.details.CuratorEndpoint;
+import org.apache.curator.x.websockets.details.SessionManager;
+import org.glassfish.tyrus.spi.ServerContainer;
+import org.glassfish.tyrus.spi.ServerContainerFactory;
+import javax.websocket.server.ServerEndpointConfig;
+import java.io.Closeable;
+import java.util.List;
+
+public class CuratorWebsocketsServer implements Closeable
+{
+ private final ServerContainer serverContainer;
+ private final String rootPath;
+ private final int port;
+ private final CommandManager commandManager = new CommandManager();
+
+ public CuratorWebsocketsServer(CuratorWebsocketsConfig config, ClientCreator clientCreator) throws Exception
+ {
+ rootPath = config.getRootPath();
+ port = config.getPort();
+
+ serverContainer = ServerContainerFactory.createServerContainer(null);
+
+ final SessionManager sessionManager = new SessionManager(clientCreator, commandManager);
+ ServerEndpointConfig.Configurator configurator = new ServerEndpointConfig.Configurator()
+ {
+ @Override
+ public String getNegotiatedSubprotocol(List<String> supported, List<String> requested)
+ {
+ return super.getNegotiatedSubprotocol(supported, requested);
+ }
+
+ @Override
+ public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException
+ {
+ Preconditions.checkArgument(endpointClass.equals(CuratorEndpoint.class), "Expected CuratorEndpoint: " + endpointClass.getName());
+ //noinspection unchecked
+ return (T)new CuratorEndpoint(sessionManager);
+ }
+ };
+ ServerEndpointConfig serverEndpointConfig = ServerEndpointConfig.Builder.create(CuratorEndpoint.class, config.getWebsocketPath()).configurator(configurator).build();
+ serverContainer.addEndpoint(serverEndpointConfig);
+ }
+
+ public void start() throws Exception
+ {
+ serverContainer.start(rootPath, port);
+ }
+
+ @Override
+ public void close()
+ {
+ serverContainer.stop();
+ }
+}
http://git-wip-us.apache.org/repos/asf/curator/blob/0910d482/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/DefaultClientCreator.java
----------------------------------------------------------------------
diff --git a/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/DefaultClientCreator.java b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/DefaultClientCreator.java
new file mode 100644
index 0000000..619445c
--- /dev/null
+++ b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/DefaultClientCreator.java
@@ -0,0 +1,45 @@
+/**
+ * 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.curator.x.websockets;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.CuratorFrameworkFactory;
+import org.apache.curator.retry.ExponentialBackoffRetry;
+
+public class DefaultClientCreator implements ClientCreator
+{
+ private final ExponentialBackoffRetry retryPolicy;
+
+ public DefaultClientCreator()
+ {
+ this(new ExponentialBackoffRetry(100, 3));
+ }
+
+ public DefaultClientCreator(ExponentialBackoffRetry retryPolicy)
+ {
+ this.retryPolicy = retryPolicy;
+ }
+
+ @Override
+ public CuratorFramework newClient() throws Exception
+ {
+ return CuratorFrameworkFactory.newClient("localhost:2181", retryPolicy);
+ }
+}
http://git-wip-us.apache.org/repos/asf/curator/blob/0910d482/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/api/ApiCommand.java
----------------------------------------------------------------------
diff --git a/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/api/ApiCommand.java b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/api/ApiCommand.java
new file mode 100644
index 0000000..438e1a6
--- /dev/null
+++ b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/api/ApiCommand.java
@@ -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.curator.x.websockets.api;
+
+import org.apache.curator.x.websockets.details.CuratorWebsocketsSession;
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.map.ObjectReader;
+import org.codehaus.jackson.map.ObjectWriter;
+
+public interface ApiCommand
+{
+ public String process(JsonNode input, CuratorWebsocketsSession session, ObjectReader reader, ObjectWriter writer) throws Exception;
+}
http://git-wip-us.apache.org/repos/asf/curator/blob/0910d482/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/api/CommandManager.java
----------------------------------------------------------------------
diff --git a/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/api/CommandManager.java b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/api/CommandManager.java
new file mode 100644
index 0000000..c16e927
--- /dev/null
+++ b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/api/CommandManager.java
@@ -0,0 +1,49 @@
+/**
+ * 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.curator.x.websockets.api;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.curator.x.websockets.api.zookeeper.Create;
+import java.io.FileNotFoundException;
+import java.util.Map;
+
+public class CommandManager
+{
+ private final Map<String, Class<? extends ApiCommand>> commands;
+
+ public CommandManager()
+ {
+ ImmutableMap.Builder<String, Class<? extends ApiCommand>> builder = ImmutableMap.builder();
+
+ builder.put("zookeeper/create", Create.class);
+
+ commands = builder.build();
+ }
+
+ public ApiCommand newCommand(String name) throws Exception
+ {
+ Class<? extends ApiCommand> clazz = commands.get(name);
+ if ( clazz == null )
+ {
+ throw new FileNotFoundException(name);
+ }
+ return clazz.newInstance();
+ }
+}
http://git-wip-us.apache.org/repos/asf/curator/blob/0910d482/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/api/JsonUtils.java
----------------------------------------------------------------------
diff --git a/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/api/JsonUtils.java b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/api/JsonUtils.java
new file mode 100644
index 0000000..8c18d7c
--- /dev/null
+++ b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/api/JsonUtils.java
@@ -0,0 +1,56 @@
+/**
+ * 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.curator.x.websockets.api;
+
+import org.codehaus.jackson.JsonNode;
+
+public class JsonUtils
+{
+ public static String getRequiredString(JsonNode node, String name) throws Exception
+ {
+ JsonNode jsonNode = node.get(name);
+ if ( jsonNode == null )
+ {
+ throw new Exception("Required field is missing: " + name);
+ }
+ return jsonNode.asText();
+ }
+
+ public static String getOptionalString(JsonNode node, String name)
+ {
+ return getOptionalString(node, name, null);
+ }
+
+ public static String getOptionalString(JsonNode node, String name, String defaultValue)
+ {
+ JsonNode jsonNode = node.get(name);
+ return (jsonNode != null) ? jsonNode.asText() : defaultValue;
+ }
+
+ public static boolean getOptionalBoolean(JsonNode node, String name)
+ {
+ JsonNode jsonNode = node.get(name);
+ return (jsonNode != null) && jsonNode.asBoolean();
+ }
+
+ private JsonUtils()
+ {
+ }
+}
http://git-wip-us.apache.org/repos/asf/curator/blob/0910d482/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/api/zookeeper/Create.java
----------------------------------------------------------------------
diff --git a/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/api/zookeeper/Create.java b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/api/zookeeper/Create.java
new file mode 100644
index 0000000..3cd148d
--- /dev/null
+++ b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/api/zookeeper/Create.java
@@ -0,0 +1,46 @@
+/**
+ * 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.curator.x.websockets.api.zookeeper;
+
+import org.apache.curator.x.websockets.api.ApiCommand;
+import org.apache.curator.x.websockets.api.JsonUtils;
+import org.apache.curator.x.websockets.details.CuratorWebsocketsSession;
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.map.ObjectReader;
+import org.codehaus.jackson.map.ObjectWriter;
+
+public class Create implements ApiCommand
+{
+ @Override
+ public String process(JsonNode input, CuratorWebsocketsSession session, ObjectReader reader, ObjectWriter writer) throws Exception
+ {
+ String path = JsonUtils.getRequiredString(input, "path");
+ boolean withProtection = JsonUtils.getOptionalBoolean(input, "withProtection");
+ boolean creatingParentsIfNeeded = JsonUtils.getOptionalBoolean(input, "creatingParentsIfNeeded");
+ boolean compressed = JsonUtils.getOptionalBoolean(input, "compressed");
+ boolean async = JsonUtils.getOptionalBoolean(input, "async");
+ String mode = JsonUtils.getOptionalString(input, "mode", "persistent");
+
+ JsonNode payload = input.get("payload");
+
+ // TODO ACL
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/curator/blob/0910d482/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/details/CuratorEndpoint.java
----------------------------------------------------------------------
diff --git a/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/details/CuratorEndpoint.java b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/details/CuratorEndpoint.java
new file mode 100644
index 0000000..576f475
--- /dev/null
+++ b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/details/CuratorEndpoint.java
@@ -0,0 +1,107 @@
+/**
+ * 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.curator.x.websockets.details;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.x.websockets.api.ApiCommand;
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.ObjectReader;
+import org.codehaus.jackson.map.ObjectWriter;
+import javax.websocket.CloseReason;
+import javax.websocket.Endpoint;
+import javax.websocket.EndpointConfig;
+import javax.websocket.MessageHandler;
+import javax.websocket.Session;
+import java.io.IOException;
+
+public class CuratorEndpoint extends Endpoint
+{
+ private final SessionManager sessionManager;
+ private final ObjectReader reader = new ObjectMapper().reader();
+ private final ObjectWriter writer = new ObjectMapper().writer();
+
+ public CuratorEndpoint(SessionManager sessionManager)
+ {
+ this.sessionManager = sessionManager;
+ }
+
+ @Override
+ public void onOpen(final Session session, EndpointConfig config)
+ {
+ try
+ {
+ CuratorFramework client = sessionManager.getClientCreator().newClient();
+ sessionManager.put(session, new CuratorWebsocketsSession(client, session));
+
+ client.start();
+ }
+ catch ( Exception e )
+ {
+ // TODO
+ }
+
+ MessageHandler handler = new MessageHandler.Whole<String>()
+ {
+ @Override
+ public void onMessage(String message)
+ {
+ processMessage(session, message);
+ }
+ };
+ session.addMessageHandler(handler);
+ }
+
+ @Override
+ public void onClose(Session session, CloseReason closeReason)
+ {
+ CuratorWebsocketsSession curatorWebsocketsSession = sessionManager.remove(session);
+ if ( curatorWebsocketsSession != null )
+ {
+ curatorWebsocketsSession.close();
+ }
+ }
+
+ private void processMessage(Session session, String message)
+ {
+ try
+ {
+ CuratorWebsocketsSession curatorWebsocketsSession = sessionManager.get(session);
+ if ( curatorWebsocketsSession == null )
+ {
+ throw new Exception("No session found for sessionId: " + session.getId());
+ }
+
+ JsonNode jsonNode = reader.readTree(message);
+ JsonNode command = jsonNode.get("command");
+ if ( command == null )
+ {
+ throw new Exception("Missing field: \"command\"");
+ }
+ String commandName = command.asText();
+ ApiCommand apiCommand = sessionManager.getCommandManager().newCommand(commandName);
+ apiCommand.process(jsonNode, curatorWebsocketsSession, reader, writer);
+ }
+ catch ( Exception e )
+ {
+ // TODO
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/curator/blob/0910d482/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/details/CuratorWebsocketsSession.java
----------------------------------------------------------------------
diff --git a/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/details/CuratorWebsocketsSession.java b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/details/CuratorWebsocketsSession.java
new file mode 100644
index 0000000..9df8b68
--- /dev/null
+++ b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/details/CuratorWebsocketsSession.java
@@ -0,0 +1,53 @@
+/**
+ * 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.curator.x.websockets.details;
+
+import com.google.common.io.Closeables;
+import org.apache.curator.framework.CuratorFramework;
+import javax.websocket.Session;
+import java.io.Closeable;
+
+public class CuratorWebsocketsSession implements Closeable
+{
+ private final CuratorFramework client;
+ private final Session session;
+
+ public CuratorWebsocketsSession(CuratorFramework client, Session session)
+ {
+ this.client = client;
+ this.session = session;
+ }
+
+ @Override
+ public void close()
+ {
+ Closeables.closeQuietly(client);
+ }
+
+ public CuratorFramework getClient()
+ {
+ return client;
+ }
+
+ public Session getSession()
+ {
+ return session;
+ }
+}
http://git-wip-us.apache.org/repos/asf/curator/blob/0910d482/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/details/SessionManager.java
----------------------------------------------------------------------
diff --git a/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/details/SessionManager.java b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/details/SessionManager.java
new file mode 100644
index 0000000..5c37ac3
--- /dev/null
+++ b/curator-x-websockets/src/main/java/org/apache/curator/x/websockets/details/SessionManager.java
@@ -0,0 +1,64 @@
+/**
+ * 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.curator.x.websockets.details;
+
+import com.google.common.collect.Maps;
+import org.apache.curator.x.websockets.ClientCreator;
+import org.apache.curator.x.websockets.api.CommandManager;
+import javax.websocket.Session;
+import java.util.Map;
+
+public class SessionManager
+{
+ private final Map<String, CuratorWebsocketsSession> sessions = Maps.newConcurrentMap();
+ private final ClientCreator clientCreator;
+ private final CommandManager commandManager;
+
+ public SessionManager(ClientCreator clientCreator, CommandManager commandManager)
+ {
+ this.clientCreator = clientCreator;
+ this.commandManager = commandManager;
+ }
+
+ public void put(Session session, CuratorWebsocketsSession curatorWebsocketsSession)
+ {
+ sessions.put(session.getId(), curatorWebsocketsSession);
+ }
+
+ public CuratorWebsocketsSession get(Session session)
+ {
+ return sessions.get(session.getId());
+ }
+
+ public CuratorWebsocketsSession remove(Session session)
+ {
+ return sessions.remove(session.getId());
+ }
+
+ public ClientCreator getClientCreator()
+ {
+ return clientCreator;
+ }
+
+ public CommandManager getCommandManager()
+ {
+ return commandManager;
+ }
+}
http://git-wip-us.apache.org/repos/asf/curator/blob/0910d482/curator-x-websockets/src/test/java/org/apache/curator/x/websockets/TestServer.java
----------------------------------------------------------------------
diff --git a/curator-x-websockets/src/test/java/org/apache/curator/x/websockets/TestServer.java b/curator-x-websockets/src/test/java/org/apache/curator/x/websockets/TestServer.java
new file mode 100644
index 0000000..f9eef23
--- /dev/null
+++ b/curator-x-websockets/src/test/java/org/apache/curator/x/websockets/TestServer.java
@@ -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.curator.x.websockets;
+
+public class TestServer
+{
+ public static void main(String[] args) throws Exception
+ {
+ CuratorWebsocketsServer server = new CuratorWebsocketsServer(new CuratorWebsocketsConfig(), new DefaultClientCreator());
+ server.start();
+ Thread.currentThread().join();
+ }
+}
http://git-wip-us.apache.org/repos/asf/curator/blob/0910d482/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index af548c2..91e899f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -224,6 +224,7 @@
<module>curator-examples</module>
<module>curator-x-discovery</module>
<module>curator-x-discovery-server</module>
+ <module>curator-x-websockets</module>
</modules>
<dependencyManagement>