# HG changeset patch # User Mario Torre # Date 1507557442 -7200 # Node ID ec644f678e6ed765af7a5bddf27aa56430efca9c # Parent 353ace15de10df4904045fd510e4a065b3f62e1b Initial JCMD Plugin review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-September/025195.html reviewed-by: stooke diff -r 353ace15de10 -r ec644f678e6e common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/executor/MongoExecutor.java --- a/common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/executor/MongoExecutor.java Mon Oct 09 15:57:14 2017 +0200 +++ b/common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/executor/MongoExecutor.java Mon Oct 09 15:57:22 2017 +0200 @@ -46,6 +46,8 @@ import java.util.Collections; import java.util.List; import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; @@ -140,7 +142,6 @@ public MongoDataResultContainer execPostRequest(MongoCollection collection, String body, Set realms, String systemId, String jvmId) { MongoDataResultContainer metaDataContainer = new MongoDataResultContainer(); - if (body.length() > 0) { List inputList = (List) JSON.parse(body); @@ -214,4 +215,4 @@ private boolean isNullOrEmpty(final String s) { return s == null || s.isEmpty(); } -} \ No newline at end of file +} diff -r 353ace15de10 -r ec644f678e6e distribution/pom.xml --- a/distribution/pom.xml Mon Oct 09 15:57:14 2017 +0200 +++ b/distribution/pom.xml Mon Oct 09 15:57:22 2017 +0200 @@ -258,6 +258,13 @@ com.redhat.thermostat + thermostat-web-gateway-service-jcmd + ${project.version} + war + false + + + com.redhat.thermostat thermostat-web-gateway-service-jvm-memory ${project.version} war @@ -340,6 +347,13 @@ com.redhat.thermostat + thermostat-web-gateway-service-jcmd + ${project.version} + war + provided + + + com.redhat.thermostat thermostat-web-gateway-service-jvm-memory ${project.version} war diff -r 353ace15de10 -r ec644f678e6e distribution/src/etc/services.properties --- a/distribution/src/etc/services.properties Mon Oct 09 15:57:14 2017 +0200 +++ b/distribution/src/etc/services.properties Mon Oct 09 15:57:22 2017 +0200 @@ -1,5 +1,6 @@ /commands = thermostat-web-gateway-service-commands-@project.version@.war /jvm-byteman = thermostat-web-gateway-service-jvm-byteman-@project.version@.war +/jcmd = thermostat-web-gateway-service-jcmd-@project.version@.war /jvm-cpu = thermostat-web-gateway-service-jvm-cpu-@project.version@.war /jvm-compiler = thermostat-web-gateway-service-jvm-compiler-@project.version@.war /jvm-gc = thermostat-web-gateway-service-jvm-gc-@project.version@.war @@ -10,3 +11,4 @@ /system-cpu = thermostat-web-gateway-service-system-cpu-@project.version@.war /system-memory = thermostat-web-gateway-service-system-memory-@project.version@.war /system-network = thermostat-web-gateway-service-system-network-@project.version@.war + diff -r 353ace15de10 -r ec644f678e6e pom.xml --- a/pom.xml Mon Oct 09 15:57:14 2017 +0200 +++ b/pom.xml Mon Oct 09 15:57:22 2017 +0200 @@ -59,6 +59,8 @@ + 0.1.0 + UTF-8 UTF-8 1.7 diff -r 353ace15de10 -r ec644f678e6e services/jcmd/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jcmd/pom.xml Mon Oct 09 15:57:22 2017 +0200 @@ -0,0 +1,115 @@ + + + 4.0.0 + + + thermostat-web-gateway-services + com.redhat.thermostat + 1.99.12-SNAPSHOT + + + thermostat-web-gateway-service-jcmd + + war + + Thermostat Web Gateway JCMD Service + + + jcmd + + + + + maven-war-plugin + + + + src/main/webapp + true + + + + + + + + + + + com.redhat.thermostat + thermostat-web-gateway-common-mongodb + ${project.version} + + + com.redhat.thermostat + thermostat-web-gateway-common-core + ${project.version} + + + + javax.servlet + javax.servlet-api + ${javax.servlet.version} + provided + + + + + javax.ws.rs + javax.ws.rs-api + ${javax-rs-api.version} + provided + + + + com.redhat.thermostat + thermostat-common + ${thermostat.common.version} + + + + + junit + junit + ${junit.version} + test + + + + diff -r 353ace15de10 -r ec644f678e6e services/jcmd/src/main/java/com/redhat/thermostat/gateway/service/jvm/jcmd/JCMDModelConverter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jcmd/src/main/java/com/redhat/thermostat/gateway/service/jvm/jcmd/JCMDModelConverter.java Mon Oct 09 15:57:22 2017 +0200 @@ -0,0 +1,112 @@ +/* + * 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.jcmd; + +import com.google.gson.Gson; +import com.redhat.thermostat.lang.schema.models.Timestamp; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +class JCMDModelConverter { + + // TODO: we need to export this model from the agent somehow, models + // this is basically a copy of + // com.redhat.thermostat.jcmd.backend.internal.model.GCStatsModel + private static class RawModel { + private Timestamp timestamp; + private String payload; + } + + public static Model createModel(String json, String systemId, String jvmId) { + + Model model = new Model(); + model.jvmId = jvmId; + model.systemId = systemId; + + RawModel rawModel = new Gson().fromJson(json, RawModel.class); + model.timestamp = rawModel.timestamp.get(); + + BufferedReader reader = new BufferedReader(new StringReader(rawModel.payload)); + try { + List headers = new ArrayList<>(Arrays.asList(reader.readLine().split("\\s+|,"))); + headers.add("systemId"); + headers.add("jvmId"); + + model.headers = headers; + + String line = null; + while ((line = reader.readLine()) != null) { + if (line.endsWith("Total") || line.startsWith(headers.get(0)) || + line.contains("%")) + { + // we reached end, the last line is the same as the first + // one, the last two lines are some simple + // stats we can infer from the other numbers + break; + } + // we need to take care for the last block, since it may contain + // a legitimate whitespace + // note: we depend on the fact that the last block is *always* + // ClassName,ClassLoader, while this should not change across + // releases, if it does we need a smarter parsing code + // it may be worth to revisit this code anyway to make it + // less dependent on the input + String[] blocks = line.trim().split(","); + String classLoaderField = blocks[1]; + List classData = new ArrayList<>(Arrays.asList(blocks[0].split("\\s+"))); + String className = classData.get(classData.size() - 1); + + classData.add(classLoaderField); + + classData.add(systemId); + classData.add(jvmId); + + model.data.put(className, classData); + } + + } catch (IOException ignored) { + ignored.printStackTrace(); + } + + return model; + } +} diff -r 353ace15de10 -r ec644f678e6e services/jcmd/src/main/java/com/redhat/thermostat/gateway/service/jvm/jcmd/JSONConverter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jcmd/src/main/java/com/redhat/thermostat/gateway/service/jvm/jcmd/JSONConverter.java Mon Oct 09 15:57:22 2017 +0200 @@ -0,0 +1,135 @@ +/* + * 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.jcmd; + +import com.google.gson.GsonBuilder; +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class JSONConverter { + + class JCMDEntry { + long timestamp; + String key; + String value; + } + + private GsonBuilder builder; + JSONConverter() { + builder = new GsonBuilder(); + // leave commented out for debugging + //builder.setPrettyPrinting(); + builder.registerTypeAdapter(HashMap.class, new ModelAdapter()); + } + + public String convert(Model model) { + Map> jsonMapping = new HashMap<>(); + for (String key : model.data.keySet()) { + List objectData = model.data.get(key); + int i = 0; + + List entries = new ArrayList<>(); + for (String fieldEntry : objectData) { + JCMDEntry jcmdEntry = new JCMDEntry(); + jcmdEntry.key = model.headers.get(i++); + jcmdEntry.value = fieldEntry; + + jcmdEntry.timestamp = model.timestamp; + + entries.add(jcmdEntry); + } + jsonMapping.put(key, entries); + } + + return builder.create().toJson(jsonMapping); + } + + private class ModelAdapter extends TypeAdapter { + + @Override + public void write(JsonWriter out, Object value) throws IOException { + Map> jsonObject = (Map>) value; + + out.beginArray(); + + for (String name : jsonObject.keySet()) { + out.beginObject(); + + for (JCMDEntry property : jsonObject.get(name)) { + + out.name(property.key); + + if (property.value.matches("-?\\d+(\\.\\d+)?")) { + out.beginObject(); + out.name("$numberLong"); + out.value(property.value); + out.endObject(); + } else { + out.value(property.value); + } + } + + // the timestamp is not part of the properties so we add + // manually here + { + out.name("timeStamp"); + out.beginObject(); + out.name("$numberLong"); + out.value("" + jsonObject.get(name).get(0).timestamp); + out.endObject(); + } + // end: timeStamp + + out.endObject(); + } + + out.endArray(); + } + + @Override + public Object read(JsonReader in) throws IOException { + throw new UnsupportedOperationException("read() not yet implemented"); + } + } +} diff -r 353ace15de10 -r ec644f678e6e services/jcmd/src/main/java/com/redhat/thermostat/gateway/service/jvm/jcmd/JcmdHttpHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jcmd/src/main/java/com/redhat/thermostat/gateway/service/jvm/jcmd/JcmdHttpHandler.java Mon Oct 09 15:57:22 2017 +0200 @@ -0,0 +1,97 @@ +/* + * 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.jcmd; + +import com.redhat.thermostat.gateway.common.core.servlet.CommonQueryParams; +import com.redhat.thermostat.gateway.common.core.servlet.RequestParameters; +import com.redhat.thermostat.gateway.common.mongodb.servlet.MongoHttpHandlerHelper; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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; + +@Path("/") +public class JcmdHttpHandler { + private static final String COLLECTION_NAME = "jcmd"; + private final MongoHttpHandlerHelper metricsServiceHelper = new MongoHttpHandlerHelper(COLLECTION_NAME); + + @POST + @Path("/systems/{" + RequestParameters.SYSTEM_ID +"}/jvms/{" + RequestParameters.JVM_ID +"}") + @Consumes({ "application/json" }) + @Produces({ "application/json", "text/html; charset=utf-8" }) + public Response postJCMDData(String body, + @PathParam(RequestParameters.SYSTEM_ID) String systemId, + @PathParam(RequestParameters.JVM_ID) String jvmId, + @Context ServletContext context, + @Context HttpServletRequest httpServletRequest) + { + //Logger.getLogger(JcmdHttpHandler.class.getName()).log(Level.WARNING, "jvmid: " + jvmId + ", body: " + body); + Model model = JCMDModelConverter.createModel(body, systemId, jvmId); + String json = new JSONConverter().convert(model); + + return metricsServiceHelper.handlePostWithJvmID(httpServletRequest, context, systemId, jvmId, false, json); + } + + @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") Boolean metadata, + @Context HttpServletRequest httpServletRequest, + @Context ServletContext context) + { + return metricsServiceHelper.handleGetWithJvmID(httpServletRequest, context, systemId, jvmId, + new CommonQueryParams(limit, offset, sort, queries, includes, excludes, metadata)); + } +} diff -r 353ace15de10 -r ec644f678e6e services/jcmd/src/main/java/com/redhat/thermostat/gateway/service/jvm/jcmd/Model.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jcmd/src/main/java/com/redhat/thermostat/gateway/service/jvm/jcmd/Model.java Mon Oct 09 15:57:22 2017 +0200 @@ -0,0 +1,53 @@ +/* + * 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.jcmd; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +class Model { + List headers; + Map> data; + String systemId; + String jvmId; + long timestamp; + + public Model() { + data = new HashMap<>(); + } +} diff -r 353ace15de10 -r ec644f678e6e services/jcmd/src/main/resources/jcmd-swagger.yaml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jcmd/src/main/resources/jcmd-swagger.yaml Mon Oct 09 15:57:22 2017 +0200 @@ -0,0 +1,108 @@ +swagger: '2.0' +info: + version: 0.0.1 + title: Thermostat Web Gateway JCMD API + license: + name: GPL v2 with Classpath Exception + url: 'http://www.gnu.org/licenses' +consumes: + - application/json +produces: + - application/json +basePath: /jcmd/0.0.1 +paths: + /systems/{systemId}/jvms/{jvmId}: + parameters: + - $ref: '#/parameters/thermostat-realms' + - $ref: '#/parameters/system-id' + - $ref: '#/parameters/jvm-id' + get: + description: Get JCMD information for {jvmId} + responses: + '200': + description: OK + schema: + $ref: '#/definitions/jvm-jcmd-get-response' + post: + description: Add JCMD information for {jvmId} + parameters: + - $ref: '#/parameters/jvm-jcmd-info' + - $ref: '#/parameters/metadata' + responses: + '200': + description: OK + schema: + $ref: '#/definitions/metadata' +definitions: + jvm-jcmd-get-response: + type: object + properties: + response: + $ref: '#/definitions/jvm-jcmd-info' + metadata: + $ref: '#/definitions/metadata' + jvm-jcmd-info: + type: object + properties: + jvmId: + type: string + timeStamp: + $ref: '#/definitions/timestamp' + payload: + type: string + metadata: + type: object + properties: + payloadCount: + type: integer + count: + type: integer + prev: + type: string + next: + type: string + first: + type: string + last: + type: string + insertCount: + type: integer + matchCount: + type: integer + elapsed: + type: integer + format: int64 + timestamp: + description: UNIX timestamp in milliseconds + type: object + properties: + $numberLong: + type: string +parameters: + system-id: + name: systemId + in: path + required: true + type: string + jvm-id: + name: jvmId + in: path + required: true + type: string + jvm-jcmd-info: + name: jvm-jcmd-info + in: body + description: The JVM JCMD information + required: true + schema: + $ref: '#/definitions/jvm-jcmd-info' + metadata: + 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." + 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'" diff -r 353ace15de10 -r ec644f678e6e services/jcmd/src/main/webapp/WEB-INF/web.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jcmd/src/main/webapp/WEB-INF/web.xml Mon Oct 09 15:57:22 2017 +0200 @@ -0,0 +1,88 @@ + + + + JCMDServlet + org.glassfish.jersey.servlet.ServletContainer + + + jersey.config.server.provider.packages + + + com.redhat.thermostat.gateway.service.jvm.jcmd, + + + + + ServiceVersionFilter + com.redhat.thermostat.gateway.common.core.servlet.ServiceVersionFilter + + version + 0.0.3 + + + + ServiceVersionFilter + /* + + + JCMDServlet + /0.0.3/* + + + + com.redhat.thermostat.gateway.SERVICE_NAME + @com.redhat.thermostat.gateway.SERVICE_NAME@ + + + + com.redhat.thermostat.gateway.common.mongodb.servlet.StorageConnectionSettingListener + + + + + Swagger API Spec File + /0.0.1/doc/@com.redhat.thermostat.gateway.SERVICE_NAME@-swagger.yaml + + + + diff -r 353ace15de10 -r ec644f678e6e services/jcmd/src/test/java/com/redhat/thermostat/gateway/service/jvm/jcmd/JCMDModelConverterTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jcmd/src/test/java/com/redhat/thermostat/gateway/service/jvm/jcmd/JCMDModelConverterTest.java Mon Oct 09 15:57:22 2017 +0200 @@ -0,0 +1,115 @@ +/* + * 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.jcmd; + +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class JCMDModelConverterTest { + + private static String RAW_PAYLOAD = + "{\"timestamp\":{\"timestamp\":\"1505992968442\"}," + + "\"payload\":\"Index Super InstCount InstBytes KlassBytes " + + "annotations CpAll MethodCount Bytecodes MethodAll ROAll " + + "RWAll Total ClassName,ClassLoader\\n 1 -1 6126 " + + "398176 464 0 0 0 " + + "0 0 24 568 592 [C,NULL class_loader\\n " + + "2 48 1614 182816 632 0 " + + "20824 130 4973 37080 20768 39544 " + + "60312 java.lang.Class,NULL class_loader\\n 3 -1 " + + "471 154720 464 0 0 " + + "0 0 0 24 568 592 " + + "[B,NULL class_loader\\n" + + "Index Super InstCount InstBytes KlassBytes annotations " + + "CpAll MethodCount Bytecodes MethodAll ROAll RWAll " + + "Total ClassName,ClassLoader\\n\"}"; + + @Test + public void testModelCreation() { + + Model model = JCMDModelConverter.createModel(RAW_PAYLOAD, "0x4A", "42"); + assertTrue(model != null); + assertEquals(3, model.data.size()); + + assertTrue(model.data.containsKey("[C")); + assertTrue(model.data.containsKey("[B")); + assertTrue(model.data.containsKey("java.lang.Class")); + + int i = 0; + assertEquals("Index", model.headers.get(i++)); + assertEquals("Super", model.headers.get(i++)); + assertEquals("InstCount", model.headers.get(i++)); + assertEquals("InstBytes", model.headers.get(i++)); + assertEquals("KlassBytes", model.headers.get(i++)); + assertEquals("annotations", model.headers.get(i++)); + assertEquals("CpAll", model.headers.get(i++)); + assertEquals("MethodCount", model.headers.get(i++)); + assertEquals("Bytecodes", model.headers.get(i++)); + assertEquals("MethodAll", model.headers.get(i++)); + assertEquals("ROAll", model.headers.get(i++)); + assertEquals("RWAll", model.headers.get(i++)); + assertEquals("Total", model.headers.get(i++)); + assertEquals("ClassName", model.headers.get(i++)); + assertEquals("ClassLoader", model.headers.get(i++)); + assertEquals("systemId", model.headers.get(i++)); + assertEquals("jvmId", model.headers.get(i++)); + + i = 0; + List data = model.data.get("[C"); + assertEquals("1", data.get(i++)); + assertEquals("-1", data.get(i++)); + assertEquals("6126", data.get(i++)); + assertEquals("398176", data.get(i++)); + assertEquals("464", data.get(i++)); + assertEquals("0", data.get(i++)); + assertEquals("0", data.get(i++)); + assertEquals("0", data.get(i++)); + assertEquals("0", data.get(i++)); + assertEquals("0", data.get(i++)); + assertEquals("24", data.get(i++)); + assertEquals("568", data.get(i++)); + assertEquals("592", data.get(i++)); + assertEquals("[C", data.get(i++)); + assertEquals("NULL class_loader", data.get(i++)); + assertEquals("0x4A", data.get(i++)); + assertEquals("42", data.get(i++)); + } +} diff -r 353ace15de10 -r ec644f678e6e services/jcmd/src/test/java/com/redhat/thermostat/gateway/service/jvm/jcmd/JSONConverterTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jcmd/src/test/java/com/redhat/thermostat/gateway/service/jvm/jcmd/JSONConverterTest.java Mon Oct 09 15:57:22 2017 +0200 @@ -0,0 +1,71 @@ +/* + * 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.jcmd; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class JSONConverterTest { + private static String RAW_PAYLOAD = + "{\"timestamp\":{\"timestamp\":\"1505992968442\"}," + + "\"payload\":\"Index Super InstCount InstBytes KlassBytes " + + "annotations CpAll MethodCount Bytecodes MethodAll ROAll " + + "RWAll Total ClassName,ClassLoader\\n 1 -1 6126 " + + "398176 464 0 0 0 " + + "0 0 24 568 592 [C,NULL class_loader\\n " + + "2 48 1614 182816 632 0 " + + "20824 130 4973 37080 20768 39544 " + + "60312 java.lang.Class,NULL class_loader\\n 3 -1 " + + "471 154720 464 0 0 " + + "0 0 0 24 568 592 " + + "[B,NULL class_loader\\n" + + "Index Super InstCount InstBytes KlassBytes annotations " + + "CpAll MethodCount Bytecodes MethodAll ROAll RWAll " + + "Total ClassName,ClassLoader\\n\"}"; + + private static final String EXPECTED = "[{\"Index\":{\"$numberLong\":\"3\"},\"Super\":{\"$numberLong\":\"-1\"},\"InstCount\":{\"$numberLong\":\"471\"},\"InstBytes\":{\"$numberLong\":\"154720\"},\"KlassBytes\":{\"$numberLong\":\"464\"},\"annotations\":{\"$numberLong\":\"0\"},\"CpAll\":{\"$numberLong\":\"0\"},\"MethodCount\":{\"$numberLong\":\"0\"},\"Bytecodes\":{\"$numberLong\":\"0\"},\"MethodAll\":{\"$numberLong\":\"0\"},\"ROAll\":{\"$numberLong\":\"24\"},\"RWAll\":{\"$numberLong\":\"568\"},\"Total\":{\"$numberLong\":\"592\"},\"ClassName\":\"[B\",\"ClassLoader\":\"NULL class_loader\",\"systemId\":\"0x4A\",\"jvmId\":{\"$numberLong\":\"42\"},\"timeStamp\":{\"$numberLong\":\"1505992968442\"}},{\"Index\":{\"$numberLong\":\"1\"},\"Super\":{\"$numberLong\":\"-1\"},\"InstCount\":{\"$numberLong\":\"6126\"},\"InstBytes\":{\"$numberLong\":\"398176\"},\"KlassBytes\":{\"$numberLong\":\"464\"},\"annotations\":{\"$numberLong\":\"0\"},\"CpAll\":{\"$numberLong\":\"0\"},\"MethodCount\":{\"$numberLong\":\"0\"},\"Bytecodes\":{\"$numberLong\":\"0\"},\"MethodAll\":{\"$numberLong\":\"0\"},\"ROAll\":{\"$numberLong\":\"24\"},\"RWAll\":{\"$numberLong\":\"568\"},\"Total\":{\"$numberLong\":\"592\"},\"ClassName\":\"[C\",\"ClassLoader\":\"NULL class_loader\",\"systemId\":\"0x4A\",\"jvmId\":{\"$numberLong\":\"42\"},\"timeStamp\":{\"$numberLong\":\"1505992968442\"}},{\"Index\":{\"$numberLong\":\"2\"},\"Super\":{\"$numberLong\":\"48\"},\"InstCount\":{\"$numberLong\":\"1614\"},\"InstBytes\":{\"$numberLong\":\"182816\"},\"KlassBytes\":{\"$numberLong\":\"632\"},\"annotations\":{\"$numberLong\":\"0\"},\"CpAll\":{\"$numberLong\":\"20824\"},\"MethodCount\":{\"$numberLong\":\"130\"},\"Bytecodes\":{\"$numberLong\":\"4973\"},\"MethodAll\":{\"$numberLong\":\"37080\"},\"ROAll\":{\"$numberLong\":\"20768\"},\"RWAll\":{\"$numberLong\":\"39544\"},\"Total\":{\"$numberLong\":\"60312\"},\"ClassName\":\"java.lang.Class\",\"ClassLoader\":\"NULL class_loader\",\"systemId\":\"0x4A\",\"jvmId\":{\"$numberLong\":\"42\"},\"timeStamp\":{\"$numberLong\":\"1505992968442\"}}]"; + + private static Model MODEL = JCMDModelConverter.createModel(RAW_PAYLOAD, "0x4A", "42"); + + @Test + public void add() throws Exception { + JSONConverter handler = new JSONConverter(); + String json = handler.convert(MODEL); + assertEquals(EXPECTED, json); + } +} diff -r 353ace15de10 -r ec644f678e6e services/pom.xml --- a/services/pom.xml Mon Oct 09 15:57:14 2017 +0200 +++ b/services/pom.xml Mon Oct 09 15:57:22 2017 +0200 @@ -53,6 +53,7 @@ commands jvms + jcmd jvm-byteman jvm-cpu jvm-gc