Mercurial > hg > thermostat-ng > web-gateway
changeset 273:ec644f678e6e
Initial JCMD Plugin
review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-September/025195.html
reviewed-by: stooke
line wrap: on
line diff
--- 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<DBObject> collection, String body, Set<String> realms, String systemId, String jvmId) { MongoDataResultContainer metaDataContainer = new MongoDataResultContainer(); - if (body.length() > 0) { List<DBObject> inputList = (List<DBObject>) JSON.parse(body); @@ -214,4 +215,4 @@ private boolean isNullOrEmpty(final String s) { return s == null || s.isEmpty(); } -} \ No newline at end of file +}
--- 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 @@ </artifactItem> <artifactItem> <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-web-gateway-service-jcmd</artifactId> + <version>${project.version}</version> + <type>war</type> + <overWrite>false</overWrite> + </artifactItem> + <artifactItem> + <groupId>com.redhat.thermostat</groupId> <artifactId>thermostat-web-gateway-service-jvm-memory</artifactId> <version>${project.version}</version> <type>war</type> @@ -340,6 +347,13 @@ </dependency> <dependency> <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-web-gateway-service-jcmd</artifactId> + <version>${project.version}</version> + <type>war</type> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> <artifactId>thermostat-web-gateway-service-jvm-memory</artifactId> <version>${project.version}</version> <type>war</type>
--- 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 +
--- 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 @@ </modules> <properties> + <thermostat.common.version>0.1.0</thermostat.common.version> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.7</java.version>
--- /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 @@ +<!-- + + 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 + <http://www.gnu.org/licenses/>. + + 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <artifactId>thermostat-web-gateway-services</artifactId> + <groupId>com.redhat.thermostat</groupId> + <version>1.99.12-SNAPSHOT</version> + </parent> + + <artifactId>thermostat-web-gateway-service-jcmd</artifactId> + + <packaging>war</packaging> + + <name>Thermostat Web Gateway JCMD Service</name> + + <properties> + <com.redhat.thermostat.gateway.SERVICE_NAME>jcmd</com.redhat.thermostat.gateway.SERVICE_NAME> + </properties> + <build> + <plugins> + <plugin> + <artifactId>maven-war-plugin</artifactId> + <configuration> + <webResources> + <resource> + <directory>src/main/webapp</directory> + <filtering>true</filtering> + </resource> + </webResources> + </configuration> + </plugin> + </plugins> + </build> + + <dependencies> + <!-- Thermostat Web Gateway Dependencies --> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-web-gateway-common-mongodb</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-web-gateway-common-core</artifactId> + <version>${project.version}</version> + </dependency> + <!-- Servlet API deps --> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + <version>${javax.servlet.version}</version> + <scope>provided</scope> + </dependency> + + <!-- JAX-RS Dependencies --> + <dependency> + <groupId>javax.ws.rs</groupId> + <artifactId>javax.ws.rs-api</artifactId> + <version>${javax-rs-api.version}</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common</artifactId> + <version>${thermostat.common.version}</version> + </dependency> + + <!-- test scoped deps --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>${junit.version}</version> + <scope>test</scope> + </dependency> + + </dependencies> +</project>
--- /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 + * <http://www.gnu.org/licenses/>. + * + * 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<String> 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<String> 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; + } +}
--- /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 + * <http://www.gnu.org/licenses/>. + * + * 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<String, List<JCMDEntry>> jsonMapping = new HashMap<>(); + for (String key : model.data.keySet()) { + List<String> objectData = model.data.get(key); + int i = 0; + + List<JCMDEntry> 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<Object> { + + @Override + public void write(JsonWriter out, Object value) throws IOException { + Map<String, List<JCMDEntry>> jsonObject = (Map<String, List<JCMDEntry>>) 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"); + } + } +}
--- /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 + * <http://www.gnu.org/licenses/>. + * + * 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)); + } +}
--- /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 + * <http://www.gnu.org/licenses/>. + * + * 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<String> headers; + Map<String, List<String>> data; + String systemId; + String jvmId; + long timestamp; + + public Model() { + data = new HashMap<>(); + } +}
--- /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'"
--- /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 @@ +<!-- + + 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 + <http://www.gnu.org/licenses/>. + + 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. + +--> +<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee + http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" + version="3.1"> + <servlet> + <servlet-name>JCMDServlet</servlet-name> + <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> + <init-param> + <param-name> + jersey.config.server.provider.packages + </param-name> + <param-value> + com.redhat.thermostat.gateway.service.jvm.jcmd, + </param-value> + </init-param> + </servlet> + <filter> + <filter-name>ServiceVersionFilter</filter-name> + <filter-class>com.redhat.thermostat.gateway.common.core.servlet.ServiceVersionFilter</filter-class> + <init-param> + <param-name>version</param-name> + <param-value>0.0.3</param-value> + </init-param> + </filter> + <filter-mapping> + <filter-name>ServiceVersionFilter</filter-name> + <url-pattern>/*</url-pattern> + </filter-mapping> + <servlet-mapping> + <servlet-name>JCMDServlet</servlet-name> + <url-pattern>/0.0.3/*</url-pattern> + </servlet-mapping> + <!-- Service configuration --> + <context-param> + <param-name>com.redhat.thermostat.gateway.SERVICE_NAME</param-name> + <param-value>@com.redhat.thermostat.gateway.SERVICE_NAME@</param-value> + </context-param> + <!-- Listener for setting up the storage connection --> + <listener> + <listener-class>com.redhat.thermostat.gateway.common.mongodb.servlet.StorageConnectionSettingListener</listener-class> + </listener> + <!-- Allow viewing of API spec without authentication --> + <security-constraint> + <web-resource-collection> + <web-resource-name>Swagger API Spec File</web-resource-name> + <url-pattern>/0.0.1/doc/@com.redhat.thermostat.gateway.SERVICE_NAME@-swagger.yaml</url-pattern> + </web-resource-collection> + <!-- Explicitly no auth constraint for this file --> + </security-constraint> +</web-app>
--- /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 + * <http://www.gnu.org/licenses/>. + * + * 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<String> 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++)); + } +}
--- /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 + * <http://www.gnu.org/licenses/>. + * + * 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); + } +}