Repository: curator Updated Branches: refs/heads/CURATOR-397 0f0db1c38 -> 4efc38f3d
wip on wrapping caches Project: http://git-wip-us.apache.org/repos/asf/curator/repo Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/4efc38f3 Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/4efc38f3 Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/4efc38f3 Branch: refs/heads/CURATOR-397 Commit: 4efc38f3d16d111c3a96c4eb28212b2cc8a08188 Parents: 0f0db1c Author: randgalt <randg...@apache.org> Authored: Sat Apr 8 21:36:07 2017 -0500 Committer: randgalt <randg...@apache.org> Committed: Sat Apr 8 21:36:07 2017 -0500 ---------------------------------------------------------------------- .../recipes/cache/PathChildrenCache.java | 2 +- curator-x-async/pom.xml | 6 + .../x/async/modeled/JacksonModelSerializer.java | 2 +- .../modeled/ModeledAsyncCuratorFramework.java | 7 +- .../curator/x/async/modeled/ModeledDetails.java | 46 ++++ .../apache/curator/x/async/modeled/ZPath.java | 18 ++ .../ModeledAsyncCuratorFrameworkImpl.java | 28 ++- .../x/async/modeled/details/ZPathImpl.java | 18 ++ .../details/recipes/ModeledNodeCacheImpl.java | 117 ++++++++++ .../recipes/ModeledPathChildrenCacheImpl.java | 233 +++++++++++++++++++ .../modeled/recipes/ModeledCachedNode.java | 104 +++++++++ .../async/modeled/recipes/ModeledNodeCache.java | 47 ++++ .../recipes/ModeledPathChildrenCache.java | 82 +++++++ .../recipes/ModeledPathChildrenCacheEvent.java | 28 +++ .../ModeledPathChildrenCacheListener.java | 24 ++ .../curator/x/async/modeled/TestZPath.java | 18 ++ 16 files changed, 775 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/curator/blob/4efc38f3/curator-recipes/src/main/java/org/apache/curator/framework/recipes/cache/PathChildrenCache.java ---------------------------------------------------------------------- diff --git a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/cache/PathChildrenCache.java b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/cache/PathChildrenCache.java index d11ced6..c5449f2 100644 --- a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/cache/PathChildrenCache.java +++ b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/cache/PathChildrenCache.java @@ -133,7 +133,7 @@ public class PathChildrenCache implements Closeable handleStateChange(newState); } }; - private static final ThreadFactory defaultThreadFactory = ThreadUtils.newThreadFactory("PathChildrenCache"); + public static final ThreadFactory defaultThreadFactory = ThreadUtils.newThreadFactory("PathChildrenCache"); /** * @param client the client http://git-wip-us.apache.org/repos/asf/curator/blob/4efc38f3/curator-x-async/pom.xml ---------------------------------------------------------------------- diff --git a/curator-x-async/pom.xml b/curator-x-async/pom.xml index fa73942..4d645db 100644 --- a/curator-x-async/pom.xml +++ b/curator-x-async/pom.xml @@ -20,6 +20,12 @@ </dependency> <dependency> + <groupId>org.apache.curator</groupId> + <artifactId>curator-recipes</artifactId> + <scope>provided</scope> + </dependency> + + <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <scope>provided</scope> http://git-wip-us.apache.org/repos/asf/curator/blob/4efc38f3/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/JacksonModelSerializer.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/JacksonModelSerializer.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/JacksonModelSerializer.java index 90b120a..429fea7 100644 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/JacksonModelSerializer.java +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/JacksonModelSerializer.java @@ -32,7 +32,7 @@ import java.util.Arrays; * Model serializer that uses Jackson for JSON serialization. <strong>IMPORTANT: </strong> * the jackson dependency is specified as <code>provided</code> in the curator-x-async Maven POM * file to avoid adding a new dependency to Curator. Therefore, if you wish to use the - * JacksonModelSerializer you must manually add the dependency to your build system. + * JacksonModelSerializer you must manually add the dependency to your build syste */ public class JacksonModelSerializer<T> implements ModelSerializer<T> { http://git-wip-us.apache.org/repos/asf/curator/blob/4efc38f3/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModeledAsyncCuratorFramework.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModeledAsyncCuratorFramework.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModeledAsyncCuratorFramework.java index 17c6c8e..d13de24 100644 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModeledAsyncCuratorFramework.java +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModeledAsyncCuratorFramework.java @@ -24,11 +24,12 @@ import org.apache.curator.x.async.AsyncStage; import org.apache.curator.x.async.api.CreateOption; import org.apache.curator.x.async.api.DeleteOption; import org.apache.zookeeper.data.Stat; +import java.util.Set; public interface ModeledAsyncCuratorFramework<T> { - ImmutableSet<CreateOption> defaultCreateOptions = ImmutableSet.of(CreateOption.createParentsAsContainers, CreateOption.setDataIfExists); - ImmutableSet<DeleteOption> defaultDeleteOptions = ImmutableSet.of(DeleteOption.guaranteed); + Set<CreateOption> defaultCreateOptions = ImmutableSet.of(CreateOption.createParentsAsContainers, CreateOption.setDataIfExists); + Set<DeleteOption> defaultDeleteOptions = ImmutableSet.of(DeleteOption.guaranteed); /** * Return a new ModeledAsyncCuratorFramework for the given path and serializer. The returned ModeledAsyncCuratorFramework @@ -69,6 +70,8 @@ public interface ModeledAsyncCuratorFramework<T> */ CuratorFramework unwrap(); + ModeledDetails<T> getDetails(); + /** * Return a new Modeled Curator instance with all the same options but applying to the given child node of this Modeled Curator's * path. E.g. if this Modeled Curator instance applies to "/a/b", calling <code>modeled.at("c")</code> returns an instance that applies to http://git-wip-us.apache.org/repos/asf/curator/blob/4efc38f3/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModeledDetails.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModeledDetails.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModeledDetails.java new file mode 100644 index 0000000..65afc94 --- /dev/null +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModeledDetails.java @@ -0,0 +1,46 @@ +/** + * 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.modeled; + +import org.apache.curator.x.async.api.CreateOption; +import java.util.Set; + +public interface ModeledDetails<T> +{ + /** + * Return the create options set for this instance + * + * @return options + */ + Set<CreateOption> getCreateOptions(); + + /** + * Return the serializer for this instance + * + * @return serializer + */ + ModelSerializer<T> getSerializer(); + + /** + * Return the path for this instance + * + * @return path + */ + ZPath getPath(); +} http://git-wip-us.apache.org/repos/asf/curator/blob/4efc38f3/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ZPath.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ZPath.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ZPath.java index 05d012a..3e0dc2d 100644 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ZPath.java +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ZPath.java @@ -1,3 +1,21 @@ +/** + * 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.modeled; import org.apache.curator.x.async.modeled.details.ZPathImpl; http://git-wip-us.apache.org/repos/asf/curator/blob/4efc38f3/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledAsyncCuratorFrameworkImpl.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledAsyncCuratorFrameworkImpl.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledAsyncCuratorFrameworkImpl.java index 40a3be8..1754f03 100644 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledAsyncCuratorFrameworkImpl.java +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledAsyncCuratorFrameworkImpl.java @@ -34,6 +34,8 @@ import org.apache.curator.x.async.api.DeleteOption; import org.apache.curator.x.async.api.WatchableAsyncCuratorFramework; import org.apache.curator.x.async.modeled.ModelSerializer; import org.apache.curator.x.async.modeled.ModeledAsyncCuratorFramework; +import org.apache.curator.x.async.modeled.ModeledDetails; +import org.apache.curator.x.async.modeled.ZPath; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.data.ACL; @@ -45,7 +47,7 @@ import java.util.Set; import java.util.concurrent.CompletionStage; import java.util.function.UnaryOperator; -public class ModeledAsyncCuratorFrameworkImpl<T> implements ModeledAsyncCuratorFramework<T> +public class ModeledAsyncCuratorFrameworkImpl<T> implements ModeledAsyncCuratorFramework<T>, ModeledDetails<T> { private final AsyncCuratorFramework client; private final WatchableAsyncCuratorFramework watchableClient; @@ -82,6 +84,30 @@ public class ModeledAsyncCuratorFrameworkImpl<T> implements ModeledAsyncCuratorF } @Override + public ModeledDetails<T> getDetails() + { + return this; + } + + @Override + public Set<CreateOption> getCreateOptions() + { + return createOptions; + } + + @Override + public ModelSerializer<T> getSerializer() + { + return serializer; + } + + @Override + public ZPath getPath() + { + return ZPath.parse(path); + } + + @Override public CuratorFramework unwrap() { return client.unwrap(); http://git-wip-us.apache.org/repos/asf/curator/blob/4efc38f3/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ZPathImpl.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ZPathImpl.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ZPathImpl.java index 06a15ad..35cae3c 100644 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ZPathImpl.java +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ZPathImpl.java @@ -1,3 +1,21 @@ +/** + * 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.modeled.details; import com.google.common.base.Splitter; http://git-wip-us.apache.org/repos/asf/curator/blob/4efc38f3/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/recipes/ModeledNodeCacheImpl.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/recipes/ModeledNodeCacheImpl.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/recipes/ModeledNodeCacheImpl.java new file mode 100644 index 0000000..f704f77 --- /dev/null +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/recipes/ModeledNodeCacheImpl.java @@ -0,0 +1,117 @@ +/** + * 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.modeled.details.recipes; + +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.listen.Listenable; +import org.apache.curator.framework.recipes.cache.ChildData; +import org.apache.curator.framework.recipes.cache.NodeCache; +import org.apache.curator.framework.recipes.cache.NodeCacheListener; +import org.apache.curator.utils.CloseableUtils; +import org.apache.curator.x.async.api.CreateOption; +import org.apache.curator.x.async.modeled.ModeledDetails; +import org.apache.curator.x.async.modeled.recipes.ModeledCachedNode; +import org.apache.curator.x.async.modeled.recipes.ModeledNodeCache; +import org.apache.zookeeper.data.Stat; +import java.util.Objects; +import java.util.Optional; + +public class ModeledNodeCacheImpl<T> implements ModeledNodeCache<T> +{ + private final NodeCache cache; + private final ModeledDetails<T> modeled; + + public ModeledNodeCacheImpl(CuratorFramework client, ModeledDetails<T> modeled) + { + this.modeled = Objects.requireNonNull(modeled, "modeled cannot be null"); + cache = new NodeCache(client, modeled.getPath().fullPath(), modeled.getCreateOptions().contains(CreateOption.compress)); + } + + @Override + public void start() + { + try + { + cache.start(); + } + catch ( Exception e ) + { + throw new RuntimeException("Could not start", e); + } + } + + @Override + public void start(boolean buildInitial) + { + try + { + cache.start(buildInitial); + } + catch ( Exception e ) + { + throw new RuntimeException("Could not start", e); + } + } + + @Override + public void rebuild() + { + try + { + cache.rebuild(); + } + catch ( Exception e ) + { + throw new RuntimeException("Could not rebuild", e); + } + } + + @Override + public Listenable<NodeCacheListener> getListenable() + { + return cache.getListenable(); + } + + @Override + public Optional<ModeledCachedNode<T>> getCurrentData() + { + ChildData currentData = cache.getCurrentData(); + if ( currentData == null ) + { + return Optional.empty(); + } + byte[] data = currentData.getData(); + Stat stat = currentData.getStat(); + if ( stat == null ) + { + stat = new Stat(); + } + if ( (data == null) || (data.length == 0) ) + { + return Optional.of(new ModeledCachedNode<T>(modeled.getPath(), null, stat)); + } + return Optional.of(new ModeledCachedNode<>(modeled.getPath(), modeled.getSerializer().deserialize(data), stat)); + } + + @Override + public void close() + { + CloseableUtils.closeQuietly(cache); + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/4efc38f3/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/recipes/ModeledPathChildrenCacheImpl.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/recipes/ModeledPathChildrenCacheImpl.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/recipes/ModeledPathChildrenCacheImpl.java new file mode 100644 index 0000000..5a5bdda --- /dev/null +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/recipes/ModeledPathChildrenCacheImpl.java @@ -0,0 +1,233 @@ +/** + * 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.modeled.details.recipes; + +import com.google.common.util.concurrent.MoreExecutors; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.listen.Listenable; +import org.apache.curator.framework.recipes.cache.ChildData; +import org.apache.curator.framework.recipes.cache.PathChildrenCache; +import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent; +import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener; +import org.apache.curator.utils.CloseableExecutorService; +import org.apache.curator.utils.CloseableUtils; +import org.apache.curator.x.async.api.CreateOption; +import org.apache.curator.x.async.modeled.ModeledDetails; +import org.apache.curator.x.async.modeled.ZPath; +import org.apache.curator.x.async.modeled.recipes.ModeledCachedNode; +import org.apache.curator.x.async.modeled.recipes.ModeledPathChildrenCache; +import org.apache.curator.x.async.modeled.recipes.ModeledPathChildrenCacheEvent; +import org.apache.curator.x.async.modeled.recipes.ModeledPathChildrenCacheListener; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.stream.Collectors; + +public class ModeledPathChildrenCacheImpl<T> implements ModeledPathChildrenCache<T> +{ + private final ModeledDetails<T> modeled; + private final PathChildrenCache cache; + private final Map<ModeledPathChildrenCacheListener, PathChildrenCacheListener> listenerMap = new ConcurrentHashMap<>(); + + public ModeledPathChildrenCacheImpl(CuratorFramework client, ModeledDetails<T> modeled, boolean cacheData, ThreadFactory threadFactory, ExecutorService executorService, CloseableExecutorService closeableExecutorService) + { + this.modeled = modeled; + PathChildrenCache localCache; + if ( threadFactory != null ) + { + localCache = new PathChildrenCache(client, modeled.getPath().fullPath(), cacheData, modeled.getCreateOptions().contains(CreateOption.compress), threadFactory); + } + else if ( executorService != null ) + { + localCache = new PathChildrenCache(client, modeled.getPath().fullPath(), cacheData, modeled.getCreateOptions().contains(CreateOption.compress), executorService); + } + else if ( closeableExecutorService != null ) + { + localCache = new PathChildrenCache(client, modeled.getPath().fullPath(), cacheData, modeled.getCreateOptions().contains(CreateOption.compress), closeableExecutorService); + } + else + { + localCache = new PathChildrenCache(client, modeled.getPath().fullPath(), cacheData, modeled.getCreateOptions().contains(CreateOption.compress), PathChildrenCache.defaultThreadFactory); + } + cache = localCache; + } + + @Override + public void start() + { + try + { + cache.start(); + } + catch ( Exception e ) + { + throw new RuntimeException("can't start cache", e); + } + } + + @Override + public void start(PathChildrenCache.StartMode mode) + { + try + { + cache.start(mode); + } + catch ( Exception e ) + { + throw new RuntimeException("can't start cache", e); + } + } + + @Override + public void rebuild() + { + try + { + cache.rebuild(); + } + catch ( Exception e ) + { + throw new RuntimeException("can't rebuild cache", e); + } + } + + @Override + public void rebuildNode(String fullPath) + { + try + { + cache.rebuildNode(fullPath); + } + catch ( Exception e ) + { + throw new RuntimeException("can't rebuild cache at " + fullPath, e); + } + } + + @Override + public Listenable<ModeledPathChildrenCacheListener> getListenable() + { + return new Listenable<ModeledPathChildrenCacheListener>() + { + @Override + public void addListener(ModeledPathChildrenCacheListener listener) + { + addListener(listener, MoreExecutors.sameThreadExecutor()); + } + + @Override + public void addListener(ModeledPathChildrenCacheListener listener, Executor executor) + { + PathChildrenCacheListener pathChildrenCacheListener = (client, event) -> { + ModeledPathChildrenCacheEvent modeledEvent = new ModeledPathChildrenCacheEvent() + { + @Override + public PathChildrenCacheEvent.Type getType() + { + return event.getType(); + } + + @Override + public ModeledCachedNode getNode() + { + return from(event.getData()); + } + }; + listener.event(modeledEvent); + }; + listenerMap.put(listener, pathChildrenCacheListener); + cache.getListenable().addListener(pathChildrenCacheListener); + } + + @Override + public void removeListener(ModeledPathChildrenCacheListener listener) + { + PathChildrenCacheListener pathChildrenCacheListener = listenerMap.remove(listener); + if ( pathChildrenCacheListener != null ) + { + cache.getListenable().removeListener(pathChildrenCacheListener); + } + } + }; + } + + @Override + public List<ModeledCachedNode> getCurrentData() + { + return cache.getCurrentData().stream() + .map(this::from) + .collect(Collectors.toList()); + } + + private ModeledCachedNode<T> from(ChildData data) + { + if ( data == null ) + { + return null; + } + T model = (data.getData() != null) ? modeled.getSerializer().deserialize(data.getData()) : null; + return new ModeledCachedNode<>(ZPath.parse(data.getPath()), model, data.getStat()); + } + + @Override + public ModeledCachedNode getCurrentData(String fullPath) + { + return from(cache.getCurrentData(fullPath)); + } + + @Override + public void clearDataBytes(String fullPath) + { + cache.clearDataBytes(fullPath); + } + + @Override + public boolean clearDataBytes(String fullPath, int ifVersion) + { + return cache.clearDataBytes(fullPath, ifVersion); + } + + @Override + public void clearAndRefresh() + { + try + { + cache.clearAndRefresh(); + } + catch ( Exception e ) + { + throw new RuntimeException("could not clear and refresh", e); + } + } + + @Override + public void clear() + { + cache.clear(); + } + + @Override + public void close() + { + CloseableUtils.closeQuietly(cache); + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/4efc38f3/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCachedNode.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCachedNode.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCachedNode.java new file mode 100644 index 0000000..8982396 --- /dev/null +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCachedNode.java @@ -0,0 +1,104 @@ +/** + * 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.modeled.recipes; + +import org.apache.curator.x.async.modeled.ZPath; +import org.apache.zookeeper.data.Stat; +import java.util.Objects; +import java.util.Optional; + +public class ModeledCachedNode<T> +{ + private final ZPath path; + private final Stat stat; + private final Optional<T> data; + + public ModeledCachedNode(ZPath path) + { + this(path, null, new Stat()); + } + + public ModeledCachedNode(ZPath path, T data) + { + this(path, data, new Stat()); + } + + public ModeledCachedNode(ZPath path, T data, Stat stat) + { + this.path = Objects.requireNonNull(path, "path cannot be null"); + this.data = Optional.ofNullable(data); + this.stat = Objects.requireNonNull(stat, "stat cannot be null"); + } + + public ZPath getPath() + { + return path; + } + + public Stat getStat() + { + return stat; + } + + public Optional<T> getData() + { + return data; + } + + @Override + public boolean equals(Object o) + { + if ( this == o ) + { + return true; + } + if ( o == null || getClass() != o.getClass() ) + { + return false; + } + + ModeledCachedNode<?> that = (ModeledCachedNode<?>)o; + + if ( !path.equals(that.path) ) + { + return false; + } + //noinspection SimplifiableIfStatement + if ( !stat.equals(that.stat) ) + { + return false; + } + return data.equals(that.data); + } + + @Override + public int hashCode() + { + int result = path.hashCode(); + result = 31 * result + stat.hashCode(); + result = 31 * result + data.hashCode(); + return result; + } + + @Override + public String toString() + { + return "ModeledCachedNode{" + "stat=" + stat + ", data=" + data + '}'; + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/4efc38f3/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledNodeCache.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledNodeCache.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledNodeCache.java new file mode 100644 index 0000000..6da08c7 --- /dev/null +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledNodeCache.java @@ -0,0 +1,47 @@ +/** + * 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.modeled.recipes; + +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.listen.Listenable; +import org.apache.curator.framework.recipes.cache.NodeCacheListener; +import org.apache.curator.x.async.modeled.ModeledDetails; +import org.apache.curator.x.async.modeled.details.recipes.ModeledNodeCacheImpl; +import java.io.Closeable; +import java.util.Optional; + +public interface ModeledNodeCache<T> extends Closeable +{ + static <T> ModeledNodeCache build(CuratorFramework client, ModeledDetails<T> modeled) + { + return new ModeledNodeCacheImpl<>(client, modeled); + } + + void start(); + + void start(boolean buildInitial); + + void rebuild(); + + Listenable<NodeCacheListener> getListenable(); + + Optional<ModeledCachedNode<T>> getCurrentData(); + + void close(); +} http://git-wip-us.apache.org/repos/asf/curator/blob/4efc38f3/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledPathChildrenCache.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledPathChildrenCache.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledPathChildrenCache.java new file mode 100644 index 0000000..06fa345 --- /dev/null +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledPathChildrenCache.java @@ -0,0 +1,82 @@ +/** + * 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.modeled.recipes; + +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.listen.Listenable; +import org.apache.curator.framework.recipes.cache.PathChildrenCache; +import org.apache.curator.utils.CloseableExecutorService; +import org.apache.curator.x.async.modeled.ModeledDetails; +import org.apache.curator.x.async.modeled.details.recipes.ModeledPathChildrenCacheImpl; +import java.io.Closeable; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ThreadFactory; + +public interface ModeledPathChildrenCache<T> extends Closeable +{ + static <T> ModeledPathChildrenCache<T> build(CuratorFramework client, ModeledDetails<T> modeled) + { + return new ModeledPathChildrenCacheImpl<>(client, modeled, true, null, null, null); + } + + static <T> ModeledPathChildrenCache<T> build(CuratorFramework client, ModeledDetails<T> modeled, boolean cacheData) + { + return new ModeledPathChildrenCacheImpl<>(client, modeled, cacheData, null, null, null); + } + + static <T> ModeledPathChildrenCache<T> build(CuratorFramework client, ModeledDetails<T> modeled, boolean cacheData, ThreadFactory threadFactory) + { + return new ModeledPathChildrenCacheImpl<>(client, modeled, cacheData, threadFactory, null, null); + } + + static <T> ModeledPathChildrenCache<T> build(CuratorFramework client, ModeledDetails<T> modeled, boolean cacheData, ExecutorService executorService) + { + return new ModeledPathChildrenCacheImpl<>(client, modeled, cacheData, null, executorService, null); + } + + static <T> ModeledPathChildrenCache<T> build(CuratorFramework client, ModeledDetails<T> modeled, boolean cacheData, CloseableExecutorService executorService) + { + return new ModeledPathChildrenCacheImpl<>(client, modeled, cacheData, null, null, executorService); + } + + void start(); + + void start(PathChildrenCache.StartMode mode); + + void rebuild(); + + void rebuildNode(String fullPath); + + Listenable<ModeledPathChildrenCacheListener> getListenable(); + + List<ModeledCachedNode> getCurrentData(); + + ModeledCachedNode getCurrentData(String fullPath); + + void clearDataBytes(String fullPath); + + boolean clearDataBytes(String fullPath, int ifVersion); + + void clearAndRefresh(); + + void clear(); + + void close(); +} http://git-wip-us.apache.org/repos/asf/curator/blob/4efc38f3/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledPathChildrenCacheEvent.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledPathChildrenCacheEvent.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledPathChildrenCacheEvent.java new file mode 100644 index 0000000..d2a9d71 --- /dev/null +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledPathChildrenCacheEvent.java @@ -0,0 +1,28 @@ +/** + * 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.modeled.recipes; + +import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent; + +public interface ModeledPathChildrenCacheEvent<T> +{ + PathChildrenCacheEvent.Type getType(); + + ModeledCachedNode<T> getNode(); +} http://git-wip-us.apache.org/repos/asf/curator/blob/4efc38f3/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledPathChildrenCacheListener.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledPathChildrenCacheListener.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledPathChildrenCacheListener.java new file mode 100644 index 0000000..9379961 --- /dev/null +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledPathChildrenCacheListener.java @@ -0,0 +1,24 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.curator.x.async.modeled.recipes; + +public interface ModeledPathChildrenCacheListener +{ + void event(ModeledPathChildrenCacheEvent event); +} http://git-wip-us.apache.org/repos/asf/curator/blob/4efc38f3/curator-x-async/src/test/java/org/apache/curator/x/async/modeled/TestZPath.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/test/java/org/apache/curator/x/async/modeled/TestZPath.java b/curator-x-async/src/test/java/org/apache/curator/x/async/modeled/TestZPath.java index 9e7a718..f3c3dff 100644 --- a/curator-x-async/src/test/java/org/apache/curator/x/async/modeled/TestZPath.java +++ b/curator-x-async/src/test/java/org/apache/curator/x/async/modeled/TestZPath.java @@ -1,3 +1,21 @@ +/** + * 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.modeled; import org.apache.curator.utils.ZKPaths;