changeset 249:f638608b889a

Add metadata responses for PUT, POST, DELETE, fix bug in executor Reviewed-by: jerboaa, stooke Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-July/024109.html
author Chris Lessard <clessard@redhat.com>
date Wed, 06 Sep 2017 10:18:26 -0400
parents b951d7bc0308
children 2d924d7904a7
files common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/response/MongoMetaDataResponseBuilder.java common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/response/MongoResponseBuilder.java common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/servlet/MongoHttpHandlerHelper.java common/mongodb/src/test/java/com/redhat/thermostat/gateway/common/mongodb/response/MongoMetaDataResponseBuilderTest.java 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 tests/test-utils/src/main/java/com/redhat/thermostat/gateway/tests/utils/HttpTestUtil.java
diffstat 7 files changed, 190 insertions(+), 65 deletions(-) [+]
line wrap: on
line diff
--- a/common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/response/MongoMetaDataResponseBuilder.java	Wed Sep 06 09:43:47 2017 -0400
+++ b/common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/response/MongoMetaDataResponseBuilder.java	Wed Sep 06 10:18:26 2017 -0400
@@ -57,8 +57,8 @@
     private final String next;
     private final String first;
     private final String last;
-    private final Integer insertCount;
-    private final Integer matchCount;
+    private final Long insertCount;
+    private final Long matchCount;
     private final Integer elapsed;
 
     public static class MetaBuilder {
@@ -69,8 +69,8 @@
         private String next;
         private String first;
         private String last;
-        private Integer insertCount;
-        private Integer matchCount;
+        private Long insertCount;
+        private Long matchCount;
         private Integer elapsed;
 
         public MetaBuilder payloadCount(Integer payload) {
@@ -103,12 +103,12 @@
             return this;
         }
 
-        public MetaBuilder insertCount(Integer count) {
+        public MetaBuilder insertCount(Long count) {
             this.insertCount = count;
             return this;
         }
 
-        public MetaBuilder matchCount(Integer count) {
+        public MetaBuilder matchCount(Long count) {
             this.matchCount = count;
             return this;
         }
--- a/common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/response/MongoResponseBuilder.java	Wed Sep 06 09:43:47 2017 -0400
+++ b/common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/response/MongoResponseBuilder.java	Wed Sep 06 10:18:26 2017 -0400
@@ -56,6 +56,11 @@
 
     private final ArrayList<Document> response;
     private final MongoMetaDataResponseBuilder metaData;
+    private static final String NO_METADATA;
+
+    static {
+        NO_METADATA = "";
+    }
 
     public static class Builder {
 
@@ -92,14 +97,18 @@
             return this;
         }
 
-
         public Builder addMetaData(MongoMetaDataResponseBuilder metaData) {
             this.metaData = metaData;
             return this;
         }
 
         public String build() {
-            MongoResponseBuilder data = new MongoResponseBuilder(this);
+            if (queryDocuments == null && metaData == null) {
+                return NO_METADATA;
+            }
+
+            MongoResponseBuilder data;
+            data = new MongoResponseBuilder(this);
             return gson.toJson(data);
         }
     }
--- a/common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/servlet/MongoHttpHandlerHelper.java	Wed Sep 06 09:43:47 2017 -0400
+++ b/common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/servlet/MongoHttpHandlerHelper.java	Wed Sep 06 10:18:26 2017 -0400
@@ -162,16 +162,26 @@
         return handlePut(httpServletRequest, context, null, null, queries, metadata, body);
     }
 
-    public Response handlePut(HttpServletRequest httpServletRequest, ServletContext context, String systemId, String jvmId, String queries, String metadata, String body) {
+    public Response handlePut(HttpServletRequest httpServletRequest, ServletContext context, String systemId, String jvmId, String queries, String returnMetadata, String body) {
         try {
             RealmAuthorizer realmAuthorizer = (RealmAuthorizer) httpServletRequest.getAttribute(RealmAuthorizer.class.getName());
+            boolean metadata = Boolean.valueOf(returnMetadata);
+
 
             if (realmAuthorizer.updatable()) {
                 ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE);
 
-                mongoExecutor.execPutRequest(storage.getDatabase().getCollection(collectionName), body, queries, realmAuthorizer.getUpdatableRealms(), systemId, jvmId);
+                MongoDataResultContainer execResult = mongoExecutor.execPutRequest(storage.getDatabase().getCollection(collectionName), body, queries, realmAuthorizer.getUpdatableRealms(), systemId, jvmId);
 
-                return Response.status(Response.Status.OK).build();
+                MongoResponseBuilder.Builder response = new MongoResponseBuilder.Builder();
+                if (metadata) {
+                    MongoMetaDataResponseBuilder.MetaBuilder metadataResponse = new MongoMetaDataResponseBuilder.MetaBuilder();
+                    metadataResponse.matchCount(execResult.getPutReqMatches());
+
+                    response.addMetaData(metadataResponse.build());
+                }
+
+                return Response.status(Response.Status.OK).entity(response.build()).build();
             } else {
                 return Response.status(Response.Status.FORBIDDEN).build();
             }
@@ -196,16 +206,26 @@
         return handlePost(httpServletRequest, context, null, null, returnMetadata, body);
     }
 
-    public Response handlePost(HttpServletRequest httpServletRequest, ServletContext context, String systemId, String jvmId, String metadata, String body) {
+    public Response handlePost(HttpServletRequest httpServletRequest, ServletContext context, String systemId, String jvmId, String returnMetadata, String body) {
         try {
             RealmAuthorizer realmAuthorizer = (RealmAuthorizer) httpServletRequest.getAttribute(RealmAuthorizer.class.getName());
+            boolean metadata = Boolean.valueOf(returnMetadata);
+
 
             if (realmAuthorizer.writable()) {
                 ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE);
 
-                mongoExecutor.execPostRequest(storage.getDatabase().getCollection(collectionName, DBObject.class), body, realmAuthorizer.getWritableRealms(), systemId, jvmId);
+                MongoDataResultContainer execResult = mongoExecutor.execPostRequest(storage.getDatabase().getCollection(collectionName, DBObject.class), body, realmAuthorizer.getWritableRealms(), systemId, jvmId);
+                MongoResponseBuilder.Builder response = new MongoResponseBuilder.Builder();
 
-                return Response.status(Response.Status.OK).build();
+                if (metadata) {
+                    MongoMetaDataResponseBuilder.MetaBuilder metadataResponse = new MongoMetaDataResponseBuilder.MetaBuilder();
+                    metadataResponse.insertCount(execResult.getPostReqInsertions());
+
+                    response.addMetaData(metadataResponse.build());
+                }
+
+                return Response.status(Response.Status.OK).entity(response.build()).build();
             } else {
                 return Response.status(Response.Status.FORBIDDEN).build();
             }
@@ -226,16 +246,24 @@
         return handleDelete(httpServletRequest, context, andSystemIdJvmIdQuery(queries, systemId, jvmId), metadata);
     }
 
-    public Response handleDelete(HttpServletRequest httpServletRequest, ServletContext context, String queries, String metadata) {
+    public Response handleDelete(HttpServletRequest httpServletRequest, ServletContext context, String queries, String returnMetadata) {
         try {
             RealmAuthorizer realmAuthorizer = (RealmAuthorizer) httpServletRequest.getAttribute(RealmAuthorizer.class.getName());
-
+            boolean metadata = Boolean.valueOf(returnMetadata);
             if (realmAuthorizer.deletable()) {
                 ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE);
 
-                mongoExecutor.execDeleteRequest(storage.getDatabase().getCollection(collectionName), queries, realmAuthorizer.getDeletableRealms());
+                MongoDataResultContainer execResult = mongoExecutor.execDeleteRequest(storage.getDatabase().getCollection(collectionName), queries, realmAuthorizer.getDeletableRealms());
 
-                return Response.status(Response.Status.OK).build();
+                MongoResponseBuilder.Builder response = new MongoResponseBuilder.Builder();
+                if (metadata) {
+                    MongoMetaDataResponseBuilder.MetaBuilder metadataResponse = new MongoMetaDataResponseBuilder.MetaBuilder();
+                    metadataResponse.matchCount(execResult.getDeleteReqMatches());
+
+                    response.addMetaData(metadataResponse.build());
+                }
+
+                return Response.status(Response.Status.OK).entity(response.build()).build();
             } else {
                 return Response.status(Response.Status.FORBIDDEN).build();
             }
--- a/common/mongodb/src/test/java/com/redhat/thermostat/gateway/common/mongodb/response/MongoMetaDataResponseBuilderTest.java	Wed Sep 06 09:43:47 2017 -0400
+++ b/common/mongodb/src/test/java/com/redhat/thermostat/gateway/common/mongodb/response/MongoMetaDataResponseBuilderTest.java	Wed Sep 06 10:18:26 2017 -0400
@@ -69,8 +69,8 @@
                 .elapsed(5000)
                 .first(fakeUrl + "/0")
                 .last(fakeUrl + "/10")
-                .matchCount(10)
-                .insertCount(0);
+                .matchCount(10L)
+                .insertCount(0L);
 
         String output = mongoMetaDataResponseBuilder.build().toString();
         String expected = "{\"payloadCount\":5,\"count\":10,\"prev\":\"http://127.0.0.1:8080/fake/endpoint/0\"," +
--- a/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcServiceIntegrationTest.java	Wed Sep 06 09:43:47 2017 -0400
+++ b/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcServiceIntegrationTest.java	Wed Sep 06 10:18:26 2017 -0400
@@ -77,6 +77,10 @@
     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 NO_EXPECTED_RESPONSE = "";
+    private static final String NO_QUERY = "";
+    private static final String NO_DATA_TO_SEND = "";
+    private static final String NO_DATA_TYPE = "";
 
     private final String data = "[{ \"a\" : \"test\", \"b\" : \"test1\", \"c\" : \"test2\" }, { \"d\" : \"test3\"}," +
             "{\"e\" : \"test4\" }]";
@@ -96,7 +100,7 @@
     private static final String OFFSET_PREFIX = "offset";
     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 EXCLUDE_PREFIX = "exclude";
     private static final String TIMESTAMP_TOKEN = "\"$TIMESTAMP$\"";
     private static final String JVMID_TOKEN = "\"$JVMID_TOKEN\"";
 
@@ -134,7 +138,11 @@
         assertEquals(expectedStatus, postResponse.getStatus());
 
         if (!expectedResponse.equals("")) {
-            makeHttpGetRequest(serviceUrl, expectedResponse, expectedStatus);
+            if (httpMethod == HttpMethod.DELETE) {
+                assertEquals(expectedResponse, postResponse.getContentAsString());
+            } else {
+                makeHttpGetRequest(serviceUrl, expectedResponse, expectedStatus);
+            }
         }
     }
 
@@ -203,11 +211,9 @@
         getUnknown(systemid, jvmid);
     }
 
-
-
     @Test
     public void testGet() throws InterruptedException, TimeoutException, ExecutionException {
-        makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 200);
         final String expectedResponse = "{\"response\":[{\"a\":\"test\",\"b\":\"test1\","+
                 "\"c\":\"test2\"" + SYSTEM_JVM_FRAGMENT + "}]}";
         makeHttpGetRequest(serviceUrl, expectedResponse, 200);
@@ -215,7 +221,7 @@
 
     @Test
     public void testGetLimitParam() throws InterruptedException, TimeoutException, ExecutionException {
-        makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 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);
@@ -224,7 +230,7 @@
     @Test
     public void testGetSortParam() throws InterruptedException, TimeoutException, ExecutionException {
         final String data ="[{\"a\":\"1\"}, {\"a\":\"2\"}]";
-        makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 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);
@@ -232,21 +238,21 @@
 
     @Test
     public void testGetProjectParam() throws InterruptedException, TimeoutException, ExecutionException {
-        makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 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);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 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);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 200);
         final String expectedResponse = "{\"response\":[{\"a\":\"test\",\"b\":\"test1\",\"c\":\"test2\"" + SYSTEM_JVM_FRAGMENT + "}]}";
         makeHttpGetRequest(serviceUrl + '?' + QUERY_PREFIX + "=b==test1", expectedResponse, 200);
     }
