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/05 13:08:44 UTC
[1/3] git commit: more testing for rest proxy
Repository: curator
Updated Branches:
refs/heads/CURATOR-88 cf30ec2f6 -> 6477a2f08
more testing for rest proxy
Project: http://git-wip-us.apache.org/repos/asf/curator/repo
Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/a798ff82
Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/a798ff82
Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/a798ff82
Branch: refs/heads/CURATOR-88
Commit: a798ff82950bd8e00fa598387ce8d487f8fc8885
Parents: cf30ec2
Author: randgalt <ra...@apache.org>
Authored: Tue Mar 4 20:53:38 2014 +0530
Committer: randgalt <ra...@apache.org>
Committed: Tue Mar 4 20:53:38 2014 +0530
----------------------------------------------------------------------
curator-recipes/pom.xml | 1 -
.../locks/TestInterProcessMutexBase.java | 28 +++-
curator-x-rest/pom.xml | 1 +
.../curator/x/rest/api/LeaderResource.java | 5 +-
.../apache/curator/x/rest/api/LockResource.java | 5 +-
.../curator/x/rest/api/NodeCacheResource.java | 5 +-
.../x/rest/api/PathChildrenCacheResource.java | 5 +-
.../api/PersistentEphemeralNodeResource.java | 4 +-
.../x/rest/api/ReadWriteLockResource.java | 6 +-
.../curator/x/rest/api/SemaphoreResource.java | 6 +-
.../org/apache/curator/x/rest/entities/Id.java | 48 +++++++
.../src/site/confluence/apis.confluence | 16 +--
.../src/site/confluence/client.confluence | 2 +-
.../src/site/confluence/entities.confluence | 2 +-
.../apache/curator/x/rest/api/TestClient.java | 25 +---
.../apache/curator/x/rest/api/TestLocks.java | 143 +++++++++++++++++++
.../x/rest/support/BaseClassForTests.java | 80 +++++++----
.../x/rest/support/InterProcessLockBridge.java | 77 +++++++++-
.../apache/curator/x/rest/support/UriMaker.java | 65 +++++++++
.../src/test/resources/test-config.json | 13 ++
20 files changed, 453 insertions(+), 84 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/curator/blob/a798ff82/curator-recipes/pom.xml
----------------------------------------------------------------------
diff --git a/curator-recipes/pom.xml b/curator-recipes/pom.xml
index 56ac0c8..576661b 100644
--- a/curator-recipes/pom.xml
+++ b/curator-recipes/pom.xml
@@ -27,7 +27,6 @@
<version>2.4.1-SNAPSHOT</version>
</parent>
- <groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.4.1-SNAPSHOT</version>
<packaging>bundle</packaging>
http://git-wip-us.apache.org/repos/asf/curator/blob/a798ff82/curator-recipes/src/test/java/org/apache/curator/framework/recipes/locks/TestInterProcessMutexBase.java
----------------------------------------------------------------------
diff --git a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/locks/TestInterProcessMutexBase.java b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/locks/TestInterProcessMutexBase.java
index b1373fa..5101d06 100644
--- a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/locks/TestInterProcessMutexBase.java
+++ b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/locks/TestInterProcessMutexBase.java
@@ -20,17 +20,16 @@
package org.apache.curator.framework.recipes.locks;
import com.google.common.collect.Lists;
-import org.apache.curator.utils.CloseableUtils;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.BaseClassForTests;
import org.apache.curator.framework.state.ConnectionState;
import org.apache.curator.framework.state.ConnectionStateListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
-import org.apache.curator.retry.RetryOneTime;
import org.apache.curator.test.KillSession;
import org.apache.curator.test.TestingServer;
import org.apache.curator.test.Timing;
+import org.apache.curator.utils.CloseableUtils;
import org.testng.Assert;
import org.testng.annotations.Test;
import java.util.List;
@@ -395,9 +394,15 @@ public abstract class TestInterProcessMutexBase extends BaseClassForTests
{
try
{
- mutexForClient1.acquire(10, TimeUnit.SECONDS);
+ if ( !mutexForClient1.acquire(10, TimeUnit.SECONDS) )
+ {
+ throw new Exception("mutexForClient1.acquire timed out");
+ }
acquiredLatchForClient1.countDown();
- latchForClient1.await(10, TimeUnit.SECONDS);
+ if ( !latchForClient1.await(10, TimeUnit.SECONDS) )
+ {
+ throw new Exception("latchForClient1 timed out");
+ }
mutexForClient1.release();
}
catch ( Exception e )
@@ -417,9 +422,15 @@ public abstract class TestInterProcessMutexBase extends BaseClassForTests
{
try
{
- mutexForClient2.acquire(10, TimeUnit.SECONDS);
+ if ( !mutexForClient2.acquire(10, TimeUnit.SECONDS) )
+ {
+ throw new Exception("mutexForClient2.acquire timed out");
+ }
acquiredLatchForClient2.countDown();
- latchForClient2.await(10, TimeUnit.SECONDS);
+ if ( !latchForClient2.await(10, TimeUnit.SECONDS) )
+ {
+ throw new Exception("latchForClient2 timed out");
+ }
mutexForClient2.release();
}
catch ( Exception e )
@@ -434,6 +445,11 @@ public abstract class TestInterProcessMutexBase extends BaseClassForTests
while ( !mutexForClient1.isAcquiredInThisProcess() && !mutexForClient2.isAcquiredInThisProcess() )
{
Thread.sleep(1000);
+ Exception exception = exceptionRef.get();
+ if ( exception != null )
+ {
+ throw exception;
+ }
Assert.assertFalse(future1.isDone() && future2.isDone());
}
http://git-wip-us.apache.org/repos/asf/curator/blob/a798ff82/curator-x-rest/pom.xml
----------------------------------------------------------------------
diff --git a/curator-x-rest/pom.xml b/curator-x-rest/pom.xml
index affe441..ff53aea 100644
--- a/curator-x-rest/pom.xml
+++ b/curator-x-rest/pom.xml
@@ -37,6 +37,7 @@
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
+ <version>${project.parent.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
http://git-wip-us.apache.org/repos/asf/curator/blob/a798ff82/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 43316a1..0f07296 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
@@ -24,10 +24,10 @@ import org.apache.curator.framework.recipes.leader.LeaderLatch;
import org.apache.curator.framework.recipes.leader.LeaderLatchListener;
import org.apache.curator.framework.recipes.leader.Participant;
import org.apache.curator.x.rest.CuratorRestContext;
+import org.apache.curator.x.rest.entities.Id;
import org.apache.curator.x.rest.entities.LeaderSpec;
import org.apache.curator.x.rest.entities.ParticipantSpec;
import org.apache.curator.x.rest.entities.StatusMessage;
-import org.codehaus.jackson.node.ObjectNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
@@ -98,8 +98,7 @@ public class LeaderResource
};
leaderLatch.addListener(listener);
- ObjectNode node = Constants.makeIdNode(context, id);
- return Response.ok(context.getWriter().writeValueAsString(node)).build();
+ return Response.ok(new Id(id)).build();
}
@DELETE
http://git-wip-us.apache.org/repos/asf/curator/blob/a798ff82/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 8104858..dfb6ebc 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,8 @@ 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.entities.Id;
import org.apache.curator.x.rest.entities.LockSpec;
-import org.codehaus.jackson.node.ObjectNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.Consumes;
@@ -76,8 +76,7 @@ public class LockResource
}
};
String id = context.getSession().addThing(lock, closer);
- ObjectNode node = Constants.makeIdNode(context, id);
- return Response.ok(context.getWriter().writeValueAsString(node)).build();
+ return Response.ok(new Id(id)).build();
}
@DELETE
http://git-wip-us.apache.org/repos/asf/curator/blob/a798ff82/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 4548759..5d2e66e 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,9 +21,9 @@ 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.entities.Id;
import org.apache.curator.x.rest.entities.NodeCacheSpec;
import org.apache.curator.x.rest.entities.StatusMessage;
-import org.codehaus.jackson.node.ObjectNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.Consumes;
@@ -84,8 +84,7 @@ public class NodeCacheResource
};
cache.getListenable().addListener(listener);
- ObjectNode node = Constants.makeIdNode(context, id);
- return Response.ok(context.getWriter().writeValueAsString(node)).build();
+ return Response.ok(new Id(id)).build();
}
@DELETE
http://git-wip-us.apache.org/repos/asf/curator/blob/a798ff82/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 4622ac1..a694930 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,10 +25,10 @@ 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.entities.Id;
import org.apache.curator.x.rest.entities.PathChildrenCacheSpec;
import org.apache.curator.x.rest.entities.StatusMessage;
import org.codehaus.jackson.node.ArrayNode;
-import org.codehaus.jackson.node.ObjectNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.Consumes;
@@ -89,8 +89,7 @@ public class PathChildrenCacheResource
};
cache.getListenable().addListener(listener);
- ObjectNode node = Constants.makeIdNode(context, id);
- return Response.ok(context.getWriter().writeValueAsString(node)).build();
+ return Response.ok(new Id(id)).build();
}
@DELETE
http://git-wip-us.apache.org/repos/asf/curator/blob/a798ff82/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 85d2c3f..d55772e 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,13 +20,13 @@ 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.entities.Id;
import org.apache.curator.x.rest.entities.PersistentEphemeralNodeSpec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
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;
@@ -69,7 +69,7 @@ public class PersistentEphemeralNodeResource
}
};
String id = context.getSession().addThing(node, closer);
- return Response.ok(context.getWriter().writeValueAsString(Constants.makeIdNode(context, id))).build();
+ return Response.ok(new Id(id)).build();
}
@DELETE
http://git-wip-us.apache.org/repos/asf/curator/blob/a798ff82/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 fe5e319..b501d0e 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,14 +21,13 @@ 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.entities.Id;
import org.apache.curator.x.rest.entities.LockSpec;
-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.POST;
-import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@@ -103,7 +102,6 @@ public class ReadWriteLockResource
}
};
String id = context.getSession().addThing(actualLock, closer);
- ObjectNode node = Constants.makeIdNode(context, id);
- return Response.ok(context.getWriter().writeValueAsString(node)).build();
+ return Response.ok(new Id(id)).build();
}
}
http://git-wip-us.apache.org/repos/asf/curator/blob/a798ff82/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 41f6e2d..2b6438b 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,14 +22,13 @@ 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.entities.Id;
import org.apache.curator.x.rest.entities.SemaphoreSpec;
-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.POST;
-import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@@ -89,8 +88,7 @@ public class SemaphoreResource
}
};
String id = context.getSession().addThing(new LeasesHolder(leases), closer);
- ObjectNode node = Constants.makeIdNode(context, id);
- return Response.ok(context.getWriter().writeValueAsString(node)).build();
+ return Response.ok(new Id(id)).build();
}
@DELETE
http://git-wip-us.apache.org/repos/asf/curator/blob/a798ff82/curator-x-rest/src/main/java/org/apache/curator/x/rest/entities/Id.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/main/java/org/apache/curator/x/rest/entities/Id.java b/curator-x-rest/src/main/java/org/apache/curator/x/rest/entities/Id.java
new file mode 100644
index 0000000..1e7ca79
--- /dev/null
+++ b/curator-x-rest/src/main/java/org/apache/curator/x/rest/entities/Id.java
@@ -0,0 +1,48 @@
+/**
+ * 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.entities;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+public class Id
+{
+ private String id;
+
+ public Id()
+ {
+ this("");
+ }
+
+ public Id(String id)
+ {
+ this.id = id;
+ }
+
+ public String getId()
+ {
+ return id;
+ }
+
+ public void setId(String id)
+ {
+ this.id = id;
+ }
+}
http://git-wip-us.apache.org/repos/asf/curator/blob/a798ff82/curator-x-rest/src/site/confluence/apis.confluence
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/site/confluence/apis.confluence b/curator-x-rest/src/site/confluence/apis.confluence
index da6ac1a..74e880f 100644
--- a/curator-x-rest/src/site/confluence/apis.confluence
+++ b/curator-x-rest/src/site/confluence/apis.confluence
@@ -38,30 +38,30 @@ h2. Recipe APIs
||URL||Method||Request Entity||Response Entity||Description||
| *Leader* | | | | |
-|/curator/v1/recipes/leader|POST|LeaderSpec|IdSpec|Start a LeaderLatch instance. When you gain leadership, it will be notified via status.|
+|/curator/v1/recipes/leader|POST|LeaderSpec|Id|Start a LeaderLatch instance. When you gain leadership, it will be notified via status.|
|/curator/v1/recipes/leader/{leader-id}|DELETE|n/a|n/a|Release/delete leadership.|
|/curator/v1/recipes/leader/{leader-id}|GET|n/a|array of ParticipantSpecs|List of participants in the leader election.|
| *Lock* | | | | |
-|/curator/v1/recipes/lock|POST|LockSpec|IdSpec|An InterProcessSemaphoreMutex. On successful return, your client will be holding the specified lock until you delete the lock via the delete API.|
+|/curator/v1/recipes/lock|POST|LockSpec|Id|An InterProcessSemaphoreMutex. On successful return, your client will be holding the specified lock until you delete the lock via the delete API.|
|/curator/v1/recipes/lock/{lock-id}|DELETE|n/a|n/a|Release and delete a lock.|
| *Read/Write Lock* | | | | |
-|/curator/v1/recipes/read-write-lock/read|POST|LockSpec|IdSpec|An InterProcessReadWriteLock. On successful return, your client will be holding the specified read lock until you delete the lock via the delete API.|
-|/curator/v1/recipes/read-write-lock/write|POST|LockSpec|IdSpec|An InterProcessReadWriteLock. On successful return, your client will be holding the specified write lock until you delete the lock via the delete API.|
+|/curator/v1/recipes/read-write-lock/read|POST|LockSpec|Id|An InterProcessReadWriteLock. On successful return, your client will be holding the specified read lock until you delete the lock via the delete API.|
+|/curator/v1/recipes/read-write-lock/write|POST|LockSpec|Id|An InterProcessReadWriteLock. On successful return, your client will be holding the specified write lock until you delete the lock via the delete API.|
|/curator/v1/recipes/read-write-lock/{lock-id}|DELETE|n/a|n/a|Release and delete the read/write lock.|
| *Semaphore* | | | | |
-|/curator/v1/recipes/semaphore|POST|SemaphoreSpec|IdSpec|An InterProcessSemaphoreV2. On successful return, your client will be holding the specified number of leases until you delete them via the delete API.|
+|/curator/v1/recipes/semaphore|POST|SemaphoreSpec|Id|An InterProcessSemaphoreV2. On successful return, your client will be holding the specified number of leases until you delete them via the delete API.|
|/curator/v1/recipes/semaphore/{lock-id}/{release-qty}|DELETE|n/a|n/a|Release the specified number of leases.|
| *Node Cache* | | | | |
-|/curator/v1/recipes/node-cache|POST|NodeCacheSpec|IdSpec|Start a NodeCache instance. NodeCache updates will be notified via status.|
+|/curator/v1/recipes/node-cache|POST|NodeCacheSpec|Id|Start a NodeCache instance. NodeCache updates will be notified via status.|
|/curator/v1/recipes/node-cache/{cache-id}|GET|n/a|NodeData|Stop and delete a node cache.|
|/curator/v1/recipes/node-cache/{cache-id}|DELETE|n/a|n/a|Stop and delete a node cache.|
| *Path Cache* | | | | |
-|/curator/v1/recipes/path-cache|POST|PathChildrenCacheSpec|IdSpec|Start a PathChildrenCache instance. PathChildrenCache updates will be notified via status.|
+|/curator/v1/recipes/path-cache|POST|PathChildrenCacheSpec|Id|Start a PathChildrenCache instance. PathChildrenCache updates will be notified via status.|
|/curator/v1/recipes/path-cache/{cache-id}|GET|n/a|array of NodeData|Return the current cached values.|
|/curator/v1/recipes/path-cache/{cache-id}/{full-path}|GET|n/a|NodeData|Return the current cached value for the node at the specified full path.|
|/curator/v1/recipes/path-cache/{cache-id}|DELETE|n/a|n/a|Stop and delete a path cache.|
| *Persistent Ephemeral Node* | | | | |
-|/curator/v1/recipes/persistent-ephemeral-node|POST|PersistentEphemeralNodeSpec|IdSpec|Start a PersistentEphemeralNode instance.|
+|/curator/v1/recipes/persistent-ephemeral-node|POST|PersistentEphemeralNodeSpec|Id|Start a PersistentEphemeralNode instance.|
|/curator/v1/recipes/persistent-ephemeral-node/{node-id}|DELETE|n/a|n/a|Stop and delete a persistent ephemeral node.|
h2. Entities
http://git-wip-us.apache.org/repos/asf/curator/blob/a798ff82/curator-x-rest/src/site/confluence/client.confluence
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/site/confluence/client.confluence b/curator-x-rest/src/site/confluence/client.confluence
index c34502a..a4639e0 100644
--- a/curator-x-rest/src/site/confluence/client.confluence
+++ b/curator-x-rest/src/site/confluence/client.confluence
@@ -42,7 +42,7 @@ Here is pseudo-code for doing a distributed lock using the Curator REST Proxy:
{code}
Address address = ... # host and port of the Curator REST Proxy instance
LockSpec lock = {path: "/lock/path", maxWaitMs: 5000}
-IdSpec lockId = restClient.post(address, "/curator/v1/recipes/lock", lock)
+Id lockId = restClient.post(address, "/curator/v1/recipes/lock", lock)
statusMaintainer.add(address, lockId)
... do work here while in the acquired mutex ...
http://git-wip-us.apache.org/repos/asf/curator/blob/a798ff82/curator-x-rest/src/site/confluence/entities.confluence
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/site/confluence/entities.confluence b/curator-x-rest/src/site/confluence/entities.confluence
index b8f686b..4606919 100644
--- a/curator-x-rest/src/site/confluence/entities.confluence
+++ b/curator-x-rest/src/site/confluence/entities.confluence
@@ -73,7 +73,7 @@ Here are the entity descriptions for the entities used in the APIs:
|watched|boolean|if true, set a watch|
|watchId|string|if watched, a user-defined ID to return in the status when the watch triggers|
| | | |
-| *IdSpec* | | |
+| *Id* | | |
|id|string|The ID of the created recipe, etc. Used for subsequent calls to delete, close, etc. the instance.|
| | | |
| *LockSpec* | | |
http://git-wip-us.apache.org/repos/asf/curator/blob/a798ff82/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestClient.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestClient.java b/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestClient.java
index e6bb391..5cc8160 100644
--- a/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestClient.java
+++ b/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestClient.java
@@ -36,9 +36,6 @@ import org.apache.zookeeper.CreateMode;
import org.testng.Assert;
import org.testng.annotations.Test;
import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.UriBuilder;
-import java.net.InetSocketAddress;
-import java.net.URI;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
@@ -50,7 +47,7 @@ public class TestClient extends BaseClassForTests
boolean connected = false;
for ( int i = 0; i < 10; ++i )
{
- Status status = restClient.resource(getStatusUri()).get(Status.class);
+ Status status = restClient.resource(uriMaker.getStatusUri()).get(Status.class);
if ( status.getState().equals("connected") )
{
connected = true;
@@ -74,7 +71,7 @@ public class TestClient extends BaseClassForTests
createSpec.setPath(path);
createSpec.setCreatingParentsIfNeeded(true);
createSpec.setMode(CreateMode.EPHEMERAL);
- PathAndId pathAndId = restClient.resource(getMethodUri("create")).type(MediaType.APPLICATION_JSON).post(PathAndId.class, createSpec);
+ PathAndId pathAndId = restClient.resource(uriMaker.getMethodUri("create")).type(MediaType.APPLICATION_JSON).post(PathAndId.class, createSpec);
final AtomicReference<String> expiredId = new AtomicReference<String>();
StatusListener listener = new StatusListener()
@@ -103,7 +100,7 @@ public class TestClient extends BaseClassForTests
{
}
};
- sessionManager.addEntry(new InetSocketAddress("localhost", PORT), pathAndId.getId(), listener);
+ sessionManager.addEntry(uriMaker.getLocalhost(), pathAndId.getId(), listener);
Thread.sleep(2 * curatorConfiguration.getSessionLengthMs());
@@ -111,7 +108,7 @@ public class TestClient extends BaseClassForTests
client.start();
Assert.assertNotNull(client.checkExists().forPath(path));
- sessionManager.removeEntry(new InetSocketAddress("localhost", PORT), pathAndId.getId());
+ sessionManager.removeEntry(uriMaker.getLocalhost(), pathAndId.getId());
Thread.sleep(2 * curatorConfiguration.getSessionLengthMs());
Assert.assertNull(client.checkExists().forPath(path));
Assert.assertEquals(pathAndId.getId(), expiredId.get());
@@ -133,7 +130,7 @@ public class TestClient extends BaseClassForTests
existsSpec.setPath(path);
existsSpec.setWatched(true);
existsSpec.setWatchId(watchId);
- restClient.resource(getMethodUri("exists")).type(MediaType.APPLICATION_JSON).post(existsSpec);
+ restClient.resource(uriMaker.getMethodUri("exists")).type(MediaType.APPLICATION_JSON).post(existsSpec);
CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new RetryOneTime(1));
try
@@ -148,7 +145,7 @@ public class TestClient extends BaseClassForTests
new Timing().sleepABit();
- Status status = restClient.resource(getStatusUri()).get(Status.class);
+ Status status = restClient.resource(uriMaker.getStatusUri()).get(Status.class);
boolean foundWatch = false;
boolean foundWatchId = false;
boolean foundMessage = false;
@@ -173,14 +170,4 @@ public class TestClient extends BaseClassForTests
Assert.assertTrue(foundWatchId);
Assert.assertTrue(foundMessage);
}
-
- private URI getMethodUri(String method)
- {
- return UriBuilder.fromUri("http://localhost:" + PORT).path(ClientResource.class).path(ClientResource.class, method).build();
- }
-
- private URI getStatusUri()
- {
- return getMethodUri("getStatus");
- }
}
http://git-wip-us.apache.org/repos/asf/curator/blob/a798ff82/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestLocks.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestLocks.java b/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestLocks.java
new file mode 100644
index 0000000..4a7eaf0
--- /dev/null
+++ b/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestLocks.java
@@ -0,0 +1,143 @@
+/**
+ * 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.locks.InterProcessLock;
+import org.apache.curator.x.rest.support.BaseClassForTests;
+import org.apache.curator.x.rest.support.InterProcessLockBridge;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class TestLocks extends BaseClassForTests
+{
+ @Test
+ public void test2Clients() throws Exception
+ {
+ final InterProcessLock mutexForClient1 = new InterProcessLockBridge(restClient, sessionManager, uriMaker);
+ final InterProcessLock mutexForClient2 = new InterProcessLockBridge(restClient, sessionManager, uriMaker);
+
+ final CountDownLatch latchForClient1 = new CountDownLatch(1);
+ final CountDownLatch latchForClient2 = new CountDownLatch(1);
+ final CountDownLatch acquiredLatchForClient1 = new CountDownLatch(1);
+ final CountDownLatch acquiredLatchForClient2 = new CountDownLatch(1);
+
+ final AtomicReference<Exception> exceptionRef = new AtomicReference<Exception>();
+
+ ExecutorService service = Executors.newCachedThreadPool();
+ Future<Object> future1 = service.submit
+ (
+ new Callable<Object>()
+ {
+ @Override
+ public Object call() throws Exception
+ {
+ try
+ {
+ if ( !mutexForClient1.acquire(10, TimeUnit.SECONDS) )
+ {
+ throw new Exception("mutexForClient1.acquire timed out");
+ }
+ acquiredLatchForClient1.countDown();
+ if ( !latchForClient1.await(10, TimeUnit.SECONDS) )
+ {
+ throw new Exception("latchForClient1 timed out");
+ }
+ mutexForClient1.release();
+ }
+ catch ( Exception e )
+ {
+ exceptionRef.set(e);
+ }
+ return null;
+ }
+ }
+ );
+ Future<Object> future2 = service.submit
+ (
+ new Callable<Object>()
+ {
+ @Override
+ public Object call() throws Exception
+ {
+ try
+ {
+ if ( !mutexForClient2.acquire(10, TimeUnit.SECONDS) )
+ {
+ throw new Exception("mutexForClient2.acquire timed out");
+ }
+ acquiredLatchForClient2.countDown();
+ if ( !latchForClient2.await(10, TimeUnit.SECONDS) )
+ {
+ throw new Exception("latchForClient2 timed out");
+ }
+ mutexForClient2.release();
+ }
+ catch ( Exception e )
+ {
+ exceptionRef.set(e);
+ }
+ return null;
+ }
+ }
+ );
+
+ while ( !mutexForClient1.isAcquiredInThisProcess() && !mutexForClient2.isAcquiredInThisProcess() )
+ {
+ Thread.sleep(1000);
+ Exception exception = exceptionRef.get();
+ if ( exception != null )
+ {
+ throw exception;
+ }
+ Assert.assertFalse(future1.isDone() && future2.isDone());
+ }
+
+ Assert.assertTrue(mutexForClient1.isAcquiredInThisProcess() != mutexForClient2.isAcquiredInThisProcess());
+ Thread.sleep(1000);
+ Assert.assertTrue(mutexForClient1.isAcquiredInThisProcess() || mutexForClient2.isAcquiredInThisProcess());
+ Assert.assertTrue(mutexForClient1.isAcquiredInThisProcess() != mutexForClient2.isAcquiredInThisProcess());
+
+ Exception exception = exceptionRef.get();
+ if ( exception != null )
+ {
+ throw exception;
+ }
+
+ if ( mutexForClient1.isAcquiredInThisProcess() )
+ {
+ latchForClient1.countDown();
+ Assert.assertTrue(acquiredLatchForClient2.await(10, TimeUnit.SECONDS));
+ Assert.assertTrue(mutexForClient2.isAcquiredInThisProcess());
+ }
+ else
+ {
+ latchForClient2.countDown();
+ Assert.assertTrue(acquiredLatchForClient1.await(10, TimeUnit.SECONDS));
+ Assert.assertTrue(mutexForClient1.isAcquiredInThisProcess());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/curator/blob/a798ff82/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/BaseClassForTests.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/BaseClassForTests.java b/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/BaseClassForTests.java
index ea0a1a5..2690559 100644
--- a/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/BaseClassForTests.java
+++ b/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/BaseClassForTests.java
@@ -19,12 +19,15 @@
package org.apache.curator.x.rest.support;
+import ch.qos.logback.core.util.CloseUtil;
import com.google.common.io.CharStreams;
import com.google.common.io.Files;
+import com.google.common.io.Resources;
import com.sun.jersey.api.client.Client;
import io.dropwizard.Application;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
+import org.apache.curator.test.InstanceSpec;
import org.apache.curator.test.TestingServer;
import org.apache.curator.utils.DebugUtils;
import org.apache.curator.x.rest.dropwizard.CuratorApplication;
@@ -37,6 +40,7 @@ import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import java.io.File;
+import java.io.IOException;
import java.nio.charset.Charset;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
@@ -50,25 +54,60 @@ public class BaseClassForTests
protected Application<CuratorConfiguration> application;
protected Client restClient;
protected CuratorConfiguration curatorConfiguration;
-
- protected static final int PORT = 8080;
+ protected SessionManager sessionManager;
+ protected UriMaker uriMaker;
private File configFile;
@BeforeMethod
public void setup() throws Exception
{
+ setup(5000);
+ }
+
+ protected void setup(int sessionLengthMs) throws Exception
+ {
+ int port = InstanceSpec.getRandomPort();
restClient = Client.create();
System.setProperty(DebugUtils.PROPERTY_DONT_LOG_CONNECTION_ISSUES, "true");
server = new TestingServer();
- configFile = File.createTempFile("temp", ".tmp");
- CharStreams.write("{\"connection-string\": \"" + server.getConnectString() + "\", \"session-length-ms\":5000}", Files.newWriterSupplier(configFile, Charset.defaultCharset()));
+ configFile = makeConfigFile(server.getConnectString(), sessionLengthMs, port);
- final CountDownLatch startedLatch = new CountDownLatch(1);
final AtomicReference<CuratorConfiguration> curatorConfigurationAtomicReference = new AtomicReference<CuratorConfiguration>();
- application = new Application<CuratorConfiguration>()
+ makeAndStartApplication(curatorConfigurationAtomicReference, configFile);
+
+ curatorConfiguration = curatorConfigurationAtomicReference.get();
+ sessionManager = new SessionManager(restClient, curatorConfiguration.getSessionLengthMs());
+ uriMaker = new UriMaker(port);
+ }
+
+ @AfterMethod
+ public void teardown() throws Exception
+ {
+ if ( configFile != null )
+ {
+ //noinspection ResultOfMethodCallIgnored
+ configFile.delete();
+ }
+
+ CloseUtil.closeQuietly(sessionManager);
+
+ ShutdownThread.getInstance().run();
+
+ CloseUtil.closeQuietly(server);
+
+ if ( restClient != null )
+ {
+ restClient.destroy();
+ }
+ }
+
+ private Application<CuratorConfiguration> makeAndStartApplication(final AtomicReference<CuratorConfiguration> curatorConfigurationRef, final File configFile) throws InterruptedException
+ {
+ final CountDownLatch startedLatch = new CountDownLatch(1);
+ final Application<CuratorConfiguration> application = new Application<CuratorConfiguration>()
{
@Override
public void initialize(Bootstrap<CuratorConfiguration> bootstrap)
@@ -79,7 +118,7 @@ public class BaseClassForTests
@Override
public void run(CuratorConfiguration configuration, Environment environment) throws Exception
{
- curatorConfigurationAtomicReference.set(configuration);
+ curatorConfigurationRef.set(configuration);
LifeCycle.Listener listener = new AbstractLifeCycle.AbstractLifeCycleListener()
{
@Override
@@ -107,26 +146,17 @@ public class BaseClassForTests
);
Assert.assertTrue(startedLatch.await(5, TimeUnit.SECONDS));
-
- curatorConfiguration = curatorConfigurationAtomicReference.get();
+ return application;
}
- @AfterMethod
- public void teardown() throws Exception
+ private static File makeConfigFile(String connectString, int sessionLengthMs, int port) throws IOException
{
- if ( configFile != null )
- {
- //noinspection ResultOfMethodCallIgnored
- configFile.delete();
- }
-
- if ( restClient != null )
- {
- restClient.destroy();
- }
-
- ShutdownThread.getInstance().run();
-
- server.close();
+ String config = Resources.toString(Resources.getResource("test-config.json"), Charset.defaultCharset());
+ config = config.replace("$CONNECT$", connectString);
+ config = config.replace("$SESSION$", Integer.toString(sessionLengthMs));
+ config = config.replace("$PORT$", Integer.toString(port));
+ File configFile = File.createTempFile("temp", ".tmp");
+ CharStreams.write(config, Files.newWriterSupplier(configFile, Charset.defaultCharset()));
+ return configFile;
}
}
http://git-wip-us.apache.org/repos/asf/curator/blob/a798ff82/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/InterProcessLockBridge.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/InterProcessLockBridge.java b/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/InterProcessLockBridge.java
index 7fdd8b3..15a7a5c 100644
--- a/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/InterProcessLockBridge.java
+++ b/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/InterProcessLockBridge.java
@@ -19,6 +19,81 @@
package org.apache.curator.x.rest.support;
-public class InterProcessLockBridge
+import com.google.common.base.Preconditions;
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.UniformInterfaceException;
+import org.apache.curator.framework.recipes.locks.InterProcessLock;
+import org.apache.curator.x.rest.api.LockResource;
+import org.apache.curator.x.rest.entities.Id;
+import org.apache.curator.x.rest.entities.LockSpec;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.net.URI;
+import java.util.concurrent.TimeUnit;
+
+public class InterProcessLockBridge implements InterProcessLock
{
+ private final Client restClient;
+ private final SessionManager sessionManager;
+ private final UriMaker uriMaker;
+
+ private volatile String id = null;
+
+ private static final String PATH = "/lock";
+
+ public InterProcessLockBridge(Client restClient, SessionManager sessionManager, UriMaker uriMaker)
+ {
+ this.restClient = restClient;
+ this.sessionManager = sessionManager;
+ this.uriMaker = uriMaker;
+ }
+
+ @Override
+ public void acquire() throws Exception
+ {
+ acquire(Integer.MAX_VALUE, TimeUnit.MILLISECONDS);
+ }
+
+ @Override
+ public boolean acquire(long time, TimeUnit unit) throws Exception
+ {
+ Preconditions.checkArgument(id == null, "Lock already acquired");
+
+ URI uri = uriMaker.getMethodUri(LockResource.class, null);
+ LockSpec lockSpec = new LockSpec();
+ lockSpec.setPath(PATH);
+ lockSpec.setMaxWaitMs((int)unit.toMillis(time));
+ try
+ {
+ id = restClient.resource(uri).type(MediaType.APPLICATION_JSON_TYPE).post(Id.class, lockSpec).getId();
+ }
+ catch ( UniformInterfaceException e )
+ {
+ if ( e.getResponse().getStatus() == Response.Status.SERVICE_UNAVAILABLE.getStatusCode() )
+ {
+ return false;
+ }
+ throw e;
+ }
+ sessionManager.addEntry(uriMaker.getLocalhost(), id, null);
+ return true;
+ }
+
+ @Override
+ public void release() throws Exception
+ {
+ Preconditions.checkArgument(id != null, "Lock not acquired");
+
+ URI uri = uriMaker.getMethodUri(LockResource.class, null);
+ restClient.resource(uri).path(id).delete();
+
+ sessionManager.removeEntry(uriMaker.getLocalhost(), id);
+ id = null;
+ }
+
+ @Override
+ public boolean isAcquiredInThisProcess()
+ {
+ return (id != null);
+ }
}
http://git-wip-us.apache.org/repos/asf/curator/blob/a798ff82/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/UriMaker.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/UriMaker.java b/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/UriMaker.java
new file mode 100644
index 0000000..0466839
--- /dev/null
+++ b/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/UriMaker.java
@@ -0,0 +1,65 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.curator.x.rest.support;
+
+import org.apache.curator.x.rest.api.ClientResource;
+import javax.ws.rs.core.UriBuilder;
+import java.net.InetSocketAddress;
+import java.net.URI;
+
+public class UriMaker
+{
+ private final int port;
+
+ public UriMaker(int port)
+ {
+ this.port = port;
+ }
+
+ public InetSocketAddress getLocalhost()
+ {
+ return new InetSocketAddress("localhost", port);
+ }
+
+ public int getPort()
+ {
+ return port;
+ }
+
+ public URI getMethodUri(Class resource, String method)
+ {
+ UriBuilder builder = UriBuilder.fromUri("http://localhost:" + port).path(resource);
+ if ( method != null )
+ {
+ builder = builder.path(resource, method);
+ }
+ return builder.build();
+ }
+
+ public URI getMethodUri(String method)
+ {
+ return getMethodUri(ClientResource.class, method);
+ }
+
+ public URI getStatusUri()
+ {
+ return getMethodUri("getStatus");
+ }
+}
http://git-wip-us.apache.org/repos/asf/curator/blob/a798ff82/curator-x-rest/src/test/resources/test-config.json
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/test/resources/test-config.json b/curator-x-rest/src/test/resources/test-config.json
new file mode 100644
index 0000000..2269fe1
--- /dev/null
+++ b/curator-x-rest/src/test/resources/test-config.json
@@ -0,0 +1,13 @@
+{
+ "connection-string": "$CONNECT$",
+ "session-length-ms": $SESSION$,
+
+ "server": {
+ "applicationConnectors": [
+ {
+ "type": "http",
+ "port": $PORT$
+ }
+ ]
+ }
+}
\ No newline at end of file
[3/3] git commit: more tests copied from TestInterProcessMutexBase
Posted by ra...@apache.org.
more tests copied from TestInterProcessMutexBase
Project: http://git-wip-us.apache.org/repos/asf/curator/repo
Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/6477a2f0
Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/6477a2f0
Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/6477a2f0
Branch: refs/heads/CURATOR-88
Commit: 6477a2f08d9e88dd3d934d18051e1193e44a1274
Parents: 0dcba0f
Author: randgalt <ra...@apache.org>
Authored: Tue Mar 4 21:14:46 2014 +0530
Committer: randgalt <ra...@apache.org>
Committed: Tue Mar 4 21:14:46 2014 +0530
----------------------------------------------------------------------
.../apache/curator/x/rest/api/TestLocks.java | 58 ++++++++++++++++++++
1 file changed, 58 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/curator/blob/6477a2f0/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestLocks.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestLocks.java b/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestLocks.java
index 6625388..7aa4585 100644
--- a/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestLocks.java
+++ b/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestLocks.java
@@ -19,6 +19,7 @@
package org.apache.curator.x.rest.api;
+import com.google.common.collect.Lists;
import org.apache.curator.framework.recipes.locks.InterProcessLock;
import org.apache.curator.test.KillSession;
import org.apache.curator.test.TestingServer;
@@ -266,4 +267,61 @@ public class TestLocks extends BaseClassForTests
KillSession.kill(getCuratorRestContext().getClient().getZookeeperClient().getZooKeeper(), server.getConnectString());
Assert.assertTrue(timing.acquireSemaphore(semaphore, 1));
}
+
+ @Test
+ public void testThreading() throws Exception
+ {
+ final int THREAD_QTY = 10;
+
+ final AtomicBoolean hasLock = new AtomicBoolean(false);
+ final AtomicBoolean isFirst = new AtomicBoolean(true);
+ final Semaphore semaphore = new Semaphore(1);
+
+ List<Future<Object>> threads = Lists.newArrayList();
+ ExecutorService service = Executors.newCachedThreadPool();
+ for ( int i = 0; i < THREAD_QTY; ++i )
+ {
+ final InterProcessLock mutex = new InterProcessLockBridge(restClient, sessionManager, uriMaker);
+ Future<Object> t = service.submit
+ (
+ new Callable<Object>()
+ {
+ @Override
+ public Object call() throws Exception
+ {
+ semaphore.acquire();
+ mutex.acquire();
+ Assert.assertTrue(hasLock.compareAndSet(false, true));
+ try
+ {
+ if ( isFirst.compareAndSet(true, false) )
+ {
+ semaphore.release(THREAD_QTY - 1);
+ while ( semaphore.availablePermits() > 0 )
+ {
+ Thread.sleep(100);
+ }
+ }
+ else
+ {
+ Thread.sleep(100);
+ }
+ }
+ finally
+ {
+ mutex.release();
+ hasLock.set(false);
+ }
+ return null;
+ }
+ }
+ );
+ threads.add(t);
+ }
+
+ for ( Future<Object> t : threads )
+ {
+ t.get();
+ }
+ }
}
[2/3] git commit: more testing for rest proxy
Posted by ra...@apache.org.
more testing for rest proxy
Project: http://git-wip-us.apache.org/repos/asf/curator/repo
Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/0dcba0f4
Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/0dcba0f4
Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/0dcba0f4
Branch: refs/heads/CURATOR-88
Commit: 0dcba0f47bc439ce506037512ab835238c2f320d
Parents: a798ff8
Author: randgalt <ra...@apache.org>
Authored: Tue Mar 4 21:06:08 2014 +0530
Committer: randgalt <ra...@apache.org>
Committed: Tue Mar 4 21:06:08 2014 +0530
----------------------------------------------------------------------
.../x/rest/dropwizard/CuratorRestBundle.java | 14 ++-
.../apache/curator/x/rest/api/TestLocks.java | 126 +++++++++++++++++++
.../x/rest/support/BaseClassForTests.java | 16 ++-
.../curator/x/rest/support/SessionManager.java | 30 ++++-
4 files changed, 173 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/curator/blob/0dcba0f4/curator-x-rest/src/main/java/org/apache/curator/x/rest/dropwizard/CuratorRestBundle.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/main/java/org/apache/curator/x/rest/dropwizard/CuratorRestBundle.java b/curator-x-rest/src/main/java/org/apache/curator/x/rest/dropwizard/CuratorRestBundle.java
index 6ad93b3..80f3e23 100644
--- a/curator-x-rest/src/main/java/org/apache/curator/x/rest/dropwizard/CuratorRestBundle.java
+++ b/curator-x-rest/src/main/java/org/apache/curator/x/rest/dropwizard/CuratorRestBundle.java
@@ -19,6 +19,7 @@
package org.apache.curator.x.rest.dropwizard;
+import com.google.common.annotations.VisibleForTesting;
import com.sun.jersey.spi.inject.SingletonTypeInjectableProvider;
import io.dropwizard.ConfiguredBundle;
import io.dropwizard.setup.Bootstrap;
@@ -34,6 +35,13 @@ import javax.ws.rs.core.Context;
public class CuratorRestBundle implements ConfiguredBundle<CuratorConfiguration>
{
+ private volatile CuratorRestContext curatorRestContext;
+
+ public CuratorRestContext getCuratorRestContext()
+ {
+ return curatorRestContext;
+ }
+
@Override
public void initialize(Bootstrap<?> bootstrap)
{
@@ -43,15 +51,15 @@ public class CuratorRestBundle implements ConfiguredBundle<CuratorConfiguration>
@Override
public void run(CuratorConfiguration configuration, Environment environment) throws Exception
{
- final CuratorRestContext context = newCuratorRestContext(configuration);
- runFromContext(environment, context);
+ curatorRestContext = newCuratorRestContext(configuration);
+ runFromContext(environment, curatorRestContext);
LifeCycle.Listener listener = new AbstractLifeCycle.AbstractLifeCycleListener()
{
@Override
public void lifeCycleStopping(LifeCycle event)
{
- closeCuratorClient(context.getClient());
+ closeCuratorClient(curatorRestContext.getClient());
}
};
environment.lifecycle().addLifeCycleListener(listener);
http://git-wip-us.apache.org/repos/asf/curator/blob/0dcba0f4/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestLocks.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestLocks.java b/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestLocks.java
index 4a7eaf0..6625388 100644
--- a/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestLocks.java
+++ b/curator-x-rest/src/test/java/org/apache/curator/x/rest/api/TestLocks.java
@@ -20,16 +20,26 @@
package org.apache.curator.x.rest.api;
import org.apache.curator.framework.recipes.locks.InterProcessLock;
+import org.apache.curator.test.KillSession;
+import org.apache.curator.test.TestingServer;
+import org.apache.curator.test.Timing;
+import org.apache.curator.x.rest.entities.Status;
+import org.apache.curator.x.rest.entities.StatusMessage;
import org.apache.curator.x.rest.support.BaseClassForTests;
import org.apache.curator.x.rest.support.InterProcessLockBridge;
+import org.apache.curator.x.rest.support.StatusListener;
import org.testng.Assert;
import org.testng.annotations.Test;
+import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
+import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
public class TestLocks extends BaseClassForTests
@@ -140,4 +150,120 @@ public class TestLocks extends BaseClassForTests
Assert.assertTrue(mutexForClient1.isAcquiredInThisProcess());
}
}
+
+ @Test
+ public void testWaitingProcessKilledServer() throws Exception
+ {
+ final Timing timing = new Timing();
+ final CountDownLatch latch = new CountDownLatch(1);
+ StatusListener statusListener = new StatusListener()
+ {
+ @Override
+ public void statusUpdate(List<StatusMessage> messages)
+ {
+ // NOP
+ }
+
+ @Override
+ public void errorState(Status status)
+ {
+ if ( status.getState().equals("lost") )
+ {
+ latch.countDown();
+ }
+ }
+ };
+ sessionManager.setStatusListener(statusListener);
+
+ final AtomicBoolean isFirst = new AtomicBoolean(true);
+ ExecutorCompletionService<Object> service = new ExecutorCompletionService<Object>(Executors.newFixedThreadPool(2));
+ for ( int i = 0; i < 2; ++i )
+ {
+ service.submit
+ (
+ new Callable<Object>()
+ {
+ @Override
+ public Object call() throws Exception
+ {
+ InterProcessLock lock = new InterProcessLockBridge(restClient, sessionManager, uriMaker);
+ lock.acquire();
+ try
+ {
+ if ( isFirst.compareAndSet(true, false) )
+ {
+ timing.sleepABit();
+
+ server.stop();
+ Assert.assertTrue(timing.awaitLatch(latch));
+ server = new TestingServer(server.getPort(), server.getTempDirectory());
+ }
+ }
+ finally
+ {
+ try
+ {
+ lock.release();
+ }
+ catch ( Exception e )
+ {
+ // ignore
+ }
+ }
+ return null;
+ }
+ }
+ );
+ }
+
+ for ( int i = 0; i < 2; ++i )
+ {
+ service.take().get(timing.forWaiting().milliseconds(), TimeUnit.MILLISECONDS);
+ }
+ }
+
+ @Test
+ public void testKilledSession() throws Exception
+ {
+ final Timing timing = new Timing();
+
+ final InterProcessLock mutex1 = new InterProcessLockBridge(restClient, sessionManager, uriMaker);
+ final InterProcessLock mutex2 = new InterProcessLockBridge(restClient, sessionManager, uriMaker);
+
+ final Semaphore semaphore = new Semaphore(0);
+ ExecutorCompletionService<Object> service = new ExecutorCompletionService<Object>(Executors.newFixedThreadPool(2));
+ service.submit
+ (
+ new Callable<Object>()
+ {
+ @Override
+ public Object call() throws Exception
+ {
+ mutex1.acquire();
+ semaphore.release();
+ Thread.sleep(1000000);
+ return null;
+ }
+ }
+ );
+
+ service.submit
+ (
+ new Callable<Object>()
+ {
+ @Override
+ public Object call() throws Exception
+ {
+ mutex2.acquire();
+ semaphore.release();
+ Thread.sleep(1000000);
+ return null;
+ }
+ }
+ );
+
+ Assert.assertTrue(timing.acquireSemaphore(semaphore, 1));
+ KillSession.kill(getCuratorRestContext().getClient().getZookeeperClient().getZooKeeper(), server.getConnectString());
+ Assert.assertTrue(timing.acquireSemaphore(semaphore, 1));
+ }
}
http://git-wip-us.apache.org/repos/asf/curator/blob/0dcba0f4/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/BaseClassForTests.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/BaseClassForTests.java b/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/BaseClassForTests.java
index 2690559..53b8b36 100644
--- a/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/BaseClassForTests.java
+++ b/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/BaseClassForTests.java
@@ -30,6 +30,7 @@ import io.dropwizard.setup.Environment;
import org.apache.curator.test.InstanceSpec;
import org.apache.curator.test.TestingServer;
import org.apache.curator.utils.DebugUtils;
+import org.apache.curator.x.rest.CuratorRestContext;
import org.apache.curator.x.rest.dropwizard.CuratorApplication;
import org.apache.curator.x.rest.dropwizard.CuratorConfiguration;
import org.apache.curator.x.rest.dropwizard.CuratorRestBundle;
@@ -58,22 +59,20 @@ public class BaseClassForTests
protected UriMaker uriMaker;
private File configFile;
+ private CuratorRestBundle bundle;
@BeforeMethod
public void setup() throws Exception
{
- setup(5000);
- }
+ bundle = new CuratorRestBundle();
- protected void setup(int sessionLengthMs) throws Exception
- {
int port = InstanceSpec.getRandomPort();
restClient = Client.create();
System.setProperty(DebugUtils.PROPERTY_DONT_LOG_CONNECTION_ISSUES, "true");
server = new TestingServer();
- configFile = makeConfigFile(server.getConnectString(), sessionLengthMs, port);
+ configFile = makeConfigFile(server.getConnectString(), 5000, port);
final AtomicReference<CuratorConfiguration> curatorConfigurationAtomicReference = new AtomicReference<CuratorConfiguration>();
makeAndStartApplication(curatorConfigurationAtomicReference, configFile);
@@ -104,6 +103,11 @@ public class BaseClassForTests
}
}
+ protected CuratorRestContext getCuratorRestContext()
+ {
+ return bundle.getCuratorRestContext();
+ }
+
private Application<CuratorConfiguration> makeAndStartApplication(final AtomicReference<CuratorConfiguration> curatorConfigurationRef, final File configFile) throws InterruptedException
{
final CountDownLatch startedLatch = new CountDownLatch(1);
@@ -112,7 +116,7 @@ public class BaseClassForTests
@Override
public void initialize(Bootstrap<CuratorConfiguration> bootstrap)
{
- bootstrap.addBundle(new CuratorRestBundle());
+ bootstrap.addBundle(bundle);
}
@Override
http://git-wip-us.apache.org/repos/asf/curator/blob/0dcba0f4/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/SessionManager.java
----------------------------------------------------------------------
diff --git a/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/SessionManager.java b/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/SessionManager.java
index 69cfc76..140569e 100644
--- a/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/SessionManager.java
+++ b/curator-x-rest/src/test/java/org/apache/curator/x/rest/support/SessionManager.java
@@ -49,6 +49,8 @@ public class SessionManager implements Closeable
private final Future<?> task;
private final ConcurrentMap<InetSocketAddress, Entry> entries = Maps.newConcurrentMap();
+ private volatile StatusListener statusListener;
+
private static class Entry
{
private final StatusListener listener;
@@ -104,6 +106,12 @@ public class SessionManager implements Closeable
task.cancel(true);
}
+ public void setStatusListener(StatusListener statusListener)
+ {
+ Preconditions.checkState(this.statusListener == null, "statusListener already set");
+ this.statusListener = statusListener;
+ }
+
private void processEntries()
{
for ( Map.Entry<InetSocketAddress, Entry> mapEntry : entries.entrySet() )
@@ -122,14 +130,28 @@ public class SessionManager implements Closeable
if ( status.getState().equals("connected") )
{
List<StatusMessage> messages = status.getMessages();
- if ( (messages.size() > 0) && (entry.listener != null) )
+ if ( messages.size() > 0 )
{
- entry.listener.statusUpdate(status.getMessages());
+ if ( statusListener != null )
+ {
+ statusListener.statusUpdate(status.getMessages());
+ }
+ if ( entry.listener != null )
+ {
+ entry.listener.statusUpdate(status.getMessages());
+ }
}
}
- else if ( entry.listener != null )
+ else
{
- entry.listener.errorState(status);
+ if ( statusListener != null )
+ {
+ statusListener.errorState(status);
+ }
+ if ( entry.listener != null )
+ {
+ entry.listener.errorState(status);
+ }
}
}
}