Mercurial > hg > thermostat-ng > web-gateway
changeset 161:16c078be30b4
Add jvm information service
PR3375
Reviewed-by: jerboaa
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-May/023328.html
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-May/023295.html
line wrap: on
line diff
--- a/common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/executor/MongoExecutor.java Fri May 19 16:03:47 2017 +0200 +++ b/common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/executor/MongoExecutor.java Tue May 30 09:16:06 2017 -0400 @@ -70,9 +70,8 @@ documents = collection.find(); } - List<String> projectionsList; if (projections != null) { - projectionsList = Arrays.asList(projections.split(",")); + List<String> projectionsList = Arrays.asList(projections.split(",")); documents = documents.projection(fields(include(projectionsList), excludeId())); } else { documents = documents.projection(excludeId()); @@ -84,7 +83,6 @@ return mongoResponseBuilder.buildGetResponseString(documents); } - public void buildPutResponse(MongoCollection<Document> collection, String body, String queries) { BasicDBObject inputObject = (BasicDBObject) JSON.parse(body);
--- a/distribution/pom.xml Fri May 19 16:03:47 2017 +0200 +++ b/distribution/pom.xml Tue May 30 09:16:06 2017 -0400 @@ -51,43 +51,43 @@ <packaging>pom</packaging> - <profiles> - - <profile> - <id>windows</id> - <activation> - <os><family>Windows</family></os> - </activation> - <build> - <plugins> - <plugin> - <artifactId>maven-resources-plugin</artifactId> - <executions> - <execution> - <id>copy-windows-scripts</id> - <phase>prepare-package</phase> - <goals> - <goal>copy-resources</goal> - </goals> - <configuration> - <outputDirectory>${project.build.directory}</outputDirectory> - <resources> - <resource> - <directory>src/windows/bin</directory> - <targetPath>image/bin</targetPath> - <filtering>true</filtering> - </resource> - </resources> - </configuration> - </execution> - </executions> - </plugin> - </plugins> - </build> - </profile> + <profiles> - </profiles> - + <profile> + <id>windows</id> + <activation> + <os><family>Windows</family></os> + </activation> + <build> + <plugins> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-windows-scripts</id> + <phase>prepare-package</phase> + <goals> + <goal>copy-resources</goal> + </goals> + <configuration> + <outputDirectory>${project.build.directory}</outputDirectory> + <resources> + <resource> + <directory>src/windows/bin</directory> + <targetPath>image/bin</targetPath> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + + </profiles> + <build> <plugins> <plugin> @@ -192,14 +192,21 @@ </artifactItem> <artifactItem> <groupId>com.redhat.thermostat</groupId> - <artifactId>thermostat-web-gateway-service-jvm-memory</artifactId> + <artifactId>thermostat-web-gateway-service-jvm-gc</artifactId> <version>${project.version}</version> <type>war</type> <overWrite>false</overWrite> </artifactItem> <artifactItem> <groupId>com.redhat.thermostat</groupId> - <artifactId>thermostat-web-gateway-service-jvm-gc</artifactId> + <artifactId>thermostat-web-gateway-service-jvms</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> <overWrite>false</overWrite> @@ -232,6 +239,13 @@ </dependency> <dependency> <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-web-gateway-service-jvms</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>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/distribution/src/etc/jvms/service-config.properties Tue May 30 09:16:06 2017 -0400 @@ -0,0 +1,4 @@ +MONGO_URL=mongodb://127.0.0.1:27518 +MONGO_DB=thermostat +MONGO_USERNAME=mongodevuser +MONGO_PASSWORD=mongodevpassword \ No newline at end of file
--- a/distribution/src/etc/services.properties Fri May 19 16:03:47 2017 +0200 +++ b/distribution/src/etc/services.properties Tue May 30 09:16:06 2017 -0400 @@ -1,4 +1,5 @@ -/jvm-memory = thermostat-web-gateway-service-jvm-memory-@project.version@.war +/commands = thermostat-web-gateway-service-commands-@project.version@.war /jvm-gc = thermostat-web-gateway-service-jvm-gc-@project.version@.war -/commands = thermostat-web-gateway-service-commands-@project.version@.war +/jvm-memory = thermostat-web-gateway-service-jvm-memory-@project.version@.war +/jvms = thermostat-web-gateway-service-jvms-@project.version@.war /white-pages = thermostat-web-gateway-service-white-pages-@project.version@.war
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jvms/pom.xml Tue May 30 09:16:06 2017 -0400 @@ -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. + +--> +<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-jvms</artifactId> + + <packaging>war</packaging> + + <name>Thermostat Web Gateway JVMs Service</name> + + <properties> + <com.redhat.thermostat.gateway.SERVICE_NAME>jvms</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> + + <!-- Servlet API Dependencies--> + <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> + </dependencies> +</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jvms/src/main/java/com/redhat/thermostat/service/jvms/http/JvmsHttpHandler.java Tue May 30 09:16:06 2017 -0400 @@ -0,0 +1,218 @@ +/* + * 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.service.jvms.http; + +import javax.servlet.ServletContext; +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.mongodb.DBObject; +import com.redhat.thermostat.gateway.common.mongodb.ThermostatMongoStorage; +import com.redhat.thermostat.gateway.common.mongodb.servlet.ServletContextConstants; +import com.redhat.thermostat.service.jvms.mongo.MongoStorageHandler; + +@Path("/") +public class JvmsHttpHandler { + private final MongoStorageHandler mongoStorageHandler = new MongoStorageHandler(); + private final String collectionName = "jvm-info"; + + @GET + @Path("/systems/{" + Parameters.SYSTEM_ID +"}") + @Consumes({ "application/json" }) + @Produces({ "application/json", "text/html; charset=utf-8" }) + public Response getJvmInfos(@PathParam(Parameters.SYSTEM_ID) String systemId, + @QueryParam(Parameters.LIMIT) @DefaultValue("1") Integer limit, + @QueryParam(Parameters.OFFSET) @DefaultValue("0") Integer offset, + @QueryParam(Parameters.SORT) String sort, + @QueryParam(Parameters.QUERY) String queries, + @QueryParam(Parameters.INCLUDE) String includes, + @QueryParam(Parameters.EXCLUDE) String excludes, + @Context ServletContext context + ) { + try { + ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE); + + String message = mongoStorageHandler.getJvmInfos(storage.getDatabase().getCollection(collectionName), systemId, limit, offset, sort, queries, includes, excludes); + + return Response.status(Response.Status.OK).entity(message).build(); + } catch (Exception e) { + return Response.status(Response.Status.BAD_REQUEST).build(); + } + } + + @POST + @Path("/systems/{" + Parameters.SYSTEM_ID +"}") + @Consumes({ "application/json" }) + @Produces({ "application/json", "text/html; charset=utf-8" }) + public Response postJvmInfos(String body, + @PathParam(Parameters.SYSTEM_ID) String systemId, + @Context ServletContext context) { + try { + ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE); + + mongoStorageHandler.addJvmInfos(storage.getDatabase().getCollection(collectionName, DBObject.class), body, systemId); + return Response.status(Response.Status.OK).build(); + } catch (Exception e) { + return Response.status(Response.Status.BAD_REQUEST).build(); + } + } + + @DELETE + @Path("/systems/{" + Parameters.SYSTEM_ID +"}") + @Consumes({ "application/json" }) + @Produces({ "application/json", "text/html; charset=utf-8" }) + public Response deleteJvmInfos(@PathParam(Parameters.SYSTEM_ID) String systemId, + @Context ServletContext context) { + try { + ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE); + + mongoStorageHandler.deleteJvmInfos(storage.getDatabase().getCollection(collectionName), systemId); + + return Response.status(Response.Status.OK).build(); + } catch (Exception e) { + return Response.status(Response.Status.BAD_REQUEST).build(); + } + } + + @GET + @Path("/systems/{" + Parameters.SYSTEM_ID +"}/jvms/{" + Parameters.JVM_ID +"}") + @Consumes({ "application/json" }) + @Produces({ "application/json", "text/html; charset=utf-8" }) + public Response getJvmInfo(@PathParam(Parameters.SYSTEM_ID) String systemId, + @PathParam(Parameters.JVM_ID) String jvmId, + @QueryParam(Parameters.INCLUDE) String includes, + @QueryParam(Parameters.EXCLUDE) String excludes, + @Context ServletContext context + ) { + try { + ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE); + + String message = mongoStorageHandler.getJvmInfo(storage.getDatabase().getCollection(collectionName), systemId, jvmId, includes, excludes); + + return Response.status(Response.Status.OK).entity(message).build(); + } catch (Exception e) { + return Response.status(Response.Status.BAD_REQUEST).build(); + } + } + @PUT + @Path("/systems/{" + Parameters.SYSTEM_ID +"}/jvms/{" + Parameters.JVM_ID +"}") + @Consumes({ "application/json" }) + @Produces({ "application/json", "text/html; charset=utf-8" }) + public Response putJvmInfo(String body, + @PathParam(Parameters.SYSTEM_ID) String systemId, + @PathParam(Parameters.JVM_ID) String jvmId, + @QueryParam(Parameters.QUERY) String queries, + @Context ServletContext context) { + try { + ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE); + + mongoStorageHandler.updateJvmInfo(storage.getDatabase().getCollection(collectionName), body, systemId, jvmId, queries); + + return Response.status(Response.Status.OK).build(); + } catch (Exception e) { + return Response.status(Response.Status.BAD_REQUEST).build(); + } + } + + @DELETE + @Path("/systems/{" + Parameters.SYSTEM_ID +"}/jvms/{" + Parameters.JVM_ID +"}") + @Consumes({ "application/json" }) + @Produces({ "application/json", "text/html; charset=utf-8" }) + public Response deleteJvmInfo(@PathParam(Parameters.SYSTEM_ID) String systemId, + @PathParam(Parameters.JVM_ID) String jvmId, + @Context ServletContext context) { + try { + ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE); + + mongoStorageHandler.deleteJvmInfo(storage.getDatabase().getCollection(collectionName), systemId, jvmId); + + return Response.status(Response.Status.OK).build(); + } catch (Exception e) { + return Response.status(Response.Status.BAD_REQUEST).build(); + } + } + + @PUT + @Path("/update/systems/{" + Parameters.SYSTEM_ID + "}/ts/{" + Parameters.TIMESTAMP +"}") + public Response putUpdateTimestamp(String body, + @PathParam(Parameters.SYSTEM_ID) String systemId, + @PathParam(Parameters.TIMESTAMP) Long timeStamp, + @Context ServletContext context) { + try { + ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE); + + mongoStorageHandler.updateTimestamps(storage.getDatabase().getCollection(collectionName), body, systemId, timeStamp); + + return Response.status(Response.Status.OK).build(); + } catch (Exception e) { + e.printStackTrace(); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + } + + @GET + @Path("/tree") + @Consumes({ "application/json" }) + @Produces({ "application/json", "text/html; charset=utf-8" }) + public Response getJvmInfoTree(@QueryParam(Parameters.LIMIT) @DefaultValue("1") Integer limit, + @QueryParam(Parameters.OFFSET) @DefaultValue("0") Integer offset, + @QueryParam(Parameters.ALIVE_ONLY) @DefaultValue("true") Boolean aliveOnly, + @QueryParam(Parameters.INCLUDE) String includes, + @QueryParam(Parameters.EXCLUDE) String excludes, + @Context ServletContext context) { + try { + ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE); + + String message = mongoStorageHandler.getJvmsTree(storage.getDatabase().getCollection(collectionName), aliveOnly, excludes, includes, limit, offset); + + return Response.status(Response.Status.OK).entity(message).build(); + } catch (Exception e) { + e.printStackTrace(); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jvms/src/main/java/com/redhat/thermostat/service/jvms/http/Parameters.java Tue May 30 09:16:06 2017 -0400 @@ -0,0 +1,52 @@ +/* + * 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.service.jvms.http; + +class Parameters { + static final String SYSTEM_ID = "systemId"; + static final String JVM_ID = "jvmId"; + + static final String SORT = "sort"; + static final String QUERY = "query"; + static final String OFFSET = "offset"; + static final String LIMIT = "limit"; + static final String INCLUDE = "include"; + static final String EXCLUDE = "exclude"; + + static final String TIMESTAMP = "timeStamp"; + static final String ALIVE_ONLY = "aliveOnly"; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jvms/src/main/java/com/redhat/thermostat/service/jvms/http/SwaggerSpecResourceHandler.java Tue May 30 09:16:06 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 + * <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.service.jvms.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); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jvms/src/main/java/com/redhat/thermostat/service/jvms/mongo/Fields.java Tue May 30 09:16:06 2017 -0400 @@ -0,0 +1,49 @@ +/* + * 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.service.jvms.mongo; + +class Fields { + static final String SYSTEM_ID = "systemId"; + static final String JVM_ID = "jvmId"; + + static final String SET = "set"; + static final String LAST_UPDATED = "lastUpdated"; + static final String STOP_TIME = "stopTime"; + + static final String RESPONSE = "response"; + static final String JVMS = "jvms"; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jvms/src/main/java/com/redhat/thermostat/service/jvms/mongo/MongoStorageHandler.java Tue May 30 09:16:06 2017 -0400 @@ -0,0 +1,244 @@ +/* + * 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.service.jvms.mongo; + +import static com.mongodb.client.model.Filters.and; +import static com.mongodb.client.model.Filters.eq; +import static com.mongodb.client.model.Filters.lt; +import static com.mongodb.client.model.Filters.or; +import static com.mongodb.client.model.Projections.exclude; +import static com.mongodb.client.model.Projections.excludeId; +import static com.mongodb.client.model.Projections.fields; +import static com.mongodb.client.model.Projections.include; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.bson.Document; +import org.bson.conversions.Bson; + +import com.mongodb.BasicDBObject; +import com.mongodb.Block; +import com.mongodb.CursorType; +import com.mongodb.DBObject; +import com.mongodb.client.FindIterable; +import com.mongodb.client.MongoCollection; +import com.mongodb.util.JSON; +import com.redhat.thermostat.gateway.common.mongodb.filters.MongoRequestFilters; +import com.redhat.thermostat.gateway.common.mongodb.filters.MongoSortFilters; +import com.redhat.thermostat.gateway.common.mongodb.response.MongoResponseBuilder; + +public class MongoStorageHandler { + + private final MongoResponseBuilder mongoResponseBuilder = new MongoResponseBuilder(); + + public String getJvmInfos(MongoCollection<Document> collection, String systemId, Integer limit, Integer offset, String sort, String queries, String includes, String excludes) { + Bson baseQuery = eq(Fields.SYSTEM_ID, systemId); + FindIterable<Document> documents; + if (queries != null) { + List<String> queriesList = Arrays.asList(queries.split(",")); + final Bson query = MongoRequestFilters.buildQueriesFilter(queriesList); + documents = collection.find(and(baseQuery, query)); + } else { + documents = collection.find(baseQuery); + } + + documents = buildProjection(documents, includes, excludes); + + final Bson sortObject = MongoSortFilters.createSortObject(sort); + documents = documents.sort(sortObject).limit(limit).skip(offset).batchSize(limit).cursorType(CursorType.NonTailable); + + return mongoResponseBuilder.buildGetResponseString(documents); + } + + public String getJvmInfo(MongoCollection<Document> collection, String systemId, String jvmId, String includes, String excludes) { + Bson query = and(eq(Fields.JVM_ID, jvmId), eq(Fields.SYSTEM_ID, systemId)); + FindIterable<Document> documents = collection.find(query); + + documents = buildProjection(documents, includes, excludes); + + documents = documents.limit(1).skip(0).batchSize(1).cursorType(CursorType.NonTailable); + + return mongoResponseBuilder.buildGetResponseString(documents); + } + + private FindIterable<Document> buildProjection(FindIterable<Document> documents, String includes, String excludes) { + if (excludes != null) { + List<String> excludesList = Arrays.asList(excludes.split(",")); + documents = documents.projection(fields(exclude(excludesList), excludeId())); + } else if (includes != null) { + List<String> includesList = Arrays.asList(includes.split(",")); + documents = documents.projection(fields(include(includesList), excludeId())); + } else { + documents = documents.projection(excludeId()); + } + + return documents; + } + + public void addJvmInfos(MongoCollection<DBObject> collection, String body, String systemId) { + if (body.length() > 0) { + List<DBObject> inputList = (List<DBObject>) JSON.parse(body); + for (DBObject o : inputList) { + o.put(Fields.SYSTEM_ID, systemId); + } + collection.insertMany(inputList); + } + } + + public void deleteJvmInfos(MongoCollection<Document> collection, String systemId) { + Bson query = eq(Fields.SYSTEM_ID, systemId); + deleteDocuments(collection, query); + } + public void deleteJvmInfo(MongoCollection<Document> collection, String systemId, String jvmId) { + Bson query = and(eq(Fields.JVM_ID, jvmId), eq(Fields.SYSTEM_ID, systemId)); + deleteDocuments(collection, query); + } + + private void deleteDocuments(MongoCollection<Document> collection, Bson query) { + collection.deleteMany(query); + } + + public void updateJvmInfo(MongoCollection<Document> collection, String body, String systemId, String jvmId, String queries) { + Bson baseQuery = and(eq(Fields.JVM_ID, jvmId), eq(Fields.SYSTEM_ID, systemId)); + + BasicDBObject inputObject = (BasicDBObject) JSON.parse(body); + BasicDBObject setObject = (BasicDBObject) inputObject.get(Fields.SET); + if (setObject.containsField(Fields.JVM_ID) || setObject.containsField(Fields.SYSTEM_ID)) { + throw new UnsupportedOperationException("Updating " + Fields.SYSTEM_ID + " or " + Fields.JVM_ID + " fields is not allowed"); + } + + final List<String> queriesList; + if (queries != null) { + queriesList = Arrays.asList(queries.split(",")); + } else { + queriesList = Collections.emptyList(); + } + + final Bson fields = new Document("$set", setObject); + + collection.updateMany(and(baseQuery, MongoRequestFilters.buildQueriesFilter(queriesList)), fields); + } + + public void updateTimestamps(MongoCollection<Document> collection, String body, String systemId, Long timeStamp) { + final Bson filter; + if (body != null && body.length() > 0) { + List<String> jvms = (List<String>) JSON.parse(body); + List<Bson> jvmFilters = new ArrayList<>(); + for (String id : jvms) { + jvmFilters.add(eq(Fields.JVM_ID, id)); + } + filter = and(eq(Fields.SYSTEM_ID, systemId), or(jvmFilters)); + } else { + filter = eq(Fields.SYSTEM_ID, systemId); + } + + String setDocument = "{ \"$set\" : { \"" + Fields.LAST_UPDATED + "\":" + timeStamp + " } }"; + final Bson update = Document.parse(setDocument); + collection.updateMany(filter, update); + } + + public String getJvmsTree(MongoCollection<Document> collection, boolean aliveOnly, String excludes, String includes, int limit, int offset) { + FindIterable<Document> documents; + + if (aliveOnly) { + documents = collection.find(lt(Fields.STOP_TIME, 0)); + } else { + documents = collection.find(); + } + + documents = documents.limit(limit).skip(offset); + + boolean includeSystemId = true; + if (excludes != null) { + List<String> excludesList = new ArrayList<>(Arrays.asList(excludes.split(","))); + if (excludesList.contains(Fields.SYSTEM_ID)) { + excludesList.remove(Fields.SYSTEM_ID); + includeSystemId = false; + } + if (excludesList.size() > 0) { + documents = documents.projection(fields(exclude(excludesList), excludeId())); + } else { + documents = documents.projection(excludeId()); + } + } else if (includes != null) { + List<String> includesList = new ArrayList<>(Arrays.asList(includes.split(","))); + if (!includesList.contains(Fields.SYSTEM_ID)) { + includesList.add(Fields.SYSTEM_ID); + includeSystemId = false; + } + documents = documents.projection(fields(include(includesList), excludeId())); + } else { + documents = documents.projection(excludeId()); + } + + final Map<String, StringBuilder> map = new HashMap<>(); + + final boolean finalIncludeSystemId = includeSystemId; + documents.forEach(new Block<Document>() { + @Override + public void apply(Document document) { + String systemId = document.getString(Fields.SYSTEM_ID); + if (!finalIncludeSystemId) { + document.remove(Fields.SYSTEM_ID); + } + + if (!map.containsKey(systemId)) { + map.put(systemId, new StringBuilder().append("{\"" + Fields.SYSTEM_ID + "\":\"" + systemId + "\", \"" + Fields.JVMS + "\":[")); + } + + map.get(systemId).append(document.toJson()).append(","); + } + }); + + StringBuilder responseBuilder = new StringBuilder().append("{ \"" + Fields.RESPONSE + "\" : ["); + if (map.size() > 0) { + for (StringBuilder systemBuilder : map.values()) { + responseBuilder.append(systemBuilder.deleteCharAt(systemBuilder.length() - 1).toString()); + responseBuilder.append("]},"); + } + responseBuilder.deleteCharAt(responseBuilder.length() - 1); + } + responseBuilder.append("]}"); + + return responseBuilder.toString(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jvms/src/main/resources/jvms-swagger.yaml Tue May 30 09:16:06 2017 -0400 @@ -0,0 +1,339 @@ +swagger: '2.0' +info: + version: 0.0.1 + title: Thermostat Web Gateway JVM Information API + license: + name: GPL v2 with Classpath Exception + url: 'http://www.gnu.org/licenses' +consumes: + - application/json +produces: + - application/json + - text/html; charset=utf-8 +basePath: /jvms/0.0.1 +paths: + '/systems/{systemId}': + parameters: + - $ref: '#/parameters/system-id' + get: + description: 'Get jvms for system {systemId}' + parameters: + - $ref: '#/parameters/limit' + - $ref: '#/parameters/offset' + - $ref: '#/parameters/sort' + - $ref: '#/parameters/include' + - $ref: '#/parameters/exclude' + - $ref: '#/parameters/query' + responses: + '200': + description: OK + schema: + $ref: '#/definitions/jvms-get-response' + post: + description: 'Add jvms for system {systemId}' + parameters: + - $ref: '#/parameters/jvms-post-body' + responses: + '200': + description: OK + delete: + description: 'Delete all jvms on system {systemId}' + responses: + '200': + description: OK + '/systems/{systemId}/jvms/{jvmId}': + parameters: + - $ref: '#/parameters/system-id' + - $ref: '#/parameters/jvm-id' + get: + description: 'Get information for the JVM with id {jvmId} running on system {systemId}' + parameters: + - $ref: '#/parameters/include' + - $ref: '#/parameters/exclude' + responses: + '200': + description: OK + schema: + $ref: '#/definitions/jvms-get-response' + put: + description: 'Update the JVM with id {jvmId} running on system {systemId}' + responses: + '200': + description: OK + parameters: + - $ref: "#/parameters/jvms-put-body" + delete: + description: 'Delete the JVM with id {jvmId} running on system {systemId}' + responses: + '200': + description: OK + '/tree': + get: + description: Get jvm information organized by systemId + parameters: + - $ref: '#/parameters/alive-only' + - $ref: '#/parameters/include' + - $ref: '#/parameters/exclude' + - $ref: '#/parameters/limit' + - $ref: '#/parameters/offset' + responses: + '200': + description: OK + schema: + $ref: '#/definitions/tree-get-response' + '/update/systems/{systemId}/ts/{timeStamp}': + parameters: + - $ref: '#/parameters/system-id' + - $ref: '#/parameters/timestamp' + put: + description: 'Set last updated to {timeStamp} for jvm information on system {systemId}' + parameters: + - $ref: "#/parameters/update-put-body" + responses: + '200': + description: OK + +definitions: + jvm-get-info: + type: object + properties: + systemId: + type: string + agentId: + type: string + jvmId: + type: string + mainClass: + type: string + startTime: + type: integer + format: int64 + endTime: + type: integer + format: int64 + jvmPid: + type: integer + javaVersion: + type: string + javaHome: + type: string + javaCommandLine: + type: string + jvmArguments: + type: string + jvmName: + type: string + jvmInfo: + type: string + jvmVersion: + type: string + classpath: + type: string + environment: + type: array + items: + $ref: '#/definitions/environment-items' + uid: + type: integer + format: int64 + username: + type: string + lastUpdated: + type: integer + format: int64 + + jvm-post-info: + type: object + properties: + agentId: + type: string + jvmId: + type: string + mainClass: + type: string + startTime: + type: integer + format: int64 + stopTime: + type: integer + format: int64 + jvmPid: + type: integer + javaVersion: + type: string + javaHome: + type: string + javaCommandLine: + type: string + jvmArguments: + type: string + jvmName: + type: string + jvmInfo: + type: string + jvmVersion: + type: string + classpath: + type: string + environment: + type: array + items: + $ref: '#/definitions/environment-items' + uid: + type: integer + format: int64 + username: + type: string + lastUpdated: + type: integer + format: int64 + environment-items: + type: object + properties: + key: + type: string + value: + type: string + + jvms-get-response: + type: object + properties: + response: + type: array + items: + $ref: '#/definitions/jvm-get-info' + jvms-put-body: + type: object + properties: + set: + type: object + jvms-post-body: + type: array + items: + $ref: '#/definitions/jvm-post-info' + + update-put-body: + type: array + description: 'An array of jvm ID strings' + items: + type: string + + tree-get-response: + type: object + properties: + systemId: + type: string + jvms: + type: array + items: + $ref: '#/definitions/jvm-get-info' +parameters: + system-id: + name: systemId + in: path + required: true + type: string + description: The system ID for the jvms + jvm-id: + name: jvmId + in: path + required: true + type: string + description: The ID of the jvm + timestamp: + name: timeStamp + in: path + required: true + type: integer + format: int64 + description: The timestamp to set the last_updated field for. + jvms-post-body: + name: body + in: body + description: The jvm information + required: true + schema: + $ref: '#/definitions/jvms-post-body' + jvms-put-body: + name: body + in: body + description: >- + The JSON object containing a 'set' object. This contains single item JSON + objects that specify the field to replace and the JSON value to replace with. + Must not include 'systemId' or 'jvmId' fields. Example { "set" : { + "field" : "value", "field2":{"object":"item"} } + required: true + schema: + $ref: '#/definitions/jvms-put-body' + update-put-body: + name: body + in: body + description: >- + An array of jvmIds for which to update the last_updated field. + required: true + schema: + $ref: '#/definitions/update-put-body' + limit: + name: limit + in: query + description: Limit of items to return. Example '1' + type: integer + required: false + default: 1 + offset: + name: offset + in: query + description: Offset of items to return. Example '0' + type: integer + required: false + default: 0 + sort: + name: sort + in: query + description: >- + Sort string. Comma separated list of fields prefixed with '+' for + ascending or '-' for descending. Example '?sort=+a,-b' Fields use dot + notation for embedded documents. Example 'outer.inner' refers to field + inner contained in field outer. + type: string + required: false + query: + name: query + in: query + description: >- + Query string. Comma separated list of key, comparator, value pairs. + Comparator supports '==', '<=', '>=', '<', '>', '!='. Example + '?query=a==b,c!=d'. Keys are fields in documents and use dot notation for + embedded documents. Example 'outer.inner' refers to field inner contained + in field outer. + type: string + required: false + include: + name: include + in: query + description: >- + Inclusion string. Comma separated list of fields to include in the + response. Example '?include=a,b' Fields use dot notation for embedded + documents. Example 'outer.inner' refers to field inner contained in field + outer. Cannot be used in combination with 'exclude' parameter Overriden by + 'exclude' parameter + type: string + required: false + exclude: + name: exclude + in: query + description: >- + Exclusion string. Comma separated list of fields to exclude in the + response. Example '?exclude=a,b' Fields use dot notation for embedded + documents. Example 'outer.inner' refers to field inner contained in field + outer. Cannot be used in combination with 'include' parameter; takes + precedence over 'include' parameter + type: string + required: false + alive-only: + name: aliveOnly + in: query + description: Whether or not to return only JVMs that are live + type: boolean + default: true + required: false \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/jvms/src/main/webapp/WEB-INF/web.xml Tue May 30 09:16:06 2017 -0400 @@ -0,0 +1,68 @@ +<!-- + + 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>JvmsServlet</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.service.jvms.http, + </param-value> + </init-param> + </servlet> + <servlet-mapping> + <servlet-name>JvmsServlet</servlet-name> + <url-pattern>/0.0.1/*</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> +</web-app> \ No newline at end of file
--- a/services/pom.xml Fri May 19 16:03:47 2017 +0200 +++ b/services/pom.xml Tue May 30 09:16:06 2017 -0400 @@ -51,9 +51,10 @@ <name>Thermostat Services</name> <modules> - <module>jvm-memory</module> + <module>commands</module> <module>jvm-gc</module> - <module>commands</module> + <module>jvms</module> + <module>jvm-memory</module> <module>white-pages</module> </modules>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvms/JvmsServiceIntegrationTest.java Tue May 30 09:16:06 2017 -0400 @@ -0,0 +1,621 @@ +/* + * 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.jvms; + +import static org.junit.Assert.assertEquals; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; + +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.util.StringContentProvider; +import org.eclipse.jetty.http.HttpMethod; +import org.junit.Before; +import org.junit.Test; + +import com.redhat.thermostat.gateway.tests.integration.IntegrationTest; + +public class JvmsServiceIntegrationTest extends IntegrationTest { + private final String collectionName = "jvm-info"; + private final String jvmsUrl = baseUrl + "/jvms/0.0.1"; + + private final String postData = "[{ \"agentId\" : \"aid\", \"jvmId\" : \"jid1\", \"jvmPid\" : 1, \"startTime\" :" + + "{ \"$numberLong\" : \"1495727607481\" }, \"stopTime\" : { \"$numberLong\" : \"-9223372036854775808\" }," + + " \"javaVersion\" : \"1.8.0_131\", \"javaHome\" : \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre\"," + + " \"mainClass\" : \"mc\", \"javaCommandLine\" : \"j cl\", \"jvmName\" : \"vm\", \"vmArguments\" :" + + " \"-Djline.log.jul=true\", \"jvmInfo\" : \"mixed mode\", \"lastUpdated\" : 0, \"jvmVersion\" :" + + " \"25.131-b12\", \"environment\" : [{ \"key\" : \"PATH\", \"value\" : \"/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin\"" + + " }, { \"key\" : \"XAUTHORITY\", \"value\" : \"/run/user/1000/gdm/Xauthority\" }, { \"key\" : \"GDMSESSION\"," + + " \"value\" : \"i3\" }, { \"key\" : \"fish_greeting\", \"value\" : \"\" }, { \"key\" : \"TERM\", \"value\" :" + + " \"xterm-256color\" }, { \"key\" : \"DARWIN_MODE\", \"value\" : \"0\" }, { \"key\" : \"LANG\", \"value\" :" + + " \"en_US.UTF-8\" }, { \"key\" : \"DBUS_SESSION_BUS_ADDRESS\", \"value\" : \"unix:path=/run/user/1000/bus\" }," + + " { \"key\" : \"XDG_SESSION_ID\", \"value\" : \"2\" }, { \"key\" : \"XDG_SESSION_TYPE\", \"value\" : \"x11\" }," + + " { \"key\" : \"XDG_CURRENT_DESKTOP\", \"value\" : \"i3\" }, { \"key\" : \"DISPLAY\", \"value\" : \":0\" }," + + " { \"key\" : \"CYGWIN_MODE\", \"value\" : \"0\" }, { \"key\" : \"COLORTERM\", \"value\" : \"truecolor\" }, " + + "{ \"key\" : \"_\", \"value\" : \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre/../bin/java\" }]," + + " \"uid\" : 1000, \"username\" : \"user\"},{ \"agentId\" : \"aid\", \"jvmId\" : \"jid2\", \"jvmPid\" : 2," + + " \"startTime\" : { \"$numberLong\" : \"1495727607481\" }, \"stopTime\" : { \"$numberLong\" : \"1495727607482\" }," + + " \"javaVersion\" : \"1.8.0_131\", \"javaHome\" : \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre\"," + + " \"mainClass\" : \"mc\", \"javaCommandLine\" : \"j cl\", \"jvmName\" : \"vm\", \"vmArguments\" :" + + " \"-Djline.log.jul=true\", \"jvmInfo\" : \"mixed mode\", \"lastUpdated\" : 0, \"jvmVersion\" : \"25.131-b12\"," + + " \"environment\" : [{ \"key\" : \"PATH\", \"value\" : \"/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin\" }," + + " { \"key\" : \"XAUTHORITY\", \"value\" : \"/run/user/1000/gdm/Xauthority\" }, { \"key\" : \"GDMSESSION\"," + + " \"value\" : \"i3\" }, { \"key\" : \"fish_greeting\", \"value\" : \"\" }, { \"key\" : \"TERM\", \"value\" :" + + " \"xterm-256color\" }, { \"key\" : \"DARWIN_MODE\", \"value\" : \"0\" }, { \"key\" : \"LANG\", \"value\" :" + + " \"en_US.UTF-8\" }, { \"key\" : \"DBUS_SESSION_BUS_ADDRESS\", \"value\" : \"unix:path=/run/user/1000/bus\" }," + + " { \"key\" : \"XDG_SESSION_ID\", \"value\" : \"2\" }, { \"key\" : \"XDG_SESSION_TYPE\", \"value\" : \"x11\" }," + + " { \"key\" : \"XDG_CURRENT_DESKTOP\", \"value\" : \"i3\" }, { \"key\" : \"DISPLAY\", \"value\" : \":0\" }," + + " { \"key\" : \"CYGWIN_MODE\", \"value\" : \"0\" }, { \"key\" : \"COLORTERM\", \"value\" : \"truecolor\" }," + + " { \"key\" : \"_\", \"value\" : \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre/../bin/java\" }]," + + " \"uid\" : 1000, \"username\" : \"user\"}]"; + + private final String postDataWithSystemId = postData.substring(0, postData.length() - 2) + + ", \"systemId\" : \"invalid\"}]"; + + @Before + public void beforeIntegrationTest() { + mongodTestUtil.dropCollection(collectionName); + } + + @Test + public void testGetEmpty() throws InterruptedException, TimeoutException, ExecutionException { + String url = jvmsUrl + "/systems/1"; + ContentResponse response = client.newRequest(url).method(HttpMethod.GET).send(); + assertEquals(200, response.getStatus()); + String expected = "{ \"response\" : [] }"; + assertEquals(expected, response.getContentAsString()); + } + + @Test + public void testPost() throws InterruptedException, ExecutionException, TimeoutException { + String url = jvmsUrl + "/systems/1"; + + ContentResponse postResponse = client.newRequest(url).method(HttpMethod.POST) + .content(new StringContentProvider(postData), "application/json").send(); + assertEquals(200, postResponse.getStatus()); + + ContentResponse getResponse = client.newRequest(url).method(HttpMethod.GET).send(); + assertEquals(200, getResponse.getStatus()); + String expected = "{ \"response\" : [{ \"agentId\" : \"aid\", \"jvmId\" : \"jid1\", \"jvmPid\" : 1, " + + "\"startTime\" : { \"$numberLong\" : \"1495727607481\" }, \"stopTime\" : { \"$numberLong\" : " + + "\"-9223372036854775808\" }, \"javaVersion\" : \"1.8.0_131\", \"javaHome\" : " + + "\"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre\", \"mainClass\" : \"mc\", " + + "\"javaCommandLine\" : \"j cl\", \"jvmName\" : \"vm\", \"vmArguments\" : \"-Djline.log.jul=true\"," + + " \"jvmInfo\" : \"mixed mode\", \"lastUpdated\" : 0, \"jvmVersion\" : \"25.131-b12\", \"environment\"" + + " : [{ \"key\" : \"PATH\", \"value\" : \"/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin\" }," + + " { \"key\" : \"XAUTHORITY\", \"value\" : \"/run/user/1000/gdm/Xauthority\" }, { \"key\" :" + + " \"GDMSESSION\", \"value\" : \"i3\" }, { \"key\" : \"fish_greeting\", \"value\" : \"\" }, { \"key\" :" + + " \"TERM\", \"value\" : \"xterm-256color\" }, { \"key\" : \"DARWIN_MODE\", \"value\" : \"0\" }," + + " { \"key\" : \"LANG\", \"value\" : \"en_US.UTF-8\" }, { \"key\" : \"DBUS_SESSION_BUS_ADDRESS\"," + + " \"value\" : \"unix:path=/run/user/1000/bus\" }, { \"key\" : \"XDG_SESSION_ID\", \"value\" : \"2\" }," + + " { \"key\" : \"XDG_SESSION_TYPE\", \"value\" : \"x11\" }, { \"key\" : \"XDG_CURRENT_DESKTOP\"," + + " \"value\" : \"i3\" }, { \"key\" : \"DISPLAY\", \"value\" : \":0\" }, { \"key\" : \"CYGWIN_MODE\"," + + " \"value\" : \"0\" }, { \"key\" : \"COLORTERM\", \"value\" : \"truecolor\" }, { \"key\" : \"_\", " + + "\"value\" : \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre/../bin/java\" }], " + + "\"uid\" : 1000, \"username\" : \"user\", \"systemId\" : \"1\" }] }"; + assertEquals(expected, getResponse.getContentAsString()); + } + + /* + * Verify POST does not override path parameter systemId with body systemId + * POST /systems/1 [{"systemId":2 ... }] should result in systemId of 1, not 2 + */ + @Test + public void testPostWithSystemId() throws InterruptedException, ExecutionException, TimeoutException { + String url = jvmsUrl + "/systems/1"; + + ContentResponse postResponse = client.newRequest(url).method(HttpMethod.POST) + .content(new StringContentProvider(postDataWithSystemId), "application/json").send(); + assertEquals(200, postResponse.getStatus()); + + ContentResponse getResponse = client.newRequest(url).method(HttpMethod.GET).send(); + assertEquals(200, getResponse.getStatus()); + String expected = "{ \"response\" : [{ \"agentId\" : \"aid\", \"jvmId\" : \"jid1\", \"jvmPid\" : 1," + + " \"startTime\" : { \"$numberLong\" : \"1495727607481\" }, \"stopTime\" : { \"$numberLong\" :" + + " \"-9223372036854775808\" }, \"javaVersion\" : \"1.8.0_131\", \"javaHome\" : \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre\", \"mainClass\" : \"mc\", " + + "\"javaCommandLine\" : \"j cl\", \"jvmName\" : \"vm\", \"vmArguments\" : \"-Djline.log.jul=true\"," + + " \"jvmInfo\" : \"mixed mode\", \"lastUpdated\" : 0, \"jvmVersion\" : \"25.131-b12\", \"environment\"" + + " : [{ \"key\" : \"PATH\", \"value\" : \"/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin\" }, { " + + "\"key\" : \"XAUTHORITY\", \"value\" : \"/run/user/1000/gdm/Xauthority\" }, { \"key\" : \"GDMSESSION\"," + + " \"value\" : \"i3\" }, { \"key\" : \"fish_greeting\", \"value\" : \"\" }, { \"key\" : \"TERM\", " + + "\"value\" : \"xterm-256color\" }, { \"key\" : \"DARWIN_MODE\", \"value\" : \"0\" }, { \"key\" : " + + "\"LANG\", \"value\" : \"en_US.UTF-8\" }, { \"key\" : \"DBUS_SESSION_BUS_ADDRESS\", \"value\" : \"unix:path=/run/user/1000/bus\" }, { \"key\" : \"XDG_SESSION_ID\", \"value\" : \"2\" }, { \"key\"" + + " : \"XDG_SESSION_TYPE\", \"value\" : \"x11\" }, { \"key\" : \"XDG_CURRENT_DESKTOP\", \"value\" : " + + "\"i3\" }, { \"key\" : \"DISPLAY\", \"value\" : \":0\" }, { \"key\" : \"CYGWIN_MODE\", \"value\" :" + + " \"0\" }, { \"key\" : \"COLORTERM\", \"value\" : \"truecolor\" }, { \"key\" : \"_\", \"value\"" + + " : \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre/../bin/java\" }], \"uid\" : 1000," + + " \"username\" : \"user\", \"systemId\" : \"1\" }] }"; + assertEquals(expected, getResponse.getContentAsString()); + } + + @Test + public void testGetLimit() throws InterruptedException, ExecutionException, TimeoutException { + String url = jvmsUrl + "/systems/1"; + + ContentResponse postResponse = client.newRequest(url).method(HttpMethod.POST) + .content(new StringContentProvider(postData), "application/json").send(); + assertEquals(200, postResponse.getStatus()); + + String query = "?limit=2"; + ContentResponse getResponse = client.newRequest(url + query).method(HttpMethod.GET).send(); + assertEquals(200, getResponse.getStatus()); + String expected = "{ \"response\" : [{ \"agentId\" : \"aid\", \"jvmId\" : \"jid1\", \"jvmPid\" : 1," + + " \"startTime\" : { \"$numberLong\" : \"1495727607481\" }, \"stopTime\" : { \"$numberLong\" :" + + " \"-9223372036854775808\" }, \"javaVersion\" : \"1.8.0_131\", \"javaHome\" : " + + "\"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre\", \"mainClass\" : \"mc\"," + + " \"javaCommandLine\" : \"j cl\", \"jvmName\" : \"vm\", \"vmArguments\" : \"-Djline.log.jul=true\"," + + " \"jvmInfo\" : \"mixed mode\", \"lastUpdated\" : 0, \"jvmVersion\" : \"25.131-b12\", \"environment\" " + + ": [{ \"key\" : \"PATH\", \"value\" : \"/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin\" }, {" + + " \"key\" : \"XAUTHORITY\", \"value\" : \"/run/user/1000/gdm/Xauthority\" }, { \"key\" : " + + "\"GDMSESSION\", \"value\" : \"i3\" }, { \"key\" : \"fish_greeting\", \"value\" : \"\" }, { \"key\" :" + + " \"TERM\", \"value\" : \"xterm-256color\" }, { \"key\" : \"DARWIN_MODE\", \"value\" : \"0\" }, { " + + "\"key\" : \"LANG\", \"value\" : \"en_US.UTF-8\" }, { \"key\" : \"DBUS_SESSION_BUS_ADDRESS\", \"value\"" + + " : \"unix:path=/run/user/1000/bus\" }, { \"key\" : \"XDG_SESSION_ID\", \"value\" : \"2\" }, { " + + "\"key\" : \"XDG_SESSION_TYPE\", \"value\" : \"x11\" }, { \"key\" : \"XDG_CURRENT_DESKTOP\", \"value\"" + + " : \"i3\" }, { \"key\" : \"DISPLAY\", \"value\" : \":0\" }, { \"key\" : \"CYGWIN_MODE\", \"value\" :" + + " \"0\" }, { \"key\" : \"COLORTERM\", \"value\" : \"truecolor\" }, { \"key\" : \"_\", \"value\" : " + + "\"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre/../bin/java\" }], \"uid\" : 1000, " + + "\"username\" : \"user\", \"systemId\" : \"1\" },{ \"agentId\" : \"aid\", \"jvmId\" : \"jid2\", " + + "\"jvmPid\" : 2, \"startTime\" : { \"$numberLong\" : \"1495727607481\" }, \"stopTime\" : { " + + "\"$numberLong\" : \"1495727607482\" }, \"javaVersion\" : \"1.8.0_131\", \"javaHome\" : " + + "\"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre\", \"mainClass\" : \"mc\", " + + "\"javaCommandLine\" : \"j cl\", \"jvmName\" : \"vm\", \"vmArguments\" : \"-Djline.log.jul=true\", " + + "\"jvmInfo\" : \"mixed mode\", \"lastUpdated\" : 0, \"jvmVersion\" : \"25.131-b12\", \"environment\" :" + + " [{ \"key\" : \"PATH\", \"value\" : \"/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin\" }, { " + + "\"key\" : \"XAUTHORITY\", \"value\" : \"/run/user/1000/gdm/Xauthority\" }, { \"key\" : \"GDMSESSION\"," + + " \"value\" : \"i3\" }, { \"key\" : \"fish_greeting\", \"value\" : \"\" }, { \"key\" : \"TERM\"," + + " \"value\" : \"xterm-256color\" }, { \"key\" : \"DARWIN_MODE\", \"value\" : \"0\" }, { \"key\" :" + + " \"LANG\", \"value\" : \"en_US.UTF-8\" }, { \"key\" : \"DBUS_SESSION_BUS_ADDRESS\", \"value\" : " + + "\"unix:path=/run/user/1000/bus\" }, { \"key\" : \"XDG_SESSION_ID\", \"value\" : \"2\" }, { \"key\" : " + + "\"XDG_SESSION_TYPE\", \"value\" : \"x11\" }, { \"key\" : \"XDG_CURRENT_DESKTOP\", \"value\" : \"i3\"" + + " }, { \"key\" : \"DISPLAY\", \"value\" : \":0\" }, { \"key\" : \"CYGWIN_MODE\", \"value\" : \"0\"" + + " }, { \"key\" : \"COLORTERM\", \"value\" : \"truecolor\" }, { \"key\" : \"_\", \"value\" : " + + "\"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre/../bin/java\" }], \"uid\" : 1000, " + + "\"username\" : \"user\", \"systemId\" : \"1\" }] }"; + assertEquals(expected, getResponse.getContentAsString()); + } + + @Test + public void testGetOffset() throws InterruptedException, ExecutionException, TimeoutException { + String url = jvmsUrl + "/systems/1"; + + ContentResponse postResponse = client.newRequest(url).method(HttpMethod.POST) + .content(new StringContentProvider(postData), "application/json").send(); + assertEquals(200, postResponse.getStatus()); + + String query = "?offset=1"; + ContentResponse getResponse = client.newRequest(url + query).method(HttpMethod.GET).send(); + assertEquals(200, getResponse.getStatus()); + String expected = "{ \"response\" : [{ \"agentId\" : \"aid\", \"jvmId\" : \"jid2\", \"jvmPid\" : 2, " + + "\"startTime\" : { \"$numberLong\" : \"1495727607481\" }, \"stopTime\" : { \"$numberLong\" : " + + "\"1495727607482\" }, \"javaVersion\" : \"1.8.0_131\", \"javaHome\" : \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre\", \"mainClass\" : \"mc\"," + + " \"javaCommandLine\" : \"j cl\", \"jvmName\" : \"vm\", \"vmArguments\" : \"-Djline.log.jul=true\"," + + " \"jvmInfo\" : \"mixed mode\", \"lastUpdated\" : 0, \"jvmVersion\" : \"25.131-b12\", \"environment\" " + + ": [{ \"key\" : \"PATH\", \"value\" : \"/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin\" }, { " + + "\"key\" : \"XAUTHORITY\", \"value\" : \"/run/user/1000/gdm/Xauthority\" }, { \"key\" : \"GDMSESSION\"," + + " \"value\" : \"i3\" }, { \"key\" : \"fish_greeting\", \"value\" : \"\" }, { \"key\" : \"TERM\"," + + " \"value\" : \"xterm-256color\" }, { \"key\" : \"DARWIN_MODE\", \"value\" : \"0\" }, { \"key\" :" + + " \"LANG\", \"value\" : \"en_US.UTF-8\" }, { \"key\" : \"DBUS_SESSION_BUS_ADDRESS\", \"value\" : \"unix:path=/run/user/1000/bus\" }, { \"key\" : \"XDG_SESSION_ID\", \"value\" : \"2\" }, { \"key\" " + + ": \"XDG_SESSION_TYPE\", \"value\" : \"x11\" }, { \"key\" : \"XDG_CURRENT_DESKTOP\", \"value\" :" + + " \"i3\" }, { \"key\" : \"DISPLAY\", \"value\" : \":0\" }, { \"key\" : \"CYGWIN_MODE\", \"value\" : " + + "\"0\" }, { \"key\" : \"COLORTERM\", \"value\" : \"truecolor\" }, { \"key\" : \"_\", \"value\" :" + + " \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre/../bin/java\" }], \"uid\" : 1000," + + " \"username\" : \"user\", \"systemId\" : \"1\" }] }"; + assertEquals(expected, getResponse.getContentAsString()); + } + + @Test + public void testGetQuery() throws InterruptedException, ExecutionException, TimeoutException { + String url = jvmsUrl + "/systems/1"; + + ContentResponse postResponse = client.newRequest(url).method(HttpMethod.POST) + .content(new StringContentProvider(postData), "application/json").send(); + assertEquals(200, postResponse.getStatus()); + + String query = "?query=jvmId==jid2"; + ContentResponse getResponse = client.newRequest(url + query).method(HttpMethod.GET).send(); + assertEquals(200, getResponse.getStatus()); + String expected = "{ \"response\" : [{ \"agentId\" : \"aid\", \"jvmId\" : \"jid2\", \"jvmPid\" : 2, " + + "\"startTime\" : { \"$numberLong\" : \"1495727607481\" }, \"stopTime\" : { \"$numberLong\" : " + + "\"1495727607482\" }, \"javaVersion\" : \"1.8.0_131\", \"javaHome\" : \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre\", \"mainClass\" : \"mc\"," + + " \"javaCommandLine\" : \"j cl\", \"jvmName\" : \"vm\", \"vmArguments\" : \"-Djline.log.jul=true\"," + + " \"jvmInfo\" : \"mixed mode\", \"lastUpdated\" : 0, \"jvmVersion\" : \"25.131-b12\", \"environment\" " + + ": [{ \"key\" : \"PATH\", \"value\" : \"/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin\" }, { " + + "\"key\" : \"XAUTHORITY\", \"value\" : \"/run/user/1000/gdm/Xauthority\" }, { \"key\" : \"GDMSESSION\"," + + " \"value\" : \"i3\" }, { \"key\" : \"fish_greeting\", \"value\" : \"\" }, { \"key\" : \"TERM\"," + + " \"value\" : \"xterm-256color\" }, { \"key\" : \"DARWIN_MODE\", \"value\" : \"0\" }, { \"key\" :" + + " \"LANG\", \"value\" : \"en_US.UTF-8\" }, { \"key\" : \"DBUS_SESSION_BUS_ADDRESS\", \"value\" : \"unix:path=/run/user/1000/bus\" }, { \"key\" : \"XDG_SESSION_ID\", \"value\" : \"2\" }, { \"key\" " + + ": \"XDG_SESSION_TYPE\", \"value\" : \"x11\" }, { \"key\" : \"XDG_CURRENT_DESKTOP\", \"value\" :" + + " \"i3\" }, { \"key\" : \"DISPLAY\", \"value\" : \":0\" }, { \"key\" : \"CYGWIN_MODE\", \"value\" : " + + "\"0\" }, { \"key\" : \"COLORTERM\", \"value\" : \"truecolor\" }, { \"key\" : \"_\", \"value\" :" + + " \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre/../bin/java\" }], \"uid\" : 1000," + + " \"username\" : \"user\", \"systemId\" : \"1\" }] }"; + assertEquals(expected, getResponse.getContentAsString()); + } + + @Test + public void testGetInclude() throws InterruptedException, ExecutionException, TimeoutException { + String url = jvmsUrl + "/systems/1"; + + ContentResponse postResponse = client.newRequest(url).method(HttpMethod.POST) + .content(new StringContentProvider(postData), "application/json").send(); + assertEquals(200, postResponse.getStatus()); + + String query = "?include=agentId,jvmId"; + ContentResponse getResponse = client.newRequest(url + query).method(HttpMethod.GET).send(); + assertEquals(200, getResponse.getStatus()); + String expected = "{ \"response\" : [{ \"agentId\" : \"aid\", \"jvmId\" : \"jid1\" }] }"; + assertEquals(expected, getResponse.getContentAsString()); + } + + @Test + public void testGetExclude() throws InterruptedException, ExecutionException, TimeoutException { + String url = jvmsUrl + "/systems/1"; + + ContentResponse postResponse = client.newRequest(url).method(HttpMethod.POST) + .content(new StringContentProvider(postData), "application/json").send(); + assertEquals(200, postResponse.getStatus()); + + String query = "?exclude=agentId"; + ContentResponse getResponse = client.newRequest(url + query).method(HttpMethod.GET).send(); + assertEquals(200, getResponse.getStatus()); + String expected = "{ \"response\" : [{ \"jvmId\" : \"jid1\", \"jvmPid\" : 1, \"startTime\" : { \"$numberLong\"" + + " : \"1495727607481\" }, \"stopTime\" : { \"$numberLong\" : \"-9223372036854775808\" }, \"javaVersion\"" + + " : \"1.8.0_131\", \"javaHome\" : \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre\"," + + " \"mainClass\" : \"mc\", \"javaCommandLine\" : \"j cl\", \"jvmName\" : \"vm\", \"vmArguments\" :" + + " \"-Djline.log.jul=true\", \"jvmInfo\" : \"mixed mode\", \"lastUpdated\" : 0, \"jvmVersion\" : " + + "\"25.131-b12\", \"environment\" : [{ \"key\" : \"PATH\", \"value\" : " + + "\"/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin\" }, { \"key\" : \"XAUTHORITY\", \"value\" : " + + "\"/run/user/1000/gdm/Xauthority\" }, { \"key\" : \"GDMSESSION\", \"value\" : \"i3\" }, { \"key\" :" + + " \"fish_greeting\", \"value\" : \"\" }, { \"key\" : \"TERM\", \"value\" : \"xterm-256color\" }, { " + + "\"key\" : \"DARWIN_MODE\", \"value\" : \"0\" }, { \"key\" : \"LANG\", \"value\" : \"en_US.UTF-8\" }, {" + + " \"key\" : \"DBUS_SESSION_BUS_ADDRESS\", \"value\" : \"unix:path=/run/user/1000/bus\" }, { \"key\" :" + + " \"XDG_SESSION_ID\", \"value\" : \"2\" }, { \"key\" : \"XDG_SESSION_TYPE\", \"value\" : \"x11\" }," + + " { \"key\" : \"XDG_CURRENT_DESKTOP\", \"value\" : \"i3\" }, { \"key\" : \"DISPLAY\", \"value\" :" + + " \":0\" }, { \"key\" : \"CYGWIN_MODE\", \"value\" : \"0\" }, { \"key\" : \"COLORTERM\", \"value\" :" + + " \"truecolor\" }, { \"key\" : \"_\", \"value\" : " + + "\"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre/../bin/java\" }], \"uid\" : 1000, " + + "\"username\" : \"user\", \"systemId\" : \"1\" }] }"; + assertEquals(expected, getResponse.getContentAsString()); + } + + @Test + public void testDeleteMany() throws InterruptedException, TimeoutException, ExecutionException { + String url = jvmsUrl + "/systems/1"; + + ContentResponse postResponse = client.newRequest(url).method(HttpMethod.POST) + .content(new StringContentProvider(postData), "application/json").send(); + assertEquals(200, postResponse.getStatus()); + + ContentResponse deleteResponse = client.newRequest(url).method(HttpMethod.DELETE).send(); + assertEquals(200, deleteResponse.getStatus()); + + ContentResponse getResponse = client.newRequest(url).method(HttpMethod.GET).send(); + assertEquals(200, getResponse.getStatus()); + String expected = "{ \"response\" : [] }"; + assertEquals(expected, getResponse.getContentAsString()); + } + + @Test + public void testPut() throws InterruptedException, TimeoutException, ExecutionException { + String url = jvmsUrl + "/systems/1"; + String putUrl = jvmsUrl + "/systems/1/jvms/jid1"; + + ContentResponse postResponse = client.newRequest(url).method(HttpMethod.POST) + .content(new StringContentProvider(postData), "application/json").send(); + assertEquals(200, postResponse.getStatus()); + + String setContent = "{\"set\":{\"mainClass\":\"hello\",\"javaVersion\":\"1.7.0\"}}"; + ContentResponse putResponse = client.newRequest(putUrl).method(HttpMethod.PUT). + content(new StringContentProvider(setContent), "application/json").send(); + assertEquals(200, putResponse.getStatus()); + + ContentResponse getResponse = client.newRequest(url).method(HttpMethod.GET).send(); + assertEquals(200, getResponse.getStatus()); + String expected = "{ \"response\" : [{ \"agentId\" : \"aid\", \"jvmId\" : \"jid1\", \"jvmPid\" : 1, " + + "\"startTime\" : { \"$numberLong\" : \"1495727607481\" }, \"stopTime\" : { \"$numberLong\" : " + + "\"-9223372036854775808\" }, \"javaVersion\" : \"1.7.0\", \"javaHome\" : " + + "\"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre\", \"mainClass\" : \"hello\", " + + "\"javaCommandLine\" : \"j cl\", \"jvmName\" : \"vm\", \"vmArguments\" : \"-Djline.log.jul=true\"," + + " \"jvmInfo\" : \"mixed mode\", \"lastUpdated\" : 0, \"jvmVersion\" : \"25.131-b12\", \"environment\"" + + " : [{ \"key\" : \"PATH\", \"value\" : \"/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin\" }, " + + "{ \"key\" : \"XAUTHORITY\", \"value\" : \"/run/user/1000/gdm/Xauthority\" }, { \"key\" : " + + "\"GDMSESSION\", \"value\" : \"i3\" }, { \"key\" : \"fish_greeting\", \"value\" : \"\" }, { \"key\" : " + + "\"TERM\", \"value\" : \"xterm-256color\" }, { \"key\" : \"DARWIN_MODE\", \"value\" : \"0\" }, { " + + "\"key\" : \"LANG\", \"value\" : \"en_US.UTF-8\" }, { \"key\" : \"DBUS_SESSION_BUS_ADDRESS\", " + + "\"value\" : \"unix:path=/run/user/1000/bus\" }, { \"key\" : \"XDG_SESSION_ID\", \"value\" : \"2\" }, " + + "{ \"key\" : \"XDG_SESSION_TYPE\", \"value\" : \"x11\" }, { \"key\" : \"XDG_CURRENT_DESKTOP\", " + + "\"value\" : \"i3\" }, { \"key\" : \"DISPLAY\", \"value\" : \":0\" }, { \"key\" : \"CYGWIN_MODE\"," + + " \"value\" : \"0\" }, { \"key\" : \"COLORTERM\", \"value\" : \"truecolor\" }, { \"key\" : \"_\", " + + "\"value\" : \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre/../bin/java\" }], " + + "\"uid\" : 1000, \"username\" : \"user\", \"systemId\" : \"1\" }] }"; + assertEquals(expected, getResponse.getContentAsString()); + } + + /* + * Verify that PUT cannot be used to update systemId or jvmId fields + */ + @Test + public void testPutInvalidField() throws InterruptedException, TimeoutException, ExecutionException { + // + String url = jvmsUrl + "/systems/1"; + String putUrl = jvmsUrl + "/systems/1/jvms/jid1"; + + ContentResponse postResponse = client.newRequest(url).method(HttpMethod.POST) + .content(new StringContentProvider(postData), "application/json").send(); + assertEquals(200, postResponse.getStatus()); + + String setContent = "{\"set\":{\"systemId\":\"hello\"}}"; + ContentResponse putResponse = client.newRequest(putUrl).method(HttpMethod.PUT) + .content(new StringContentProvider(setContent), "application/json").send(); + assertEquals(400, putResponse.getStatus()); + + setContent = "{\"set\":{\"jvmId\":\"hello\"}}"; + putResponse = client.newRequest(putUrl).method(HttpMethod.PUT) + .content(new StringContentProvider(setContent), "application/json").send(); + assertEquals(400, putResponse.getStatus()); + + ContentResponse getResponse = client.newRequest(url).method(HttpMethod.GET).send(); + assertEquals(200, getResponse.getStatus()); + String expected = "{ \"response\" : [{ \"agentId\" : \"aid\", \"jvmId\" : \"jid1\", \"jvmPid\" : 1," + + " \"startTime\" : { \"$numberLong\" : \"1495727607481\" }, \"stopTime\" : { \"$numberLong\" : " + + "\"-9223372036854775808\" }, \"javaVersion\" : \"1.8.0_131\", \"javaHome\" : \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre\", \"mainClass\" : \"mc\", " + + "\"javaCommandLine\" : \"j cl\", \"jvmName\" : \"vm\", \"vmArguments\" : \"-Djline.log.jul=true\", " + + "\"jvmInfo\" : \"mixed mode\", \"lastUpdated\" : 0, \"jvmVersion\" : \"25.131-b12\", \"environment\" :" + + " [{ \"key\" : \"PATH\", \"value\" : \"/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin\" }, { \"key\"" + + " : \"XAUTHORITY\", \"value\" : \"/run/user/1000/gdm/Xauthority\" }, { \"key\" : \"GDMSESSION\"," + + " \"value\" : \"i3\" }, { \"key\" : \"fish_greeting\", \"value\" : \"\" }, { \"key\" : \"TERM\", " + + "\"value\" : \"xterm-256color\" }, { \"key\" : \"DARWIN_MODE\", \"value\" : \"0\" }, { \"key\" :" + + " \"LANG\", \"value\" : \"en_US.UTF-8\" }, { \"key\" : \"DBUS_SESSION_BUS_ADDRESS\", \"value\" :" + + " \"unix:path=/run/user/1000/bus\" }, { \"key\" : \"XDG_SESSION_ID\", \"value\" : \"2\" }, { \"key\"" + + " : \"XDG_SESSION_TYPE\", \"value\" : \"x11\" }, { \"key\" : \"XDG_CURRENT_DESKTOP\", \"value\" :" + + " \"i3\" }, { \"key\" : \"DISPLAY\", \"value\" : \":0\" }, { \"key\" : \"CYGWIN_MODE\", \"value\" :" + + " \"0\" }, { \"key\" : \"COLORTERM\", \"value\" : \"truecolor\" }, { \"key\" : \"_\", \"value\" :" + + " \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre/../bin/java\" }], \"uid\" : 1000," + + " \"username\" : \"user\", \"systemId\" : \"1\" }] }"; + assertEquals(expected, getResponse.getContentAsString()); + } + + @Test + public void testDeleteOne() throws InterruptedException, TimeoutException, ExecutionException { + String url = jvmsUrl + "/systems/1"; + String deleteUrl = jvmsUrl + "/systems/1/jvms/jid1"; + + ContentResponse postResponse = client.newRequest(url).method(HttpMethod.POST) + .content(new StringContentProvider(postData), "application/json").send(); + assertEquals(200, postResponse.getStatus()); + + ContentResponse deleteResponse = client.newRequest(deleteUrl).method(HttpMethod.DELETE).send(); + assertEquals(200, deleteResponse.getStatus()); + + ContentResponse getResponse = client.newRequest(url).method(HttpMethod.GET).send(); + assertEquals(200, getResponse.getStatus()); + String expected = "{ \"response\" : [{ \"agentId\" : \"aid\", \"jvmId\" : \"jid2\", \"jvmPid\" : 2, " + + "\"startTime\" : { \"$numberLong\" : \"1495727607481\" }, \"stopTime\" : { \"$numberLong\" : " + + "\"1495727607482\" }, \"javaVersion\" : \"1.8.0_131\", \"javaHome\" : \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre\", \"mainClass\" : \"mc\"," + + " \"javaCommandLine\" : \"j cl\", \"jvmName\" : \"vm\", \"vmArguments\" : \"-Djline.log.jul=true\"," + + " \"jvmInfo\" : \"mixed mode\", \"lastUpdated\" : 0, \"jvmVersion\" : \"25.131-b12\", \"environment\" " + + ": [{ \"key\" : \"PATH\", \"value\" : \"/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin\" }, { " + + "\"key\" : \"XAUTHORITY\", \"value\" : \"/run/user/1000/gdm/Xauthority\" }, { \"key\" : \"GDMSESSION\"," + + " \"value\" : \"i3\" }, { \"key\" : \"fish_greeting\", \"value\" : \"\" }, { \"key\" : \"TERM\"," + + " \"value\" : \"xterm-256color\" }, { \"key\" : \"DARWIN_MODE\", \"value\" : \"0\" }, { \"key\" :" + + " \"LANG\", \"value\" : \"en_US.UTF-8\" }, { \"key\" : \"DBUS_SESSION_BUS_ADDRESS\", \"value\" : \"unix:path=/run/user/1000/bus\" }, { \"key\" : \"XDG_SESSION_ID\", \"value\" : \"2\" }, { \"key\" " + + ": \"XDG_SESSION_TYPE\", \"value\" : \"x11\" }, { \"key\" : \"XDG_CURRENT_DESKTOP\", \"value\" :" + + " \"i3\" }, { \"key\" : \"DISPLAY\", \"value\" : \":0\" }, { \"key\" : \"CYGWIN_MODE\", \"value\" : " + + "\"0\" }, { \"key\" : \"COLORTERM\", \"value\" : \"truecolor\" }, { \"key\" : \"_\", \"value\" :" + + " \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre/../bin/java\" }], \"uid\" : 1000," + + " \"username\" : \"user\", \"systemId\" : \"1\" }] }"; + assertEquals(expected, getResponse.getContentAsString()); + } + + @Test + public void testUpdateTimestamp() throws InterruptedException, TimeoutException, ExecutionException { + String updateUrl = jvmsUrl + "/update/systems/1/ts/2000"; + String url = jvmsUrl + "/systems/1"; + + ContentResponse postResponse = client.newRequest(url).method(HttpMethod.POST) + .content(new StringContentProvider(postData), "application/json").send(); + assertEquals(200, postResponse.getStatus()); + + + ContentResponse updateResponse = client.newRequest(updateUrl).method(HttpMethod.PUT).send(); + assertEquals(200, updateResponse.getStatus()); + + ContentResponse response = client.newRequest(url).method(HttpMethod.GET) + .param("include", "lastUpdated").send(); + assertEquals(200, response.getStatus()); + String expected = "{ \"response\" : [{ \"lastUpdated\" : 2000 }] }"; + assertEquals(expected, response.getContentAsString()); + + } + + @Test + public void testTree() throws InterruptedException, TimeoutException, ExecutionException { + String postUrl = jvmsUrl + "/systems/1"; + String treeUrl = jvmsUrl + "/tree"; + + ContentResponse postResponse = client.newRequest(postUrl).method(HttpMethod.POST) + .content(new StringContentProvider(postData), "application/json").send(); + assertEquals(200, postResponse.getStatus()); + + ContentResponse response = client.newRequest(treeUrl).method(HttpMethod.GET).send(); + assertEquals(200, response.getStatus()); + String expected = "{ \"response\" : [{\"systemId\":\"1\", \"jvms\":[{ \"agentId\" : \"aid\", \"jvmId\" : " + + "\"jid1\", \"jvmPid\" : 1, \"startTime\" : { \"$numberLong\" : \"1495727607481\" }, \"stopTime\" : {" + + " \"$numberLong\" : \"-9223372036854775808\" }, \"javaVersion\" : \"1.8.0_131\", \"javaHome\" : \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre\", \"mainClass\" : \"mc\", " + + "\"javaCommandLine\" : \"j cl\", \"jvmName\" : \"vm\", \"vmArguments\" : \"-Djline.log.jul=true\", " + + "\"jvmInfo\" : \"mixed mode\", \"lastUpdated\" : 0, \"jvmVersion\" : \"25.131-b12\", \"environment\" :" + + " [{ \"key\" : \"PATH\", \"value\" : \"/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin\" }, { \"key\"" + + " : \"XAUTHORITY\", \"value\" : \"/run/user/1000/gdm/Xauthority\" }, { \"key\" : \"GDMSESSION\", " + + "\"value\" : \"i3\" }, { \"key\" : \"fish_greeting\", \"value\" : \"\" }, { \"key\" : \"TERM\", " + + "\"value\" : \"xterm-256color\" }, { \"key\" : \"DARWIN_MODE\", \"value\" : \"0\" }, { \"key\" : " + + "\"LANG\", \"value\" : \"en_US.UTF-8\" }, { \"key\" : \"DBUS_SESSION_BUS_ADDRESS\", \"value\" : \"unix:path=/run/user/1000/bus\" }, { \"key\" : \"XDG_SESSION_ID\", \"value\" : \"2\" }, { \"key\"" + + " : \"XDG_SESSION_TYPE\", \"value\" : \"x11\" }, { \"key\" : \"XDG_CURRENT_DESKTOP\", \"value\" : " + + "\"i3\" }, { \"key\" : \"DISPLAY\", \"value\" : \":0\" }, { \"key\" : \"CYGWIN_MODE\", \"value\" : " + + "\"0\" }, { \"key\" : \"COLORTERM\", \"value\" : \"truecolor\" }, { \"key\" : \"_\", \"value\" :" + + " \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre/../bin/java\" }], \"uid\" : 1000," + + " \"username\" : \"user\", \"systemId\" : \"1\" }]}]}"; + assertEquals(expected, response.getContentAsString()); + } + + @Test + public void testTreeInclude() throws InterruptedException, TimeoutException, ExecutionException { + String postUrl = jvmsUrl + "/systems/1"; + String treeUrl = jvmsUrl + "/tree"; + + ContentResponse postResponse = client.newRequest(postUrl).method(HttpMethod.POST) + .content(new StringContentProvider(postData), "application/json").send(); + assertEquals(200, postResponse.getStatus()); + + String query = "?include=jvmId"; + ContentResponse response = client.newRequest(treeUrl + query).method(HttpMethod.GET).send(); + assertEquals(200, response.getStatus()); + String expected = "{ \"response\" : [{\"systemId\":\"1\", \"jvms\":[{ \"jvmId\" : \"jid1\" }]}]}"; + assertEquals(expected, response.getContentAsString()); + } + + @Test + public void testTreeExclude() throws InterruptedException, TimeoutException, ExecutionException { + String postUrl = jvmsUrl + "/systems/1"; + String treeUrl = jvmsUrl + "/tree"; + + ContentResponse postResponse = client.newRequest(postUrl).method(HttpMethod.POST) + .content(new StringContentProvider(postData), "application/json").send(); + assertEquals(200, postResponse.getStatus()); + + String query = "?exclude=systemId"; + ContentResponse response = client.newRequest(treeUrl + query).method(HttpMethod.GET).send(); + assertEquals(200, response.getStatus()); + String expected = "{ \"response\" : [{\"systemId\":\"1\", \"jvms\":[{ \"agentId\" : \"aid\", \"jvmId\" : " + + "\"jid1\", \"jvmPid\" : 1, \"startTime\" : { \"$numberLong\" : \"1495727607481\" }, \"stopTime\" : {" + + " \"$numberLong\" : \"-9223372036854775808\" }, \"javaVersion\" : \"1.8.0_131\", \"javaHome\" : \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre\", \"mainClass\" : \"mc\", " + + "\"javaCommandLine\" : \"j cl\", \"jvmName\" : \"vm\", \"vmArguments\" : \"-Djline.log.jul=true\", " + + "\"jvmInfo\" : \"mixed mode\", \"lastUpdated\" : 0, \"jvmVersion\" : \"25.131-b12\", \"environment\" : " + + "[{ \"key\" : \"PATH\", \"value\" : \"/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin\" }, { \"key\" :" + + " \"XAUTHORITY\", \"value\" : \"/run/user/1000/gdm/Xauthority\" }, { \"key\" : \"GDMSESSION\", \"value\"" + + " : \"i3\" }, { \"key\" : \"fish_greeting\", \"value\" : \"\" }, { \"key\" : \"TERM\", \"value\" : " + + "\"xterm-256color\" }, { \"key\" : \"DARWIN_MODE\", \"value\" : \"0\" }, { \"key\" : \"LANG\", " + + "\"value\" : \"en_US.UTF-8\" }, { \"key\" : \"DBUS_SESSION_BUS_ADDRESS\", \"value\" : " + + "\"unix:path=/run/user/1000/bus\" }, { \"key\" : \"XDG_SESSION_ID\", \"value\" : \"2\" }, { \"key\" :" + + " \"XDG_SESSION_TYPE\", \"value\" : \"x11\" }, { \"key\" : \"XDG_CURRENT_DESKTOP\", \"value\" : \"i3\"" + + " }, { \"key\" : \"DISPLAY\", \"value\" : \":0\" }, { \"key\" : \"CYGWIN_MODE\", \"value\" : \"0\" }, " + + "{ \"key\" : \"COLORTERM\", \"value\" : \"truecolor\" }, { \"key\" : \"_\", \"value\" : " + + "\"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre/../bin/java\" }], \"uid\" : 1000, " + + "\"username\" : \"user\" }]}]}"; + assertEquals(expected, response.getContentAsString()); + } + + @Test + public void testTreeAllLimit() throws InterruptedException, TimeoutException, ExecutionException { + String postUrl = jvmsUrl + "/systems/1"; + String treeUrl = jvmsUrl + "/tree"; + + ContentResponse postResponse = client.newRequest(postUrl).method(HttpMethod.POST) + .content(new StringContentProvider(postData), "application/json").send(); + assertEquals(200, postResponse.getStatus()); + + String query = "?aliveOnly=false&limit=2"; + ContentResponse response = client.newRequest(treeUrl + query).method(HttpMethod.GET).send(); + assertEquals(200, response.getStatus()); + String expected = "{ \"response\" : [{\"systemId\":\"1\", \"jvms\":[{ \"agentId\" : \"aid\", \"jvmId\" : " + + "\"jid1\", \"jvmPid\" : 1, \"startTime\" : { \"$numberLong\" : \"1495727607481\" }, \"stopTime\" : {" + + " \"$numberLong\" : \"-9223372036854775808\" }, \"javaVersion\" : \"1.8.0_131\", \"javaHome\" :" + + " \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre\", \"mainClass\" : \"mc\", " + + "\"javaCommandLine\" : \"j cl\", \"jvmName\" : \"vm\", \"vmArguments\" : \"-Djline.log.jul=true\"," + + " \"jvmInfo\" : \"mixed mode\", \"lastUpdated\" : 0, \"jvmVersion\" : \"25.131-b12\", \"environment\"" + + " : [{ \"key\" : \"PATH\", \"value\" : \"/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin\" }," + + " { \"key\" : \"XAUTHORITY\", \"value\" : \"/run/user/1000/gdm/Xauthority\" }, { \"key\" : " + + "\"GDMSESSION\", \"value\" : \"i3\" }, { \"key\" : \"fish_greeting\", \"value\" : \"\" }, { \"key\" " + + ": \"TERM\", \"value\" : \"xterm-256color\" }, { \"key\" : \"DARWIN_MODE\", \"value\" : \"0\" }, {" + + " \"key\" : \"LANG\", \"value\" : \"en_US.UTF-8\" }, { \"key\" : \"DBUS_SESSION_BUS_ADDRESS\", " + + "\"value\" : \"unix:path=/run/user/1000/bus\" }, { \"key\" : \"XDG_SESSION_ID\", \"value\" : \"2\" }, " + + "{ \"key\" : \"XDG_SESSION_TYPE\", \"value\" : \"x11\" }, { \"key\" : \"XDG_CURRENT_DESKTOP\", " + + "\"value\" : \"i3\" }, { \"key\" : \"DISPLAY\", \"value\" : \":0\" }, { \"key\" : \"CYGWIN_MODE\"," + + " \"value\" : \"0\" }, { \"key\" : \"COLORTERM\", \"value\" : \"truecolor\" }, { \"key\" : \"_\", " + + "\"value\" : \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre/../bin/java\" }], " + + "\"uid\" : 1000, \"username\" : \"user\", \"systemId\" : \"1\" },{ \"agentId\" : \"aid\", \"jvmId\" " + + ": \"jid2\", \"jvmPid\" : 2, \"startTime\" : { \"$numberLong\" : \"1495727607481\" }, \"stopTime\" " + + ": { \"$numberLong\" : \"1495727607482\" }, \"javaVersion\" : \"1.8.0_131\", \"javaHome\" : " + + "\"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre\", \"mainClass\" : \"mc\", " + + "\"javaCommandLine\" : \"j cl\", \"jvmName\" : \"vm\", \"vmArguments\" : \"-Djline.log.jul=true\"," + + " \"jvmInfo\" : \"mixed mode\", \"lastUpdated\" : 0, \"jvmVersion\" : \"25.131-b12\", \"environment\"" + + " : [{ \"key\" : \"PATH\", \"value\" : \"/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin\" }," + + " { \"key\" : \"XAUTHORITY\", \"value\" : \"/run/user/1000/gdm/Xauthority\" }, { \"key\" : " + + "\"GDMSESSION\", \"value\" : \"i3\" }, { \"key\" : \"fish_greeting\", \"value\" : \"\" }, { \"key\" " + + ": \"TERM\", \"value\" : \"xterm-256color\" }, { \"key\" : \"DARWIN_MODE\", \"value\" : \"0\" }," + + " { \"key\" : \"LANG\", \"value\" : \"en_US.UTF-8\" }, { \"key\" : \"DBUS_SESSION_BUS_ADDRESS\", " + + "\"value\" : \"unix:path=/run/user/1000/bus\" }, { \"key\" : \"XDG_SESSION_ID\", \"value\" : \"2\"" + + " }, { \"key\" : \"XDG_SESSION_TYPE\", \"value\" : \"x11\" }, { \"key\" : \"XDG_CURRENT_DESKTOP\"," + + " \"value\" : \"i3\" }, { \"key\" : \"DISPLAY\", \"value\" : \":0\" }, { \"key\" : \"CYGWIN_MODE\"," + + " \"value\" : \"0\" }, { \"key\" : \"COLORTERM\", \"value\" : \"truecolor\" }, { \"key\" : \"_\"," + + " \"value\" : \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre/../bin/java\" }]," + + " \"uid\" : 1000, \"username\" : \"user\", \"systemId\" : \"1\" }]}]}"; + assertEquals(expected, response.getContentAsString()); + } + + @Test + public void testTreeAllOffset() throws InterruptedException, TimeoutException, ExecutionException { + String postUrl = jvmsUrl + "/systems/1"; + String treeUrl = jvmsUrl + "/tree"; + + ContentResponse postResponse = client.newRequest(postUrl).method(HttpMethod.POST) + .content(new StringContentProvider(postData), "application/json").send(); + assertEquals(200, postResponse.getStatus()); + + String query = "?aliveOnly=false&offset=1"; + ContentResponse response = client.newRequest(treeUrl + query).method(HttpMethod.GET).send(); + assertEquals(200, response.getStatus()); + String expected = "{ \"response\" : [{\"systemId\":\"1\", \"jvms\":[{ \"agentId\" : \"aid\", \"jvmId\" :" + + " \"jid2\", \"jvmPid\" : 2, \"startTime\" : { \"$numberLong\" : \"1495727607481\" }, \"stopTime\" :" + + " { \"$numberLong\" : \"1495727607482\" }, \"javaVersion\" : \"1.8.0_131\", \"javaHome\" : " + + "\"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre\", \"mainClass\" : \"mc\", " + + "\"javaCommandLine\" : \"j cl\", \"jvmName\" : \"vm\", \"vmArguments\" : \"-Djline.log.jul=true\", " + + "\"jvmInfo\" : \"mixed mode\", \"lastUpdated\" : 0, \"jvmVersion\" : \"25.131-b12\", \"environment\"" + + " : [{ \"key\" : \"PATH\", \"value\" : \"/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin\" }, { " + + "\"key\" : \"XAUTHORITY\", \"value\" : \"/run/user/1000/gdm/Xauthority\" }, { \"key\" : " + + "\"GDMSESSION\", \"value\" : \"i3\" }, { \"key\" : \"fish_greeting\", \"value\" : \"\" }, { \"key\"" + + " : \"TERM\", \"value\" : \"xterm-256color\" }, { \"key\" : \"DARWIN_MODE\", \"value\" : \"0\" }, {" + + " \"key\" : \"LANG\", \"value\" : \"en_US.UTF-8\" }, { \"key\" : \"DBUS_SESSION_BUS_ADDRESS\", " + + "\"value\" : \"unix:path=/run/user/1000/bus\" }, { \"key\" : \"XDG_SESSION_ID\", \"value\" : \"2\" }," + + " { \"key\" : \"XDG_SESSION_TYPE\", \"value\" : \"x11\" }, { \"key\" : \"XDG_CURRENT_DESKTOP\", " + + "\"value\" : \"i3\" }, { \"key\" : \"DISPLAY\", \"value\" : \":0\" }, { \"key\" : \"CYGWIN_MODE\", " + + "\"value\" : \"0\" }, { \"key\" : \"COLORTERM\", \"value\" : \"truecolor\" }, { \"key\" : \"_\", " + + "\"value\" : \"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-1.b12.fc24.x86_64/jre/../bin/java\" }], " + + "\"uid\" : 1000, \"username\" : \"user\", \"systemId\" : \"1\" }]}]}"; + assertEquals(expected, response.getContentAsString()); + } +}