@@ -254,45 +260,83 @@
     @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",
+        makeHttpMethodRequest(HttpMethod.POST, '?' + METADATA_PREFIX + "=false", "[{\"f1\":\"test\"}]", "application/json",
                  expectedResponse, 200);
     }
 
     @Test
     public void testPostXML() throws InterruptedException,TimeoutException, ExecutionException {
-        makeHttpMethodRequest(HttpMethod.POST,"","","application/xml","", 415);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, NO_DATA_TO_SEND, "application/xml", NO_EXPECTED_RESPONSE, 415);
+    }
+
+    @Test
+    public void testPostWithMetaData() throws InterruptedException, TimeoutException, ExecutionException {
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, "[{\"f1\":\"test\"}]", "application/json", NO_EXPECTED_RESPONSE, 200);
+        StringContentProvider stringContentProvider = new StringContentProvider("[{\"f1\":\"test\"}]", "UTF-8");
+        ContentResponse response = client.newRequest(serviceUrl + "?" + METADATA_PREFIX + "=true")
+                .method(HttpMethod.POST)
+                .content(stringContentProvider, "application/json")
+                .send();
+
+        assertEquals(200, response.getStatus());
+
+        assertEquals("{\"metaData\":{\"insertCount\":1}}", response.getContentAsString());
     }
 
     @Test
     public void testInvalidDataPost() throws InterruptedException, TimeoutException, ExecutionException {
-        makeHttpMethodRequest(HttpMethod.POST,"","{\"badFormat\":\"missing square brackets\"}",
-                "application/json","", 400);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, "{\"badFormat\":\"missing square brackets\"}",
+                "application/json", NO_EXPECTED_RESPONSE, 400);
     }
 
     @Test
     public void testDelete() throws InterruptedException, TimeoutException, ExecutionException {
-        makeHttpMethodRequest(HttpMethod.DELETE,"","","","", 200);
+        makeHttpMethodRequest(HttpMethod.DELETE, NO_QUERY, NO_DATA_TO_SEND, NO_DATA_TYPE, NO_EXPECTED_RESPONSE, 200);
+    }
+
+    @Test
+    public void testDeleteWithMetaData() throws InterruptedException, TimeoutException, ExecutionException {
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, "[{\"f1\":\"test\"}]", "application/json", NO_EXPECTED_RESPONSE, 200);
+
+        makeHttpMethodRequest(HttpMethod.DELETE, "?" + QUERY_PREFIX + "=f1==test&" + METADATA_PREFIX + "=true",
+                NO_DATA_TO_SEND, NO_DATA_TYPE, "{\"metaData\":{\"matchCount\":1}}", 200);
     }
 
     @Test
     public void testNonExistentDataDelete() throws InterruptedException, TimeoutException, ExecutionException {
-        makeHttpMethodRequest(HttpMethod.DELETE,'?' + QUERY_PREFIX + "=nonExist==Null","","","", 200);
+        makeHttpMethodRequest(HttpMethod.DELETE, '?' + QUERY_PREFIX + "=nonExist==Null", NO_DATA_TO_SEND, NO_DATA_TYPE,
+                NO_EXPECTED_RESPONSE, 200);
     }
 
     @Test
     public void testPostPutDeleteMockedData() throws InterruptedException, TimeoutException, ExecutionException {
         final String expectedResponse = "{\"response\":[{\"f1\":\"test\"" + SYSTEM_JVM_FRAGMENT + "}]}";
-        makeHttpMethodRequest(HttpMethod.POST,"","[{\"f1\":\"test\"}]","application/json",
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, "[{\"f1\":\"test\"}]", "application/json",
                  expectedResponse, 200);
 
         final String expectedResponse2 = "{\"response\":[{\"f1\":\"newdata\"" + SYSTEM_JVM_FRAGMENT + "}]}";
-        makeHttpMethodRequest(HttpMethod.PUT,'?' + QUERY_PREFIX + "=f1==test","{\"set\": {\"f1\":\"newdata\"}}",
+        makeHttpMethodRequest(HttpMethod.PUT, '?' + QUERY_PREFIX + "=f1==test", "{\"set\": {\"f1\":\"newdata\"}}",
                 "application/json", expectedResponse2, 200);
 
-        makeHttpMethodRequest(HttpMethod.DELETE,"?q=f1==test","","","", 200);
+        makeHttpMethodRequest(HttpMethod.DELETE, "?q=f1==test", NO_DATA_TO_SEND, NO_DATA_TYPE, NO_EXPECTED_RESPONSE, 200);
     }
 
     @Test
+    public void testPutWithMetaData() throws InterruptedException, TimeoutException, ExecutionException {
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, "[{\"f1\":\"test\"}]", "application/json", NO_EXPECTED_RESPONSE, 200);
+        StringContentProvider stringContentProvider = new StringContentProvider("{\"set\": {\"f1\":\"newdata\"}}", "UTF-8");
+        ContentResponse response = client
+                .newRequest(serviceUrl + "?" + QUERY_PREFIX + "=f1==test&" + METADATA_PREFIX + "=true")
+                .method(HttpMethod.PUT)
+                .content(stringContentProvider, "application/json")
+                .send();
+
+        assertEquals(200, response.getStatus());
+        assertEquals("{\"metaData\":{\"matchCount\":1}}", response.getContentAsString());
+
+
+    }
+    @Test
     public void testGetWithMetaDataAndLimit() throws InterruptedException, TimeoutException, ExecutionException {
         String data ="[{\"a\":\"test\",\"b\":\"test1\",\"c\":\"test2\"}, {\"b\":\"test1\"},"+
                 "{\"e\":\"test4\",\"b\":\"test1\"}]";
@@ -304,7 +348,7 @@
                 "\"metaData\":{\"payloadCount\":1,\"count\":3,"+
                 "\"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);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 200);
         makeHttpGetRequest(serviceUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=1", expectedResponse, 200);
     }
 
@@ -320,7 +364,7 @@
                 "\"metaData\":{\"payloadCount\":1,\"count\":3,"+
                 "\"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);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 200);
 
         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);
