You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by gr...@apache.org on 2014/12/05 02:19:21 UTC

incubator-usergrid git commit: Added new basis of rest test framework using cleaner api's to manage the Resources. Currently Added is the bare minimum need for modeling rest tests, but missing is the Jersey integration so that we can send the calls out.

Repository: incubator-usergrid
Updated Branches:
  refs/heads/UG-rest-test-framework-overhaul [created] 6a2b28462


Added new basis of rest test framework using cleaner api's to manage the Resources. Currently Added is the bare minimum need for modeling rest tests, but missing is the Jersey integration so that we can send the calls out. Next step is to comment and get the JerseyTest framework working within this testing framework. This is a clean commit before any integration so here is where you would start to build in a different framework. Added license header to all new files.


Project: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/commit/6a2b2846
Tree: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/tree/6a2b2846
Diff: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/diff/6a2b2846

Branch: refs/heads/UG-rest-test-framework-overhaul
Commit: 6a2b28462dddc62ab15074c99a5cb43410e1d63b
Parents: c4973e9
Author: grey <gr...@apigee.com>
Authored: Thu Dec 4 17:19:19 2014 -0800
Committer: grey <gr...@apigee.com>
Committed: Thu Dec 4 17:19:19 2014 -0800

----------------------------------------------------------------------
 .../rest/test/resource2point0/Client.java       |  60 ++++
 .../rest/test/resource2point0/DumbClient.java   |  35 ++
 .../endpoints/ApplicationResource.java          |  20 ++
 .../resource2point0/endpoints/Collection.java   | 101 ++++++
 .../endpoints/ManagementResource.java           |  19 +
 .../endpoints/NamedResource.java                |  27 ++
 .../endpoints/OrganizationResource.java         |  20 ++
 .../resource2point0/endpoints/RootResource.java |  45 +++
 .../endpoints/TokenResource.java                |  16 +
 .../resource2point0/endpoints/UrlResource.java  |  19 +
 .../test/resource2point0/model/ApiResponse.java | 204 +++++++++++
 .../rest/test/resource2point0/model/Entity.java | 346 +++++++++++++++++++
 .../resource2point0/model/EntityResponse.java   | 132 +++++++
 .../resource2point0/state/ClientContext.java    |  19 +
 14 files changed, 1063 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6a2b2846/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/Client.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/Client.java b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/Client.java
