Major rework of caching. Having the wrapped caches adds little value. Focus on the integrated caching in the modeled client instance
Project: http://git-wip-us.apache.org/repos/asf/curator/repo Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/2cbbf999 Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/2cbbf999 Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/2cbbf999 Branch: refs/heads/CURATOR-397 Commit: 2cbbf999294181dbefeccebabd9c6de867142e2c Parents: e40ed18 Author: randgalt <[email protected]> Authored: Mon May 1 22:56:36 2017 -0500 Committer: randgalt <[email protected]> Committed: Mon May 1 22:56:36 2017 -0500 ---------------------------------------------------------------------- .../main/java/modeled/ModeledCacheExamples.java | 57 ---- .../modeled/CachedModeledCuratorFramework.java | 43 --- .../async/modeled/ModeledCuratorFramework.java | 14 +- .../apache/curator/x/async/modeled/ZPath.java | 9 + .../cached/CachedModeledCuratorFramework.java | 48 ++++ .../x/async/modeled/cached/ModeledCache.java | 53 ++++ .../modeled/cached/ModeledCacheEventType.java | 42 +++ .../modeled/cached/ModeledCacheListener.java | 58 ++++ .../async/modeled/cached/ModeledCachedNode.java | 49 ++++ .../CachedModeledCuratorFrameworkImpl.java | 140 +++------- .../x/async/modeled/details/ModelStage.java | 6 + .../async/modeled/details/ModeledCacheImpl.java | 173 ++++++++++++ .../details/ModeledCuratorFrameworkImpl.java | 34 +-- .../x/async/modeled/details/ZPathImpl.java | 13 +- .../details/recipes/ModeledCachedNodeImpl.java | 107 -------- .../details/recipes/ModeledNodeCacheImpl.java | 232 ---------------- .../recipes/ModeledPathChildrenCacheImpl.java | 266 ------------------- .../details/recipes/ModeledTreeCacheImpl.java | 179 ------------- .../x/async/modeled/recipes/ModeledCache.java | 51 ---- .../modeled/recipes/ModeledCacheEvent.java | 39 --- .../modeled/recipes/ModeledCacheEventType.java | 57 ---- .../modeled/recipes/ModeledCacheListener.java | 84 ------ .../modeled/recipes/ModeledCachedNode.java | 49 ---- .../async/modeled/recipes/ModeledNodeCache.java | 91 ------- .../recipes/ModeledPathChildrenCache.java | 114 -------- .../async/modeled/recipes/ModeledTreeCache.java | 70 ----- .../TestCachedModeledCuratorFramework.java | 4 +- .../details/recipes/TestEventTypeMappings.java | 44 --- .../modeled/recipes/TestModeledCaches.java | 193 -------------- 29 files changed, 497 insertions(+), 1822 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/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 deleted file mode 100644 index 3157f7e..0000000 --- a/curator-examples/src/main/java/modeled/ModeledCacheExamples.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * 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/2cbbf999/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/CachedModeledCuratorFramework.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/CachedModeledCuratorFramework.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/CachedModeledCuratorFramework.java deleted file mode 100644 index b4c6fef..0000000 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/CachedModeledCuratorFramework.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * 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.recipes.ModeledCache; -import java.io.Closeable; - -public interface CachedModeledCuratorFramework<T> extends ModeledCuratorFramework<T>, Closeable -{ - /** - * Return the cache instance - * - * @return cache - */ - ModeledCache<T> getCache(); - - /** - * Start the internally created via {@link #cached()} - */ - void start(); - - /** - * Close the internally created via {@link #cached()} - */ - @Override - void close(); -} http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModeledCuratorFramework.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModeledCuratorFramework.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModeledCuratorFramework.java index ac4fd8d..31b630d 100644 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModeledCuratorFramework.java +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModeledCuratorFramework.java @@ -22,7 +22,7 @@ import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.api.transaction.CuratorOp; import org.apache.curator.framework.api.transaction.CuratorTransactionResult; import org.apache.curator.x.async.AsyncStage; -import org.apache.curator.x.async.modeled.recipes.ModeledCache; +import org.apache.curator.x.async.modeled.cached.CachedModeledCuratorFramework; import org.apache.zookeeper.data.Stat; import java.util.List; import java.util.Map; @@ -54,19 +54,9 @@ public interface ModeledCuratorFramework<T> } /** - * Use the given cache as a front for this modeled instance. All read APIs check the cache - * first and, if available, return the values from the cache. - * the cache - * - * @param cache cache to use - * @return wrapped instance - */ - CachedModeledCuratorFramework<T> cached(ModeledCache<T> cache); - - /** * Use an internally created cache as a front for this modeled instance. All read APIs check the cache * first and, if available, return the values from the cache. Note: you must call - * {@link org.apache.curator.x.async.modeled.CachedModeledCuratorFramework#start()} and + * {@link org.apache.curator.x.async.modeled.cached.CachedModeledCuratorFramework#start()} and * {@link CachedModeledCuratorFramework#close()} to start/stop * * @return wrapped instance http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/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 78cd40f..1b10a40 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 @@ -176,6 +176,15 @@ public interface ZPath boolean isRoot(); /** + * Return true if this path starts with the given path. i.e. + * <code>ZPath.from("/one/two/three").startsWith(ZPath.from("/one/two"))</code> returns true + * + * @param path base path + * @return true/false + */ + boolean startsWith(ZPath path); + + /** * The string full path that this ZPath represents * * @return full path http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/CachedModeledCuratorFramework.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/CachedModeledCuratorFramework.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/CachedModeledCuratorFramework.java new file mode 100644 index 0000000..8718e60 --- /dev/null +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/CachedModeledCuratorFramework.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.async.modeled.cached; + +import org.apache.curator.x.async.modeled.ModeledCuratorFramework; +import java.io.Closeable; + +public interface CachedModeledCuratorFramework<T> extends ModeledCuratorFramework<T>, Closeable +{ + /** + * Return the cache instance + * + * @return cache + */ + ModeledCache<T> getCache(); + + /** + * Start the internally created via {@link #cached()} + */ + void start(); + + /** + * Close the internally created via {@link #cached()} + */ + @Override + void close(); + + /** + * {@inheritDoc} + */ + CachedModeledCuratorFramework<T> at(String child); +} http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/ModeledCache.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/ModeledCache.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/ModeledCache.java new file mode 100644 index 0000000..3536a65 --- /dev/null +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/ModeledCache.java @@ -0,0 +1,53 @@ +/** + * 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.cached; + +import org.apache.curator.framework.listen.Listenable; +import org.apache.curator.x.async.modeled.ZPath; +import java.util.Map; +import java.util.Optional; + +public interface ModeledCache<T> +{ + /** + * Return the modeled current data for the given path. There are no guarantees of accuracy. This is + * merely the most recent view of the data. If there is no node at the given path, + * {@link java.util.Optional#empty()} is returned. + * + * @param path path to the node to check + * @return data if the node is alive, or null + */ + Optional<ModeledCachedNode<T>> getCurrentData(ZPath path); + + /** + * Return the modeled current set of children at the given path, mapped by child name. There are no + * guarantees of accuracy; this is merely the most recent view of the data. + * + * @param path path to the node to check + * @return a possibly-empty list of children if the node is alive, or null + */ + Map<ZPath, ModeledCachedNode<T>> getCurrentChildren(ZPath path); + + /** + * Return the listener container so that you can add/remove listeners + * + * @return listener container + */ + Listenable<ModeledCacheListener<T>> getListenable(); +} http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/ModeledCacheEventType.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/ModeledCacheEventType.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/ModeledCacheEventType.java new file mode 100644 index 0000000..e7754ea --- /dev/null +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/ModeledCacheEventType.java @@ -0,0 +1,42 @@ +/** + * 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.cached; + +public enum ModeledCacheEventType +{ + /** + * A child was added to the path + */ + NODE_ADDED, + + /** + * A child's data was changed + */ + NODE_UPDATED, + + /** + * A child was removed from the path + */ + NODE_REMOVED, + + /** + * Signals that the initial cache has been populated. + */ + INITIALIZED +} http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/ModeledCacheListener.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/ModeledCacheListener.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/ModeledCacheListener.java new file mode 100644 index 0000000..9ddef87 --- /dev/null +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/ModeledCacheListener.java @@ -0,0 +1,58 @@ +package org.apache.curator.x.async.modeled.cached; + +import org.apache.curator.x.async.modeled.ZPath; +import org.apache.zookeeper.data.Stat; + +@FunctionalInterface +public interface ModeledCacheListener<T> +{ + /** + * The given path was added, updated or removed + * + * @param type action type + * @param path the path + * @param stat the node's stat (previous stat for removal) + * @param model the node's model (previous model for removal) + */ + void accept(ModeledCacheEventType type, ZPath path, Stat stat, T model); + + /** + * The cache has finished initializing + */ + default void initialized() + { + // NOP + } + + /** + * Returns a version of this listener that only begins calling + * {@link #accept(ModeledCacheEventType, org.apache.curator.x.async.modeled.ZPath, org.apache.zookeeper.data.Stat, Object)} + * once {@link #initialized()} has been called. i.e. changes that occur as the cache is initializing are not sent + * to the listener + * + * @return wrapped listener + */ + default ModeledCacheListener<T> postInitializedOnly() + { + return new ModeledCacheListener<T>() + { + private volatile boolean isInitialized = false; + + @Override + public void accept(ModeledCacheEventType type, ZPath path, Stat stat, T model) + { + if ( isInitialized ) + { + ModeledCacheListener.this.accept(type, path, stat, model); + } + } + + @Override + public void initialized() + { + isInitialized = true; + ModeledCacheListener.this.initialized(); + } + }; + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/ModeledCachedNode.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/ModeledCachedNode.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/ModeledCachedNode.java new file mode 100644 index 0000000..3a8e742 --- /dev/null +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/ModeledCachedNode.java @@ -0,0 +1,49 @@ +/** + * 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.cached; + +import org.apache.curator.x.async.modeled.ZPath; +import org.apache.zookeeper.data.Stat; + +/** + * Abstracts a cached node + */ +public interface ModeledCachedNode<T> +{ + /** + * The path of the node + * + * @return path + */ + ZPath getPath(); + + /** + * The node's last known stat if available + * + * @return stat + */ + Stat getStat(); + + /** + * The node's current model + * + * @return model + */ + T getModel(); +} http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/CachedModeledCuratorFrameworkImpl.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/CachedModeledCuratorFrameworkImpl.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/CachedModeledCuratorFrameworkImpl.java index 6192f3a..3318403 100644 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/CachedModeledCuratorFrameworkImpl.java +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/CachedModeledCuratorFrameworkImpl.java @@ -18,44 +18,43 @@ */ package org.apache.curator.x.async.modeled.details; -import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Lists; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.api.transaction.CuratorOp; import org.apache.curator.framework.api.transaction.CuratorTransactionResult; import org.apache.curator.x.async.AsyncStage; -import org.apache.curator.x.async.modeled.CachedModeledCuratorFramework; +import org.apache.curator.x.async.api.CreateOption; import org.apache.curator.x.async.modeled.CuratorModelSpec; import org.apache.curator.x.async.modeled.ModeledCuratorFramework; import org.apache.curator.x.async.modeled.ZPath; -import org.apache.curator.x.async.modeled.recipes.ModeledCache; -import org.apache.curator.x.async.modeled.recipes.ModeledCachedNode; +import org.apache.curator.x.async.modeled.cached.CachedModeledCuratorFramework; +import org.apache.curator.x.async.modeled.cached.ModeledCache; +import org.apache.curator.x.async.modeled.cached.ModeledCachedNode; +import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.data.Stat; import org.apache.zookeeper.server.DataTree; import java.util.AbstractMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Optional; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; +import java.util.Set; import java.util.stream.Collectors; class CachedModeledCuratorFrameworkImpl<T> implements CachedModeledCuratorFramework<T> { private final ModeledCuratorFramework<T> client; - private final ModeledCache<T> cache; - private final ZPath path; + private final ModeledCacheImpl<T> cache; - CachedModeledCuratorFrameworkImpl(ModeledCuratorFramework<T> client, ModeledCache<T> cache, ZPath path) + CachedModeledCuratorFrameworkImpl(ModeledCuratorFramework<T> client) { - this.client = Objects.requireNonNull(client, "client cannot be null"); - this.cache = Objects.requireNonNull(cache, "cache cannot be null"); - this.path = Objects.requireNonNull(path, "path cannot be null"); + this(client, new ModeledCacheImpl<>(client.unwrap(), client.modelSpec().path(), client.modelSpec().serializer(), client.modelSpec().createOptions().contains(CreateOption.compress))); } - @VisibleForTesting - volatile AtomicInteger debugCachedReadCount = null; + private CachedModeledCuratorFrameworkImpl(ModeledCuratorFramework<T> client, ModeledCacheImpl<T> cache) + { + this.client = client; + this.cache = cache; + } @Override public ModeledCache<T> getCache() @@ -66,55 +65,49 @@ class CachedModeledCuratorFrameworkImpl<T> implements CachedModeledCuratorFramew @Override public void start() { - throw new UnsupportedOperationException(); + cache.start(); } @Override public void close() { - throw new UnsupportedOperationException(); - } - - @Override - public CuratorModelSpec<T> modelSpec() - { - return client.modelSpec(); + cache.close(); } @Override - public CachedModeledCuratorFramework<T> cached(ModeledCache<T> cache) + public CachedModeledCuratorFramework<T> cached() { - throw new UnsupportedOperationException(); + return this; } @Override - public CachedModeledCuratorFramework<T> cached() + public CuratorFramework unwrap() { - throw new UnsupportedOperationException(); + return client.unwrap(); } @Override - public CuratorFramework unwrap() + public CuratorModelSpec<T> modelSpec() { - return client.unwrap(); + return client.modelSpec(); } @Override - public ModeledCuratorFramework<T> at(String child) + public CachedModeledCuratorFramework<T> at(String child) { - return new CachedModeledCuratorFrameworkImpl<>(client.at(child), cache, path.at(child)); + return new CachedModeledCuratorFrameworkImpl<>(client.at(child), cache); } @Override public AsyncStage<String> set(T model) { - return client.set(model); + return client.set(model); // TODO - update cache? } @Override public AsyncStage<String> set(T model, Stat storingStatIn) { - return client.set(model, storingStatIn); + return client.set(model, storingStatIn); // TODO - update cache? } @Override @@ -126,25 +119,15 @@ class CachedModeledCuratorFrameworkImpl<T> implements CachedModeledCuratorFramew @Override public AsyncStage<T> read(Stat storingStatIn) { + ZPath path = client.modelSpec().path(); Optional<ModeledCachedNode<T>> data = cache.getCurrentData(path); - if ( data.isPresent() ) - { - ModeledCachedNode<T> localData = data.get(); - T model = localData.getModel(); - if ( model != null ) + return data.map(node -> { + if ( storingStatIn != null ) { - if ( (storingStatIn != null) && (localData.getStat() != null) ) - { - DataTree.copyStat(localData.getStat(), storingStatIn); - } - if ( debugCachedReadCount != null ) - { - debugCachedReadCount.incrementAndGet(); - } - return new ModelStage<>(model); + DataTree.copyStat(node.getStat(), storingStatIn); } - } - return (storingStatIn != null) ? client.read(storingStatIn) : client.read(); + return new ModelStage<>(node.getModel()); + }).orElseGet(() -> new ModelStage<>(new KeeperException.NoNodeException(path.fullPath()))); } @Override @@ -174,67 +157,26 @@ class CachedModeledCuratorFrameworkImpl<T> implements CachedModeledCuratorFramew @Override public AsyncStage<Stat> checkExists() { + ZPath path = client.modelSpec().path(); Optional<ModeledCachedNode<T>> data = cache.getCurrentData(path); - return data.map(node -> { - AsyncStage<Stat> stage = new ModelStage<>(node.getStat()); - if ( debugCachedReadCount != null ) - { - debugCachedReadCount.incrementAndGet(); - } - return stage; - }).orElseGet(client::checkExists); + return data.map(node -> new ModelStage<>(node.getStat())).orElseGet(() -> new ModelStage<>((Stat)null)); } @Override public AsyncStage<List<ZPath>> getChildren() { - Map<ZPath, ModeledCachedNode<T>> currentChildren = cache.getCurrentChildren(path); - if ( currentChildren != cache.noChildrenValue() ) - { - if ( debugCachedReadCount != null ) - { - debugCachedReadCount.incrementAndGet(); - } - return new ModelStage<>(Lists.newArrayList(currentChildren.keySet())); - } - return client.getChildren(); + Set<ZPath> paths = cache.getCurrentChildren(client.modelSpec().path()).keySet(); + return new ModelStage<>(Lists.newArrayList(paths)); } @Override public AsyncStage<Map<ZPath, AsyncStage<T>>> readChildren() { - Map<ZPath, ModeledCachedNode<T>> currentChildren = cache.getCurrentChildren(path); - if ( currentChildren != cache.noChildrenValue() ) - { - if ( debugCachedReadCount != null ) - { - debugCachedReadCount.incrementAndGet(); - } - Map<ZPath, AsyncStage<T>> children = currentChildren.entrySet() - .stream() - .map(e -> new AbstractMap.SimpleEntry<>(e.getKey(), e.getValue().getModel())) - .filter(e -> e.getValue() != null) - .collect(Collectors.toMap(Map.Entry::getKey, e -> new ModelStage<>(e.getValue()))); - return new ModelStage<>(children); - } - - ModelStage<Map<ZPath, AsyncStage<T>>> modelStage = new ModelStage<>(); - client.getChildren().whenComplete((children, e) -> { - if ( e != null ) - { - modelStage.completeExceptionally(e); - } - else - { - if ( debugCachedReadCount != null ) - { - debugCachedReadCount.incrementAndGet(); - } - Map<ZPath, AsyncStage<T>> map = children.stream().collect(Collectors.toMap(Function.identity(), path1 -> at(path1.nodeName()).read())); - modelStage.complete(map); - } - }); - return modelStage; + Map<ZPath, AsyncStage<T>> map = cache.getCurrentChildren(client.modelSpec().path()).entrySet() + .stream() + .map(entry -> new AbstractMap.SimpleEntry<>(entry.getKey(), new ModelStage<>(entry.getValue().getModel()))) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + return new ModelStage<>(map); } @Override http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModelStage.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModelStage.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModelStage.java index c28b133..77caed1 100644 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModelStage.java +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModelStage.java @@ -43,6 +43,12 @@ class ModelStage<T> extends CompletableFuture<T> implements AsyncStage<T> complete(value); } + ModelStage(Exception e) + { + event = null; + completeExceptionally(e); + } + @Override public CompletionStage<WatchedEvent> event() { http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledCacheImpl.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledCacheImpl.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledCacheImpl.java new file mode 100644 index 0000000..c1ab8cd --- /dev/null +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledCacheImpl.java @@ -0,0 +1,173 @@ +package org.apache.curator.x.async.modeled.details; + +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.listen.Listenable; +import org.apache.curator.framework.listen.ListenerContainer; +import org.apache.curator.framework.recipes.cache.TreeCache; +import org.apache.curator.framework.recipes.cache.TreeCacheEvent; +import org.apache.curator.framework.recipes.cache.TreeCacheListener; +import org.apache.curator.x.async.modeled.ModelSerializer; +import org.apache.curator.x.async.modeled.ZPath; +import org.apache.curator.x.async.modeled.cached.ModeledCache; +import org.apache.curator.x.async.modeled.cached.ModeledCacheEventType; +import org.apache.curator.x.async.modeled.cached.ModeledCacheListener; +import org.apache.curator.x.async.modeled.cached.ModeledCachedNode; +import org.apache.zookeeper.data.Stat; +import java.util.AbstractMap; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +class ModeledCacheImpl<T> implements TreeCacheListener, ModeledCache<T> +{ + private final TreeCache cache; + private final Map<ZPath, Entry<T>> entries = new ConcurrentHashMap<>(); + private final ModelSerializer<T> serializer; + private final ListenerContainer<ModeledCacheListener<T>> listenerContainer = new ListenerContainer<>(); + + private static final class Entry<T> + { + final Stat stat; + final T model; + + Entry(Stat stat, T model) + { + this.stat = stat; + this.model = model; + } + } + + ModeledCacheImpl(CuratorFramework client, ZPath path, ModelSerializer<T> serializer, boolean compressed) + { + this.serializer = serializer; + cache = TreeCache.newBuilder(client, path.fullPath()) + .setCacheData(false) + .setDataIsCompressed(compressed) + .build(); + } + + public void start() + { + try + { + cache.start(); + } + catch ( Exception e ) + { + throw new RuntimeException(e); + } + } + + public void close() + { + cache.close(); + entries.clear(); + } + + @Override + public Optional<ModeledCachedNode<T>> getCurrentData(ZPath path) + { + Entry<T> entry = entries.remove(path); + if ( entry != null ) + { + return Optional.of(new InternalCachedNode<>(path, entry)); + } + return Optional.empty(); + } + + @Override + public Map<ZPath, ModeledCachedNode<T>> getCurrentChildren(ZPath path) + { + return entries.entrySet() + .stream() + .filter(entry -> entry.getKey().startsWith(path)) + .map(entry -> new AbstractMap.SimpleEntry<>(entry.getKey(), new InternalCachedNode<>(entry.getKey(), entry.getValue()))) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + } + + @Override + public Listenable<ModeledCacheListener<T>> getListenable() + { + return listenerContainer; + } + + @Override + public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception + { + switch ( event.getType() ) + { + case NODE_ADDED: + case NODE_UPDATED: + { + ZPath path = ZPath.from(event.toString()); + T model = serializer.deserialize(event.getData().getData()); + entries.put(path, new Entry<>(event.getData().getStat(), model)); + ModeledCacheEventType type = (event.getType() == TreeCacheEvent.Type.NODE_ADDED) ? ModeledCacheEventType.NODE_ADDED : ModeledCacheEventType.NODE_UPDATED; + accept(type, path, event.getData().getStat(), model); + break; + } + + case NODE_REMOVED: + { + ZPath path = ZPath.from(event.toString()); + Entry<T> entry = entries.remove(path); + T model = (entry != null) ? entry.model : serializer.deserialize(event.getData().getData()); + Stat stat = (entry != null) ? entry.stat : event.getData().getStat(); + accept(ModeledCacheEventType.NODE_REMOVED, path, stat, model); + break; + } + + case INITIALIZED: + { + listenerContainer.forEach(l -> { + l.initialized(); + return null; + }); + break; + } + + default: + // ignore + break; + } + } + + private void accept(ModeledCacheEventType type, ZPath path, Stat stat, T model) + { + listenerContainer.forEach(l -> { + l.accept(type, path, stat, model); + return null; + }); + } + + private static class InternalCachedNode<U> implements ModeledCachedNode<U> + { + private final ZPath path; + private final Entry<U> entry; + + private InternalCachedNode(ZPath path, Entry<U> entry) + { + this.path = path; + this.entry = entry; + } + + @Override + public ZPath getPath() + { + return path; + } + + @Override + public Stat getStat() + { + return entry.stat; + } + + @Override + public U getModel() + { + return entry.model; + } + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledCuratorFrameworkImpl.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledCuratorFrameworkImpl.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledCuratorFrameworkImpl.java index 6ed0649..aba87f3 100644 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledCuratorFrameworkImpl.java +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledCuratorFrameworkImpl.java @@ -23,7 +23,6 @@ import org.apache.curator.framework.api.CuratorEvent; import org.apache.curator.framework.api.UnhandledErrorListener; import org.apache.curator.framework.api.transaction.CuratorOp; import org.apache.curator.framework.api.transaction.CuratorTransactionResult; -import org.apache.curator.framework.recipes.cache.TreeCache; import org.apache.curator.x.async.AsyncCuratorFramework; import org.apache.curator.x.async.AsyncStage; import org.apache.curator.x.async.WatchMode; @@ -33,12 +32,10 @@ import org.apache.curator.x.async.api.AsyncPathable; import org.apache.curator.x.async.api.AsyncTransactionSetDataBuilder; import org.apache.curator.x.async.api.CreateOption; import org.apache.curator.x.async.api.WatchableAsyncCuratorFramework; -import org.apache.curator.x.async.modeled.CachedModeledCuratorFramework; import org.apache.curator.x.async.modeled.CuratorModelSpec; import org.apache.curator.x.async.modeled.ModeledCuratorFramework; import org.apache.curator.x.async.modeled.ZPath; -import org.apache.curator.x.async.modeled.recipes.ModeledCache; -import org.apache.curator.x.async.modeled.recipes.ModeledTreeCache; +import org.apache.curator.x.async.modeled.cached.CachedModeledCuratorFramework; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.data.ACL; import org.apache.zookeeper.data.Stat; @@ -98,36 +95,9 @@ public class ModeledCuratorFrameworkImpl<T> implements ModeledCuratorFramework<T } @Override - public CachedModeledCuratorFramework<T> cached(ModeledCache<T> cache) - { - return new CachedModeledCuratorFrameworkImpl<>(this, cache, modelSpec.path()); - } - - @Override public CachedModeledCuratorFramework<T> cached() { - TreeCache.Builder builder = TreeCache.newBuilder(client.unwrap(), modelSpec.path().fullPath()); - builder = builder.setCacheData(true); - if ( modelSpec.createOptions().contains(CreateOption.compress) ) - { - builder = builder.setDataIsCompressed(true); - } - TreeCache cache = builder.build(); - ModeledTreeCache<T> wrapped = ModeledTreeCache.wrap(cache, modelSpec.serializer()); - return new CachedModeledCuratorFrameworkImpl<T>(this, wrapped, modelSpec.path()) - { - @Override - public void start() - { - wrapped.start(); - } - - @Override - public void close() - { - wrapped.close(); - } - }; + return new CachedModeledCuratorFrameworkImpl<>(this); } @Override http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/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 8072785..36c9d1a 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 @@ -73,7 +73,7 @@ public class ZPathImpl implements ZPath { names = Objects.requireNonNull(names, "names cannot be null"); names.forEach(ZPathImpl::validate); - ImmutableList.Builder<String> builder = ImmutableList.<String>builder(); + ImmutableList.Builder<String> builder = ImmutableList.builder(); if ( base != null ) { if ( base instanceof ZPathImpl ) @@ -113,6 +113,17 @@ public class ZPathImpl implements ZPath } @Override + public boolean startsWith(ZPath path) + { + if ( path instanceof ZPathImpl ) + { + ZPathImpl rhs = (ZPathImpl)path; + return (nodes.size() >= rhs.nodes.size()) && nodes.subList(0, rhs.nodes.size()).equals(rhs); + } + return false; + } + + @Override public Pattern toSchemaPathPattern() { return Pattern.compile(fullPath() + ZKPaths.PATH_SEPARATOR + ".*"); http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/recipes/ModeledCachedNodeImpl.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/recipes/ModeledCachedNodeImpl.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/recipes/ModeledCachedNodeImpl.java deleted file mode 100644 index e66fd8a..0000000 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/recipes/ModeledCachedNodeImpl.java +++ /dev/null @@ -1,107 +0,0 @@ -/** - * 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.x.async.modeled.ZPath; -import org.apache.curator.x.async.modeled.recipes.ModeledCachedNode; -import org.apache.zookeeper.data.Stat; -import java.util.Objects; - -public class ModeledCachedNodeImpl<T> implements ModeledCachedNode<T> -{ - private final ZPath path; - private final Stat stat; - private final T data; - - public ModeledCachedNodeImpl(ZPath path) - { - this(path, null, new Stat()); - } - - public ModeledCachedNodeImpl(ZPath path, T data) - { - this(path, data, new Stat()); - } - - public ModeledCachedNodeImpl(ZPath path, T data, Stat stat) - { - this.path = Objects.requireNonNull(path, "path cannot be null"); - this.stat = Objects.requireNonNull(stat, "stat cannot be null"); - this.data = data; - } - - @Override - public ZPath getPath() - { - return path; - } - - @Override - public Stat getStat() - { - return stat; - } - - @Override - public T getModel() - { - return data; - } - - @Override - public boolean equals(Object o) - { - if ( this == o ) - { - return true; - } - if ( o == null || getClass() != o.getClass() ) - { - return false; - } - - ModeledCachedNodeImpl<?> that = (ModeledCachedNodeImpl<?>)o; - - if ( !path.equals(that.path) ) - { - return false; - } - //noinspection SimplifiableIfStatement - if ( !stat.equals(that.stat) ) - { - return false; - } - return data != null ? data.equals(that.data) : that.data == null; - } - - @Override - public int hashCode() - { - int result = path.hashCode(); - result = 31 * result + stat.hashCode(); - result = 31 * result + (data != null ? data.hashCode() : 0); - return result; - } - - @Override - public String toString() - { - return "ModeledCachedNode{" + "stat=" + stat + ", data=" + data + '}'; - } -} http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/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 deleted file mode 100644 index 5b89faf..0000000 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/recipes/ModeledNodeCacheImpl.java +++ /dev/null @@ -1,232 +0,0 @@ -/** - * 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.NodeCache; -import org.apache.curator.framework.recipes.cache.NodeCacheListener; -import org.apache.curator.framework.state.ConnectionState; -import org.apache.curator.framework.state.ConnectionStateListener; -import org.apache.curator.utils.CloseableUtils; -import org.apache.curator.x.async.modeled.ModelSerializer; -import org.apache.curator.x.async.modeled.ZPath; -import org.apache.curator.x.async.modeled.recipes.ModeledCacheEvent; -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.ModeledCachedNode; -import org.apache.curator.x.async.modeled.recipes.ModeledNodeCache; -import org.apache.zookeeper.data.Stat; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Executor; - -public class ModeledNodeCacheImpl<T> implements ModeledNodeCache<T>, ConnectionStateListener -{ - private final NodeCache cache; - private final ModelSerializer<T> serializer; - private final ZPath path; - private final Map<ModeledCacheListener<T>, NodeCacheListener> listenerMap = new ConcurrentHashMap<>(); - - public ModeledNodeCacheImpl(NodeCache cache, ModelSerializer<T> serializer) - { - this.cache = Objects.requireNonNull(cache, "cache cannot be null"); - this.serializer = Objects.requireNonNull(serializer, "serializer cannot be null"); - path = ZPath.parse(cache.getPath()); - } - - @Override - public void stateChanged(CuratorFramework client, ConnectionState newState) - { - ModeledCacheEventType mappedType; - switch ( newState ) - { - default: - { - mappedType = null; - break; - } - - case RECONNECTED: - case CONNECTED: - { - mappedType = ModeledCacheEventType.CONNECTION_RECONNECTED; - break; - } - - case SUSPENDED: - { - mappedType = ModeledCacheEventType.CONNECTION_SUSPENDED; - break; - } - - case LOST: - { - mappedType = ModeledCacheEventType.CONNECTION_LOST; - break; - } - } - - if ( mappedType != null ) - { - ModeledCacheEvent<T> event = new ModeledCacheEvent<T>() - { - @Override - public ModeledCacheEventType getType() - { - return mappedType; - } - - @Override - public ModeledCachedNode<T> getNode() - { - return null; - } - }; - listenerMap.keySet().forEach(l -> l.event(null)); - } - } - - @Override - public NodeCache unwrap() - { - return cache; - } - - @Override - public void start() - { - try - { - cache.start(); - } - catch ( Exception e ) - { - throw new RuntimeException("Could not start", e); - } - cache.getClient().getConnectionStateListenable().addListener(this); - } - - @Override - public void start(boolean buildInitial) - { - cache.getClient().getConnectionStateListenable().removeListener(this); - 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<ModeledCacheListener<T>> getListenable() - { - return new Listenable<ModeledCacheListener<T>>() - { - @Override - public void addListener(ModeledCacheListener<T> listener) - { - addListener(listener, MoreExecutors.sameThreadExecutor()); - } - - @Override - public void addListener(ModeledCacheListener<T> listener, Executor executor) - { - NodeCacheListener nodeCacheListener = () -> - { - Optional<ModeledCachedNode<T>> currentData = getCurrentData(); - ModeledCacheEvent<T> event = new ModeledCacheEvent<T>() - { - @Override - public ModeledCacheEventType getType() - { - return currentData.isPresent() ? ModeledCacheEventType.NODE_UPDATED : ModeledCacheEventType.NODE_REMOVED; - } - - @Override - public ModeledCachedNode<T> getNode() - { - return currentData.orElse(null); - } - }; - listener.event(event); - }; - listenerMap.put(listener, nodeCacheListener); - cache.getListenable().addListener(nodeCacheListener, executor); - } - - @Override - public void removeListener(ModeledCacheListener<T> listener) - { - NodeCacheListener nodeCacheListener = listenerMap.remove(listener); - if ( nodeCacheListener != null ) - { - cache.getListenable().removeListener(nodeCacheListener); - } - } - }; - } - - @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 ModeledCachedNodeImpl<T>(path, null, stat)); - } - return Optional.of(new ModeledCachedNodeImpl<>(path, serializer.deserialize(data), stat)); - } - - @Override - public void close() - { - CloseableUtils.closeQuietly(cache); - } -} http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/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 deleted file mode 100644 index ed86404..0000000 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/recipes/ModeledPathChildrenCacheImpl.java +++ /dev/null @@ -1,266 +0,0 @@ -/** - * 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.annotations.VisibleForTesting; -import com.google.common.collect.Maps; -import com.google.common.util.concurrent.MoreExecutors; -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.CloseableUtils; -import org.apache.curator.x.async.modeled.ModelSerializer; -import org.apache.curator.x.async.modeled.ZPath; -import org.apache.curator.x.async.modeled.recipes.ModeledCacheEvent; -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.ModeledCachedNode; -import org.apache.curator.x.async.modeled.recipes.ModeledPathChildrenCache; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Executor; -import java.util.stream.Collectors; - -public class ModeledPathChildrenCacheImpl<T> implements ModeledPathChildrenCache<T> -{ - private final PathChildrenCache cache; - private final Map<ModeledCacheListener<T>, PathChildrenCacheListener> listenerMap = new ConcurrentHashMap<>(); - private final ModelSerializer<T> serializer; - - public ModeledPathChildrenCacheImpl(PathChildrenCache cache, ModelSerializer<T> serializer) - { - this.cache = Objects.requireNonNull(cache, "cache cannot be null"); - this.serializer = Objects.requireNonNull(serializer, "serializer cannot be null"); - } - - @Override - public PathChildrenCache unwrap() - { - return cache; - } - - @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(ZPath fullPath) - { - try - { - cache.rebuildNode(fullPath.fullPath()); - } - catch ( Exception e ) - { - throw new RuntimeException("can't rebuild cache at " + fullPath, e); - } - } - - @Override - public Listenable<ModeledCacheListener<T>> getListenable() - { - return new Listenable<ModeledCacheListener<T>>() - { - @Override - public void addListener(ModeledCacheListener<T> listener) - { - addListener(listener, MoreExecutors.sameThreadExecutor()); - } - - @Override - public void addListener(ModeledCacheListener<T> listener, Executor executor) - { - PathChildrenCacheListener pathChildrenCacheListener = (client, event) -> { - ModeledCacheEventType eventType = toType(event.getType()); - ModeledCachedNode<T> node = from(serializer, event.getData()); - ModeledCacheEvent<T> modeledEvent = new ModeledCacheEvent<T>() - { - @Override - public ModeledCacheEventType getType() - { - return eventType; - } - - @Override - public ModeledCachedNode<T> getNode() - { - return node; - } - }; - listener.event(modeledEvent); - }; - listenerMap.put(listener, pathChildrenCacheListener); - cache.getListenable().addListener(pathChildrenCacheListener); - } - - @Override - public void removeListener(ModeledCacheListener listener) - { - PathChildrenCacheListener pathChildrenCacheListener = listenerMap.remove(listener); - if ( pathChildrenCacheListener != null ) - { - cache.getListenable().removeListener(pathChildrenCacheListener); - } - } - }; - } - - @Override - public List<ModeledCachedNode<T>> getCurrentData() - { - return cache.getCurrentData().stream() - .map(data -> from(serializer, data)) - .collect(Collectors.toList()); - } - - @Override - public Map<ZPath, ModeledCachedNode<T>> getCurrentChildren(ZPath fullPath) - { - ChildData currentData = cache.getCurrentData(fullPath.fullPath()); - if ( currentData == null ) - { - return noChildrenValue(); - } - Map<ZPath, ModeledCachedNode<T>> map = Maps.newHashMap(); - map.put(fullPath, from(serializer, currentData)); - return map; - } - - @Override - public Optional<ModeledCachedNode<T>> getCurrentData(ZPath fullPath) - { - return Optional.ofNullable(from(serializer, cache.getCurrentData(fullPath.fullPath()))); - } - - @Override - public void clearDataBytes(ZPath fullPath) - { - cache.clearDataBytes(fullPath.fullPath()); - } - - @Override - public boolean clearDataBytes(ZPath fullPath, int ifVersion) - { - return cache.clearDataBytes(fullPath.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); - } - - static <T> ModeledCachedNode<T> from(ModelSerializer<T> serializer, ChildData data) - { - if ( data == null ) - { - return null; - } - T model = ((data.getData() != null) && (data.getData().length > 0)) ? serializer.deserialize(data.getData()) : null; - return new ModeledCachedNodeImpl<>(ZPath.parse(data.getPath()), model, data.getStat()); - } - - @VisibleForTesting - static ModeledCacheEventType toType(PathChildrenCacheEvent.Type type) - { - switch ( type ) - { - case CHILD_ADDED: - return ModeledCacheEventType.NODE_ADDED; - - case CHILD_UPDATED: - return ModeledCacheEventType.NODE_UPDATED; - - case CHILD_REMOVED: - return ModeledCacheEventType.NODE_REMOVED; - - case CONNECTION_SUSPENDED: - return ModeledCacheEventType.CONNECTION_SUSPENDED; - - case CONNECTION_RECONNECTED: - return ModeledCacheEventType.CONNECTION_RECONNECTED; - - case CONNECTION_LOST: - return ModeledCacheEventType.CONNECTION_LOST; - - case INITIALIZED: - return ModeledCacheEventType.INITIALIZED; - } - throw new UnsupportedOperationException("Unknown type: " + type); - } -} http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/recipes/ModeledTreeCacheImpl.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/recipes/ModeledTreeCacheImpl.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/recipes/ModeledTreeCacheImpl.java deleted file mode 100644 index 7f0aecc..0000000 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/recipes/ModeledTreeCacheImpl.java +++ /dev/null @@ -1,179 +0,0 @@ -/** - * 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.annotations.VisibleForTesting; -import com.google.common.util.concurrent.MoreExecutors; -import org.apache.curator.framework.listen.Listenable; -import org.apache.curator.framework.recipes.cache.ChildData; -import org.apache.curator.framework.recipes.cache.TreeCache; -import org.apache.curator.framework.recipes.cache.TreeCacheEvent; -import org.apache.curator.framework.recipes.cache.TreeCacheListener; -import org.apache.curator.utils.CloseableUtils; -import org.apache.curator.x.async.modeled.ModelSerializer; -import org.apache.curator.x.async.modeled.ZPath; -import org.apache.curator.x.async.modeled.recipes.ModeledCacheEvent; -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.ModeledCachedNode; -import org.apache.curator.x.async.modeled.recipes.ModeledTreeCache; -import java.util.AbstractMap; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Executor; -import java.util.stream.Collectors; - -import static org.apache.curator.x.async.modeled.details.recipes.ModeledPathChildrenCacheImpl.from; - -public class ModeledTreeCacheImpl<T> implements ModeledTreeCache<T> -{ - private final TreeCache cache; - private final Map<ModeledCacheListener<T>, TreeCacheListener> listenerMap = new ConcurrentHashMap<>(); - private final ModelSerializer<T> serializer; - - public ModeledTreeCacheImpl(TreeCache cache, ModelSerializer<T> serializer) - { - this.cache = Objects.requireNonNull(cache, "cache cannot be null"); - this.serializer = Objects.requireNonNull(serializer, "serializer cannot be null"); - } - - @Override - public TreeCache unwrap() - { - return cache; - } - - @Override - public void start() - { - try - { - cache.start(); - } - catch ( Exception e ) - { - throw new RuntimeException("Could not start", e); - } - } - - @Override - public void close() - { - CloseableUtils.closeQuietly(cache); - } - - @Override - public Listenable<ModeledCacheListener<T>> getListenable() - { - return new Listenable<ModeledCacheListener<T>>() - { - @Override - public void addListener(ModeledCacheListener<T> listener) - { - addListener(listener, MoreExecutors.sameThreadExecutor()); - } - - @Override - public void addListener(ModeledCacheListener<T> listener, Executor executor) - { - TreeCacheListener treeCacheListener = (client, event) -> { - ModeledCacheEventType eventType = toType(event.getType()); - ModeledCachedNode<T> node = from(serializer, event.getData()); - ModeledCacheEvent<T> wrappedEvent = new ModeledCacheEvent<T>() - { - @Override - public ModeledCacheEventType getType() - { - return eventType; - } - - @Override - public ModeledCachedNode<T> getNode() - { - return node; - } - }; - listener.event(wrappedEvent); - }; - listenerMap.put(listener, treeCacheListener); - cache.getListenable().addListener(treeCacheListener, executor); - } - - @Override - public void removeListener(ModeledCacheListener<T> listener) - { - TreeCacheListener treeCacheListener = listenerMap.remove(listener); - if ( treeCacheListener != null ) - { - cache.getListenable().removeListener(treeCacheListener); - } - } - }; - } - - @Override - public Map<ZPath, ModeledCachedNode<T>> getCurrentChildren(ZPath fullPath) - { - Map<String, ChildData> currentChildren = cache.getCurrentChildren(fullPath.fullPath()); - if ( currentChildren == null ) - { - return noChildrenValue(); - } - return currentChildren.entrySet().stream() - .map(entry -> new AbstractMap.SimpleEntry<>(ZPath.parse(entry.getKey()), from(serializer, entry.getValue()))) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - } - - @Override - public Optional<ModeledCachedNode<T>> getCurrentData(ZPath fullPath) - { - return Optional.ofNullable(from(serializer, cache.getCurrentData(fullPath.fullPath()))); - } - - @VisibleForTesting - static ModeledCacheEventType toType(TreeCacheEvent.Type type) - { - switch ( type ) - { - case NODE_ADDED: - return ModeledCacheEventType.NODE_ADDED; - - case NODE_UPDATED: - return ModeledCacheEventType.NODE_UPDATED; - - case NODE_REMOVED: - return ModeledCacheEventType.NODE_REMOVED; - - case CONNECTION_SUSPENDED: - return ModeledCacheEventType.CONNECTION_SUSPENDED; - - case CONNECTION_RECONNECTED: - return ModeledCacheEventType.CONNECTION_RECONNECTED; - - case CONNECTION_LOST: - return ModeledCacheEventType.CONNECTION_LOST; - - case INITIALIZED: - return ModeledCacheEventType.INITIALIZED; - } - throw new UnsupportedOperationException("Unknown type: " + type); - } -} http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCache.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCache.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCache.java deleted file mode 100644 index b810512..0000000 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCache.java +++ /dev/null @@ -1,51 +0,0 @@ -/** - * 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 java.util.Collections; -import java.util.Map; -import java.util.Optional; - -public interface ModeledCache<T> -{ - default Map<ZPath, ModeledCachedNode<T>> noChildrenValue() - { - return Collections.emptyMap(); - } - - /** - * Return the modeled current data for the given path. There are no guarantees of accuracy. This is - * merely the most recent view of the data. If there is no node at the given path, - * {@link java.util.Optional#empty()} is returned. - * - * @param fullPath full path to the node to check - * @return data if the node is alive, or null - */ - Optional<ModeledCachedNode<T>> getCurrentData(ZPath fullPath); - - /** - * Return the modeled current set of children at the given path, mapped by child name. There are no - * guarantees of accuracy; this is merely the most recent view of the data. - * - * @param fullPath full path to the node to check - * @return a possibly-empty list of children if the node is alive, or null - */ - Map<ZPath, ModeledCachedNode<T>> getCurrentChildren(ZPath fullPath); -} http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCacheEvent.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCacheEvent.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCacheEvent.java deleted file mode 100644 index 469d8d6..0000000 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCacheEvent.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * 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; - -/** - * Abstracts a cache event - */ -public interface ModeledCacheEvent<T> -{ - /** - * The event type - * - * @return event type - */ - ModeledCacheEventType getType(); - - /** - * Cached node if appropriate for the event (i.e. NODE_* events) - * - * @return node - */ - ModeledCachedNode<T> getNode(); -} http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCacheEventType.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCacheEventType.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCacheEventType.java deleted file mode 100644 index bfdf57d..0000000 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCacheEventType.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * 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 enum ModeledCacheEventType -{ - /** - * A child was added to the path - */ - NODE_ADDED, - - /** - * A child's data was changed - */ - NODE_UPDATED, - - /** - * A child was removed from the path - */ - NODE_REMOVED, - - /** - * Called when the connection has changed to {@link org.apache.curator.framework.state.ConnectionState#SUSPENDED} - */ - CONNECTION_SUSPENDED, - - /** - * Called when the connection has changed to {@link org.apache.curator.framework.state.ConnectionState#RECONNECTED} - */ - CONNECTION_RECONNECTED, - - /** - * Called when the connection has changed to {@link org.apache.curator.framework.state.ConnectionState#LOST} - */ - CONNECTION_LOST, - - /** - * Signals that the initial cache has been populated. - */ - INITIALIZED -} http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCacheListener.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCacheListener.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCacheListener.java deleted file mode 100644 index 7b82e72..0000000 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCacheListener.java +++ /dev/null @@ -1,84 +0,0 @@ -/** - * 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 java.util.function.Predicate; - -/** - * Event listener - */ -@FunctionalInterface -public interface ModeledCacheListener<T> -{ - /** - * Receive an event - * - * @param event the event - */ - void event(ModeledCacheEvent<T> event); - - /** - * Wrap this listener with a filter - * - * @param filter test for events. Only events that pass the filter are sent to the listener - * @return filtered version of this listener - */ - static <T> ModeledCacheListener<T> filtered(ModeledCacheListener<T> listener, Predicate<ModeledCacheEvent<T>> filter) - { - return event -> { - if ( filter.test(event) ) - { - listener.event(event); - } - }; - } - - /** - * Filters out all but CRUD events - * - * @return predicate - */ - static <T> Predicate<ModeledCacheEvent<T>> nodeEventFilter() - { - return event -> (event.getType() == ModeledCacheEventType.NODE_ADDED) - || (event.getType() == ModeledCacheEventType.NODE_UPDATED) - || (event.getType() == ModeledCacheEventType.NODE_REMOVED) - ; - } - - /** - * Filters out all but {@link ModeledCacheEventType#NODE_REMOVED} events - * - * @return predicate - */ - static <T> Predicate<ModeledCacheEvent<T>> nodeRemovedFilter() - { - return event -> event.getType() == ModeledCacheEventType.NODE_REMOVED; - } - - /** - * Filters out all but events that have valid model instances - * - * @return predicate - */ - static <T> Predicate<ModeledCacheEvent<T>> hasModelFilter() - { - return event -> (event.getNode() != null) && (event.getNode().getModel() != null); - } -} http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/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 deleted file mode 100644 index a54f7b7..0000000 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledCachedNode.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * 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; - -/** - * Abstracts a cached node - */ -public interface ModeledCachedNode<T> -{ - /** - * The path of the node - * - * @return path - */ - ZPath getPath(); - - /** - * The node's last known stat if available - * - * @return stat - */ - Stat getStat(); - - /** - * The node's current model - * - * @return model - */ - T getModel(); -} http://git-wip-us.apache.org/repos/asf/curator/blob/2cbbf999/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 deleted file mode 100644 index a5fb598..0000000 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/recipes/ModeledNodeCache.java +++ /dev/null @@ -1,91 +0,0 @@ -/** - * 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.listen.Listenable; -import org.apache.curator.framework.recipes.cache.NodeCache; -import org.apache.curator.x.async.modeled.ModelSerializer; -import org.apache.curator.x.async.modeled.details.recipes.ModeledNodeCacheImpl; -import java.io.Closeable; -import java.util.Optional; - -/** - * Wraps a {@link org.apache.curator.framework.recipes.cache.NodeCache} so that - * node data can be viewed as strongly typed models. - */ -public interface ModeledNodeCache<T> extends Closeable -{ - /** - * Return a newly wrapped cache - * - * @param cache the cache to wrap - * @param serializer for the model - * @return new wrapped cache - */ - static <T> ModeledNodeCache<T> wrap(NodeCache cache, ModelSerializer<T> serializer) - { - return new ModeledNodeCacheImpl<>(cache, serializer); - } - - /** - * Return the original cache that was wrapped - * - * @return cache - */ - NodeCache unwrap(); - - /** - * Forwards to {@link org.apache.curator.framework.recipes.cache.NodeCache#start()} - */ - void start(); - - /** - * Forwards to {@link org.apache.curator.framework.recipes.cache.NodeCache#start(boolean)} - */ - void start(boolean buildInitial); - - /** - * Forwards to {@link org.apache.curator.framework.recipes.cache.NodeCache#rebuild()} - */ - void rebuild(); - - /** - * Return the listener container so that you can add/remove listeners. Note: - * {@link org.apache.curator.x.async.modeled.recipes.ModeledCacheEventType#INITIALIZED} - * and {@link org.apache.curator.x.async.modeled.recipes.ModeledCacheEventType#NODE_ADDED} are not - * used. - * - * @return listener container - */ - Listenable<ModeledCacheListener<T>> getListenable(); - - /** - * Return the modeled current data. There are no guarantees of accuracy. This is - * merely the most recent view of the data. If the node does not exist, - * this returns {@link java.util.Optional#empty()} is returned - * - * @return node data - */ - Optional<ModeledCachedNode<T>> getCurrentData(); - - /** - * Forwards to {@link org.apache.curator.framework.recipes.cache.NodeCache#close()} - */ - void close(); -}