@@ -344,7 +388,7 @@
                 "\"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);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 200);
         makeHttpGetRequest(serviceUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + OFFSET_PREFIX + "=1", expectedResponse, 200);
     }
 
@@ -363,7 +407,7 @@
                 "\"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);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 200);
         makeHttpGetRequest(serviceUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=2&" + OFFSET_PREFIX + "=3", expectedResponse, 200);
     }
 
@@ -380,7 +424,7 @@
                 "\"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);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 200);
         makeHttpGetRequest(serviceUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=1&" + OFFSET_PREFIX + "=1", expectedResponse, 200);
     }
 
@@ -399,7 +443,7 @@
                 "\"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);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 200);
         makeHttpGetRequest(serviceUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=2&" + OFFSET_PREFIX + "=1", expectedResponse, 200);
     }
 
@@ -419,7 +463,7 @@
                 "\"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);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 200);
         makeHttpGetRequest(serviceUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=2&" + OFFSET_PREFIX + "=3", expectedResponse, 200);
     }
 
@@ -438,7 +482,7 @@
                 "\"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);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 200);
         makeHttpGetRequest(serviceUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=2&" + OFFSET_PREFIX + "=2", expectedResponse, 200);
     }
 
@@ -457,7 +501,7 @@
                 "\"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);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 200);
         makeHttpGetRequest(serviceUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=2&" + OFFSET_PREFIX + "=2", expectedResponse, 200);
     }
 
