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/02/16 00:55:08 UTC

git commit: 1. Beginnings of doxia doc 2. Got rid of session manager concept. It's unnecessary and complicated.

Repository: curator
Updated Branches:
  refs/heads/CURATOR-88 95b8e77e9 -> a3cdddc1b


1. Beginnings of doxia doc
2. Got rid of session manager concept. It's unnecessary and complicated.


Project: http://git-wip-us.apache.org/repos/asf/curator/repo
Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/a3cdddc1
Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/a3cdddc1
Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/a3cdddc1

Branch: refs/heads/CURATOR-88
Commit: a3cdddc1b50b2ca4ced1b7deb8a70328eba75be8
Parents: 95b8e77
Author: randgalt <ra...@apache.org>
Authored: Sat Feb 15 18:54:30 2014 -0500
Committer: randgalt <ra...@apache.org>
Committed: Sat Feb 15 18:54:30 2014 -0500

----------------------------------------------------------------------
 .../curator/x/rest/CuratorRestClasses.java      |   2 -
 .../curator/x/rest/CuratorRestContext.java      |  24 +++--
 .../curator/x/rest/api/ClientResource.java      |  43 +++++---
 .../org/apache/curator/x/rest/api/Closer.java   |  24 +++++
 .../apache/curator/x/rest/api/Constants.java    |  17 ++-
 .../curator/x/rest/api/LeaderResource.java      |  15 +--
 .../apache/curator/x/rest/api/LockResource.java |  14 +--
 .../curator/x/rest/api/NodeCacheResource.java   |  20 ++--
 .../x/rest/api/PathChildrenCacheResource.java   |  25 ++---
 .../api/PersistentEphemeralNodeResource.java    |  14 +--
 .../x/rest/api/ReadWriteLockResource.java       |  22 ++--
 .../curator/x/rest/api/SemaphoreResource.java   |  16 ++-
 .../org/apache/curator/x/rest/api/Session.java  | 103 +++++++++++++++++++
 .../curator/x/rest/api/SessionResource.java     |  79 --------------
 .../apache/curator/x/rest/details/Closer.java   |  24 -----
 .../apache/curator/x/rest/details/Session.java  | 103 -------------------
 .../curator/x/rest/details/SessionManager.java  |  91 ----------------
 .../src/site/confluence/index.confluence        |   8 ++
 curator-x-rest/src/site/site.xml                |  31 ++++++
 .../x/rest/dropwizard/DropwizardRunner.java     |   3 +-
 pom.xml                                         |   2 +
 src/site/site.xml                               |   1 +
 22 files changed, 266 insertions(+), 415 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/curator-x-rest/src/main/java/org/apache/curator/x/rest/CuratorRestClasses.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/main/java/org/apache/curator/x/rest/CuratorRestClasses.java b/curator-x-rest/src/main/java/org/apache/curator/x/rest/CuratorRestClasses.java
index 768b649..42c7fb9 100644
--- a/curator-x-rest/src/main/java/org/apache/curator/x/rest/CuratorRestClasses.java
+++ b/curator-x-rest/src/main/java/org/apache/curator/x/rest/CuratorRestClasses.java
@@ -27,7 +27,6 @@ import org.apache.curator.x.rest.api.PathChildrenCacheResource;
 import org.apache.curator.x.rest.api.PersistentEphemeralNodeResource;
 import org.apache.curator.x.rest.api.ReadWriteLockResource;
 import org.apache.curator.x.rest.api.SemaphoreResource;
-import org.apache.curator.x.rest.api.SessionResource;
 import java.util.List;
 
 public class CuratorRestClasses
@@ -35,7 +34,6 @@ public class CuratorRestClasses
     public static List<Class<?>> getClasses()
     {
         ImmutableList.Builder<Class<?>> builder = ImmutableList.builder();
-        builder.add(SessionResource.class);
         builder.add(ClientResource.class);
         builder.add(LockResource.class);
         builder.add(SemaphoreResource.class);

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/curator-x-rest/src/main/java/org/apache/curator/x/rest/CuratorRestContext.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/main/java/org/apache/curator/x/rest/CuratorRestContext.java b/curator-x-rest/src/main/java/org/apache/curator/x/rest/CuratorRestContext.java
index e2f57a2..95d50fb 100644
--- a/curator-x-rest/src/main/java/org/apache/curator/x/rest/CuratorRestContext.java
+++ b/curator-x-rest/src/main/java/org/apache/curator/x/rest/CuratorRestContext.java
@@ -25,7 +25,7 @@ import org.apache.curator.framework.CuratorFramework;
 import org.apache.curator.framework.state.ConnectionState;
 import org.apache.curator.framework.state.ConnectionStateListener;
 import org.apache.curator.utils.ThreadUtils;
-import org.apache.curator.x.rest.details.SessionManager;
+import org.apache.curator.x.rest.api.Session;
 import org.apache.curator.x.rest.entities.StatusMessage;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.codehaus.jackson.map.ObjectWriter;
@@ -42,7 +42,7 @@ import java.util.concurrent.atomic.AtomicReference;
 public class CuratorRestContext implements Closeable
 {
     private final Logger log = LoggerFactory.getLogger(getClass());
-    private final SessionManager sessionManager = new SessionManager();
+    private final Session session = new Session();
     private final ObjectMapper mapper = new ObjectMapper();
     private final ObjectWriter writer = mapper.writer();
     private final CuratorFramework client;
@@ -81,10 +81,11 @@ public class CuratorRestContext implements Closeable
         return client;
     }
 
-    public SessionManager getSessionManager()
+    public Session getSession()
     {
         Preconditions.checkState(state.get() == State.STARTED, "Not started");
-        return sessionManager;
+        session.updateLastUse();
+        return session;
     }
 
     public void start()
@@ -98,7 +99,7 @@ public class CuratorRestContext implements Closeable
             @Override
             public void run()
             {
-                checkSessions();
+                checkSession();
             }
         };
         executorService.scheduleAtFixedRate(runner, sessionLengthMs, sessionLengthMs, TimeUnit.MILLISECONDS);
