changeset 234:0e22b21cfe6c

Refactor jvm-memory and jvm-gc endpoints to use path-based query This series of patches brings the jvm-gc and jvm-memory APIs in line with the other web services. Previously, you would GET or PUT ? https://host**/jvm-memory/0.0.2?query=jvmId=={jvmId} (properly escaped, of course). Now, you call ? https://host/jvm-memory/0.0.3/systems/{systemId}/jvms/{jvmId}. In addition, I've added a new endpoint (valid for GET only) ? https://host/jvm-memory/0.0.3/jvms/{jvmId} ...which is easier for the web client to call.? I didn't implement this for POST, etc. Reviewed-by: aazores, jkang Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-August/024586.html
author Simon Tooke <stooke@redhat.com>
date Fri, 25 Aug 2017 09:59:56 -0400
parents f872349e7038
children 3fed9a0827ac
files common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/servlet/MongoHttpHandlerHelper.java services/jvm-gc/src/main/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcHttpHandler.java services/jvm-gc/src/main/resources/jvm-gc-swagger.yaml services/jvm-gc/src/main/webapp/WEB-INF/web.xml services/jvm-memory/src/main/java/com/redhat/thermostat/gateway/service/jvm/memory/JvmMemoryHttpHandler.java services/jvm-memory/src/main/resources/jvm-memory-swagger.yaml services/jvm-memory/src/main/webapp/WEB-INF/web.xml tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcServiceIntegrationTest.java tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/memory/JvmMemoryServiceIntegrationTest.java
diffstat 9 files changed, 837 insertions(+), 229 deletions(-) [+]
line wrap: on
line diff
--- a/common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/servlet/MongoHttpHandlerHelper.java	Wed Aug 23 13:43:11 2017 +0200
+++ b/common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/servlet/MongoHttpHandlerHelper.java	Fri Aug 25 09:59:56 2017 -0400
@@ -166,6 +166,10 @@
         return handlePost(httpServletRequest, context, systemId, null, returnMetadata, body);
     }
 
+    public Response handlePostWithJvmID(HttpServletRequest httpServletRequest, ServletContext context, String systemId, String jvmId, String returnMetadata, String body) {
+        return handlePost(httpServletRequest, context, systemId, jvmId, returnMetadata, body);
+    }
+
     public Response handlePost(HttpServletRequest httpServletRequest, ServletContext context, String returnMetadata, String body) {
         return handlePost(httpServletRequest, context, null, null, returnMetadata, body);
     }
