wip
Project: http://git-wip-us.apache.org/repos/asf/curator/repo Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/ef9df2b7 Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/ef9df2b7 Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/ef9df2b7 Branch: refs/heads/CURATOR-397 Commit: ef9df2b7915ced99e227e2c2cd6f9ec12c7d7309 Parents: 56c6c85 Author: randgalt <[email protected]> Authored: Tue May 2 12:58:50 2017 -0500 Committer: randgalt <[email protected]> Committed: Tue May 2 12:58:50 2017 -0500 ---------------------------------------------------------------------- .../java/modeled/ModeledCuratorExamples.java | 4 +- .../src/main/java/modeled/PersonModelSpec.java | 8 +- .../src/main/java/modeledRegistry/Clients.java | 35 +++ .../main/java/modeledRegistry/ModelSpecs.java | 37 ++++ .../src/main/java/modeledRegistry/Paths.java | 17 ++ .../java/modeledRegistry/RegistryExamples.java | 20 ++ .../main/java/modeledRegistry/models/Cache.java | 24 ++ .../java/modeledRegistry/models/Database.java | 32 +++ .../java/modeledRegistry/models/InstanceId.java | 24 ++ .../java/modeledRegistry/models/Server.java | 25 +++ .../java/modeledRegistry/models/Session.java | 24 ++ .../main/java/modeledRegistry/models/Zone.java | 36 +++ .../x/async/modeled/CuratorModelSpec.java | 118 ---------- .../async/modeled/CuratorModelSpecBuilder.java | 104 --------- .../curator/x/async/modeled/ModelSpec.java | 143 ++++++++++++ .../x/async/modeled/ModelSpecBuilder.java | 136 ++++++++++++ .../async/modeled/ModeledCuratorFramework.java | 35 +-- .../modeled/ModeledCuratorFrameworkBuilder.java | 4 +- .../apache/curator/x/async/modeled/ZPath.java | 31 ++- .../cached/CachedModeledCuratorFramework.java | 14 ++ .../x/async/modeled/cached/ModeledCache.java | 4 +- .../async/modeled/cached/ModeledCachedNode.java | 49 ----- .../curator/x/async/modeled/cached/ZNode.java | 49 +++++ .../CachedModeledCuratorFrameworkImpl.java | 39 ++-- .../modeled/details/CuratorModelSpecImpl.java | 208 ------------------ .../x/async/modeled/details/ModelSpecImpl.java | 217 +++++++++++++++++++ .../async/modeled/details/ModeledCacheImpl.java | 40 +--- .../details/ModeledCuratorFrameworkImpl.java | 62 +++--- .../x/async/modeled/details/ZNodeImpl.java | 38 ++++ .../x/async/modeled/details/ZPathImpl.java | 34 +-- .../x/async/modeled/typed/TypedModelSpec.java | 29 +++ .../x/async/modeled/typed/TypedModelSpec10.java | 23 ++ .../x/async/modeled/typed/TypedModelSpec2.java | 23 ++ .../x/async/modeled/typed/TypedModelSpec3.java | 23 ++ .../x/async/modeled/typed/TypedModelSpec4.java | 23 ++ .../x/async/modeled/typed/TypedModelSpec5.java | 23 ++ .../x/async/modeled/typed/TypedModelSpec6.java | 23 ++ .../x/async/modeled/typed/TypedModelSpec7.java | 23 ++ .../x/async/modeled/typed/TypedModelSpec8.java | 23 ++ .../x/async/modeled/typed/TypedModelSpec9.java | 23 ++ .../modeled/TestModeledCuratorFramework.java | 8 +- .../curator/x/async/modeled/TestZPath.java | 8 +- .../TestCachedModeledCuratorFramework.java | 4 +- 43 files changed, 1241 insertions(+), 626 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-examples/src/main/java/modeled/ModeledCuratorExamples.java ---------------------------------------------------------------------- diff --git a/curator-examples/src/main/java/modeled/ModeledCuratorExamples.java b/curator-examples/src/main/java/modeled/ModeledCuratorExamples.java index aa37ab1..3e0d140 100644 --- a/curator-examples/src/main/java/modeled/ModeledCuratorExamples.java +++ b/curator-examples/src/main/java/modeled/ModeledCuratorExamples.java @@ -19,7 +19,7 @@ package modeled; import org.apache.curator.framework.CuratorFramework; -import org.apache.curator.x.async.modeled.CuratorModelSpec; +import org.apache.curator.x.async.modeled.ModelSpec; import org.apache.curator.x.async.modeled.JacksonModelSerializer; import org.apache.curator.x.async.modeled.ModeledCuratorFramework; import org.apache.curator.x.async.modeled.ZPath; @@ -32,7 +32,7 @@ public class ModeledCuratorExamples JacksonModelSerializer<PersonModel> serializer = JacksonModelSerializer.build(PersonModel.class); // build a model specification - you can pre-build all the model specifications for your app at startup - CuratorModelSpec<PersonModel> modelSpec = CuratorModelSpec.builder(ZPath.parse("/example/path"), serializer).build(); + ModelSpec<PersonModel> modelSpec = ModelSpec.builder(ZPath.parse("/example/path"), serializer).build(); // wrap a CuratorFramework instance so that it can be used "modeled". // do this once and re-use the returned ModeledCuratorFramework instance. http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-examples/src/main/java/modeled/PersonModelSpec.java ---------------------------------------------------------------------- diff --git a/curator-examples/src/main/java/modeled/PersonModelSpec.java b/curator-examples/src/main/java/modeled/PersonModelSpec.java index 3f0198d..7e0d821 100644 --- a/curator-examples/src/main/java/modeled/PersonModelSpec.java +++ b/curator-examples/src/main/java/modeled/PersonModelSpec.java @@ -19,7 +19,7 @@ package modeled; import org.apache.curator.framework.CuratorFramework; -import org.apache.curator.x.async.modeled.CuratorModelSpec; +import org.apache.curator.x.async.modeled.ModelSpec; import org.apache.curator.x.async.modeled.JacksonModelSerializer; import org.apache.curator.x.async.modeled.ModeledCuratorFramework; import org.apache.curator.x.async.modeled.ZPath; @@ -27,7 +27,7 @@ import org.apache.curator.x.async.modeled.ZPath; public class PersonModelSpec { private final CuratorFramework client; - private final CuratorModelSpec<PersonModel> modelSpec; + private final ModelSpec<PersonModel> modelSpec; public PersonModelSpec(CuratorFramework client) { @@ -35,12 +35,12 @@ public class PersonModelSpec JacksonModelSerializer<PersonModel> serializer = JacksonModelSerializer.build(PersonModel.class); ZPath path = ZPath.from("example", ZPath.parameterNodeName(), "path", ZPath.parameterNodeName()); - modelSpec = CuratorModelSpec.builder(path, serializer).build(); + modelSpec = ModelSpec.builder(path, serializer).build(); } public ModeledCuratorFramework<PersonModel> resolved(ContainerType containerType, PersonId personId) { - CuratorModelSpec<PersonModel> resolved = modelSpec.resolved(containerType.getTypeId(), personId.getId()); + ModelSpec<PersonModel> resolved = null;// TODO modelSpec.resolved(containerType.getTypeId(), personId.getId()); return ModeledCuratorFramework.wrap(client, resolved); } } http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-examples/src/main/java/modeledRegistry/Clients.java ---------------------------------------------------------------------- diff --git a/curator-examples/src/main/java/modeledRegistry/Clients.java b/curator-examples/src/main/java/modeledRegistry/Clients.java new file mode 100644 index 0000000..e9071e7 --- /dev/null +++ b/curator-examples/src/main/java/modeledRegistry/Clients.java @@ -0,0 +1,35 @@ +package modeledRegistry; + +import modeledRegistry.models.Cache; +import modeledRegistry.models.Database; +import modeledRegistry.models.InstanceId; +import modeledRegistry.models.Session; +import modeledRegistry.models.Zone; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.x.async.modeled.ModeledCuratorFramework; + +import static modeledRegistry.ModelSpecs.cacheModelSpec; +import static modeledRegistry.ModelSpecs.databaseModelSpec; +import static modeledRegistry.ModelSpecs.sessionModelSpec; + +public class Clients +{ + public static ModeledCuratorFramework<Cache> cacheClient(CuratorFramework client, Zone zone, InstanceId id) + { + return ModeledCuratorFramework.wrap(client, cacheModelSpec.resolved(zone, id)); + } + + public static ModeledCuratorFramework<Session> sessionClient(CuratorFramework client, Zone zone, InstanceId id) + { + return ModeledCuratorFramework.wrap(client, sessionModelSpec.resolved(zone, id)); + } + + public static ModeledCuratorFramework<Database> databaseClient(CuratorFramework client, Zone zone) + { + return ModeledCuratorFramework.wrap(client, databaseModelSpec.resolved(zone)); + } + + private Clients() + { + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-examples/src/main/java/modeledRegistry/ModelSpecs.java ---------------------------------------------------------------------- diff --git a/curator-examples/src/main/java/modeledRegistry/ModelSpecs.java b/curator-examples/src/main/java/modeledRegistry/ModelSpecs.java new file mode 100644 index 0000000..96469cc --- /dev/null +++ b/curator-examples/src/main/java/modeledRegistry/ModelSpecs.java @@ -0,0 +1,37 @@ +package modeledRegistry; + +import modeledRegistry.models.Cache; +import modeledRegistry.models.Database; +import modeledRegistry.models.InstanceId; +import modeledRegistry.models.Session; +import modeledRegistry.models.Zone; +import org.apache.curator.x.async.modeled.JacksonModelSerializer; +import org.apache.curator.x.async.modeled.ModelSpec; +import org.apache.curator.x.async.modeled.typed.TypedModelSpec; +import org.apache.curator.x.async.modeled.typed.TypedModelSpec2; + +import static modeledRegistry.Paths.cachePath; +import static modeledRegistry.Paths.databasePath; +import static modeledRegistry.Paths.sessionPath; + +public class ModelSpecs +{ + public static final TypedModelSpec2<Cache, Zone, InstanceId> cacheModelSpec = TypedModelSpec2.from( + ModelSpec.builder(JacksonModelSerializer.build(Cache.class)).withNodeName(Cache::getId), + cachePath + ); + + public static final TypedModelSpec2<Session, Zone, InstanceId> sessionModelSpec = TypedModelSpec2.from( + ModelSpec.builder(JacksonModelSerializer.build(Session.class)).withNodeName(Session::getId), + sessionPath + ); + + public static final TypedModelSpec<Database, Zone> databaseModelSpec = TypedModelSpec.from( + ModelSpec.builder(JacksonModelSerializer.build(Database.class)).withNodeName(Database::getServerName), + databasePath + ); + + private ModelSpecs() + { + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-examples/src/main/java/modeledRegistry/Paths.java ---------------------------------------------------------------------- diff --git a/curator-examples/src/main/java/modeledRegistry/Paths.java b/curator-examples/src/main/java/modeledRegistry/Paths.java new file mode 100644 index 0000000..de23aa4 --- /dev/null +++ b/curator-examples/src/main/java/modeledRegistry/Paths.java @@ -0,0 +1,17 @@ +package modeledRegistry; + +import modeledRegistry.models.InstanceId; +import modeledRegistry.models.Zone; +import org.apache.curator.x.async.modeled.typed.TypedZPath; +import org.apache.curator.x.async.modeled.typed.TypedZPath2; + +public class Paths +{ + public static final TypedZPath2<Zone, InstanceId> cachePath = TypedZPath2.from("/root/registry/{id}/{id}/caches"); + public static final TypedZPath2<Zone, InstanceId> sessionPath = TypedZPath2.from("/root/registry/{id}/{id}/sessions"); + public static final TypedZPath<Zone> databasePath = TypedZPath.from("/root/registry/{id}/dbs"); + + private Paths() + { + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-examples/src/main/java/modeledRegistry/RegistryExamples.java ---------------------------------------------------------------------- diff --git a/curator-examples/src/main/java/modeledRegistry/RegistryExamples.java b/curator-examples/src/main/java/modeledRegistry/RegistryExamples.java new file mode 100644 index 0000000..c344dd9 --- /dev/null +++ b/curator-examples/src/main/java/modeledRegistry/RegistryExamples.java @@ -0,0 +1,20 @@ +package modeledRegistry; + +import modeledRegistry.models.Database; +import org.apache.curator.x.async.modeled.ModeledCuratorFramework; +import java.util.List; +import java.util.function.Consumer; + +public class RegistryExamples +{ + public static void addDatabase(ModeledCuratorFramework<Database> client, Database database) + { + ModeledCuratorFramework<Database> resolved = client.resolved(database); + resolved.set(database); + } + + public static void getDatabases(ModeledCuratorFramework<Database> client, Consumer<List<Database>> consumer) + { +// client.children().thenCombine(); + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-examples/src/main/java/modeledRegistry/models/Cache.java ---------------------------------------------------------------------- diff --git a/curator-examples/src/main/java/modeledRegistry/models/Cache.java b/curator-examples/src/main/java/modeledRegistry/models/Cache.java new file mode 100644 index 0000000..a148a5f --- /dev/null +++ b/curator-examples/src/main/java/modeledRegistry/models/Cache.java @@ -0,0 +1,24 @@ +package modeledRegistry.models; + +import java.util.UUID; + +public class Cache extends Server +{ + private final int maxObjects; + + public Cache() + { + this(UUID.randomUUID().toString(), "localhost", Integer.MAX_VALUE); + } + + public Cache(String id, String ipAddress, int maxObjects) + { + super(id, ipAddress); + this.maxObjects = maxObjects; + } + + public int getMaxObjects() + { + return maxObjects; + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-examples/src/main/java/modeledRegistry/models/Database.java ---------------------------------------------------------------------- diff --git a/curator-examples/src/main/java/modeledRegistry/models/Database.java b/curator-examples/src/main/java/modeledRegistry/models/Database.java new file mode 100644 index 0000000..681ed34 --- /dev/null +++ b/curator-examples/src/main/java/modeledRegistry/models/Database.java @@ -0,0 +1,32 @@ +package modeledRegistry.models; + +import java.util.Objects; +import java.util.UUID; + +public class Database extends Server +{ + private final String connectionString; + private final String serverName; + + public Database() + { + this(UUID.randomUUID().toString(), "localhost", "", ""); + } + + public Database(String id, String ipAddress, String serverName, String connectionString) + { + super(id, ipAddress); + this.serverName = Objects.requireNonNull(serverName, "serverName cannot be null"); + this.connectionString = Objects.requireNonNull(connectionString, "connectionString cannot be null"); + } + + public String getConnectionString() + { + return connectionString; + } + + public String getServerName() + { + return serverName; + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-examples/src/main/java/modeledRegistry/models/InstanceId.java ---------------------------------------------------------------------- diff --git a/curator-examples/src/main/java/modeledRegistry/models/InstanceId.java b/curator-examples/src/main/java/modeledRegistry/models/InstanceId.java new file mode 100644 index 0000000..24ab98e --- /dev/null +++ b/curator-examples/src/main/java/modeledRegistry/models/InstanceId.java @@ -0,0 +1,24 @@ +package modeledRegistry.models; + +import java.util.Objects; +import java.util.UUID; + +public class InstanceId +{ + private final String id; + + public InstanceId() + { + this(UUID.randomUUID().toString()); + } + + public InstanceId(String id) + { + this.id = Objects.requireNonNull(id, "id cannot be null"); + } + + public String getId() + { + return id; + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-examples/src/main/java/modeledRegistry/models/Server.java ---------------------------------------------------------------------- diff --git a/curator-examples/src/main/java/modeledRegistry/models/Server.java b/curator-examples/src/main/java/modeledRegistry/models/Server.java new file mode 100644 index 0000000..9085b0f --- /dev/null +++ b/curator-examples/src/main/java/modeledRegistry/models/Server.java @@ -0,0 +1,25 @@ +package modeledRegistry.models; + +import java.util.Objects; + +public abstract class Server +{ + private final String id; + private final String ipAddress; + + protected Server(String id, String ipAddress) + { + this.id = Objects.requireNonNull(id, "id cannot be null"); + this.ipAddress = Objects.requireNonNull(ipAddress, "ipAddress cannot be null"); + } + + public String getId() + { + return id; + } + + public String getIpAddress() + { + return ipAddress; + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-examples/src/main/java/modeledRegistry/models/Session.java ---------------------------------------------------------------------- diff --git a/curator-examples/src/main/java/modeledRegistry/models/Session.java b/curator-examples/src/main/java/modeledRegistry/models/Session.java new file mode 100644 index 0000000..230dec2 --- /dev/null +++ b/curator-examples/src/main/java/modeledRegistry/models/Session.java @@ -0,0 +1,24 @@ +package modeledRegistry.models; + +import java.util.UUID; + +public class Session extends Server +{ + private final long ttl; + + public Session() + { + this(UUID.randomUUID().toString(), "localhost", Long.MAX_VALUE); + } + + public Session(String id, String ipAddress, long ttl) + { + super(id, ipAddress); + this.ttl = ttl; + } + + public long getTtl() + { + return ttl; + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-examples/src/main/java/modeledRegistry/models/Zone.java ---------------------------------------------------------------------- diff --git a/curator-examples/src/main/java/modeledRegistry/models/Zone.java b/curator-examples/src/main/java/modeledRegistry/models/Zone.java new file mode 100644 index 0000000..c0f094e --- /dev/null +++ b/curator-examples/src/main/java/modeledRegistry/models/Zone.java @@ -0,0 +1,36 @@ +package modeledRegistry.models; + +import java.util.Objects; +import java.util.UUID; + +public class Zone +{ + private final String id; + private final String name; + + public Zone() + { + this(UUID.randomUUID().toString(), ""); + } + + public Zone(String name) + { + this(UUID.randomUUID().toString(), name); + } + + public Zone(String id, String name) + { + this.id = Objects.requireNonNull(id, "id cannot be null"); + this.name = Objects.requireNonNull(name, "name cannot be null"); + } + + public String getId() + { + return id; + } + + public String getName() + { + return name; + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/CuratorModelSpec.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/CuratorModelSpec.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/CuratorModelSpec.java deleted file mode 100644 index ee1865b..0000000 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/CuratorModelSpec.java +++ /dev/null @@ -1,118 +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 com.google.common.collect.ImmutableSet; -import org.apache.curator.framework.schema.Schema; -import org.apache.curator.x.async.api.CreateOption; -import org.apache.curator.x.async.api.DeleteOption; -import org.apache.zookeeper.CreateMode; -import org.apache.zookeeper.data.ACL; -import java.util.List; -import java.util.Set; - -public interface CuratorModelSpec<T> -{ - Set<CreateOption> defaultCreateOptions = ImmutableSet.of(CreateOption.createParentsAsContainers, CreateOption.setDataIfExists); - Set<DeleteOption> defaultDeleteOptions = ImmutableSet.of(DeleteOption.guaranteed); - - /** - * Start a new CuratorModelBuilder for the given path and serializer. The returned CuratorModelBuilder - * uses {@link #defaultCreateOptions} and {@link #defaultDeleteOptions}, but you can change these - * with builder methods. - * - * @param path path to model - * @param serializer the model's serializer - * @return builder - */ - static <T> CuratorModelSpecBuilder<T> builder(ZPath path, ModelSerializer<T> serializer) - { - return new CuratorModelSpecBuilder<>(path, serializer) - .withCreateOptions(defaultCreateOptions) - .withDeleteOptions(defaultDeleteOptions); - } - - /** - * Return a new CuratorModel instance with all the same options but applying to the given child node of this CuratorModel's - * path. E.g. if this CuratorModel instance applies to "/a/b", calling <code>modeled.at("c")</code> returns an instance that applies to - * "/a/b/c". - * - * @param child child node. - * @return new Modeled Curator instance - */ - CuratorModelSpec<T> at(String child); - - /** - * Return a new CuratorModel instance with all the same options but using the given path. - * - * @param path new path - * @return new Modeled Curator instance - */ - CuratorModelSpec<T> at(ZPath path); - - /** - * Return the model's path - * - * @return path - */ - ZPath path(); - - /** - * Return the model's serializer - * - * @return serializer - */ - ModelSerializer<T> serializer(); - - /** - * Return the model's create mode - * - * @return create mode - */ - CreateMode createMode(); - - /** - * Return the model's ACL list - * - * @return ACL list - */ - List<ACL> aclList(); - - /** - * Return the model's create options - * - * @return create options - */ - Set<CreateOption> createOptions(); - - /** - * Return the model's delete options - * - * @return delete options - */ - Set<DeleteOption> deleteOptions(); - - /** - * Return a Curator schema that validates ZNodes at this model's - * path using this model's values - * - * @return schema - */ - Schema schema(); -} http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/CuratorModelSpecBuilder.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/CuratorModelSpecBuilder.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/CuratorModelSpecBuilder.java deleted file mode 100644 index 1d91784..0000000 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/CuratorModelSpecBuilder.java +++ /dev/null @@ -1,104 +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 com.google.common.collect.ImmutableSet; -import org.apache.curator.x.async.api.CreateOption; -import org.apache.curator.x.async.api.DeleteOption; -import org.apache.curator.x.async.modeled.details.CuratorModelSpecImpl; -import org.apache.zookeeper.CreateMode; -import org.apache.zookeeper.data.ACL; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.Set; - -public class CuratorModelSpecBuilder<T> -{ - private final ZPath path; - private final ModelSerializer<T> serializer; - private CreateMode createMode = CreateMode.PERSISTENT; - private List<ACL> aclList = Collections.emptyList(); - private Set<CreateOption> createOptions = Collections.emptySet(); - private Set<DeleteOption> deleteOptions = Collections.emptySet(); - - /** - * Build a new CuratorModel instance - * - * @return new CuratorModel instance - */ - public CuratorModelSpec<T> build() - { - return new CuratorModelSpecImpl<>(path, serializer, createMode, aclList, createOptions, deleteOptions); - } - - /** - * Use the given createMode for create operations on the Modeled Curator's ZNode - * - * @param createMode create mode - * @return this for chaining - */ - public CuratorModelSpecBuilder<T> withCreateMode(CreateMode createMode) - { - this.createMode = createMode; - return this; - } - - /** - * Use the given aclList for create operations on the Modeled Curator's ZNode - * - * @param aclList ACLs - * @return this for chaining - */ - public CuratorModelSpecBuilder<T> withAclList(List<ACL> aclList) - { - this.aclList = aclList; - return this; - } - - /** - * Use the given create options on the Modeled Curator's ZNode - * - * @param createOptions options - * @return this for chaining - */ - public CuratorModelSpecBuilder<T> withCreateOptions(Set<CreateOption> createOptions) - { - this.createOptions = (createOptions != null) ? ImmutableSet.copyOf(createOptions) : null; - return this; - } - - /** - * Use the given delete options on the Modeled Curator's ZNode - * - * @param deleteOptions options - * @return this for chaining - */ - public CuratorModelSpecBuilder<T> withDeleteOptions(Set<DeleteOption> deleteOptions) - { - this.deleteOptions = (deleteOptions != null) ? ImmutableSet.copyOf(deleteOptions) : null; - return this; - } - - CuratorModelSpecBuilder(ZPath path, ModelSerializer<T> serializer) - { - this.path = Objects.requireNonNull(path, "path cannot be null"); - this.serializer = Objects.requireNonNull(serializer, "serializer cannot be null"); - } -} http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModelSpec.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModelSpec.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModelSpec.java new file mode 100644 index 0000000..cb0f534 --- /dev/null +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModelSpec.java @@ -0,0 +1,143 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.curator.x.async.modeled; + +import com.google.common.collect.ImmutableSet; +import org.apache.curator.framework.schema.Schema; +import org.apache.curator.x.async.api.CreateOption; +import org.apache.curator.x.async.api.DeleteOption; +import org.apache.zookeeper.CreateMode; +import org.apache.zookeeper.data.ACL; +import java.util.List; +import java.util.Set; + +public interface ModelSpec<T> +{ + Set<CreateOption> defaultCreateOptions = ImmutableSet.of(CreateOption.createParentsAsContainers, CreateOption.setDataIfExists); + Set<DeleteOption> defaultDeleteOptions = ImmutableSet.of(DeleteOption.guaranteed); + + /** + * Start a new ModelSpecBuilder for the given path and serializer. The returned ModelSpecBuilder + * uses {@link #defaultCreateOptions} and {@link #defaultDeleteOptions}, but you can change these + * with builder methods. + * + * @param path path to model + * @param serializer the model's serializer + * @return builder + */ + static <T> ModelSpecBuilder<T> builder(ZPath path, ModelSerializer<T> serializer) + { + return new ModelSpecBuilder<>(path, serializer) + .withCreateOptions(defaultCreateOptions) + .withDeleteOptions(defaultDeleteOptions); + } + + /** + * Start a new ModelSpecBuilder for the given serializer. The returned ModelSpecBuilder + * uses {@link #defaultCreateOptions} and {@link #defaultDeleteOptions}, but you can change these + * with builder methods. You must set a path before calling {@link ModelSpecBuilder#build()} + * + * @param serializer the model's serializer + * @return builder + */ + static <T> ModelSpecBuilder<T> builder(ModelSerializer<T> serializer) + { + return new ModelSpecBuilder<>(serializer) + .withCreateOptions(defaultCreateOptions) + .withDeleteOptions(defaultDeleteOptions); + } + + /** + * Return a new CuratorModel instance with all the same options but applying to the given child node of this CuratorModel's + * path. E.g. if this CuratorModel instance applies to "/a/b", calling <code>modeled.at("c")</code> returns an instance that applies to + * "/a/b/c". + * + * @param child child node. + * @return new Modeled Spec instance + */ + ModelSpec<T> at(String child); + + /** + * Return a new CuratorModel instance with all the same options but using the given path. + * + * @param path new path + * @return new Modeled Spec instance + */ + ModelSpec<T> at(ZPath path); + + /** + * Return a new CuratorModel instance with all the same options but using the + * {@link ModelSpecBuilder#nodeName} functor + * to generate the child node's name + * + * @param model model to use to generate the name + * @return new Modeled Spec instance + */ + ModelSpec<T> resolved(T model); + + /** + * Return the model's path + * + * @return path + */ + ZPath path(); + + /** + * Return the model's serializer + * + * @return serializer + */ + ModelSerializer<T> serializer(); + + /** + * Return the model's create mode + * + * @return create mode + */ + CreateMode createMode(); + + /** + * Return the model's ACL list + * + * @return ACL list + */ + List<ACL> aclList(); + + /** + * Return the model's create options + * + * @return create options + */ + Set<CreateOption> createOptions(); + + /** + * Return the model's delete options + * + * @return delete options + */ + Set<DeleteOption> deleteOptions(); + + /** + * Return a Curator schema that validates ZNodes at this model's + * path using this model's values + * + * @return schema + */ + Schema schema(); +} http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModelSpecBuilder.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModelSpecBuilder.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModelSpecBuilder.java new file mode 100644 index 0000000..16e7696 --- /dev/null +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModelSpecBuilder.java @@ -0,0 +1,136 @@ +/** + * 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 com.google.common.collect.ImmutableSet; +import org.apache.curator.x.async.api.CreateOption; +import org.apache.curator.x.async.api.DeleteOption; +import org.apache.curator.x.async.modeled.details.ModelSpecImpl; +import org.apache.zookeeper.CreateMode; +import org.apache.zookeeper.data.ACL; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; + +public class ModelSpecBuilder<T> +{ + private final ModelSerializer<T> serializer; + private ZPath path; + private CreateMode createMode = CreateMode.PERSISTENT; + private List<ACL> aclList = Collections.emptyList(); + private Set<CreateOption> createOptions = Collections.emptySet(); + private Set<DeleteOption> deleteOptions = Collections.emptySet(); + private Function<T, String> nodeName = Object::toString; + + /** + * Build a new ModelSpec instance + * + * @return new ModelSpec instance + */ + public ModelSpec<T> build() + { + return new ModelSpecImpl<>(path, serializer, createMode, aclList, createOptions, deleteOptions, nodeName); + } + + /** + * Use the given createMode for create operations on the Modeled Curator's ZNode + * + * @param createMode create mode + * @return this for chaining + */ + public ModelSpecBuilder<T> withCreateMode(CreateMode createMode) + { + this.createMode = createMode; + return this; + } + + /** + * Use the given aclList for create operations on the Modeled Curator's ZNode + * + * @param aclList ACLs + * @return this for chaining + */ + public ModelSpecBuilder<T> withAclList(List<ACL> aclList) + { + this.aclList = aclList; + return this; + } + + /** + * Use the given create options on the Modeled Curator's ZNode + * + * @param createOptions options + * @return this for chaining + */ + public ModelSpecBuilder<T> withCreateOptions(Set<CreateOption> createOptions) + { + this.createOptions = (createOptions != null) ? ImmutableSet.copyOf(createOptions) : null; + return this; + } + + /** + * Use the given delete options on the Modeled Curator's ZNode + * + * @param deleteOptions options + * @return this for chaining + */ + public ModelSpecBuilder<T> withDeleteOptions(Set<DeleteOption> deleteOptions) + { + this.deleteOptions = (deleteOptions != null) ? ImmutableSet.copyOf(deleteOptions) : null; + return this; + } + + /** + * Functor that returns the node name to use for a model instance. Default is to call + * <code>toString()</code> on the model instance. + * + * @param nodeName naming functor + * @return this for chaining + */ + public ModelSpecBuilder<T> withNodeName(Function<T, String> nodeName) + { + this.nodeName = Objects.requireNonNull(nodeName, "nodeName cannot be null"); + return this; + } + + /** + * Change the model spec's path + * + * @param path new path + * @return this for chaining + */ + public ModelSpecBuilder<T> withPath(ZPath path) + { + this.path = Objects.requireNonNull(path, "path cannot be null"); + return this; + } + + ModelSpecBuilder(ModelSerializer<T> serializer) + { + this.serializer = Objects.requireNonNull(serializer, "serializer cannot be null"); + } + + ModelSpecBuilder(ZPath path, ModelSerializer<T> serializer) + { + this.path = Objects.requireNonNull(path, "path cannot be null"); + this.serializer = Objects.requireNonNull(serializer, "serializer cannot be null"); + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/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 a8e8f5c..85d0e30 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 @@ -25,7 +25,6 @@ import org.apache.curator.x.async.AsyncStage; import org.apache.curator.x.async.modeled.cached.CachedModeledCuratorFramework; import org.apache.zookeeper.data.Stat; import java.util.List; -import java.util.Map; public interface ModeledCuratorFramework<T> { @@ -36,7 +35,7 @@ public interface ModeledCuratorFramework<T> * @param model the model * @return new Modeled Curator instance */ - static <T> ModeledCuratorFramework<T> wrap(CuratorFramework client, CuratorModelSpec<T> model) + static <T> ModeledCuratorFramework<T> wrap(CuratorFramework client, ModelSpec<T> model) { return builder(client, model).build(); } @@ -48,7 +47,7 @@ public interface ModeledCuratorFramework<T> * @param model the model * @return builder */ - static <T> ModeledCuratorFrameworkBuilder<T> builder(CuratorFramework client, CuratorModelSpec<T> model) + static <T> ModeledCuratorFrameworkBuilder<T> builder(CuratorFramework client, ModelSpec<T> model) { return new ModeledCuratorFrameworkBuilder<>(client, model); } @@ -64,7 +63,7 @@ public interface ModeledCuratorFramework<T> CachedModeledCuratorFramework<T> cached(); /** - * Returns the client that was originally passed to {@link #wrap(org.apache.curator.framework.CuratorFramework, CuratorModelSpec)} or + * Returns the client that was originally passed to {@link #wrap(org.apache.curator.framework.CuratorFramework, ModelSpec)} or * the builder. * * @return original client @@ -76,7 +75,7 @@ public interface ModeledCuratorFramework<T> * * @return model */ - CuratorModelSpec<T> modelSpec(); + ModelSpec<T> modelSpec(); /** * Return a new Modeled Curator instance with all the same options but applying to the given child node of this Modeled Curator's @@ -89,6 +88,24 @@ public interface ModeledCuratorFramework<T> ModeledCuratorFramework<T> at(String child); /** + * Return a Modeled Curator instance with all the same options but using the given path. + * + * @param path new path + * @return new Modeled Curator instance + */ + ModeledCuratorFramework<T> at(ZPath path); + + /** + * Return a new Modeled Curator instance with all the same options but using the + * {@link ModelSpecBuilder#nodeName} functor + * to generate the child node's name + * + * @param model model to use to generate the name + * @return new Modeled Curator instance + */ + ModeledCuratorFramework<T> resolved(T model); + + /** * Create (or update depending on build options) a ZNode at this instance's path with a serialized * version of the given model * @@ -181,14 +198,6 @@ public interface ModeledCuratorFramework<T> AsyncStage<List<ZPath>> children(); /** - * Return the children of this instance's path - * - * @return AsyncStage - * @see org.apache.curator.x.async.AsyncStage - */ - AsyncStage<Map<ZPath, AsyncStage<T>>> readChildren(); - - /** * Create operation instance that can be passed among other operations to * {@link #inTransaction(java.util.List)} to be executed as a single transaction. Note: * due to ZooKeeper transaction limits, this is a _not_ a "set or update" operation but only http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModeledCuratorFrameworkBuilder.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModeledCuratorFrameworkBuilder.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModeledCuratorFrameworkBuilder.java index 76926e9..37224ff 100644 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModeledCuratorFrameworkBuilder.java +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ModeledCuratorFrameworkBuilder.java @@ -30,7 +30,7 @@ import java.util.function.UnaryOperator; public class ModeledCuratorFrameworkBuilder<T> { private final CuratorFramework client; - private final CuratorModelSpec<T> model; + private final ModelSpec<T> model; private WatchMode watchMode; private UnaryOperator<WatchedEvent> watcherFilter; private UnhandledErrorListener unhandledErrorListener; @@ -118,7 +118,7 @@ public class ModeledCuratorFrameworkBuilder<T> return this; } - ModeledCuratorFrameworkBuilder(CuratorFramework client, CuratorModelSpec<T> model) + ModeledCuratorFrameworkBuilder(CuratorFramework client, ModelSpec<T> model) { this.client = Objects.requireNonNull(client, "client cannot be null"); this.model = Objects.requireNonNull(model, "model cannot be null"); http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/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 bb251b1..b50bd01 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 @@ -31,6 +31,14 @@ import java.util.regex.Pattern; public interface ZPath { /** + * The special node name that can be used for replacements at runtime + * via {@link #resolved(Object...)} when passed via the various <code>from()</code> methods + */ + String parameterNodeName = System.getProperty("curator-zpath-parameter", ""); // empty paths are illegal so it's useful for this purpose + + String idName = System.getProperty("curator-zpath-id-name", "{id}"); // empty paths are illegal so it's useful for this purpose + + /** * Return the root path: "/" * * @return root path @@ -54,7 +62,7 @@ public interface ZPath /** * Take a ZNode string path and return a ZPath. Each part of the path - * that is <code>{id}</code> is replaced with {@link #parameterNodeName()}. + * that is <code>{id}</code> is replaced with {@link #parameterNodeName}. * E.g. <code>parseWithIds("/one/two/{id}/three/{id}")</code> is the equivalent * of calling <code>ZPath.from("one", "two", parameterNodeName(), "three", parameterNodeName())</code> * @@ -64,7 +72,7 @@ public interface ZPath */ static ZPath parseWithIds(String fullPath) { - return ZPathImpl.parse(fullPath, s -> s.equals("{id}") ? parameterNodeName() : s); + return ZPathImpl.parse(fullPath, s -> s.equals(idName) ? parameterNodeName : s); } /** @@ -134,18 +142,7 @@ public interface ZPath } /** - * Return the special node name that can be used for replacements at runtime - * via {@link #resolved(Object...)} when passed via the various <code>from()</code> methods - * - * @return name - */ - static String parameterNodeName() - { - return ZPathImpl.parameter; - } - - /** - * When creating paths, any node in the path can be set to {@link #parameterNodeName()}. + * When creating paths, any node in the path can be set to {@link #parameterNodeName}. * At runtime, the ZPath can be "resolved" by replacing these nodes with values. * * @param parameters list of replacements. Must have be the same length as the number of @@ -158,7 +155,7 @@ public interface ZPath } /** - * When creating paths, any node in the path can be set to {@link #parameterNodeName()}. + * When creating paths, any node in the path can be set to {@link #parameterNodeName}. * At runtime, the ZPath can be "resolved" by replacing these nodes with values. * * @param parameters list of replacements. Must have be the same length as the number of @@ -169,14 +166,14 @@ public interface ZPath /** * An "auto" resolving version of this ZPath. i.e. if any of the path names is - * the {@link #parameterNodeName()} the ZPath must be resolved. This method + * the {@link #parameterNodeName} the ZPath must be resolved. This method * creates a new ZPath that auto resolves by using the given parameter suppliers * whenever needed. * * @param parameterSuppliers parameter suppliers * @return new auto resolving ZNode * @see #resolved(Object...) - * @see #parameterNodeName() + * @see #parameterNodeName */ ZPath resolving(List<Supplier<Object>> parameterSuppliers); http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/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 index 8718e60..9f417dd 100644 --- 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 @@ -19,6 +19,7 @@ package org.apache.curator.x.async.modeled.cached; import org.apache.curator.x.async.modeled.ModeledCuratorFramework; +import org.apache.curator.x.async.modeled.ZPath; import java.io.Closeable; public interface CachedModeledCuratorFramework<T> extends ModeledCuratorFramework<T>, Closeable @@ -44,5 +45,18 @@ public interface CachedModeledCuratorFramework<T> extends ModeledCuratorFramewor /** * {@inheritDoc} */ + @Override CachedModeledCuratorFramework<T> at(String child); + + /** + * {@inheritDoc} + */ + @Override + CachedModeledCuratorFramework<T> at(ZPath path); + + /** + * {@inheritDoc} + */ + @Override + CachedModeledCuratorFramework<T> resolved(T model); } http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/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 index 84b9898..05886a9 100644 --- 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 @@ -33,7 +33,7 @@ public interface ModeledCache<T> * @param path path to the node to check * @return data if the node is alive, or null */ - Optional<ModeledCachedNode<T>> currentData(ZPath path); + Optional<ZNode<T>> currentData(ZPath path); /** * Return the modeled current set of children at the given path, mapped by child name. There are no @@ -42,7 +42,7 @@ public interface ModeledCache<T> * @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>> currentChildren(ZPath path); + Map<ZPath, ZNode<T>> currentChildren(ZPath path); /** * Return the listener container so that you can add/remove listeners http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/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 deleted file mode 100644 index 68fdadc..0000000 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/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.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 path(); - - /** - * The node's last known stat if available - * - * @return stat - */ - Stat stat(); - - /** - * The node's current model - * - * @return model - */ - T model(); -} http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/ZNode.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/ZNode.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/ZNode.java new file mode 100644 index 0000000..88f3489 --- /dev/null +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/cached/ZNode.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 ZNode<T> +{ + /** + * The path of the node + * + * @return path + */ + ZPath path(); + + /** + * The node's last known stat if available + * + * @return stat + */ + Stat stat(); + + /** + * The node's current model + * + * @return model + */ + T model(); +} http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/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 c45d28b..a48b9bb 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 @@ -24,21 +24,18 @@ 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.api.CreateOption; -import org.apache.curator.x.async.modeled.CuratorModelSpec; +import org.apache.curator.x.async.modeled.ModelSpec; import org.apache.curator.x.async.modeled.ModeledCuratorFramework; +import org.apache.curator.x.async.modeled.cached.ZNode; import org.apache.curator.x.async.modeled.ZPath; 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.Optional; import java.util.Set; -import java.util.stream.Collectors; class CachedModeledCuratorFrameworkImpl<T> implements CachedModeledCuratorFramework<T> { @@ -87,7 +84,7 @@ class CachedModeledCuratorFrameworkImpl<T> implements CachedModeledCuratorFramew } @Override - public CuratorModelSpec<T> modelSpec() + public ModelSpec<T> modelSpec() { return client.modelSpec(); } @@ -99,15 +96,27 @@ class CachedModeledCuratorFrameworkImpl<T> implements CachedModeledCuratorFramew } @Override + public CachedModeledCuratorFramework<T> at(ZPath path) + { + return new CachedModeledCuratorFrameworkImpl<>(client.at(path), cache); + } + + @Override + public CachedModeledCuratorFramework<T> resolved(T model) + { + return new CachedModeledCuratorFrameworkImpl<>(client.resolved(model), cache); + } + + @Override public AsyncStage<String> set(T model) { - return client.set(model); // TODO - update cache? + return client.set(model); } @Override public AsyncStage<String> set(T model, Stat storingStatIn) { - return client.set(model, storingStatIn); // TODO - update cache? + return client.set(model, storingStatIn); } @Override @@ -120,7 +129,7 @@ class CachedModeledCuratorFrameworkImpl<T> implements CachedModeledCuratorFramew public AsyncStage<T> read(Stat storingStatIn) { ZPath path = client.modelSpec().path(); - Optional<ModeledCachedNode<T>> data = cache.currentData(path); + Optional<ZNode<T>> data = cache.currentData(path); return data.map(node -> { if ( storingStatIn != null ) { @@ -158,7 +167,7 @@ class CachedModeledCuratorFrameworkImpl<T> implements CachedModeledCuratorFramew public AsyncStage<Stat> checkExists() { ZPath path = client.modelSpec().path(); - Optional<ModeledCachedNode<T>> data = cache.currentData(path); + Optional<ZNode<T>> data = cache.currentData(path); return data.map(node -> new ModelStage<>(node.stat())).orElseGet(() -> new ModelStage<>((Stat)null)); } @@ -170,16 +179,6 @@ class CachedModeledCuratorFrameworkImpl<T> implements CachedModeledCuratorFramew } @Override - public AsyncStage<Map<ZPath, AsyncStage<T>>> readChildren() - { - Map<ZPath, AsyncStage<T>> map = cache.currentChildren(client.modelSpec().path()).entrySet() - .stream() - .map(entry -> new AbstractMap.SimpleEntry<>(entry.getKey(), new ModelStage<>(entry.getValue().model()))) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - return new ModelStage<>(map); - } - - @Override public CuratorOp createOp(T model) { return client.createOp(model); http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/CuratorModelSpecImpl.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/CuratorModelSpecImpl.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/CuratorModelSpecImpl.java deleted file mode 100644 index 1469222..0000000 --- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/CuratorModelSpecImpl.java +++ /dev/null @@ -1,208 +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; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import org.apache.curator.framework.schema.Schema; -import org.apache.curator.framework.schema.SchemaValidator; -import org.apache.curator.framework.schema.SchemaViolation; -import org.apache.curator.x.async.api.CreateOption; -import org.apache.curator.x.async.api.DeleteOption; -import org.apache.curator.x.async.modeled.CuratorModelSpec; -import org.apache.curator.x.async.modeled.ModelSerializer; -import org.apache.curator.x.async.modeled.ZPath; -import org.apache.zookeeper.CreateMode; -import org.apache.zookeeper.data.ACL; -import java.util.List; -import java.util.Objects; -import java.util.Set; - -public class CuratorModelSpecImpl<T> implements CuratorModelSpec<T>, SchemaValidator -{ - private final ZPath path; - private final ModelSerializer<T> serializer; - private final CreateMode createMode; - private final List<ACL> aclList; - private final Set<CreateOption> createOptions; - private final Set<DeleteOption> deleteOptions; - private final Schema schema; - - public CuratorModelSpecImpl(ZPath path, ModelSerializer<T> serializer, CreateMode createMode, List<ACL> aclList, Set<CreateOption> createOptions, Set<DeleteOption> deleteOptions) - { - this(path, serializer, createMode, aclList, createOptions, deleteOptions, null); - } - - private CuratorModelSpecImpl(ZPath path, ModelSerializer<T> serializer, CreateMode createMode, List<ACL> aclList, Set<CreateOption> createOptions, Set<DeleteOption> deleteOptions, Schema schema) - { - this.path = Objects.requireNonNull(path, "path cannot be null"); - this.serializer = Objects.requireNonNull(serializer, "serializer cannot be null"); - this.createMode = Objects.requireNonNull(createMode, "createMode cannot be null"); - this.aclList = ImmutableList.copyOf(Objects.requireNonNull(aclList, "aclList cannot be null")); - this.createOptions = ImmutableSet.copyOf(Objects.requireNonNull(createOptions, "createOptions cannot be null")); - this.deleteOptions = ImmutableSet.copyOf(Objects.requireNonNull(deleteOptions, "deleteOptions cannot be null")); - - this.schema = (schema != null) ? schema : makeSchema(); // must be last in statement in ctor - } - - @Override - public CuratorModelSpec<T> at(String child) - { - return new CuratorModelSpecImpl<>(path.at(child), serializer, createMode, aclList, createOptions, deleteOptions); - } - - @Override - public CuratorModelSpec<T> at(ZPath newPath) - { - return new CuratorModelSpecImpl<>(newPath, serializer, createMode, aclList, createOptions, deleteOptions); - } - - @Override - public ZPath path() - { - return path; - } - - @Override - public ModelSerializer<T> serializer() - { - return serializer; - } - - @Override - public CreateMode createMode() - { - return createMode; - } - - @Override - public List<ACL> aclList() - { - return aclList; - } - - @Override - public Set<CreateOption> createOptions() - { - return createOptions; - } - - @Override - public Set<DeleteOption> deleteOptions() - { - return deleteOptions; - } - - @Override - public Schema schema() - { - return schema; - } - - @Override - public boolean equals(Object o) - { - if ( this == o ) - { - return true; - } - if ( o == null || getClass() != o.getClass() ) - { - return false; - } - - CuratorModelSpecImpl<?> that = (CuratorModelSpecImpl<?>)o; - - if ( !path.equals(that.path) ) - { - return false; - } - if ( !serializer.equals(that.serializer) ) - { - return false; - } - if ( createMode != that.createMode ) - { - return false; - } - if ( !aclList.equals(that.aclList) ) - { - return false; - } - if ( !createOptions.equals(that.createOptions) ) - { - return false; - } - //noinspection SimplifiableIfStatement - if ( !deleteOptions.equals(that.deleteOptions) ) - { - return false; - } - return schema.equals(that.schema); - } - - @Override - public int hashCode() - { - int result = path.hashCode(); - result = 31 * result + serializer.hashCode(); - result = 31 * result + createMode.hashCode(); - result = 31 * result + aclList.hashCode(); - result = 31 * result + createOptions.hashCode(); - result = 31 * result + deleteOptions.hashCode(); - result = 31 * result + schema.hashCode(); - return result; - } - - @Override - public String toString() - { - return "CuratorModelImpl{" + "path=" + path + ", serializer=" + serializer + ", createMode=" + createMode + ", aclList=" + aclList + ", createOptions=" + createOptions + ", deleteOptions=" + deleteOptions + ", schema=" + schema + '}'; - } - - @Override - public boolean isValid(Schema schema, String path, byte[] data, List<ACL> acl) - { - if ( !acl.equals(aclList) ) - { - throw new SchemaViolation(schema, new SchemaViolation.ViolatorData(path, data, acl), "ACLs do not match model ACLs"); - } - - try - { - serializer.deserialize(data); - } - catch ( RuntimeException e ) - { - throw new SchemaViolation(schema, new SchemaViolation.ViolatorData(path, data, acl), "Data cannot be deserialized into a model"); - } - return true; - } - - private Schema makeSchema() - { - return Schema.builder(path.toSchemaPathPattern()) - .dataValidator(this) - .ephemeral(createMode.isEphemeral() ? Schema.Allowance.MUST : Schema.Allowance.CANNOT) - .canBeDeleted(true) - .sequential(createMode.isSequential() ? Schema.Allowance.MUST : Schema.Allowance.CANNOT) - .watched(Schema.Allowance.CAN) - .build(); - } -} http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModelSpecImpl.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModelSpecImpl.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModelSpecImpl.java new file mode 100644 index 0000000..1ce7134 --- /dev/null +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModelSpecImpl.java @@ -0,0 +1,217 @@ +/** + * 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.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import org.apache.curator.framework.schema.Schema; +import org.apache.curator.framework.schema.SchemaValidator; +import org.apache.curator.framework.schema.SchemaViolation; +import org.apache.curator.x.async.api.CreateOption; +import org.apache.curator.x.async.api.DeleteOption; +import org.apache.curator.x.async.modeled.ModelSpec; +import org.apache.curator.x.async.modeled.ModelSerializer; +import org.apache.curator.x.async.modeled.ZPath; +import org.apache.zookeeper.CreateMode; +import org.apache.zookeeper.data.ACL; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; + +public class ModelSpecImpl<T> implements ModelSpec<T>, SchemaValidator +{ + private final ZPath path; + private final ModelSerializer<T> serializer; + private final CreateMode createMode; + private final List<ACL> aclList; + private final Set<CreateOption> createOptions; + private final Set<DeleteOption> deleteOptions; + private final AtomicReference<Schema> schema = new AtomicReference<>(); + private final Function<T, String> nodeName; + + public ModelSpecImpl(ZPath path, ModelSerializer<T> serializer, CreateMode createMode, List<ACL> aclList, Set<CreateOption> createOptions, Set<DeleteOption> deleteOptions, Function<T, String> nodeName) + { + this.path = Objects.requireNonNull(path, "path cannot be null"); + this.serializer = Objects.requireNonNull(serializer, "serializer cannot be null"); + this.createMode = Objects.requireNonNull(createMode, "createMode cannot be null"); + this.aclList = ImmutableList.copyOf(Objects.requireNonNull(aclList, "aclList cannot be null")); + this.createOptions = ImmutableSet.copyOf(Objects.requireNonNull(createOptions, "createOptions cannot be null")); + this.deleteOptions = ImmutableSet.copyOf(Objects.requireNonNull(deleteOptions, "deleteOptions cannot be null")); + this.nodeName = Objects.requireNonNull(nodeName, "nodeName cannot be null"); + } + + @Override + public ModelSpec<T> at(String child) + { + return at(path.at(child)); + } + + @Override + public ModelSpec<T> resolved(T model) + { + return at(path.at(nodeName.apply(model))); + } + + @Override + public ModelSpec<T> at(ZPath newPath) + { + return new ModelSpecImpl<>(newPath, serializer, createMode, aclList, createOptions, deleteOptions, nodeName); + } + + @Override + public ZPath path() + { + return path; + } + + @Override + public ModelSerializer<T> serializer() + { + return serializer; + } + + @Override + public CreateMode createMode() + { + return createMode; + } + + @Override + public List<ACL> aclList() + { + return aclList; + } + + @Override + public Set<CreateOption> createOptions() + { + return createOptions; + } + + @Override + public Set<DeleteOption> deleteOptions() + { + return deleteOptions; + } + + @Override + public Schema schema() + { + Schema schemaValue = schema.get(); + if ( schemaValue == null ) + { + schemaValue = makeSchema(); + schema.compareAndSet(null, schemaValue); + } + return schemaValue; + } + + @Override + public boolean equals(Object o) + { + if ( this == o ) + { + return true; + } + if ( o == null || getClass() != o.getClass() ) + { + return false; + } + + ModelSpecImpl<?> that = (ModelSpecImpl<?>)o; + + if ( !path.equals(that.path) ) + { + return false; + } + if ( !serializer.equals(that.serializer) ) + { + return false; + } + if ( createMode != that.createMode ) + { + return false; + } + if ( !aclList.equals(that.aclList) ) + { + return false; + } + if ( !createOptions.equals(that.createOptions) ) + { + return false; + } + //noinspection SimplifiableIfStatement + if ( !deleteOptions.equals(that.deleteOptions) ) + { + return false; + } + return schema.equals(that.schema); + } + + @Override + public int hashCode() + { + int result = path.hashCode(); + result = 31 * result + serializer.hashCode(); + result = 31 * result + createMode.hashCode(); + result = 31 * result + aclList.hashCode(); + result = 31 * result + createOptions.hashCode(); + result = 31 * result + deleteOptions.hashCode(); + result = 31 * result + schema.hashCode(); + return result; + } + + @Override + public String toString() + { + return "CuratorModelImpl{" + "path=" + path + ", serializer=" + serializer + ", createMode=" + createMode + ", aclList=" + aclList + ", createOptions=" + createOptions + ", deleteOptions=" + deleteOptions + ", schema=" + schema + '}'; + } + + @Override + public boolean isValid(Schema schema, String path, byte[] data, List<ACL> acl) + { + if ( !acl.equals(aclList) ) + { + throw new SchemaViolation(schema, new SchemaViolation.ViolatorData(path, data, acl), "ACLs do not match model ACLs"); + } + + try + { + serializer.deserialize(data); + } + catch ( RuntimeException e ) + { + throw new SchemaViolation(schema, new SchemaViolation.ViolatorData(path, data, acl), "Data cannot be deserialized into a model"); + } + return true; + } + + private Schema makeSchema() + { + return Schema.builder(path.toSchemaPathPattern()) + .dataValidator(this) + .ephemeral(createMode.isEphemeral() ? Schema.Allowance.MUST : Schema.Allowance.CANNOT) + .canBeDeleted(true) + .sequential(createMode.isSequential() ? Schema.Allowance.MUST : Schema.Allowance.CANNOT) + .watched(Schema.Allowance.CAN) + .build(); + } +} http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/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 index fb4bc70..fd03977 100644 --- 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 @@ -28,7 +28,7 @@ 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.ModeledCacheListener; -import org.apache.curator.x.async.modeled.cached.ModeledCachedNode; +import org.apache.curator.x.async.modeled.cached.ZNode; import org.apache.zookeeper.data.Stat; import java.util.AbstractMap; import java.util.Map; @@ -83,23 +83,23 @@ class ModeledCacheImpl<T> implements TreeCacheListener, ModeledCache<T> } @Override - public Optional<ModeledCachedNode<T>> currentData(ZPath path) + public Optional<ZNode<T>> currentData(ZPath path) { Entry<T> entry = entries.remove(path); if ( entry != null ) { - return Optional.of(new InternalCachedNode<>(path, entry)); + return Optional.of(new ZNodeImpl<>(path, entry.stat, entry.model)); } return Optional.empty(); } @Override - public Map<ZPath, ModeledCachedNode<T>> currentChildren(ZPath path) + public Map<ZPath, ZNode<T>> currentChildren(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()))) + .map(entry -> new AbstractMap.SimpleEntry<>(entry.getKey(), new ZNodeImpl<>(entry.getKey(), entry.getValue().stat, entry.getValue().model))) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); } @@ -157,34 +157,4 @@ class ModeledCacheImpl<T> implements TreeCacheListener, ModeledCache<T> 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 path() - { - return path; - } - - @Override - public Stat stat() - { - return entry.stat; - } - - @Override - public U model() - { - return entry.model; - } - } } http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/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 eaa4f43..202e62f 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 @@ -32,7 +32,7 @@ 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.CuratorModelSpec; +import org.apache.curator.x.async.modeled.ModelSpec; import org.apache.curator.x.async.modeled.ModeledCuratorFramework; import org.apache.curator.x.async.modeled.ZPath; import org.apache.curator.x.async.modeled.cached.CachedModeledCuratorFramework; @@ -40,7 +40,6 @@ import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.data.ACL; import org.apache.zookeeper.data.Stat; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.function.UnaryOperator; @@ -50,14 +49,14 @@ public class ModeledCuratorFrameworkImpl<T> implements ModeledCuratorFramework<T { private final AsyncCuratorFramework client; private final WatchableAsyncCuratorFramework watchableClient; - private final CuratorModelSpec<T> modelSpec; + private final ModelSpec<T> modelSpec; private final WatchMode watchMode; private final UnaryOperator<WatchedEvent> watcherFilter; private final UnhandledErrorListener unhandledErrorListener; private final UnaryOperator<CuratorEvent> resultFilter; private final AsyncCuratorFrameworkDsl dslClient; - public static <T> ModeledCuratorFrameworkImpl<T> build(CuratorFramework client, CuratorModelSpec<T> model, WatchMode watchMode, UnaryOperator<WatchedEvent> watcherFilter, UnhandledErrorListener unhandledErrorListener, UnaryOperator<CuratorEvent> resultFilter) + public static <T> ModeledCuratorFrameworkImpl<T> build(CuratorFramework client, ModelSpec<T> model, WatchMode watchMode, UnaryOperator<WatchedEvent> watcherFilter, UnhandledErrorListener unhandledErrorListener, UnaryOperator<CuratorEvent> resultFilter) { boolean localIsWatched = (watchMode != null); @@ -82,7 +81,7 @@ public class ModeledCuratorFrameworkImpl<T> implements ModeledCuratorFramework<T ); } - private ModeledCuratorFrameworkImpl(AsyncCuratorFramework client, AsyncCuratorFrameworkDsl dslClient, WatchableAsyncCuratorFramework watchableClient, CuratorModelSpec<T> modelSpec, WatchMode watchMode, UnaryOperator<WatchedEvent> watcherFilter, UnhandledErrorListener unhandledErrorListener, UnaryOperator<CuratorEvent> resultFilter) + private ModeledCuratorFrameworkImpl(AsyncCuratorFramework client, AsyncCuratorFrameworkDsl dslClient, WatchableAsyncCuratorFramework watchableClient, ModelSpec<T> modelSpec, WatchMode watchMode, UnaryOperator<WatchedEvent> watcherFilter, UnhandledErrorListener unhandledErrorListener, UnaryOperator<CuratorEvent> resultFilter) { this.client = client; this.dslClient = dslClient; @@ -101,7 +100,7 @@ public class ModeledCuratorFrameworkImpl<T> implements ModeledCuratorFramework<T } @Override - public CuratorModelSpec<T> modelSpec() + public ModelSpec<T> modelSpec() { return modelSpec; } @@ -221,35 +220,46 @@ public class ModeledCuratorFrameworkImpl<T> implements ModeledCuratorFramework<T } @Override - public AsyncStage<Map<ZPath, AsyncStage<T>>> readChildren() + public ModeledCuratorFramework<T> at(String child) { - AsyncStage<List<String>> asyncStage = watchableClient.getChildren().forPath(modelSpec.path().fullPath()); - ModelStage<Map<ZPath, AsyncStage<T>>> modelStage = new ModelStage<>(asyncStage.event()); - asyncStage.whenComplete((children, e) -> { - if ( e != null ) - { - modelStage.completeExceptionally(e); - } - else - { - Map<ZPath, AsyncStage<T>> map = children - .stream() - .collect(Collectors.toMap(name -> modelSpec.path().at(name), name -> at(name).read())); - modelStage.complete(map); - } - }); - return modelStage; + ModelSpec<T> newModelSpec = modelSpec.at(child); + return new ModeledCuratorFrameworkImpl<>( + client, + dslClient, + watchableClient, + newModelSpec, + watchMode, + watcherFilter, + unhandledErrorListener, + resultFilter + ); } @Override - public ModeledCuratorFramework<T> at(String child) + public ModeledCuratorFramework<T> at(ZPath path) + { + ModelSpec<T> newModelSpec = modelSpec.at(path); + return new ModeledCuratorFrameworkImpl<>( + client, + dslClient, + watchableClient, + newModelSpec, + watchMode, + watcherFilter, + unhandledErrorListener, + resultFilter + ); + } + + @Override + public ModeledCuratorFramework<T> resolved(T model) { - CuratorModelSpec<T> childModel = modelSpec.at(child); + ModelSpec<T> newModelSpec = modelSpec.resolved(model); return new ModeledCuratorFrameworkImpl<>( client, dslClient, watchableClient, - childModel, + newModelSpec, watchMode, watcherFilter, unhandledErrorListener, http://git-wip-us.apache.org/repos/asf/curator/blob/ef9df2b7/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ZNodeImpl.java ---------------------------------------------------------------------- diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ZNodeImpl.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ZNodeImpl.java new file mode 100644 index 0000000..1390c8d --- /dev/null +++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ZNodeImpl.java @@ -0,0 +1,38 @@ +package org.apache.curator.x.async.modeled.details; + +import org.apache.curator.x.async.modeled.cached.ZNode; +import org.apache.curator.x.async.modeled.ZPath; +import org.apache.zookeeper.data.Stat; +import java.util.Objects; + +public class ZNodeImpl<T> implements ZNode<T> +{ + private final ZPath path; + private final Stat stat; + private final T model; + + public ZNodeImpl(ZPath path, Stat stat, T model) + { + this.path = Objects.requireNonNull(path, "path cannot be null"); + this.stat = Objects.requireNonNull(stat, "stat cannot be null"); + this.model = Objects.requireNonNull(model, "model cannot be null"); + } + + @Override + public ZPath path() + { + return path; + } + + @Override + public Stat stat() + { + return stat; + } + + @Override + public T model() + { + return model; + } +}
