You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@curator.apache.org by dr...@apache.org on 2017/05/02 20:06:30 UTC
[22/50] curator git commit: Added AsyncResult - still needs
documentation
Added AsyncResult - still needs documentation
Project: http://git-wip-us.apache.org/repos/asf/curator/repo
Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/649c4415
Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/649c4415
Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/649c4415
Branch: refs/heads/master
Commit: 649c441529040401e2f414fbaffd8c6122263e70
Parents: 2ef420c
Author: randgalt <ra...@apache.org>
Authored: Sat Jan 21 11:06:36 2017 -0500
Committer: randgalt <ra...@apache.org>
Committed: Sat Jan 21 11:06:36 2017 -0500
----------------------------------------------------------------------
.../org/apache/curator/x/async/AsyncResult.java | 118 +++++++++++++++
.../x/async/details/AsyncResultImpl.java | 142 +++++++++++++++++++
.../curator/x/async/TestBasicOperations.java | 40 +++++-
3 files changed, 299 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/curator/blob/649c4415/curator-x-async/src/main/java/org/apache/curator/x/async/AsyncResult.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/AsyncResult.java b/curator-x-async/src/main/java/org/apache/curator/x/async/AsyncResult.java
new file mode 100644
index 0000000..5c99480
--- /dev/null
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/AsyncResult.java
@@ -0,0 +1,118 @@
+/**
+ * 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.async;
+
+import org.apache.curator.x.async.details.AsyncResultImpl;
+import org.apache.zookeeper.KeeperException;
+import java.util.Optional;
+import java.util.concurrent.CompletionStage;
+
+/**
+ * <p>
+ * Utility that combines the value, the ZooKeeper result code and the exception in one object
+ * allowing you to not worry about exceptional completions. i.e. the {@link java.util.concurrent.CompletionStage}
+ * retured by {@link org.apache.curator.x.async.AsyncResult#of(AsyncStage)} always completes successfully with an
+ * {@link org.apache.curator.x.async.AsyncResult} object.
+ * </p>
+ *
+ * <p>
+ * All three possible results from a ZooKeeper method are encapsulated in this object. If the ZooKeeper
+ * method succeeds, the internal value will be set. If there was a standard ZooKeeper error code
+ * ({@link org.apache.zookeeper.KeeperException.Code#NODEEXISTS}, etc.), that code is set and the
+ * value is null. If there was a general exception, that exception is set, the value will be null
+ * and the code will be {@link org.apache.zookeeper.KeeperException.Code#SYSTEMERROR}.
+ * </p>
+ * @param <T> value type
+ */
+public interface AsyncResult<T>
+{
+ /**
+ * Return a new stage that wraps an async stage into a result-style completion stage. The returned
+ * CompletionStage will always complete successfully.
+ *
+ * @param stage the stage to wrap
+ * @param <T> value type
+ * @return completion stage that resolves to a result
+ */
+ static <T> CompletionStage<AsyncResult<T>> of(AsyncStage<T> stage)
+ {
+ return stage.handle((value, ex) -> {
+ if ( ex != null )
+ {
+ if ( ex instanceof KeeperException )
+ {
+ return new AsyncResultImpl<T>(((KeeperException)ex).code());
+ }
+ return new AsyncResultImpl<T>(ex);
+ }
+ return new AsyncResultImpl<T>(value);
+ });
+ }
+
+ /**
+ * Returns the raw result of the ZooKeeper method or <code>null</code>
+ *
+ * @return result or <code>null</code>
+ */
+ T getRawValue();
+
+ /**
+ * An optional wrapper around the ZooKeeper method result
+ *
+ * @return wrapped result
+ */
+ Optional<T> getValue();
+
+ /**
+ * Return the ZooKeeper result code. If the method was successful,
+ * {@link org.apache.zookeeper.KeeperException.Code#OK} is returned. If there was a general
+ * exception {@link org.apache.zookeeper.KeeperException.Code#SYSTEMERROR} is returned.
+ *
+ * @return result code
+ */
+ KeeperException.Code getCode();
+
+ /**
+ * Return any general exception or <code>null</code>
+ *
+ * @return exception or <code>null</code>
+ */
+ Throwable getRawException();
+
+ /**
+ * An optional wrapper around any general exception
+ *
+ * @return wrapped exception
+ */
+ Optional<Throwable> getException();
+
+ /**
+ * If there was a general exception (but <strong>not</strong> a {@link org.apache.zookeeper.KeeperException})
+ * a {@link java.lang.RuntimeException} is thrown that wraps the exception. Otherwise, the method returns
+ * without any action being performed.
+ */
+ void checkException();
+
+ /**
+ * If there was a general exception or a {@link org.apache.zookeeper.KeeperException}
+ * a {@link java.lang.RuntimeException} is thrown that wraps the exception. Otherwise, the method returns
+ * without any action being performed.
+ */
+ void checkError();
+}
http://git-wip-us.apache.org/repos/asf/curator/blob/649c4415/curator-x-async/src/main/java/org/apache/curator/x/async/details/AsyncResultImpl.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/details/AsyncResultImpl.java b/curator-x-async/src/main/java/org/apache/curator/x/async/details/AsyncResultImpl.java
new file mode 100644
index 0000000..c555b83
--- /dev/null
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/details/AsyncResultImpl.java
@@ -0,0 +1,142 @@
+/**
+ * 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.async.details;
+
+import org.apache.curator.x.async.AsyncResult;
+import org.apache.zookeeper.KeeperException;
+import java.util.Objects;
+import java.util.Optional;
+
+public class AsyncResultImpl<T> implements AsyncResult<T>
+{
+ private final T value;
+ private final KeeperException.Code code;
+ private final Throwable exception;
+
+ public AsyncResultImpl()
+ {
+ this(null, KeeperException.Code.OK, null);
+ }
+
+ public AsyncResultImpl(KeeperException.Code code)
+ {
+ this(null, code, null);
+ }
+
+ public AsyncResultImpl(T value)
+ {
+ this(value, KeeperException.Code.OK, null);
+ }
+
+ public AsyncResultImpl(Throwable exception)
+ {
+ this(null, KeeperException.Code.SYSTEMERROR, exception);
+ }
+
+ private AsyncResultImpl(T value, KeeperException.Code code, Throwable exception)
+ {
+ this.value = value;
+ this.exception = exception;
+ this.code = Objects.requireNonNull(code, "error cannot be null");
+ }
+
+ public T getRawValue()
+ {
+ return value;
+ }
+
+ public Optional<T> getValue()
+ {
+ return Optional.ofNullable(value);
+ }
+
+ public KeeperException.Code getCode()
+ {
+ return code;
+ }
+
+ public Throwable getRawException()
+ {
+ return exception;
+ }
+
+ public Optional<Throwable> getException()
+ {
+ return Optional.ofNullable(exception);
+ }
+
+ public void checkException()
+ {
+ if ( exception != null )
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ @Override
+ public void checkError()
+ {
+ checkException();
+ if ( code != KeeperException.Code.OK )
+ {
+ throw new RuntimeException(KeeperException.create(code));
+ }
+ }
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if ( this == o )
+ {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() )
+ {
+ return false;
+ }
+
+ AsyncResultImpl<?> that = (AsyncResultImpl<?>)o;
+
+ if ( value != null ? !value.equals(that.value) : that.value != null )
+ {
+ return false;
+ }
+ //noinspection SimplifiableIfStatement
+ if ( code != that.code )
+ {
+ return false;
+ }
+ return exception != null ? exception.equals(that.exception) : that.exception == null;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int result = value != null ? value.hashCode() : 0;
+ result = 31 * result + code.hashCode();
+ result = 31 * result + (exception != null ? exception.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "AsyncResult{" + "value=" + value + ", code=" + code + ", exception=" + exception + '}';
+ }
+}
http://git-wip-us.apache.org/repos/asf/curator/blob/649c4415/curator-x-async/src/test/java/org/apache/curator/x/async/TestBasicOperations.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/test/java/org/apache/curator/x/async/TestBasicOperations.java b/curator-x-async/src/test/java/org/apache/curator/x/async/TestBasicOperations.java
index 34c02aa..1c4f241 100644
--- a/curator-x-async/src/test/java/org/apache/curator/x/async/TestBasicOperations.java
+++ b/curator-x-async/src/test/java/org/apache/curator/x/async/TestBasicOperations.java
@@ -55,7 +55,7 @@ public class TestBasicOperations extends BaseClassForTests
{
super.setup();
- CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new RetryOneTime(timing.milliseconds()));
+ CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new RetryOneTime(timing.forSleepingABit().milliseconds()));
client.start();
this.client = AsyncCuratorFramework.wrap(client);
}
@@ -144,6 +144,44 @@ public class TestBasicOperations extends BaseClassForTests
Assert.assertTrue(timing.awaitLatch(latch));
}
+ @Test
+ public void testResultWrapper() throws Exception
+ {
+ CompletionStage<AsyncResult<String>> resultStage = AsyncResult.of(client.create().forPath("/first"));
+ complete(resultStage, (v, e) -> {
+ Assert.assertNull(e);
+ Assert.assertEquals(v.getRawValue(), "/first");
+ Assert.assertNull(v.getRawException());
+ Assert.assertEquals(v.getCode(), KeeperException.Code.OK);
+ });
+
+ resultStage = AsyncResult.of(client.create().forPath("/foo/bar"));
+ complete(resultStage, (v, e) -> {
+ Assert.assertNull(e);
+ Assert.assertNull(v.getRawValue());
+ Assert.assertNull(v.getRawException());
+ Assert.assertEquals(v.getCode(), KeeperException.Code.NONODE);
+ });
+
+ resultStage = AsyncResult.of(client.create().forPath("illegal path"));
+ complete(resultStage, (v, e) -> {
+ Assert.assertNull(e);
+ Assert.assertNull(v.getRawValue());
+ Assert.assertNotNull(v.getRawException());
+ Assert.assertTrue(v.getRawException() instanceof IllegalArgumentException);
+ Assert.assertEquals(v.getCode(), KeeperException.Code.SYSTEMERROR);
+ });
+
+ server.stop();
+ resultStage = AsyncResult.of(client.create().forPath("/second"));
+ complete(resultStage, (v, e) -> {
+ Assert.assertNull(e);
+ Assert.assertNull(v.getRawValue());
+ Assert.assertNull(v.getRawException());
+ Assert.assertEquals(v.getCode(), KeeperException.Code.CONNECTIONLOSS);
+ });
+ }
+
private <T, U> void complete(CompletionStage<T> stage)
{
complete(stage, (v, e) -> {});