# HG changeset patch # User Jie Kang # Date 1504789627 14400 # Node ID ed634d83e742e3eeb43951bf2aae6ad8accd9b0b # Parent 2d924d7904a71bb29ed42a4b29eb1a8b526fe30f Add delta information to jvm-gc service Reviewed-by: jerboaa Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-July/024048.html Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-August/024417.html diff -r 2d924d7904a7 -r ed634d83e742 common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/filters/MongoSortFilters.java --- a/common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/filters/MongoSortFilters.java Wed Sep 06 13:11:55 2017 -0400 +++ b/common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/filters/MongoSortFilters.java Thu Sep 07 09:07:07 2017 -0400 @@ -42,14 +42,17 @@ public class MongoSortFilters { + public static final Character DESCENDING_SORT = '-'; + public static final Character ASCENDING_SORT = '+'; + public static Bson createSortObject(String sort) { BasicDBObject sortObject = new BasicDBObject(); if (sort != null) { String[] items = sort.split(","); for (String item : items) { - if (item.charAt(0) == '+') { + if (item.charAt(0) == ASCENDING_SORT) { sortObject.append(item.substring(1), 1); - } else if (item.charAt(0) == '-') { + } else if (item.charAt(0) == DESCENDING_SORT) { sortObject.append(item.substring(1), -1); } } diff -r 2d924d7904a7 -r ed634d83e742 services/jvm-gc/src/main/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcHttpHandler.java --- a/services/jvm-gc/src/main/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcHttpHandler.java Wed Sep 06 13:11:55 2017 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,138 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.gateway.service.jvm.gc; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.GET; -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; -import javax.ws.rs.core.Response; - -import com.redhat.thermostat.gateway.common.mongodb.servlet.RequestParameters; -import com.redhat.thermostat.gateway.common.mongodb.servlet.MongoHttpHandlerHelper; - -@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(@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, - @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, 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.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.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(@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.handleDeleteWithJvmID(httpServletRequest, context, systemId, jvmId, queries, metadata); - } -} diff -r 2d924d7904a7 -r ed634d83e742 services/jvm-gc/src/main/java/com/redhat/thermostat/gateway/service/jvm/gc/SwaggerSpecResourceHandler.java --- a/services/jvm-gc/src/main/java/com/redhat/thermostat/gateway/service/jvm/gc/SwaggerSpecResourceHandler.java Wed Sep 06 13:11:55 2017 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.gateway.service.jvm.gc; - -import java.io.IOException; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import com.redhat.thermostat.gateway.common.core.servlet.BasicResourceHandler; - -@Path("doc/{fileName: .+\\.yaml}") -@Produces(MediaType.TEXT_PLAIN) -public class SwaggerSpecResourceHandler extends BasicResourceHandler { - - @GET - public Response getFileAsPlainText(@PathParam("fileName") String fileName) throws IOException { - return getFileAsResponse(SwaggerSpecResourceHandler.class.getClassLoader(), fileName); - } - -} diff -r 2d924d7904a7 -r ed634d83e742 services/jvm-gc/src/main/java/com/redhat/thermostat/gateway/service/jvm/gc/http/JvmGcHttpHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jvm-gc/src/main/java/com/redhat/thermostat/gateway/service/jvm/gc/http/JvmGcHttpHandler.java Thu Sep 07 09:07:07 2017 -0400 @@ -0,0 +1,174 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.gateway.service.jvm.gc.http; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +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; +import javax.ws.rs.core.Response; + +import com.redhat.thermostat.gateway.common.core.auth.RealmAuthorizer; +import com.redhat.thermostat.gateway.common.mongodb.ThermostatMongoStorage; +import com.redhat.thermostat.gateway.common.mongodb.servlet.RequestParameters; +import com.redhat.thermostat.gateway.common.mongodb.servlet.MongoHttpHandlerHelper; +import com.redhat.thermostat.gateway.common.mongodb.servlet.ServletContextConstants; +import com.redhat.thermostat.gateway.service.jvm.gc.mongo.JvmGcMongoStorageHandler; + +@Path("/") +public class JvmGcHttpHandler { + + + private static final String collectionName = "jvm-gc"; + private final JvmGcMongoStorageHandler mongoStorageHandler = new JvmGcMongoStorageHandler(); + 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(@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, + @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, 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.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.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(@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.handleDeleteWithJvmID(httpServletRequest, context, systemId, jvmId, queries, metadata); + } + + @GET + @Path("/delta/{jvmId}") + @Consumes({ "application/json" }) + @Produces({ "application/json", "text/html; charset=utf-8" }) + public Response getJvmGcDelta(@PathParam("jvmId") String jvmId, + @QueryParam("l") @DefaultValue("1") Integer limit, + @QueryParam("o") @DefaultValue("0") Integer offset, + @QueryParam("a") Long afterTimeStamp, + @QueryParam("b") Long beforeTimeStamp, + @QueryParam("m") @DefaultValue("false") Boolean metadata, + @Context HttpServletRequest httpServletRequest, + @Context ServletContext context) { + try { + RealmAuthorizer realmAuthorizer = (RealmAuthorizer) httpServletRequest.getAttribute(RealmAuthorizer.class.getName()); + + if (realmAuthorizer.readable()) { + ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE); + + String response = mongoStorageHandler.getJvmGcDelta(storage.getDatabase().getCollection(collectionName), + jvmId, limit, offset, afterTimeStamp, beforeTimeStamp, metadata, httpServletRequest, + realmAuthorizer.getReadableRealms()); + return Response.status(Response.Status.OK).entity(response).build(); + } else { + return Response.status(Response.Status.FORBIDDEN).build(); + } + } catch (Exception e) { + return Response.status(Response.Status.BAD_REQUEST).build(); + } + } +} diff -r 2d924d7904a7 -r ed634d83e742 services/jvm-gc/src/main/java/com/redhat/thermostat/gateway/service/jvm/gc/http/SwaggerSpecResourceHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jvm-gc/src/main/java/com/redhat/thermostat/gateway/service/jvm/gc/http/SwaggerSpecResourceHandler.java Thu Sep 07 09:07:07 2017 -0400 @@ -0,0 +1,59 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.gateway.service.jvm.gc.http; + +import java.io.IOException; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import com.redhat.thermostat.gateway.common.core.servlet.BasicResourceHandler; + +@Path("doc/{fileName: .+\\.yaml}") +@Produces(MediaType.TEXT_PLAIN) +public class SwaggerSpecResourceHandler extends BasicResourceHandler { + + @GET + public Response getFileAsPlainText(@PathParam("fileName") String fileName) throws IOException { + return getFileAsResponse(SwaggerSpecResourceHandler.class.getClassLoader(), fileName); + } + +} diff -r 2d924d7904a7 -r ed634d83e742 services/jvm-gc/src/main/java/com/redhat/thermostat/gateway/service/jvm/gc/mongo/Fields.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jvm-gc/src/main/java/com/redhat/thermostat/gateway/service/jvm/gc/mongo/Fields.java Thu Sep 07 09:07:07 2017 -0400 @@ -0,0 +1,44 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.gateway.service.jvm.gc.mongo; + +class Fields { + static final String COLLECTOR_NAME = "collectorName"; + + static final String WALL_TIME = "wallTimeInMicros"; + static final String WALL_TIME_DELTA = "wallTimeDelta"; +} diff -r 2d924d7904a7 -r ed634d83e742 services/jvm-gc/src/main/java/com/redhat/thermostat/gateway/service/jvm/gc/mongo/JvmGcMongoStorageHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jvm-gc/src/main/java/com/redhat/thermostat/gateway/service/jvm/gc/mongo/JvmGcMongoStorageHandler.java Thu Sep 07 09:07:07 2017 -0400 @@ -0,0 +1,171 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.gateway.service.jvm.gc.mongo; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; + +import org.bson.Document; + +import com.mongodb.client.MongoCollection; +import com.redhat.thermostat.gateway.common.mongodb.ThermostatFields; +import com.redhat.thermostat.gateway.common.mongodb.executor.MongoDataResultContainer; +import com.redhat.thermostat.gateway.common.mongodb.executor.MongoExecutor; +import com.redhat.thermostat.gateway.common.mongodb.filters.MongoSortFilters; +import com.redhat.thermostat.gateway.common.mongodb.response.ArgumentRunnable; +import com.redhat.thermostat.gateway.common.mongodb.response.MongoMetaDataGenerator; +import com.redhat.thermostat.gateway.common.mongodb.response.MongoMetaDataResponseBuilder; +import com.redhat.thermostat.gateway.common.mongodb.response.MongoResponseBuilder; +import com.redhat.thermostat.gateway.common.mongodb.servlet.RequestParameters; + +public class JvmGcMongoStorageHandler { + + private static final String LONG_KEY = "$numberLong"; + private final MongoExecutor mongoExecutor = new MongoExecutor(); + + public String getJvmGcDelta(MongoCollection collection, + String jvmId, int limit, int offset, + Long afterTimeStamp, Long beforeTimeStamp, boolean metadata, + HttpServletRequest httpServletRequest, Set realms) throws IOException { + final String descendingSort = MongoSortFilters.DESCENDING_SORT + ThermostatFields.TIMESTAMP; + + List queries = new ArrayList<>(); + queries.add(ThermostatFields.JVM_ID + "==" + jvmId); + + if (afterTimeStamp != null) { + queries.add(ThermostatFields.TIMESTAMP + ">" + afterTimeStamp); + } + if (beforeTimeStamp != null) { + queries.add(ThermostatFields.TIMESTAMP + "<" + beforeTimeStamp); + } + + MongoDataResultContainer execResult = mongoExecutor.execGetRequest( + collection, limit, offset, descendingSort, queries, null, null, realms); + + MongoResponseBuilder.Builder response = new MongoResponseBuilder.Builder(); + + final Map previous = new HashMap<>(); + ArgumentRunnable runnable = new ArgumentRunnable() { + @Override + public void run(Document current) { + if (current.containsKey(Fields.WALL_TIME) && current.containsKey(Fields.COLLECTOR_NAME)) { + String collectorName = current.getString(Fields.COLLECTOR_NAME); + if (previous.containsKey(collectorName)) { + Document pre = previous.get(collectorName); + long prevWall = pre.get(Fields.WALL_TIME, Long.class); + long thisWall = current.get(Fields.WALL_TIME, Long.class); + long wallTimeDelta = prevWall - thisWall; + setWallTimeDelta(pre, wallTimeDelta); + previous.put(collectorName, current); + } else { + previous.put(collectorName, current); + } + } + } + }; + response.addQueryDocuments(execResult.getQueryDataResult(), runnable); + + // At this point, previous contains the last Documents for each collector + // in the list, which is sorted by timeStamp descending. Find the next + // Document in storage with timeStamp less than this last Document to calculate + // delta for the last Document. Set delta to 0 if there is no Document + + for (Map.Entry item : previous.entrySet()) { + List nextQuery = new ArrayList<>(); + + nextQuery.add(ThermostatFields.TIMESTAMP + "<" + + item.getValue().get(ThermostatFields.TIMESTAMP, Long.class)); + nextQuery.add(Fields.COLLECTOR_NAME + "==" + item.getKey()); + nextQuery.add(ThermostatFields.JVM_ID + "==" + jvmId); + + MongoDataResultContainer execLastResult = mongoExecutor.execGetRequest( + collection, 1, 0, descendingSort, nextQuery, null, null, realms); + + Document first = execLastResult.getQueryDataResult().first(); + + long wallTimeDelta = 0; + if (first != null) { + long prevWall = item.getValue().get(Fields.WALL_TIME, Long.class); + long lastWall = first.get(Fields.WALL_TIME, Long.class); + wallTimeDelta = prevWall - lastWall; + } + setWallTimeDelta(item.getValue(), wallTimeDelta); + } + + if (metadata) { + setMetadata(limit, offset, descendingSort, null, null, null, httpServletRequest, execResult, response); + } + + return response.build(); + } + + private void setMetadata(int limit, int offset, String sort, String queries, String includes, String excludes, HttpServletRequest httpServletRequest, + MongoDataResultContainer execResult, MongoResponseBuilder.Builder response) { + MongoMetaDataResponseBuilder.MetaBuilder metaDataResponse = new MongoMetaDataResponseBuilder.MetaBuilder(); + + LinkedHashMap paramArgs = new LinkedHashMap<>(); + paramArgs.put(RequestParameters.SORT, sort); + paramArgs.put(RequestParameters.QUERY, queries); + paramArgs.put(RequestParameters.INCLUDE, includes); + paramArgs.put(RequestParameters.EXCLUDE, excludes); + paramArgs.put(RequestParameters.METADATA, "true"); + paramArgs.put(RequestParameters.LIMIT, String.valueOf(limit)); + paramArgs.put(RequestParameters.OFFSET, String.valueOf(offset)); + String baseUrl = httpServletRequest.getRequestURL().toString(); + + MongoMetaDataGenerator metaDataGenerator = new MongoMetaDataGenerator(limit, offset, sort, queries, includes, excludes, paramArgs, execResult, baseUrl); + + metaDataGenerator.setDocAndPayloadCount(metaDataResponse); + metaDataGenerator.setPrev(metaDataResponse); + metaDataGenerator.setNext(metaDataResponse); + + response.addMetaData(metaDataResponse.build()); + } + + private void setWallTimeDelta(Document toSet, long delta) { + Document d = new Document(); + d.put(LONG_KEY, delta); + toSet.put(Fields.WALL_TIME_DELTA, d); + } +} diff -r 2d924d7904a7 -r ed634d83e742 services/jvm-gc/src/main/resources/jvm-gc-swagger.yaml --- a/services/jvm-gc/src/main/resources/jvm-gc-swagger.yaml Wed Sep 06 13:11:55 2017 -0400 +++ b/services/jvm-gc/src/main/resources/jvm-gc-swagger.yaml Thu Sep 07 09:07:07 2017 -0400 @@ -82,6 +82,21 @@ description: OK schema: $ref: '#/definitions/metadata' + /delta/{jvmId}: + parameters: + - $ref: '#/parameters/jvm-id' + get: + description: Get jvm gc information for jvm {jvmId} with deltas for wallTime. Always sorted by timeStamp ascending + parameters: + - $ref: '#/parameters/limit' + - $ref: '#/parameters/offset' + - $ref: '#/parameters/before' + - $ref: '#/parameters/after' + responses: + '200': + description: OK + schema: + $ref: '#/definitions/jvm-gc-delta-response' definitions: jvm-gc-stats-response: type: object @@ -107,8 +122,34 @@ type: string runCount: $ref: '#/definitions/metric' - wallTime: + wallTimeInMicros: $ref: '#/definitions/metric' + jvm-gc-delta-response: + type: object + properties: + response: + $ref: '#/definitions/jvm-gc-delta-stats' + jvm-gc-delta-stats: + type: array + items: + $ref: '#/definitions/jvm-gc-delta-stat' + jvm-gc-delta-stat: + type: object + properties: + agentId: + type: string + jvmId: + type: string + timeStamp: + $ref: '#/definitions/timestamp' + collectorName: + type: string + runCount: + $ref: '#/definitions/metric' + wallTimeInMicros: + $ref: '#/definitions/metric' + wallTimeDelta: + $ref: '#/definitions/metric' metric: type: object properties: @@ -165,6 +206,12 @@ required: true schema: $ref: '#/definitions/jvm-gc-stats' + jvm-id: + name: jvmId + in: path + required: true + type: string + description: The ID of the jvm put-body: name: putBody in: body @@ -214,6 +261,18 @@ precedence over 'include' parameter type: string required: false + before: + name: b + in: query + description: Before timeStamp. A long that specifies to return documents before the timeStamp. + type: integer + format: int64 + after: + name: a + in: query + description: After timeStamp. A long that specifies to return documents after the timeStamp. + type: integer + format: int64 metadata: name: metadata type: boolean diff -r 2d924d7904a7 -r ed634d83e742 tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcServiceIntegrationTest.java --- a/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcServiceIntegrationTest.java Wed Sep 06 13:11:55 2017 -0400 +++ b/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcServiceIntegrationTest.java Thu Sep 07 09:07:07 2017 -0400 @@ -42,6 +42,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.io.UnsupportedEncodingException; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; @@ -62,6 +63,7 @@ import org.eclipse.jetty.client.util.StringContentProvider; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; +import org.junit.Ignore; import org.junit.Test; import com.google.gson.Gson; @@ -87,12 +89,12 @@ private final String jsonData = "{\n" + - " \"timeStamp\" : " + TIMESTAMP_TOKEN + ",\n" + - " \"jvmId\" : " + JVMID_TOKEN + ",\n" + - " \"collectorName\" : \"some-collection\",\n" + - " \"runCount\" : \"22\",\n" + - " \"wallTimeInMicros\" : \"333333\"\n" + - "}\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"; @@ -110,6 +112,8 @@ private final String simpleUrl = baseUrl + "/" + serviceName + "/" + versionNumber; private final String serviceUrl = simpleUrl + "/systems/" + AGENT_ID + "/jvms/" + JVM_ID; + private final String deltaUrl = simpleUrl + "/delta"; + private final String deltaJvmUrl = deltaUrl + "/" + JVM_ID; private final String SYSTEM_JVM_FRAGMENT = ",\"systemId\":\"" + AGENT_ID + "\",\"jvmId\":\"" + JVM_ID + "\""; public JvmGcServiceIntegrationTest() { @@ -122,11 +126,15 @@ ContentResponse response = client.newRequest(url).method(HttpMethod.GET).send(); if (!expectedResponse.equals("")) { - assertEquals(expectedStatus, response.getStatus()); - assertEquals(expectedResponse, response.getContentAsString()); + verifyResponse(response, expectedResponse, expectedStatus); } } + private void verifyResponse(ContentResponse response, String expectedResponse, int expectedStatus) { + assertEquals(expectedStatus, response.getStatus()); + assertEquals(expectedResponse, response.getContentAsString()); + } + private void makeHttpMethodRequest(HttpMethod httpMethod, String urlQuery, String dataToSend, String dataType, String expectedResponse, int expectedStatus) throws InterruptedException, TimeoutException, ExecutionException { @@ -623,6 +631,252 @@ } @Test + public void testGetDeltaWallTime() throws InterruptedException, ExecutionException, TimeoutException, UnsupportedEncodingException { + String data = "[{\"collectorName\" : \"CMS\", \"timeStamp\" : { \"$numberLong\" : \"600\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"212864\" } }," + + "{\"collectorName\" : \"CMS\", \"timeStamp\": { \"$numberLong\" : \"500\"}," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"170887\"}}]"; + + makeHttpMethodRequest(HttpMethod.POST, "", data, "application/json", "", 200); + + String expectedResponse = "{\"response\":[{\"collectorName\":\"CMS\",\"timeStamp\":600," + + "\"wallTimeInMicros\":212864" + SYSTEM_JVM_FRAGMENT + "," + + "\"wallTimeDelta\":{\"$numberLong\":41977}}]}"; + ContentResponse response = client.newRequest(deltaJvmUrl).method(HttpMethod.GET).send(); + + verifyResponse(response, expectedResponse, 200); + } + + @Test + public void testGetSingleDeltaWallTime() throws InterruptedException, ExecutionException, TimeoutException, UnsupportedEncodingException { + String data = "[{\"collectorName\" : \"CMS\", \"timeStamp\" : { \"$numberLong\" : \"600\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"212864\" } }]"; + + makeHttpMethodRequest(HttpMethod.POST, "", data, "application/json", "", 200); + + String expectedResponse = "{\"response\":[{\"collectorName\":\"CMS\",\"timeStamp\":600," + + "\"wallTimeInMicros\":212864" + SYSTEM_JVM_FRAGMENT + "," + + "\"wallTimeDelta\":{\"$numberLong\":0}}]}"; + ContentResponse response = client.newRequest(deltaJvmUrl).method(HttpMethod.GET).param("l", "2").send(); + + verifyResponse(response, expectedResponse, 200); + } + + @Test + public void testGetMultipleDeltaWallTime() throws InterruptedException, ExecutionException, TimeoutException, UnsupportedEncodingException { + String data = "[{\"collectorName\" : \"CMS\", \"timeStamp\" : { \"$numberLong\" : \"400\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"14000\" } }," + + "{\"collectorName\" : \"CMS\", \"timeStamp\" : { \"$numberLong\" : \"600\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"212864\" } }," + + "{\"collectorName\" : \"CMS\", \"timeStamp\": { \"$numberLong\" : \"500\"}," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"170887\"}}]"; + + makeHttpMethodRequest(HttpMethod.POST, "", data, "application/json", "", 200); + + String expectedResponse = "{\"response\":[{\"collectorName\":\"CMS\",\"timeStamp\":600," + + "\"wallTimeInMicros\":212864" + SYSTEM_JVM_FRAGMENT + "," + + "\"wallTimeDelta\":{\"$numberLong\":41977}},{\"collectorName\":\"CMS\"," + + "\"timeStamp\":500,\"wallTimeInMicros\":170887" + SYSTEM_JVM_FRAGMENT + "," + + "\"wallTimeDelta\":{\"$numberLong\":156887}},{\"collectorName\":\"CMS\"," + + "\"timeStamp\":400,\"wallTimeInMicros\":14000" + SYSTEM_JVM_FRAGMENT + "," + + "\"wallTimeDelta\":{\"$numberLong\":0}}]}"; + ContentResponse response = client.newRequest(deltaJvmUrl).method(HttpMethod.GET).param("l", "10").send(); + + verifyResponse(response, expectedResponse, 200); + } + + @Test + public void testGetDeltaWallTimeWithOffset() throws InterruptedException, ExecutionException, TimeoutException, UnsupportedEncodingException { + String data = "[{\"collectorName\" : \"CMS\", \"timeStamp\" : { \"$numberLong\" : \"400\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"14000\" } }," + + "{\"collectorName\" : \"CMS\", \"timeStamp\" : { \"$numberLong\" : \"600\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"212864\" } }," + + "{\"collectorName\" : \"CMS\", \"timeStamp\": { \"$numberLong\" : \"500\"}," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"170887\"}}]"; + + makeHttpMethodRequest(HttpMethod.POST, "", data, "application/json", "", 200); + String offset = "1"; + String expectedResponse = "{\"response\":[{\"collectorName\":\"CMS\",\"timeStamp\":500," + + "\"wallTimeInMicros\":170887" + SYSTEM_JVM_FRAGMENT + "," + + "\"wallTimeDelta\":{\"$numberLong\":156887}}]}"; + ContentResponse response = client.newRequest(deltaJvmUrl).method(HttpMethod.GET).param("l", "1").param("o", offset).send(); + + verifyResponse(response, expectedResponse, 200); + + offset = "2"; + expectedResponse = "{\"response\":[{\"collectorName\":\"CMS\",\"timeStamp\":400," + + "\"wallTimeInMicros\":14000" + SYSTEM_JVM_FRAGMENT + "," + + "\"wallTimeDelta\":{\"$numberLong\":0}}]}"; + response = client.newRequest(deltaJvmUrl).method(HttpMethod.GET).param("l", "1").param("o", offset).send(); + + verifyResponse(response, expectedResponse, 200); + } + + @Test + public void testGetDeltaWallTimeWithAfter() throws InterruptedException, ExecutionException, TimeoutException, UnsupportedEncodingException { + String data = "[{\"collectorName\" : \"CMS\", \"timeStamp\" : { \"$numberLong\" : \"400\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"14000\" } }," + + "{\"collectorName\" : \"CMS\", \"timeStamp\" : { \"$numberLong\" : \"600\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"212864\" } }," + + "{\"collectorName\" : \"CMS\", \"timeStamp\": { \"$numberLong\" : \"500\"}," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"170887\"}}]"; + + makeHttpMethodRequest(HttpMethod.POST, "", data, "application/json", "", 200); + + String expectedResponse = "{\"response\":[{\"collectorName\":\"CMS\",\"timeStamp\":600," + + "\"wallTimeInMicros\":212864" + SYSTEM_JVM_FRAGMENT + "," + + "\"wallTimeDelta\":{\"$numberLong\":41977}},{\"collectorName\":\"CMS\"," + + "\"timeStamp\":500,\"wallTimeInMicros\":170887" + SYSTEM_JVM_FRAGMENT + "," + + "\"wallTimeDelta\":{\"$numberLong\":156887}}]}"; + ContentResponse response = client.newRequest(deltaJvmUrl).method(HttpMethod.GET).param("l", "10").param("a", "400").send(); + + verifyResponse(response, expectedResponse, 200); + } + + @Test + public void testGetDeltaWallTimeWithOffsetAndAfter() throws InterruptedException, ExecutionException, TimeoutException, UnsupportedEncodingException { + String data = "[{\"collectorName\" : \"CMS\", \"timeStamp\" : { \"$numberLong\" : \"400\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"14000\" } }," + + "{\"collectorName\" : \"CMS\", \"timeStamp\" : { \"$numberLong\" : \"600\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"212864\" } }," + + "{\"collectorName\" : \"CMS\", \"timeStamp\": { \"$numberLong\" : \"500\"}," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"170887\"}}]"; + + makeHttpMethodRequest(HttpMethod.POST, "", data, "application/json", "", 200); + + String expectedResponse = "{\"response\":[{\"collectorName\":\"CMS\",\"timeStamp\":500," + + "\"wallTimeInMicros\":170887" + SYSTEM_JVM_FRAGMENT + "," + + "\"wallTimeDelta\":{\"$numberLong\":156887}}]}"; + ContentResponse response = client.newRequest(deltaJvmUrl).method(HttpMethod.GET).param("l", "10") + .param("a", "400").param("o", "1").send(); + + verifyResponse(response, expectedResponse, 200); + } + + @Test + public void testGetDeltaWallTimeWithBefore() throws InterruptedException, ExecutionException, TimeoutException, UnsupportedEncodingException { + String data = "[{\"collectorName\" : \"CMS\", \"timeStamp\" : { \"$numberLong\" : \"400\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"14000\" } }," + + "{\"collectorName\" : \"CMS\", \"timeStamp\" : { \"$numberLong\" : \"600\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"212864\" } }," + + "{\"collectorName\" : \"CMS\", \"timeStamp\": { \"$numberLong\" : \"500\"}," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"170887\"}}]"; + + makeHttpMethodRequest(HttpMethod.POST, "", data, "application/json", "", 200); + + String expectedResponse = "{\"response\":[{\"collectorName\":\"CMS\",\"timeStamp\":400," + + "\"wallTimeInMicros\":14000" + SYSTEM_JVM_FRAGMENT + "," + + "\"wallTimeDelta\":{\"$numberLong\":0}}]}"; + ContentResponse response = client.newRequest(deltaJvmUrl).method(HttpMethod.GET).param("l", "10") + .param("b", "500").send(); + + verifyResponse(response, expectedResponse, 200); + } + + @Test + public void testGetDeltaWallTimeWithBeforeAndAfter() throws InterruptedException, ExecutionException, TimeoutException, UnsupportedEncodingException { + String data = "[{\"collectorName\" : \"CMS\", \"timeStamp\" : { \"$numberLong\" : \"400\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"14000\" } }," + + "{\"collectorName\" : \"CMS\", \"timeStamp\" : { \"$numberLong\" : \"600\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"212864\" } }," + + "{\"collectorName\" : \"CMS\", \"timeStamp\": { \"$numberLong\" : \"500\"}," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"170887\"}}]"; + + makeHttpMethodRequest(HttpMethod.POST, "", data, "application/json", "", 200); + + String expectedResponse = "{\"response\":[{\"collectorName\":\"CMS\",\"timeStamp\":500,\"wallTimeInMicros\":170887" + SYSTEM_JVM_FRAGMENT + ",\"wallTimeDelta\":{\"$numberLong\":156887}}]}"; + ContentResponse response = client.newRequest(deltaJvmUrl).method(HttpMethod.GET).param("l", "10") + .param("b", "600").param("a", "400").send(); + + verifyResponse(response, expectedResponse, 200); + } + + @Test + public void testGetDeltaWallTimeWithMultipleCollectors() throws InterruptedException, ExecutionException, TimeoutException, UnsupportedEncodingException { + String data = "[{\"collectorName\" : \"CMS\", \"timeStamp\" : { \"$numberLong\" : \"400\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"14000\" } }," + + "{\"collectorName\" : \"CMS\", \"timeStamp\" : { \"$numberLong\" : \"600\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"212864\" } }," + + "{\"collectorName\" : \"CMS\", \"timeStamp\": { \"$numberLong\" : \"500\"}," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"170887\"} }," + + "{\"collectorName\" : \"ABC\", \"timeStamp\" : { \"$numberLong\" : \"440\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"500\" } }," + + "{\"collectorName\" : \"ABC\", \"timeStamp\" : { \"$numberLong\" : \"660\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"2000\" } }," + + "{\"collectorName\" : \"ABC\", \"timeStamp\": { \"$numberLong\" : \"550\"}," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"1000\"}}]"; + + makeHttpMethodRequest(HttpMethod.POST, "", data, "application/json", "", 200); + + String expectedResponse = "{\"response\":[{\"collectorName\":\"ABC\",\"timeStamp\":660," + + "\"wallTimeInMicros\":2000" + SYSTEM_JVM_FRAGMENT + "," + + "\"wallTimeDelta\":{\"$numberLong\":1000}},{\"collectorName\":\"CMS\",\"timeStamp\":600," + + "\"wallTimeInMicros\":212864" + SYSTEM_JVM_FRAGMENT + "," + + "\"wallTimeDelta\":{\"$numberLong\":41977}},{\"collectorName\":\"ABC\",\"timeStamp\":550," + + "\"wallTimeInMicros\":1000" + SYSTEM_JVM_FRAGMENT + "," + + "\"wallTimeDelta\":{\"$numberLong\":500}}]}"; + ContentResponse response = client.newRequest(deltaJvmUrl).method(HttpMethod.GET).param("l", "10") + .param("a", "500").send(); + + verifyResponse(response, expectedResponse, 200); + } + + @Test + @Ignore + public void testGetDeltaWallTimeWithMultipleJvms() throws InterruptedException, ExecutionException, TimeoutException, UnsupportedEncodingException { + String data = "[{\"jvmId\" : \"jvm-X\",\"collectorName\" : \"CMS\", \"timeStamp\" : { \"$numberLong\" : \"400\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"14000\" } }," + + "{\"jvmId\" : \"jvm-X\",\"collectorName\" : \"CMS\", \"timeStamp\" : { \"$numberLong\" : \"600\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"212864\" } }," + + "{\"jvmId\" : \"jvm-X\",\"collectorName\" : \"CMS\", \"timeStamp\": { \"$numberLong\" : \"500\"}," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"170887\"} }," + + "{\"jvmId\" : \"jvm-Y\",\"collectorName\" : \"CMS\", \"timeStamp\" : { \"$numberLong\" : \"440\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"500\" } }," + + "{\"jvmId\" : \"jvm-Y\",\"collectorName\" : \"CMS\", \"timeStamp\" : { \"$numberLong\" : \"660\" }," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"2000\" } }," + + "{\"jvmId\" : \"jvm-Y\",\"collectorName\" : \"CMS\", \"timeStamp\": { \"$numberLong\" : \"550\"}," + + "\"wallTimeInMicros\": { \"$numberLong\" : \"1000\"}}]"; + + makeHttpMethodRequest(HttpMethod.POST, "", data, "application/json", "", 200); + + /* + {"response":[{"jvmId":"jvm-X","collectorName":"CMS","timeStamp":600, + "wallTimeInMicros":212864,"wallTimeDelta":{"$numberLong":41977}}, + {"jvmId":"jvm-X","collectorName":"CMS","timeStamp":500, + "wallTimeInMicros":170887,"wallTimeDelta":{"$numberLong":156887}}, + {"jvmId":"jvm-X","collectorName":"CMS","timeStamp":400, + "wallTimeInMicros":14000,"wallTimeDelta":{"$numberLong":0}}]} + */ + String expectedResponse = "{\"response\":[{\"jvmId\":\"jvm-X\",\"collectorName\":\"CMS\",\"timeStamp\":600," + + "\"wallTimeInMicros\":212864,\"wallTimeDelta\":{\"$numberLong\":41977}}," + + "{\"jvmId\":\"jvm-X\",\"collectorName\":\"CMS\",\"timeStamp\":500," + + "\"wallTimeInMicros\":170887,\"wallTimeDelta\":{\"$numberLong\":156887}}," + + "{\"jvmId\":\"jvm-X\",\"collectorName\":\"CMS\",\"timeStamp\":400," + + "\"wallTimeInMicros\":14000,\"wallTimeDelta\":{\"$numberLong\":0}}]}"; + ContentResponse response = client.newRequest(deltaUrl + "/jvm-X").method(HttpMethod.GET).param("l", "10").send(); + verifyResponse(response, expectedResponse, 200); + + /* + {"response":[{"jvmId":"jvm-Y","collectorName":"CMS","timeStamp":660, + "wallTimeInMicros":2000,"wallTimeDelta":{"$numberLong":1000}}, + {"jvmId":"jvm-Y","collectorName":"CMS","timeStamp":550, + "wallTimeInMicros":1000,"wallTimeDelta":{"$numberLong":500}}, + {"jvmId":"jvm-Y","collectorName":"CMS","timeStamp":440, + "wallTimeInMicros":500,"wallTimeDelta":{"$numberLong":0}}]} + */ + expectedResponse = "{\"response\":[{\"jvmId\":\"jvm-Y\",\"collectorName\":\"CMS\",\"timeStamp\":660," + + "\"wallTimeInMicros\":2000,\"wallTimeDelta\":{\"$numberLong\":1000}}," + + "{\"jvmId\":\"jvm-Y\",\"collectorName\":\"CMS\",\"timeStamp\":550," + + "\"wallTimeInMicros\":1000,\"wallTimeDelta\":{\"$numberLong\":500}}," + + "{\"jvmId\":\"jvm-Y\",\"collectorName\":\"CMS\",\"timeStamp\":440," + + "\"wallTimeInMicros\":500,\"wallTimeDelta\":{\"$numberLong\":0}}]}"; + response = client.newRequest(deltaUrl + "/jvm-Y").method(HttpMethod.GET).param("l", "10").send(); + + + verifyResponse(response, expectedResponse, 200); + } + + @Test public void testGetCannotSeeRealms() throws InterruptedException, ExecutionException, TimeoutException { String data = "[{\"item\":1},{\"item\":2}]"; makeHttpMethodRequest(HttpMethod.POST, NO_QUERY, data, "application/json", NO_EXPECTED_RESPONSE, 200);