You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by ni...@apache.org on 2015/08/02 12:39:55 UTC

[3/4] zest-java git commit: ZEST-111; First commit to the Restful Library.

ZEST-111; First commit to the Restful Library.


Project: http://git-wip-us.apache.org/repos/asf/zest-java/repo
Commit: http://git-wip-us.apache.org/repos/asf/zest-java/commit/9304d008
Tree: http://git-wip-us.apache.org/repos/asf/zest-java/tree/9304d008
Diff: http://git-wip-us.apache.org/repos/asf/zest-java/diff/9304d008

Branch: refs/heads/develop
Commit: 9304d0086af9036b6ce14d578badae251e211dff
Parents: 274ae43
Author: Niclas Hedhman <ni...@hedhman.org>
Authored: Sun Aug 2 18:39:27 2015 +0800
Committer: Niclas Hedhman <ni...@hedhman.org>
Committed: Sun Aug 2 18:39:27 2015 +0800

----------------------------------------------------------------------
 .../layered/IllegalLayerAssemblerException.java |  31 ++
 .../layered/LayeredApplicationAssembler.java    | 125 +++++++--
 .../LayeredApplicationAssemblerTest.java        |   1 +
 libraries/restlet/build.gradle                  |  41 +++
 libraries/restlet/dev-status.xml                |  38 +++
 libraries/restlet/src/docs/restlet.txt          |  63 +++++
 .../apache/zest/library/restlet/Command.java    |  29 ++
 .../library/restlet/ConversionException.java    |  29 ++
 .../apache/zest/library/restlet/FormField.java  | 105 +++++++
 .../zest/library/restlet/HasDescription.java    |  31 ++
 .../apache/zest/library/restlet/HasName.java    |  28 ++
 .../apache/zest/library/restlet/RestForm.java   |  53 ++++
 .../apache/zest/library/restlet/RestLink.java   |  31 ++
 .../zest/library/restlet/ZestEntityRestlet.java | 281 +++++++++++++++++++
 .../restlet/assembly/CrudServiceAssembler.java  |  41 +++
 .../restlet/assembly/GenericRestLayer.java      |  36 +++
 .../assembly/RestApplicationAssembler.java      |  86 ++++++
 .../RestletCrudConnectivityAssembler.java       |  61 ++++
 .../assembly/RestletCrudModuleAssembler.java    |  66 +++++
 .../configuration/ConfigurationLayer.java       |  47 ++++
 .../configuration/ConfigurationModule.java      |  45 +++
 .../connectivity/ConnectivityLayer.java         |  41 +++
 .../assembly/connectivity/RestModule.java       |  43 +++
 .../assembly/connectivity/SecurityModule.java   |  37 +++
 .../restlet/assembly/domain/CrudModule.java     |  39 +++
 .../restlet/assembly/domain/DomainLayer.java    |  47 ++++
 .../infrastructue/FileStorageModule.java        |  52 ++++
 .../assembly/infrastructue/IndexingModule.java  |  56 ++++
 .../infrastructue/InfrastructureLayer.java      |  63 +++++
 .../infrastructue/SerializationModule.java      |  56 ++++
 .../assembly/resource/ResourceLayer.java        |  39 +++
 .../zest/library/restlet/crud/EntityList.java   |  33 +++
 .../restlet/crud/EntityListResource.java        | 116 ++++++++
 .../zest/library/restlet/crud/EntityRef.java    |  35 +++
 .../library/restlet/crud/EntityResource.java    | 228 +++++++++++++++
 .../restlet/crud/IdentitySpecification.java     |  44 +++
 .../crud/RepositoryNotFoundException.java       |  29 ++
 .../library/restlet/filters/NameFilter.java     |  41 +++
 .../library/restlet/identity/CanonicalName.java |  56 ++++
 .../restlet/identity/IdentityManager.java       | 163 +++++++++++
 .../identity/IdentityMappingConfiguration.java  |  33 +++
 .../InvalidIdentityFormatException.java         |  29 ++
 .../library/restlet/metainfo/UserIdentity.java  |  66 +++++
 .../restlet/repository/CrudRepository.java      |  49 ++++
 .../library/restlet/repository/EntityName.java  |  64 +++++
 .../repository/EntityTypeDescriptor.java        |  42 +++
 .../repository/MissingRepositoryException.java  |  29 ++
 .../restlet/repository/RepositoryLocator.java   |  58 ++++
 .../repository/SmallCrudRepositoryMixin.java    | 122 ++++++++
 .../restlet/resource/CreationParameterized.java |  33 +++
 .../restlet/resource/CreationResource.java      | 117 ++++++++
 .../resource/DefaultResourceFactoryImpl.java    |  95 +++++++
 .../library/restlet/resource/EntryPoint.java    |  31 ++
 .../restlet/resource/EntryPointResource.java    |  98 +++++++
 .../restlet/resource/NotPresentException.java   |  25 ++
 .../library/restlet/resource/Parameterizer.java |  25 ++
 .../restlet/resource/ResourceBuilder.java       | 173 ++++++++++++
 .../restlet/resource/ResourceFactory.java       |  31 ++
 .../restlet/resource/ServerResource.java        | 109 +++++++
 .../serialization/FormRepresentation.java       | 157 +++++++++++
 .../serialization/JsonRepresentation.java       | 126 +++++++++
 .../restlet/serialization/ZestConverter.java    | 268 ++++++++++++++++++
 ...org.restlet.engine.converter.ConverterHelper |   1 +
 .../apache/zest/library/restlet/Customer.java   |  27 ++
 .../org/apache/zest/library/restlet/Order.java  |  27 ++
 .../zest/library/restlet/OrdersModule.java      |  41 +++
 .../apache/zest/library/restlet/Product.java    |  27 ++
 .../zest/library/restlet/TestApplication.java   |  70 +++++
 settings.gradle                                 |   1 +
 69 files changed, 4436 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/IllegalLayerAssemblerException.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/IllegalLayerAssemblerException.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/IllegalLayerAssemblerException.java
