Mercurial > hg > thermostat-ng > web-gateway
changeset 3:ccb2cb262665
Add base for plugin http handler. Add assembly file to build zip of plugin.
line wrap: on
line diff
--- a/server/core/src/main/java/com/redhat/thermostat/server/core/CoreServer.java Thu Feb 02 15:37:43 2017 -0500 +++ b/server/core/src/main/java/com/redhat/thermostat/server/core/CoreServer.java Mon Feb 06 13:08:04 2017 -0500 @@ -26,8 +26,8 @@ import com.redhat.thermostat.server.core.internal.security.UserStore; import com.redhat.thermostat.server.core.internal.security.auth.proxy.ProxyAuthFilter; import com.redhat.thermostat.server.core.internal.storage.ThermostatMongoStorage; -import com.redhat.thermostat.server.core.internal.web.handler.http.HttpHandler; -import com.redhat.thermostat.server.core.internal.web.handler.storage.MongoStorageHandler; +import com.redhat.thermostat.server.core.internal.web.handler.http.CoreHttpHandler; +import com.redhat.thermostat.server.core.internal.web.handler.storage.MongoCoreStorageHandler; @Component @Service(CoreServer.class) @@ -50,7 +50,7 @@ } private void setupResourceConfig(Map<String, String> serverConfig, Map<String, String> userConfig, ResourceConfig resourceConfig) { - resourceConfig.register(new HttpHandler(new MongoStorageHandler())); + resourceConfig.register(new CoreHttpHandler(new MongoCoreStorageHandler())); resourceConfig.register(new ProxyAuthFilter(new UserStore(userConfig))); resourceConfig.register(new RolesAllowedDynamicFeature()); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/core/src/main/java/com/redhat/thermostat/server/core/internal/web/handler/http/CoreHttpHandler.java Mon Feb 06 13:08:04 2017 -0500 @@ -0,0 +1,106 @@ +/* + * 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.server.core.internal.web.handler.http; + +import javax.annotation.security.RolesAllowed; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +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.container.AsyncResponse; +import javax.ws.rs.container.Suspended; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.SecurityContext; + +import org.glassfish.jersey.server.ChunkedOutput; + +import com.redhat.thermostat.server.core.internal.web.handler.storage.CoreStorageHandler; + +@Path("/api") +@RolesAllowed("user") +public class CoreHttpHandler { + + private final CoreStorageHandler handler; + + public CoreHttpHandler(CoreStorageHandler handler) { + this.handler = handler; + } + + @GET + @Path("agents/{agentId}") + @Produces(MediaType.APPLICATION_JSON) + public void getAgent(@Context SecurityContext securityContext, + @Suspended final AsyncResponse asyncResponse, + @PathParam("agentId") String agentId, + @QueryParam("size") @DefaultValue("1") String count, + @QueryParam("sort") @DefaultValue("-1") String sort) { + handler.getAgent(securityContext, asyncResponse, agentId, count, sort); + } + + @PUT + @Path("agents/{agentId}") + @Produces(MediaType.APPLICATION_JSON) + public Response putAgent(String body, + @Context SecurityContext context) { + return handler.putAgent(body, context); + } + + @GET + @Path("agents/{agentId}/host/cpu") + @Produces(MediaType.APPLICATION_JSON) + public Response getHostCpuInfo(@Context SecurityContext securityContext, + @PathParam("agentId") String agentId, + @QueryParam("size") @DefaultValue("1") String count, + @QueryParam("sort") @DefaultValue("-1") String sort, + @QueryParam("maxTimestamp") String maxTimestamp, + @QueryParam("minTimestamp") String minTimestamp) { + return handler.getHostCpuInfo(securityContext, agentId, count, sort, maxTimestamp, minTimestamp); + } + + @GET + @Path("stream/agents/{agentId}/host/cpu") + @Produces(MediaType.APPLICATION_JSON) + public ChunkedOutput<String> streamHostCpuInfo(@Context SecurityContext securityContext, + @PathParam("agentId") String agentId) { + return handler.streamHostCpuInfo(securityContext, agentId); + } +} \ No newline at end of file
--- a/server/core/src/main/java/com/redhat/thermostat/server/core/internal/web/handler/http/HttpHandler.java Thu Feb 02 15:37:43 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,106 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.server.core.internal.web.handler.http; - -import javax.annotation.security.RolesAllowed; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.GET; -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.container.AsyncResponse; -import javax.ws.rs.container.Suspended; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.SecurityContext; - -import org.glassfish.jersey.server.ChunkedOutput; - -import com.redhat.thermostat.server.core.internal.web.handler.storage.StorageHandler; - -@Path("/api") -@RolesAllowed("user") -public class HttpHandler { - - private final StorageHandler handler; - - public HttpHandler(StorageHandler handler) { - this.handler = handler; - } - - @GET - @Path("agents/{agentId}") - @Produces(MediaType.APPLICATION_JSON) - public void getAgent(@Context SecurityContext securityContext, - @Suspended final AsyncResponse asyncResponse, - @PathParam("agentId") String agentId, - @QueryParam("size") @DefaultValue("1") String count, - @QueryParam("sort") @DefaultValue("-1") String sort) { - handler.getAgent(securityContext, asyncResponse, agentId, count, sort); - } - - @PUT - @Path("agents/{agentId}") - @Produces(MediaType.APPLICATION_JSON) - public Response putAgent(String body, - @Context SecurityContext context) { - return handler.putAgent(body, context); - } - - @GET - @Path("agents/{agentId}/host/cpu") - @Produces(MediaType.APPLICATION_JSON) - public Response getHostCpuInfo(@Context SecurityContext securityContext, - @PathParam("agentId") String agentId, - @QueryParam("size") @DefaultValue("1") String count, - @QueryParam("sort") @DefaultValue("-1") String sort, - @QueryParam("maxTimestamp") String maxTimestamp, - @QueryParam("minTimestamp") String minTimestamp) { - return handler.getHostCpuInfo(securityContext, agentId, count, sort, maxTimestamp, minTimestamp); - } - - @GET - @Path("stream/agents/{agentId}/host/cpu") - @Produces(MediaType.APPLICATION_JSON) - public ChunkedOutput<String> streamHostCpuInfo(@Context SecurityContext securityContext, - @PathParam("agentId") String agentId) { - return handler.streamHostCpuInfo(securityContext, agentId); - } -} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/core/src/main/java/com/redhat/thermostat/server/core/internal/web/handler/http/PluginHttpHandler.java Mon Feb 06 13:08:04 2017 -0500 @@ -0,0 +1,145 @@ +package com.redhat.thermostat.server.core.internal.web.handler.http; + +import javax.annotation.security.RolesAllowed; +import javax.ws.rs.DELETE; +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.container.AsyncResponse; +import javax.ws.rs.container.Suspended; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.SecurityContext; + +import org.glassfish.jersey.server.ChunkedOutput; + +import com.redhat.thermostat.server.core.internal.web.handler.storage.PluginStorageHandler; + +@Path("/plugin") +@RolesAllowed("user") +public class PluginHttpHandler { + private final PluginStorageHandler handler; + + public PluginHttpHandler(PluginStorageHandler handler) { + this.handler = handler; + } + + /** + * Get information about the path. + */ + @GET + @Path("/{path}") + @Produces(MediaType.APPLICATION_JSON) + public void getPath(@Context SecurityContext securityContext, + @Suspended final AsyncResponse asyncResponse, + @PathParam("path") String path) { + handler.getPath(securityContext, asyncResponse, path); + } + + /** + * Add one or more items to the path + */ + @PUT + @Path("/{path}") + @Produces(MediaType.APPLICATION_JSON) + public void putPath(@Context SecurityContext securityContext, + @Suspended final AsyncResponse asyncResponse, + @PathParam("path") String path, + String body) { + handler.putPath(securityContext, asyncResponse, path, body); + } + + /** + * Query the path for items + */ + @POST + @Path("/{path}") + @Produces(MediaType.APPLICATION_JSON) + public void postPath(@Context SecurityContext securityContext, + @Suspended final AsyncResponse asyncResponse, + @PathParam("path") String path, + String body) { + handler.postPath(securityContext, asyncResponse, path, body); + } + + /** + * Delete the entire path + */ + @DELETE + @Path("/{path}") + @Produces(MediaType.APPLICATION_JSON) + public void deletePath(@Context SecurityContext securityContext, + @Suspended final AsyncResponse asyncResponse, + @PathParam("path") String path) { + handler.deletePath(securityContext, asyncResponse, path); + } + + /** + * Stream items from the path + */ + @GET + @Path("stream/{path}") + @Produces(MediaType.APPLICATION_JSON) + public ChunkedOutput<String> streamPath(@Context SecurityContext securityContext, + @Suspended final AsyncResponse asyncResponse, + @PathParam("path") String path) { + return handler.streamPath(securityContext, asyncResponse, path); + } + + /** + * Get the item + */ + @GET + @Path("/{path}/{item}") + @Produces(MediaType.APPLICATION_JSON) + public void getPathItem(@Context SecurityContext securityContext, + @Suspended final AsyncResponse asyncResponse, + @PathParam("path") String path, + @PathParam("item") String item) { + handler.getPathItem(securityContext, asyncResponse, path, item); + } + + /** + * Create or replace the item + */ + @PUT + @Path("/{path}/{item}") + @Produces(MediaType.APPLICATION_JSON) + public void putPathItem(@Context SecurityContext securityContext, + @Suspended final AsyncResponse asyncResponse, + @PathParam("path") String path, + @PathParam("item") String item, + String body) { + handler.putPathItem(securityContext, asyncResponse, path, item, body); + } + + /** + * Query the item + */ + @POST + @Path("/{path}/{item}") + @Produces(MediaType.APPLICATION_JSON) + public void postPathItem(@Context SecurityContext securityContext, + @Suspended final AsyncResponse asyncResponse, + @PathParam("path") String path, + @PathParam("item") String item, + String body) { + handler.postPathItem(securityContext, asyncResponse, path, item, body); + } + + /** + * Delete the item + */ + @DELETE + @Path("/{path}/{item}") + @Produces(MediaType.APPLICATION_JSON) + public void deletePathItem(@Context SecurityContext securityContext, + @Suspended final AsyncResponse asyncResponse, + @PathParam("path") String path, + @PathParam("item") String item) { + handler.deletePathItem(securityContext, asyncResponse, path, item); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/core/src/main/java/com/redhat/thermostat/server/core/internal/web/handler/storage/CoreStorageHandler.java Mon Feb 06 13:08:04 2017 -0500 @@ -0,0 +1,64 @@ +/* + * 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.server.core.internal.web.handler.storage; + +import javax.ws.rs.container.AsyncResponse; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.SecurityContext; + +import org.glassfish.jersey.server.ChunkedOutput; + +public interface CoreStorageHandler { + void getAgent(SecurityContext securityContext, + AsyncResponse asyncResponse, + String agentId, + String count, + String sort); + + Response putAgent(String body, + SecurityContext context); + + Response getHostCpuInfo(SecurityContext securityContext, + String agentId, + String count, + String sort, + String maxTimestamp, + String minTimestamp); + + ChunkedOutput<String> streamHostCpuInfo(SecurityContext securityContext, + String agentId); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/core/src/main/java/com/redhat/thermostat/server/core/internal/web/handler/storage/MongoCoreStorageHandler.java Mon Feb 06 13:08:04 2017 -0500 @@ -0,0 +1,185 @@ +/* + * 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.server.core.internal.web.handler.storage; + +import java.io.IOException; +import java.util.Collections; + +import javax.ws.rs.container.AsyncResponse; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.SecurityContext; + +import org.bson.Document; +import org.bson.conversions.Bson; +import org.glassfish.jersey.server.ChunkedOutput; + +import com.mongodb.BasicDBObject; +import com.mongodb.client.FindIterable; +import com.redhat.thermostat.server.core.internal.storage.ThermostatMongoStorage; +import com.redhat.thermostat.server.core.internal.web.filters.RequestFilters; +import com.redhat.thermostat.server.core.internal.web.json.DocumentBuilder; +import com.redhat.thermostat.server.core.internal.web.request.TimedRequest; +import com.redhat.thermostat.server.core.internal.web.response.MongoResponseBuilder; + +public class MongoCoreStorageHandler implements CoreStorageHandler { + + private final int MAX_MONGO_DOCUMENTS = 5000; + + @Override + public void getAgent(final SecurityContext securityContext, + final AsyncResponse asyncResponse, + final String agentId, + final String count, + final String sort) { + new Thread(new Runnable() { + @Override + public void run() { + if (!ThermostatMongoStorage.isConnected()) { + asyncResponse.resume(Response.status(Response.Status.OK).entity("GET " + agentId + " " + count + " " + sort + " " + securityContext.getUserPrincipal().getName()).build()); + return; + } + + final int limit = Math.min(Integer.valueOf(count), MAX_MONGO_DOCUMENTS); + final int sortOrder = Integer.valueOf(sort); + final String userName = securityContext.getUserPrincipal().getName(); + final Bson filter = RequestFilters.buildGetFilter(agentId, Collections.singletonList(userName)); + + TimedRequest<FindIterable<Document>> timedRequest = new TimedRequest<>(); + + FindIterable<Document> documents = timedRequest.run(new TimedRequest.TimedRunnable<FindIterable<Document>>() { + @Override + public FindIterable<Document> run() { + return ThermostatMongoStorage.getDatabase().getCollection("agents").find(filter).sort(new BasicDBObject("_id", sortOrder)).limit(limit); + } + }); + + asyncResponse.resume(Response.status(Response.Status.OK).entity(MongoResponseBuilder.buildJsonResponse(documents, timedRequest.getElapsed())).build()); + } + }).start(); + } + + @Override + public Response putAgent(String body, + @Context SecurityContext context) { + if (!ThermostatMongoStorage.isConnected()) { + return Response.status(Response.Status.OK).entity("PUT " + context.getUserPrincipal().getName() + "\n\n" + body).build(); + } + + TimedRequest<FindIterable<Document>> timedRequest = new TimedRequest<>(); + + /* + * TODO: Verify body matches expected schema + * TODO: Clean up insertion of tags into JSON body + */ + final Document item = Document.parse(DocumentBuilder.addTags(body, context.getUserPrincipal().getName())); + + timedRequest.run(new TimedRequest.TimedRunnable<FindIterable<Document>>() { + @Override + public FindIterable<Document> run() { + ThermostatMongoStorage.getDatabase().getCollection("agents").insertOne(item); + return null; + } + }); + + return Response.status(Response.Status.OK).entity("PUT successful").build(); + } + + @Override + public Response getHostCpuInfo(SecurityContext securityContext, + String agentId, + String count, + String sort, + String maxTimestamp, + String minTimestamp) { + if (!ThermostatMongoStorage.isConnected()) { + return Response.status(Response.Status.OK).entity(agentId + count + sort + maxTimestamp + minTimestamp).build(); + } + + final int size = Integer.valueOf(count); + + final String userName = securityContext.getUserPrincipal().getName(); + final Bson filter = RequestFilters.buildGetFilter(agentId, Collections.singletonList(userName), maxTimestamp, minTimestamp); + + final int sortOrder = Integer.valueOf(sort); + + TimedRequest<FindIterable<Document>> request = new TimedRequest<>(); + FindIterable<Document> documents = request.run(new TimedRequest.TimedRunnable<FindIterable<Document>>() { + @Override + public FindIterable<Document> run() { + return ThermostatMongoStorage.getDatabase().getCollection("cpu-stats").find(filter).sort(new BasicDBObject("_id", sortOrder)).limit(size); + } + }); + + return Response.status(Response.Status.OK).entity(MongoResponseBuilder.buildJsonResponse(documents, request.getElapsed())).build(); + } + + @Override + public ChunkedOutput<String> streamHostCpuInfo(SecurityContext securityContext, String agentId) { + final ChunkedOutput<String> output = new ChunkedOutput<>(String.class, "\r\n"); + + new Thread() { + public void run() { + try { + + while (true) { + TimedRequest<FindIterable<Document>> request = new TimedRequest<>(); + FindIterable<Document> documents = request.run(new TimedRequest.TimedRunnable<FindIterable<Document>>() { + @Override + public FindIterable<Document> run() { + return ThermostatMongoStorage.getDatabase().getCollection("cpu-stats").find().sort(new BasicDBObject("_id", -1)).limit(1); + } + }); + output.write(MongoResponseBuilder.buildJsonResponse(documents, request.getElapsed())); + + Thread.sleep(1000L); + } + } catch (IOException | InterruptedException e) { + // An IOException occurs when reader closes the connection + } finally { + try { + output.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + }.start(); + + return output; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/core/src/main/java/com/redhat/thermostat/server/core/internal/web/handler/storage/MongoPluginStorageHandler.java Mon Feb 06 13:08:04 2017 -0500 @@ -0,0 +1,53 @@ +package com.redhat.thermostat.server.core.internal.web.handler.storage; + +import javax.ws.rs.container.AsyncResponse; +import javax.ws.rs.core.SecurityContext; + +import org.glassfish.jersey.server.ChunkedOutput; + +public class MongoPluginStorageHandler implements PluginStorageHandler { + @Override + public void getPath(SecurityContext securityContext, AsyncResponse asyncResponse, String path) { + + } + + @Override + public void putPath(SecurityContext securityContext, AsyncResponse asyncResponse, String path, String body) { + + } + + @Override + public void postPath(SecurityContext securityContext, AsyncResponse asyncResponse, String path, String body) { + + } + + @Override + public void deletePath(SecurityContext securityContext, AsyncResponse asyncResponse, String path) { + + } + + @Override + public ChunkedOutput<String> streamPath(SecurityContext securityContext, AsyncResponse asyncResponse, String path) { + return null; + } + + @Override + public void getPathItem(SecurityContext securityContext, AsyncResponse asyncResponse, String path, String item) { + + } + + @Override + public void putPathItem(SecurityContext securityContext, AsyncResponse asyncResponse, String path, String item, String body) { + + } + + @Override + public void postPathItem(SecurityContext securityContext, AsyncResponse asyncResponse, String path, String item, String body) { + + } + + @Override + public void deletePathItem(SecurityContext securityContext, AsyncResponse asyncResponse, String path, String item) { + + } +}
--- a/server/core/src/main/java/com/redhat/thermostat/server/core/internal/web/handler/storage/MongoStorageHandler.java Thu Feb 02 15:37:43 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,185 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.server.core.internal.web.handler.storage; - -import java.io.IOException; -import java.util.Collections; - -import javax.ws.rs.container.AsyncResponse; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.SecurityContext; - -import org.bson.Document; -import org.bson.conversions.Bson; -import org.glassfish.jersey.server.ChunkedOutput; - -import com.mongodb.BasicDBObject; -import com.mongodb.client.FindIterable; -import com.redhat.thermostat.server.core.internal.storage.ThermostatMongoStorage; -import com.redhat.thermostat.server.core.internal.web.filters.RequestFilters; -import com.redhat.thermostat.server.core.internal.web.json.DocumentBuilder; -import com.redhat.thermostat.server.core.internal.web.request.TimedRequest; -import com.redhat.thermostat.server.core.internal.web.response.MongoResponseBuilder; - -public class MongoStorageHandler implements StorageHandler { - - private final int MAX_MONGO_DOCUMENTS = 5000; - - @Override - public void getAgent(final SecurityContext securityContext, - final AsyncResponse asyncResponse, - final String agentId, - final String count, - final String sort) { - new Thread(new Runnable() { - @Override - public void run() { - if (!ThermostatMongoStorage.isConnected()) { - asyncResponse.resume(Response.status(Response.Status.OK).entity("GET " + agentId + " " + count + " " + sort + " " + securityContext.getUserPrincipal().getName()).build()); - return; - } - - final int limit = Math.min(Integer.valueOf(count), MAX_MONGO_DOCUMENTS); - final int sortOrder = Integer.valueOf(sort); - final String userName = securityContext.getUserPrincipal().getName(); - final Bson filter = RequestFilters.buildGetFilter(agentId, Collections.singletonList(userName)); - - TimedRequest<FindIterable<Document>> timedRequest = new TimedRequest<>(); - - FindIterable<Document> documents = timedRequest.run(new TimedRequest.TimedRunnable<FindIterable<Document>>() { - @Override - public FindIterable<Document> run() { - return ThermostatMongoStorage.getDatabase().getCollection("agents").find(filter).sort(new BasicDBObject("_id", sortOrder)).limit(limit); - } - }); - - asyncResponse.resume(Response.status(Response.Status.OK).entity(MongoResponseBuilder.buildJsonResponse(documents, timedRequest.getElapsed())).build()); - } - }).start(); - } - - @Override - public Response putAgent(String body, - @Context SecurityContext context) { - if (!ThermostatMongoStorage.isConnected()) { - return Response.status(Response.Status.OK).entity("PUT " + context.getUserPrincipal().getName() + "\n\n" + body).build(); - } - - TimedRequest<FindIterable<Document>> timedRequest = new TimedRequest<>(); - - /* - * TODO: Verify body matches expected schema - * TODO: Clean up insertion of tags into JSON body - */ - final Document item = Document.parse(DocumentBuilder.addTags(body, context.getUserPrincipal().getName())); - - timedRequest.run(new TimedRequest.TimedRunnable<FindIterable<Document>>() { - @Override - public FindIterable<Document> run() { - ThermostatMongoStorage.getDatabase().getCollection("agents").insertOne(item); - return null; - } - }); - - return Response.status(Response.Status.OK).entity("PUT successful").build(); - } - - @Override - public Response getHostCpuInfo(SecurityContext securityContext, - String agentId, - String count, - String sort, - String maxTimestamp, - String minTimestamp) { - if (!ThermostatMongoStorage.isConnected()) { - return Response.status(Response.Status.OK).entity(agentId + count + sort + maxTimestamp + minTimestamp).build(); - } - - final int size = Integer.valueOf(count); - - final String userName = securityContext.getUserPrincipal().getName(); - final Bson filter = RequestFilters.buildGetFilter(agentId, Collections.singletonList(userName), maxTimestamp, minTimestamp); - - final int sortOrder = Integer.valueOf(sort); - - TimedRequest<FindIterable<Document>> request = new TimedRequest<>(); - FindIterable<Document> documents = request.run(new TimedRequest.TimedRunnable<FindIterable<Document>>() { - @Override - public FindIterable<Document> run() { - return ThermostatMongoStorage.getDatabase().getCollection("cpu-stats").find(filter).sort(new BasicDBObject("_id", sortOrder)).limit(size); - } - }); - - return Response.status(Response.Status.OK).entity(MongoResponseBuilder.buildJsonResponse(documents, request.getElapsed())).build(); - } - - @Override - public ChunkedOutput<String> streamHostCpuInfo(SecurityContext securityContext, String agentId) { - final ChunkedOutput<String> output = new ChunkedOutput<>(String.class, "\r\n"); - - new Thread() { - public void run() { - try { - - while (true) { - TimedRequest<FindIterable<Document>> request = new TimedRequest<>(); - FindIterable<Document> documents = request.run(new TimedRequest.TimedRunnable<FindIterable<Document>>() { - @Override - public FindIterable<Document> run() { - return ThermostatMongoStorage.getDatabase().getCollection("cpu-stats").find().sort(new BasicDBObject("_id", -1)).limit(1); - } - }); - output.write(MongoResponseBuilder.buildJsonResponse(documents, request.getElapsed())); - - Thread.sleep(1000L); - } - } catch (IOException | InterruptedException e) { - // An IOException occurs when reader closes the connection - } finally { - try { - output.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - }.start(); - - return output; - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/core/src/main/java/com/redhat/thermostat/server/core/internal/web/handler/storage/PluginStorageHandler.java Mon Feb 06 13:08:04 2017 -0500 @@ -0,0 +1,52 @@ +package com.redhat.thermostat.server.core.internal.web.handler.storage; + +import javax.ws.rs.container.AsyncResponse; +import javax.ws.rs.core.SecurityContext; + +import org.glassfish.jersey.server.ChunkedOutput; + +public interface PluginStorageHandler { + void getPath(SecurityContext securityContext, + AsyncResponse asyncResponse, + String path); + + void putPath(SecurityContext securityContext, + AsyncResponse asyncResponse, + String path, + String body); + + void postPath(SecurityContext securityContext, + AsyncResponse asyncResponse, + String path, + String body); + + void deletePath(SecurityContext securityContext, + AsyncResponse asyncResponse, + String path); + + ChunkedOutput<String> streamPath(SecurityContext securityContext, + AsyncResponse asyncResponse, + String path); + + void getPathItem(SecurityContext securityContext, + AsyncResponse asyncResponse, + String path, + String item); + + void putPathItem(SecurityContext securityContext, + AsyncResponse asyncResponse, + String path, + String item, + String body); + + void postPathItem(SecurityContext securityContext, + AsyncResponse asyncResponse, + String path, + String item, + String body); + + void deletePathItem(SecurityContext securityContext, + AsyncResponse asyncResponse, + String path, + String item); +}
--- a/server/core/src/main/java/com/redhat/thermostat/server/core/internal/web/handler/storage/StorageHandler.java Thu Feb 02 15:37:43 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <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.server.core.internal.web.handler.storage; - -import javax.ws.rs.container.AsyncResponse; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.SecurityContext; - -import org.glassfish.jersey.server.ChunkedOutput; - -public interface StorageHandler { - void getAgent(SecurityContext securityContext, - AsyncResponse asyncResponse, - String agentId, - String count, - String sort); - - Response putAgent(String body, - SecurityContext context); - - Response getHostCpuInfo(SecurityContext securityContext, - String agentId, - String count, - String sort, - String maxTimestamp, - String minTimestamp); - - ChunkedOutput<String> streamHostCpuInfo(SecurityContext securityContext, - String agentId); -}
--- a/server/distribution/pom.xml Thu Feb 02 15:37:43 2017 -0500 +++ b/server/distribution/pom.xml Mon Feb 06 13:08:04 2017 -0500 @@ -57,17 +57,10 @@ <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> - <dependencies> - <dependency> - <groupId>com.redhat.thermostat</groupId> - <artifactId>thermostat-assembly</artifactId> - <version>${project.version}</version> - </dependency> - </dependencies> <configuration> - <descriptorRefs> - <descriptorRef>plugin-assembly</descriptorRef> - </descriptorRefs> + <descriptors> + <descriptor>src/assembly/src.xml</descriptor> + </descriptors> <appendAssemblyId>false</appendAssemblyId> </configuration> <executions>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/distribution/src/assembly/src.xml Mon Feb 06 13:08:04 2017 -0500 @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd"> + <id>plugin-assembly</id> + <formats> + <format>zip</format> + </formats> + <baseDirectory>/</baseDirectory> + <includeBaseDirectory>true</includeBaseDirectory> + + + <dependencySets> + <dependencySet> + <useProjectArtifact>false</useProjectArtifact> + <useTransitiveDependencies>false</useTransitiveDependencies> + <outputDirectory>/plugins/${thermostat.plugin}</outputDirectory> + </dependencySet> + </dependencySets> + <files> + <file> + <source>thermostat-plugin.xml</source> + <outputDirectory>/plugins/${thermostat.plugin}</outputDirectory> + <filtered>true</filtered> + </file> + </files> +</assembly> +