@@ -116,9 +117,14 @@ public class CuratorRestContext implements Closeable
         return localMessages;
     }
 
-    private void checkSessions()
+    private void checkSession()
     {
-
+        long elapsedSinceLastUse = System.currentTimeMillis() - session.getLastUseMs();
+        if ( elapsedSinceLastUse > sessionLengthMs )
+        {
+            log.warn("Session has expired. Closing all open recipes. Milliseconds since last ping: " + elapsedSinceLastUse);
+            session.closeThings();
+        }
     }
 
     @Override
@@ -128,7 +134,7 @@ public class CuratorRestContext implements Closeable
         {
             client.getConnectionStateListenable().removeListener(connectionStateListener);
             executorService.shutdownNow();
-            sessionManager.close();
+            session.close();
         }
     }
 
@@ -145,6 +151,6 @@ public class CuratorRestContext implements Closeable
     private void handleLostConnection()
     {
         log.warn("Connection lost - closing all REST sessions");
-        sessionManager.deleteAllSessions();
+        session.closeThings();
     }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/ClientResource.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/ClientResource.java b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/ClientResource.java
index 8d3486d..6f8a02f 100644
--- a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/ClientResource.java
+++ b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/ClientResource.java
@@ -30,18 +30,19 @@ import org.apache.curator.x.rest.entities.SetDataSpec;
 import org.codehaus.jackson.node.ObjectNode;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
+import java.io.IOException;
 import java.util.List;
 
-@Path("/curator/v1/client/{session-id}")
+@Path("/curator/v1/client")
 public class ClientResource
 {
     private final CuratorRestContext context;
@@ -51,13 +52,27 @@ public class ClientResource
         this.context = context;
     }
 
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("/status")
+    public Response getStatus() throws IOException
+    {
+        context.getSession();   // update last use
+
+        ObjectNode node = context.getMapper().createObjectNode();
+        node.put("state", context.getClient().getState().name());
+        node.putPOJO("messages", context.drainMessages());
+
+        return Response.ok(context.getWriter().writeValueAsString(node)).build();
+    }
+
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
     @Path("/get-children")
