Repository: curator Updated Branches: refs/heads/CURATOR-397 792aef209 -> 7c8f3fb62
added more examples Project: http://git-wip-us.apache.org/repos/asf/curator/repo Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/7c8f3fb6 Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/7c8f3fb6 Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/7c8f3fb6 Branch: refs/heads/CURATOR-397 Commit: 7c8f3fb62f6c9c7042cf07e78df7c00427392278 Parents: 792aef2 Author: randgalt <[email protected]> Authored: Sun Apr 9 16:58:58 2017 -0500 Committer: randgalt <[email protected]> Committed: Sun Apr 9 16:58:58 2017 -0500 ---------------------------------------------------------------------- curator-examples/pom.xml | 22 ++++ .../src/main/java/async/AsyncExamples.java | 127 +++++++++++++++++++ .../main/java/modeled/ModeledCacheExamples.java | 57 +++++++++ .../java/modeled/ModeledCuratorExamples.java | 63 +++++++++ .../src/main/java/modeled/PersonModel.java | 106 ++++++++++++++++ pom.xml | 12 ++ 6 files changed, 387 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/curator/blob/7c8f3fb6/curator-examples/pom.xml ---------------------------------------------------------------------- diff --git a/curator-examples/pom.xml b/curator-examples/pom.xml index f612cc2..6d8be77 100644 --- a/curator-examples/pom.xml +++ b/curator-examples/pom.xml @@ -50,9 +50,31 @@ </dependency> <dependency> + <groupId>org.apache.curator</groupId> + <artifactId>curator-x-async</artifactId> + </dependency> + + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </dependency> + + <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <scope>test</scope> </dependency> </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + </plugins> + </build> </project> http://git-wip-us.apache.org/repos/asf/curator/blob/7c8f3fb6/curator-examples/src/main/java/async/AsyncExamples.java ---------------------------------------------------------------------- diff --git a/curator-examples/src/main/java/async/AsyncExamples.java b/curator-examples/src/main/java/async/AsyncExamples.java new file mode 100644 index 0000000..43db219 --- /dev/null +++ b/curator-examples/src/main/java/async/AsyncExamples.java @@ -0,0 +1,127 @@ +/** + * 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 async; + +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.x.async.AsyncCuratorFramework; +import org.apache.curator.x.async.AsyncEventException; +import org.apache.curator.x.async.WatchMode; +import org.apache.zookeeper.WatchedEvent; +import java.util.concurrent.CompletionStage; + +/** + * Examples using the asynchronous DSL + */ +public class AsyncExamples +{ + public static AsyncCuratorFramework wrap(CuratorFramework client) + { + // wrap a CuratorFramework instance so that it can be used async. + // do this once and re-use the returned AsyncCuratorFramework instance + return AsyncCuratorFramework.wrap(client); + } + + public static void create(CuratorFramework client, String path, byte[] payload) + { + AsyncCuratorFramework async = AsyncCuratorFramework.wrap(client); // normally you'd wrap early in your app and reuse the instance + + // create a node at the given path with the given payload asynchronously + async.create().forPath(path, payload).whenComplete((name, exception) -> { + if ( exception != null ) + { + // there was a problem + exception.printStackTrace(); + } + else + { + System.out.println("Created node name is: " + name); + } + }); + } + + public static void createThenWatch(CuratorFramework client, String path) + { + AsyncCuratorFramework async = AsyncCuratorFramework.wrap(client); // normally you'd wrap early in your app and reuse the instance + + // this example shows to asynchronously use watchers for both event + // triggering and connection problems. If you don't need to be notified + // of connection problems, use the simpler approach shown in createThenWatchSimple() + + // create a node at the given path with the given payload asynchronously + // then watch the created node + async.create().forPath(path).whenComplete((name, exception) -> { + if ( exception != null ) + { + // there was a problem creating the node + exception.printStackTrace(); + } + else + { + handleWatchedStage(async.watched().checkExists().forPath(path).event()); + } + }); + } + + public static void createThenWatchSimple(CuratorFramework client, String path) + { + AsyncCuratorFramework async = AsyncCuratorFramework.wrap(client); // normally you'd wrap early in your app and reuse the instance + + // create a node at the given path with the given payload asynchronously + // then watch the created node + async.create().forPath(path).whenComplete((name, exception) -> { + if ( exception != null ) + { + // there was a problem creating the node + exception.printStackTrace(); + } + else + { + // because "WatchMode.successOnly" is used the watch stage is only triggered when + // the EventType is a node event + async.with(WatchMode.successOnly).watched().checkExists().forPath(path).event().thenAccept(event -> { + System.out.println(event.getType()); + System.out.println(event); + }); + } + }); + } + + private static void handleWatchedStage(CompletionStage<WatchedEvent> watchedStage) + { + // async handling of Watchers is complicated because watchers can trigger multiple times + // and CompletionStage don't support this behavior + + // thenAccept() handles normal watcher triggering. + watchedStage.thenAccept(event -> { + System.out.println(event.getType()); + System.out.println(event); + // etc. + }); + + // exceptionally is called if there is a connection problem in which case + // watchers trigger to signal the connection problem. "reset()" must be called + // to reset the watched stage + watchedStage.exceptionally(exception -> { + AsyncEventException asyncEx = (AsyncEventException)exception; + asyncEx.printStackTrace(); // handle the error as needed + handleWatchedStage(asyncEx.reset()); + return null; + }); + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/7c8f3fb6/curator-examples/src/main/java/modeled/ModeledCacheExamples.java ---------------------------------------------------------------------- diff --git a/curator-examples/src/main/java/modeled/ModeledCacheExamples.java b/curator-examples/src/main/java/modeled/ModeledCacheExamples.java new file mode 100644 index 0000000..3157f7e --- /dev/null +++ b/curator-examples/src/main/java/modeled/ModeledCacheExamples.java @@ -0,0 +1,57 @@ +/** + * 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 modeled; + +import org.apache.curator.framework.recipes.cache.TreeCache; +import org.apache.curator.x.async.modeled.JacksonModelSerializer; +import org.apache.curator.x.async.modeled.recipes.ModeledCacheEventType; +import org.apache.curator.x.async.modeled.recipes.ModeledCacheListener; +import org.apache.curator.x.async.modeled.recipes.ModeledTreeCache; +import java.util.function.Consumer; + +public class ModeledCacheExamples +{ + public static ModeledTreeCache<PersonModel> wrap(TreeCache cache) + { + JacksonModelSerializer<PersonModel> serializer = JacksonModelSerializer.build(PersonModel.class); + + // wrap a TreeCache instance so that it can be used "modeled". + return ModeledTreeCache.wrap(cache, serializer); + } + + public static void watchForChanges(TreeCache cache, Consumer<PersonModel> deletePersonReceiver, Consumer<PersonModel> updatedPersonReceiver) + { + ModeledTreeCache<PersonModel> modeledCache = wrap(cache); + ModeledCacheListener<PersonModel> listener = event -> { + PersonModel person = event.getNode().getModel(); + if ( event.getType() == ModeledCacheEventType.NODE_REMOVED ) + { + deletePersonReceiver.accept(person); + } + else + { + updatedPersonReceiver.accept(person); + } + }; + + // take a standard listener and filter so that only events that have a valid model instance are sent to the listener + ModeledCacheListener<PersonModel> filteredListener = ModeledCacheListener.filtered(listener, ModeledCacheListener.hasModelFilter()); + modeledCache.getListenable().addListener(filteredListener); + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/7c8f3fb6/curator-examples/src/main/java/modeled/ModeledCuratorExamples.java ---------------------------------------------------------------------- diff --git a/curator-examples/src/main/java/modeled/ModeledCuratorExamples.java b/curator-examples/src/main/java/modeled/ModeledCuratorExamples.java new file mode 100644 index 0000000..81eead8 --- /dev/null +++ b/curator-examples/src/main/java/modeled/ModeledCuratorExamples.java @@ -0,0 +1,63 @@ +/** + * 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 modeled; + +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.x.async.modeled.JacksonModelSerializer; +import org.apache.curator.x.async.modeled.ModeledCuratorFramework; +import org.apache.curator.x.async.modeled.ZPath; +import java.util.function.Consumer; + +public class ModeledCuratorExamples +{ + public static ModeledCuratorFramework<PersonModel> wrap(CuratorFramework client) + { + JacksonModelSerializer<PersonModel> serializer = JacksonModelSerializer.build(PersonModel.class); + + // wrap a CuratorFramework instance so that it can be used "modeled". + // do this once and re-use the returned ModeledCuratorFramework instance. + // ModeledCuratorFramework instances are tied to a given path + return ModeledCuratorFramework.wrap(client, ZPath.parse("/example/path"), serializer); + } + + public static void createOrUpdate(ModeledCuratorFramework<PersonModel> modeled, PersonModel model) + { + // change the affected path to be modeled's base path plus id: i.e. "/example/path/{id}" + ModeledCuratorFramework<PersonModel> atId = modeled.at(model.getId()); + + // by default ModeledCuratorFramework instances update the node if it already exists + // so this will either create or update the node + atId.create(model); // note - this is async + } + + public static void readPerson(ModeledCuratorFramework<PersonModel> modeled, String id, Consumer<PersonModel> receiver) + { + // read the person with the given ID and asynchronously call the receiver after it is read + modeled.at(id).read().whenComplete((person, exception) -> { + if ( exception != null ) + { + exception.printStackTrace(); // handle the error + } + else + { + receiver.accept(person); + } + }); + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/7c8f3fb6/curator-examples/src/main/java/modeled/PersonModel.java ---------------------------------------------------------------------- diff --git a/curator-examples/src/main/java/modeled/PersonModel.java b/curator-examples/src/main/java/modeled/PersonModel.java new file mode 100644 index 0000000..7bb5a44 --- /dev/null +++ b/curator-examples/src/main/java/modeled/PersonModel.java @@ -0,0 +1,106 @@ +/** + * 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 modeled; + +public class PersonModel +{ + private final String id; + private final String firstName; + private final String lastName; + private final int age; + + public PersonModel() + { + this(null, null, null, 0); + } + + public PersonModel(String id, String firstName, String lastName, int age) + { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + this.age = age; + } + + public String getId() + { + return id; + } + + public String getFirstName() + { + return firstName; + } + + public String getLastName() + { + return lastName; + } + + public int getAge() + { + return age; + } + + @Override + public boolean equals(Object o) + { + if ( this == o ) + { + return true; + } + if ( o == null || getClass() != o.getClass() ) + { + return false; + } + + PersonModel that = (PersonModel)o; + + if ( age != that.age ) + { + return false; + } + if ( id != null ? !id.equals(that.id) : that.id != null ) + { + return false; + } + //noinspection SimplifiableIfStatement + if ( firstName != null ? !firstName.equals(that.firstName) : that.firstName != null ) + { + return false; + } + return lastName != null ? lastName.equals(that.lastName) : that.lastName == null; + } + + @Override + public int hashCode() + { + int result = id != null ? id.hashCode() : 0; + result = 31 * result + (firstName != null ? firstName.hashCode() : 0); + result = 31 * result + (lastName != null ? lastName.hashCode() : 0); + result = 31 * result + age; + return result; + } + + @Override + public String toString() + { + return "PersonModel{" + "id='" + id + '\'' + ", firstName='" + firstName + '\'' + ", lastName='" + lastName + '\'' + ", age=" + age + '}'; + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/7c8f3fb6/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 1f66800..c5e791d 100644 --- a/pom.xml +++ b/pom.xml @@ -364,6 +364,18 @@ </dependency> <dependency> + <groupId>org.apache.curator</groupId> + <artifactId>curator-x-async</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.curator</groupId> + <artifactId>curator-x-rpc</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-math</artifactId> <version>${commons-math-version}</version>