--- a/services/jvm-gc/src/main/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcHttpHandler.java	Wed Aug 23 13:43:11 2017 +0200
+++ b/services/jvm-gc/src/main/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcHttpHandler.java	Fri Aug 25 09:59:56 2017 -0400
@@ -45,6 +45,7 @@
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
@@ -55,13 +56,35 @@
 
 @Path("/")
 public class JvmGcHttpHandler {
+
     private static final String collectionName = "jvm-gc";
     private final MongoHttpHandlerHelper serviceHelper = new MongoHttpHandlerHelper( collectionName );
 
     @GET
+    @Path("/jvms/{" + RequestParameters.JVM_ID +"}")
     @Consumes({ "application/json" })
     @Produces({ "application/json", "text/html; charset=utf-8" })
-    public Response getJvmGc(@QueryParam(RequestParameters.LIMIT) @DefaultValue("1") Integer limit,
+    public Response getJvmGc(@PathParam(RequestParameters.JVM_ID) String jvmId,
+                             @QueryParam(RequestParameters.LIMIT) @DefaultValue("1") Integer limit,
+                             @QueryParam(RequestParameters.OFFSET) @DefaultValue("0") Integer offset,
+                             @QueryParam(RequestParameters.SORT) String sort,
+                             @QueryParam(RequestParameters.QUERY) String queries,
+                             @QueryParam(RequestParameters.INCLUDE) String includes,
+                             @QueryParam(RequestParameters.EXCLUDE) String excludes,
+                             @QueryParam(RequestParameters.METADATA) @DefaultValue("false") String metadata,
+                             @Context HttpServletRequest httpServletRequest,
+                             @Context ServletContext context) {
+        return serviceHelper.handleGetWithJvmID(httpServletRequest, context, null, jvmId, limit, offset, sort, queries, includes, excludes, metadata);
+    }
+
+
+    @GET
+    @Path("/systems/{" + RequestParameters.SYSTEM_ID +"}/jvms/{" + RequestParameters.JVM_ID +"}")
+    @Consumes({ "application/json" })
+    @Produces({ "application/json", "text/html; charset=utf-8" })
+    public Response getJvmGc(@PathParam(RequestParameters.SYSTEM_ID) String systemId,
+                             @PathParam(RequestParameters.JVM_ID) String jvmId,
+                             @QueryParam(RequestParameters.LIMIT) @DefaultValue("1") Integer limit,
                              @QueryParam(RequestParameters.OFFSET) @DefaultValue("0") Integer offset,
                              @QueryParam(RequestParameters.SORT) String sort,
                              @QueryParam(RequestParameters.QUERY) String queries,
@@ -70,37 +93,46 @@
                              @QueryParam(RequestParameters.METADATA) @DefaultValue("false") String metadata,
                              @Context HttpServletRequest httpServletRequest,
                              @Context ServletContext context) {
-        return serviceHelper.handleGet(httpServletRequest, context, limit, offset, sort, queries, includes, excludes, metadata);
+        return serviceHelper.handleGetWithJvmID(httpServletRequest, context, systemId, jvmId, limit, offset, sort, queries, includes, excludes, metadata);
     }
 
     @PUT
+    @Path("/systems/{" + RequestParameters.SYSTEM_ID +"}/jvms/{" + RequestParameters.JVM_ID +"}")
     @Consumes({ "application/json" })
     @Produces({ "application/json", "text/html; charset=utf-8" })
     public Response putJvmGc(String body,
+                             @PathParam(RequestParameters.SYSTEM_ID) String systemId,
+                             @PathParam(RequestParameters.JVM_ID) String jvmId,
                              @QueryParam(RequestParameters.QUERY) String queries,
                              @QueryParam(RequestParameters.METADATA) @DefaultValue("false") String metadata,
                              @Context ServletContext context,
                              @Context HttpServletRequest httpServletRequest) {
-        return serviceHelper.handlePut(httpServletRequest, context, queries, metadata, body);
+        return serviceHelper.handlePutWithJvmId(httpServletRequest, context, systemId, jvmId, queries, metadata, body);
     }
 
     @POST
+    @Path("/systems/{" + RequestParameters.SYSTEM_ID +"}/jvms/{" + RequestParameters.JVM_ID +"}")
     @Consumes({ "application/json" })
     @Produces({ "application/json", "text/html; charset=utf-8" })
     public Response postJvmGc(String body,
+                              @PathParam(RequestParameters.SYSTEM_ID) String systemId,
+                              @PathParam(RequestParameters.JVM_ID) String jvmId,
                               @QueryParam(RequestParameters.METADATA) @DefaultValue("false") String metadata,
                               @Context ServletContext context,
                               @Context HttpServletRequest httpServletRequest) {
-        return serviceHelper.handlePost(httpServletRequest, context, metadata, body);
+        return serviceHelper.handlePostWithJvmID(httpServletRequest, context, systemId, jvmId, metadata, body);
     }
 
     @DELETE
+    @Path("/systems/{" + RequestParameters.SYSTEM_ID +"}/jvms/{" + RequestParameters.JVM_ID +"}")
     @Consumes({ "application/json" })
     @Produces({ "application/json", "text/html; charset=utf-8" })
-    public Response deleteJvmGc(@QueryParam(RequestParameters.QUERY) String queries,
+    public Response deleteJvmGc(@PathParam(RequestParameters.SYSTEM_ID) String systemId,
+                                @PathParam(RequestParameters.JVM_ID) String jvmId,
+                                @QueryParam(RequestParameters.QUERY) String queries,
                                 @QueryParam(RequestParameters.METADATA) @DefaultValue("false") String metadata,
                                 @Context ServletContext context,
                                 @Context HttpServletRequest httpServletRequest) {
-        return serviceHelper.handleDelete(httpServletRequest, context, queries, metadata);
+        return serviceHelper.handleDeleteWithJvmID(httpServletRequest, context, systemId, jvmId, queries, metadata);
     }
 }
--- a/services/jvm-gc/src/main/resources/jvm-gc-swagger.yaml	Wed Aug 23 13:43:11 2017 +0200
+++ b/services/jvm-gc/src/main/resources/jvm-gc-swagger.yaml	Fri Aug 25 09:59:56 2017 -0400
@@ -10,11 +10,32 @@
 produces:
   - application/json
   - text/html; charset=utf-8
-basePath: /jvm-gc/0.0.2
+basePath: /jvm-gc/0.0.3
 paths:
-  /:
+  /jvms/{jvmId}:
     parameters:
       - $ref: '#/parameters/thermostat-realms'
+      - $ref: '#/parameters/jvm-id'
+    get:
+      description: Get jvm gc information.
+      parameters:
+        - $ref: '#/parameters/limit'
+        - $ref: '#/parameters/offset'
+        - $ref: '#/parameters/sort'
+        - $ref: '#/parameters/include'
+        - $ref: '#/parameters/exclude'
+        - $ref: '#/parameters/query'
+        - $ref: '#/parameters/metadata'
+      responses:
+        '200':
+          description: OK
+          schema:
+            $ref: '#/definitions/jvm-gc-stats-response'
+  /systems/{systemId}/jvms/{jvmId}:
+    parameters:
+      - $ref: '#/parameters/thermostat-realms'
+      - $ref: '#/parameters/system-id'
+      - $ref: '#/parameters/jvm-id'
     get:
       description: Get jvm gc information.
       parameters:
@@ -65,6 +86,8 @@
   jvm-gc-stats-response:
     type: object
     properties:
+      fred:
+          type: string
       response:
           $ref: '#/definitions/jvm-gc-stats'
       metadata:
@@ -127,6 +150,16 @@
       "set":
         type: object
 parameters:
+  system-id:
+    name: systemId
+    in: path
+    required: true
+    type: string
+  jvm-id:
+    name: jvmId
+    in: path
+    required: true
+    type: string
   jvm-gc-stats:
     name: jvm-gc-stats
     in: body
@@ -192,4 +225,4 @@
     name: X-Thermostat-Realms
     type: string
     in: header
-    description: "Realms Header used to specify a subset of roles to use for Keycloak authorization. Attempts to specify realms that the client does not have, or no valid realms at all will result in a 400 Bad Request response. Expects a space separated list of realms. Example 'X-Thermostat-Realms: realm-one realm-two'"
\ No newline at end of file
+    description: "Realms Header used to specify a subset of roles to use for Keycloak authorization. Attempts to specify realms that the client does not have, or no valiod realms at all will result in a 400 Bad Request response. Expects a space separated list of realms. Example 'X-Thermostat-Realms: realm-one realm-two'"
\ No newline at end of file
--- a/services/jvm-gc/src/main/webapp/WEB-INF/web.xml	Wed Aug 23 13:43:11 2017 +0200
+++ b/services/jvm-gc/src/main/webapp/WEB-INF/web.xml	Fri Aug 25 09:59:56 2017 -0400
@@ -57,7 +57,7 @@
         <filter-class>com.redhat.thermostat.gateway.common.core.servlet.ServiceVersionFilter</filter-class>
         <init-param>
             <param-name>version</param-name>
-            <param-value>0.0.2</param-value>
+            <param-value>0.0.3</param-value>
         </init-param>
     </filter>
     <filter-mapping>
@@ -66,7 +66,7 @@
     </filter-mapping>
     <servlet-mapping>
         <servlet-name>JvmGcServlet</servlet-name>
-        <url-pattern>/0.0.2/*</url-pattern>
+        <url-pattern>/0.0.3/*</url-pattern>
     </servlet-mapping>
     <!-- Service configuration -->
     <context-param>
--- a/services/jvm-memory/src/main/java/com/redhat/thermostat/gateway/service/jvm/memory/JvmMemoryHttpHandler.java	Wed Aug 23 13:43:11 2017 +0200
+++ b/services/jvm-memory/src/main/java/com/redhat/thermostat/gateway/service/jvm/memory/JvmMemoryHttpHandler.java	Fri Aug 25 09:59:56 2017 -0400
@@ -45,6 +45,7 @@
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
@@ -60,9 +61,29 @@
     private final MongoHttpHandlerHelper serviceHelper = new MongoHttpHandlerHelper( collectionName );
 
     @GET
+    @Path("/jvms/{" + RequestParameters.JVM_ID +"}")
     @Consumes({ "application/json" })
     @Produces({ "application/json", "text/html; charset=utf-8" })
-    public Response getJvmMemory(@QueryParam(RequestParameters.LIMIT) @DefaultValue("1") Integer limit,
+    public Response getJvmMemory(@PathParam(RequestParameters.JVM_ID) String jvmId,
+                                 @QueryParam(RequestParameters.LIMIT) @DefaultValue("1") Integer limit,
+                                 @QueryParam(RequestParameters.OFFSET) @DefaultValue("0") OffsetParameter offsetParam,
+                                 @QueryParam(RequestParameters.SORT) String sort,
+                                 @QueryParam(RequestParameters.QUERY) String queries,
+                                 @QueryParam(RequestParameters.INCLUDE) String includes,
+                                 @QueryParam(RequestParameters.EXCLUDE) String excludes,
+                                 @QueryParam(RequestParameters.METADATA) @DefaultValue("false") String metadata,
+                                 @Context ServletContext context,
+                                 @Context HttpServletRequest httpServletRequest) {
+        return serviceHelper.handleGetWithJvmID(httpServletRequest, context, null, jvmId, limit, offsetParam.getValue(), sort, queries, includes, excludes, metadata);
+    }
+
+    @GET
+    @Path("/systems/{" + RequestParameters.SYSTEM_ID +"}/jvms/{" + RequestParameters.JVM_ID +"}")
+    @Consumes({ "application/json" })
+    @Produces({ "application/json", "text/html; charset=utf-8" })
+    public Response getJvmMemory(@PathParam(RequestParameters.SYSTEM_ID) String systemId,
+                                 @PathParam(RequestParameters.JVM_ID) String jvmId,
+                                 @QueryParam(RequestParameters.LIMIT) @DefaultValue("1") Integer limit,
                                  @QueryParam(RequestParameters.OFFSET) @DefaultValue("0") OffsetParameter offsetParam,
                                  @QueryParam(RequestParameters.SORT) String sort,
                                  @QueryParam(RequestParameters.QUERY) String queries,
@@ -71,37 +92,46 @@
                                  @QueryParam(RequestParameters.METADATA) @DefaultValue("false") String metadata,
                                  @Context ServletContext context,
                                  @Context HttpServletRequest httpServletRequest) {
-        return serviceHelper.handleGet(httpServletRequest, context, limit, offsetParam.getValue(), sort, queries, includes, excludes, metadata);
+        return serviceHelper.handleGetWithJvmID(httpServletRequest, context, systemId, jvmId, limit, offsetParam.getValue(), sort, queries, includes, excludes, metadata);
     }
 
     @PUT
+    @Path("/systems/{" + RequestParameters.SYSTEM_ID +"}/jvms/{" + RequestParameters.JVM_ID +"}")
     @Consumes({ "application/json" })
     @Produces({ "application/json", "text/html; charset=utf-8" })
     public Response putJvmMemory(String body,
+                                 @PathParam(RequestParameters.SYSTEM_ID) String systemId,
+                                 @PathParam(RequestParameters.JVM_ID) String jvmId,
                                  @QueryParam(RequestParameters.QUERY) String queries,
                                  @QueryParam(RequestParameters.METADATA) @DefaultValue("false") String metadata,
                                  @Context ServletContext context,
                                  @Context HttpServletRequest httpServletRequest) {
-        return serviceHelper.handlePut(httpServletRequest, context, queries, metadata, body);
+        return serviceHelper.handlePutWithJvmId(httpServletRequest, context, systemId, jvmId, queries, metadata, body);
     }
 
     @POST
+    @Path("/systems/{" + RequestParameters.SYSTEM_ID +"}/jvms/{" + RequestParameters.JVM_ID +"}")
     @Consumes({ "application/json" })
     @Produces({ "application/json", "text/html; charset=utf-8" })
     public Response postJvmMemory(String body,
+                                  @PathParam(RequestParameters.SYSTEM_ID) String systemId,
+                                  @PathParam(RequestParameters.JVM_ID) String jvmId,
                                   @QueryParam(RequestParameters.METADATA) @DefaultValue("false") String metadata,
                                   @Context ServletContext context,
                                   @Context HttpServletRequest httpServletRequest) {
-        return serviceHelper.handlePost(httpServletRequest, context, metadata, body);
+        return serviceHelper.handlePostWithJvmID(httpServletRequest, context, systemId, jvmId, metadata, body);
     }
 
     @DELETE
+    @Path("/systems/{" + RequestParameters.SYSTEM_ID +"}/jvms/{" + RequestParameters.JVM_ID +"}")
     @Consumes({ "application/json" })
     @Produces({ "application/json", "text/html; charset=utf-8" })
-    public Response deleteJvmMemory(@QueryParam(RequestParameters.QUERY) String queries,
+    public Response deleteJvmMemory(@PathParam(RequestParameters.SYSTEM_ID) String systemId,
+                                    @PathParam(RequestParameters.JVM_ID) String jvmId,
+                                    @QueryParam(RequestParameters.QUERY) String queries,
                                     @QueryParam(RequestParameters.METADATA) @DefaultValue("false") String metadata,
                                     @Context ServletContext context,
                                     @Context HttpServletRequest httpServletRequest) {
-        return serviceHelper.handleDelete(httpServletRequest, context, queries, metadata);
+        return serviceHelper.handleDeleteWithJvmID(httpServletRequest, context, systemId, jvmId, queries, metadata);
     }
 }
--- a/services/jvm-memory/src/main/resources/jvm-memory-swagger.yaml	Wed Aug 23 13:43:11 2017 +0200
+++ b/services/jvm-memory/src/main/resources/jvm-memory-swagger.yaml	Fri Aug 25 09:59:56 2017 -0400
@@ -10,9 +10,32 @@
 produces:
   - application/json
   - text/html; charset=utf-8
-basePath: /jvm-memory/0.0.2
+basePath: /jvm-memory/0.0.3
 paths:
-  /:
+  /jvms/{jvmId}:
+    parameters:
+      - $ref: '#/parameters/thermostat-realms'
+      - $ref: '#/parameters/jvm-id'
+    get:
+      description: Get jvm memory information.
+      parameters:
+        - $ref: '#/parameters/limit'
+        - $ref: '#/parameters/offset'
+        - $ref: '#/parameters/sort'
+        - $ref: '#/parameters/include'
+        - $ref: '#/parameters/exclude'
+        - $ref: '#/parameters/query'
+        - $ref: '#/parameters/metadata'
+      responses:
+        '200':
+          description: OK
+          schema:
+            $ref: '#/definitions/jvm-memory-stats-response'
+  /systems/{systemId}/jvms/{jvmId}:
+    parameters:
+      - $ref: '#/parameters/thermostat-realms'
+      - $ref: '#/parameters/system-id'
+      - $ref: '#/parameters/jvm-id'
     get:
       description: Get jvm memory information.
       parameters:
@@ -158,6 +181,16 @@
       "set":
         type: object
 parameters:
+  system-id:
+    name: systemId
+    in: path
+    required: true
+    type: string
+  jvm-id:
+    name: jvmId
+    in: path
+    required: true
+    type: string
   jvm-memory-stats:
     name: jvm-memory-stats
     in: body
@@ -218,4 +251,9 @@
     name: metadata
     type: boolean
     in: query
-    description: "Metadata flag. If set to 'true', the subsequent request response will return metadata information. If set to 'false', such metadata information will be omitted."
\ No newline at end of file
+    description: "Metadata flag. If set to 'true', the subsequent request response will return metadata information. If set to 'false', such metadata information will be omitted."
+  thermostat-realms:
+      name: X-Thermostat-Realms
+      type: string
+      in: header
+      description: "Realms Header used to specify a subset of roles to use for Keycloak authorization. Attempts to specify realms that the client does not have, or no valid realms at all will result in a 400 Bad Request response. Expects a space separated list of realms. Example 'X-Thermostat-Realms: realm-one realm-two'"
--- a/services/jvm-memory/src/main/webapp/WEB-INF/web.xml	Wed Aug 23 13:43:11 2017 +0200
+++ b/services/jvm-memory/src/main/webapp/WEB-INF/web.xml	Fri Aug 25 09:59:56 2017 -0400
@@ -57,7 +57,7 @@
         <filter-class>com.redhat.thermostat.gateway.common.core.servlet.ServiceVersionFilter</filter-class>
         <init-param>
             <param-name>version</param-name>
-            <param-value>0.0.2</param-value>
+            <param-value>0.0.3</param-value>
         </init-param>
     </filter>
     <filter-mapping>
@@ -66,7 +66,7 @@
     </filter-mapping>
     <servlet-mapping>
         <servlet-name>JvmMemoryServlet</servlet-name>
-        <url-pattern>/0.0.2/*</url-pattern>
+        <url-pattern>/0.0.3/*</url-pattern>
     </servlet-mapping>
     <!-- Service configuration -->
     <context-param>
--- a/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcServiceIntegrationTest.java	Wed Aug 23 13:43:11 2017 +0200
+++ b/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcServiceIntegrationTest.java	Fri Aug 25 09:59:56 2017 -0400
@@ -39,19 +39,28 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.lang.reflect.Type;
+import java.util.ArrayList;
 import java.util.List;
+import java.util.UUID;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
 
 import com.redhat.thermostat.gateway.common.core.auth.basic.BasicRealmAuthorizer;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
 import com.redhat.thermostat.gateway.common.mongodb.servlet.RequestParameters;
 import com.redhat.thermostat.gateway.tests.integration.MongoIntegrationTest;
 import org.bson.Document;
 import org.eclipse.jetty.client.api.ContentResponse;
+import org.eclipse.jetty.client.api.Request;
 import org.eclipse.jetty.client.util.StringContentProvider;
+import org.eclipse.jetty.http.HttpHeader;
 import org.eclipse.jetty.http.HttpMethod;
 import org.junit.Test;
 
@@ -65,11 +74,22 @@
 public class JvmGcServiceIntegrationTest extends MongoIntegrationTest {
 
     private static final String serviceName = "jvm-gc";
-    private static final String versionNumber = "0.0.2";
-    private static final String gcUrl = baseUrl + "/" + serviceName + "/" + versionNumber;
+    private static final String versionNumber = "0.0.3";
+    private static final int HTTP_200_OK = 200;
+    private static final int HTTP_404_NOTFOUND = 404;
+
     private final String data = "[{ \"a\" : \"test\", \"b\" : \"test1\", \"c\" : \"test2\" }, { \"d\" : \"test3\"}," +
             "{\"e\" : \"test4\" }]";
 
+    private final String jsonData =
+            "{\n" +
+            "   \"timeStamp\" : " + TIMESTAMP_TOKEN + ",\n" +
+            "   \"jvmId\" : " + JVMID_TOKEN + ",\n" +
+            "   \"collectorName\" : \"some-collection\",\n" +
+            "   \"runCount\" : \"22\",\n" +
+            "   \"wallTimeInMicros\" : \"333333\"\n" +
+            "}\n";
+
     private static final String QUERY_PREFIX = "query";
     private static final String LIMIT_PREFIX = "limit";
     private static final String SORT_PREFIX = "sort";
@@ -77,6 +97,16 @@
     private static final String METADATA_PREFIX = "metadata";
     private static final String INCLUDE_PREFIX = "include";
     private static final String IEXCLUDE_PREFIX = "exclude";
+    private static final String TIMESTAMP_TOKEN = "\"$TIMESTAMP$\"";
+    private static final String JVMID_TOKEN = "\"$JVMID_TOKEN\"";
+
+    private final String AGENT_ID = getRandomSystemId();
+    private final String JVM_ID = getRandomJvmId();
+    private long timeStamp = java.lang.System.nanoTime();
+
+    private final String simpleUrl = baseUrl + "/" + serviceName + "/" + versionNumber;
+    private final String serviceUrl = simpleUrl + "/systems/" + AGENT_ID + "/jvms/" + JVM_ID;
+    private final String SYSTEM_JVM_FRAGMENT = ",\"systemId\":\"" + AGENT_ID + "\",\"jvmId\":\"" + JVM_ID + "\"";
 
     public JvmGcServiceIntegrationTest() {
         super(serviceName + "/" + versionNumber, serviceName);
@@ -98,63 +128,134 @@
             throws InterruptedException, TimeoutException, ExecutionException {
 
         StringContentProvider stringContentProvider = new StringContentProvider(dataToSend, "UTF-8");
-        ContentResponse postResponse = client.newRequest(gcUrl + urlQuery).method(httpMethod)
+        ContentResponse postResponse = client.newRequest(serviceUrl + urlQuery).method(httpMethod)
                 .content(stringContentProvider, dataType)
                 .send();
         assertEquals(expectedStatus, postResponse.getStatus());
 
         if (!expectedResponse.equals("")) {
-            makeHttpGetRequest(gcUrl, expectedResponse, expectedStatus);
+            makeHttpGetRequest(serviceUrl, expectedResponse, expectedStatus);
         }
     }
 
     @Test
+    public void testGetUnknown() throws InterruptedException, TimeoutException, ExecutionException {
+        getUnknown(getRandomSystemId(), getRandomJvmId());
+    }
+
+    @Test
+    public void testCreateOne() throws InterruptedException, TimeoutException, ExecutionException {
+
+        final String systemid = getRandomSystemId();
+        final String jvmid = getRandomJvmId();
+        post(systemid, jvmid);
+        getKnown(systemid, jvmid);
+    }
+
+    @Test
+    public void testPut() throws InterruptedException, TimeoutException, ExecutionException {
+
+        final String systemid = getRandomSystemId();
+        final String jvmid = getRandomJvmId();
+
+        final long timestamp = getTimestamp();
+
+        // create it
+        post(systemid, jvmid);
+
+        // retrieve it
+        final ContentResponse response1 = getKnown(systemid, jvmid);
+        final List<TinyJvmGc> list1 = parse(response1, jvmid);
+        assertEquals(1, list1.size());
+
+        // modify it
+        put(systemid, jvmid, timestamp+1);
+
+        // ensure it was changed
+        final ContentResponse response2 = getKnown(systemid, jvmid);
+        final List<TinyJvmGc> list2 = parse(response2, jvmid);
+        assertEquals(1, list2.size());
+    }
+
+    @Test
+    public void testDeleteUnknown() throws InterruptedException, TimeoutException, ExecutionException {
+        final String systemid = getRandomSystemId();
+        final String jvmid = getRandomJvmId();
+        // delete it
+        delete(systemid, jvmid);
+    }
+
+    @Test
+    public void testDeleteOne() throws InterruptedException, ExecutionException, TimeoutException {
+        final String systemid = getRandomSystemId();
+        final String jvmid = getRandomJvmId();
+
+        // create the new record
+        post(systemid, jvmid);
+
+        // check that it's there
+        getKnown(systemid, jvmid);
+
+        // delete it
+        delete(systemid, jvmid);
+
+        // check that it's not there
+        getUnknown(systemid, jvmid);
+    }
+
+
+
+    @Test
     public void testGet() throws InterruptedException, TimeoutException, ExecutionException {
         makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
-        makeHttpGetRequest(gcUrl,"{\"response\":[{\"a\":\"test\",\"b\":\"test1\","+
-                "\"c\":\"test2\"}]}", 200);
+        final String expectedResponse = "{\"response\":[{\"a\":\"test\",\"b\":\"test1\","+
+                "\"c\":\"test2\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        makeHttpGetRequest(serviceUrl, expectedResponse, 200);
     }
 
     @Test
     public void testGetLimitParam() throws InterruptedException, TimeoutException, ExecutionException {
         makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
-        makeHttpGetRequest(gcUrl + '?' + LIMIT_PREFIX + "=2","{\"response\":[{\"a\":\"test\",\"b\":"+
-                "\"test1\",\"c\":\"test2\"},{\"d\":\"test3\"}]}", 200);
+        final String expectedResponse = "{\"response\":[{\"a\":\"test\",\"b\":\"test1\",\"c\":\"test2\"" + SYSTEM_JVM_FRAGMENT + "}," +
+                "{\"d\":\"test3\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        makeHttpGetRequest(serviceUrl + '?' + LIMIT_PREFIX + "=2", expectedResponse, 200);
     }
 
     @Test
     public void testGetSortParam() throws InterruptedException, TimeoutException, ExecutionException {
-        String data ="[{\"a\":\"1\"}, {\"a\":\"2\"}]";
-
+        final String data ="[{\"a\":\"1\"}, {\"a\":\"2\"}]";
         makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
-        makeHttpGetRequest(gcUrl + '?' + LIMIT_PREFIX + "=2&" + SORT_PREFIX + "=-a","{\"response\":[{\"a\":\"2\"},{\"a\":"+
-                "\"1\"}]}", 200);
+        final String expectedResponse = "{\"response\":[{\"a\":\"2\"" + SYSTEM_JVM_FRAGMENT + "}," +
+                "{\"a\":\"1\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        makeHttpGetRequest(serviceUrl + '?' + LIMIT_PREFIX + "=2&" + SORT_PREFIX + "=-a", expectedResponse, 200);
     }
 
     @Test
     public void testGetProjectParam() throws InterruptedException, TimeoutException, ExecutionException {
         makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
-        makeHttpGetRequest(gcUrl + '?' + INCLUDE_PREFIX + "=b,c","{\"response\":[{\"b\":\"test1\",\"c\":"+
-                "\"test2\"}]}", 200);
+        final String expectedResponse = "{\"response\":[{\"b\":\"test1\",\"c\":\"test2\"}]}";
+        makeHttpGetRequest(serviceUrl + '?' + INCLUDE_PREFIX + "=b,c", expectedResponse, 200);
     }
 
     @Test
     public void testGetOffsetParam() throws InterruptedException, TimeoutException, ExecutionException {
         makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
-        makeHttpGetRequest(gcUrl + '?' + OFFSET_PREFIX + "=1","{\"response\":[{\"d\":\"test3\"}]}", 200);
+        final String expectedResponse = "{\"response\":[{\"d\":\"test3\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        makeHttpGetRequest(serviceUrl + '?' + OFFSET_PREFIX + "=1", expectedResponse, 200);
     }
 
     @Test
     public void testGetQueryParam() throws InterruptedException, TimeoutException, ExecutionException {
         makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
-        makeHttpGetRequest(gcUrl + '?' + QUERY_PREFIX + "=b==test1","{\"response\":[{\"a\":\"test\",\"b\":"+
-                "\"test1\",\"c\":\"test2\"}]}", 200);
+        final String expectedResponse = "{\"response\":[{\"a\":\"test\",\"b\":\"test1\",\"c\":\"test2\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        makeHttpGetRequest(serviceUrl + '?' + QUERY_PREFIX + "=b==test1", expectedResponse, 200);
     }
 
     @Test
     public void testPostJSON() throws InterruptedException, TimeoutException, ExecutionException {
+        final String expectedResponse = "{\"response\":[{\"f1\":\"test\"" + SYSTEM_JVM_FRAGMENT + "}]}";
         makeHttpMethodRequest(HttpMethod.POST, '?' + METADATA_PREFIX + "=true","[{\"f1\":\"test\"}]","application/json",
-                "{\"response\":[{\"f1\":\"test\"}]}", 200);
+                 expectedResponse, 200);
     }
 
     @Test
@@ -180,11 +281,13 @@
 
     @Test
     public void testPostPutDeleteMockedData() throws InterruptedException, TimeoutException, ExecutionException {
+        final String expectedResponse = "{\"response\":[{\"f1\":\"test\"" + SYSTEM_JVM_FRAGMENT + "}]}";
         makeHttpMethodRequest(HttpMethod.POST,"","[{\"f1\":\"test\"}]","application/json",
-                "{\"response\":[{\"f1\":\"test\"}]}", 200);
+                 expectedResponse, 200);
 
+        final String expectedResponse2 = "{\"response\":[{\"f1\":\"newdata\"" + SYSTEM_JVM_FRAGMENT + "}]}";
         makeHttpMethodRequest(HttpMethod.PUT,'?' + QUERY_PREFIX + "=f1==test","{\"set\": {\"f1\":\"newdata\"}}",
-                "application/json","{\"response\":[{\"f1\":\"newdata\"}]}", 200);
+                "application/json", expectedResponse2, 200);
 
         makeHttpMethodRequest(HttpMethod.DELETE,"?q=f1==test","","","", 200);
     }
@@ -197,12 +300,12 @@
         // {"response":["{\"a\":\"test\",\"b\":\"test1\",\"c\":\"test2\"}"],
         //"metaData":{"payloadCount":1,"count":3,
         //"next":"http://127.0.0.1:30000/jvm-gc/0.0.2?o=1&l=1&q===test1&m=true"}}
-        String expectedResponse ="{\"response\":[{\"a\":\"test\",\"b\":\"test1\",\"c\":\"test2\"}],"+
+        String expectedResponse ="{\"response\":[{\"a\":\"test\",\"b\":\"test1\",\"c\":\"test2\"" + SYSTEM_JVM_FRAGMENT + "}],"+
                 "\"metaData\":{\"payloadCount\":1,\"count\":3,"+
-                "\"next\":\"" + gcUrl + "?" + OFFSET_PREFIX + "\\u003d1\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX  +"\\u003dtrue\"}}";
+                "\"next\":\"" + serviceUrl + "?" + OFFSET_PREFIX + "\\u003d1\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX  +"\\u003dtrue\"}}";
 
         makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
-        makeHttpGetRequest(gcUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=1", expectedResponse, 200);
+        makeHttpGetRequest(serviceUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=1", expectedResponse, 200);
     }
 
     @Test
@@ -213,17 +316,17 @@
         // {"response":["{\"a\":\"test\",\"b\":\"test1\",\"c\":\"test2\"}"],
         //"metaData":{"payloadCount":1,"count":3,
         //"next":"http://127.0.0.1:30000/jvm-gc/0.0.2?o=1&l=1&q===test1&m=true"}}
-        String expectedResponse ="{\"response\":[{\"a\":\"test\",\"b\":\"test1\",\"c\":\"test2\"}],"+
+        String expectedResponse ="{\"response\":[{\"a\":\"test\",\"b\":\"test1\",\"c\":\"test2\"" + SYSTEM_JVM_FRAGMENT + "}],"+
                 "\"metaData\":{\"payloadCount\":1,\"count\":3,"+
-                "\"next\":\"" + gcUrl + "?" + OFFSET_PREFIX + "\\u003d1\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX  +"\\u003dtrue\"}}";
+                "\"next\":\"" + serviceUrl + "?" + OFFSET_PREFIX + "\\u003d1\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX  +"\\u003dtrue\"}}";
 
         makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
 
-        final String url1 =  baseUrl + "/" + serviceName + "/" + "0.0";;
+        final String url1 =  baseUrl + "/" + serviceName + "/" + "0.0" + "/systems/" + AGENT_ID + "/jvms/" + JVM_ID;
         makeHttpGetRequest(url1 + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=1", expectedResponse, 200);
-        final String url2 =  baseUrl + "/" + serviceName + "/" + "0.0.1";;
+        final String url2 =  baseUrl + "/" + serviceName + "/" + "0.0.2" + "/systems/" + AGENT_ID + "/jvms/" + JVM_ID;
         makeHttpGetRequest(url2 + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=1", expectedResponse, 200);
-        final String url3 =  baseUrl + "/" + serviceName + "/" + "0.0.3";;
+        final String url3 =  baseUrl + "/" + serviceName + "/" + "0.0.4" + "/systems/" + AGENT_ID + "/jvms/" + JVM_ID;
         makeHttpGetRequest(url3 + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=1", "", 404);
 
     }
@@ -236,13 +339,13 @@
         // {"response":["{\"b\":\"test1\"}"],"metaData":{"payloadCount":1,"count":3,
         //"prev":"http://127.0.0.1:30000/jvm-gc/0.0.2?q===test1&m=true&l=1",
         //"next":"http://127.0.0.1:30000/jvm-gc/0.0.2?o=2&l=1&q===test1&m=true"}}
-        String expectedResponse ="{\"response\":[{\"b\":\"test1\"}],"+
+        String expectedResponse ="{\"response\":[{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}],"+
                 "\"metaData\":{\"payloadCount\":1,\"count\":3,"+
-                "\"prev\":\"" + gcUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d1\","+
-                "\"next\":\"" + gcUrl + "?" + OFFSET_PREFIX + "\\u003d2\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
+                "\"prev\":\"" + serviceUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d1\","+
+                "\"next\":\"" + serviceUrl + "?" + OFFSET_PREFIX + "\\u003d2\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
 
         makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
-        makeHttpGetRequest(gcUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=1", expectedResponse, 200);
+        makeHttpGetRequest(serviceUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=1", expectedResponse, 200);
     }
 
     @Test
@@ -254,13 +357,14 @@
         // {"response":["{\"b\":\"test1\"}","{\"b\":\"test1\"}"],
         //"metaData":{"payloadCount":1,"count":6,"prev":"http://127.0.0.1:30000/jvm-gc/0.0.2?q===test1&m=true&l=2&o=1",
         //"next":"http://127.0.0.1:30000/jvm-gc/0.0.2?o=5&l=1&q===test1&m=true"}}
-        String expectedResponse ="{\"response\":[{\"b\":\"test1\"},{\"b\":\"test1\"}],"+
-                "\"metaData\":{\"payloadCount\":1,\"count\":6,"+
-                "\"prev\":\"" + gcUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + OFFSET_PREFIX + "\\u003d1\","+
-                "\"next\":\"" + gcUrl + "?" + OFFSET_PREFIX + "\\u003d5\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
+        String expectedResponse ="{\"response\":[{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}," +
+                "{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}]," +
+                "\"metaData\":{\"payloadCount\":1,\"count\":6," +
+                "\"prev\":\"" + serviceUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + OFFSET_PREFIX + "\\u003d1\","+
+                "\"next\":\"" + serviceUrl + "?" + OFFSET_PREFIX + "\\u003d5\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
 
         makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
-        makeHttpGetRequest(gcUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=2&" + OFFSET_PREFIX + "=3", expectedResponse, 200);
+        makeHttpGetRequest(serviceUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=2&" + OFFSET_PREFIX + "=3", expectedResponse, 200);
     }
 
     @Test
@@ -271,13 +375,13 @@
         // {"response":["{\"b\":\"test1\"}"],
         //"metaData":{"payloadCount":1,"count":3,"prev":"http://127.0.0.1:30000/jvm-gc/0.0.2?q===test1&m=true&l=1",
         //"next":"http://127.0.0.1:30000/jvm-gc/0.0.2?o=2&l=1&q===test1&m=true"}}
-        String expectedResponse ="{\"response\":[{\"b\":\"test1\"}],"+
+        String expectedResponse ="{\"response\":[{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}],"+
                 "\"metaData\":{\"payloadCount\":1,\"count\":3,"+
-                "\"prev\":\"" + gcUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d1\","+
-                "\"next\":\"" + gcUrl + "?" + OFFSET_PREFIX + "\\u003d2\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
+                "\"prev\":\"" + serviceUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d1\","+
+                "\"next\":\"" + serviceUrl + "?" + OFFSET_PREFIX + "\\u003d2\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
 
         makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
-        makeHttpGetRequest(gcUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=1&" + OFFSET_PREFIX + "=1", expectedResponse, 200);
+        makeHttpGetRequest(serviceUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=1&" + OFFSET_PREFIX + "=1", expectedResponse, 200);
     }
 
     @Test
@@ -289,13 +393,14 @@
         // {"response":["{\"b\":\"test1\"}","{\"e\":\"test4\",\"b\":\"test1\"}"],
         //"metaData":{"payloadCount":2,"count":6,"prev":"http://127.0.0.1:30000/jvm-gc/0.0.2?q===test1&m=true&l=1&o=0",
         //"next":"http://127.0.0.1:30000/jvm-gc/0.0.2?o=3&l=2&q===test1&m=true"}}
-        String expectedResponse ="{\"response\":[{\"b\":\"test1\"},{\"e\":\"test4\",\"b\":\"test1\"}],"+
-                "\"metaData\":{\"payloadCount\":2,\"count\":6,"+
-                "\"prev\":\"" + gcUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + OFFSET_PREFIX + "\\u003d0\","+
-                "\"next\":\"" + gcUrl + "?" + OFFSET_PREFIX + "\\u003d3\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
+        String expectedResponse ="{\"response\":[{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}," +
+                "{\"e\":\"test4\",\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}]," +
+                "\"metaData\":{\"payloadCount\":2,\"count\":6," +
+                "\"prev\":\"" + serviceUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + OFFSET_PREFIX + "\\u003d0\","+
+                "\"next\":\"" + serviceUrl + "?" + OFFSET_PREFIX + "\\u003d3\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
 
         makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
-        makeHttpGetRequest(gcUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=2&" + OFFSET_PREFIX + "=1", expectedResponse, 200);
+        makeHttpGetRequest(serviceUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=2&" + OFFSET_PREFIX + "=1", expectedResponse, 200);
     }
 
     @Test
@@ -308,13 +413,14 @@
         //"metaData":{"payloadCount":1,"count":6,
         //"prev":"http://127.0.0.1:30000/jvm-gc/0.0.2?q===test1&m=true&l=2&o=1",
         //"next":"http://127.0.0.1:30000/jvm-gc/0.0.2?o=5&l=1&q===test1&m=true"}}
-        String expectedResponse ="{\"response\":[{\"b\":\"test1\"},{\"b\":\"test1\"}],"+
-                "\"metaData\":{\"payloadCount\":1,\"count\":6,"+
-                "\"prev\":\"" + gcUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + OFFSET_PREFIX + "\\u003d1\","+
-                "\"next\":\"" + gcUrl + "?" + OFFSET_PREFIX + "\\u003d5\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
+        String expectedResponse ="{\"response\":[{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}," +
+                "{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}]," +
+                "\"metaData\":{\"payloadCount\":1,\"count\":6," +
+                "\"prev\":\"" + serviceUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + OFFSET_PREFIX + "\\u003d1\","+
+                "\"next\":\"" + serviceUrl + "?" + OFFSET_PREFIX + "\\u003d5\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
 
         makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
-        makeHttpGetRequest(gcUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=2&" + OFFSET_PREFIX + "=3", expectedResponse, 200);
+        makeHttpGetRequest(serviceUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=2&" + OFFSET_PREFIX + "=3", expectedResponse, 200);
     }
 
     @Test
@@ -326,13 +432,14 @@
         // {"response":["{\"e\":\"test4\",\"b\":\"test1\"}","{\"b\":\"test1\"}"],
         //"metaData":{"payloadCount":2,"count":6,"prev":"http://127.0.0.1:30000/jvm-gc/0.0.2?q===test1&m=true&l=2&o=0",
         //"next":"http://127.0.0.1:30000/jvm-gc/0.0.2?o=4&l=2&q===test1&m=true"}}
-        String expectedResponse ="{\"response\":[{\"e\":\"test4\",\"b\":\"test1\"},{\"b\":\"test1\"}],"+
-                "\"metaData\":{\"payloadCount\":2,\"count\":6,"+
-                "\"prev\":\"" + gcUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + OFFSET_PREFIX + "\\u003d0\","+
-                "\"next\":\"" + gcUrl + "?" + OFFSET_PREFIX + "\\u003d4\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
+        String expectedResponse ="{\"response\":[{\"e\":\"test4\",\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}," +
+                "{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}]," +
+                "\"metaData\":{\"payloadCount\":2,\"count\":6," +
+                "\"prev\":\"" + serviceUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + OFFSET_PREFIX + "\\u003d0\","+
+                "\"next\":\"" + serviceUrl + "?" + OFFSET_PREFIX + "\\u003d4\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
 
         makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
-        makeHttpGetRequest(gcUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=2&" + OFFSET_PREFIX + "=2", expectedResponse, 200);
+        makeHttpGetRequest(serviceUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=2&" + OFFSET_PREFIX + "=2", expectedResponse, 200);
     }
 
     @Test
@@ -345,12 +452,13 @@
         //"metaData":{"payloadCount":2,"count":6,
         //"prev":"http://127.0.0.1:30000/jvm-gc/0.0.2?q===test1&m=true&l=2&o=0",
         //"next":"http://127.0.0.1:30000/jvm-gc/0.0.2?o=4&l=2&q===test1&m=true"}}
-        String expectedResponse ="{\"response\":[{\"e\":\"test4\",\"b\":\"test1\"},{\"b\":\"test1\"}],"+
-                "\"metaData\":{\"payloadCount\":2,\"count\":6,"+
-                "\"prev\":\"" + gcUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + OFFSET_PREFIX + "\\u003d0\","+
-            "\"next\":\"" + gcUrl + "?" + OFFSET_PREFIX + "\\u003d4\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
+        String expectedResponse ="{\"response\":[{\"e\":\"test4\",\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}," +
+                "{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}]," +
+                "\"metaData\":{\"payloadCount\":2,\"count\":6," +
+                "\"prev\":\"" + serviceUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + OFFSET_PREFIX + "\\u003d0\","+
+            "\"next\":\"" + serviceUrl + "?" + OFFSET_PREFIX + "\\u003d4\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
         makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
-        makeHttpGetRequest(gcUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=2&" + OFFSET_PREFIX + "=2", expectedResponse, 200);
+        makeHttpGetRequest(serviceUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=2&" + OFFSET_PREFIX + "=2", expectedResponse, 200);
     }
 
     @Test
@@ -363,13 +471,14 @@
         // {"response":["{\"e\":\"test4\",\"b\":\"test1\"}","{\"b\":\"test1\"}","{\"b\":\"test1\"}"],
         //"metaData":{"payloadCount":1,"count":6,"prev":"http://127.0.0.1:30000/jvm-gc/0.0.2?q===test1&m=true&l=2&o=0",
         //"next":"http://127.0.0.1:30000/jvm-gc/0.0.2?o=5&l=1&q===test1&m=true"}}
-        String expectedResponse ="{\"response\":[{\"e\":\"test4\",\"b\":\"test1\"},"+
-                "{\"b\":\"test1\"},{\"b\":\"test1\"}],"+
+        String expectedResponse ="{\"response\":[{\"e\":\"test4\",\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "},"+
+                "{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}," +
+                "{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}],"+
                 "\"metaData\":{\"payloadCount\":1,\"count\":6,"+
-                "\"prev\":\"" + gcUrl + "?" +QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + OFFSET_PREFIX + "\\u003d0\","+
-                "\"next\":\"" + gcUrl + "?" + OFFSET_PREFIX + "\\u003d5\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
+                "\"prev\":\"" + serviceUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + OFFSET_PREFIX + "\\u003d0\","+
+                "\"next\":\"" + serviceUrl + "?" + OFFSET_PREFIX + "\\u003d5\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
         makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
-        makeHttpGetRequest(gcUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=3&" + OFFSET_PREFIX + "=2", expectedResponse, 200);
+        makeHttpGetRequest(serviceUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=3&" + OFFSET_PREFIX + "=2", expectedResponse, 200);
     }
 
     @Test
@@ -431,7 +540,7 @@
 
         String updateString = "{\"set\" : {\"item\" : 5}}";
         StringContentProvider stringContentProvider = new StringContentProvider(updateString, "UTF-8");
-        ContentResponse response = client.newRequest(gcUrl).param(RequestParameters.QUERY, "realms==[\"a\"]")
+        ContentResponse response = client.newRequest(serviceUrl).param(RequestParameters.QUERY, "realms==[\"a\"]")
                 .method(HttpMethod.PUT).content(stringContentProvider, "application/json")
                 .send();
         assertEquals(400, response.getStatus());
@@ -477,9 +586,9 @@
         makeHttpMethodRequest(HttpMethod.POST, "", data,
                 "application/json", "", 200);
 
-        String expected = "{\"response\":[{\"item\":1}]}";
+        String expected = "{\"response\":[{\"item\":1" + SYSTEM_JVM_FRAGMENT + "}]}";
 
-        makeHttpGetRequest(gcUrl,expected, 200);
+        makeHttpGetRequest(serviceUrl, expected, 200);
     }
 
     @Test
@@ -488,10 +597,9 @@
         makeHttpMethodRequest(HttpMethod.POST, "", data,
                 "application/json", "", 200);
 
-
         String expected = "{\"response\":[{\"item\":1}]}";
 
-        makeHttpGetRequest(gcUrl + "?" + RequestParameters.INCLUDE + "=realms,item", expected, 200);
+        makeHttpGetRequest(serviceUrl + "?" + RequestParameters.INCLUDE + "=realms,item",expected, 200);
     }
 
     @Test
@@ -500,8 +608,7 @@
         makeHttpMethodRequest(HttpMethod.POST, "", data,
                 "application/json", "", 200);
 
-
-        ContentResponse response = client.newRequest(gcUrl)
+        ContentResponse response = client.newRequest(serviceUrl)
                 .param(RequestParameters.QUERY, "realms==" + getRealmArray(BasicRealmAuthorizer.DEFAULT_REALM))
                 .method(HttpMethod.GET).send();
 
@@ -540,7 +647,7 @@
 
         collection.insertMany(insertDocuments);
 
-        ContentResponse response = client.newRequest(gcUrl)
+        ContentResponse response = client.newRequest(serviceUrl)
                 .param(RequestParameters.QUERY, "realms==[\"a\",\"b\"]").method(HttpMethod.DELETE)
                 .send();
         assertEquals(400, response.getStatus());
@@ -570,4 +677,133 @@
             return "[]";
         }
     }
+
+
+    private static String getRandomSystemId() {
+        return UUID.randomUUID().toString();
+    }
+
+    private static String getRandomJvmId() {
+        return UUID.randomUUID().toString();
+    }
+
+    private String createJSON() {
+        return createJSON(getTimestamp());
+    }
+
+    private long getTimestamp() {
+        timeStamp += 1;
+        return timeStamp;
+    }
+
+    private String createJSON(final long ts) {
+        return jsonData.replace(TIMESTAMP_TOKEN, Long.toString(ts));
+    }
+
+    private ContentResponse put(final String systemid, final String jvmid, final long ts) throws InterruptedException, ExecutionException, TimeoutException {
+        final Request request = client.newRequest(simpleUrl + "/systems/" + systemid + "/jvms/" + jvmid);
+        request.header(HttpHeader.CONTENT_TYPE, "application/json");
+        final String contentStr = createJSON(ts);
+        request.content(new StringContentProvider("{ \"set\" : " +contentStr + "}"));
+        ContentResponse response = request.method(HttpMethod.PUT).send();
+        assertEquals(HTTP_200_OK, response.getStatus());
+        final String expected = "";
+        assertEquals(expected, response.getContentAsString());
+        return response;
+    }
+
+    private ContentResponse post(final String systemid, final String jvmid) throws InterruptedException, ExecutionException, TimeoutException {
+        final Request request = client.newRequest(simpleUrl + "/systems/" + systemid + "/jvms/" + jvmid);
+        request.header(HttpHeader.CONTENT_TYPE, "application/json");
+        request.content(new StringContentProvider( '[' + createJSON() + ']'));
+        ContentResponse response = request.method(HttpMethod.POST).send();
+        assertEquals(HTTP_200_OK, response.getStatus());
+        final String expected = "";
+        assertEquals(expected, response.getContentAsString());
+        return response;
+    }
+
+    private ContentResponse getUnknown(final String systemid, final String jvmid) throws InterruptedException, ExecutionException, TimeoutException {
+        ContentResponse response = get(systemid, jvmid);
+        assertTrue(parse(response, jvmid).isEmpty());
+        return response;
+    }
+
+    private ContentResponse getKnown(final String systemid, final String jvmid) throws InterruptedException, ExecutionException, TimeoutException {
+        ContentResponse response = get(systemid, jvmid);
+        assertEquals(1, parse(response, jvmid).size());
+        return response;
+    }
+
+    private ContentResponse get(final String systemid, final String jvmid) throws InterruptedException, ExecutionException, TimeoutException {
+        ContentResponse response = client.newRequest(simpleUrl + "/systems/" + systemid + "/jvms/" + jvmid).method(HttpMethod.GET).send();
+        assertEquals(HTTP_200_OK, response.getStatus());
+        return response;
+    }
+
+    private ContentResponse get(final String systemid, final String jvmid, final String query) throws InterruptedException, ExecutionException, TimeoutException {
+        final Request rq = client.newRequest(simpleUrl + "/systems/" + systemid + "/jvms/" + jvmid + query);
+        rq.method(HttpMethod.GET);
+        ContentResponse response = rq.send();
+        assertEquals(HTTP_200_OK, response.getStatus());
+        return response;
+    }
+
+    private ContentResponse delete(final String systemid, final String jvmid) throws InterruptedException, ExecutionException, TimeoutException {
+        ContentResponse response = client.newRequest(simpleUrl + "/systems/" + systemid + "/jvms/" + jvmid).method(HttpMethod.DELETE).send();
+        assertEquals(HTTP_200_OK, response.getStatus());
+        final String expected = "";
+        assertEquals(expected, response.getContentAsString());
+        return response;
+    }
+
+    class TinyJvmGc {
+        String jvmId;
+        long timeStamp;
+        TinyJvmGc(String jvmId, long ts) {
+            this.jvmId = jvmId;
+            this.timeStamp = ts;
+        }
+    }
+    private List<TinyJvmGc> parse(ContentResponse contentResponse, final String expectedJvmId) {
+
+        JsonParser parser = new JsonParser();
+        JsonObject json = (JsonObject) parser.parse(contentResponse.getContentAsString());
+        JsonElement response = json.get("response");
+
+        JsonArray allData = response.getAsJsonArray();
+        List<TinyJvmGc> result = new ArrayList<>();
+
+        for (JsonElement entry : allData) {
+
+            json = (JsonObject) parser.parse(entry.toString());
+
+            assertTrue(json.has("jvmId"));
+            //assertTrue(json.has("agentId"));
+            assertTrue(json.has("timeStamp"));
+
+            final String jvmId = json.get("jvmId").getAsString();
+            //final String agentId = json.get("agentId").getAsString();
+            //final long timeStamp = getLong(json, "timeStamp");
+
+            if (expectedJvmId != null) {
+                assertEquals(expectedJvmId, jvmId);
+            }
+
+            TinyJvmGc hi = new TinyJvmGc(jvmId, 0);
+
+            result.add(hi);
+        }
+        return result;
+    }
+
+    private static long getLong(JsonObject json, final String id) {
+        JsonElement el = json.get(id);
+        if (el.isJsonObject()) {
+            final JsonObject o = el.getAsJsonObject();
+            return o.get("$numberLong").getAsLong();
+        } else {
+            return el.getAsLong();
+        }
+    }
 }
--- a/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/memory/JvmMemoryServiceIntegrationTest.java	Wed Aug 23 13:43:11 2017 +0200
+++ b/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/memory/JvmMemoryServiceIntegrationTest.java	Fri Aug 25 09:59:56 2017 -0400
@@ -36,19 +36,37 @@
 
 package com.redhat.thermostat.gateway.service.jvm.memory;
 
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.redhat.thermostat.gateway.service.jvm.gc.JvmGcServiceIntegrationTest;
 import com.redhat.thermostat.gateway.tests.integration.MongoIntegrationTest;
 import com.redhat.thermostat.gateway.tests.utils.HttpTestUtil;
+import org.eclipse.jetty.client.api.ContentResponse;
+import org.eclipse.jetty.client.api.Request;
+import org.eclipse.jetty.client.util.StringContentProvider;
+import org.eclipse.jetty.http.HttpHeader;
 import org.eclipse.jetty.http.HttpMethod;
 import org.junit.Test;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
 public class JvmMemoryServiceIntegrationTest extends MongoIntegrationTest {
 
     private static final String serviceName = "jvm-memory";
-    private static final String versionNumber = "0.0.2";
+    private static final String versionNumber = "0.0.3";
 
+    private static final int HTTP_200_OK = 200;
+    private static final int HTTP_404_NOTFOUND = 404;
+    
     private static final String QUERY_PREFIX = "query";
     private static final String LIMIT_PREFIX = "limit";
     private static final String SORT_PREFIX = "sort";
@@ -56,197 +74,285 @@
     private static final String METADATA_PREFIX = "metadata";
     private static final String INCLUDE_PREFIX = "include";
 
+    private static final String TIMESTAMP_TOKEN = "\"$TIMESTAMP$\"";
+    private static final String JVMID_TOKEN = "\"$JVMID_TOKEN\"";
+
+    private final String AGENT_ID = getRandomSystemId();
+    private final String JVM_ID = getRandomJvmId();
+    private long timeStamp = java.lang.System.nanoTime();
+    private final String SYSTEM_JVM_FRAGMENT = ",\"systemId\":\"" + AGENT_ID + "\",\"jvmId\":\"" + JVM_ID + "\"";
+
+    private final String jsonData =
+            "{\n" +
+                    "   \"timeStamp\" : " + TIMESTAMP_TOKEN + ",\n" +
+                    "   \"jvmId\" : " + JVMID_TOKEN + ",\n" +
+                    "   \"metaspaceMaxCapacity\" : \"1000\",\n" +
+                    "   \"metaspaceMinCapacity\" : \"22\",\n" +
+                    "   \"metaspaceCapacity\" : \"777\",\n" +
+                    "   \"metaspaceUsed\" : \"77\"\n" +
+                    "}\n";
+
+    private final String simpleUrl = baseUrl + "/" + serviceName + "/" + versionNumber;
+    private final String serviceUrl = simpleUrl + "/systems/" + AGENT_ID + "/jvms/" + JVM_ID;
+    
     private final String returnedUrl;
 
     public JvmMemoryServiceIntegrationTest() {
         super(serviceName + "/" + versionNumber, serviceName);
-        this.returnedUrl = resourceUrl;
+        this.returnedUrl = serviceUrl;
+    }
+
+    @Test
+    public void testGetUnknown() throws InterruptedException, TimeoutException, ExecutionException {
+        getUnknown(getRandomSystemId(), getRandomJvmId());
+    }
+
+    @Test
+    public void testCreateOne() throws InterruptedException, TimeoutException, ExecutionException {
+
+        final String systemid = getRandomSystemId();
+        final String jvmid = getRandomJvmId();
+        post(systemid, jvmid);
+        getKnown(systemid, jvmid);
     }
 
     @Test
+    public void testPut() throws InterruptedException, TimeoutException, ExecutionException {
+
+        final String systemid = getRandomSystemId();
+        final String jvmid = getRandomJvmId();
+
+        final long timestamp = getTimestamp();
+
+        // create it
+        post(systemid, jvmid);
+
+        // retrieve it
+        final ContentResponse response1 = getKnown(systemid, jvmid);
+        final List<TinyJvmMemory> list1 = parse(response1, jvmid);
+        assertEquals(1, list1.size());
+
+        // modify it
+        put(systemid, jvmid, timestamp+1);
+
+        // ensure it was changed
+        final ContentResponse response2 = getKnown(systemid, jvmid);
+        final List<TinyJvmMemory> list2 = parse(response2, jvmid);
+        assertEquals(1, list2.size());
+    }
+
+    @Test
+    public void testDeleteUnknown() throws InterruptedException, TimeoutException, ExecutionException {
+        final String systemid = getRandomSystemId();
+        final String jvmid = getRandomJvmId();
+        // delete it
+        delete(systemid, jvmid);
+    }
+
+    @Test
+    public void testDeleteOne() throws InterruptedException, ExecutionException, TimeoutException {
+        final String systemid = getRandomSystemId();
+        final String jvmid = getRandomJvmId();
+
+        // create the new record
+        post(systemid, jvmid);
+
+        // check that it's there
+        getKnown(systemid, jvmid);
+
+        // delete it
+        delete(systemid, jvmid);
+
+        // check that it's not there
+        getUnknown(systemid, jvmid);
+    }
+
+
+
+    @Test
     public void testGetWithUnsupportedQuery() throws InterruptedException, TimeoutException, ExecutionException {
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?xyz=5", 200, HttpTestUtil.EMPTY_RESPONSE);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?xyz=5", 200, HttpTestUtil.EMPTY_RESPONSE);
     }
 
     @Test
     public void testDefaultLimitOne() throws InterruptedException, TimeoutException, ExecutionException {
-        String expected = "{\"response\":[{\"a\":\"b\"}]}";
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"a\":\"b\"},{\"a\":\"d\"}]");
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?s=+a&l=", 200, expected);
+        String expected = "{\"response\":[{\"a\":\"b\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"a\":\"b\"},{\"a\":\"d\"}]");
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?s=+a&l=", 200, expected);
     }
 
     @Test
     public void testGetWithCommaQuery() throws InterruptedException, TimeoutException, ExecutionException {
-        String expectedFirst = "{\"response\":[{\"a\":\"b\",\"c\":\"d\",\"e\":\"f\"}]}";
-        String expectedAll = "{\"response\":[{\"a\":\"b\",\"c\":\"d\",\"e\":\"f\"},{\"x\":\"y\"},{\"z\":\"z\"}]}";
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"a\":\"b\",\"c\":\"d\",\"e\":\"f\"},{\"x\":\"y\"},{\"z\":\"z\"}]");
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + LIMIT_PREFIX + "=5", 200, expectedAll);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + QUERY_PREFIX + "=a==b", 200, expectedFirst);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + QUERY_PREFIX + "=c==d", 200, expectedFirst);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + QUERY_PREFIX + "=a==b,c==d", 200, expectedFirst);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + QUERY_PREFIX + "=a==b,c==none", 200, HttpTestUtil.EMPTY_RESPONSE);
+        String expectedFirst = "{\"response\":[{\"a\":\"b\",\"c\":\"d\",\"e\":\"f\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        String expectedAll = "{\"response\":[{\"a\":\"b\",\"c\":\"d\",\"e\":\"f\"" + SYSTEM_JVM_FRAGMENT + "},{\"x\":\"y\"" + SYSTEM_JVM_FRAGMENT + "},{\"z\":\"z\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"a\":\"b\",\"c\":\"d\",\"e\":\"f\"},{\"x\":\"y\"},{\"z\":\"z\"}]");
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + LIMIT_PREFIX + "=5", 200, expectedAll);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + QUERY_PREFIX + "=a==b", 200, expectedFirst);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + QUERY_PREFIX + "=c==d", 200, expectedFirst);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + QUERY_PREFIX + "=a==b,c==d", 200, expectedFirst);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + QUERY_PREFIX + "=a==b,c==none", 200, HttpTestUtil.EMPTY_RESPONSE);
     }
 
     @Test
     public void testGetWithAmpersandQuery() throws InterruptedException, TimeoutException, ExecutionException {
-        String expectedAll = "{\"response\":[{\"a\":\"b\"},{\"c\":\"d\"}]}";
-        String expectedAmpersand = "{\"response\":[{\"a\":\"b\"}]}";
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"a\":\"b\"},{\"c\":\"d\"}]");
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + LIMIT_PREFIX + "=5", 200, expectedAll);
+        String expectedAll = "{\"response\":[{\"a\":\"b\"" + SYSTEM_JVM_FRAGMENT + "},{\"c\":\"d\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        String expectedAmpersand = "{\"response\":[{\"a\":\"b\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"a\":\"b\"},{\"c\":\"d\"}]");
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + LIMIT_PREFIX + "=5", 200, expectedAll);
 
         // Since q=a==b&c==d means "q= 'a==b'" and "c= '=d'", we should only
         // get 'a: b' back.
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + QUERY_PREFIX + "=a==b&c==d", 200, expectedAmpersand);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + QUERY_PREFIX + "=a==b&c==d", 200, expectedAmpersand);
 
         // The following should find the one with multiple matches, not the
         // single match. This means we will evaluate u==v only, and should get
         // back the first one it finds since no limit query is specified.
-        String expectedSingleMatch = "{\"response\":[{\"u\":\"v\",\"x\":\"y\"}]}";
-        String expectedMultiMatch = "{\"response\":[{\"u\":\"v\",\"x\":\"y\"},{\"u\":\"v\"}]}";
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"x\":\"y\"},{\"u\":\"v\",\"x\":\"y\"},{\"u\":\"v\"}]");
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + QUERY_PREFIX + "=u==v&" + QUERY_PREFIX + "=x==y", 200, expectedSingleMatch);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + QUERY_PREFIX + "=u==v&" + QUERY_PREFIX + "=x==y&" + LIMIT_PREFIX + "=5", 200, expectedMultiMatch);
+        String expectedSingleMatch = "{\"response\":[{\"u\":\"v\",\"x\":\"y\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        String expectedMultiMatch = "{\"response\":[{\"u\":\"v\",\"x\":\"y\"" + SYSTEM_JVM_FRAGMENT + "},{\"u\":\"v\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"x\":\"y\"},{\"u\":\"v\",\"x\":\"y\"},{\"u\":\"v\"}]");
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + QUERY_PREFIX + "=u==v&" + QUERY_PREFIX + "=x==y", 200, expectedSingleMatch);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + QUERY_PREFIX + "=u==v&" + QUERY_PREFIX + "=x==y&" + LIMIT_PREFIX + "=5", 200, expectedMultiMatch);
     }
 
     @Test
     public void testMultiplePosts() throws InterruptedException, TimeoutException, ExecutionException {
-        String expectedResponse = "{\"response\":[{\"fakedata\":\"test\"},{\"new\":\"data\"}]}";
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"fakedata\":\"test\"}]");
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"new\":\"data\"}]");
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + LIMIT_PREFIX + "=5", 200, expectedResponse);
+        String expectedResponse = "{\"response\":[{\"fakedata\":\"test\"" + SYSTEM_JVM_FRAGMENT + "},{\"new\":\"data\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"fakedata\":\"test\"}]");
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"new\":\"data\"}]");
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + LIMIT_PREFIX + "=5", 200, expectedResponse);
     }
 
     @Test
     public void testPostPutAddsData() throws InterruptedException, TimeoutException, ExecutionException {
-        String expectedDataBeforePut = "{\"response\":[{\"a\":\"b\"}]}";
-        String expectedDataAfterPut = "{\"response\":[{\"a\":\"b\",\"x\":\"y\"}]}";
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"a\":\"b\"},{\"a\":\"c\"}]");
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl, 200, expectedDataBeforePut);
-        HttpTestUtil.testContentResponse(client, HttpMethod.PUT, resourceUrl + "?" + QUERY_PREFIX + "=a==b", "{\"set\":{\"x\":\"y\"}}", 200);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl, 200, expectedDataAfterPut);
+        String expectedDataBeforePut = "{\"response\":[{\"a\":\"b\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        String expectedDataAfterPut = "{\"response\":[{\"a\":\"b\"" + SYSTEM_JVM_FRAGMENT + ",\"x\":\"y\"}]}";
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"a\":\"b\"},{\"a\":\"c\"}]");
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl, 200, expectedDataBeforePut);
+        HttpTestUtil.testContentResponse(client, HttpMethod.PUT, serviceUrl + "?" + QUERY_PREFIX + "=a==b", "{\"set\":{\"x\":\"y\"}}", 200);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl, 200, expectedDataAfterPut);
     }
 
     @Test
     public void testPostPutModifiesData() throws InterruptedException, TimeoutException, ExecutionException {
-        String expectedDataBeforePut = "{\"response\":[{\"a\":\"b\"}]}";
-        String expectedDataAfterPut = "{\"response\":[{\"a\":\"c\"}]}";
-        String expectedAllDataAfterPut = "{\"response\":[{\"a\":\"c\"},{\"x\":\"y\"}]}";
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"a\":\"b\"},{\"x\":\"y\"}]");
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl, 200, expectedDataBeforePut);
-        HttpTestUtil.testContentResponse(client, HttpMethod.PUT, resourceUrl + "?" + QUERY_PREFIX + "=a==b", "{\"set\":{\"a\":\"c\"}}", 200);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl, 200, expectedDataAfterPut);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + LIMIT_PREFIX + "=5", 200, expectedAllDataAfterPut);
+        String expectedDataBeforePut = "{\"response\":[{\"a\":\"b\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        String expectedDataAfterPut = "{\"response\":[{\"a\":\"c\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        String expectedAllDataAfterPut = "{\"response\":[{\"a\":\"c\"" + SYSTEM_JVM_FRAGMENT + "},{\"x\":\"y\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"a\":\"b\"},{\"x\":\"y\"}]");
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl, 200, expectedDataBeforePut);
+        HttpTestUtil.testContentResponse(client, HttpMethod.PUT, serviceUrl + "?" + QUERY_PREFIX + "=a==b", "{\"set\":{\"a\":\"c\"}}", 200);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl, 200, expectedDataAfterPut);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + LIMIT_PREFIX + "=5", 200, expectedAllDataAfterPut);
     }
 
     @Test
     public void testDeleteProperlyDeletesData() throws InterruptedException, TimeoutException, ExecutionException {
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"fakedata\":\"test\"}]");
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.DELETE, resourceUrl + "?" + QUERY_PREFIX + "=fakedata==test", 200);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl, 200, HttpTestUtil.EMPTY_RESPONSE);
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"fakedata\":\"test\"}]");
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.DELETE, serviceUrl + "?" + QUERY_PREFIX + "=fakedata==test", 200);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl, 200, HttpTestUtil.EMPTY_RESPONSE);
 
-        String expectedAfterDeletion = "{\"response\":[{\"c\":\"d\"}]}";
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"fakedata\":\"test\",\"a\":\"b\"},{\"c\":\"d\"}]");
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.DELETE, resourceUrl + "?" + QUERY_PREFIX + "=a==b", 200);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl, 200, expectedAfterDeletion);
+        String expectedAfterDeletion = "{\"response\":[{\"c\":\"d\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"fakedata\":\"test\",\"a\":\"b\"},{\"c\":\"d\"}]");
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.DELETE, serviceUrl + "?" + QUERY_PREFIX + "=a==b", 200);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl, 200, expectedAfterDeletion);
     }
 
     @Test
     public void testMalformedDeleteRequestDoesNotMutateData() throws InterruptedException, TimeoutException, ExecutionException {
-        String expectedDataResponse = "{\"response\":[{\"fakedata\":\"test\"}]}";
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"fakedata\":\"test\"}]");
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl, 200, expectedDataResponse);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.DELETE, resourceUrl + "?" + QUERY_PREFIX + "=nosuchkey==", 200);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl, 200, expectedDataResponse);
+        String expectedDataResponse = "{\"response\":[{\"fakedata\":\"test\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"fakedata\":\"test\"}]");
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl, 200, expectedDataResponse);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.DELETE, serviceUrl + "?" + QUERY_PREFIX + "=nosuchkey==", 200);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl, 200, expectedDataResponse);
     }
 
     @Test
     public void testPutDataWithoutUrlQuery() throws InterruptedException, TimeoutException, ExecutionException {
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"fakedata\":\"test\"}]");
-        HttpTestUtil.testContentResponse(client, HttpMethod.PUT, resourceUrl, "{\"set\":{\"fakedata\":\"test\"}}", 200);
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"fakedata\":\"test\"}]");
+        HttpTestUtil.testContentResponse(client, HttpMethod.PUT, serviceUrl, "{\"set\":{\"fakedata\":\"test\"}}", 200);
     }
 
     @Test
     public void testPostAndPutWithInvalidData() throws InterruptedException, TimeoutException, ExecutionException {
-        String expectedDataResponse = "{\"response\":[{\"fakedata\":\"test\"}]}";
-        String urlQuery = resourceUrl + "?" + QUERY_PREFIX + "=nosuchkey==nosuchvalue";
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"fakedata\":\"test\"}]");
+        String expectedDataResponse = "{\"response\":[{\"fakedata\":\"test\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        String urlQuery = serviceUrl + "?" + QUERY_PREFIX + "=nosuchkey==nosuchvalue";
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"fakedata\":\"test\"}]");
         HttpTestUtil.testContentResponse(client, HttpMethod.PUT, urlQuery, "{\"set\":{\"fakedata\":\"somethingnew\"}}", 200);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + LIMIT_PREFIX + "=5", 200, expectedDataResponse);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + LIMIT_PREFIX + "=5", 200, expectedDataResponse);
     }
 
     @Test
     public void testPutWithIdenticalData() throws InterruptedException, TimeoutException, ExecutionException {
-        String expectedDataResponse = "{\"response\":[{\"fakedata\":\"test\"}]}";
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"fakedata\":\"test\"}]");
-        HttpTestUtil.testContentResponse(client, HttpMethod.PUT, resourceUrl, "{\"set\":{\"fakedata\":\"test\"}}", 200);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + LIMIT_PREFIX + "=5", 200, expectedDataResponse);
+        String expectedDataResponse = "{\"response\":[{\"fakedata\":\"test\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"fakedata\":\"test\"}]");
+        HttpTestUtil.testContentResponse(client, HttpMethod.PUT, serviceUrl, "{\"set\":{\"fakedata\":\"test\"}}", 200);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + LIMIT_PREFIX + "=5", 200, expectedDataResponse);
     }
 
     @Test
     public void testPutDifferentData() throws InterruptedException, TimeoutException, ExecutionException {
-        String expectedDataResponse = "{\"response\":[{\"a\":\"b\",\"c\":\"d\"}]}";
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"a\":\"b\"}]");
-        HttpTestUtil.testContentResponse(client, HttpMethod.PUT, resourceUrl + "?" + QUERY_PREFIX + "=a==b", "{\"set\":{\"c\":\"d\"}}", 200);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + LIMIT_PREFIX + "=5", 200, expectedDataResponse);
+        String expectedDataResponse = "{\"response\":[{\"a\":\"b\"" + SYSTEM_JVM_FRAGMENT + ",\"c\":\"d\"}]}";
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"a\":\"b\"}]");
+        HttpTestUtil.testContentResponse(client, HttpMethod.PUT, serviceUrl + "?" + QUERY_PREFIX + "=a==b", "{\"set\":{\"c\":\"d\"}}", 200);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + LIMIT_PREFIX + "=5", 200, expectedDataResponse);
     }
 
     @Test
     public void testChangeDataWithPutMultipleTimes() throws InterruptedException, TimeoutException, ExecutionException {
-        String expectedData = "{\"response\":[{\"a\":\"a2\",\"b\":\"b2\",\"c\":\"c2\"}]}";
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"a\":\"a2\"}]");
-        HttpTestUtil.testContentResponse(client, HttpMethod.PUT, resourceUrl + "?" + QUERY_PREFIX + "=a==a2", "{\"set\":{\"b\":\"b2\"}}", 200);
-        HttpTestUtil.testContentResponse(client, HttpMethod.PUT, resourceUrl + "?" + QUERY_PREFIX + "=a==a2", "{\"set\":{\"c\":\"c2\"}}", 200);
+        String expectedData = "{\"response\":[{\"a\":\"a2\"" + SYSTEM_JVM_FRAGMENT + ",\"b\":\"b2\",\"c\":\"c2\"}]}";
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"a\":\"a2\"}]");
+        HttpTestUtil.testContentResponse(client, HttpMethod.PUT, serviceUrl + "?" + QUERY_PREFIX + "=a==a2", "{\"set\":{\"b\":\"b2\"}}", 200);
+        HttpTestUtil.testContentResponse(client, HttpMethod.PUT, serviceUrl + "?" + QUERY_PREFIX + "=a==a2", "{\"set\":{\"c\":\"c2\"}}", 200);
 
         // It won't find the target from the query, so the addition should not occur to any object.
-        HttpTestUtil.testContentResponse(client, HttpMethod.PUT, resourceUrl + "?" + QUERY_PREFIX + "=a==none", "{\"set\":{\"d\":\"d2\"}}", 200);
+        HttpTestUtil.testContentResponse(client, HttpMethod.PUT, serviceUrl + "?" + QUERY_PREFIX + "=a==none", "{\"set\":{\"d\":\"d2\"}}", 200);
 
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + LIMIT_PREFIX + "=5", 200, expectedData);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + LIMIT_PREFIX + "=5", 200, expectedData);
     }
 
     @Test
     public void testGetWithBadUrlQuery() throws InterruptedException, TimeoutException, ExecutionException {
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + QUERY_PREFIX + "=2", 400);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + QUERY_PREFIX + "=2", 400);
     }
 
     @Test
     public void testGetLimitWithQuery() throws InterruptedException, TimeoutException, ExecutionException {
-        String expectedDataOne = "{\"response\":[{\"a\":\"a2\"}]}";
-        String expectedDataAll = "{\"response\":[{\"a\":\"a2\"},{\"b\":\"b2\"}]}";
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"a\":\"a2\"},{\"b\":\"b2\"}]");
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl, 200, expectedDataOne);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + LIMIT_PREFIX + "=2", 200, expectedDataAll);
+        String expectedDataOne = "{\"response\":[{\"a\":\"a2\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        String expectedDataAll = "{\"response\":[{\"a\":\"a2\"" + SYSTEM_JVM_FRAGMENT + "},{\"b\":\"b2\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"a\":\"a2\"},{\"b\":\"b2\"}]");
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl, 200, expectedDataOne);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + LIMIT_PREFIX + "=2", 200, expectedDataAll);
     }
 
     @Test
     public void testQueryOffset() throws InterruptedException, TimeoutException, ExecutionException {
-        String expectedOffsetRestOfData = "{\"response\":[{\"b\":\"2\"},{\"c\":\"3\"}]}";
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"a\":\"1\"},{\"b\":\"2\"},{\"c\":\"3\"}]");
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + OFFSET_PREFIX + "=1", 200, "{\"response\":[{\"b\":\"2\"}]}");
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + OFFSET_PREFIX + "=3", 200, HttpTestUtil.EMPTY_RESPONSE);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + LIMIT_PREFIX + "=5&" + OFFSET_PREFIX + "=1", 200, expectedOffsetRestOfData);
+        String expectedOffsetRestOfData = "{\"response\":[{\"b\":\"2\"" + SYSTEM_JVM_FRAGMENT + "},{\"c\":\"3\"" + SYSTEM_JVM_FRAGMENT + "}]}";
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"a\":\"1\"},{\"b\":\"2\"},{\"c\":\"3\"}]");
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + OFFSET_PREFIX + "=1", 200, "{\"response\":[{\"b\":\"2\"" + SYSTEM_JVM_FRAGMENT + "}]}");
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + OFFSET_PREFIX + "=3", 200, HttpTestUtil.EMPTY_RESPONSE);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + LIMIT_PREFIX + "=5&" + OFFSET_PREFIX + "=1", 200, expectedOffsetRestOfData);
     }
 
     @Test
     public void testNegativeOffsetQuery() throws InterruptedException, TimeoutException, ExecutionException {
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"a\":\"1\"}]");
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + OFFSET_PREFIX + "=-1", 400);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + OFFSET_PREFIX + "=-582", 400);
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"a\":\"1\"}]");
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + OFFSET_PREFIX + "=-1", 400);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + OFFSET_PREFIX + "=-582", 400);
     }
 
     @Test
     public void testQueryOrdering() throws InterruptedException, TimeoutException, ExecutionException {
-        String expectedGet = "{\"response\":[{\"a\":1},{\"a\":2}]}";
-        String expectedGetReverse = "{\"response\":[{\"a\":2},{\"a\":1}]}";
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"a\":1},{\"a\":2}]");
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + LIMIT_PREFIX + "=10&" + SORT_PREFIX + "=+a", 200, expectedGet);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + LIMIT_PREFIX + "=10&" + SORT_PREFIX + "=-a", 200, expectedGetReverse);
+        String expectedGet = "{\"response\":[{\"a\":1" + SYSTEM_JVM_FRAGMENT + "},{\"a\":2" + SYSTEM_JVM_FRAGMENT + "}]}";
+        String expectedGetReverse = "{\"response\":[{\"a\":2" + SYSTEM_JVM_FRAGMENT + "},{\"a\":1" + SYSTEM_JVM_FRAGMENT + "}]}";
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"a\":1},{\"a\":2}]");
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + LIMIT_PREFIX + "=10&" + SORT_PREFIX + "=+a", 200, expectedGet);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + LIMIT_PREFIX + "=10&" + SORT_PREFIX + "=-a", 200, expectedGetReverse);
     }
 
     @Test
     public void testQueryProjection() throws InterruptedException, TimeoutException, ExecutionException {
         String expectedGet = "{\"response\":[{\"b\":\"2\",\"c\":\"3\"}]}";
-        HttpTestUtil.addRecords(client, resourceUrl, "[{\"a\":\"1\",\"b\":\"2\",\"c\":\"3\"}]");
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + INCLUDE_PREFIX + "=b,c", 200, expectedGet);
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"a\":\"1\",\"b\":\"2\",\"c\":\"3\"}]");
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + INCLUDE_PREFIX + "=b,c", 200, expectedGet);
     }
 
     @Test
@@ -258,11 +364,11 @@
         // "metaData":{"payloadCount":1,"count":3,
         // "next":"http://127.0.0.1:30000/jvm-memory/0.0.2?o=1&l=1&q===test1&m=true"}}
         String expectedResponse = "{\"response\":[{\"a\":\"test\",\"b\":\"test1\"," +
-                "\"c\":\"test2\"}],\"metaData\":{\"payloadCount\":1,\"count\":3," +
+                "\"c\":\"test2\"" + SYSTEM_JVM_FRAGMENT + "}],\"metaData\":{\"payloadCount\":1,\"count\":3," +
                 "\"next\":\"" + returnedUrl + "?" + OFFSET_PREFIX + "\\u003d1\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
 
-        HttpTestUtil.addRecords(client, resourceUrl, data);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=1", 200, expectedResponse);
+        HttpTestUtil.addRecords(client, serviceUrl, data);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=1", 200, expectedResponse);
     }
 
     @Test
@@ -271,15 +377,15 @@
                 "{\"e\":\"test4\",\"b\":\"test1\"}]";
 
         String expectedResponse = "{\"response\":[{\"a\":\"test\",\"b\":\"test1\"," +
-                "\"c\":\"test2\"}],\"metaData\":{\"payloadCount\":1,\"count\":3," +
+                "\"c\":\"test2\"" + SYSTEM_JVM_FRAGMENT + "}],\"metaData\":{\"payloadCount\":1,\"count\":3," +
                 "\"next\":\"" + returnedUrl + "?" + OFFSET_PREFIX + "\\u003d1\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
 
-        HttpTestUtil.addRecords(client, resourceUrl, data);
-        final String url1 = baseUrl + "/jvm-memory/0.0";
+        HttpTestUtil.addRecords(client, serviceUrl, data);
+        final String url1 =  baseUrl + "/" + serviceName + "/" + "0.0" + "/systems/" + AGENT_ID + "/jvms/" + JVM_ID;
         HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, url1 + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=1", 200, expectedResponse);
-        final String url2 = baseUrl + "/jvm-memory/0.0.1";
+        final String url2 =  baseUrl + "/" + serviceName + "/" + "0.0.2" + "/systems/" + AGENT_ID + "/jvms/" + JVM_ID;
         HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, url2 + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=1", 200, expectedResponse);
-        final String url3 = baseUrl + "/jvm-memory/0.0.3";
+        final String url3 =  baseUrl + "/" + serviceName + "/" + "0.0.4" + "/systems/" + AGENT_ID + "/jvms/" + JVM_ID;
         HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, url3 + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=1", 404, null);
     }
 
@@ -291,13 +397,13 @@
         // {"response":["{\"b\":\"test1\"}"],"metaData":{"payloadCount":1,"count":3,
         // "prev":"http://127.0.0.1:30000/jvm-memory/0.0.2?q===test1&m=true&l=1",
         // "next":"http://127.0.0.1:30000/jvm-memory/0.0.2?o=2&l=1&q===test1&m=true"}}
-        String expectedResponse = "{\"response\":[{\"b\":\"test1\"}]," +
+        String expectedResponse = "{\"response\":[{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}]," +
                 "\"metaData\":{\"payloadCount\":1,\"count\":3," +
                 "\"prev\":\"" + returnedUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d1\"," +
                 "\"next\":\"" + returnedUrl + "?" + OFFSET_PREFIX + "\\u003d2\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
 
-        HttpTestUtil.addRecords(client, resourceUrl, data);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=1", 200, expectedResponse);
+        HttpTestUtil.addRecords(client, serviceUrl, data);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=1", 200, expectedResponse);
     }
 
     @Test
@@ -309,15 +415,15 @@
         // "metaData":{"payloadCount":1,"count":5,
         // "prev":"http://127.0.0.1:30000/jvm-memory/0.0.2?q===test1&m=true&l=1&o=0",
         // "next":"http://127.0.0.1:30000/jvm-memory/0.0.2?o=4&l=1&q===test1&m=true"}}
-        String expectedResponse = "{\"response\":[{\"b\":\"test1\"},{\"e\":\"test4\"," +
-                "\"b\":\"test1\"},{\"b\":\"test1\"}]," +
+        String expectedResponse = "{\"response\":[{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "},{\"e\":\"test4\"," +
+                "\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "},{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}]," +
                 "\"metaData\":{\"payloadCount\":1,\"count\":5," +
                 "\"prev\":\"" + returnedUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue" +
                 "\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + OFFSET_PREFIX + "\\u003d0\",\"next\":\"" + returnedUrl + "?" + OFFSET_PREFIX + "\\u003d4" +
                 "\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
 
-        HttpTestUtil.addRecords(client, resourceUrl, data);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=1&" + LIMIT_PREFIX + "=3", 200, expectedResponse);
+        HttpTestUtil.addRecords(client, serviceUrl, data);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=1&" + LIMIT_PREFIX + "=3", 200, expectedResponse);
     }
 
     @Test
@@ -330,13 +436,13 @@
         // "metaData":{"payloadCount":1,"count":6,
         // "prev":"http://127.0.0.1:30000/jvm-memory/0.0.2?q===test1&m=true&l=2&o=1",
         // "next":"http://127.0.0.1:30000/jvm-memory/0.0.2?o=5&l=1&q===test1&m=true"}}
-        String expectedResponse = "{\"response\":[{\"b\":\"test1\"},{\"b\":\"test1\"}]," +
+        String expectedResponse = "{\"response\":[{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "},{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}]," +
                 "\"metaData\":{\"payloadCount\":1,\"count\":6," +
                 "\"prev\":\"" + returnedUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + OFFSET_PREFIX + "\\u003d1\"," +
                 "\"next\":\"" + returnedUrl + "?" + OFFSET_PREFIX + "\\u003d5\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
 
-        HttpTestUtil.addRecords(client, resourceUrl, data);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=3&" + LIMIT_PREFIX + "=2", 200, expectedResponse);
+        HttpTestUtil.addRecords(client, serviceUrl, data);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=3&" + LIMIT_PREFIX + "=2", 200, expectedResponse);
     }
 
     @Test
@@ -348,13 +454,13 @@
         // "metaData":{"payloadCount":1,"count":3,
         // "prev":"http://127.0.0.1:30000/jvm-memory/0.0.2?q===test1&m=true&l=1",
         // "next":"http://127.0.0.1:30000/jvm-memory/0.0.2?o=2&l=1&q===test1&m=true"}}
-        String expectedResponse = "{\"response\":[{\"b\":\"test1\"}]," +
+        String expectedResponse = "{\"response\":[{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}]," +
                 "\"metaData\":{\"payloadCount\":1,\"count\":3," +
                 "\"prev\":\"" + returnedUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d1\"," +
                 "\"next\":\"" + returnedUrl + "?" + OFFSET_PREFIX + "\\u003d2\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
 
-        HttpTestUtil.addRecords(client, resourceUrl, data);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=1&" + LIMIT_PREFIX + "=1", 200, expectedResponse);
+        HttpTestUtil.addRecords(client, serviceUrl, data);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=1&" + LIMIT_PREFIX + "=1", 200, expectedResponse);
     }
 
     @Test
@@ -367,13 +473,13 @@
         // "metaData":{"payloadCount":2,"count":6,
         // "prev":"http://127.0.0.1:30000/jvm-memory/0.0.2?q===test1&m=true&l=1&o=0",
         // "next":"http://127.0.0.1:30000/jvm-memory/0.0.2?o=3&l=2&q===test1&m=true"}}
-        String expectedResponse = "{\"response\":[{\"b\":\"test1\"},{\"e\":\"test4\"," +
-                "\"b\":\"test1\"}],\"metaData\":{\"payloadCount\":2,\"count\":6," +
+        String expectedResponse = "{\"response\":[{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "},{\"e\":\"test4\"," +
+                "\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}],\"metaData\":{\"payloadCount\":2,\"count\":6," +
                 "\"prev\":\"" + returnedUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + OFFSET_PREFIX + "\\u003d0\"," +
                 "\"next\":\"" + returnedUrl + "?" + OFFSET_PREFIX + "\\u003d3\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
 
-        HttpTestUtil.addRecords(client, resourceUrl, data);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=1&" + LIMIT_PREFIX + "=2", 200, expectedResponse);
+        HttpTestUtil.addRecords(client, serviceUrl, data);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=1&" + LIMIT_PREFIX + "=2", 200, expectedResponse);
     }
 
     @Test
@@ -386,13 +492,13 @@
         // "metaData":{"payloadCount":1,"count":6,
         // "prev":"http://127.0.0.1:30000/jvm-memory/0.0.2?q===test1&m=true&l=2&o=1",
         // "next":"http://127.0.0.1:30000/jvm-memory/0.0.2?o=5&l=1&q===test1&m=true"}}
-        String expectedResponse = "{\"response\":[{\"b\":\"test1\"},{\"b\":\"test1\"}]," +
+        String expectedResponse = "{\"response\":[{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "},{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}]," +
                 "\"metaData\":{\"payloadCount\":1,\"count\":6," +
                 "\"prev\":\"" + returnedUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + OFFSET_PREFIX + "\\u003d1\"," +
                 "\"next\":\"" + returnedUrl + "?" + OFFSET_PREFIX + "\\u003d5\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
 
-        HttpTestUtil.addRecords(client, resourceUrl, data);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=3&" +LIMIT_PREFIX + "=2", 200, expectedResponse);
+        HttpTestUtil.addRecords(client, serviceUrl, data);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=3&" +LIMIT_PREFIX + "=2", 200, expectedResponse);
     }
 
     @Test
@@ -404,13 +510,13 @@
         // "metaData":{"payloadCount":2,"count":6,
         // "prev":"http://127.0.0.1:30000/jvm-memory/0.0.2?q===test1&m=true&l=2&o=0",
         // "next":"http://127.0.0.1:30000/jvm-memory/0.0.2?o=4&l=2&q===test1&m=true"}}
-        String expectedResponse = "{\"response\":[{\"e\":\"test4\",\"b\":\"test1\"},{\"b\":\"test1\"}]," +
+        String expectedResponse = "{\"response\":[{\"e\":\"test4\",\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "},{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}]," +
                 "\"metaData\":{\"payloadCount\":2,\"count\":6," +
                 "\"prev\":\"" + returnedUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + OFFSET_PREFIX + "\\u003d0\"," +
                 "\"next\":\"" + returnedUrl + "?" + OFFSET_PREFIX + "\\u003d4\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
 
-        HttpTestUtil.addRecords(client, resourceUrl, data);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=2&" + LIMIT_PREFIX + "=2", 200, expectedResponse);
+        HttpTestUtil.addRecords(client, serviceUrl, data);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=2&" + LIMIT_PREFIX + "=2", 200, expectedResponse);
     }
 
     @Test
@@ -423,13 +529,13 @@
         // "metaData":{"payloadCount":2,"count":6,
         // "prev":"http://127.0.0.1:30000/jvm-memory/0.0.2?q===test1&m=true&l=2&o=0",
         // "next":"http://127.0.0.1:30000/jvm-memory/0.0.2?o=4&l=2&q===test1&m=true"}}
-        String expectedResponse = "{\"response\":[{\"e\":\"test4\",\"b\":\"test1\"},{\"b\":\"test1\"}]," +
+        String expectedResponse = "{\"response\":[{\"e\":\"test4\",\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "},{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}]," +
                 "\"metaData\":{\"payloadCount\":2,\"count\":6," +
                 "\"prev\":\"" + returnedUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + OFFSET_PREFIX + "\\u003d0\"," +
                 "\"next\":\"" + returnedUrl + "?" + OFFSET_PREFIX + "\\u003d4\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
 
-        HttpTestUtil.addRecords(client, resourceUrl, data);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=2&" + LIMIT_PREFIX + "=2", 200, expectedResponse);
+        HttpTestUtil.addRecords(client, serviceUrl, data);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=2&" + LIMIT_PREFIX + "=2", 200, expectedResponse);
     }
 
     @Test
@@ -442,13 +548,142 @@
         // metaData":{"payloadCount":1,"count":6,
         // "prev":"http://127.0.0.1:30000/jvm-memory/0.0.2?q=b==test1&m=true&l=2&o=0",
         // "next":"http://127.0.0.1:30000/jvm-memory/0.0.2?o=5&l=1&q=b==test1&m=true"}}
-        String expectedResponse = "{\"response\":[{\"e\":\"test4\",\"b\":\"test1\"}," +
-                "{\"b\":\"test1\"},{\"b\":\"test1\"}]," +
+        String expectedResponse = "{\"response\":[{\"e\":\"test4\",\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}," +
+                "{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "},{\"b\":\"test1\"" + SYSTEM_JVM_FRAGMENT + "}]," +
                 "\"metaData\":{\"payloadCount\":1,\"count\":6," +
                 "\"prev\":\"" + returnedUrl + "?" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\\u0026" + LIMIT_PREFIX + "\\u003d2\\u0026" + OFFSET_PREFIX + "\\u003d0\"," +
                 "\"next\":\"" + returnedUrl + "?" + OFFSET_PREFIX + "\\u003d5\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
 
-        HttpTestUtil.addRecords(client, resourceUrl, data);
-        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, resourceUrl + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=2&" + LIMIT_PREFIX + "=3", 200, expectedResponse);
+        HttpTestUtil.addRecords(client, serviceUrl, data);
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?" + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=2&" + LIMIT_PREFIX + "=3", 200, expectedResponse);
+    }
+
+
+    private static String getRandomSystemId() {
+        return UUID.randomUUID().toString();
+    }
+
+    private static String getRandomJvmId() {
+        return UUID.randomUUID().toString();
+    }
+
+    private String createJSON() {
+        return createJSON(getTimestamp());
+    }
+
+    private long getTimestamp() {
+        timeStamp += 1;
+        return timeStamp;
+    }
+
+    private String createJSON(final long ts) {
+        return jsonData.replace(TIMESTAMP_TOKEN, Long.toString(ts));
+    }
+
+    private ContentResponse put(final String systemid, final String jvmid, final long ts) throws InterruptedException, ExecutionException, TimeoutException {
+        final Request request = client.newRequest(simpleUrl + "/systems/" + systemid + "/jvms/" + jvmid);
+        request.header(HttpHeader.CONTENT_TYPE, "application/json");
+        final String contentStr = createJSON(ts);
+        request.content(new StringContentProvider("{ \"set\" : " +contentStr + "}"));
+        ContentResponse response = request.method(HttpMethod.PUT).send();
+        assertEquals(HTTP_200_OK, response.getStatus());
+        final String expected = "";
+        assertEquals(expected, response.getContentAsString());
+        return response;
+    }
+
+    private ContentResponse post(final String systemid, final String jvmid) throws InterruptedException, ExecutionException, TimeoutException {
+        final Request request = client.newRequest(simpleUrl + "/systems/" + systemid + "/jvms/" + jvmid);
+        request.header(HttpHeader.CONTENT_TYPE, "application/json");
+        request.content(new StringContentProvider( '[' + createJSON() + ']'));
+        ContentResponse response = request.method(HttpMethod.POST).send();
+        assertEquals(HTTP_200_OK, response.getStatus());
+        final String expected = "";
+        assertEquals(expected, response.getContentAsString());
+        return response;
+    }
+
+    private ContentResponse getUnknown(final String systemid, final String jvmid) throws InterruptedException, ExecutionException, TimeoutException {
+        ContentResponse response = get(systemid, jvmid);
+        assertTrue(parse(response, jvmid).isEmpty());
+        return response;
+    }
+
+    private ContentResponse getKnown(final String systemid, final String jvmid) throws InterruptedException, ExecutionException, TimeoutException {
+        ContentResponse response = get(systemid, jvmid);
+        assertEquals(1, parse(response, jvmid).size());
+        return response;
+    }
+
+    private ContentResponse get(final String systemid, final String jvmid) throws InterruptedException, ExecutionException, TimeoutException {
+        ContentResponse response = client.newRequest(simpleUrl + "/systems/" + systemid + "/jvms/" + jvmid).method(HttpMethod.GET).send();
+        assertEquals(HTTP_200_OK, response.getStatus());
+        return response;
+    }
+
+    private ContentResponse get(final String systemid, final String jvmid, final String query) throws InterruptedException, ExecutionException, TimeoutException {
+        final Request rq = client.newRequest(simpleUrl + "/systems/" + systemid + "/jvms/" + jvmid + query);
+        rq.method(HttpMethod.GET);
+        ContentResponse response = rq.send();
+        assertEquals(HTTP_200_OK, response.getStatus());
+        return response;
+    }
+
+    private ContentResponse delete(final String systemid, final String jvmid) throws InterruptedException, ExecutionException, TimeoutException {
+        ContentResponse response = client.newRequest(simpleUrl + "/systems/" + systemid + "/jvms/" + jvmid).method(HttpMethod.DELETE).send();
+        assertEquals(HTTP_200_OK, response.getStatus());
+        final String expected = "";
+        assertEquals(expected, response.getContentAsString());
+        return response;
+    }
+
+    class TinyJvmMemory {
+        String jvmId;
+        long timeStamp;
+        public TinyJvmMemory(String jvmId, long ts) {
+            this.jvmId = jvmId;
+            this.timeStamp = ts;
+        }
+    }
+    private List<TinyJvmMemory> parse(ContentResponse contentResponse, final String expectedJvmId) {
+
+        JsonParser parser = new JsonParser();
+        JsonObject json = (JsonObject) parser.parse(contentResponse.getContentAsString());
+        JsonElement response = json.get("response");
+
+        JsonArray allData = response.getAsJsonArray();
+        List<TinyJvmMemory> result = new ArrayList<>();
+
+        for (JsonElement entry : allData) {
+
+            json = (JsonObject) parser.parse(entry.toString());
+
+            assertTrue(json.has("jvmId"));
+            //assertTrue(json.has("agentId"));
+            assertTrue(json.has("timeStamp"));
+
+            final String jvmId = json.get("jvmId").getAsString();
+            //final String agentId = json.get("agentId").getAsString();
+            //final long timeStamp = getLong(json, "timeStamp");
+
+            if (expectedJvmId != null) {
+                assertEquals(expectedJvmId, jvmId);
+            }
+
+            TinyJvmMemory hi = new TinyJvmMemory(jvmId, 0);
+
+            result.add(hi);
+        }
+        return result;
+    }
+
+    private static long getLong(JsonObject json, final String id) {
+        JsonElement el = json.get(id);
+        if (el.isJsonObject()) {
+            final JsonObject o = el.getAsJsonObject();
+            return o.get("$numberLong").getAsLong();
+        } else {
+            return el.getAsLong();
+        }
     }
 }