@@ -477,7 +521,7 @@
                 "\"metaData\":{\"payloadCount\":1,\"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 + "\\u003d5\\u0026" + LIMIT_PREFIX + "\\u003d1\\u0026" + QUERY_PREFIX + "\\u003db\\u003d\\u003dtest1\\u0026" + METADATA_PREFIX + "\\u003dtrue\"}}";
-        makeHttpMethodRequest(HttpMethod.POST,"", data,"application/json","", 200);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 200);
         makeHttpGetRequest(serviceUrl + '?' + QUERY_PREFIX + "=b==test1&" + METADATA_PREFIX + "=true&" + LIMIT_PREFIX + "=3&" + OFFSET_PREFIX + "=2", expectedResponse, 200);
     }
 
@@ -493,7 +537,7 @@
         collection.insertMany(insertDocuments);
 
         String updateString = "{\"set\" : {\"realms\" : 1, \"a\" : 2}}";
-        makeHttpMethodRequest(HttpMethod.PUT,"", updateString,"application/json","", 200);
+        makeHttpMethodRequest(HttpMethod.PUT, NO_QUERY, updateString, "application/json", NO_EXPECTED_RESPONSE, 200);
 
         FindIterable<Document> documents = collection.find();
         documents.forEach(new Block<Document>() {
@@ -509,11 +553,10 @@
         String data = "[{\"item\":1,}," +
                 "{\"item\":2}]";
 
-        makeHttpMethodRequest(HttpMethod.POST, "", data,
-                "application/json", "", 200);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 200);
 
         String updateString = "{\"set\" : {\"realms\" : 1}}";
-        makeHttpMethodRequest(HttpMethod.PUT,"", updateString,"application/json","", 400);
+        makeHttpMethodRequest(HttpMethod.PUT, NO_QUERY, updateString,"application/json", NO_EXPECTED_RESPONSE, 400);
 
         MongoCollection<Document> collection = mongodTestUtil.getCollection(serviceName);
         final Gson gson = new GsonBuilder().create();
@@ -561,11 +604,10 @@
         String data = "[{\"item\":1,}," +
                 "{\"item\":2}]";
 
-        makeHttpMethodRequest(HttpMethod.POST, "", data,
-                "application/json", "", 200);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 200);
 
         String updateString = "{\"set\" : {\"realms\" : 1, \"realms\" : 2}}";
