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/10 02:17:52 UTC

git commit: NodeCache test

Repository: curator
Updated Branches:
  refs/heads/CURATOR-88 7e768f0bd -> 982251cc3


NodeCache test


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

Branch: refs/heads/CURATOR-88
Commit: 982251cc33b2d1846206742caef69ac24367a552
Parents: 7e768f0
Author: randgalt <ra...@apache.org>
Authored: Sun Mar 9 20:17:45 2014 -0500
Committer: randgalt <ra...@apache.org>
Committed: Sun Mar 9 20:17:45 2014 -0500

----------------------------------------------------------------------
 .../framework/recipes/cache/ChildData.java      |   4 +-
 .../curator/x/rest/api/ClientResource.java      |   3 +-
 .../curator/x/rest/api/NodeCacheResource.java   |   5 +-
 .../curator/x/rest/api/TestNodeCache.java       |  84 +++++++++++++
 .../curator/x/rest/support/NodeCacheBridge.java | 121 +++++++++++++++++++
 5 files changed, 211 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/982251cc/curator-recipes/src/main/java/org/apache/curator/framework/recipes/cache/ChildData.java
----------------------------------------------------------------------
diff --git a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/cache/ChildData.java b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/cache/ChildData.java
index 4b6fe83..4059532 100644
--- a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/cache/ChildData.java
+++ b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/cache/ChildData.java
@@ -28,7 +28,7 @@ public class ChildData implements Comparable<ChildData>
     private final Stat      stat;
     private final AtomicReference<byte[]>    data;
 
-    ChildData(String path, Stat stat, byte[] data)
+    public ChildData(String path, Stat stat, byte[] data)
     {
         this.path = path;
         this.stat = stat;
@@ -91,7 +91,7 @@ public class ChildData implements Comparable<ChildData>
     {
         int result = path != null ? path.hashCode() : 0;
         result = 31 * result + (stat != null ? stat.hashCode() : 0);
-        result = 31 * result + (data != null ? Arrays.hashCode(data.get()) : 0);
+        result = 31 * result + Arrays.hashCode(data.get());
         return result;
     }
 

http://git-wip-us.apache.org/repos/asf/curator/blob/982251cc/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 b490427..639d865 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
@@ -37,7 +37,6 @@ import org.codehaus.jackson.node.ObjectNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
@@ -122,7 +121,7 @@ public class ClientResource
         return Response.ok().build();
     }
 
-    @DELETE
+    @POST
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
     @Path("/delete")

http://git-wip-us.apache.org/repos/asf/curator/blob/982251cc/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 5d2e66e..53d111d 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
@@ -54,7 +54,7 @@ public class NodeCacheResource
     @Produces(MediaType.APPLICATION_JSON)
     public Response newCache(final NodeCacheSpec spec) throws Exception
     {
-        NodeCache cache = new NodeCache(context.getClient(), spec.getPath(), spec.isDataIsCompressed());
+        final NodeCache cache = new NodeCache(context.getClient(), spec.getPath(), spec.isDataIsCompressed());
         cache.start(spec.isBuildInitial());
 
         Closer<NodeCache> closer = new Closer<NodeCache>()
@@ -79,7 +79,8 @@ public class NodeCacheResource
             @Override
             public void nodeChanged() throws Exception
             {
-                context.getSession().pushMessage(new StatusMessage(Constants.NODE_CACHE, id, "", ""));
+                String data = (cache.getCurrentData() != null) ? new String(cache.getCurrentData().getData()) : "";
+                context.getSession().pushMessage(new StatusMessage(Constants.NODE_CACHE, id, data, ""));
             }
         };
         cache.getListenable().addListener(listener);

