You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@curator.apache.org by ra...@apache.org on 2017/05/04 15:17:45 UTC

curator git commit: Allow type model specs and typed clients to be created in "one shot". This made writing the sub-pub example simpler and easier to understand.

Repository: curator
Updated Branches:
  refs/heads/CURATOR-397 5ac1a3314 -> 1793675c1


Allow type model specs and typed clients to be created in "one shot". This made writing the sub-pub example simpler and easier to understand.


Project: http://git-wip-us.apache.org/repos/asf/curator/repo
Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/1793675c
Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/1793675c
Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/1793675c

Branch: refs/heads/CURATOR-397
Commit: 1793675c136bf0ba89a33f9c5490e9ab5c7f0000
Parents: 5ac1a33
Author: randgalt <ra...@apache.org>
Authored: Thu May 4 10:16:55 2017 -0500
Committer: randgalt <ra...@apache.org>
Committed: Thu May 4 10:16:55 2017 -0500

----------------------------------------------------------------------
 .../src/main/java/pubsub/Clients.java           |  76 +++++++++
 .../src/main/java/pubsub/Publisher.java         | 152 ++++++++++++++++++
 .../src/main/java/pubsub/SubPubTest.java        |   2 -
 .../src/main/java/pubsub/Subscriber.java        |  88 +++++++++++
 .../src/main/java/pubsub/builders/Clients.java  |  60 --------
 .../main/java/pubsub/builders/ModelSpecs.java   |  72 ---------
 .../src/main/java/pubsub/builders/Paths.java    |  49 ------
 .../src/main/java/pubsub/util/Publisher.java    | 154 -------------------
 .../src/main/java/pubsub/util/Subscriber.java   |  90 -----------
 .../x/async/modeled/typed/TypedModelSpec.java   |  16 ++
 .../x/async/modeled/typed/TypedModelSpec10.java |  16 ++
 .../x/async/modeled/typed/TypedModelSpec2.java  |  16 ++
 .../x/async/modeled/typed/TypedModelSpec3.java  |  16 ++
 .../x/async/modeled/typed/TypedModelSpec4.java  |  16 ++
 .../x/async/modeled/typed/TypedModelSpec5.java  |  16 ++
 .../x/async/modeled/typed/TypedModelSpec6.java  |  16 ++
 .../x/async/modeled/typed/TypedModelSpec7.java  |  16 ++
 .../x/async/modeled/typed/TypedModelSpec8.java  |  16 ++
 .../x/async/modeled/typed/TypedModelSpec9.java  |  16 ++
 .../modeled/typed/TypedModeledFramework.java    |  17 ++
 .../modeled/typed/TypedModeledFramework10.java  |  17 ++
 .../modeled/typed/TypedModeledFramework2.java   |  17 ++
 .../modeled/typed/TypedModeledFramework3.java   |  17 ++
 .../modeled/typed/TypedModeledFramework4.java   |  17 ++
 .../modeled/typed/TypedModeledFramework5.java   |  17 ++
 .../modeled/typed/TypedModeledFramework6.java   |  17 ++
 .../modeled/typed/TypedModeledFramework7.java   |  17 ++
 .../modeled/typed/TypedModeledFramework8.java   |  17 ++
 .../modeled/typed/TypedModeledFramework9.java   |  17 ++
 29 files changed, 646 insertions(+), 427 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-examples/src/main/java/pubsub/Clients.java