-        makeHttpMethodRequest(HttpMethod.PUT,"", updateString,"application/json","", 400);
+        makeHttpMethodRequest(HttpMethod.PUT, NO_QUERY, updateString, "application/json", NO_EXPECTED_RESPONSE, 400);
 
         MongoCollection<Document> collection = mongodTestUtil.getCollection(serviceName);
         final Gson gson = new GsonBuilder().create();
@@ -583,8 +625,7 @@
     @Test
     public void testGetCannotSeeRealms() throws InterruptedException, ExecutionException, TimeoutException {
         String data = "[{\"item\":1},{\"item\":2}]";
-        makeHttpMethodRequest(HttpMethod.POST, "", data,
-                "application/json", "", 200);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 200);
 
         String expected = "{\"response\":[{\"item\":1" + SYSTEM_JVM_FRAGMENT + "}]}";
 
@@ -594,8 +635,7 @@
     @Test
     public void testGetProjectionCannotSeeRealms() throws InterruptedException, ExecutionException, TimeoutException {
         String data = "[{\"item\":1},{\"item\":2}]";
-        makeHttpMethodRequest(HttpMethod.POST, "", data,
-                "application/json", "", 200);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 200);
 
         String expected = "{\"response\":[{\"item\":1}]}";
 
@@ -605,8 +645,7 @@
     @Test
     public void testGetQueryCannotMatchRealms() throws InterruptedException, ExecutionException, TimeoutException {
         String data = "[{\"item\":1},{\"item\":2}]";
-        makeHttpMethodRequest(HttpMethod.POST, "", data,
-                "application/json", "", 200);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 200);
 
         ContentResponse response = client.newRequest(serviceUrl)
                 .param(RequestParameters.QUERY, "realms==" + getRealmArray(BasicRealmAuthorizer.DEFAULT_REALM))