new file mode 100644
index 0000000..b551f2e
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/IllegalLayerAssemblerException.java
@@ -0,0 +1,31 @@
+/*
+ * 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.zest.bootstrap.layered;
+
+import org.apache.zest.bootstrap.AssemblyException;
+
+public class IllegalLayerAssemblerException extends AssemblyException
+{
+    public IllegalLayerAssemblerException( String message )
+    {
+        super( message );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/LayeredApplicationAssembler.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/LayeredApplicationAssembler.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/LayeredApplicationAssembler.java
index 3250de5..536a239 100644
--- a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/LayeredApplicationAssembler.java
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/LayeredApplicationAssembler.java
@@ -20,6 +20,8 @@ package org.apache.zest.bootstrap.layered;
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.HashMap;
 import org.apache.zest.api.activation.ActivationException;
@@ -36,13 +38,15 @@ import org.apache.zest.bootstrap.LayerAssembly;
 public abstract class LayeredApplicationAssembler
     implements ApplicationAssembler
 {
-    protected Application application;
-    protected String name;
-    protected String version;
+    protected final Energy4Java zest;
+    protected final String name;
+    protected final String version;
+
     private final Application.Mode mode;
-    private ApplicationAssembly assembly;
+    private final HashMap<Class<? extends LayerAssembler>, LayerAssembler> assemblers = new HashMap<>();
 
-    private HashMap<Class<? extends LayerAssembler>, LayerAssembler> assemblers = new HashMap<>();
+    private ApplicationAssembly assembly;
+    protected Application application;
 
     public LayeredApplicationAssembler( String name, String version, Application.Mode mode )
         throws AssemblyException
@@ -50,7 +54,12 @@ public abstract class LayeredApplicationAssembler
         this.name = name;
         this.version = version;
         this.mode = mode;
-        Energy4Java zest = new Energy4Java();
+        zest = new Energy4Java();
+    }
+
+    public void initialize()
+        throws AssemblyException
+    {
         ApplicationDescriptor model = zest.newApplicationModel( this );
         onModelCreated( model );
         instantiateApplication( zest, model );
@@ -89,7 +98,7 @@ public abstract class LayeredApplicationAssembler
      * expected to take place.
      * </p>
      *
-     * @param model
+     * @param model The model that has just been created.
      */
     protected void onModelCreated( ApplicationDescriptor model )
     {
@@ -137,15 +146,10 @@ public abstract class LayeredApplicationAssembler
             setNameIfPresent( layerAssemblerClass, classname );
             LayerAssembly layer = assembly.layer( classname );
 
-            LayerAssembler layerAssembler = instantiateAssembler( layerAssemblerClass, layer );
+            LayerAssembler layerAssembler = instantiateLayerAssembler( layerAssemblerClass, layer );
             assemblers.put( layerAssemblerClass, layerAssembler );
-            LayerAssembly assembly = layerAssembler.assemble( layer );
-            if( assembly == null )
-            {
-                // Assume that people forgot, and let's not require a "return layer", since we can do that ourselves.
-                return layer;
-            }
-            return assembly;
+            assembleLayer( layerAssembler, layer );
+            return layer;
         }
         catch( Exception e )
         {
@@ -153,23 +157,96 @@ public abstract class LayeredApplicationAssembler
         }
     }
 
