Mercurial > hg > thermostat-ng > web-gateway
changeset 158:c0199757fe20
Add static resource handler for web-client.
Reviewed-by: jkang
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-May/023164.html
author | Severin Gehwolf <sgehwolf@redhat.com> |
---|---|
date | Wed, 17 May 2017 19:39:08 +0200 |
parents | e34d462cc342 |
children | e0c80817fd11 |
files | common/core/src/main/java/com/redhat/thermostat/gateway/common/core/config/GlobalConfiguration.java distribution/src/etc/global-config.properties server/src/main/java/com/redhat/thermostat/gateway/server/CoreServerBuilder.java server/src/main/java/com/redhat/thermostat/gateway/server/webclient/StaticAssetsHandler.java server/src/test/java/com/redhat/thermostat/gateway/server/CoreServerBuilderTest.java server/src/test/java/com/redhat/thermostat/gateway/server/webclient/StaticAssetsHandlerFactory.java services/commands/src/test/java/com/redhat/thermostat/service/commands/http/handlers/AuthBasicCoreServerTest.java |
diffstat | 7 files changed, 273 insertions(+), 32 deletions(-) [+] |
line wrap: on
line diff
--- a/common/core/src/main/java/com/redhat/thermostat/gateway/common/core/config/GlobalConfiguration.java Tue May 23 14:46:14 2017 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/gateway/common/core/config/GlobalConfiguration.java Wed May 17 19:39:08 2017 +0200 @@ -70,6 +70,17 @@ * */ SERVICES, + /** + * Specifies whether or not the swagger UI handler should get + * created under context path /doc + */ + WITH_SWAGGER_UI, + /** + * Specifies whether or not a static resource handler, at + * context path /web-client, for built web-client assets + * should get created. + */ + WITH_WEB_CLIENT } }
--- a/distribution/src/etc/global-config.properties Tue May 23 14:46:14 2017 +0200 +++ b/distribution/src/etc/global-config.properties Wed May 17 19:39:08 2017 +0200 @@ -5,3 +5,14 @@ # The file specifying which services to deploy in the # servlet container. properties|SERVICES=services.properties +# +# Specifies whether or not the swagger UI handler should get +# created under context path /doc +# +WITH_SWAGGER_UI=true +# +# Specifies whether or not a static resource handler, at +# context path /web-client, for built web-client assets +# should get created. +# +WITH_WEB_CLIENT=true
--- a/server/src/main/java/com/redhat/thermostat/gateway/server/CoreServerBuilder.java Tue May 23 14:46:14 2017 +0200 +++ b/server/src/main/java/com/redhat/thermostat/gateway/server/CoreServerBuilder.java Wed May 17 19:39:08 2017 +0200 @@ -52,16 +52,30 @@ import com.redhat.thermostat.gateway.common.core.config.Configuration; import com.redhat.thermostat.gateway.common.core.config.GlobalConfiguration; +import com.redhat.thermostat.gateway.common.core.config.GlobalConfiguration.ConfigurationKey; import com.redhat.thermostat.gateway.server.apidoc.SwaggerUiHandler; import com.redhat.thermostat.gateway.server.services.CoreService; import com.redhat.thermostat.gateway.server.services.CoreServiceBuilder; +import com.redhat.thermostat.gateway.server.webclient.StaticAssetsHandler; public class CoreServerBuilder { - private Server server = new Server(); + private final SwaggerUiHandler swaggerHandler; + private final StaticAssetsHandler staticAssetsHandler; + private final Server server = new Server(); private CoreServiceBuilder coreServiceBuilder; private Configuration serverConfig; + public CoreServerBuilder() { + this(new SwaggerUiHandler(), new StaticAssetsHandler()); + } + + // package-private for test-overrides + CoreServerBuilder(SwaggerUiHandler swaggerHandler, StaticAssetsHandler staticHandler) { + this.staticAssetsHandler = staticHandler; + this.swaggerHandler = swaggerHandler; + } + public CoreServerBuilder setServiceBuilder(CoreServiceBuilder builder) { this.coreServiceBuilder = builder; return this; @@ -94,16 +108,31 @@ } } - // Set up Swagger UI-based API doc handler together with the service handlers. - // It'll be able to generate API docs based on any URL accessible - // swagger spec (swagger.json/swagger.yaml). Hence, we set this up - // once in the deploying server and make the swagger spec available - // in the services themselves - ContextHandler swaggerHandler = new SwaggerUiHandler().createSwaggerResourceHandler(); - contextHandlerCollection.addHandler(swaggerHandler); + Map<String, Object> config = serverConfig.asMap(); + if (isEnabled(config, ConfigurationKey.WITH_SWAGGER_UI)) { + // Set up Swagger UI-based API doc handler together with the service handlers. + // It'll be able to generate API docs based on any URL accessible + // swagger spec (swagger.json/swagger.yaml). Hence, we set this up + // once in the deploying server and make the swagger spec available + // in the services themselves + ContextHandler swHandler = swaggerHandler.createSwaggerResourceHandler(); + contextHandlerCollection.addHandler(swHandler); + } + + if (isEnabled(config, ConfigurationKey.WITH_WEB_CLIENT)) { + // Set up a static resource handler which serves static assets + // via /web-client context path + ContextHandler webClientHandler = staticAssetsHandler.create(); + contextHandlerCollection.addHandler(webClientHandler); + } + server.setHandler(contextHandlerCollection); } + private boolean isEnabled(Map<String, Object> config, ConfigurationKey configKey) { + return Boolean.parseBoolean((String)config.get(configKey.name())); + } + private void setupConnector() { ServerConnector httpConnector = new ServerConnector(server);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/main/java/com/redhat/thermostat/gateway/server/webclient/StaticAssetsHandler.java Wed May 17 19:39:08 2017 +0200 @@ -0,0 +1,87 @@ +/* + * 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.server.webclient; + +import java.io.File; + +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.server.handler.ResourceHandler; + +import com.redhat.thermostat.gateway.common.core.servlet.GlobalConstants; + +public class StaticAssetsHandler { + + private static final String WEB_CLIENT_ASSETS_FOLDER = "web-client"; + private static final String WEB_CLIENT_CONTEXT_PATH = "/" + WEB_CLIENT_ASSETS_FOLDER; + + private final EnvHelper envHelper; + + public StaticAssetsHandler() { + this(new EnvHelper()); + } + + // package-private for test-overrides + StaticAssetsHandler(EnvHelper helper) { + this.envHelper = helper; + } + + public ContextHandler create() { + ContextHandler apiContext = new ContextHandler(); + apiContext.setContextPath(WEB_CLIENT_CONTEXT_PATH); + ResourceHandler resourceHandler = new ResourceHandler(); + resourceHandler.setDirectoriesListed(false); + resourceHandler.setWelcomeFiles(new String[]{ "index.html" }); + File webClientDir = getWebClientAssetsDir(); + resourceHandler.setResourceBase(webClientDir.getAbsolutePath()); + apiContext.setHandler(resourceHandler); + return apiContext; + } + + private File getWebClientAssetsDir() { + String gatewayHome = envHelper.getEnv(GlobalConstants.GATEWAY_HOME_ENV); + if (gatewayHome == null) { + throw new RuntimeException("THERMOSTAT_GATEWAY_HOME environment variable not set"); + } + return new File(gatewayHome, WEB_CLIENT_ASSETS_FOLDER); + } + + public static class EnvHelper { + public String getEnv(String var) { + return System.getenv(var); + } + } +}
--- a/server/src/test/java/com/redhat/thermostat/gateway/server/CoreServerBuilderTest.java Tue May 23 14:46:14 2017 +0200 +++ b/server/src/test/java/com/redhat/thermostat/gateway/server/CoreServerBuilderTest.java Wed May 17 19:39:08 2017 +0200 @@ -54,13 +54,86 @@ import com.redhat.thermostat.gateway.common.core.config.Configuration; import com.redhat.thermostat.gateway.common.core.config.GlobalConfiguration; +import com.redhat.thermostat.gateway.server.apidoc.SwaggerUiHandler; import com.redhat.thermostat.gateway.server.services.CoreService; import com.redhat.thermostat.gateway.server.services.CoreServiceBuilder; +import com.redhat.thermostat.gateway.server.webclient.StaticAssetsHandler; +import com.redhat.thermostat.gateway.server.webclient.StaticAssetsHandler.EnvHelper; +import com.redhat.thermostat.gateway.server.webclient.StaticAssetsHandlerFactory; public class CoreServerBuilderTest { + /** + * Tests building without optional handlers, like swagger-ui or web-client + * static resources. + */ @Test - public void testBuild() { + public void testBuildNoDefaultHandlers() { + CoreServiceBuilder serviceBuilder = getMockServiceBuilder(); + + Map<String, Object> configMap = new HashMap<>(); + String ip = "127.0.0.1"; + String port = "8080"; + configMap.put(GlobalConfiguration.ConfigurationKey.IP.name(), ip); + configMap.put(GlobalConfiguration.ConfigurationKey.PORT.name(), port); + configMap.put(GlobalConfiguration.ConfigurationKey.WITH_SWAGGER_UI.name(), Boolean.FALSE.toString()); + configMap.put(GlobalConfiguration.ConfigurationKey.WITH_WEB_CLIENT.name(), Boolean.FALSE.toString()); + Configuration configuration = getMockConfiguration(configMap); + + CoreServerBuilder builder = new CoreServerBuilder(); + builder.setServerConfiguration(configuration); + builder.setServiceBuilder(serviceBuilder); + + Server server = builder.build(); + + ContextHandlerCollection handler = (ContextHandlerCollection) server.getHandler(); + // Expects 1 handlers, 1 service mocked. Others disabled by config + assertEquals(1, handler.getHandlers().length); + + ServerConnector connector = (ServerConnector) server.getConnectors()[0]; + assertEquals(connector.getPort(), Integer.parseInt(port)); + assertEquals(connector.getHost(), ip); + } + + /** + * Tests building *with* optional handlers, like swagger-ui or web-client + * static resources. + */ + @Test + public void testBuildWithDefaultHandlers() { + CoreServiceBuilder serviceBuilder = getMockServiceBuilder(); + + Map<String, Object> configMap = new HashMap<>(); + String ip = "127.0.0.1"; + String port = "8080"; + configMap.put(GlobalConfiguration.ConfigurationKey.IP.name(), ip); + configMap.put(GlobalConfiguration.ConfigurationKey.PORT.name(), port); + configMap.put(GlobalConfiguration.ConfigurationKey.WITH_SWAGGER_UI.name(), Boolean.TRUE.toString()); + configMap.put(GlobalConfiguration.ConfigurationKey.WITH_WEB_CLIENT.name(), Boolean.TRUE.toString()); + Configuration configuration = getMockConfiguration(configMap); + + SwaggerUiHandler swaggerHandler = new SwaggerUiHandler(); + EnvHelper envHelper = mock(EnvHelper.class); + when(envHelper.getEnv(any(String.class))).thenReturn("/fake-gw-home"); + StaticAssetsHandler staticAssetsHandler = new StaticAssetsHandlerFactory().create(envHelper); + CoreServerBuilder builder = new CoreServerBuilder(swaggerHandler, staticAssetsHandler); + builder.setServerConfiguration(configuration); + builder.setServiceBuilder(serviceBuilder); + + Server server = builder.build(); + + ContextHandlerCollection handler = (ContextHandlerCollection) server.getHandler(); + // Expects 3 handlers, 1 service mocked above, 1 swagger ui handler, 1 static resource handler + assertEquals(3, handler.getHandlers().length); + } + + private Configuration getMockConfiguration(Map<String, Object> configMap) { + Configuration configuration = mock(Configuration.class); + when(configuration.asMap()).thenReturn(configMap); + return configuration; + } + + private CoreServiceBuilder getMockServiceBuilder() { CoreServiceBuilder serviceBuilder = mock(CoreServiceBuilder.class); List<CoreService> serviceList = new ArrayList<>(); CoreService service = mock(CoreService.class); @@ -69,28 +142,6 @@ when(service.createServletContextHandler(any(Server.class))).thenReturn(servletContextHandler); serviceList.add(service); when(serviceBuilder.build()).thenReturn(serviceList); - - Map<String, Object> configMap = new HashMap<>(); - String ip = "127.0.0.1"; - String port = "8080"; - configMap.put(GlobalConfiguration.ConfigurationKey.IP.name(), ip); - configMap.put(GlobalConfiguration.ConfigurationKey.PORT.name(), port); - Configuration configuration = mock(Configuration.class); - when(configuration.asMap()).thenReturn(configMap); - - - CoreServerBuilder builder = new CoreServerBuilder(); - builder.setServerConfiguration(configuration); - builder.setServiceBuilder(serviceBuilder); - - Server server = builder.build(); - - ContextHandlerCollection handler = (ContextHandlerCollection) server.getHandler(); - // Expects 2 handlers, 1 service mocked above and 1 swagger ui handler - assertEquals(2, handler.getHandlers().length); - - ServerConnector connector = (ServerConnector) server.getConnectors()[0]; - assertEquals(connector.getPort(), Integer.parseInt(port)); - assertEquals(connector.getHost(), ip); + return serviceBuilder; } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/test/java/com/redhat/thermostat/gateway/server/webclient/StaticAssetsHandlerFactory.java Wed May 17 19:39:08 2017 +0200 @@ -0,0 +1,50 @@ +/* + * 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.server.webclient; + +import com.redhat.thermostat.gateway.server.webclient.StaticAssetsHandler.EnvHelper; + +/** + * Test artifact to create a handler with a mock env helper + * + */ +public class StaticAssetsHandlerFactory { + + public StaticAssetsHandler create(EnvHelper helper) { + return new StaticAssetsHandler(helper); + } +}
--- a/services/commands/src/test/java/com/redhat/thermostat/service/commands/http/handlers/AuthBasicCoreServerTest.java Tue May 23 14:46:14 2017 +0200 +++ b/services/commands/src/test/java/com/redhat/thermostat/service/commands/http/handlers/AuthBasicCoreServerTest.java Wed May 17 19:39:08 2017 +0200 @@ -107,6 +107,8 @@ Map<String, Object> config = new HashMap<>(); config.put(GlobalConfiguration.ConfigurationKey.IP.name(), TEST_ADDRESS); config.put(GlobalConfiguration.ConfigurationKey.PORT.name(), Integer.toString(TEST_PORT)); + config.put(GlobalConfiguration.ConfigurationKey.WITH_SWAGGER_UI.name(), Boolean.FALSE.toString()); + config.put(GlobalConfiguration.ConfigurationKey.WITH_WEB_CLIENT.name(), Boolean.FALSE.toString()); return config; } });