http://git-wip-us.apache.org/repos/asf/curator/blob/982251cc/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestNodeCache.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestNodeCache.java b/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestNodeCache.java
new file mode 100644
index 0000000..7982f18
--- /dev/null
+++ b/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestNodeCache.java
@@ -0,0 +1,84 @@
+/**
+ * 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.framework.recipes.cache.NodeCacheListener;
+import org.apache.curator.test.Timing;
+import org.apache.curator.x.rest.entities.CreateSpec;
+import org.apache.curator.x.rest.entities.DeleteSpec;
+import org.apache.curator.x.rest.entities.PathAndId;
+import org.apache.curator.x.rest.entities.SetDataSpec;
+import org.apache.curator.x.rest.support.BaseClassForTests;
+import org.apache.curator.x.rest.support.NodeCacheBridge;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+import javax.ws.rs.core.MediaType;
+import java.util.concurrent.Semaphore;
+
+public class TestNodeCache extends BaseClassForTests
+{
+    @Test
+    public void     testBasics() throws Exception
+    {
+        Timing timing = new Timing();
+
+        CreateSpec createSpec = new CreateSpec();
+
+        createSpec.setPath("/test");
+        restClient.resource(uriMaker.getMethodUri("create")).type(MediaType.APPLICATION_JSON).post(PathAndId.class, createSpec);
+
+        NodeCacheBridge cache = new NodeCacheBridge(restClient, sessionManager, uriMaker, "/test/node");
+        cache.start(true);
+
+        final Semaphore semaphore = new Semaphore(0);
+        cache.getListenable().addListener
+            (
+                new NodeCacheListener()
+                {
+                    @Override
+                    public void nodeChanged() throws Exception
+                    {
+                        semaphore.release();
+                    }
+                }
+            );
+
+        Assert.assertNull(cache.getCurrentData());
+
+        createSpec.setPath("/test/node");
+        createSpec.setData("a");
+        restClient.resource(uriMaker.getMethodUri("create")).type(MediaType.APPLICATION_JSON).post(PathAndId.class, createSpec);
+        Assert.assertTrue(timing.acquireSemaphore(semaphore));
+        Assert.assertEquals(cache.getCurrentData().getData(), "a".getBytes());
+
+        SetDataSpec setDataSpec = new SetDataSpec();
+        setDataSpec.setPath("/test/node");
+        setDataSpec.setData("b");
+        restClient.resource(uriMaker.getMethodUri("setData")).type(MediaType.APPLICATION_JSON).post(setDataSpec);
+        Assert.assertTrue(timing.acquireSemaphore(semaphore));
+        Assert.assertEquals(cache.getCurrentData().getData(), "b".getBytes());
+
+        DeleteSpec deleteSpec = new DeleteSpec();
+        deleteSpec.setPath("/test/node");
+        restClient.resource(uriMaker.getMethodUri("delete")).type(MediaType.APPLICATION_JSON).post(deleteSpec);
+        Assert.assertTrue(timing.acquireSemaphore(semaphore));
+        Assert.assertNull(cache.getCurrentData());
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/982251cc/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/NodeCacheBridge.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/NodeCacheBridge.java b/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/NodeCacheBridge.java
new file mode 100644
index 0000000..c88764d
--- /dev/null
+++ b/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/NodeCacheBridge.java
@@ -0,0 +1,121 @@
+/**
+ * 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.support;
+
+import com.google.common.base.Function;
+import com.sun.jersey.api.client.Client;
+import org.apache.curator.framework.listen.ListenerContainer;
+import org.apache.curator.framework.recipes.cache.ChildData;
+import org.apache.curator.framework.recipes.cache.NodeCacheListener;
+import org.apache.curator.x.rest.api.NodeCacheResource;
+import org.apache.curator.x.rest.entities.NodeCacheSpec;
+import org.apache.curator.x.rest.entities.PathAndId;
+import org.apache.curator.x.rest.entities.Status;
+import org.apache.curator.x.rest.entities.StatusMessage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import javax.annotation.Nullable;
+import javax.ws.rs.core.MediaType;
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class NodeCacheBridge implements Closeable, StatusListener
+{
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private final ListenerContainer<NodeCacheListener> listeners = new ListenerContainer<NodeCacheListener>();
+    private final AtomicReference<ChildData> data = new AtomicReference<ChildData>(null);
+    private final Client restClient;
+    private final SessionManager sessionManager;
+    private final UriMaker uriMaker;
+    private final String path;
+
+    private volatile String id;
+
+    public NodeCacheBridge(Client restClient, SessionManager sessionManager, UriMaker uriMaker, String path)
+    {
+        this.restClient = restClient;
+        this.sessionManager = sessionManager;
+        this.uriMaker = uriMaker;
+        this.path = path;
+    }
+
+    @Override
+    public void close() throws IOException
+    {
+        sessionManager.removeEntry(uriMaker.getLocalhost(), id);
+        restClient.resource(uriMaker.getMethodUri(NodeCacheResource.class, null)).path(id).delete();
+    }
+
+    public void start(boolean buildInitial)
+    {
+        NodeCacheSpec nodeCacheSpec = new NodeCacheSpec();
+        nodeCacheSpec.setPath(path);
+        nodeCacheSpec.setBuildInitial(buildInitial);
+        id = restClient.resource(uriMaker.getMethodUri(NodeCacheResource.class, null)).type(MediaType.APPLICATION_JSON).post(PathAndId.class, nodeCacheSpec).getId();
+        sessionManager.addEntry(uriMaker.getLocalhost(), id, this);
+    }
+
+    public ListenerContainer<NodeCacheListener> getListenable()
+    {
+        return listeners;
+    }
+
+    public ChildData getCurrentData()
+    {
+        return data.get();
+    }
+
+    @Override
+    public void statusUpdate(List<StatusMessage> messages)
+    {
+        for ( StatusMessage statusMessage : messages )
+        {
+            if ( statusMessage.getType().equals("node-cache") && statusMessage.getSourceId().equals(id) )
+            {
+                ChildData newData = (statusMessage.getMessage().length() > 0) ? new ChildData(path, null, statusMessage.getMessage().getBytes()) : null;
+                data.set(newData);
+                listeners.forEach(new Function<NodeCacheListener, Void>()
+                {
+                    @Nullable
+                    @Override
+                    public Void apply(NodeCacheListener listener)
+                    {
+                        try
+                        {
+                            listener.nodeChanged();
+                        }
+                        catch ( Exception e )
+                        {
+                            log.error("Calling listener", e);
+                        }
+                        return null;
+                    }
+                });
+            }
+        }
+    }
+
+    @Override
+    public void errorState(Status status)
+    {
+    }
+}