new file mode 100644
index 0000000..9682f0e
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/Client.java
@@ -0,0 +1,60 @@
+package org.apache.usergrid.rest.test.resource2point0;
+
+
+import org.apache.usergrid.rest.test.resource2point0.endpoints.Collection;
+import org.apache.usergrid.rest.test.resource2point0.endpoints.ManagementResource;
+import org.apache.usergrid.rest.test.resource2point0.endpoints.OrganizationResource;
+import org.apache.usergrid.rest.test.resource2point0.endpoints.RootResource;
+import org.apache.usergrid.rest.test.resource2point0.endpoints.UrlResource;
+import org.apache.usergrid.rest.test.resource2point0.model.EntityResponse;
+import org.apache.usergrid.rest.test.resource2point0.state.ClientContext;
+
+
+/**
+ * Created by ApigeeCorporation on 12/4/14.
+ */
+public class Client implements UrlResource {
+
+
+    private final String serverUrl;
+    private final ClientContext context;
+//This should work independantly of test frameowkr. Need to be able to pull the WebResource Url and not have to integrate the webresource into the Endpoints/Client.
+    //This uses jeresy to create the client. Initialize the client with the webresource, and then the CLIENT calls the root resource.
+    //
+    //after initialization of the client htne use it to build our path using our resources.
+    //Just keep checking in early and checkin often.
+
+    public Client( final String serverUrl ) {
+        this.serverUrl = serverUrl;
+        this.context = new ClientContext();
+    }
+
+
+    @Override
+    public String getPath() {
+        return serverUrl;
+    }
+
+
+    /**
+     * Get the management resource
+     */
+    public ManagementResource management() {
+        return new ManagementResource( context, this );
+    }
+
+
+    /**
+     * Get hte organization resource
+     */
+    public OrganizationResource org( final String orgName ) {
+        return new OrganizationResource( orgName, context,  this );
+    }
+
+
+    public void loginAdminUser( final String username, final String password ) {
+        final String token = management().token().post(username, password);
+
+        context.setToken( token );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6a2b2846/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/DumbClient.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/DumbClient.java b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/DumbClient.java
new file mode 100644
index 0000000..53b9de7
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/DumbClient.java
@@ -0,0 +1,35 @@
+package org.apache.usergrid.rest.test.resource2point0;
+
+
+import org.apache.usergrid.rest.test.resource2point0.endpoints.Collection;
+import org.apache.usergrid.rest.test.resource2point0.endpoints.RootResource;
+import org.apache.usergrid.rest.test.resource2point0.model.Entity;
+import org.apache.usergrid.rest.test.resource2point0.model.EntityResponse;
+
+
+/**
+ * Created by ApigeeCorporation on 12/4/14.
+ */
+public class DumbClient {
+
+    private final Client client = new Client("http://localhost:8080");
+
+    public void stuff(){
+        EntityResponse itr  =  client.org( "test" ).getApp( "test" ).users().getEntityResponse();
+
+        for(Entity entity: itr){
+
+        }
+    }
+
+    public void stateful(){
+
+
+
+        EntityResponse itr  =  client.org( "test" ).getApp( "test" ).users().getEntityResponse();
+
+        for(Entity entity: itr){
+
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6a2b2846/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/ApplicationResource.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/ApplicationResource.java b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/ApplicationResource.java
new file mode 100644
index 0000000..af8d957
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/ApplicationResource.java
@@ -0,0 +1,20 @@
+package org.apache.usergrid.rest.test.resource2point0.endpoints;
+
+
+import org.apache.usergrid.rest.test.resource2point0.state.ClientContext;
+
+
+/**
+ * Created by ApigeeCorporation on 12/4/14.
+ */
+public class ApplicationResource extends NamedResource {
+
+
+    public ApplicationResource( final String name,final ClientContext context,  final UrlResource parent ) {
+        super( name, context, parent );
+    }
+
+    public Collection users(){
+        return new Collection("users", this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6a2b2846/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/Collection.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/Collection.java b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/Collection.java
new file mode 100644
index 0000000..d794718
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/Collection.java
@@ -0,0 +1,101 @@
+package org.apache.usergrid.rest.test.resource2point0.endpoints;
+
+
+import java.util.UUID;
+
+import org.apache.usergrid.rest.test.resource2point0.model.ApiResponse;
+import org.apache.usergrid.rest.test.resource2point0.model.Entity;
+import org.apache.usergrid.rest.test.resource2point0.model.EntityResponse;
+import org.apache.usergrid.rest.test.resource2point0.state.ClientContext;
+
+import com.google.common.base.Optional;
+
+
+/**
+ * Created by ApigeeCorporation on 12/4/14.
+ */
+public class Collection extends NamedResource {
+
+
+    public Collection( final String name, final ClientContext context,  final UrlResource parent ) {
+        super( name, context, parent );
+    }
+
+
+    /**
+     * Get a list of entities
+     * @return
+     */
+    public ApiResponse get(final Optional<String> cursor){
+        return null;
+    }
+
+
+    /**
+     * Get the response as an entity response
+     * @return
+     */
+    public EntityResponse getEntityResponse(){
+        return EntityResponse.fromCollection( this );
+    }
+
+
+    /**
+     * Post the entity to the users collection
+     * @param user
+     * @return
+     */
+    public Entity post(final Entity user){
+        return null;
+    }
+
+
+    /**
+     * Get the entity by uuid
+     * @param uuid
+     * @return
+     */
+    public Entity get(final UUID uuid){
+        return get(uuid.toString());
+    }
+
+
+    /**
+     * Get the entity by name
+     * @param name
+     * @return
+     */
+    public Entity get(final String name){
+        return null;
+    }
+
+
+    /**
+     * Updte the entity
+     * @param toUpdate
+     * @return
+     */
+    public Entity put(final Entity toUpdate){
+        return null;
+    }
+
+
+    /**
+     * Delete the entity
+     * @param uuid
+     * @return
+     */
+    public Entity delete(final UUID uuid){
+        return delete(uuid.toString());
+    }
+
+
+    /**
+     * Delete the entity by name
+     * @param name
+     * @return
+     */
+    public Entity delete(final String name){
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6a2b2846/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/ManagementResource.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/ManagementResource.java b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/ManagementResource.java
new file mode 100644
index 0000000..63620f1
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/ManagementResource.java
@@ -0,0 +1,19 @@
+package org.apache.usergrid.rest.test.resource2point0.endpoints;
+
+
+import org.apache.usergrid.rest.test.resource2point0.state.ClientContext;
+
+
+/**
+ * Created by ApigeeCorporation on 12/4/14.
+ */
+public class ManagementResource extends NamedResource {
+    public ManagementResource( final ClientContext context, final UrlResource parent ) {
+        super( "management", context, parent );
+    }
+
+    public TokenResource token(){
+        return new TokenResource( context, this );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6a2b2846/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/NamedResource.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/NamedResource.java b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/NamedResource.java
new file mode 100644
index 0000000..8e95b51
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/NamedResource.java
@@ -0,0 +1,27 @@
+package org.apache.usergrid.rest.test.resource2point0.endpoints;
+
+
+import org.apache.usergrid.rest.test.resource2point0.state.ClientContext;
+
+
+/**
+ * Created by ApigeeCorporation on 12/4/14.
+ */
+public class NamedResource implements UrlResource {
+
+    protected final String name;
+    protected final ClientContext context;
+    protected final UrlResource parent;
+
+
+    public NamedResource( final String name, final ClientContext context, final UrlResource parent ) {this.name = name;
+        this.context = context;
+        this.parent = parent;
+    }
+
+
+    @Override
+    public String getPath() {
+        return name;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6a2b2846/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/OrganizationResource.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/OrganizationResource.java b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/OrganizationResource.java
new file mode 100644
index 0000000..a7fac2c
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/OrganizationResource.java
@@ -0,0 +1,20 @@
+package org.apache.usergrid.rest.test.resource2point0.endpoints;
+
+
+import org.apache.usergrid.rest.test.resource2point0.state.ClientContext;
+
+
+/**
+ * Created by ApigeeCorporation on 12/4/14.
+ */
+public class OrganizationResource extends NamedResource {
+
+
+    public OrganizationResource( final String name, final ClientContext context, final UrlResource parent ) {
+        super( name, context, parent );
+    }
+
+    public ApplicationResource getApp(final String app){
+        return new ApplicationResource( app, this );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6a2b2846/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/RootResource.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/RootResource.java b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/RootResource.java
new file mode 100644
index 0000000..8856c9f
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/RootResource.java
@@ -0,0 +1,45 @@
+package org.apache.usergrid.rest.test.resource2point0.endpoints;
+
+
+import org.apache.usergrid.rest.test.resource2point0.state.ClientContext;
+
+
+/**
+ * Root resource for stuff
+ */
+public class RootResource implements UrlResource {
+
+
+    private final String serverUrl;
+    private final ClientContext context;
+
+
+    public RootResource( final String serverUrl, final ClientContext context ) {this.serverUrl = serverUrl;
+        this.context = context;
+    }
+
+
+    @Override
+    public String getPath() {
+        return serverUrl;
+    }
+
+
+    /**
+     * Get the management resource
+     * @return
+     */
+    public ManagementResource management(){
+        return new ManagementResource( context, this);
+    }
+
+
+    /**
+     * Get hte organization resource
+     * @param orgName
+     * @return
+     */
+    public OrganizationResource  org(final String orgName){
+        return new OrganizationResource( orgName,context,  this );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6a2b2846/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/TokenResource.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/TokenResource.java b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/TokenResource.java
new file mode 100644
index 0000000..5574569
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/TokenResource.java
@@ -0,0 +1,16 @@
+package org.apache.usergrid.rest.test.resource2point0.endpoints;
+
+
+import org.apache.usergrid.rest.test.resource2point0.state.ClientContext;
+
+
+/**
+ * Created by ApigeeCorporation on 12/4/14.
+ */
+public class TokenResource extends NamedResource {
+    public TokenResource( final ClientContext context, final UrlResource parent ) {
+        super( "management", context, parent );
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6a2b2846/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/UrlResource.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/UrlResource.java b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/UrlResource.java
new file mode 100644
index 0000000..2154459
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/endpoints/UrlResource.java
@@ -0,0 +1,19 @@
+package org.apache.usergrid.rest.test.resource2point0.endpoints;
+
+
+import org.apache.usergrid.rest.test.resource2point0.state.ClientContext;
+
+
+/**
+ * Created by ApigeeCorporation on 12/4/14.
+ */
+public interface UrlResource {
+
+    /**
+     * Get the url path to this resource
+     * @return
+     */
+    public String getPath();
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6a2b2846/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/model/ApiResponse.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/model/ApiResponse.java b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/model/ApiResponse.java
new file mode 100644
index 0000000..33153c6
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/model/ApiResponse.java
@@ -0,0 +1,204 @@
+/**
+ * Created by ApigeeCorporation on 12/4/14.
+ */
+/*
+ * 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.usergrid.rest.test.resource2point0.model;
+
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion;
+
+
+public class ApiResponse {
+
+    private String accessToken;
+
+    private String error;
+    private String errorDescription;
+    private String errorUri;
+    private String exception;
+
+    private String path;
+    private String uri;
+    private String status;
+    private long timestamp;
+    private List<Entity> entities;
+    private String cursor;
+
+
+    private final Map<String, JsonNode> properties = new HashMap<String, JsonNode>();
+
+
+    public ApiResponse() {
+    }
+
+
+    @JsonAnyGetter
+    public Map<String, JsonNode> getProperties() {
+        return properties;
+    }
+
+
+    @JsonAnySetter
+    public void setProperty( String key, JsonNode value ) {
+        properties.put( key, value );
+    }
+
+
+    @JsonProperty( "access_token" )
+    @JsonSerialize( include = Inclusion.NON_NULL )
+    public String getAccessToken() {
+        return accessToken;
+    }
+
+
+    @JsonProperty( "access_token" )
+    public void setAccessToken( String accessToken ) {
+        this.accessToken = accessToken;
+    }
+
+
+    @JsonSerialize( include = Inclusion.NON_NULL )
+    public String getError() {
+        return error;
+    }
+
+
+    public void setError( String error ) {
+        this.error = error;
+    }
+
+
+    @JsonSerialize( include = Inclusion.NON_NULL )
+    @JsonProperty( "error_description" )
+    public String getErrorDescription() {
+        return errorDescription;
+    }
+
+
+    @JsonProperty( "error_description" )
+    public void setErrorDescription( String errorDescription ) {
+        this.errorDescription = errorDescription;
+    }
+
+
+    @JsonSerialize( include = Inclusion.NON_NULL )
+    @JsonProperty( "error_uri" )
+    public String getErrorUri() {
+        return errorUri;
+    }
+
+
+    @JsonProperty( "error_uri" )
+    public void setErrorUri( String errorUri ) {
+        this.errorUri = errorUri;
+    }
+
+
+    @JsonSerialize( include = Inclusion.NON_NULL )
+    public String getException() {
+        return exception;
+    }
+
+
+    public void setException( String exception ) {
+        this.exception = exception;
+    }
+
+
+    @JsonSerialize( include = Inclusion.NON_NULL )
+    public String getPath() {
+        return path;
+    }
+
+
+    public void setPath( String path ) {
+        this.path = path;
+    }
+
+
+    @JsonSerialize( include = Inclusion.NON_NULL )
+    public String getUri() {
+        return uri;
+    }
+
+
+    public void setUri( String uri ) {
+        this.uri = uri;
+    }
+
+
+    @JsonSerialize( include = Inclusion.NON_NULL )
+    public String getStatus() {
+        return status;
+    }
+
+
+    public void setStatus( String status ) {
+        this.status = status;
+    }
+
+
+    public long getTimestamp() {
+        return timestamp;
+    }
+
+
+    public void setTimestamp( long timestamp ) {
+        this.timestamp = timestamp;
+    }
+
+    @JsonSerialize( include = Inclusion.NON_NULL  )
+    public List<Entity> getEntities() {
+        return entities;
+    }
+
+
+    public void setEntities( List<Entity> entities ) {
+        this.entities = entities;
+    }
+
+
+    public int getEntityCount() {
+        if ( entities == null ) {
+            return 0;
+        }
+        return entities.size();
+    }
+
+    @JsonSerialize( include = Inclusion.NON_NULL )
+    public String getCursor() {
+        return cursor;
+    }
+
+
+    public void setCursor( String cursor ) {
+        this.cursor = cursor;
+    }
+
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6a2b2846/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/model/Entity.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/model/Entity.java b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/model/Entity.java
new file mode 100644
index 0000000..1bbeb60
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/model/Entity.java
@@ -0,0 +1,346 @@
+/**
+ * Created by ApigeeCorporation on 12/4/14.
+ */
+/*
+ * 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.usergrid.rest.test.resource2point0.model;
+
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.UUID;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.usergrid.persistence.EntityFactory;
+import org.apache.usergrid.persistence.Schema;
+import org.apache.usergrid.persistence.annotations.EntityProperty;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+import static org.apache.usergrid.persistence.Schema.PROPERTY_NAME;
+import static org.apache.usergrid.persistence.Schema.PROPERTY_TYPE;
+import static org.apache.usergrid.persistence.Schema.PROPERTY_URI;
+import static org.apache.usergrid.persistence.Schema.PROPERTY_UUID;
+
+
+/**
+ * Entities are the base object type in the service.
+ */
+
+//@JsonPropertyOrder({ PROPERTY_UUID, PROPERTY_TYPE, PROPERTY_URI, PROPERTY_NAME })
+@XmlRootElement
+public class Entity implements Serializable {
+
+    protected UUID uuid;
+
+    protected Long created;
+
+    protected Long modified;
+
+    protected String type;
+
+    protected Map<String, Object> dynamic_properties = new TreeMap<String, Object>( String.CASE_INSENSITIVE_ORDER );
+
+    protected Map<String, Set<Object>> dynamic_sets = new TreeMap<String, Set<Object>>( String.CASE_INSENSITIVE_ORDER );
+
+
+    @EntityProperty( required = true, mutable = false, basic = true, indexed = false )
+    @JsonSerialize( include = JsonSerialize.Inclusion.NON_NULL )
+    public UUID getUuid() {
+        return uuid;
+    }
+
+
+    public void setUuid( UUID uuid ) {
+        this.uuid = uuid;
+    }
+
+
+    @EntityProperty( required = true, mutable = false, basic = true, indexed = false )
+    public String getType() {
+        return type;
+        //return Schema.getDefaultSchema().getEntityType( this.getClass() );
+    }
+
+
+    public void setType( String type ) {
+        this.type = type;
+    }
+
+
+    @EntityProperty( indexed = true, required = true, mutable = false )
+    @JsonSerialize( include = JsonSerialize.Inclusion.NON_NULL )
+    public Long getCreated() {
+        return created;
+    }
+
+
+    public void setCreated( Long created ) {
+        if ( created == null ) {
+            created = System.currentTimeMillis();
+        }
+        this.created = created;
+    }
+
+
+    @EntityProperty( indexed = true, required = true, mutable = true )
+    @JsonSerialize( include = JsonSerialize.Inclusion.NON_NULL )
+    public Long getModified() {
+        return modified;
+    }
+
+
+    public void setModified( Long modified ) {
+        if ( modified == null ) {
+            modified = System.currentTimeMillis();
+        }
+        this.modified = modified;
+    }
+
+
+    @JsonSerialize( include = JsonSerialize.Inclusion.NON_NULL )
+    public String getName() {
+        Object value = getProperty( PROPERTY_NAME );
+
+        if ( value instanceof UUID ) {
+            // fixes existing data that uses UUID in USERGRID-2099
+            return value.toString();
+        }
+
+        return ( String ) value;
+    }
+
+
+    @JsonIgnore
+    public Map<String, Object> getProperties() {
+        return dynamic_properties;
+    }
+
+
+    public final Object getProperty( String propertyName ) {
+        return dynamic_properties.get( propertyName );
+    }
+
+
+    public final void setProperty( String propertyName, Object propertyValue ) {
+        if ( propertyValue == null || propertyValue.equals( "" ) ) {
+            if ( dynamic_properties.containsKey( propertyName ) ) {
+                dynamic_properties.remove( propertyName );
+            }
+        }
+        else {
+            dynamic_properties.put( propertyName, propertyValue );
+        }
+    }
+
+
+    public void setProperties( Map<String, Object> properties ) {
+        dynamic_properties = new TreeMap<String, Object>( String.CASE_INSENSITIVE_ORDER );
+        addProperties( properties );
+    }
+
+
+    public void addProperties( Map<String, Object> properties ) {
+        if ( properties == null ) {
+            return;
+        }
+        for ( Map.Entry<String, Object> entry : properties.entrySet() ) {
+            setProperty( entry.getKey(), entry.getValue() );
+        }
+    }
+
+
+    @JsonSerialize( include = JsonSerialize.Inclusion.NON_NULL )
+    public Object getMetadata( String key ) {
+        return getDataset( "metadata", key );
+    }
+
+
+    public void setMetadata( String key, Object value ) {
+        setDataset( "metadata", key, value );
+    }
+
+
+    public void mergeMetadata( Map<String, Object> new_metadata ) {
+        mergeDataset( "metadata", new_metadata );
+    }
+
+
+    public void clearMetadata() {
+        clearDataset( "metadata" );
+    }
+
+
+    public <T> T getDataset( String property, String key ) {
+        Object md = dynamic_properties.get( property );
+        if ( md == null ) {
+            return null;
+        }
+        if ( !( md instanceof Map<?, ?> ) ) {
+            return null;
+        }
+        @SuppressWarnings( "unchecked" ) Map<String, T> metadata = ( Map<String, T> ) md;
+        return metadata.get( key );
+    }
+
+
+    public <T> void setDataset( String property, String key, T value ) {
+        if ( key == null ) {
+            return;
+        }
+        Object md = dynamic_properties.get( property );
+        if ( !( md instanceof Map<?, ?> ) ) {
+            md = new HashMap<String, T>();
+            dynamic_properties.put( property, md );
+        }
+        @SuppressWarnings( "unchecked" ) Map<String, T> metadata = ( Map<String, T> ) md;
+        metadata.put( key, value );
+    }
+
+
+    public <T> void mergeDataset( String property, Map<String, T> new_metadata ) {
+        Object md = dynamic_properties.get( property );
+        if ( !( md instanceof Map<?, ?> ) ) {
+            md = new HashMap<String, T>();
+            dynamic_properties.put( property, md );
+        }
+        @SuppressWarnings( "unchecked" ) Map<String, T> metadata = ( Map<String, T> ) md;
+        metadata.putAll( new_metadata );
+    }
+
+
+    public void clearDataset( String property ) {
+        dynamic_properties.remove( property );
+    }
+
+
+    public List<org.apache.usergrid.persistence.Entity> getCollections( String key ) {
+        return getDataset( "collections", key );
+    }
+
+
+    public void setCollections( String key, List<org.apache.usergrid.persistence.Entity> results ) {
+        setDataset( "collections", key, results );
+    }
+
+
+    public List<org.apache.usergrid.persistence.Entity> getConnections( String key ) {
+        return getDataset( "connections", key );
+    }
+
+
+    public void setConnections( String key, List<org.apache.usergrid.persistence.Entity> results ) {
+        setDataset( "connections", key, results );
+    }
+
+
+    public String toString() {
+        return "Entity(" + getProperties() + ")";
+    }
+
+
+    @JsonAnySetter
+    public void setDynamicProperty( String key, Object value ) {
+        if ( value == null || value.equals( "" ) ) {
+            if ( dynamic_properties.containsKey( key ) ) {
+                dynamic_properties.remove( key );
+            }
+        }
+        else {
+            dynamic_properties.put( key, value );
+        }
+    }
+
+
+    @JsonAnyGetter
+    public Map<String, Object> getDynamicProperties() {
+        return dynamic_properties;
+    }
+
+
+    public final int compareTo( org.apache.usergrid.persistence.Entity o ) {
+        if ( o == null ) {
+            return 1;
+        }
+        try {
+            long t1 = getUuid().timestamp();
+            long t2 = o.getUuid().timestamp();
+            return ( t1 < t2 ) ? -1 : ( t1 == t2 ) ? 0 : 1;
+        }
+        catch ( UnsupportedOperationException e ) {
+        }
+        return getUuid().compareTo( o.getUuid() );
+    }
+
+
+    public org.apache.usergrid.persistence.Entity toTypedEntity() {
+        org.apache.usergrid.persistence.Entity entity = EntityFactory.newEntity( getUuid(), getType() );
+        entity.setProperties( getProperties() );
+        return entity;
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#hashCode()
+     */
+
+
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ( ( uuid == null ) ? 0 : uuid.hashCode() );
+        return result;
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+
+    //    public boolean equals( Object obj ) {
+    //        if ( this == obj ) {
+    //            return true;
+    //        }
+    //        if ( obj == null ) {
+    //            return false;
+    //        }
+    //        if ( getClass() != obj.getClass() ) {
+    //            return false;
+    //        }
+    //        AbstractEntity other = ( AbstractEntity ) obj;
+    //        if ( uuid == null ) {
+    //            if ( other.uuid != null ) {
+    //                return false;
+    //            }
+    //        }
+    //        else if ( !uuid.equals( other.uuid ) ) {
+    //            return false;
+    //        }
+    //        return true;
+    //    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6a2b2846/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/model/EntityResponse.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/model/EntityResponse.java b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/model/EntityResponse.java
new file mode 100644
index 0000000..2f3406a
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/model/EntityResponse.java
@@ -0,0 +1,132 @@
+/**
+ * Created by ApigeeCorporation on 12/4/14.
+ */
+/*
+ * 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.usergrid.rest.test.resource2point0.model;
+
+
+
+
+
+        import java.util.Iterator;
+
+        import org.apache.usergrid.rest.test.resource2point0.endpoints.Collection;
+
+        import com.google.common.base.Optional;
+
+
+/**
+ * A stateful iterable collection response.  This is a "collection" of entities from our response that are easier
+ * to work with. The Generic means that we can type cast the iterator.
+ * Keep generics? Maybe just use entities for now
+ * 1.) Primary key
+ * 2.) Default data-> default data is different from type to type. (Groups would need path and title, Activities require actors...etc)
+ * 3.) Things that you can do with them-> Groups create connections or something else. Adding users to a group. ( this can be boiled down to creating a connection )
+ *
+ * Two connecting builder patterns
+ * 1. POST /collection/entity/verb (e.g. likes or following)/collection/entity  //connect any two entities
+ *  - POST /users/fred/following/users/barney
+ * 2. POST /collection/entity/collection/entity //for built in collections e.g. add user to group, add role to group, etc
+ *  - POST users/fred/groups/funlovincriminals
+ *
+ * Two similar builder patterns for getting connected entities
+ * 1. GET /users/fred/following
+ * 2. GET /users/fred/groups
+ *
+ */
+public class EntityResponse implements Iterable<Entity>, Iterator<Entity> {
+
+    private final Collection sourceEndpoint;
+
+    private String cursor;
+
+    public Iterator entities;
+
+
+    /**
+     * Use the factory method instead
+     * @param sourceCollection
+     */
+    private EntityResponse( final Collection sourceCollection ){
+        this.sourceEndpoint = sourceCollection;
+        loadPage();
+    }
+
+
+    @Override
+    public Iterator iterator() {
+        return this;
+    }
+
+
+    @Override
+    public boolean hasNext() {
+        if(!entities.hasNext()){
+            advance();
+        }
+
+        return entities.hasNext();
+    }
+
+
+    @Override
+    public Entity next() {
+        return (Entity)entities.next();
+    }
+
+
+    /**
+     * Go back to the endpoint and try to load the next page
+     */
+    private void advance(){
+
+
+        //no next page
+        if(cursor == null){
+            return;
+        }
+
+        loadPage();
+
+
+    }
+
+    private void loadPage(){
+        final ApiResponse response = sourceEndpoint.get( Optional.of(cursor));
+
+        cursor = response.getCursor();
+    }
+
+
+    @Override
+    public void remove() {
+        throw new UnsupportedOperationException( "Remove is unsupported" );
+    }
+
+
+    /**
+     * Create a new instance of the iterator (uninitialized) from the collection
+     * @param collection
+     * @return The iterator
+     */
+    public static EntityResponse fromCollection(final Collection collection){
+        return new EntityResponse(collection);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6a2b2846/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/state/ClientContext.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/state/ClientContext.java b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/state/ClientContext.java
new file mode 100644
index 0000000..588dedf
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource2point0/state/ClientContext.java
@@ -0,0 +1,19 @@
+package org.apache.usergrid.rest.test.resource2point0.state;
+
+
+/**
+ * Context to hold client stateful information
+ */
+public class ClientContext {
+    private String token;
+
+
+    public String getToken() {
+        return token;
+    }
+
+
+    public void setToken( final String token ) {
+        this.token = token;
+    }
+}