----------------------------------------------------------------------
diff --git a/curator-examples/src/main/java/pubsub/Clients.java b/curator-examples/src/main/java/pubsub/Clients.java
new file mode 100644
index 0000000..626b675
--- /dev/null
+++ b/curator-examples/src/main/java/pubsub/Clients.java
@@ -0,0 +1,76 @@
+/**
+ * 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 pubsub;
+
+import org.apache.curator.x.async.modeled.JacksonModelSerializer;
+import org.apache.curator.x.async.modeled.ModelSpec;
+import org.apache.curator.x.async.modeled.ModelSpecBuilder;
+import org.apache.curator.x.async.modeled.ModeledFramework;
+import org.apache.curator.x.async.modeled.typed.TypedModeledFramework;
+import org.apache.curator.x.async.modeled.typed.TypedModeledFramework2;
+import org.apache.zookeeper.CreateMode;
+import pubsub.messages.LocationAvailable;
+import pubsub.messages.UserCreated;
+import pubsub.models.Group;
+import pubsub.models.Instance;
+import pubsub.models.InstanceType;
+import pubsub.models.Priority;
+import java.util.concurrent.TimeUnit;
+
+public class Clients
+{
+    /**
+     * A client template for LocationAvailable instances
+     */
+    public static final TypedModeledFramework2<LocationAvailable, Group, Priority> locationAvailableClient = TypedModeledFramework2.from(
+        ModeledFramework.builder(),
+        builder(LocationAvailable.class),
+        "/root/pubsub/messages/locations/{id}/{id}"
+    );
+
+    /**
+     * A client template for UserCreated instances
+     */
+    public static final TypedModeledFramework2<UserCreated, Group, Priority> userCreatedClient = TypedModeledFramework2.from(
+        ModeledFramework.builder(),
+        builder(UserCreated.class),
+        "/root/pubsub//messages/users/{id}/{id}"
+    );
+
+    /**
+     * A client template for Instance instances
+     */
+    public static final TypedModeledFramework<Instance, InstanceType> instanceClient = TypedModeledFramework.from(
+        ModeledFramework.builder(),
+        builder(Instance.class),
+        "/root/pubsub//instances/{id}"
+    );
+
+    private static <T> ModelSpecBuilder<T> builder(Class<T> clazz)
+    {
+        return ModelSpec.builder(JacksonModelSerializer.build(clazz))
+            .withTtl(TimeUnit.MINUTES.toMillis(10)) // for our pub-sub example, messages are valid for 10 minutes
+            .withCreateMode(CreateMode.PERSISTENT_WITH_TTL)
+            ;
+    }
+
+    private Clients()
+    {
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-examples/src/main/java/pubsub/Publisher.java
----------------------------------------------------------------------
diff --git a/curator-examples/src/main/java/pubsub/Publisher.java b/curator-examples/src/main/java/pubsub/Publisher.java
new file mode 100644
index 0000000..e471262
--- /dev/null
+++ b/curator-examples/src/main/java/pubsub/Publisher.java
@@ -0,0 +1,152 @@
+/**
+ * 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 pubsub;
+
+import org.apache.curator.framework.api.transaction.CuratorOp;
+import org.apache.curator.x.async.AsyncCuratorFramework;
+import org.apache.curator.x.async.modeled.ModeledFramework;
+import org.apache.curator.x.async.modeled.typed.TypedModeledFramework2;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import pubsub.messages.LocationAvailable;
+import pubsub.messages.UserCreated;
+import pubsub.models.Group;
+import pubsub.models.Instance;
+import pubsub.models.Message;
+import pubsub.models.Priority;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+public class Publisher
+{
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private final AsyncCuratorFramework client;
+
+    public Publisher(AsyncCuratorFramework client)
+    {
+        this.client = Objects.requireNonNull(client, "client cannot be null");
+    }
+
+    /**
+     * Publish the given instance using the Instance client template
+     *
+     * @param instance instance to publish
+     */
+    public void publishInstance(Instance instance)
+    {
+        ModeledFramework<Instance> resolvedClient = Clients.instanceClient
+            .resolved(client, instance.getType())   // this resolves to the parent path
+            .at(instance);                          // this resolves to a child node - uses the Instance's id because Instance extends NodeName
+        resolvedClient.set(instance).exceptionally(e -> {
+            log.error("Could not publish instance: " + instance, e);
+            return null;
+        });
+    }
+
+    /**
+     * Publish the given instances using the Instance client template in a transaction
+     *
+     * @param instances instances to publish
+     */
+    public void publishInstances(List<Instance> instances)
+    {
+        List<CuratorOp> operations = instances.stream()
+            .map(instance -> Clients.instanceClient
+                .resolved(client, instance.getType())   // this resolves to the parent path
+                .at(instance)                           // this resolves to a child node - uses the Instance's id because Instance extends NodeName
+                .createOp(instance)
+            )
+            .collect(Collectors.toList());
+        client.transaction().forOperations(operations).exceptionally(e -> {
+            log.error("Could not publish instances: " + instances, e);
+            return null;
+        });
+    }
+
+    /**
+     * Publish the given LocationAvailable using the LocationAvailable client template
+     *
+     * @param group group
+     * @param locationAvailable message to publish
+     */
+    public void publishLocationAvailable(Group group, LocationAvailable locationAvailable)
+    {
+        publishMessage(Clients.locationAvailableClient, group, locationAvailable);
+    }
+
+    /**
+     * Publish the given UserCreated using the UserCreated client template
+     *
+     * @param group group
+     * @param userCreated message to publish
+     */
+    public void publishUserCreated(Group group, UserCreated userCreated)
+    {
+        publishMessage(Clients.userCreatedClient, group, userCreated);
+    }
+
+    /**
+     * Publish the given LocationAvailables using the LocationAvailable client template in a transaction
+     *
+     * @param group group
+     * @param locationsAvailable messages to publish
+     */
+    public void publishLocationsAvailable(Group group, List<LocationAvailable> locationsAvailable)
+    {
+        publishMessages(Clients.locationAvailableClient, group, locationsAvailable);
+    }
+
+    /**
+     * Publish the given UserCreateds using the UserCreated client template in a transaction
+     *
+     * @param group group
+     * @param usersCreated messages to publish
+     */
+    public void publishUsersCreated(Group group, List<UserCreated> usersCreated)
+    {
+        publishMessages(Clients.userCreatedClient, group, usersCreated);
+    }
+
+    private <T extends Message> void publishMessage(TypedModeledFramework2<T, Group, Priority> typedClient, Group group, T message)
+    {
+        ModeledFramework<T> resolvedClient = typedClient
+            .resolved(client, group, message.getPriority())
+            .at(message);
+        resolvedClient.set(message).exceptionally(e -> {
+            log.error("Could not publish message: " + message, e);
+            return null;
+        });
+    }
+
+    private <T extends Message> void publishMessages(TypedModeledFramework2<T, Group, Priority> typedClient, Group group, List<T> messages)
+    {
+        List<CuratorOp> operations = messages.stream()
+            .map(message -> typedClient
+                    .resolved(client, group, message.getPriority()) // this resolves to the parent path
+                    .at(message)                                    // this resolves to a child node - uses the Message's id because Message extends NodeName
+                    .createOp(message)
+                )
+            .collect(Collectors.toList());
+        client.transaction().forOperations(operations).exceptionally(e -> {
+            log.error("Could not publish messages: " + messages, e);
+            return null;
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-examples/src/main/java/pubsub/SubPubTest.java
----------------------------------------------------------------------
diff --git a/curator-examples/src/main/java/pubsub/SubPubTest.java b/curator-examples/src/main/java/pubsub/SubPubTest.java
index b5c1629..bddfe8e 100644
--- a/curator-examples/src/main/java/pubsub/SubPubTest.java
+++ b/curator-examples/src/main/java/pubsub/SubPubTest.java
@@ -30,8 +30,6 @@ import pubsub.models.Group;
 import pubsub.models.Instance;
 import pubsub.models.InstanceType;
 import pubsub.models.Priority;
-import pubsub.util.Publisher;
-import pubsub.util.Subscriber;
 import java.io.Closeable;
 import java.io.IOException;
 import java.time.Duration;

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-examples/src/main/java/pubsub/Subscriber.java
----------------------------------------------------------------------
diff --git a/curator-examples/src/main/java/pubsub/Subscriber.java b/curator-examples/src/main/java/pubsub/Subscriber.java
new file mode 100644
index 0000000..df7ee4c
--- /dev/null
+++ b/curator-examples/src/main/java/pubsub/Subscriber.java
@@ -0,0 +1,88 @@
+/**
+ * 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 pubsub;
+
+import org.apache.curator.x.async.AsyncCuratorFramework;
+import org.apache.curator.x.async.modeled.cached.CachedModeledFramework;
+import org.apache.curator.x.async.modeled.typed.TypedModeledFramework2;
+import pubsub.messages.LocationAvailable;
+import pubsub.messages.UserCreated;
+import pubsub.models.Group;
+import pubsub.models.Instance;
+import pubsub.models.InstanceType;
+import pubsub.models.Message;
+import pubsub.models.Priority;
+
+public class Subscriber
+{
+    private final AsyncCuratorFramework client;
+
+    public Subscriber(AsyncCuratorFramework client)
+    {
+        this.client = client;
+    }
+
+    /**
+     * Start a subscriber (a CachedModeledFramework instance) using the LocationAvailable client template
+     *
+     * @param group group to listen for
+     * @param priority priority to listen for
+     * @return CachedModeledFramework instance (already started)
+     */
+    public CachedModeledFramework<LocationAvailable> startLocationAvailableSubscriber(Group group, Priority priority)
+    {
+        return startSubscriber(Clients.locationAvailableClient, group, priority);
+    }
+
+    /**
+     * Start a subscriber (a CachedModeledFramework instance) using the UserCreated client template
+     *
+     * @param group group to listen for
+     * @param priority priority to listen for
+     * @return CachedModeledFramework instance (already started)
+     */
+    public CachedModeledFramework<UserCreated> startUserCreatedSubscriber(Group group, Priority priority)
+    {
+        return startSubscriber(Clients.userCreatedClient, group, priority);
+    }
+
+    /**
+     * Start a subscriber (a CachedModeledFramework instance) using the Instance client template
+     *
+     * @param instanceType type to listen for
+     * @return CachedModeledFramework instance (already started)
+     */
+    public CachedModeledFramework<Instance> startInstanceSubscriber(InstanceType instanceType)
+    {
+        CachedModeledFramework<Instance> resolved = Clients.instanceClient
+            .resolved(client, instanceType) // resolves to the parent path - models are children of this path
+            .cached();                      // makes a cached modeled instance
+        resolved.start();
+        return resolved;
+    }
+
+    private <T extends Message> CachedModeledFramework<T> startSubscriber(TypedModeledFramework2<T, Group, Priority> typedClient, Group group, Priority priority)
+    {
+        CachedModeledFramework<T> resolved = typedClient
+            .resolved(client, group, priority)  // resolves to the parent path - models are children of this path
+            .cached();                          // makes a cached modeled instance
+        resolved.start();
+        return resolved;
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-examples/src/main/java/pubsub/builders/Clients.java
----------------------------------------------------------------------
diff --git a/curator-examples/src/main/java/pubsub/builders/Clients.java b/curator-examples/src/main/java/pubsub/builders/Clients.java
deleted file mode 100644
index c435906..0000000
--- a/curator-examples/src/main/java/pubsub/builders/Clients.java
+++ /dev/null
@@ -1,60 +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 pubsub.builders;
-
-import org.apache.curator.x.async.modeled.ModeledFramework;
-import org.apache.curator.x.async.modeled.typed.TypedModeledFramework;
-import org.apache.curator.x.async.modeled.typed.TypedModeledFramework2;
-import pubsub.messages.LocationAvailable;
-import pubsub.messages.UserCreated;
-import pubsub.models.Group;
-import pubsub.models.Instance;
-import pubsub.models.InstanceType;
-import pubsub.models.Priority;
-
-public class Clients
-{
-    /**
-     * A client template for LocationAvailable instances
-     */
-    public static final TypedModeledFramework2<LocationAvailable, Group, Priority> locationAvailableClient = TypedModeledFramework2.from(
-        ModeledFramework.builder(),             // our client will use only defaults
-        ModelSpecs.locationAvailableModelSpec   // the LocationAvailable model spec
-    );
-
-    /**
-     * A client template for UserCreated instances
-     */
-    public static final TypedModeledFramework2<UserCreated, Group, Priority> userCreatedClient = TypedModeledFramework2.from(
-        ModeledFramework.builder(),             // our client will use only defaults
-        ModelSpecs.userCreatedModelSpec         // the UserCreated model spec
-    );
-
-    /**
-     * A client template for Instance instances
-     */
-    public static final TypedModeledFramework<Instance, InstanceType> instanceClient = TypedModeledFramework.from(
-        ModeledFramework.builder(),             // our client will use only defaults
-        ModelSpecs.instanceModelSpec            // the Instance model spec
-    );
-
-    private Clients()
-    {
-    }
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-examples/src/main/java/pubsub/builders/ModelSpecs.java
----------------------------------------------------------------------
diff --git a/curator-examples/src/main/java/pubsub/builders/ModelSpecs.java b/curator-examples/src/main/java/pubsub/builders/ModelSpecs.java
deleted file mode 100644
index c31b9ae..0000000
--- a/curator-examples/src/main/java/pubsub/builders/ModelSpecs.java
+++ /dev/null
@@ -1,72 +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 pubsub.builders;
-
-import org.apache.curator.x.async.modeled.JacksonModelSerializer;
-import org.apache.curator.x.async.modeled.ModelSpec;
-import org.apache.curator.x.async.modeled.ModelSpecBuilder;
-import org.apache.curator.x.async.modeled.typed.TypedModelSpec;
-import org.apache.curator.x.async.modeled.typed.TypedModelSpec2;
-import org.apache.zookeeper.CreateMode;
-import pubsub.messages.LocationAvailable;
-import pubsub.messages.UserCreated;
-import pubsub.models.Group;
-import pubsub.models.Instance;
-import pubsub.models.InstanceType;
-import pubsub.models.Priority;
-import java.util.concurrent.TimeUnit;
-
-public class ModelSpecs
-{
-    /**
-     * A model spec for LocationAvailable instances
-     */
-    public static final TypedModelSpec2<LocationAvailable, Group, Priority> locationAvailableModelSpec = TypedModelSpec2.from(
-        builder(LocationAvailable.class),   // creates a standard JSON serializer
-        Paths.locationAvailablePath         // use the path for LocationAvailable instances
-    );
-
-    /**
-     * A model spec for UserCreated instances
-     */
-    public static final TypedModelSpec2<UserCreated, Group, Priority> userCreatedModelSpec = TypedModelSpec2.from(
-        builder(UserCreated.class),         // creates a standard JSON serializer
-        Paths.userCreatedPath               // use the path for UserCreated instances
-    );
-
-    /**
-     * A model spec for Instance instances
-     */
-    public static final TypedModelSpec<Instance, InstanceType> instanceModelSpec = TypedModelSpec.from(
-        builder(Instance.class),            // creates a standard JSON serializer
-        Paths.instancesPath                 // use the path for Instance instances
-    );
-
-    private static <T> ModelSpecBuilder<T> builder(Class<T> clazz)
-    {
-        return ModelSpec.builder(JacksonModelSerializer.build(clazz))
-            .withTtl(TimeUnit.MINUTES.toMillis(10)) // for our pub-sub example, messages are valid for 10 minutes
-            .withCreateMode(CreateMode.PERSISTENT_WITH_TTL)
-            ;
-    }
-
-    private ModelSpecs()
-    {
-    }
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-examples/src/main/java/pubsub/builders/Paths.java
----------------------------------------------------------------------
diff --git a/curator-examples/src/main/java/pubsub/builders/Paths.java b/curator-examples/src/main/java/pubsub/builders/Paths.java
deleted file mode 100644
index 84c7932..0000000
--- a/curator-examples/src/main/java/pubsub/builders/Paths.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 pubsub.builders;
-
-import org.apache.curator.x.async.modeled.typed.TypedZPath;
-import org.apache.curator.x.async.modeled.typed.TypedZPath2;
-import pubsub.models.Group;
-import pubsub.models.InstanceType;
-import pubsub.models.Priority;
-
-public class Paths
-{
-    private static final String basePath = "/root/pubsub";
-
-    /**
-     * Represents a path for LocationAvailable models that is parameterized with a Group and a Priority
-     */
-    public static final TypedZPath2<Group, Priority> locationAvailablePath = TypedZPath2.from(basePath + "/messages/locations/{id}/{id}");
-
-    /**
-     * Represents a path for UserCreated models that is parameterized with a Group and a Priority
-     */
-    public static final TypedZPath2<Group, Priority> userCreatedPath = TypedZPath2.from(basePath + "/messages/users/{id}/{id}");
-
-    /**
-     * Represents a path for Instance models that is parameterized with a InstanceType
-     */
-    public static final TypedZPath<InstanceType> instancesPath = TypedZPath.from(basePath + "/instances/{id}");
-
-    private Paths()
-    {
-    }
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-examples/src/main/java/pubsub/util/Publisher.java
----------------------------------------------------------------------
diff --git a/curator-examples/src/main/java/pubsub/util/Publisher.java b/curator-examples/src/main/java/pubsub/util/Publisher.java
deleted file mode 100644
index 9993e28..0000000
--- a/curator-examples/src/main/java/pubsub/util/Publisher.java
+++ /dev/null
@@ -1,154 +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 pubsub.util;
-
-import org.apache.curator.framework.api.transaction.CuratorOp;
-import org.apache.curator.x.async.AsyncCuratorFramework;
-import org.apache.curator.x.async.modeled.ModeledFramework;
-import org.apache.curator.x.async.modeled.typed.TypedModeledFramework2;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import pubsub.messages.LocationAvailable;
-import pubsub.messages.UserCreated;
-import pubsub.models.Group;
-import pubsub.models.Instance;
-import pubsub.models.Message;
-import pubsub.models.Priority;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-import static pubsub.builders.Clients.*;
-
-public class Publisher
-{
-    private final Logger log = LoggerFactory.getLogger(getClass());
-    private final AsyncCuratorFramework client;
-
-    public Publisher(AsyncCuratorFramework client)
-    {
-        this.client = Objects.requireNonNull(client, "client cannot be null");
-    }
-
-    /**
-     * Publish the given instance using the Instance client template
-     *
-     * @param instance instance to publish
-     */
-    public void publishInstance(Instance instance)
-    {
-        ModeledFramework<Instance> resolvedClient = instanceClient
-            .resolved(client, instance.getType())   // this resolves to the parent path
-            .at(instance);                          // this resolves to a child node - uses the Instance's id because Instance extends NodeName
-        resolvedClient.set(instance).exceptionally(e -> {
-            log.error("Could not publish instance: " + instance, e);
-            return null;
-        });
-    }
-
-    /**
-     * Publish the given instances using the Instance client template in a transaction
-     *
-     * @param instances instances to publish
-     */
-    public void publishInstances(List<Instance> instances)
-    {
-        List<CuratorOp> operations = instances.stream()
-            .map(instance -> instanceClient
-                .resolved(client, instance.getType())   // this resolves to the parent path
-                .at(instance)                           // this resolves to a child node - uses the Instance's id because Instance extends NodeName
-                .createOp(instance)
-            )
-            .collect(Collectors.toList());
-        client.transaction().forOperations(operations).exceptionally(e -> {
-            log.error("Could not publish instances: " + instances, e);
-            return null;
-        });
-    }
-
-    /**
-     * Publish the given LocationAvailable using the LocationAvailable client template
-     *
-     * @param group group
-     * @param locationAvailable message to publish
-     */
-    public void publishLocationAvailable(Group group, LocationAvailable locationAvailable)
-    {
-        publishMessage(locationAvailableClient, group, locationAvailable);
-    }
-
-    /**
-     * Publish the given UserCreated using the UserCreated client template
-     *
-     * @param group group
-     * @param userCreated message to publish
-     */
-    public void publishUserCreated(Group group, UserCreated userCreated)
-    {
-        publishMessage(userCreatedClient, group, userCreated);
-    }
-
-    /**
-     * Publish the given LocationAvailables using the LocationAvailable client template in a transaction
-     *
-     * @param group group
-     * @param locationsAvailable messages to publish
-     */
-    public void publishLocationsAvailable(Group group, List<LocationAvailable> locationsAvailable)
-    {
-        publishMessages(locationAvailableClient, group, locationsAvailable);
-    }
-
-    /**
-     * Publish the given UserCreateds using the UserCreated client template in a transaction
-     *
-     * @param group group
-     * @param usersCreated messages to publish
-     */
-    public void publishUsersCreated(Group group, List<UserCreated> usersCreated)
-    {
-        publishMessages(userCreatedClient, group, usersCreated);
-    }
-
-    private <T extends Message> void publishMessage(TypedModeledFramework2<T, Group, Priority> typedClient, Group group, T message)
-    {
-        ModeledFramework<T> resolvedClient = typedClient
-            .resolved(client, group, message.getPriority())
-            .at(message);
-        resolvedClient.set(message).exceptionally(e -> {
-            log.error("Could not publish message: " + message, e);
-            return null;
-        });
-    }
-
-    private <T extends Message> void publishMessages(TypedModeledFramework2<T, Group, Priority> typedClient, Group group, List<T> messages)
-    {
-        List<CuratorOp> operations = messages.stream()
-            .map(message -> typedClient
-                    .resolved(client, group, message.getPriority()) // this resolves to the parent path
-                    .at(message)                                    // this resolves to a child node - uses the Message's id because Message extends NodeName
-                    .createOp(message)
-                )
-            .collect(Collectors.toList());
-        client.transaction().forOperations(operations).exceptionally(e -> {
-            log.error("Could not publish messages: " + messages, e);
-            return null;
-        });
-    }
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-examples/src/main/java/pubsub/util/Subscriber.java
----------------------------------------------------------------------
diff --git a/curator-examples/src/main/java/pubsub/util/Subscriber.java b/curator-examples/src/main/java/pubsub/util/Subscriber.java
deleted file mode 100644
index 06c2cdf..0000000
--- a/curator-examples/src/main/java/pubsub/util/Subscriber.java
+++ /dev/null
@@ -1,90 +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 pubsub.util;
-
-import org.apache.curator.x.async.AsyncCuratorFramework;
-import org.apache.curator.x.async.modeled.cached.CachedModeledFramework;
-import org.apache.curator.x.async.modeled.typed.TypedModeledFramework2;
-import pubsub.messages.LocationAvailable;
-import pubsub.messages.UserCreated;
-import pubsub.models.Group;
-import pubsub.models.Instance;
-import pubsub.models.InstanceType;
-import pubsub.models.Message;
-import pubsub.models.Priority;
-
-import static pubsub.builders.Clients.*;
-
-public class Subscriber
-{
-    private final AsyncCuratorFramework client;
-
-    public Subscriber(AsyncCuratorFramework client)
-    {
-        this.client = client;
-    }
-
-    /**
-     * Start a subscriber (a CachedModeledFramework instance) using the LocationAvailable client template
-     *
-     * @param group group to listen for
-     * @param priority priority to listen for
-     * @return CachedModeledFramework instance (already started)
-     */
-    public CachedModeledFramework<LocationAvailable> startLocationAvailableSubscriber(Group group, Priority priority)
-    {
-        return startSubscriber(locationAvailableClient, group, priority);
-    }
-
-    /**
-     * Start a subscriber (a CachedModeledFramework instance) using the UserCreated client template
-     *
-     * @param group group to listen for
-     * @param priority priority to listen for
-     * @return CachedModeledFramework instance (already started)
-     */
-    public CachedModeledFramework<UserCreated> startUserCreatedSubscriber(Group group, Priority priority)
-    {
-        return startSubscriber(userCreatedClient, group, priority);
-    }
-
-    /**
-     * Start a subscriber (a CachedModeledFramework instance) using the Instance client template
-     *
-     * @param instanceType type to listen for
-     * @return CachedModeledFramework instance (already started)
-     */
-    public CachedModeledFramework<Instance> startInstanceSubscriber(InstanceType instanceType)
-    {
-        CachedModeledFramework<Instance> resolved = instanceClient
-            .resolved(client, instanceType) // resolves to the parent path - models are children of this path
-            .cached();                      // makes a cached modeled instance
-        resolved.start();
-        return resolved;
-    }
-
-    private <T extends Message> CachedModeledFramework<T> startSubscriber(TypedModeledFramework2<T, Group, Priority> typedClient, Group group, Priority priority)
-    {
-        CachedModeledFramework<T> resolved = typedClient
-            .resolved(client, group, priority)  // resolves to the parent path - models are children of this path
-            .cached();                          // makes a cached modeled instance
-        resolved.start();
-        return resolved;
-    }
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec.java
index c19236e..218cfaa 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec.java
@@ -68,4 +68,20 @@ public interface TypedModelSpec<M, P1>
     {
         return p1 -> builder.withPath(path.resolved(p1)).build();
     }
+
+    /**
+     * Return a new TypedModelSpec using the given model spec builder and path. A TypedZPath
+     * is created from the given full path and When
+     * {@link #resolved(Object)} is called the actual model spec is generated with the
+     * resolved path
+     *
+     * @param builder model spec builder
+     * @param path typed path
+     * @return new TypedModelSpec
+     */
+    static <M, P1> TypedModelSpec<M, P1> from(ModelSpecBuilder<M> builder, String path)
+    {
+        TypedZPath<P1> zPath = TypedZPath.from(path);
+        return p1 -> builder.withPath(zPath.resolved(p1)).build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec10.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec10.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec10.java
index 99fa90d..d3241df 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec10.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec10.java
@@ -42,4 +42,20 @@ public interface TypedModelSpec10<M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10>
     {
         return (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) -> builder.withPath(path.resolved(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)).build();
     }
+
+    /**
+     * Return a new TypedModelSpec using the given model spec builder and path. A TypedZPath
+     * is created from the given full path and When
+     * {@link #resolved(Object, Object, Object, Object, Object, Object, Object, Object, Object, Object)} is called the actual model spec is generated with the
+     * resolved path
+     *
+     * @param builder model spec builder
+     * @param path typed path
+     * @return new TypedModelSpec
+     */
+    static <M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> TypedModelSpec10<M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> from(ModelSpecBuilder<M> builder, String path)
+    {
+        TypedZPath10<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> zPath = TypedZPath10.from(path);
+        return (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) -> builder.withPath(zPath.resolved(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)).build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec2.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec2.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec2.java
index 6ae935b..2fe2426 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec2.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec2.java
@@ -42,4 +42,20 @@ public interface TypedModelSpec2<M, P1, P2>
     {
         return (p1, p2) -> builder.withPath(path.resolved(p1, p2)).build();
     }
+
+    /**
+     * Return a new TypedModelSpec using the given model spec builder and path. A TypedZPath
+     * is created from the given full path and When
+     * {@link #resolved(Object, Object)} is called the actual model spec is generated with the
+     * resolved path
+     *
+     * @param builder model spec builder
+     * @param path typed path
+     * @return new TypedModelSpec
+     */
+    static <M, P1, P2> TypedModelSpec2<M, P1, P2> from(ModelSpecBuilder<M> builder, String path)
+    {
+        TypedZPath2<P1, P2> zPath = TypedZPath2.from(path);
+        return (p1, p2) -> builder.withPath(zPath.resolved(p1, p2)).build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec3.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec3.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec3.java
index 5e95b8d..1d9466c 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec3.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec3.java
@@ -42,4 +42,20 @@ public interface TypedModelSpec3<M, P1, P2, P3>
     {
         return (p1, p2, p3) -> builder.withPath(path.resolved(p1, p2, p3)).build();
     }
+
+    /**
+     * Return a new TypedModelSpec using the given model spec builder and path. A TypedZPath
+     * is created from the given full path and When
+     * {@link #resolved(Object, Object, Object)} is called the actual model spec is generated with the
+     * resolved path
+     *
+     * @param builder model spec builder
+     * @param path typed path
+     * @return new TypedModelSpec
+     */
+    static <M, P1, P2, P3> TypedModelSpec3<M, P1, P2, P3> from(ModelSpecBuilder<M> builder, String path)
+    {
+        TypedZPath3<P1, P2, P3> zPath = TypedZPath3.from(path);
+        return (p1, p2, p3) -> builder.withPath(zPath.resolved(p1, p2, p3)).build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec4.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec4.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec4.java
index 8e0f798..ebe6e3d 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec4.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec4.java
@@ -42,4 +42,20 @@ public interface TypedModelSpec4<M, P1, P2, P3, P4>
     {
         return (p1, p2, p3, p4) -> builder.withPath(path.resolved(p1, p2, p3, p4)).build();
     }
+
+    /**
+     * Return a new TypedModelSpec using the given model spec builder and path. A TypedZPath
+     * is created from the given full path and When
+     * {@link #resolved(Object, Object, Object, Object)} is called the actual model spec is generated with the
+     * resolved path
+     *
+     * @param builder model spec builder
+     * @param path typed path
+     * @return new TypedModelSpec
+     */
+    static <M, P1, P2, P3, P4> TypedModelSpec4<M, P1, P2, P3, P4> from(ModelSpecBuilder<M> builder, String path)
+    {
+        TypedZPath4<P1, P2, P3, P4> zPath = TypedZPath4.from(path);
+        return (p1, p2, p3, p4) -> builder.withPath(zPath.resolved(p1, p2, p3, p4)).build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec5.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec5.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec5.java
index 6f750bd..33a6674 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec5.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec5.java
@@ -42,4 +42,20 @@ public interface TypedModelSpec5<M, P1, P2, P3, P4, P5>
     {
         return (p1, p2, p3, p4, p5) -> builder.withPath(path.resolved(p1, p2, p3, p4, p5)).build();
     }
+
+    /**
+     * Return a new TypedModelSpec using the given model spec builder and path. A TypedZPath
+     * is created from the given full path and When
+     * {@link #resolved(Object, Object, Object, Object, Object)} is called the actual model spec is generated with the
+     * resolved path
+     *
+     * @param builder model spec builder
+     * @param path typed path
+     * @return new TypedModelSpec
+     */
+    static <M, P1, P2, P3, P4, P5> TypedModelSpec5<M, P1, P2, P3, P4, P5> from(ModelSpecBuilder<M> builder, String path)
+    {
+        TypedZPath5<P1, P2, P3, P4, P5> zPath = TypedZPath5.from(path);
+        return (p1, p2, p3, p4, p5) -> builder.withPath(zPath.resolved(p1, p2, p3, p4, p5)).build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec6.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec6.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec6.java
index 280fa3d..2e18426 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec6.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec6.java
@@ -42,4 +42,20 @@ public interface TypedModelSpec6<M, P1, P2, P3, P4, P5, P6>
     {
         return (p1, p2, p3, p4, p5, p6) -> builder.withPath(path.resolved(p1, p2, p3, p4, p5, p6)).build();
     }
+
+    /**
+     * Return a new TypedModelSpec using the given model spec builder and path. A TypedZPath
+     * is created from the given full path and When
+     * {@link #resolved(Object, Object, Object, Object, Object, Object)} is called the actual model spec is generated with the
+     * resolved path
+     *
+     * @param builder model spec builder
+     * @param path typed path
+     * @return new TypedModelSpec
+     */
+    static <M, P1, P2, P3, P4, P5, P6> TypedModelSpec6<M, P1, P2, P3, P4, P5, P6> from(ModelSpecBuilder<M> builder, String path)
+    {
+        TypedZPath6<P1, P2, P3, P4, P5, P6> zPath = TypedZPath6.from(path);
+        return (p1, p2, p3, p4, p5, p6) -> builder.withPath(zPath.resolved(p1, p2, p3, p4, p5, p6)).build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec7.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec7.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec7.java
index 09a5cea..81766f9 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec7.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec7.java
@@ -42,4 +42,20 @@ public interface TypedModelSpec7<M, P1, P2, P3, P4, P5, P6, P7>
     {
         return (p1, p2, p3, p4, p5, p6, p7) -> builder.withPath(path.resolved(p1, p2, p3, p4, p5, p6, p7)).build();
     }
+
+    /**
+     * Return a new TypedModelSpec using the given model spec builder and path. A TypedZPath
+     * is created from the given full path and When
+     * {@link #resolved(Object, Object, Object, Object, Object, Object, Object)} is called the actual model spec is generated with the
+     * resolved path
+     *
+     * @param builder model spec builder
+     * @param path typed path
+     * @return new TypedModelSpec
+     */
+    static <M, P1, P2, P3, P4, P5, P6, P7> TypedModelSpec7<M, P1, P2, P3, P4, P5, P6, P7> from(ModelSpecBuilder<M> builder, String path)
+    {
+        TypedZPath7<P1, P2, P3, P4, P5, P6, P7> zPath = TypedZPath7.from(path);
+        return (p1, p2, p3, p4, p5, p6, p7) -> builder.withPath(zPath.resolved(p1, p2, p3, p4, p5, p6, p7)).build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec8.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec8.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec8.java
index a65862a..8ab7ebd 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec8.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec8.java
@@ -42,4 +42,20 @@ public interface TypedModelSpec8<M, P1, P2, P3, P4, P5, P6, P7, P8>
     {
         return (p1, p2, p3, p4, p5, p6, p7, p8) -> builder.withPath(path.resolved(p1, p2, p3, p4, p5, p6, p7, p8)).build();
     }
+
+    /**
+     * Return a new TypedModelSpec using the given model spec builder and path. A TypedZPath
+     * is created from the given full path and When
+     * {@link #resolved(Object, Object, Object, Object, Object, Object, Object, Object)} is called the actual model spec is generated with the
+     * resolved path
+     *
+     * @param builder model spec builder
+     * @param path typed path
+     * @return new TypedModelSpec
+     */
+    static <M, P1, P2, P3, P4, P5, P6, P7, P8> TypedModelSpec8<M, P1, P2, P3, P4, P5, P6, P7, P8> from(ModelSpecBuilder<M> builder, String path)
+    {
+        TypedZPath8<P1, P2, P3, P4, P5, P6, P7, P8> zPath = TypedZPath8.from(path);
+        return (p1, p2, p3, p4, p5, p6, p7, p8) -> builder.withPath(zPath.resolved(p1, p2, p3, p4, p5, p6, p7, p8)).build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec9.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec9.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec9.java
index 8e9e80c..1528d37 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec9.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec9.java
@@ -42,4 +42,20 @@ public interface TypedModelSpec9<M, P1, P2, P3, P4, P5, P6, P7, P8, P9>
     {
         return (p1, p2, p3, p4, p5, p6, p7, p8, p9) -> builder.withPath(path.resolved(p1, p2, p3, p4, p5, p6, p7, p8, p9)).build();
     }
+
+    /**
+     * Return a new TypedModelSpec using the given model spec builder and path. A TypedZPath
+     * is created from the given full path and When
+     * {@link #resolved(Object, Object, Object, Object, Object, Object, Object, Object, Object)} is called the actual model spec is generated with the
+     * resolved path
+     *
+     * @param builder model spec builder
+     * @param path typed path
+     * @return new TypedModelSpec
+     */
+    static <M, P1, P2, P3, P4, P5, P6, P7, P8, P9> TypedModelSpec9<M, P1, P2, P3, P4, P5, P6, P7, P8, P9> from(ModelSpecBuilder<M> builder, String path)
+    {
+        TypedZPath9<P1, P2, P3, P4, P5, P6, P7, P8, P9> zPath = TypedZPath9.from(path);
+        return (p1, p2, p3, p4, p5, p6, p7, p8, p9) -> builder.withPath(zPath.resolved(p1, p2, p3, p4, p5, p6, p7, p8, p9)).build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework.java
index d72514d..196b9b5 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework.java
@@ -19,6 +19,7 @@
 package org.apache.curator.x.async.modeled.typed;
 
 import org.apache.curator.x.async.AsyncCuratorFramework;
+import org.apache.curator.x.async.modeled.ModelSpecBuilder;
 import org.apache.curator.x.async.modeled.ModeledFramework;
 import org.apache.curator.x.async.modeled.ModeledFrameworkBuilder;
 
@@ -73,4 +74,20 @@ public interface TypedModeledFramework<M, P1>
     {
         return (client, p1) -> frameworkBuilder.withClient(client).withModelSpec(modelSpec.resolved(p1)).build();
     }
+
+    /**
+     * Return a new TypedModeledFramework using the given modeled framework builder, model spec builder and a path with ids.
+     * When {@link #resolved(AsyncCuratorFramework, Object)} is called the actual ModeledFramework is generated with the
+     * resolved model spec and resolved path
+     *
+     * @param frameworkBuilder ModeledFrameworkBuilder
+     * @param modelSpecBuilder model spec builder
+     * @param path path with {id} parameters
+     * @return new TypedModeledFramework
+     */
+    static <M, P1> TypedModeledFramework<M, P1> from(ModeledFrameworkBuilder<M> frameworkBuilder, ModelSpecBuilder<M> modelSpecBuilder, String path)
+    {
+        TypedModelSpec<M, P1> typedModelSpec = TypedModelSpec.from(modelSpecBuilder, path);
+        return (client, p1) -> frameworkBuilder.withClient(client).withModelSpec(typedModelSpec.resolved(p1)).build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework10.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework10.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework10.java
index c5631d9..07280b3 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework10.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework10.java
@@ -19,6 +19,7 @@
 package org.apache.curator.x.async.modeled.typed;
 
 import org.apache.curator.x.async.AsyncCuratorFramework;
+import org.apache.curator.x.async.modeled.ModelSpecBuilder;
 import org.apache.curator.x.async.modeled.ModeledFramework;
 import org.apache.curator.x.async.modeled.ModeledFrameworkBuilder;
 
@@ -43,4 +44,20 @@ public interface TypedModeledFramework10<M, P1, P2, P3, P4, P5, P6, P7, P8, P9,
     {
         return (client, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) -> frameworkBuilder.withClient(client).withModelSpec(modelSpec.resolved(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)).build();
     }
+
+    /**
+     * Return a new TypedModeledFramework using the given modeled framework builder, model spec builder and a path with ids.
+     * When {@link #resolved(AsyncCuratorFramework, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object)} is called the actual ModeledFramework is generated with the
+     * resolved model spec and resolved path
+     *
+     * @param frameworkBuilder ModeledFrameworkBuilder
+     * @param modelSpecBuilder model spec builder
+     * @param path path with {id} parameters
+     * @return new TypedModeledFramework
+     */
+    static <M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> TypedModeledFramework10<M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> from(ModeledFrameworkBuilder<M> frameworkBuilder, ModelSpecBuilder<M> modelSpecBuilder, String path)
+    {
+        TypedModelSpec10<M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> typedModelSpec = TypedModelSpec10.from(modelSpecBuilder, path);
+        return (client, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) -> frameworkBuilder.withClient(client).withModelSpec(typedModelSpec.resolved(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)).build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework2.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework2.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework2.java
index e5b912e..520cabc 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework2.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework2.java
@@ -19,6 +19,7 @@
 package org.apache.curator.x.async.modeled.typed;
 
 import org.apache.curator.x.async.AsyncCuratorFramework;
+import org.apache.curator.x.async.modeled.ModelSpecBuilder;
 import org.apache.curator.x.async.modeled.ModeledFramework;
 import org.apache.curator.x.async.modeled.ModeledFrameworkBuilder;
 
@@ -43,4 +44,20 @@ public interface TypedModeledFramework2<M, P1, P2>
     {
         return (client, p1, p2) -> frameworkBuilder.withClient(client).withModelSpec(modelSpec.resolved(p1, p2)).build();
     }
+
+    /**
+     * Return a new TypedModeledFramework using the given modeled framework builder, model spec builder and a path with ids.
+     * When {@link #resolved(AsyncCuratorFramework, Object, Object)} is called the actual ModeledFramework is generated with the
+     * resolved model spec and resolved path
+     *
+     * @param frameworkBuilder ModeledFrameworkBuilder
+     * @param modelSpecBuilder model spec builder
+     * @param path path with {id} parameters
+     * @return new TypedModeledFramework
+     */
+    static <M, P1, P2> TypedModeledFramework2<M, P1, P2> from(ModeledFrameworkBuilder<M> frameworkBuilder, ModelSpecBuilder<M> modelSpecBuilder, String path)
+    {
+        TypedModelSpec2<M, P1, P2> typedModelSpec = TypedModelSpec2.from(modelSpecBuilder, path);
+        return (client, p1, p2) -> frameworkBuilder.withClient(client).withModelSpec(typedModelSpec.resolved(p1, p2)).build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework3.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework3.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework3.java
index 7e7d2d6..9a88461 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework3.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework3.java
@@ -19,6 +19,7 @@
 package org.apache.curator.x.async.modeled.typed;
 
 import org.apache.curator.x.async.AsyncCuratorFramework;
+import org.apache.curator.x.async.modeled.ModelSpecBuilder;
 import org.apache.curator.x.async.modeled.ModeledFramework;
 import org.apache.curator.x.async.modeled.ModeledFrameworkBuilder;
 
@@ -43,4 +44,20 @@ public interface TypedModeledFramework3<M, P1, P2, P3>
     {
         return (client, p1, p2, p3) -> frameworkBuilder.withClient(client).withModelSpec(modelSpec.resolved(p1, p2, p3)).build();
     }
+
+    /**
+     * Return a new TypedModeledFramework using the given modeled framework builder, model spec builder and a path with ids.
+     * When {@link #resolved(AsyncCuratorFramework, Object, Object, Object)} is called the actual ModeledFramework is generated with the
+     * resolved model spec and resolved path
+     *
+     * @param frameworkBuilder ModeledFrameworkBuilder
+     * @param modelSpecBuilder model spec builder
+     * @param path path with {id} parameters
+     * @return new TypedModeledFramework
+     */
+    static <M, P1, P2, P3> TypedModeledFramework3<M, P1, P2, P3> from(ModeledFrameworkBuilder<M> frameworkBuilder, ModelSpecBuilder<M> modelSpecBuilder, String path)
+    {
+        TypedModelSpec3<M, P1, P2, P3> typedModelSpec = TypedModelSpec3.from(modelSpecBuilder, path);
+        return (client, p1, p2, p3) -> frameworkBuilder.withClient(client).withModelSpec(typedModelSpec.resolved(p1, p2, p3)).build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework4.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework4.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework4.java
index 9123f51..60d9db3 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework4.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework4.java
@@ -19,6 +19,7 @@
 package org.apache.curator.x.async.modeled.typed;
 
 import org.apache.curator.x.async.AsyncCuratorFramework;
+import org.apache.curator.x.async.modeled.ModelSpecBuilder;
 import org.apache.curator.x.async.modeled.ModeledFramework;
 import org.apache.curator.x.async.modeled.ModeledFrameworkBuilder;
 
@@ -43,4 +44,20 @@ public interface TypedModeledFramework4<M, P1, P2, P3, P4>
     {
         return (client, p1, p2, p3, p4) -> frameworkBuilder.withClient(client).withModelSpec(modelSpec.resolved(p1, p2, p3, p4)).build();
     }
+
+    /**
+     * Return a new TypedModeledFramework using the given modeled framework builder, model spec builder and a path with ids.
+     * When {@link #resolved(AsyncCuratorFramework, Object, Object, Object, Object)} is called the actual ModeledFramework is generated with the
+     * resolved model spec and resolved path
+     *
+     * @param frameworkBuilder ModeledFrameworkBuilder
+     * @param modelSpecBuilder model spec builder
+     * @param path path with {id} parameters
+     * @return new TypedModeledFramework
+     */
+    static <M, P1, P2, P3, P4> TypedModeledFramework4<M, P1, P2, P3, P4> from(ModeledFrameworkBuilder<M> frameworkBuilder, ModelSpecBuilder<M> modelSpecBuilder, String path)
+    {
+        TypedModelSpec4<M, P1, P2, P3, P4> typedModelSpec = TypedModelSpec4.from(modelSpecBuilder, path);
+        return (client, p1, p2, p3, p4) -> frameworkBuilder.withClient(client).withModelSpec(typedModelSpec.resolved(p1, p2, p3, p4)).build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework5.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework5.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework5.java
index 783f708..2281b91 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework5.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework5.java
@@ -19,6 +19,7 @@
 package org.apache.curator.x.async.modeled.typed;
 
 import org.apache.curator.x.async.AsyncCuratorFramework;
+import org.apache.curator.x.async.modeled.ModelSpecBuilder;
 import org.apache.curator.x.async.modeled.ModeledFramework;
 import org.apache.curator.x.async.modeled.ModeledFrameworkBuilder;
 
@@ -43,4 +44,20 @@ public interface TypedModeledFramework5<M, P1, P2, P3, P4, P5>
     {
         return (client, p1, p2, p3, p4, p5) -> frameworkBuilder.withClient(client).withModelSpec(modelSpec.resolved(p1, p2, p3, p4, p5)).build();
     }
+
+    /**
+     * Return a new TypedModeledFramework using the given modeled framework builder, model spec builder and a path with ids.
+     * When {@link #resolved(AsyncCuratorFramework, Object, Object, Object, Object, Object)} is called the actual ModeledFramework is generated with the
+     * resolved model spec and resolved path
+     *
+     * @param frameworkBuilder ModeledFrameworkBuilder
+     * @param modelSpecBuilder model spec builder
+     * @param path path with {id} parameters
+     * @return new TypedModeledFramework
+     */
+    static <M, P1, P2, P3, P4, P5> TypedModeledFramework5<M, P1, P2, P3, P4, P5> from(ModeledFrameworkBuilder<M> frameworkBuilder, ModelSpecBuilder<M> modelSpecBuilder, String path)
+    {
+        TypedModelSpec5<M, P1, P2, P3, P4, P5> typedModelSpec = TypedModelSpec5.from(modelSpecBuilder, path);
+        return (client, p1, p2, p3, p4, p5) -> frameworkBuilder.withClient(client).withModelSpec(typedModelSpec.resolved(p1, p2, p3, p4, p5)).build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework6.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework6.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework6.java
index 852c47f..e97fef6 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework6.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework6.java
@@ -19,6 +19,7 @@
 package org.apache.curator.x.async.modeled.typed;
 
 import org.apache.curator.x.async.AsyncCuratorFramework;
+import org.apache.curator.x.async.modeled.ModelSpecBuilder;
 import org.apache.curator.x.async.modeled.ModeledFramework;
 import org.apache.curator.x.async.modeled.ModeledFrameworkBuilder;
 
@@ -43,4 +44,20 @@ public interface TypedModeledFramework6<M, P1, P2, P3, P4, P5, P6>
     {
         return (client, p1, p2, p3, p4, p5, p6) -> frameworkBuilder.withClient(client).withModelSpec(modelSpec.resolved(p1, p2, p3, p4, p5, p6)).build();
     }
+
+    /**
+     * Return a new TypedModeledFramework using the given modeled framework builder, model spec builder and a path with ids.
+     * When {@link #resolved(AsyncCuratorFramework, Object, Object, Object, Object, Object, Object)} is called the actual ModeledFramework is generated with the
+     * resolved model spec and resolved path
+     *
+     * @param frameworkBuilder ModeledFrameworkBuilder
+     * @param modelSpecBuilder model spec builder
+     * @param path path with {id} parameters
+     * @return new TypedModeledFramework
+     */
+    static <M, P1, P2, P3, P4, P5, P6> TypedModeledFramework6<M, P1, P2, P3, P4, P5, P6> from(ModeledFrameworkBuilder<M> frameworkBuilder, ModelSpecBuilder<M> modelSpecBuilder, String path)
+    {
+        TypedModelSpec6<M, P1, P2, P3, P4, P5, P6> typedModelSpec = TypedModelSpec6.from(modelSpecBuilder, path);
+        return (client, p1, p2, p3, p4, p5, p6) -> frameworkBuilder.withClient(client).withModelSpec(typedModelSpec.resolved(p1, p2, p3, p4, p5, p6)).build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework7.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework7.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework7.java
index 3da234e..7233b51 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework7.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework7.java
@@ -19,6 +19,7 @@
 package org.apache.curator.x.async.modeled.typed;
 
 import org.apache.curator.x.async.AsyncCuratorFramework;
+import org.apache.curator.x.async.modeled.ModelSpecBuilder;
 import org.apache.curator.x.async.modeled.ModeledFramework;
 import org.apache.curator.x.async.modeled.ModeledFrameworkBuilder;
 
@@ -43,4 +44,20 @@ public interface TypedModeledFramework7<M, P1, P2, P3, P4, P5, P6, P7>
     {
         return (client, p1, p2, p3, p4, p5, p6, p7) -> frameworkBuilder.withClient(client).withModelSpec(modelSpec.resolved(p1, p2, p3, p4, p5, p6, p7)).build();
     }
+
+    /**
+     * Return a new TypedModeledFramework using the given modeled framework builder, model spec builder and a path with ids.
+     * When {@link #resolved(AsyncCuratorFramework, Object, Object, Object, Object, Object, Object, Object)} is called the actual ModeledFramework is generated with the
+     * resolved model spec and resolved path
+     *
+     * @param frameworkBuilder ModeledFrameworkBuilder
+     * @param modelSpecBuilder model spec builder
+     * @param path path with {id} parameters
+     * @return new TypedModeledFramework
+     */
+    static <M, P1, P2, P3, P4, P5, P6, P7> TypedModeledFramework7<M, P1, P2, P3, P4, P5, P6, P7> from(ModeledFrameworkBuilder<M> frameworkBuilder, ModelSpecBuilder<M> modelSpecBuilder, String path)
+    {
+        TypedModelSpec7<M, P1, P2, P3, P4, P5, P6, P7> typedModelSpec = TypedModelSpec7.from(modelSpecBuilder, path);
+        return (client, p1, p2, p3, p4, p5, p6, p7) -> frameworkBuilder.withClient(client).withModelSpec(typedModelSpec.resolved(p1, p2, p3, p4, p5, p6, p7)).build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework8.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework8.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework8.java
index a0c78bd..df6a2e0 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework8.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework8.java
@@ -19,6 +19,7 @@
 package org.apache.curator.x.async.modeled.typed;
 
 import org.apache.curator.x.async.AsyncCuratorFramework;
+import org.apache.curator.x.async.modeled.ModelSpecBuilder;
 import org.apache.curator.x.async.modeled.ModeledFramework;
 import org.apache.curator.x.async.modeled.ModeledFrameworkBuilder;
 
@@ -43,4 +44,20 @@ public interface TypedModeledFramework8<M, P1, P2, P3, P4, P5, P6, P7, P8>
     {
         return (client, p1, p2, p3, p4, p5, p6, p7, p8) -> frameworkBuilder.withClient(client).withModelSpec(modelSpec.resolved(p1, p2, p3, p4, p5, p6, p7, p8)).build();
     }
+
+    /**
+     * Return a new TypedModeledFramework using the given modeled framework builder, model spec builder and a path with ids.
+     * When {@link #resolved(AsyncCuratorFramework, Object, Object, Object, Object, Object, Object, Object, Object)} is called the actual ModeledFramework is generated with the
+     * resolved model spec and resolved path
+     *
+     * @param frameworkBuilder ModeledFrameworkBuilder
+     * @param modelSpecBuilder model spec builder
+     * @param path path with {id} parameters
+     * @return new TypedModeledFramework
+     */
+    static <M, P1, P2, P3, P4, P5, P6, P7, P8> TypedModeledFramework8<M, P1, P2, P3, P4, P5, P6, P7, P8> from(ModeledFrameworkBuilder<M> frameworkBuilder, ModelSpecBuilder<M> modelSpecBuilder, String path)
+    {
+        TypedModelSpec8<M, P1, P2, P3, P4, P5, P6, P7, P8> typedModelSpec = TypedModelSpec8.from(modelSpecBuilder, path);
+        return (client, p1, p2, p3, p4, p5, p6, p7, p8) -> frameworkBuilder.withClient(client).withModelSpec(typedModelSpec.resolved(p1, p2, p3, p4, p5, p6, p7, p8)).build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1793675c/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework9.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework9.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework9.java
index 553cb8c..ce56727 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework9.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework9.java
@@ -19,6 +19,7 @@
 package org.apache.curator.x.async.modeled.typed;
 
 import org.apache.curator.x.async.AsyncCuratorFramework;
+import org.apache.curator.x.async.modeled.ModelSpecBuilder;
 import org.apache.curator.x.async.modeled.ModeledFramework;
 import org.apache.curator.x.async.modeled.ModeledFrameworkBuilder;
 
@@ -43,4 +44,20 @@ public interface TypedModeledFramework9<M, P1, P2, P3, P4, P5, P6, P7, P8, P9>
     {
         return (client, p1, p2, p3, p4, p5, p6, p7, p8, p9) -> frameworkBuilder.withClient(client).withModelSpec(modelSpec.resolved(p1, p2, p3, p4, p5, p6, p7, p8, p9)).build();
     }
+
+    /**
+     * Return a new TypedModeledFramework using the given modeled framework builder, model spec builder and a path with ids.
+     * When {@link #resolved(AsyncCuratorFramework, Object, Object, Object, Object, Object, Object, Object, Object, Object)} is called the actual ModeledFramework is generated with the
+     * resolved model spec and resolved path
+     *
+     * @param frameworkBuilder ModeledFrameworkBuilder
+     * @param modelSpecBuilder model spec builder
+     * @param path path with {id} parameters
+     * @return new TypedModeledFramework
+     */
+    static <M, P1, P2, P3, P4, P5, P6, P7, P8, P9> TypedModeledFramework9<M, P1, P2, P3, P4, P5, P6, P7, P8, P9> from(ModeledFrameworkBuilder<M> frameworkBuilder, ModelSpecBuilder<M> modelSpecBuilder, String path)
+    {
+        TypedModelSpec9<M, P1, P2, P3, P4, P5, P6, P7, P8, P9> typedModelSpec = TypedModelSpec9.from(modelSpecBuilder, path);
+        return (client, p1, p2, p3, p4, p5, p6, p7, p8, p9) -> frameworkBuilder.withClient(client).withModelSpec(typedModelSpec.resolved(p1, p2, p3, p4, p5, p6, p7, p8, p9)).build();
+    }
 }