@@ -615,13 +654,12 @@
         assertEquals(400, response.getStatus());
     }
 
-
     @Test
     public void testPostCannotAddRealms() throws InterruptedException, ExecutionException, TimeoutException {
         String data = "[{\"item\":1,\"realms\":[\"a\",\"b\"]}," +
                 "{\"item\":2,\"realms\":[\"a\",\"b\"]}]";
 
-        makeHttpMethodRequest(HttpMethod.POST, "", data, "application/json", "", 200);
+        makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 200);
 
         MongoCollection<Document> collection = mongodTestUtil.getCollection(serviceName);
         final Gson gson = new GsonBuilder().create();
--- a/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/memory/JvmMemoryServiceIntegrationTest.java	Wed Sep 06 09:43:47 2017 -0400
+++ b/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/memory/JvmMemoryServiceIntegrationTest.java	Wed Sep 06 10:18:26 2017 -0400
@@ -223,6 +223,12 @@
     }
 
     @Test
+    public void testPostDataWithMetaData() throws InterruptedException, TimeoutException, ExecutionException {
+        HttpTestUtil.addRecords(client, serviceUrl + "?" + METADATA_PREFIX + "=true",
+                "[{\"fakedata\":\"test\",\"a\":\"b\"},{\"c\":\"d\"}]", "{\"metaData\":{\"insertCount\":2}}");
+    }
+
+    @Test
     public void testPostPutAddsData() throws InterruptedException, TimeoutException, ExecutionException {
         String expectedDataBeforePut = "{\"response\":[{\"a\":\"b\"" + SYSTEM_JVM_FRAGMENT + "}]}";
         String expectedDataAfterPut = "{\"response\":[{\"a\":\"b\"" + SYSTEM_JVM_FRAGMENT + ",\"x\":\"y\"}]}";
@@ -257,6 +263,13 @@
     }
 
     @Test