-    private LayerAssembler instantiateAssembler( Class<? extends LayerAssembler> layerAssemblerClass,
-                                                 LayerAssembly layer
+    protected void assembleLayer( LayerAssembler layerAssembler, LayerAssembly layer )
+        throws AssemblyException
+    {
+        layerAssembler.assemble( layer );
+    }
+
+    protected <T extends LayerAssembler> LayerAssembler instantiateLayerAssembler( Class<T> layerAssemblerClass,
+                                                                                   LayerAssembly layer
+    )
+        throws InstantiationException, IllegalAccessException, InvocationTargetException, IllegalLayerAssemblerException
+    {
+        LayerAssembler assembler = createWithFactoryMethod( layerAssemblerClass, layer );
+        if( assembler != null )
+        {
+            return assembler;
+        }
+        assembler = createWithConstructor( layerAssemblerClass, layer );
+        if( assembler != null )
+        {
+            return assembler;
+        }
+        throw new IllegalLayerAssemblerException( "No matching factory method nor constructor found in " + layerAssemblerClass );
+    }
+
+    private LayerAssembler createWithFactoryMethod( Class<? extends LayerAssembler> layerAssemblerClass,
+                                                    LayerAssembly layer
     )
-        throws InstantiationException, IllegalAccessException, java.lang.reflect.InvocationTargetException
+        throws InvocationTargetException, IllegalAccessException
     {
-        LayerAssembler layerAssembler;
         try
         {
-            Constructor<? extends LayerAssembler> assemblyConstructor = layerAssemblerClass.getConstructor( LayerAssembly.class );
-            layerAssembler = assemblyConstructor.newInstance( layer );
+            Method factoryMethod = layerAssemblerClass.getDeclaredMethod( "create", LayerAssembly.class );
+            factoryMethod.setAccessible( true );
+            int modifiers = factoryMethod.getModifiers();
+            if( Modifier.isStatic( modifiers ) && LayerAssembler.class.isAssignableFrom( factoryMethod.getReturnType() ) )
+            {
+                return (LayerAssembler) factoryMethod.invoke( null, layer );
+            }
+        }
+        catch( NoSuchMethodException e )
+        {
+            try
+            {
+                Method factoryMethod = layerAssemblerClass.getDeclaredMethod( "create" );
+                factoryMethod.setAccessible( true );
+                int modifiers = factoryMethod.getModifiers();
+                if( Modifier.isStatic( modifiers ) && LayerAssembler.class.isAssignableFrom( factoryMethod.getReturnType() ) )
+                {
+                    return (LayerAssembler) factoryMethod.invoke( null );
+                }
+            }
+            catch( NoSuchMethodException e1 )
+            {
+            }
+        }
+        return null;
+    }
+
+    private LayerAssembler createWithConstructor( Class<? extends LayerAssembler> layerAssemblerClass,
+                                                  LayerAssembly assembly
+    )
+        throws IllegalAccessException, InvocationTargetException, InstantiationException
+    {
+        try
+        {
+            Constructor<? extends LayerAssembler> constructor = layerAssemblerClass.getConstructor( LayerAssembly.class );
+            if( constructor != null )
+            {
+                constructor.setAccessible( true );
+                return constructor.newInstance( assembly );
+            }
         }
         catch( NoSuchMethodException e )
         {
-            // Use default constructor then.
-            layerAssembler = layerAssemblerClass.newInstance();
+            try
+            {
+                Constructor<? extends LayerAssembler> constructor = layerAssemblerClass.getDeclaredConstructor();
+                if( constructor != null )
+                {
+                    constructor.setAccessible( true );
+                    System.out.println(constructor);
+                    return constructor.newInstance();
+                }
+            }
+            catch( NoSuchMethodException e1 )
+            {
+                return null;
+            }
         }
-        return layerAssembler;
+        return null;
     }
 
     static void setNameIfPresent( Class<?> clazz, String classname )

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/core/bootstrap/src/test/java/org/apache/zest/bootstrap/assembly/LayeredApplicationAssemblerTest.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/test/java/org/apache/zest/bootstrap/assembly/LayeredApplicationAssemblerTest.java b/core/bootstrap/src/test/java/org/apache/zest/bootstrap/assembly/LayeredApplicationAssemblerTest.java
index 8529ec9..eab911a 100644
--- a/core/bootstrap/src/test/java/org/apache/zest/bootstrap/assembly/LayeredApplicationAssemblerTest.java
+++ b/core/bootstrap/src/test/java/org/apache/zest/bootstrap/assembly/LayeredApplicationAssemblerTest.java
@@ -33,6 +33,7 @@ public class LayeredApplicationAssemblerTest
         throws AssemblyException, ActivationException
     {
         TestApplication assembler = new TestApplication( "Test Application", "1.0.1", Application.Mode.test );
+        assembler.initialize();
         assembler.start();
 
         assertThat( assembler.application().name(), equalTo("Test Application") );

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/build.gradle
----------------------------------------------------------------------
diff --git a/libraries/restlet/build.gradle b/libraries/restlet/build.gradle
new file mode 100644
index 0000000..2b4a66c
--- /dev/null
+++ b/libraries/restlet/build.gradle
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ *
+ */
+
+description = "Apache Zestâ„¢ Restlet Library provides utomatic CRUD resources as well as custom resources integrated to Zest."
+
+jar { manifest { name = "Apache Zestâ„¢ Library - Restlet" } }
+
+dependencies {
+
+  compile project( ":org.apache.zest.core:org.apache.zest.core.api" )
+  compile project( ":org.apache.zest.core:org.apache.zest.core.spi" )
+  compile project( ":org.apache.zest.core:org.apache.zest.core.bootstrap" )
+  compile project( ':org.apache.zest.extensions:org.apache.zest.extension.valueserialization-jackson' )
+
+  compile libraries.restlet
+  compile libraries.servlet_api
+
+  testCompile project( ":org.apache.zest.core:org.apache.zest.core.testsupport" )
+  testCompile project( ":org.apache.zest.libraries:org.apache.zest.library.http" )
+  testCompile libraries.http_client
+
+  testRuntime project( ":org.apache.zest.core:org.apache.zest.core.runtime" )
+  testRuntime libraries.logback
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/dev-status.xml
----------------------------------------------------------------------
diff --git a/libraries/restlet/dev-status.xml b/libraries/restlet/dev-status.xml
new file mode 100644
index 0000000..8fb2e8a
--- /dev/null
+++ b/libraries/restlet/dev-status.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  ~ 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.
+  ~
+  -->
+<module xmlns="http://zest.apache.org/schemas/2008/dev-status/1"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://zest.apache.org/schemas/2008/dev-status/1
+        http://zest.apache.org/schemas/2008/dev-status/1/dev-status.xsd">
+  <status>
+    <!--none,early,beta,stable,mature-->
+    <codebase>beta</codebase>
+
+    <!-- none, brief, good, complete -->
+    <documentation>brief</documentation>
+
+    <!-- none, some, good, complete -->
+    <unittests>none</unittests>
+  </status>
+  <licenses>
+    <license>ALv2</license>
+  </licenses>
+</module>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/docs/restlet.txt
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/docs/restlet.txt b/libraries/restlet/src/docs/restlet.txt
new file mode 100644
index 0000000..21abd33
--- /dev/null
+++ b/libraries/restlet/src/docs/restlet.txt
@@ -0,0 +1,63 @@
+///////////////////////////////////////////////////////////////
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+///////////////////////////////////////////////////////////////
+
+[[library-restlet, Rsstlet Library]]
+= Restlet Support =
+
+[devstatus]
+--------------
+source=libraries/restlet/dev-status.xml
+--------------
+
+The Restlet Support Library has support to expose CRUD operations directly
+as well as regular Rest resources.
+
+include::../../build/docs/buildinfo/artifact.txt[]
+
+This library leverages +restlet.org+ which has a very neat way to map resources
+to URIs, and flexible ways to be served the requests. This library defines
+all the plumbing needed to set up Restlet, map resources to URIs, convert
+Zest ValueComposites to resource representations (such as JSON) and
+create a fully HATEOAS environment, with single bookmarkable URI.
+
+To set up the Restlet Connectivity Module, it is recommended to use the provided
++Assembler+ for it;
+
+
+[[library-restlet-resource-binding, Restlet Resource Binding]]
+== Resource Binding ==
+REST defines that all URLs are *resources* and that a known, small set of
+operations can be done on those resources.
+
+
+
+== CRUD Repository ==
+This library provides a +CrudRepository+ which simplifies accessing entities
+directly from the Rest module. This is implemented by using the
+<<library-restlet-resource-binding, Resource Binding>> above.
+
+It also requires that one or more Crud Modules are defined. These are typically
+either in the domain layer directly, or in the layer above (some call that the
+service layer). There is a RestletCrudModuleAssembler that helps set up such
+module. Typical setup is like this;
+
+
+
+
+

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/Command.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/Command.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/Command.java
new file mode 100644
index 0000000..ab63a98
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/Command.java
@@ -0,0 +1,29 @@
+/*
+ * 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.zest.library.restlet;
+
+import org.apache.zest.api.property.Property;
+
+public interface Command
+{
+    Property<String> name();
+
+    Property<RestForm> form();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/ConversionException.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/ConversionException.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/ConversionException.java
new file mode 100644
index 0000000..fe74ad9
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/ConversionException.java
@@ -0,0 +1,29 @@
+/*
+ * 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.zest.library.restlet;
+
+public class ConversionException extends RuntimeException
+{
+    public ConversionException( String entityAsText )
+    {
+        super( "Unable to convert REST entity: " + entityAsText );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/FormField.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/FormField.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/FormField.java
new file mode 100644
index 0000000..3279900
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/FormField.java
@@ -0,0 +1,105 @@
+/*
+ * 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.zest.library.restlet;
+
+import java.util.Map;
+import java.util.Objects;
+import org.apache.zest.api.common.Optional;
+import org.apache.zest.api.common.UseDefaults;
+import org.apache.zest.api.mixin.Mixins;
+import org.apache.zest.api.property.Property;
+
+@Mixins( FormField.Mixin.class )
+public interface FormField extends HasName
+{
+    String TEXT = "TEXT";
+
+    Property<String> type();
+
+    @Optional
+    @UseDefaults
+    Property<String> value();
+
+    Map.Entry<String,String> toMapEntry();
+
+    abstract class Mixin
+        implements FormField
+    {
+        @Override
+        public Map.Entry<String, String> toMapEntry()
+        {
+            return new StringMapEntry( name().get(), value().get() );
+        }
+    }
+
+    class StringMapEntry implements Map.Entry<String, String>
+    {
+        private final String key;
+        private final String value;
+
+        public StringMapEntry( String key, String value )
+        {
+            this.key = key;
+            this.value = value;
+        }
+
+        @Override
+        public String getKey()
+        {
+            return key;
+        }
+
+        @Override
+        public String getValue()
+        {
+            return value;
+        }
+
+        @Override
+        public String setValue( String value )
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean equals( Object o )
+        {
+            if( this == o )
+            {
+                return true;
+            }
+            if( !( o instanceof StringMapEntry ) )
+            {
+                return false;
+            }
+            StringMapEntry miniMap = (StringMapEntry) o;
+            return Objects.equals( key, miniMap.key ) &&
+                   Objects.equals( value, miniMap.value );
+        }
+
+        @Override
+        public int hashCode()
+        {
+            return Objects.hash( key, value );
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/HasDescription.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/HasDescription.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/HasDescription.java
new file mode 100644
index 0000000..f113148
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/HasDescription.java
@@ -0,0 +1,31 @@
+/*
+ * 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.zest.library.restlet;
+
+import org.apache.zest.api.common.Optional;
+import org.apache.zest.api.common.UseDefaults;
+import org.apache.zest.api.property.Property;
+
+public interface HasDescription
+{
+    @Optional @UseDefaults
+    Property<String> description();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/HasName.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/HasName.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/HasName.java
new file mode 100644
index 0000000..e79469e
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/HasName.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.zest.library.restlet;
+
+import org.apache.zest.api.property.Property;
+
+public interface HasName
+{
+    Property<String> name();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/RestForm.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/RestForm.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/RestForm.java
new file mode 100644
index 0000000..d3f1f57
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/RestForm.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.zest.library.restlet;
+
+import java.util.List;
+import org.apache.zest.api.common.Optional;
+import org.apache.zest.api.mixin.Mixins;
+import org.apache.zest.api.property.Property;
+import org.apache.zest.library.restlet.filters.NameFilter;
+
+@Mixins( RestForm.Mixin.class )
+public interface RestForm
+{
+    FormField field( String name );
+
+    @Optional
+    Property<RestLink> link();
+
+    Property<List<FormField>> fields();
+
+    abstract class Mixin
+        implements RestForm
+    {
+        @Override
+        public FormField field( String name )
+        {
+            java.util.Optional<FormField> exists = fields().get().stream().filter( new NameFilter( name ) ).findFirst();
+            if( exists.isPresent() )
+            {
+                return exists.get();
+            }
+            return null;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/RestLink.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/RestLink.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/RestLink.java
new file mode 100644
index 0000000..4dc03ce
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/RestLink.java
@@ -0,0 +1,31 @@
+/*
+ * 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.zest.library.restlet;
+
+import org.apache.zest.api.common.Optional;
+import org.apache.zest.api.property.Property;
+
+public interface RestLink extends HasDescription
+{
+    Property<String> method();
+
+    Property<String> path();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/ZestEntityRestlet.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/ZestEntityRestlet.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/ZestEntityRestlet.java
new file mode 100644
index 0000000..94efac3
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/ZestEntityRestlet.java
@@ -0,0 +1,281 @@
+/*
+ * 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.zest.library.restlet;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+import org.apache.zest.api.common.Optional;
+import org.apache.zest.api.entity.EntityComposite;
+import org.apache.zest.api.entity.Identity;
+import org.apache.zest.api.injection.scope.Service;
+import org.apache.zest.api.injection.scope.Structure;
+import org.apache.zest.api.injection.scope.Uses;
+import org.apache.zest.api.unitofwork.NoSuchEntityException;
+import org.apache.zest.api.unitofwork.UnitOfWork;
+import org.apache.zest.api.unitofwork.UnitOfWorkFactory;
+import org.apache.zest.api.usecase.Usecase;
+import org.apache.zest.api.usecase.UsecaseBuilder;
+import org.apache.zest.api.value.ValueBuilder;
+import org.apache.zest.api.value.ValueBuilderFactory;
+import org.apache.zest.library.restlet.metainfo.UserIdentity;
+import org.apache.zest.library.restlet.repository.RepositoryLocator;
+import org.apache.zest.library.restlet.resource.NotPresentException;
+import org.apache.zest.library.restlet.resource.ResourceFactory;
+import org.apache.zest.library.restlet.resource.ServerResource;
+import org.apache.zest.library.restlet.serialization.ZestConverter;
+import org.apache.zest.spi.ZestSPI;
+import org.restlet.Context;
+import org.restlet.Request;
+import org.restlet.Response;
+import org.restlet.Restlet;
+import org.restlet.data.Form;
+import org.restlet.data.Method;
+import org.restlet.data.Parameter;
+import org.restlet.data.Status;
+import org.restlet.representation.Representation;
+import org.restlet.representation.Variant;
+import org.restlet.routing.Router;
+import org.restlet.security.User;
+
+public class ZestEntityRestlet<T extends Identity> extends Restlet
+{
+    @Structure
+    private ValueBuilderFactory vbf;
+
+    @Structure
+    private UnitOfWorkFactory uowf;
+
+    @Uses
+    private ResourceFactory resourceFactory;
+
+    @Uses
+    private Router router;
+
+    @Uses
+    @Optional
+    private Class<T> identityType;
+
+    @Structure
+    private ZestSPI spi;
+
+    @Uses
+    private ZestConverter converter;
+
+    @Service
+    private RepositoryLocator locator;
+
+    @Override
+    public void handle( Request request, Response response )
+    {
+        try
+        {
+            super.handle( request, response );
+            Method method = request.getMethod();
+            if( method.equals( Method.GET ) )
+            {
+                get( request, response );
+            }
+            if( method.equals( Method.DELETE ) )
+            {
+                delete( request, response );
+            }
+            if( method.equals( Method.POST ) )
+            {
+                post( request, response );
+            }
+            if( method.equals( Method.PUT ) )
+            {
+                put( request, response );
+            }
+        }
+        catch( RuntimeException e )
+        {
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+    private void get( Request request, Response response )
+    {
+        execute( request, response, resource -> {
+                     try
+                     {
+                         T result = resource.get();
+                         if( result != null )
+                         {
+                             if( result instanceof EntityComposite )
+                             {
+                                 result = locator.find( identityType ).toValue( result );
+                             }
+                             Representation representation = converter.toRepresentation( result, new Variant(), null );
+                             response.setEntity( representation );
+                             response.setEntity( representation );
+                             response.setStatus( Status.SUCCESS_OK );
+                         }
+                         else
+                         {
+                             response.setStatus( Status.CLIENT_ERROR_NOT_FOUND );
+                         }
+                     }
+                     catch( NoSuchEntityException e )
+                     {
+                         response.setStatus( Status.CLIENT_ERROR_NOT_FOUND, e, "Entity not found." );
+                     }
+                 }
+        );
+    }
+
+    private void put( Request request, Response response )
+    {
+        execute( request, response, resource -> {
+
+            T value = convertToObject( identityType, request );
+            resource.put( value );
+            response.setStatus( Status.SUCCESS_OK );
+        } );
+    }
+
+    private void delete( Request request, Response response )
+    {
+        execute( request, response, resource -> {
+            resource.delete();
+            response.setStatus( Status.SUCCESS_OK );
+        } );
+    }
+
+    private void post( final Request request, final Response response )
+    {
+        execute( request, response, resource -> {
+            RestForm form = createRestForm( request );
+            RestLink link = resource.post( form );
+            response.setLocationRef( link.path().get() );
+            response.setStatus( Status.REDIRECTION_SEE_OTHER );
+        } );
+    }
+
+    private RestForm createRestForm( final Request request )
+    {
+        //noinspection MismatchedQueryAndUpdateOfCollection
+        Form form = new Form( request.getEntity() );
+        ValueBuilder<RestForm> builder = vbf.newValueBuilderWithState(
+            RestForm.class,
+            descriptor -> {
+                if( descriptor.qualifiedName().name().equals( "fields" ) )
+                {
+                    List<FormField> result = new ArrayList<>();
+                    for( Parameter param : form )
+                    {
+                        String name = param.getName();
+                        String value = param.getValue();
+                        ValueBuilder<FormField> fieldBuilder = vbf.newValueBuilder( FormField.class );
+                        FormField prototype = fieldBuilder.prototype();
+                        prototype.name().set( name );
+                        prototype.value().set( value );
+                        prototype.type().set( FormField.TEXT );
+                        result.add( fieldBuilder.newInstance() );
+                    }
+                    return result;
+                }
+                return null;
+            },
+            descriptor -> null,
+            descriptor -> null,
+            descriptor -> null
+        );
+        return builder.newInstance();
+    }
+
+    private void execute( Request request, Response response, Consumer<ServerResource<T>> closure )
+    {
+        UnitOfWork uow = null;
+        try
+        {
+            uow = createUnitOfWork( request );
+            ServerResource<T> resource = createResource( request, response, getContext() );
+            closure.accept( resource );
+            uow.complete();
+        }
+        catch( UnsupportedOperationException e )
+        {
+            e.printStackTrace();
+            response.setStatus( Status.CLIENT_ERROR_BAD_REQUEST, e, e.getMessage() );
+        }
+        catch( ConversionException e )
+        {
+            e.printStackTrace();
+            response.setStatus( Status.CLIENT_ERROR_BAD_REQUEST, e.getMessage() );
+        }
+        catch( NotPresentException e )
+        {
+            e.printStackTrace();
+            response.setStatus( Status.CLIENT_ERROR_NOT_FOUND, e.getMessage() );
+        }
+        catch( Throwable e )
+        {
+            e.printStackTrace();
+            response.setStatus( Status.CLIENT_ERROR_BAD_REQUEST, e.getMessage() );
+        }
+        finally
+        {
+            if( uow != null && uow.isOpen() )
+            {
+                uow.discard();
+            }
+        }
+    }
+
+    private ServerResource<T> createResource( Request request, Response response, Context context )
+    {
+        @SuppressWarnings( "unchecked" )
+        ServerResource<T> serverResource = resourceFactory.create( identityType, request, response, context );
+        return serverResource;
+    }
+
+    private UnitOfWork createUnitOfWork( Request request )
+    {
+        User user = request.getClientInfo().getUser();
+        UserIdentity userIdentity = new UserIdentity( user.getIdentifier(),
+                                                      user.getName(),
+                                                      user.getEmail(),
+                                                      user.getFirstName(),
+                                                      user.getLastName()
+        );
+        Usecase usecase = UsecaseBuilder
+            .buildUsecase( request.getResourceRef().getIdentifier( true ) )
+            .withMetaInfo( userIdentity )
+            .newUsecase();
+        return uowf.newUnitOfWork( usecase );
+    }
+
+    private <K> K convertToObject( Class<K> type, Request request )
+    {
+        try
+        {
+            return converter.toObject( request.getEntity(), type, null );
+        }
+        catch( IOException e )
+        {
+            throw new ConversionException( request.getEntityAsText() );
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/CrudServiceAssembler.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/CrudServiceAssembler.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/CrudServiceAssembler.java
new file mode 100644
index 0000000..1cfe412
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/CrudServiceAssembler.java
@@ -0,0 +1,41 @@
+/*
+ * 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.zest.library.restlet.assembly;
+
+import org.apache.zest.api.common.Visibility;
+import org.apache.zest.bootstrap.Assembler;
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.ModuleAssembly;
+import org.apache.zest.library.restlet.identity.IdentityManager;
+import org.apache.zest.library.restlet.identity.IdentityMappingConfiguration;
+import org.apache.zest.library.restlet.repository.RepositoryLocator;
+
+public class CrudServiceAssembler
+    implements Assembler
+{
+    @Override
+    public void assemble( ModuleAssembly module )
+        throws AssemblyException
+    {
+        module.entities( IdentityMappingConfiguration.class ).visibleIn( Visibility.module );
+        module.services( IdentityManager.class ).visibleIn( Visibility.application ).instantiateOnStartup();
+        module.services( RepositoryLocator.class ).visibleIn( Visibility.application );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/GenericRestLayer.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/GenericRestLayer.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/GenericRestLayer.java
new file mode 100644
index 0000000..aba404f
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/GenericRestLayer.java
@@ -0,0 +1,36 @@
+/*
+ * 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.zest.library.restlet.assembly;
+
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.LayerAssembly;
+import org.apache.zest.bootstrap.layered.LayeredLayerAssembler;
+
+public class GenericRestLayer extends LayeredLayerAssembler
+{
+
+    @Override
+    public LayerAssembly assemble( LayerAssembly layer )
+        throws AssemblyException
+    {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/RestApplicationAssembler.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/RestApplicationAssembler.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/RestApplicationAssembler.java
new file mode 100644
index 0000000..1074fb1
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/RestApplicationAssembler.java
@@ -0,0 +1,86 @@
+/*
+ * 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.zest.library.restlet.assembly;
+
+import java.util.LinkedHashMap;
+import java.util.function.BinaryOperator;
+import org.apache.zest.api.activation.PassivationException;
+import org.apache.zest.api.structure.Application;
+import org.apache.zest.bootstrap.ApplicationAssembly;
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.LayerAssembly;
+import org.apache.zest.bootstrap.layered.LayerAssembler;
+import org.apache.zest.bootstrap.layered.LayeredApplicationAssembler;
+import org.apache.zest.bootstrap.layered.ModuleAssembler;
+
+public class RestApplicationAssembler extends LayeredApplicationAssembler
+{
+    private final LinkedHashMap<Class<? extends LayerAssembler>, LayerAssembly> assemblies = new LinkedHashMap<>();
+    private Class<? extends LayerAssembler>[] layers;
+
+    @SafeVarargs
+    public RestApplicationAssembler( String name, String version, Application.Mode mode, Class<? extends LayerAssembler>... layers )
+        throws AssemblyException
+    {
+        super( name, version, mode );
+        this.layers = layers;
+    }
+
+    @Override
+    protected void assembleLayers( ApplicationAssembly assembly )
+        throws AssemblyException
+    {
+        for( Class<? extends LayerAssembler> layer : layers )
+        {
+            LayerAssembly layerAssembly = createLayer( layer );
+            assemblies.put( layer, layerAssembly );
+        }
+    }
+
+    public void setupUses( BinaryOperator<LayerAssembly> uses )
+    {
+        assemblies.values().stream().reduce( uses );
+    }
+
+    public void setupUses()
+    {
+        assemblies.values().stream().reduce( LayerAssembly::uses );
+    }
+
+    public LayerAssembly layer( Class<? extends LayerAssembler> layerClass, ModuleAssembler... assemblers )
+    {
+        return assemblies.get( layerClass );
+    }
+
+    public void addShutdownHook()
+    {
+        Runtime.getRuntime().addShutdownHook( new Thread( () -> {
+            try
+            {
+                stop();
+            }
+            catch( PassivationException e )
+            {
+                e.printStackTrace();
+            }
+        } ) );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/RestletCrudConnectivityAssembler.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/RestletCrudConnectivityAssembler.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/RestletCrudConnectivityAssembler.java
new file mode 100644
index 0000000..faa607c
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/RestletCrudConnectivityAssembler.java
@@ -0,0 +1,61 @@
+/*
+ * 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.zest.library.restlet.assembly;
+
+import org.apache.zest.bootstrap.Assembler;
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.ModuleAssembly;
+import org.apache.zest.library.restlet.Command;
+import org.apache.zest.library.restlet.FormField;
+import org.apache.zest.library.restlet.ZestEntityRestlet;
+import org.apache.zest.library.restlet.RestForm;
+import org.apache.zest.library.restlet.RestLink;
+import org.apache.zest.library.restlet.crud.EntityList;
+import org.apache.zest.library.restlet.crud.EntityListResource;
+import org.apache.zest.library.restlet.crud.EntityRef;
+import org.apache.zest.library.restlet.crud.EntityResource;
+import org.apache.zest.library.restlet.resource.CreationResource;
+import org.apache.zest.library.restlet.resource.DefaultResourceFactoryImpl;
+import org.apache.zest.library.restlet.resource.EntryPointResource;
+import org.apache.zest.library.restlet.resource.ResourceBuilder;
+import org.apache.zest.library.restlet.serialization.FormRepresentation;
+import org.apache.zest.library.restlet.serialization.JsonRepresentation;
+import org.apache.zest.valueserialization.jackson.JacksonValueSerializationAssembler;
+
+public class RestletCrudConnectivityAssembler
+    implements Assembler
+{
+    @Override
+    public void assemble( ModuleAssembly module )
+        throws AssemblyException
+    {
+        module.values( EntryPointResource.class );
+        module.values( EntityListResource.class );
+        module.values( EntityResource.class );
+        module.values( CreationResource.class );
+        module.values( Command.class, FormField.class, RestForm.class, RestLink.class, EntityList.class, EntityRef.class );
+        module.objects( DefaultResourceFactoryImpl.class );
+        module.objects( JsonRepresentation.class );
+        module.objects( FormRepresentation.class );
+        module.objects( ZestEntityRestlet.class );
+        module.services( ResourceBuilder.class );
+        new JacksonValueSerializationAssembler().assemble( module );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/RestletCrudModuleAssembler.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/RestletCrudModuleAssembler.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/RestletCrudModuleAssembler.java
new file mode 100644
index 0000000..3e6607e
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/RestletCrudModuleAssembler.java
@@ -0,0 +1,66 @@
+/*
+ * 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.zest.library.restlet.assembly;
+
+import org.apache.zest.api.common.Visibility;
+import org.apache.zest.api.unitofwork.concern.UnitOfWorkConcern;
+import org.apache.zest.bootstrap.Assembler;
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.ModuleAssembly;
+import org.apache.zest.library.restlet.repository.CrudRepository;
+import org.apache.zest.library.restlet.repository.EntityTypeDescriptor;
+import org.apache.zest.library.restlet.repository.SmallCrudRepositoryMixin;
+
+public class RestletCrudModuleAssembler
+    implements Assembler
+{
+    private final Class type;
+    private final Class repositoryType;
+
+    public RestletCrudModuleAssembler( Class type, Class repositoryType )
+    {
+        this.type = type;
+        this.repositoryType = repositoryType;
+    }
+
+    public RestletCrudModuleAssembler( Class type )
+    {
+        this.type = type;
+        repositoryType = CrudRepository.class;
+    }
+
+    @Override
+    public void assemble( ModuleAssembly module )
+        throws AssemblyException
+    {
+        module
+            .addServices( repositoryType )
+            .identifiedBy( "repository_" + type.getSimpleName() )
+            .visibleIn( Visibility.application )
+            .withMixins( SmallCrudRepositoryMixin.class )
+            .withConcerns( UnitOfWorkConcern.class )
+            .taggedWith( type.getSimpleName() )
+            .setMetaInfo( new EntityTypeDescriptor( type ) )
+        ;
+        module.entities( type ).visibleIn( Visibility.layer );
+        module.values( type ).visibleIn( Visibility.layer );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/configuration/ConfigurationLayer.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/configuration/ConfigurationLayer.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/configuration/ConfigurationLayer.java
new file mode 100644
index 0000000..1d5eea2
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/configuration/ConfigurationLayer.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.zest.library.restlet.assembly.configuration;
+
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.LayerAssembly;
+import org.apache.zest.bootstrap.ModuleAssembly;
+import org.apache.zest.bootstrap.layered.LayerAssembler;
+import org.apache.zest.bootstrap.layered.LayeredLayerAssembler;
+
+public class ConfigurationLayer extends LayeredLayerAssembler
+    implements LayerAssembler
+{
+    public static final String NAME = "Configuration Layer";
+    private ModuleAssembly configModule;
+
+    @Override
+    public LayerAssembly assemble( LayerAssembly layer )
+        throws AssemblyException
+    {
+        configModule = createModule( layer, ConfigurationModule.class );
+        return layer;
+    }
+
+    public ModuleAssembly configModule()
+    {
+        return configModule;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/configuration/ConfigurationModule.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/configuration/ConfigurationModule.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/configuration/ConfigurationModule.java
new file mode 100644
index 0000000..ed97909
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/configuration/ConfigurationModule.java
@@ -0,0 +1,45 @@
+/*
+ * 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.zest.library.restlet.assembly.configuration;
+
+import org.apache.zest.api.common.Visibility;
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.LayerAssembly;
+import org.apache.zest.bootstrap.ModuleAssembly;
+import org.apache.zest.bootstrap.layered.ModuleAssembler;
+import org.apache.zest.entitystore.memory.MemoryEntityStoreService;
+import org.apache.zest.spi.uuid.UuidIdentityGeneratorService;
+import org.apache.zest.valueserialization.jackson.JacksonValueSerializationAssembler;
+
+public class ConfigurationModule
+    implements ModuleAssembler
+{
+    public static final String NAME = "Configuration Module";
+    @Override
+    public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module )
+        throws AssemblyException
+    {
+        module.services( MemoryEntityStoreService.class ).visibleIn( Visibility.layer );
+        new JacksonValueSerializationAssembler().visibleIn( Visibility.layer ).assemble( module );
+        module.services( UuidIdentityGeneratorService.class ).visibleIn( Visibility.layer );
+        return module;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/connectivity/ConnectivityLayer.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/connectivity/ConnectivityLayer.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/connectivity/ConnectivityLayer.java
new file mode 100644
index 0000000..037ae6d
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/connectivity/ConnectivityLayer.java
@@ -0,0 +1,41 @@
+/*
+ * 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.zest.library.restlet.assembly.connectivity;
+
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.LayerAssembly;
+import org.apache.zest.bootstrap.layered.LayerAssembler;
+import org.apache.zest.bootstrap.layered.LayeredLayerAssembler;
+
+public class ConnectivityLayer extends LayeredLayerAssembler
+    implements LayerAssembler
+{
+    public static final String NAME = "Connectivity Layer";
+
+    @Override
+    public LayerAssembly assemble( LayerAssembly layer )
+        throws AssemblyException
+    {
+        createModule( layer, RestModule.class );
+        createModule( layer, SecurityModule.class );
+        return layer;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/connectivity/RestModule.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/connectivity/RestModule.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/connectivity/RestModule.java
new file mode 100644
index 0000000..12f6201
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/connectivity/RestModule.java
@@ -0,0 +1,43 @@
+/*
+ * 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.zest.library.restlet.assembly.connectivity;
+
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.LayerAssembly;
+import org.apache.zest.bootstrap.ModuleAssembly;
+import org.apache.zest.bootstrap.layered.ModuleAssembler;
+import org.apache.zest.library.restlet.assembly.RestletCrudConnectivityAssembler;
+import org.apache.zest.library.restlet.resource.EntryPoint;
+
+public class RestModule
+    implements ModuleAssembler
+{
+    public static String NAME;
+
+    @Override
+    public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module )
+        throws AssemblyException
+    {
+        new RestletCrudConnectivityAssembler().assemble( module );
+        module.values( EntryPoint.class );
+        return module;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/connectivity/SecurityModule.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/connectivity/SecurityModule.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/connectivity/SecurityModule.java
new file mode 100644
index 0000000..b61f9dc
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/connectivity/SecurityModule.java
@@ -0,0 +1,37 @@
+/*
+ * 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.zest.library.restlet.assembly.connectivity;
+
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.LayerAssembly;
+import org.apache.zest.bootstrap.ModuleAssembly;
+import org.apache.zest.bootstrap.layered.ModuleAssembler;
+
+public class SecurityModule
+    implements ModuleAssembler
+{
+    @Override
+    public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module )
+        throws AssemblyException
+    {
+        return module;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/domain/CrudModule.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/domain/CrudModule.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/domain/CrudModule.java
new file mode 100644
index 0000000..acac756
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/domain/CrudModule.java
@@ -0,0 +1,39 @@
+/*
+ * 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.zest.library.restlet.assembly.domain;
+
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.LayerAssembly;
+import org.apache.zest.bootstrap.ModuleAssembly;
+import org.apache.zest.bootstrap.layered.ModuleAssembler;
+import org.apache.zest.library.restlet.assembly.CrudServiceAssembler;
+
+public class CrudModule
+    implements ModuleAssembler
+{
+    @Override
+    public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module )
+        throws AssemblyException
+    {
+        new CrudServiceAssembler().assemble( module );
+        return module;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/domain/DomainLayer.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/domain/DomainLayer.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/domain/DomainLayer.java
new file mode 100644
index 0000000..0f311c4
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/domain/DomainLayer.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.zest.library.restlet.assembly.domain;
+
+import org.apache.zest.api.structure.Application;
+import org.apache.zest.api.structure.Module;
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.LayerAssembly;
+import org.apache.zest.bootstrap.layered.LayerAssembler;
+import org.apache.zest.bootstrap.layered.LayeredLayerAssembler;
+import org.apache.zest.functional.Function;
+
+public class DomainLayer extends LayeredLayerAssembler
+    implements LayerAssembler
+{
+    public static final String NAME = "Domain Layer";
+
+    @Override
+    public LayerAssembly assemble( LayerAssembly layer )
+        throws AssemblyException
+    {
+        return layer;
+    }
+
+    public static Function<Application, Module> typeFinder()
+    {
+        return application -> application.findModule( "Domain Layer", "TypeFinder Module" );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/infrastructue/FileStorageModule.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/infrastructue/FileStorageModule.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/infrastructue/FileStorageModule.java
new file mode 100644
index 0000000..483038b
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/infrastructue/FileStorageModule.java
@@ -0,0 +1,52 @@
+/*
+ * 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.zest.library.restlet.assembly.infrastructue;
+
+import org.apache.zest.api.common.Visibility;
+import org.apache.zest.entitystore.file.assembly.FileEntityStoreAssembler;
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.LayerAssembly;
+import org.apache.zest.bootstrap.ModuleAssembly;
+import org.apache.zest.bootstrap.layered.ModuleAssembler;
+
+public class FileStorageModule
+    implements ModuleAssembler
+{
+    public static final String NAME = "Storage Module";
+
+    private final ModuleAssembly configModule;
+
+    public FileStorageModule( ModuleAssembly configModule )
+    {
+        this.configModule = configModule;
+    }
+
+    @Override
+    public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module )
+        throws AssemblyException
+    {
+        new FileEntityStoreAssembler()
+            .visibleIn( Visibility.application  )
+            .withConfig( configModule, Visibility.application )
+            .assemble( module );
+        return module;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/infrastructue/IndexingModule.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/infrastructue/IndexingModule.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/infrastructue/IndexingModule.java
new file mode 100644
index 0000000..3ec1dde
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/infrastructue/IndexingModule.java
@@ -0,0 +1,56 @@
+/*
+ * 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.zest.library.restlet.assembly.infrastructue;
+
+import org.apache.zest.api.common.Visibility;
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.LayerAssembly;
+import org.apache.zest.bootstrap.ModuleAssembly;
+import org.apache.zest.bootstrap.layered.ModuleAssembler;
+import org.apache.zest.index.rdf.assembly.RdfNativeSesameStoreAssembler;
+import org.apache.zest.library.rdf.repository.NativeConfiguration;
+
+public class IndexingModule
+    implements ModuleAssembler
+{
+    public static final String NAME = "Indexing Module";
+    private final ModuleAssembly configModule;
+
+    public IndexingModule( ModuleAssembly configModule )
+    {
+        this.configModule = configModule;
+    }
+
+    @Override
+    public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module )
+        throws AssemblyException
+    {
+//        new FileConfigurationAssembler().assemble( module );
+//        new ESFilesystemIndexQueryAssembler()
+//            .visibleIn( Visibility.application )
+//            .withConfig( configModule, Visibility.application )
+//            .assemble( module );
+
+        configModule.entities( NativeConfiguration.class ).visibleIn( Visibility.application );
+        new RdfNativeSesameStoreAssembler(Visibility.application, Visibility.module).assemble( module );
+        return module;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/infrastructue/InfrastructureLayer.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/infrastructue/InfrastructureLayer.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/infrastructue/InfrastructureLayer.java
new file mode 100644
index 0000000..7fc3157
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/infrastructue/InfrastructureLayer.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.zest.library.restlet.assembly.infrastructue;
+
+import org.apache.zest.api.structure.Application;
+import org.apache.zest.api.structure.Module;
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.LayerAssembly;
+import org.apache.zest.bootstrap.ModuleAssembly;
+import org.apache.zest.bootstrap.layered.LayerAssembler;
+import org.apache.zest.bootstrap.layered.LayeredLayerAssembler;
+import org.apache.zest.functional.Function;
+import org.apache.zest.library.restlet.assembly.configuration.ConfigurationLayer;
+import org.apache.zest.library.restlet.assembly.configuration.ConfigurationModule;
+import org.apache.zest.library.restlet.assembly.domain.DomainLayer;
+
+public class InfrastructureLayer extends LayeredLayerAssembler
+    implements LayerAssembler
+{
+    public static final String NAME = "Infrastructure Layer";
+    private final ModuleAssembly configModule;
+    private final Function<Application, Module> typeFinder;
+
+    public static InfrastructureLayer create( LayerAssembly layer )
+    {
+        Function<Application, Module> typeFinder = DomainLayer.typeFinder();
+        ModuleAssembly config = layer.application().layer( ConfigurationLayer.NAME ).module( ConfigurationModule.NAME );
+        return new InfrastructureLayer( config, typeFinder );
+    }
+
+    public InfrastructureLayer( ModuleAssembly configModule, Function<Application, Module> typeFinder )
+    {
+        this.configModule = configModule;
+        this.typeFinder = typeFinder;
+    }
+
+    @Override
+    public LayerAssembly assemble( LayerAssembly layer )
+        throws AssemblyException
+    {
+        new IndexingModule( configModule ).assemble( layer, layer.module( IndexingModule.NAME ) );
+        new SerializationModule( typeFinder ).assemble( layer, layer.module( SerializationModule.NAME ) );
+        return layer;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/9304d008/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/infrastructue/SerializationModule.java
----------------------------------------------------------------------
diff --git a/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/infrastructue/SerializationModule.java b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/infrastructue/SerializationModule.java
new file mode 100644
index 0000000..f4f43e4
--- /dev/null
+++ b/libraries/restlet/src/main/java/org/apache/zest/library/restlet/assembly/infrastructue/SerializationModule.java
@@ -0,0 +1,56 @@
+/*
+ * 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.zest.library.restlet.assembly.infrastructue;
+
+import org.apache.zest.api.common.Visibility;
+import org.apache.zest.api.structure.Application;
+import org.apache.zest.api.structure.Module;
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.LayerAssembly;
+import org.apache.zest.bootstrap.ModuleAssembly;
+import org.apache.zest.bootstrap.layered.ModuleAssembler;
+import org.apache.zest.functional.Function;
+import org.apache.zest.spi.uuid.UuidIdentityGeneratorService;
+import org.apache.zest.valueserialization.jackson.JacksonValueSerializationAssembler;
+
+public class SerializationModule
+    implements ModuleAssembler
+{
+    public static final String NAME = "Serialization Module";
+    private final Function<Application, Module> typeFinder;
+
+    public SerializationModule( Function<Application, Module> typeFinder )
+    {
+        this.typeFinder = typeFinder;
+    }
+
+    @Override
+    public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module )
+        throws AssemblyException
+    {
+        new JacksonValueSerializationAssembler()
+            .visibleIn( Visibility.layer )
+            .withValuesModuleFinder( typeFinder )
+            .assemble( module );
+        module.services( UuidIdentityGeneratorService.class ).visibleIn( Visibility.layer );
+        return module;
+    }
+}