-    public Response getChildren(@PathParam("session-id") String sessionId, final GetChildrenSpec getChildrenSpec) throws Exception
+    public Response getChildren(final GetChildrenSpec getChildrenSpec) throws Exception
     {
-        Constants.getSession(context, sessionId);
+        context.getSession();   // update last use
 
         Object builder = context.getClient().getChildren();
         if ( getChildrenSpec.isWatched() )
@@ -95,9 +110,9 @@ public class ClientResource
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
     @Path("/delete")
-    public Response delete(@PathParam("session-id") String sessionId, final DeleteSpec deleteSpec) throws Exception
+    public Response delete(final DeleteSpec deleteSpec) throws Exception
     {
-        Constants.getSession(context, sessionId);
+        context.getSession();   // update last use
 
         Object builder = context.getClient().delete();
         if ( deleteSpec.isGuaranteed() )
@@ -120,9 +135,9 @@ public class ClientResource
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
     @Path("/set-data")
-    public Response setData(@PathParam("session-id") String sessionId, final SetDataSpec setDataSpec) throws Exception
+    public Response setData(final SetDataSpec setDataSpec) throws Exception
     {
-        Constants.getSession(context, sessionId);
+        context.getSession();   // update last use
 
         Object builder = context.getClient().setData();
         if ( setDataSpec.isCompressed() )
@@ -149,9 +164,9 @@ public class ClientResource
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
     @Path("/create")
-    public Response create(@PathParam("session-id") String sessionId, final CreateSpec createSpec) throws Exception
+    public Response create(final CreateSpec createSpec) throws Exception
     {
-        Constants.getSession(context, sessionId);
+        context.getSession();   // update last use
 
         Object builder = context.getClient().create();
         if ( createSpec.isCreatingParentsIfNeeded() )
@@ -185,9 +200,9 @@ public class ClientResource
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
     @Path("/get-data")
-    public Response getData(@PathParam("session-id") String sessionId, final GetDataSpec getDataSpec) throws Exception
+    public Response getData(final GetDataSpec getDataSpec) throws Exception
     {
-        Constants.getSession(context, sessionId);
+        context.getSession();   // update last use
 
         Object builder = context.getClient().getData();
         if ( getDataSpec.isWatched() )
@@ -228,9 +243,9 @@ public class ClientResource
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
     @Path("/exists")
-    public Response exists(@PathParam("session-id") String sessionId, final ExistsSpec existsSpec) throws Exception
+    public Response exists(final ExistsSpec existsSpec) throws Exception
     {
-        Constants.getSession(context, sessionId);
+        context.getSession();   // update last use
 
         Object builder = context.getClient().checkExists();
         if ( existsSpec.isWatched() )

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/Closer.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/Closer.java b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/Closer.java
new file mode 100644
index 0000000..48e3d6a
--- /dev/null
+++ b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/Closer.java
@@ -0,0 +1,24 @@
+/**
+ * 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.rest.api;
+
+interface Closer<T>
+{
+    public void close(T thing);
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/Constants.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/Constants.java b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/Constants.java
index 378ef65..2696c12 100644
--- a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/Constants.java
+++ b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/Constants.java
@@ -20,11 +20,11 @@ package org.apache.curator.x.rest.api;
 
 import org.apache.curator.framework.recipes.cache.ChildData;
 import org.apache.curator.x.rest.CuratorRestContext;
-import org.apache.curator.x.rest.details.Session;
 import org.apache.curator.x.rest.entities.NodeData;
 import org.codehaus.jackson.node.ObjectNode;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Response;
+import java.util.UUID;
 
 class Constants
 {
@@ -46,16 +46,6 @@ class Constants
         return node;
     }
 
-    static Session getSession(CuratorRestContext context, String sessionId)
-    {
-        Session session = context.getSessionManager().getSession(sessionId);
-        if ( session == null )
-        {
-            throw new WebApplicationException(Response.Status.NOT_FOUND);
-        }
-        return session;
-    }
-
     static <T> T getThing(Session session, String id, Class<T> clazz)
     {
         T thing = session.getThing(id, clazz);
@@ -85,4 +75,9 @@ class Constants
         String payload = (c.getData() != null) ? new String(c.getData()) : "";
         return new NodeData(c.getPath(), c.getStat(), payload);
     }
+
+    public static String newId()
+    {
+        return UUID.randomUUID().toString();
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/LeaderResource.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/LeaderResource.java b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/LeaderResource.java
index 338b744..d5b0cab 100644
--- a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/LeaderResource.java
+++ b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/LeaderResource.java
@@ -21,8 +21,6 @@ package org.apache.curator.x.rest.api;
 import org.apache.curator.framework.recipes.leader.LeaderLatch;
 import org.apache.curator.framework.recipes.leader.LeaderLatchListener;
 import org.apache.curator.x.rest.CuratorRestContext;
-import org.apache.curator.x.rest.details.Closer;
-import org.apache.curator.x.rest.details.Session;
 import org.apache.curator.x.rest.entities.LeaderSpec;
 import org.apache.curator.x.rest.entities.StatusMessage;
 import org.codehaus.jackson.node.ObjectNode;
@@ -39,7 +37,7 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import java.io.IOException;
 
-@Path("/curator/v1/recipes/leader/{session-id}")
+@Path("/curator/v1/recipes/leader")
 public class LeaderResource
 {
     private final Logger log = LoggerFactory.getLogger(getClass());
@@ -53,10 +51,8 @@ public class LeaderResource
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
-    public Response startLeaderSelection(@PathParam("session-id") String sessionId, final LeaderSpec leaderSpec) throws Exception
+    public Response startLeaderSelection(final LeaderSpec leaderSpec) throws Exception
     {
-        Session session = Constants.getSession(context, sessionId);
-
         LeaderLatch leaderLatch = new LeaderLatch(context.getClient(), leaderSpec.getPath(), leaderSpec.getId());
         leaderLatch.start();
 
@@ -75,7 +71,7 @@ public class LeaderResource
                 }
             }
         };
-        final String id = session.addThing(leaderLatch, closer);
+        final String id = context.getSession().addThing(leaderLatch, closer);
 
         LeaderLatchListener listener = new LeaderLatchListener()
         {
@@ -99,10 +95,9 @@ public class LeaderResource
 
     @DELETE
     @Path("{leader-id}")
-    public Response closeLeader(@PathParam("session-id") String sessionId, @PathParam("leader-id") String leaderId) throws Exception
+    public Response closeLeader(@PathParam("leader-id") String leaderId) throws Exception
     {
-        Session session = Constants.getSession(context, sessionId);
-        LeaderLatch leaderLatch = Constants.deleteThing(session, leaderId, LeaderLatch.class);
+        LeaderLatch leaderLatch = Constants.deleteThing(context.getSession(), leaderId, LeaderLatch.class);
         leaderLatch.close();
         return Response.ok().build();
     }

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/LockResource.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/LockResource.java b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/LockResource.java
index f38468f..a5eebda 100644
--- a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/LockResource.java
+++ b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/LockResource.java
@@ -20,8 +20,6 @@ package org.apache.curator.x.rest.api;
 
 import org.apache.curator.framework.recipes.locks.InterProcessSemaphoreMutex;
 import org.apache.curator.x.rest.CuratorRestContext;
-import org.apache.curator.x.rest.details.Closer;
-import org.apache.curator.x.rest.details.Session;
 import org.apache.curator.x.rest.entities.LockSpec;
 import org.codehaus.jackson.node.ObjectNode;
 import org.slf4j.Logger;
@@ -37,7 +35,7 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import java.util.concurrent.TimeUnit;
 
-@Path("/curator/v1/recipes/lock/{session-id}")
+@Path("/curator/v1/recipes/lock")
 public class LockResource
 {
     private final Logger log = LoggerFactory.getLogger(getClass());
@@ -51,9 +49,8 @@ public class LockResource
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
-    public Response acquireLock(@PathParam("session-id") String sessionId, final LockSpec lockSpec) throws Exception
+    public Response acquireLock(final LockSpec lockSpec) throws Exception
     {
-        Session session = Constants.getSession(context, sessionId);
         InterProcessSemaphoreMutex lock = new InterProcessSemaphoreMutex(context.getClient(), lockSpec.getPath());
         if ( !lock.acquire(lockSpec.getMaxWaitMs(), TimeUnit.MILLISECONDS) )
         {
@@ -78,17 +75,16 @@ public class LockResource
                 }
             }
         };
-        String id = session.addThing(lock, closer);
+        String id = context.getSession().addThing(lock, closer);
         ObjectNode node = Constants.makeIdNode(context, id);
         return Response.ok(context.getWriter().writeValueAsString(node)).build();
     }
 
     @DELETE
     @Path("{lock-id}")
-    public Response releaseLock(@PathParam("session-id") String sessionId, @PathParam("lock-id") String lockId) throws Exception
+    public Response releaseLock(@PathParam("lock-id") String lockId) throws Exception
     {
-        Session session = Constants.getSession(context, sessionId);
-        InterProcessSemaphoreMutex lock = Constants.deleteThing(session, lockId, InterProcessSemaphoreMutex.class);
+        InterProcessSemaphoreMutex lock = Constants.deleteThing(context.getSession(), lockId, InterProcessSemaphoreMutex.class);
         lock.release();
         return Response.ok().build();
     }

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/NodeCacheResource.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/NodeCacheResource.java b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/NodeCacheResource.java
index a93f725..74094b6 100644
--- a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/NodeCacheResource.java
+++ b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/NodeCacheResource.java
@@ -21,8 +21,6 @@ package org.apache.curator.x.rest.api;
 import org.apache.curator.framework.recipes.cache.NodeCache;
 import org.apache.curator.framework.recipes.cache.NodeCacheListener;
 import org.apache.curator.x.rest.CuratorRestContext;
-import org.apache.curator.x.rest.details.Closer;
-import org.apache.curator.x.rest.details.Session;
 import org.apache.curator.x.rest.entities.NodeCacheSpec;
 import org.apache.curator.x.rest.entities.StatusMessage;
 import org.codehaus.jackson.node.ObjectNode;
@@ -40,7 +38,7 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import java.io.IOException;
 
-@Path("/curator/v1/recipes/node-cache/{session-id}")
+@Path("/curator/v1/recipes/node-cache")
 public class NodeCacheResource
 {
     private final Logger log = LoggerFactory.getLogger(getClass());
@@ -54,10 +52,8 @@ public class NodeCacheResource
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
-    public Response newCache(@PathParam("session-id") String sessionId, final NodeCacheSpec spec) throws Exception
+    public Response newCache(final NodeCacheSpec spec) throws Exception
     {
-        Session session = Constants.getSession(context, sessionId);
-
         NodeCache cache = new NodeCache(context.getClient(), spec.getPath(), spec.isDataIsCompressed());
         cache.start(spec.isBuildInitial());
 
@@ -76,7 +72,7 @@ public class NodeCacheResource
                 }
             }
         };
-        final String id = session.addThing(cache, closer);
+        final String id = context.getSession().addThing(cache, closer);
 
         NodeCacheListener listener = new NodeCacheListener()
         {
@@ -94,10 +90,9 @@ public class NodeCacheResource
 
     @DELETE
     @Path("/{cache-id}")
-    public Response deleteCache(@PathParam("session-id") String sessionId, @PathParam("cache-id") String cacheId)
+    public Response deleteCache(@PathParam("cache-id") String cacheId)
     {
-        Session session = Constants.getSession(context, sessionId);
-        NodeCache cache = Constants.deleteThing(session, cacheId, NodeCache.class);
+        NodeCache cache = Constants.deleteThing(context.getSession(), cacheId, NodeCache.class);
         try
         {
             cache.close();
@@ -111,10 +106,9 @@ public class NodeCacheResource
 
     @GET
     @Path("/{cache-id}")
-    public Response getCacheData(@PathParam("session-id") String sessionId, @PathParam("cache-id") String cacheId) throws Exception
+    public Response getCacheData(@PathParam("cache-id") String cacheId) throws Exception
     {
-        Session session = Constants.getSession(context, sessionId);
-        NodeCache cache = Constants.getThing(session, cacheId, NodeCache.class);
+        NodeCache cache = Constants.getThing(context.getSession(), cacheId, NodeCache.class);
         return Response.ok(Constants.toNodeData(cache.getCurrentData())).build();
     }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/PathChildrenCacheResource.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/PathChildrenCacheResource.java b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/PathChildrenCacheResource.java
index 704782d..6245d56 100644
--- a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/PathChildrenCacheResource.java
+++ b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/PathChildrenCacheResource.java
@@ -25,8 +25,6 @@ import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
 import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
 import org.apache.curator.utils.ThreadUtils;
 import org.apache.curator.x.rest.CuratorRestContext;
-import org.apache.curator.x.rest.details.Closer;
-import org.apache.curator.x.rest.details.Session;
 import org.apache.curator.x.rest.entities.PathChildrenCacheSpec;
 import org.apache.curator.x.rest.entities.StatusMessage;
 import org.codehaus.jackson.node.ArrayNode;
@@ -45,7 +43,7 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import java.io.IOException;
 
-@Path("/curator/v1/recipes/path-cache/{session-id}")
+@Path("/curator/v1/recipes/path-cache")
 public class PathChildrenCacheResource
 {
     private final Logger log = LoggerFactory.getLogger(getClass());
@@ -59,10 +57,8 @@ public class PathChildrenCacheResource
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
-    public Response newCache(@PathParam("session-id") String sessionId, final PathChildrenCacheSpec spec) throws Exception
+    public Response newCache(final PathChildrenCacheSpec spec) throws Exception
     {
-        Session session = Constants.getSession(context, sessionId);
-
         PathChildrenCache cache = new PathChildrenCache(context.getClient(), spec.getPath(), spec.isCacheData(), spec.isDataIsCompressed(), ThreadUtils.newThreadFactory("PathChildrenCacheResource"));
         cache.start(spec.getStartMode());
 
@@ -81,7 +77,7 @@ public class PathChildrenCacheResource
                 }
             }
         };
-        final String id = session.addThing(cache, closer);
+        final String id = context.getSession().addThing(cache, closer);
 
         PathChildrenCacheListener listener = new PathChildrenCacheListener()
         {
@@ -99,10 +95,9 @@ public class PathChildrenCacheResource
 
     @DELETE
     @Path("/{cache-id}")
-    public Response deleteCache(@PathParam("session-id") String sessionId, @PathParam("cache-id") String cacheId)
+    public Response deleteCache(@PathParam("cache-id") String cacheId)
     {
-        Session session = Constants.getSession(context, sessionId);
-        PathChildrenCache cache = Constants.deleteThing(session, cacheId, PathChildrenCache.class);
+        PathChildrenCache cache = Constants.deleteThing(context.getSession(), cacheId, PathChildrenCache.class);
         try
         {
             cache.close();
@@ -116,10 +111,9 @@ public class PathChildrenCacheResource
 
     @GET
     @Path("/{cache-id}")
-    public Response getCacheData(@PathParam("session-id") String sessionId, @PathParam("cache-id") String cacheId) throws Exception
+    public Response getCacheData(@PathParam("cache-id") String cacheId) throws Exception
     {
-        Session session = Constants.getSession(context, sessionId);
-        PathChildrenCache cache = Constants.getThing(session, cacheId, PathChildrenCache.class);
+        PathChildrenCache cache = Constants.getThing(context.getSession(), cacheId, PathChildrenCache.class);
 
         ArrayNode data = context.getMapper().createArrayNode();
         for ( ChildData c : cache.getCurrentData() )
@@ -131,10 +125,9 @@ public class PathChildrenCacheResource
 
     @GET
     @Path("/{cache-id}/{path:.*}")
-    public Response getCacheDataForPath(@PathParam("session-id") String sessionId, @PathParam("cache-id") String cacheId, @PathParam("path") String path) throws Exception
+    public Response getCacheDataForPath(@PathParam("cache-id") String cacheId, @PathParam("path") String path) throws Exception
     {
-        Session session = Constants.getSession(context, sessionId);
-        PathChildrenCache cache = Constants.getThing(session, cacheId, PathChildrenCache.class);
+        PathChildrenCache cache = Constants.getThing(context.getSession(), cacheId, PathChildrenCache.class);
         ChildData currentData = cache.getCurrentData(path);
         if ( currentData == null )
         {

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/PersistentEphemeralNodeResource.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/PersistentEphemeralNodeResource.java b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/PersistentEphemeralNodeResource.java
index a272476..9a30e0a 100644
--- a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/PersistentEphemeralNodeResource.java
+++ b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/PersistentEphemeralNodeResource.java
@@ -20,8 +20,6 @@ package org.apache.curator.x.rest.api;
 
 import org.apache.curator.framework.recipes.nodes.PersistentEphemeralNode;
 import org.apache.curator.x.rest.CuratorRestContext;
-import org.apache.curator.x.rest.details.Closer;
-import org.apache.curator.x.rest.details.Session;
 import org.apache.curator.x.rest.entities.PersistentEphemeralNodeSpec;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -35,7 +33,7 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
-@Path("/curator/v1/recipes/persistent-ephemeral-node/{session-id}")
+@Path("/curator/v1/recipes/persistent-ephemeral-node")
 public class PersistentEphemeralNodeResource
 {
     private final Logger log = LoggerFactory.getLogger(getClass());
@@ -49,9 +47,8 @@ public class PersistentEphemeralNodeResource
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
-    public Response start(@PathParam("session-id") String sessionId, final PersistentEphemeralNodeSpec spec) throws Exception
+    public Response start(final PersistentEphemeralNodeSpec spec) throws Exception
     {
-        Session session = Constants.getSession(context, sessionId);
         PersistentEphemeralNode node = new PersistentEphemeralNode(context.getClient(), spec.getMode(), spec.getPath(), spec.getData().getBytes());
         node.start();
 
@@ -70,16 +67,15 @@ public class PersistentEphemeralNodeResource
                 }
             }
         };
-        String id = session.addThing(node, closer);
+        String id = context.getSession().addThing(node, closer);
         return Response.ok(context.getWriter().writeValueAsString(Constants.makeIdNode(context, id))).build();
     }
 
     @DELETE
     @Path("{node-id}")
-    public Response close(@PathParam("session-id") String sessionId, @PathParam("node-id") String nodeId) throws Exception
+    public Response close(@PathParam("node-id") String nodeId) throws Exception
     {
-        Session session = Constants.getSession(context, sessionId);
-        PersistentEphemeralNode node = Constants.deleteThing(session, nodeId, PersistentEphemeralNode.class);
+        PersistentEphemeralNode node = Constants.deleteThing(context.getSession(), nodeId, PersistentEphemeralNode.class);
         node.close();
         return Response.ok().build();
     }

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/ReadWriteLockResource.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/ReadWriteLockResource.java b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/ReadWriteLockResource.java
index 9bf9649..6ee70e7 100644
--- a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/ReadWriteLockResource.java
+++ b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/ReadWriteLockResource.java
@@ -21,8 +21,6 @@ package org.apache.curator.x.rest.api;
 import org.apache.curator.framework.recipes.locks.InterProcessMutex;
 import org.apache.curator.framework.recipes.locks.InterProcessReadWriteLock;
 import org.apache.curator.x.rest.CuratorRestContext;
-import org.apache.curator.x.rest.details.Closer;
-import org.apache.curator.x.rest.details.Session;
 import org.apache.curator.x.rest.entities.LockSpec;
 import org.codehaus.jackson.node.ObjectNode;
 import org.slf4j.Logger;
@@ -38,7 +36,7 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import java.util.concurrent.TimeUnit;
 
-@Path("/curator/v1/recipes/read-write-lock/{session-id}")
+@Path("/curator/v1/recipes/read-write-lock")
 public class ReadWriteLockResource
 {
     private final Logger log = LoggerFactory.getLogger(getClass());
@@ -53,23 +51,22 @@ public class ReadWriteLockResource
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
     @Path("/read")
-    public Response acquireReadLock(@PathParam("session-id") String sessionId, final LockSpec lockSpec) throws Exception
+    public Response acquireReadLock(final LockSpec lockSpec) throws Exception
     {
-        return internalLock(sessionId, lockSpec, false);
+        return internalLock(lockSpec, false);
     }
 
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
     @Path("/write")
-    public Response acquireWriteLock(@PathParam("session-id") String sessionId, final LockSpec lockSpec) throws Exception
+    public Response acquireWriteLock(final LockSpec lockSpec) throws Exception
     {
-        return internalLock(sessionId, lockSpec, true);
+        return internalLock(lockSpec, true);
     }
 
-    private Response internalLock(String sessionId, final LockSpec lockSpec, boolean writeLock) throws Exception
+    private Response internalLock(final LockSpec lockSpec, boolean writeLock) throws Exception
     {
-        Session session = Constants.getSession(context, sessionId);
         InterProcessReadWriteLock lock = new InterProcessReadWriteLock(context.getClient(), lockSpec.getPath());
         InterProcessMutex actualLock = writeLock ? lock.writeLock() : lock.readLock();
         if ( !actualLock.acquire(lockSpec.getMaxWaitMs(), TimeUnit.MILLISECONDS) )
@@ -95,17 +92,16 @@ public class ReadWriteLockResource
                 }
             }
         };
-        String id = session.addThing(actualLock, closer);
+        String id = context.getSession().addThing(actualLock, closer);
         ObjectNode node = Constants.makeIdNode(context, id);
         return Response.ok(context.getWriter().writeValueAsString(node)).build();
     }
 
     @DELETE
     @Path("{lock-id}")
-    public Response releaseLock(@PathParam("session-id") String sessionId, @PathParam("lock-id") String lockId) throws Exception
+    public Response releaseLock(@PathParam("lock-id") String lockId) throws Exception
     {
-        Session session = Constants.getSession(context, sessionId);
-        InterProcessMutex lock = Constants.deleteThing(session, lockId, InterProcessMutex.class);
+        InterProcessMutex lock = Constants.deleteThing(context.getSession(), lockId, InterProcessMutex.class);
         lock.release();
         return Response.ok().build();
     }

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/SemaphoreResource.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/SemaphoreResource.java b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/SemaphoreResource.java
index 779e628..2116866 100644
--- a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/SemaphoreResource.java
+++ b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/SemaphoreResource.java
@@ -22,8 +22,6 @@ import com.google.common.collect.Lists;
 import org.apache.curator.framework.recipes.locks.InterProcessSemaphoreV2;
 import org.apache.curator.framework.recipes.locks.Lease;
 import org.apache.curator.x.rest.CuratorRestContext;
-import org.apache.curator.x.rest.details.Closer;
-import org.apache.curator.x.rest.details.Session;
 import org.apache.curator.x.rest.entities.SemaphoreSpec;
 import org.codehaus.jackson.node.ObjectNode;
 import org.slf4j.Logger;
@@ -41,7 +39,7 @@ import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
-@Path("/curator/v1/recipes/semaphore/{session-id}")
+@Path("/curator/v1/recipes/semaphore")
 public class SemaphoreResource
 {
     private final Logger log = LoggerFactory.getLogger(getClass());
@@ -65,9 +63,8 @@ public class SemaphoreResource
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
-    public Response acquireSemaphore(@PathParam("session-id") String sessionId, final SemaphoreSpec semaphoreSpec) throws Exception
+    public Response acquireSemaphore(final SemaphoreSpec semaphoreSpec) throws Exception
     {
-        Session session = Constants.getSession(context, sessionId);
         final InterProcessSemaphoreV2 semaphore = new InterProcessSemaphoreV2(context.getClient(), semaphoreSpec.getPath(), semaphoreSpec.getMaxLeases());
         final Collection<Lease> leases = semaphore.acquire(semaphoreSpec.getAcquireQty(), semaphoreSpec.getMaxWaitMs(), TimeUnit.MILLISECONDS);
         if ( leases == null )
@@ -90,17 +87,16 @@ public class SemaphoreResource
                 }
             }
         };
-        String id = session.addThing(new LeasesHolder(leases), closer);
+        String id = context.getSession().addThing(new LeasesHolder(leases), closer);
         ObjectNode node = Constants.makeIdNode(context, id);
         return Response.ok(context.getWriter().writeValueAsString(node)).build();
     }
 
     @DELETE
     @Path("{lease-id}/{release-qty}")
-    public Response releaseSemaphore(@PathParam("session-id") String sessionId, @PathParam("lease-id") String leaseId, @PathParam("release-qty") int releaseQty) throws Exception
+    public Response releaseSemaphore(@PathParam("lease-id") String leaseId, @PathParam("release-qty") int releaseQty) throws Exception
     {
-        Session session = Constants.getSession(context, sessionId);
-        LeasesHolder holder = Constants.getThing(session, leaseId, LeasesHolder.class);
+        LeasesHolder holder = Constants.getThing(context.getSession(), leaseId, LeasesHolder.class);
         if ( holder.leases.size() < releaseQty )
         {
             return Response.status(Response.Status.NOT_FOUND).build();
@@ -113,7 +109,7 @@ public class SemaphoreResource
         }
         if ( holder.leases.size() == 0 )
         {
-            session.deleteThing(leaseId, LeasesHolder.class);
+            context.getSession().deleteThing(leaseId, LeasesHolder.class);
         }
 
         return Response.ok().build();

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/Session.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/Session.java b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/Session.java
new file mode 100644
index 0000000..8671383
--- /dev/null
+++ b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/Session.java
@@ -0,0 +1,103 @@
+/**
+ * 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.rest.api;
+
+import com.google.common.collect.Maps;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.io.Closeable;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class Session implements Closeable
+{
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private final Map<String, Entry> things = Maps.newConcurrentMap();
+    private final AtomicLong lastUseMs = new AtomicLong(System.currentTimeMillis());
+
+    private static class Entry
+    {
+        final Object thing;
+        final Closer closer;
+
+        private Entry(Object thing, Closer closer)
+        {
+            this.thing = thing;
+            this.closer = closer;
+        }
+    }
+
+    public void updateLastUse()
+    {
+        lastUseMs.set(System.currentTimeMillis());
+    }
+
+    public long getLastUseMs()
+    {
+        return lastUseMs.get();
+    }
+
+    @Override
+    public void close()
+    {
+        closeThings();
+    }
+
+    public void closeThings()
+    {
+        for ( Map.Entry<String, Entry> mapEntry : things.entrySet() )
+        {
+            Entry entry = mapEntry.getValue();
+            if ( entry.closer != null )
+            {
+                log.debug(String.format("Closing left over thing. Type: %s - Id: %s", entry.thing.getClass(), mapEntry.getKey()));
+                //noinspection unchecked
+                entry.closer.close(entry.thing);    // lack of generics is safe because addThing() is type-safe
+            }
+        }
+    }
+
+    <T> String addThing(T thing, Closer<T> closer)
+    {
+        String id = Constants.newId();
+        things.put(id, new Entry(thing, closer));
+        return id;
+    }
+
+    <T> T getThing(String id, Class<T> clazz)
+    {
+        Entry entry = things.get(id);
+        return cast(clazz, entry);
+    }
+
+    <T> T deleteThing(String id, Class<T> clazz)
+    {
+        Entry entry = things.remove(id);
+        return cast(clazz, entry);
+    }
+
+    private <T> T cast(Class<T> clazz, Entry entry)
+    {
+        if ( entry != null )
+        {
+            return clazz.cast(entry.thing);
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/SessionResource.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/SessionResource.java b/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/SessionResource.java
deleted file mode 100644
index bde36e9..0000000
--- a/curator-x-rest/src/main/java/org/apache/curator/x/rest/api/SessionResource.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.curator.x.rest.api;
-
-import org.apache.curator.x.rest.CuratorRestContext;
-import org.codehaus.jackson.node.ObjectNode;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-@Path("/curator/v1/session")
-public class SessionResource
-{
-    private final CuratorRestContext context;
-
-    public SessionResource(@Context CuratorRestContext context)
-    {
-        this.context = context;
-    }
-
-    @POST
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response newSession() throws Exception
-    {
-        String sessionId = context.getSessionManager().newSession();
-        ObjectNode node = Constants.makeIdNode(context, sessionId);
-        return Response.ok(context.getWriter().writeValueAsString(node)).build();
-    }
-
-    @DELETE
-    @Path("{id}")
-    public Response deleteSession(@PathParam("id") String id)
-    {
-        if ( !context.getSessionManager().deleteSession(id) )
-        {
-            return Response.status(Response.Status.NOT_FOUND).build();
-        }
-        return Response.ok().build();
-    }
-
-    @GET
-    @Path("{id}")
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response pingSession(@PathParam("id") String id) throws Exception
-    {
-        if ( !context.getSessionManager().pingSession(id) )
-        {
-            return Response.status(Response.Status.NOT_FOUND).build();
-        }
-
-        ObjectNode node = context.getMapper().createObjectNode();
-        node.put("state", context.getClient().getState().name());
-        node.putPOJO("messages", context.drainMessages());
-
-        return Response.ok(context.getWriter().writeValueAsString(node)).build();
-    }
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/curator-x-rest/src/main/java/org/apache/curator/x/rest/details/Closer.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/main/java/org/apache/curator/x/rest/details/Closer.java b/curator-x-rest/src/main/java/org/apache/curator/x/rest/details/Closer.java
deleted file mode 100644
index 7c349f4..0000000
--- a/curator-x-rest/src/main/java/org/apache/curator/x/rest/details/Closer.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.curator.x.rest.details;
-
-public interface Closer<T>
-{
-    public void close(T thing);
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/curator-x-rest/src/main/java/org/apache/curator/x/rest/details/Session.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/main/java/org/apache/curator/x/rest/details/Session.java b/curator-x-rest/src/main/java/org/apache/curator/x/rest/details/Session.java
deleted file mode 100644
index 612bf58..0000000
--- a/curator-x-rest/src/main/java/org/apache/curator/x/rest/details/Session.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.curator.x.rest.details;
-
-import com.google.common.collect.Maps;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import java.io.Closeable;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicLong;
-
-public class Session implements Closeable
-{
-    private final Logger log = LoggerFactory.getLogger(getClass());
-    private final Map<String, Entry> things = Maps.newConcurrentMap();
-    private final AtomicLong lastUseMs = new AtomicLong(System.currentTimeMillis());
-
-    private static class Entry
-    {
-        final Object thing;
-        final Closer closer;
-
-        private Entry(Object thing, Closer closer)
-        {
-            this.thing = thing;
-            this.closer = closer;
-        }
-    }
-
-    public void updateLastUse()
-    {
-        lastUseMs.set(System.currentTimeMillis());
-    }
-
-    public long getLastUseMs()
-    {
-        return lastUseMs.get();
-    }
-
-    @Override
-    public void close()
-    {
-        for ( Map.Entry<String, Entry> mapEntry : things.entrySet() )
-        {
-            Entry entry = mapEntry.getValue();
-            if ( entry.closer != null )
-            {
-                log.debug(String.format("Closing left over thing. Type: %s - Id: %s", entry.thing.getClass(), mapEntry.getKey()));
-                //noinspection unchecked
-                entry.closer.close(entry.thing);    // lack of generics is safe because addThing() is type-safe
-            }
-        }
-    }
-
-    public String addThing(Object thing)
-    {
-        return addThing(thing, null);
-    }
-
-    public <T> String addThing(T thing, Closer<T> closer)
-    {
-        String id = SessionManager.newId();
-        things.put(id, new Entry(thing, closer));
-        return id;
-    }
-
-    public <T> T getThing(String id, Class<T> clazz)
-    {
-        Entry entry = things.get(id);
-        return cast(clazz, entry);
-    }
-
-    public <T> T deleteThing(String id, Class<T> clazz)
-    {
-        Entry entry = things.remove(id);
-        return cast(clazz, entry);
-    }
-
-    private <T> T cast(Class<T> clazz, Entry entry)
-    {
-        if ( entry != null )
-        {
-            return clazz.cast(entry.thing);
-        }
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/curator-x-rest/src/main/java/org/apache/curator/x/rest/details/SessionManager.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/main/java/org/apache/curator/x/rest/details/SessionManager.java b/curator-x-rest/src/main/java/org/apache/curator/x/rest/details/SessionManager.java
deleted file mode 100644
index 2accdd9..0000000
--- a/curator-x-rest/src/main/java/org/apache/curator/x/rest/details/SessionManager.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.curator.x.rest.details;
-
-import com.google.common.collect.Maps;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import java.io.Closeable;
-import java.util.Collection;
-import java.util.Map;
-import java.util.UUID;
-
-public class SessionManager implements Closeable
-{
-    private final Logger log = LoggerFactory.getLogger(getClass());
-    private final Map<String, Session> sessions = Maps.newConcurrentMap();
-
-    public String newSession()
-    {
-        String id = newId();
-        sessions.put(id, new Session());
-        log.debug("Creating session. Id: " + id);
-        return id;
-    }
-
-    static String newId()
-    {
-        return UUID.randomUUID().toString();
-    }
-
-    @Override
-    public void close()
-    {
-        deleteAllSessions();
-    }
-
-    public void deleteAllSessions()
-    {
-        Collection<Session> localSessions = sessions.values();
-        sessions.clear();
-
-        for ( Session session : localSessions )
-        {
-            session.close();
-        }
-    }
-
-    public boolean deleteSession(String id)
-    {
-        Session session = sessions.remove(id);
-        if ( session != null )
-        {
-            log.debug("Deleting session. Id: " + id);
-            session.close();
-            return true;
-        }
-        return false;
-    }
-
-    public boolean pingSession(String id)
-    {
-        return getSession(id) != null;
-    }
-
-    public Session getSession(String id)
-    {
-        Session session = sessions.get(id);
-        if ( session != null )
-        {
-            log.debug("Pinging session. Id: " + id);
-            session.updateLastUse();
-        }
-        return session;
-    }
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/curator-x-rest/src/site/confluence/index.confluence
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/site/confluence/index.confluence b/curator-x-rest/src/site/confluence/index.confluence
new file mode 100644
index 0000000..5303b40
--- /dev/null
+++ b/curator-x-rest/src/site/confluence/index.confluence
@@ -0,0 +1,8 @@
+h1. Curator REST Proxy
+
+h2. Packaging
+Curator REST Proxy is in its own package in Maven Central: {{curator-x-rest}}
+
+h2. Description
+The Curator REST module implements a proxy that bridges non-java environments with the Curator framework and recipes. *TBD*
+

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/curator-x-rest/src/site/site.xml
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/site/site.xml b/curator-x-rest/src/site/site.xml
new file mode 100644
index 0000000..fe42cef
--- /dev/null
+++ b/curator-x-rest/src/site/site.xml
@@ -0,0 +1,31 @@
+<?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/DECORATION/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/DECORATION/1.1.0 http://maven.apache.org/xsd/decoration-1.1.0.xsd" name="Discovery Service Server">
+    <body>
+        <head>
+            <link rel="stylesheet" href="../css/site.css" />
+            <script type="text/javascript">
+                $(function(){
+                    $('a[title="Curator REST Proxy"]').parent().addClass("active");
+                });
+            </script>
+        </head>
+    </body>
+</project>

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/curator-x-rest/src/test/java/org/apache/curator/x/rest/dropwizard/DropwizardRunner.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/test/java/org/apache/curator/x/rest/dropwizard/DropwizardRunner.java b/curator-x-rest/src/test/java/org/apache/curator/x/rest/dropwizard/DropwizardRunner.java
index eb30590..44e2194 100644
--- a/curator-x-rest/src/test/java/org/apache/curator/x/rest/dropwizard/DropwizardRunner.java
+++ b/curator-x-rest/src/test/java/org/apache/curator/x/rest/dropwizard/DropwizardRunner.java
@@ -26,7 +26,6 @@ import io.dropwizard.setup.Environment;
 import org.apache.curator.framework.CuratorFramework;
 import org.apache.curator.framework.CuratorFrameworkFactory;
 import org.apache.curator.retry.ExponentialBackoffRetry;
-import org.apache.curator.x.rest.CuratorRestContext;
 
 public class DropwizardRunner
 {
@@ -39,7 +38,7 @@ public class DropwizardRunner
             {
                 CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", new ExponentialBackoffRetry(100, 3));
                 client.start();
-                bootstrap.addBundle(new CuratorRestBundle(new CuratorRestContext(client, 60000)));
+                bootstrap.addBundle(new CuratorRestBundle(client, 60000));
             }
 
             @Override

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index e600d42..6fa1d4e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -350,6 +350,7 @@
                 <artifactId>maven-javadoc-plugin</artifactId>
                 <version>2.9.1</version>
                 <configuration>
+                    <maxmemory>1024m</maxmemory>
                     <aggregate>true</aggregate>
                 </configuration>
             </plugin>
@@ -446,6 +447,7 @@
                 <artifactId>maven-javadoc-plugin</artifactId>
                 <version>2.9</version>
                 <configuration>
+                    <maxmemory>1024m</maxmemory>
                     <aggregate>true</aggregate>
                 </configuration>
             </plugin>

http://git-wip-us.apache.org/repos/asf/curator/blob/a3cdddc1/src/site/site.xml
----------------------------------------------------------------------
diff --git a/src/site/site.xml b/src/site/site.xml
index e393ece..627dfdc 100644
--- a/src/site/site.xml
+++ b/src/site/site.xml
@@ -91,6 +91,7 @@
         <menu name="Extensions" inherit="top">
             <item name="Service Discovery" href="curator-x-discovery/index.html"/>
             <item name="Service Discovery Server" href="curator-x-discovery-server/index.html"/>
+            <item name="Curator REST Proxy" href="curator-x-rest/index.html"/>
         </menu>
 
         <menu name="Community" inherit="top">