+    public void testDeleteDifferentDataWithMetaData() throws InterruptedException, TimeoutException, ExecutionException {
+        HttpTestUtil.addRecords(client, serviceUrl, "[{\"fakedata\":\"test\",\"a\":\"b\"},{\"c\":\"d\"}]");
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.DELETE, serviceUrl + "?" + QUERY_PREFIX + "=a==b&"
+                + METADATA_PREFIX + "=true", 200, "{\"metaData\":{\"matchCount\":1}}");
+    }
+
+    @Test
     public void testMalformedDeleteRequestDoesNotMutateData() throws InterruptedException, TimeoutException, ExecutionException {
         String expectedDataResponse = "{\"response\":[{\"fakedata\":\"test\"" + SYSTEM_JVM_FRAGMENT + "}]}";
         HttpTestUtil.addRecords(client, serviceUrl, "[{\"fakedata\":\"test\"}]");
@@ -272,6 +285,15 @@
     }
 
     @Test
+    public void testPutDifferentDataWithMetaData() throws InterruptedException, TimeoutException, ExecutionException {
+        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&" +
+                METADATA_PREFIX + "=true", "{\"set\":{\"c\":\"d\"}}", 200, "{\"metaData\":{\"matchCount\":1}}");
+        HttpTestUtil.testContentlessResponse(client, HttpMethod.GET, serviceUrl + "?l=5", 200, expectedDataResponse);
+    }
+    @Test
     public void testPostAndPutWithInvalidData() throws InterruptedException, TimeoutException, ExecutionException {
         String expectedDataResponse = "{\"response\":[{\"fakedata\":\"test\"" + SYSTEM_JVM_FRAGMENT + "}]}";
         String urlQuery = serviceUrl + "?" + QUERY_PREFIX + "=nosuchkey==nosuchvalue";
--- a/tests/test-utils/src/main/java/com/redhat/thermostat/gateway/tests/utils/HttpTestUtil.java	Wed Sep 06 09:43:47 2017 -0400
+++ b/tests/test-utils/src/main/java/com/redhat/thermostat/gateway/tests/utils/HttpTestUtil.java	Wed Sep 06 10:18:26 2017 -0400
@@ -50,7 +50,8 @@
 
     public static final String EMPTY_RESPONSE = "{\"response\":[]}";
 
-    public static void addRecords(HttpClient client, String resourceUrl, String content) throws InterruptedException, ExecutionException, TimeoutException {
+    public static void addRecords(HttpClient client, String resourceUrl, String content)
+            throws InterruptedException, ExecutionException, TimeoutException {
         StringContentProvider stringContentProvider = new StringContentProvider(content, "UTF-8");
         ContentResponse response = client.newRequest(resourceUrl)
                                          .method(HttpMethod.POST)
@@ -59,6 +60,17 @@
         assertEquals(200, response.getStatus());
     }
 
+    public static void addRecords(HttpClient client, String resourceUrl, String content, String expectedResponse)
+            throws InterruptedException, ExecutionException, TimeoutException {
+        StringContentProvider stringContentProvider = new StringContentProvider(content, "UTF-8");
+        ContentResponse response = client.newRequest(resourceUrl)
+                .method(HttpMethod.POST)
+                .content(stringContentProvider, "application/json")
+                .send();
+        assertEquals(200, response.getStatus());
+        assertEquals(expectedResponse, response.getContentAsString());
+    }
+
     public static void testContentlessResponse(HttpClient client,
                                                HttpMethod httpMethod,
                                                String url,
@@ -94,4 +106,20 @@
                                          .send();
         assertEquals(expectedResponseStatus, response.getStatus());
     }
+
+    public static void testContentResponse(HttpClient client,
+                                           HttpMethod httpMethod,
+                                           String url,
+                                           String content,
+                                           int expectedResponseStatus,
+                                           String expectedResponse)
+            throws InterruptedException, TimeoutException, ExecutionException {
+        StringContentProvider stringContentProvider = new StringContentProvider(content, "UTF-8");
+        ContentResponse response = client.newRequest(url)
+                                         .method(httpMethod)
+                                         .content(stringContentProvider, "application/json")
+                                         .send();
+        assertEquals(expectedResponseStatus, response.getStatus());
+        assertEquals(expectedResponse, response.getContentAsString());
+    }
 }