- Added multiple alternatives for server modules with different servlet engines.
Project: http://git-wip-us.apache.org/repos/asf/incubator-edgent/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-edgent/commit/d07dff67 Tree: http://git-wip-us.apache.org/repos/asf/incubator-edgent/tree/d07dff67 Diff: http://git-wip-us.apache.org/repos/asf/incubator-edgent/diff/d07dff67 Branch: refs/heads/feature/alternate-servlet-engines Commit: d07dff673edb8d4c89cefe11b746130d55be7b83 Parents: 572cde0 Author: Christofer Dutz <christofer.d...@c-ware.de> Authored: Wed Aug 1 14:55:55 2018 +0200 Committer: Christofer Dutz <christofer.d...@c-ware.de> Committed: Wed Aug 1 14:55:55 2018 +0200 ---------------------------------------------------------------------- DEVELOPMENT.md | 2 +- JAVA_SUPPORT.md | 2 +- api/execution/pom.xml | 1 - connectors/csv/pom.xml | 1 - connectors/jdbc/pom.xml | 2 +- connectors/kafka/pom.xml | 4 +- connectors/websocket-jetty/pom.xml | 2 +- connectors/websocket-server/pom.xml | 2 +- console/pom.xml | 4 +- console/server-jetty/pom.xml | 160 +++++++++++++++ .../edgent/console/server/HttpServer.java | 174 ++++++++++++++++ .../edgent/console/server/ServerUtil.java | 84 ++++++++ .../src/main/remote-resources/META-INF/LICENSE | 42 ++++ .../src/main/remote-resources/META-INF/NOTICE | 28 +++ .../test/console/server/HttpServerPortTest.java | 58 ++++++ .../test/console/server/HttpServerTest.java | 172 ++++++++++++++++ .../test/console/server/ServerUtilTest.java | 43 ++++ console/server-tomcat/pom.xml | 85 ++++++++ .../edgent/console/server/HttpServer.java | 169 ++++++++++++++++ .../src/main/remote-resources/META-INF/LICENSE | 42 ++++ .../src/main/remote-resources/META-INF/NOTICE | 28 +++ .../test/console/server/HttpServerPortTest.java | 58 ++++++ .../test/console/server/HttpServerTest.java | 172 ++++++++++++++++ console/server-undertow/pom.xml | 84 ++++++++ .../edgent/console/server/HttpServer.java | 189 ++++++++++++++++++ .../src/main/remote-resources/META-INF/LICENSE | 42 ++++ .../src/main/remote-resources/META-INF/NOTICE | 28 +++ .../test/console/server/HttpServerPortTest.java | 58 ++++++ .../test/console/server/HttpServerTest.java | 172 ++++++++++++++++ console/server/pom.xml | 160 --------------- .../edgent/console/server/HttpServer.java | 174 ---------------- .../edgent/console/server/ServerUtil.java | 84 -------- .../src/main/remote-resources/META-INF/LICENSE | 42 ---- .../src/main/remote-resources/META-INF/NOTICE | 28 --- .../test/console/server/HttpServerPortTest.java | 58 ------ .../test/console/server/HttpServerTest.java | 172 ---------------- .../test/console/server/ServerUtilTest.java | 43 ---- console/servlets/pom.xml | 8 + distribution/pom.xml | 4 +- platforms/android/android/hardware/pom.xml | 11 ++ platforms/android/android/topology/pom.xml | 11 ++ platforms/android/api/execution/pom.xml | 1 - platforms/android/connectors/csv/pom.xml | 1 - platforms/android/connectors/kafka/pom.xml | 4 +- .../android/connectors/websocket-jetty/pom.xml | 2 +- .../android/connectors/websocket-server/pom.xml | 2 +- platforms/android/distribution/pom.xml | 4 +- platforms/android/pom.xml | 2 +- platforms/java7/api/execution/pom.xml | 1 - platforms/java7/connectors/csv/pom.xml | 1 - platforms/java7/connectors/jdbc/pom.xml | 23 ++- platforms/java7/connectors/kafka/pom.xml | 4 +- .../java7/connectors/websocket-jetty/pom.xml | 2 +- .../java7/connectors/websocket-server/pom.xml | 2 +- platforms/java7/console/pom.xml | 4 +- platforms/java7/console/server-jetty/pom.xml | 198 +++++++++++++++++++ .../src/main/remote-resources/META-INF/LICENSE | 41 ++++ .../src/main/remote-resources/META-INF/NOTICE | 28 +++ platforms/java7/console/server-tomcat/pom.xml | 145 ++++++++++++++ .../src/main/remote-resources/META-INF/LICENSE | 41 ++++ .../src/main/remote-resources/META-INF/NOTICE | 28 +++ platforms/java7/console/server-undertow/pom.xml | 140 +++++++++++++ .../src/main/remote-resources/META-INF/LICENSE | 41 ++++ .../src/main/remote-resources/META-INF/NOTICE | 28 +++ platforms/java7/console/server/pom.xml | 198 ------------------- .../src/main/remote-resources/META-INF/LICENSE | 41 ---- .../src/main/remote-resources/META-INF/NOTICE | 28 --- platforms/java7/console/servlets/pom.xml | 2 + platforms/java7/distribution/pom.xml | 4 +- platforms/java7/pom.xml | 2 +- platforms/java7/providers/development/pom.xml | 2 +- platforms/java7/test/svt/pom.xml | 2 +- pom.xml | 46 ++++- providers/development/pom.xml | 2 +- test/svt/pom.xml | 2 +- 75 files changed, 2707 insertions(+), 1068 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/DEVELOPMENT.md ---------------------------------------------------------------------- diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index e7b71f8..c69f2ae 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -446,7 +446,7 @@ information may help to better understand it. license text as described above. Its own LICENSE and NOTICE is copied from the respective files in its `src/main/remote-resources/META-INF`. <b>There are copies of those in under the java7 platform as well.</b> - * `edgent-console-server:jar` bundles the console-servlets war and as such + * `edgent-console-server-jetty:jar` bundles the console-servlets war and as such requires the same LICENSE/NOTICE/licenses treatment as the servlets war. <b>There are copies of its LICENSE/NOTICE in its `src/main/remote-resources/META-INF`. There are copies of those in under the java7 platform as well.</b> http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/JAVA_SUPPORT.md ---------------------------------------------------------------------- diff --git a/JAVA_SUPPORT.md b/JAVA_SUPPORT.md index 38555b3..fb770fb 100644 --- a/JAVA_SUPPORT.md +++ b/JAVA_SUPPORT.md @@ -145,7 +145,7 @@ and its features are supported in that environment. | Jar | Java 8 SE | Java 7 SE | Android | Notes | |-----------------------------------|-----------|-----------|---------|-------| -|edgent-console-server-<ver>.jar | yes | yes | no | Uses JMX, Servlet | +|edgent-console-server-jetty-<ver>.jar | yes | yes | no | Uses JMX, Servlet | |edgent-console-servlets-<ver>.war | yes | yes | no | Uses JMX, Servlet | ### Android http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/api/execution/pom.xml ---------------------------------------------------------------------- diff --git a/api/execution/pom.xml b/api/execution/pom.xml index 0502503..50ff3a3 100644 --- a/api/execution/pom.xml +++ b/api/execution/pom.xml @@ -43,7 +43,6 @@ <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> - <version>2.8.0</version> </dependency> </dependencies> http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/connectors/csv/pom.xml ---------------------------------------------------------------------- diff --git a/connectors/csv/pom.xml b/connectors/csv/pom.xml index 2723b5c..899b5d1 100644 --- a/connectors/csv/pom.xml +++ b/connectors/csv/pom.xml @@ -34,7 +34,6 @@ <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> - <version>2.8.0</version> </dependency> <dependency> http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/connectors/jdbc/pom.xml ---------------------------------------------------------------------- diff --git a/connectors/jdbc/pom.xml b/connectors/jdbc/pom.xml index 5e7ca2b..b2f1644 100644 --- a/connectors/jdbc/pom.xml +++ b/connectors/jdbc/pom.xml @@ -103,7 +103,7 @@ <dependency> <groupId>org.apache.derby</groupId> <artifactId>derby</artifactId> - <version>10.13.1.1</version> + <version>10.14.2.0</version> <scope>test</scope> </dependency> </dependencies> http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/connectors/kafka/pom.xml ---------------------------------------------------------------------- diff --git a/connectors/kafka/pom.xml b/connectors/kafka/pom.xml index 51c34a0..8a2aee2 100644 --- a/connectors/kafka/pom.xml +++ b/connectors/kafka/pom.xml @@ -100,7 +100,7 @@ <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> - <version>2.10.4</version> + <version>2.10.7</version> <exclusions> <exclusion> <!-- not transitive --> <groupId>*</groupId> @@ -122,7 +122,7 @@ <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> - <version>3.4.6</version> + <version>3.4.13</version> <exclusions> <exclusion> <!-- not transitive --> <groupId>*</groupId> http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/connectors/websocket-jetty/pom.xml ---------------------------------------------------------------------- diff --git a/connectors/websocket-jetty/pom.xml b/connectors/websocket-jetty/pom.xml index eb3df35..57aa13f 100644 --- a/connectors/websocket-jetty/pom.xml +++ b/connectors/websocket-jetty/pom.xml @@ -43,7 +43,7 @@ <dependency> <groupId>org.eclipse.jetty.websocket</groupId> <artifactId>javax-websocket-client-impl</artifactId> - <version>9.3.6.v20151106</version> + <version>9.4.8.v20180619</version> </dependency> </dependencies> http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/connectors/websocket-server/pom.xml ---------------------------------------------------------------------- diff --git a/connectors/websocket-server/pom.xml b/connectors/websocket-server/pom.xml index 50f6e73..9cb92b4 100644 --- a/connectors/websocket-server/pom.xml +++ b/connectors/websocket-server/pom.xml @@ -43,7 +43,7 @@ <dependency> <groupId>org.eclipse.jetty.websocket</groupId> <artifactId>javax-websocket-server-impl</artifactId> - <version>9.3.6.v20151106</version> + <version>9.4.8.v20180619</version> </dependency> </dependencies> http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/console/pom.xml ---------------------------------------------------------------------- diff --git a/console/pom.xml b/console/pom.xml index 35f7c91..4237258 100644 --- a/console/pom.xml +++ b/console/pom.xml @@ -32,7 +32,9 @@ <name>Apache Edgent (Java 8): Console</name> <modules> - <module>server</module> + <module>server-jetty</module> + <module>server-tomcat</module> + <module>server-undertow</module> <module>servlets</module> </modules> http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/console/server-jetty/pom.xml ---------------------------------------------------------------------- diff --git a/console/server-jetty/pom.xml b/console/server-jetty/pom.xml new file mode 100644 index 0000000..4a333ea --- /dev/null +++ b/console/server-jetty/pom.xml @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<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/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.edgent</groupId> + <artifactId>edgent-console</artifactId> + <version>1.3.0-SNAPSHOT</version> + </parent> + + <artifactId>edgent-console-server-jetty</artifactId> + + <name>Apache Edgent (Java 8): Console: Server (Jetty)</name> + + <build> + <resources> + <resource> + <directory>${project.basedir}/src/main/resources</directory> + <targetPath>${project.build.outputDirectory}/</targetPath> + </resource> + <resource> + <!-- bundle the licenses of the artifacts we are bundling --> + <directory>${project.basedir}/../../src/main/appended-resources/licenses</directory> + <targetPath>${project.build.outputDirectory}/META-INF/licenses</targetPath> + </resource> + </resources> + <plugins> + <!-- + Copy the servlets.war into the build output so it is embedded as + resource into the jar. + --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy</id> + <phase>generate-resources</phase> + <goals> + <goal>copy</goal> + </goals> + <configuration> + <!-- Bundle these dependencies in the jar. + + You must maintain the corresponding info if you + add/remove artifacts or change their versions: + - entry in src/main/resources/META-INF/LICENSE + - entry in src/main/resources/META-INF/NOTICE when appropriate + + See console/servlets and its pom,LICENSE,NOTICE. + + You must maintain the info in this project's + corresponding platforms/java7 files. + --> + <artifactItems> + <artifactItem> + <groupId>org.apache.edgent</groupId> + <artifactId>edgent-console-servlets</artifactId> + <version>${project.version}</version> + <type>war</type> + <outputDirectory>${project.build.outputDirectory}/resources</outputDirectory> + <destFileName>servlets.war</destFileName> + </artifactItem> + </artifactItems> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <!-- needed because of HttpServer impl and HttpServerPortTest --> + <reuseForks>false</reuseForks> + </configuration> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-http</artifactId> + <version>${jetty.version}</version> + </dependency> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-io</artifactId> + <version>${jetty.version}</version> + </dependency> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-security</artifactId> + <version>${jetty.version}</version> + </dependency> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-server</artifactId> + <version>${jetty.version}</version> + </dependency> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-servlet</artifactId> + <version>${jetty.version}</version> + </dependency> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-util</artifactId> + <version>${jetty.version}</version> + </dependency> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-webapp</artifactId> + <version>${jetty.version}</version> + </dependency> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-xml</artifactId> + <version>${jetty.version}</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>1.7.12</version> + </dependency> + + <!-- + This artifact is needed by the maven-dependency-plugin + by marking this dependency optional, it is not included + in the resulting artifact, but Maven ensures it is built + prior to this module. + --> + <dependency> + <groupId>org.apache.edgent</groupId> + <artifactId>edgent-console-servlets</artifactId> + <version>1.3.0-SNAPSHOT</version> + <type>war</type> + <optional>true</optional> + </dependency> + </dependencies> + +</project> http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/console/server-jetty/src/main/java/org/apache/edgent/console/server/HttpServer.java ---------------------------------------------------------------------- diff --git a/console/server-jetty/src/main/java/org/apache/edgent/console/server/HttpServer.java b/console/server-jetty/src/main/java/org/apache/edgent/console/server/HttpServer.java new file mode 100644 index 0000000..dd89093 --- /dev/null +++ b/console/server-jetty/src/main/java/org/apache/edgent/console/server/HttpServer.java @@ -0,0 +1,174 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +package org.apache.edgent.console.server; + +import java.io.File; + +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.handler.AllowSymLinkAliasChecker; +import org.eclipse.jetty.server.handler.ContextHandlerCollection; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.webapp.WebAppContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The "Edgent Console". + * <p> + * The Console's HTTP server starts with a random available port unless + * a port is specified via the {@code edgent.console.port} system property. + */ +public class HttpServer { + + private static final Logger logger = LoggerFactory.getLogger(HttpServer.class); + + /** + * The only constructor. A private no-argument constructor. Called only once from the static HttpServerHolder class. + */ + private HttpServer() { + } + + /** + * The static class that creates the singleton HttpServer object. + */ + private static class HttpServerHolder { + // use port 0 if system prop not set, so we know the server will always start + private static final Server JETTYSERVER = new Server(Integer.getInteger("edgent.console.port", 0)); + private static final WebAppContext WEBAPP = new WebAppContext(); + private static final HttpServer INSTANCE = new HttpServer(); + private static boolean INITIALIZED = false; + } + + /** + * Gets the jetty server associated with this class + * @return the org.eclipse.jetty.server.Server + */ + private static Server getJettyServer() { + return HttpServerHolder.JETTYSERVER; + } + /** + * Initialization of the context path for the web application "/console" occurs in this method + * and the handler for the web application is set. This only occurs once. + * @return HttpServer: the singleton instance of this class + * @throws Exception on failure + */ + public static HttpServer getInstance() throws Exception { + if (!HttpServerHolder.INITIALIZED) { + logger.info("initializing"); + HttpServerHolder.WEBAPP.setContextPath("/console"); + ServletContextHandler contextJobs = new ServletContextHandler(ServletContextHandler.SESSIONS); + contextJobs.setContextPath("/jobs"); + ServletContextHandler contextMetrics = new ServletContextHandler(ServletContextHandler.SESSIONS); + contextMetrics.setContextPath("/metrics"); + ServerUtil sUtil = new ServerUtil(); + File servletsJarFile = sUtil.getWarFilePath(); + if (servletsJarFile.exists()){ + HttpServerHolder.WEBAPP.setWar(servletsJarFile.getAbsolutePath()); + } else { + throw new RuntimeException("Unable to find WAR archive in " + servletsJarFile.getAbsolutePath()); + } + + HttpServerHolder.WEBAPP.addAliasCheck(new AllowSymLinkAliasChecker()); + ContextHandlerCollection contexts = new ContextHandlerCollection(); + contexts.setHandlers(new Handler[] { contextJobs, contextMetrics, HttpServerHolder.WEBAPP }); + HttpServerHolder.JETTYSERVER.setHandler(contexts); + HttpServerHolder.INITIALIZED = true; + } + return HttpServerHolder.INSTANCE; + } + + /** + * + * @return the ServerConnector object for the jetty server + */ + private static ServerConnector getServerConnector() { + return (ServerConnector) HttpServerHolder.JETTYSERVER.getConnectors()[0]; + } + + /** + * + * @return a String containing the context path to the console web application + * @throws Exception on failure + */ + public String getConsoleContextPath() throws Exception { + return HttpServerHolder.WEBAPP.getContextPath(); + } + + /** + * Starts the jetty web server + * @throws Exception on failure + */ + public void startServer() throws Exception { + getJettyServer().start(); + } + + /** + * Stops the jetty web server + * @throws Exception + */ + @SuppressWarnings("unused") + private static void stopServer() throws Exception { + getJettyServer().stop(); + } + + /** + * Checks to see if the jetty web server is started + * @return a boolean: true if the server is started, false if not + */ + public boolean isServerStarted() { + if (getJettyServer().isStarted() || getJettyServer().isStarting() || getJettyServer().isRunning()) { + return true; + } + else { + return false; + } + } + + /** + * Checks to see if the server is in a "stopping" or "stopped" state + * @return a boolean: true if the server is stopping or stopped, false otherwise + */ + public boolean isServerStopped() { + if (getJettyServer().isStopping() || getJettyServer().isStopped()) { + return true; + } + else { + return false; + } + } + /** + * Returns the port number the console is running on. Each time the console is started a different port number may be returned. + * @return an int: the port number the jetty server is listening on + */ + public int getConsolePortNumber() { + return getServerConnector().getLocalPort(); + } + + /** + * Returns the url for the web application at the "console" context path. Localhost is always assumed + * @return the url for the web application at the "console" context path. + * @throws Exception on failure + */ + public String getConsoleUrl() throws Exception { + return new String("http://localhost" + ":" + getConsolePortNumber() + getConsoleContextPath()); + } +} http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/console/server-jetty/src/main/java/org/apache/edgent/console/server/ServerUtil.java ---------------------------------------------------------------------- diff --git a/console/server-jetty/src/main/java/org/apache/edgent/console/server/ServerUtil.java b/console/server-jetty/src/main/java/org/apache/edgent/console/server/ServerUtil.java new file mode 100644 index 0000000..f8c6fde --- /dev/null +++ b/console/server-jetty/src/main/java/org/apache/edgent/console/server/ServerUtil.java @@ -0,0 +1,84 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +package org.apache.edgent.console.server; + +import java.io.*; + +public class ServerUtil { + + /** + * The public constructor of this utility class for use by the HttpServer class. + */ + public ServerUtil() { + } + + /** + * Returns the File object representing the "webapps" directory + * @return a File object or null if the "webapps" directory is not found + */ + public File getWarFilePath() { + File war = new File("target/war-resources/servlets.war"); + if(!war.exists()) { + // Eventually create the directory for serving the war. + if(!war.getParentFile().exists()) { + if(!war.getParentFile().mkdirs()) { + throw new RuntimeException("Could not create output directory at " + war.getAbsolutePath()); + } + } + + // Dump the servlet.war into the output directory. + InputStream stream = null; + FileOutputStream fileOutputStream = null; + try { + stream = ServerUtil.class.getResourceAsStream("/resources/servlets.war"); + if(stream == null) { + throw new RuntimeException("Could not get resource '/resources/servlets.war' from classpath."); + } + + int readBytes; + byte[] buffer = new byte[4096]; + fileOutputStream = new FileOutputStream(war); + while ((readBytes = stream.read(buffer)) > 0) { + fileOutputStream.write(buffer, 0, readBytes); + } + } catch (IOException e) { + throw new RuntimeException("Could not dump resource 'resources/servlets.war' from classpath.", e); + } finally { + if(stream != null) { + try { + stream.close(); + } catch (IOException e) { + // Ignore. + } + } + if(fileOutputStream != null) { + try { + fileOutputStream.close(); + } catch (IOException e) { + // Ignore. + } + } + } + } + + return war; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/console/server-jetty/src/main/remote-resources/META-INF/LICENSE ---------------------------------------------------------------------- diff --git a/console/server-jetty/src/main/remote-resources/META-INF/LICENSE b/console/server-jetty/src/main/remote-resources/META-INF/LICENSE new file mode 100644 index 0000000..8d0e1a0 --- /dev/null +++ b/console/server-jetty/src/main/remote-resources/META-INF/LICENSE @@ -0,0 +1,42 @@ + +=============================================================================== +APACHE EDGENT SUBCOMPONENTS: + +This binary includes a number of subcomponents with separate +copyright notices and license terms. Your use of this binary +is subject to the terms and conditions of the following licenses. + +=============================================================================== +License: Apache License Version 2.0 +For details, see META-INF/licenses/apache-license-version-2.0.txt + +gson (com.google.code.gson:gson:2.2.4) +metrics-core (io.dropwizard.metrics:metrics-core:3.1.2) + +=============================================================================== +License: MIT + +jquery (org.webjars:jquery:1.11.2) + For details, see META-INF/licenses/jquery-1_11_2-MIT.txt. + +jquery-ui (org.webjars:jquery-ui:1.11.4) + For details, see META-INF/licenses/jquery-ui-1_11_4-MIT.txt. + +d3.legend.js (included inside the resources/servlets.war!/js/ext/d3.legend/d3.legend.js) + https://gist.githubusercontent.com/ZJONSSON/3918369/raw/bf9bce6b68a3b70f87450f155436ca4a84af1ba4/d3.legend.js + With Edgent specific modifications. + For details, see META-INF/licenses/d3.legend-MIT.txt. + +=============================================================================== +License: BSD 3-Clause + +d3 (org.webjars.bower:d3:3.3.9) + For details, see META-INF/licenses/d3-3_3_9-BSD.txt. + +=============================================================================== +License: BSD 2-Clause + +d3-plugins-sankey (org.webjars.bower:d3-plugins-sankey:1.1.0) + For details, see META-INF/licenses/d3-plugins-sankey-1_1_0-BSD.txt. + +=============================================================================== http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/console/server-jetty/src/main/remote-resources/META-INF/NOTICE ---------------------------------------------------------------------- diff --git a/console/server-jetty/src/main/remote-resources/META-INF/NOTICE b/console/server-jetty/src/main/remote-resources/META-INF/NOTICE new file mode 100644 index 0000000..9c9e7e9 --- /dev/null +++ b/console/server-jetty/src/main/remote-resources/META-INF/NOTICE @@ -0,0 +1,28 @@ +=============================================================================== + +Portions of this software were developed by IBM Corp. +Copyright IBM Corp. 2015, 2016 + +=============================================================================== + +APACHE EDGENT SUBCOMPONENTS: + +This product includes a number of subcomponents with separate +copyright notices and license terms. The following notices apply. + +------------------------------------------------------------------------------- +metrics-core (io.dropwizard.metrics:metrics-core:3.1.2) + +Metrics +Copyright 2010-2013 Coda Hale and Yammer, Inc. + +This product includes software developed by Coda Hale and Yammer, Inc. + +This product includes code derived from the JSR-166 project (ThreadLocalRandom, +Striped64, LongAdder) with the following comments: + + Written by Doug Lea with assistance from members of JCP JSR-166 + Expert Group and released to the public domain, as explained at + http://creativecommons.org/publicdomain/zero/1.0/ + +=============================================================================== http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/console/server-jetty/src/test/java/org/apache/edgent/test/console/server/HttpServerPortTest.java ---------------------------------------------------------------------- diff --git a/console/server-jetty/src/test/java/org/apache/edgent/test/console/server/HttpServerPortTest.java b/console/server-jetty/src/test/java/org/apache/edgent/test/console/server/HttpServerPortTest.java new file mode 100644 index 0000000..64e8b22 --- /dev/null +++ b/console/server-jetty/src/test/java/org/apache/edgent/test/console/server/HttpServerPortTest.java @@ -0,0 +1,58 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ +package org.apache.edgent.test.console.server; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assume.assumeTrue; + +import java.io.IOException; +import java.net.Socket; + +import org.apache.edgent.console.server.HttpServer; +import org.junit.Test; + +/** + * This is a separate test because the HttpServer implementation + * precludes changing the console port within a jvm instance. + */ +public class HttpServerPortTest { + + int getAvailablePort() throws IOException { + try (Socket s = new Socket()) { + s.bind(null); + return s.getLocalPort(); + } + } + + @Test + public void testOverridePortNumber() throws Exception { + // count on the OS not immediately reusing an available local port. + int port = getAvailablePort(); + int port2 = getAvailablePort(); + assumeTrue(port != port2); + + System.setProperty("edgent.console.port", String.valueOf(port)); + HttpServer myHttpServer = HttpServer.getInstance(); + myHttpServer.startServer(); + + int portNum = myHttpServer.getConsolePortNumber(); + assertEquals(port, portNum); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/console/server-jetty/src/test/java/org/apache/edgent/test/console/server/HttpServerTest.java ---------------------------------------------------------------------- diff --git a/console/server-jetty/src/test/java/org/apache/edgent/test/console/server/HttpServerTest.java b/console/server-jetty/src/test/java/org/apache/edgent/test/console/server/HttpServerTest.java new file mode 100644 index 0000000..46bd511 --- /dev/null +++ b/console/server-jetty/src/test/java/org/apache/edgent/test/console/server/HttpServerTest.java @@ -0,0 +1,172 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ +package org.apache.edgent.test.console.server; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.apache.edgent.console.server.HttpServer; +import org.junit.Test; + +public class HttpServerTest { + + public static final String consoleWarNotFoundMessage = + "console.war not found. Run 'ant' from the top level edgent directory, or 'ant' from 'console/servlets' to create console.war under the webapps directory."; + + + @Test + public void testGetInstance() { + HttpServer myHttpServer = null; + boolean warNotFoundExceptionThrown = false; + try { + myHttpServer = HttpServer.getInstance(); + } catch (Exception warNotFoundException) { + System.out.println(warNotFoundException.getMessage()); + if (warNotFoundException.getMessage().equals(consoleWarNotFoundMessage)) { + warNotFoundExceptionThrown = true; + assertEquals("", ""); + } + } finally { + if (!warNotFoundExceptionThrown) { + assertNotNull("HttpServer getInstance is null", myHttpServer); + } else { + assertNull("HttpServer getInstance is null because console.war could not be found", myHttpServer); + } + } + } + + @Test + public void startServer() throws Exception { + HttpServer myHttpServer = null; + boolean warNotFoundExceptionThrown = false; + try { + myHttpServer = HttpServer.getInstance(); + } catch (Exception warNotFoundException) { + System.out.println(warNotFoundException.getMessage()); + if (warNotFoundException.getMessage().equals(consoleWarNotFoundMessage)) { + warNotFoundExceptionThrown = true; + assertEquals("", ""); + } + } finally { + if ((!warNotFoundExceptionThrown) && (myHttpServer != null)){ + myHttpServer.startServer(); + assertTrue(myHttpServer.isServerStarted()); + } else { + assertNull("HttpServer getInstance is null because console.war could not be found", myHttpServer); + } + } + } + + @Test + public void isServerStopped() throws Exception { + HttpServer myHttpServer = null; + boolean warNotFoundExceptionThrown = false; + try { + myHttpServer = HttpServer.getInstance(); + } catch (Exception warNotFoundException) { + System.out.println(warNotFoundException.getMessage()); + if (warNotFoundException.getMessage().equals(consoleWarNotFoundMessage)) { + warNotFoundExceptionThrown = true; + assertEquals("", ""); + } + } finally { + if ((!warNotFoundExceptionThrown) && (myHttpServer != null)){ + myHttpServer.startServer(); + assertFalse(myHttpServer.isServerStopped()); + } else { + assertNull("HttpServer getInstance is null because console.war could not be found", myHttpServer); + } + } + } + + @Test + public void getConsolePath() throws Exception { + HttpServer myHttpServer = null; + boolean warNotFoundExceptionThrown = false; + try { + myHttpServer = HttpServer.getInstance(); + } catch (Exception warNotFoundException) { + System.out.println(warNotFoundException.getMessage()); + if (warNotFoundException.getMessage().equals(consoleWarNotFoundMessage)) { + warNotFoundExceptionThrown = true; + assertEquals("", ""); + } + } finally { + if ((!warNotFoundExceptionThrown) && (myHttpServer != null)){ + assertEquals("/console", myHttpServer.getConsoleContextPath()); + } else { + assertNull("HttpServer getInstance is null because console.war could not be found", myHttpServer); + } + } + + } + + @Test + public void getConsoleUrl() throws Exception { + + HttpServer myHttpServer = null; + boolean warNotFoundExceptionThrown = false; + try { + myHttpServer = HttpServer.getInstance(); + } catch (Exception warNotFoundException) { + System.out.println(warNotFoundException.getMessage()); + if (warNotFoundException.getMessage().equals(consoleWarNotFoundMessage)) { + warNotFoundExceptionThrown = true; + assertEquals("", ""); + } + } finally { + if ((!warNotFoundExceptionThrown) && (myHttpServer != null)){ + myHttpServer.startServer(); + int portNum = myHttpServer.getConsolePortNumber(); + String context = myHttpServer.getConsoleContextPath(); + assertEquals("http://localhost:" + portNum + context, myHttpServer.getConsoleUrl()); + } else { + assertNull("HttpServer getInstance is null because console.war could not be found", myHttpServer); + } + } + } + + @Test + public void getConsolePortNumber() throws Exception { + HttpServer myHttpServer = null; + boolean warNotFoundExceptionThrown = false; + try { + myHttpServer = HttpServer.getInstance(); + } catch (Exception warNotFoundException) { + System.out.println(warNotFoundException.getMessage()); + if (warNotFoundException.getMessage().equals(consoleWarNotFoundMessage)) { + warNotFoundExceptionThrown = true; + assertEquals("", ""); + } + } finally { + if ((!warNotFoundExceptionThrown) && (myHttpServer != null)){ + myHttpServer.startServer(); + int portNum = myHttpServer.getConsolePortNumber(); + assertTrue("the port number is not in integer range: " + Integer.toString(portNum), + (Integer.MAX_VALUE > portNum) && (0 < portNum)); + } else { + assertNull("HttpServer getInstance is null because console.war could not be found", myHttpServer); + } + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/console/server-jetty/src/test/java/org/apache/edgent/test/console/server/ServerUtilTest.java ---------------------------------------------------------------------- diff --git a/console/server-jetty/src/test/java/org/apache/edgent/test/console/server/ServerUtilTest.java b/console/server-jetty/src/test/java/org/apache/edgent/test/console/server/ServerUtilTest.java new file mode 100644 index 0000000..cea0ac4 --- /dev/null +++ b/console/server-jetty/src/test/java/org/apache/edgent/test/console/server/ServerUtilTest.java @@ -0,0 +1,43 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ +package org.apache.edgent.test.console.server; + +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; + +import org.apache.edgent.console.server.ServerUtil; +import org.junit.Test; + + +public class ServerUtilTest { + + @Test + public void testServerUtil() { + ServerUtil serverUtil = new ServerUtil(); + assertNotNull("ServerUtil is null", serverUtil); + } + + @Test + public void testGetPath() throws IOException { + ServerUtil serverUtil = new ServerUtil(); + assertNotNull("Get AbsoluteWarFilePath is null", serverUtil.getWarFilePath()); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/console/server-tomcat/pom.xml ---------------------------------------------------------------------- diff --git a/console/server-tomcat/pom.xml b/console/server-tomcat/pom.xml new file mode 100644 index 0000000..92d6c8a --- /dev/null +++ b/console/server-tomcat/pom.xml @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<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/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.edgent</groupId> + <artifactId>edgent-console</artifactId> + <version>1.3.0-SNAPSHOT</version> + </parent> + + <artifactId>edgent-console-server-tomcat</artifactId> + + <name>Apache Edgent (Java 8): Console: Server (Tomcat)</name> + + <build> + <resources> + <resource> + <directory>${project.basedir}/src/main/resources</directory> + <targetPath>${project.build.outputDirectory}/</targetPath> + </resource> + <resource> + <!-- bundle the licenses of the artifacts we are bundling --> + <directory>${project.basedir}/../../src/main/appended-resources/licenses</directory> + <targetPath>${project.build.outputDirectory}/META-INF/licenses</targetPath> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <!-- needed because of HttpServer impl and HttpServerPortTest --> + <reuseForks>false</reuseForks> + <!-- Make tomcat start within the target directory --> + <workingDirectory>${project.build.directory}</workingDirectory> + <basedir>${project.build.directory}</basedir> + </configuration> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + <version>3.1.0</version> + </dependency> + <dependency> + <groupId>org.apache.tomcat.embed</groupId> + <artifactId>tomcat-embed-core</artifactId> + <version>${tomcat.version}</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>1.7.25</version> + </dependency> + + <dependency> + <groupId>org.apache.edgent</groupId> + <artifactId>edgent-console-servlets</artifactId> + <version>1.3.0-SNAPSHOT</version> + <classifier>classes</classifier> + </dependency> + </dependencies> + +</project> http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/console/server-tomcat/src/main/java/org/apache/edgent/console/server/HttpServer.java ---------------------------------------------------------------------- diff --git a/console/server-tomcat/src/main/java/org/apache/edgent/console/server/HttpServer.java b/console/server-tomcat/src/main/java/org/apache/edgent/console/server/HttpServer.java new file mode 100644 index 0000000..212cc69 --- /dev/null +++ b/console/server-tomcat/src/main/java/org/apache/edgent/console/server/HttpServer.java @@ -0,0 +1,169 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +package org.apache.edgent.console.server; + +import org.apache.catalina.Context; +import org.apache.catalina.startup.Tomcat; +import org.apache.edgent.console.servlets.ConsoleJobServlet; +import org.apache.edgent.console.servlets.ConsoleMetricsServlet; +import org.apache.edgent.console.servlets.ConsoleServlet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; + +/** + * The "Edgent Console". + * <p> + * The Console's HTTP server starts with a random available port unless + * a port is specified via the {@code edgent.console.port} system property. + */ +public class HttpServer { + + private static final Logger logger = LoggerFactory.getLogger(HttpServer.class); + + /** + * The only constructor. A private no-argument constructor. Called only once from the static HttpServerHolder class. + */ + private HttpServer() { + } + + /** + * The static class that creates the singleton HttpServer object. + */ + private static class HttpServerHolder { + // use port 0 if system prop not set, so we know the server will always start + private static final Tomcat TOMCATSERVER; + static { + TOMCATSERVER = new Tomcat(); + TOMCATSERVER.setPort(Integer.getInteger("edgent.console.port", 0)); + // Trigger the creation of the default connector + TOMCATSERVER.getConnector(); + } + + private static Context CONSOLE_CONTEXT; + private static final HttpServer INSTANCE = new HttpServer(); + private static boolean INITIALIZED = false; + } + + /** + * Gets the tomcat server associated with this class + * @return the org.apache.catalina.startup.Tomcat + */ + private static Tomcat getTomcatServer() { + return HttpServerHolder.TOMCATSERVER; + } + + /** + * Initialization of the context path for the web application "/console" occurs in this method + * and the handler for the web application is set. This only occurs once. + * @return HttpServer: the singleton instance of this class + */ + public static HttpServer getInstance() { + if (!HttpServerHolder.INITIALIZED) { + logger.info("initializing"); + + Tomcat tomcat = HttpServerHolder.TOMCATSERVER; + + // Initialize the console context + Context context = tomcat.addContext("/console", new File(".").getAbsolutePath()); + HttpServerHolder.CONSOLE_CONTEXT = context; + + // Initialize the console servlet. + Class consoleServletClass = ConsoleServlet.class; + String consoleServletName = consoleServletClass.getSimpleName(); + Tomcat.addServlet(context, consoleServletName, consoleServletClass.getName()); + context.addServletMappingDecoded("/console/*", consoleServletName); + + // Initialize the jobs servlet. + Class jobsServletClass = ConsoleJobServlet.class; + String jobsServletName = jobsServletClass.getSimpleName(); + Tomcat.addServlet(context, jobsServletName, jobsServletClass.getName()); + context.addServletMappingDecoded("/console/jobs/*", jobsServletName); + + // Initialize the metrics servlet. + Class metricsServletClass = ConsoleMetricsServlet.class; + String metricsServletName = metricsServletClass.getSimpleName(); + Tomcat.addServlet(context, metricsServletName, metricsServletClass.getName()); + context.addServletMappingDecoded("/console/metrics/*", metricsServletName); + + HttpServerHolder.INITIALIZED = true; + } + return HttpServerHolder.INSTANCE; + } + + /** + * + * @return a String containing the context path to the console web application + */ + public String getConsoleContextPath() { + return HttpServerHolder.CONSOLE_CONTEXT.getPath(); + } + + /** + * Starts the tomcat web server + * @throws Exception on failure + */ + public void startServer() throws Exception { + getTomcatServer().start(); + } + + /** + * Stops the tomcat web server + * @throws Exception on failure + */ + @SuppressWarnings("unused") + private static void stopServer() throws Exception { + getTomcatServer().stop(); + } + + /** + * Checks to see if the tomcat web server is started + * @return a boolean: true if the server is started, false if not + */ + public boolean isServerStarted() { + return getTomcatServer().getConnector().getState().isAvailable(); + } + + /** + * Checks to see if the server is in a "stopping" or "stopped" state + * @return a boolean: true if the server is stopping or stopped, false otherwise + */ + public boolean isServerStopped() { + return !getTomcatServer().getConnector().getState().isAvailable(); + } + + /** + * Returns the port number the console is running on. Each time the console is started a different port number may be returned. + * @return an int: the port number the jetty server is listening on + */ + public int getConsolePortNumber() { + return getTomcatServer().getConnector().getLocalPort(); + } + + /** + * Returns the url for the web application at the "console" context path. Localhost is always assumed + * @return the url for the web application at the "console" context path. + */ + public String getConsoleUrl() { + return "http://localhost" + ":" + getConsolePortNumber() + getConsoleContextPath(); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/console/server-tomcat/src/main/remote-resources/META-INF/LICENSE ---------------------------------------------------------------------- diff --git a/console/server-tomcat/src/main/remote-resources/META-INF/LICENSE b/console/server-tomcat/src/main/remote-resources/META-INF/LICENSE new file mode 100644 index 0000000..8d0e1a0 --- /dev/null +++ b/console/server-tomcat/src/main/remote-resources/META-INF/LICENSE @@ -0,0 +1,42 @@ + +=============================================================================== +APACHE EDGENT SUBCOMPONENTS: + +This binary includes a number of subcomponents with separate +copyright notices and license terms. Your use of this binary +is subject to the terms and conditions of the following licenses. + +=============================================================================== +License: Apache License Version 2.0 +For details, see META-INF/licenses/apache-license-version-2.0.txt + +gson (com.google.code.gson:gson:2.2.4) +metrics-core (io.dropwizard.metrics:metrics-core:3.1.2) + +=============================================================================== +License: MIT + +jquery (org.webjars:jquery:1.11.2) + For details, see META-INF/licenses/jquery-1_11_2-MIT.txt. + +jquery-ui (org.webjars:jquery-ui:1.11.4) + For details, see META-INF/licenses/jquery-ui-1_11_4-MIT.txt. + +d3.legend.js (included inside the resources/servlets.war!/js/ext/d3.legend/d3.legend.js) + https://gist.githubusercontent.com/ZJONSSON/3918369/raw/bf9bce6b68a3b70f87450f155436ca4a84af1ba4/d3.legend.js + With Edgent specific modifications. + For details, see META-INF/licenses/d3.legend-MIT.txt. + +=============================================================================== +License: BSD 3-Clause + +d3 (org.webjars.bower:d3:3.3.9) + For details, see META-INF/licenses/d3-3_3_9-BSD.txt. + +=============================================================================== +License: BSD 2-Clause + +d3-plugins-sankey (org.webjars.bower:d3-plugins-sankey:1.1.0) + For details, see META-INF/licenses/d3-plugins-sankey-1_1_0-BSD.txt. + +=============================================================================== http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/console/server-tomcat/src/main/remote-resources/META-INF/NOTICE ---------------------------------------------------------------------- diff --git a/console/server-tomcat/src/main/remote-resources/META-INF/NOTICE b/console/server-tomcat/src/main/remote-resources/META-INF/NOTICE new file mode 100644 index 0000000..9c9e7e9 --- /dev/null +++ b/console/server-tomcat/src/main/remote-resources/META-INF/NOTICE @@ -0,0 +1,28 @@ +=============================================================================== + +Portions of this software were developed by IBM Corp. +Copyright IBM Corp. 2015, 2016 + +=============================================================================== + +APACHE EDGENT SUBCOMPONENTS: + +This product includes a number of subcomponents with separate +copyright notices and license terms. The following notices apply. + +------------------------------------------------------------------------------- +metrics-core (io.dropwizard.metrics:metrics-core:3.1.2) + +Metrics +Copyright 2010-2013 Coda Hale and Yammer, Inc. + +This product includes software developed by Coda Hale and Yammer, Inc. + +This product includes code derived from the JSR-166 project (ThreadLocalRandom, +Striped64, LongAdder) with the following comments: + + Written by Doug Lea with assistance from members of JCP JSR-166 + Expert Group and released to the public domain, as explained at + http://creativecommons.org/publicdomain/zero/1.0/ + +=============================================================================== http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/console/server-tomcat/src/test/java/org/apache/edgent/test/console/server/HttpServerPortTest.java ---------------------------------------------------------------------- diff --git a/console/server-tomcat/src/test/java/org/apache/edgent/test/console/server/HttpServerPortTest.java b/console/server-tomcat/src/test/java/org/apache/edgent/test/console/server/HttpServerPortTest.java new file mode 100644 index 0000000..64e8b22 --- /dev/null +++ b/console/server-tomcat/src/test/java/org/apache/edgent/test/console/server/HttpServerPortTest.java @@ -0,0 +1,58 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ +package org.apache.edgent.test.console.server; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assume.assumeTrue; + +import java.io.IOException; +import java.net.Socket; + +import org.apache.edgent.console.server.HttpServer; +import org.junit.Test; + +/** + * This is a separate test because the HttpServer implementation + * precludes changing the console port within a jvm instance. + */ +public class HttpServerPortTest { + + int getAvailablePort() throws IOException { + try (Socket s = new Socket()) { + s.bind(null); + return s.getLocalPort(); + } + } + + @Test + public void testOverridePortNumber() throws Exception { + // count on the OS not immediately reusing an available local port. + int port = getAvailablePort(); + int port2 = getAvailablePort(); + assumeTrue(port != port2); + + System.setProperty("edgent.console.port", String.valueOf(port)); + HttpServer myHttpServer = HttpServer.getInstance(); + myHttpServer.startServer(); + + int portNum = myHttpServer.getConsolePortNumber(); + assertEquals(port, portNum); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/console/server-tomcat/src/test/java/org/apache/edgent/test/console/server/HttpServerTest.java ---------------------------------------------------------------------- diff --git a/console/server-tomcat/src/test/java/org/apache/edgent/test/console/server/HttpServerTest.java b/console/server-tomcat/src/test/java/org/apache/edgent/test/console/server/HttpServerTest.java new file mode 100644 index 0000000..46bd511 --- /dev/null +++ b/console/server-tomcat/src/test/java/org/apache/edgent/test/console/server/HttpServerTest.java @@ -0,0 +1,172 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ +package org.apache.edgent.test.console.server; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.apache.edgent.console.server.HttpServer; +import org.junit.Test; + +public class HttpServerTest { + + public static final String consoleWarNotFoundMessage = + "console.war not found. Run 'ant' from the top level edgent directory, or 'ant' from 'console/servlets' to create console.war under the webapps directory."; + + + @Test + public void testGetInstance() { + HttpServer myHttpServer = null; + boolean warNotFoundExceptionThrown = false; + try { + myHttpServer = HttpServer.getInstance(); + } catch (Exception warNotFoundException) { + System.out.println(warNotFoundException.getMessage()); + if (warNotFoundException.getMessage().equals(consoleWarNotFoundMessage)) { + warNotFoundExceptionThrown = true; + assertEquals("", ""); + } + } finally { + if (!warNotFoundExceptionThrown) { + assertNotNull("HttpServer getInstance is null", myHttpServer); + } else { + assertNull("HttpServer getInstance is null because console.war could not be found", myHttpServer); + } + } + } + + @Test + public void startServer() throws Exception { + HttpServer myHttpServer = null; + boolean warNotFoundExceptionThrown = false; + try { + myHttpServer = HttpServer.getInstance(); + } catch (Exception warNotFoundException) { + System.out.println(warNotFoundException.getMessage()); + if (warNotFoundException.getMessage().equals(consoleWarNotFoundMessage)) { + warNotFoundExceptionThrown = true; + assertEquals("", ""); + } + } finally { + if ((!warNotFoundExceptionThrown) && (myHttpServer != null)){ + myHttpServer.startServer(); + assertTrue(myHttpServer.isServerStarted()); + } else { + assertNull("HttpServer getInstance is null because console.war could not be found", myHttpServer); + } + } + } + + @Test + public void isServerStopped() throws Exception { + HttpServer myHttpServer = null; + boolean warNotFoundExceptionThrown = false; + try { + myHttpServer = HttpServer.getInstance(); + } catch (Exception warNotFoundException) { + System.out.println(warNotFoundException.getMessage()); + if (warNotFoundException.getMessage().equals(consoleWarNotFoundMessage)) { + warNotFoundExceptionThrown = true; + assertEquals("", ""); + } + } finally { + if ((!warNotFoundExceptionThrown) && (myHttpServer != null)){ + myHttpServer.startServer(); + assertFalse(myHttpServer.isServerStopped()); + } else { + assertNull("HttpServer getInstance is null because console.war could not be found", myHttpServer); + } + } + } + + @Test + public void getConsolePath() throws Exception { + HttpServer myHttpServer = null; + boolean warNotFoundExceptionThrown = false; + try { + myHttpServer = HttpServer.getInstance(); + } catch (Exception warNotFoundException) { + System.out.println(warNotFoundException.getMessage()); + if (warNotFoundException.getMessage().equals(consoleWarNotFoundMessage)) { + warNotFoundExceptionThrown = true; + assertEquals("", ""); + } + } finally { + if ((!warNotFoundExceptionThrown) && (myHttpServer != null)){ + assertEquals("/console", myHttpServer.getConsoleContextPath()); + } else { + assertNull("HttpServer getInstance is null because console.war could not be found", myHttpServer); + } + } + + } + + @Test + public void getConsoleUrl() throws Exception { + + HttpServer myHttpServer = null; + boolean warNotFoundExceptionThrown = false; + try { + myHttpServer = HttpServer.getInstance(); + } catch (Exception warNotFoundException) { + System.out.println(warNotFoundException.getMessage()); + if (warNotFoundException.getMessage().equals(consoleWarNotFoundMessage)) { + warNotFoundExceptionThrown = true; + assertEquals("", ""); + } + } finally { + if ((!warNotFoundExceptionThrown) && (myHttpServer != null)){ + myHttpServer.startServer(); + int portNum = myHttpServer.getConsolePortNumber(); + String context = myHttpServer.getConsoleContextPath(); + assertEquals("http://localhost:" + portNum + context, myHttpServer.getConsoleUrl()); + } else { + assertNull("HttpServer getInstance is null because console.war could not be found", myHttpServer); + } + } + } + + @Test + public void getConsolePortNumber() throws Exception { + HttpServer myHttpServer = null; + boolean warNotFoundExceptionThrown = false; + try { + myHttpServer = HttpServer.getInstance(); + } catch (Exception warNotFoundException) { + System.out.println(warNotFoundException.getMessage()); + if (warNotFoundException.getMessage().equals(consoleWarNotFoundMessage)) { + warNotFoundExceptionThrown = true; + assertEquals("", ""); + } + } finally { + if ((!warNotFoundExceptionThrown) && (myHttpServer != null)){ + myHttpServer.startServer(); + int portNum = myHttpServer.getConsolePortNumber(); + assertTrue("the port number is not in integer range: " + Integer.toString(portNum), + (Integer.MAX_VALUE > portNum) && (0 < portNum)); + } else { + assertNull("HttpServer getInstance is null because console.war could not be found", myHttpServer); + } + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/console/server-undertow/pom.xml ---------------------------------------------------------------------- diff --git a/console/server-undertow/pom.xml b/console/server-undertow/pom.xml new file mode 100644 index 0000000..e921136 --- /dev/null +++ b/console/server-undertow/pom.xml @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<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/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.edgent</groupId> + <artifactId>edgent-console</artifactId> + <version>1.3.0-SNAPSHOT</version> + </parent> + + <artifactId>edgent-console-server-undertow</artifactId> + + <name>Apache Edgent (Java 8): Console: Server (Undertow)</name> + + <properties> + <undertow.version>2.0.11.Final</undertow.version> + </properties> + + <build> + <resources> + <resource> + <directory>${project.basedir}/src/main/resources</directory> + <targetPath>${project.build.outputDirectory}/</targetPath> + </resource> + <resource> + <!-- bundle the licenses of the artifacts we are bundling --> + <directory>${project.basedir}/../../src/main/appended-resources/licenses</directory> + <targetPath>${project.build.outputDirectory}/META-INF/licenses</targetPath> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <!-- needed because of HttpServer impl and HttpServerPortTest --> + <reuseForks>false</reuseForks> + <!-- Make tomcat start within the target directory --> + <workingDirectory>${project.build.directory}</workingDirectory> + <basedir>${project.build.directory}</basedir> + </configuration> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>io.undertow</groupId> + <artifactId>undertow-servlet</artifactId> + <version>${undertow.version}</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>1.7.25</version> + </dependency> + + <dependency> + <groupId>org.apache.edgent</groupId> + <artifactId>edgent-console-servlets</artifactId> + <version>1.3.0-SNAPSHOT</version> + <classifier>classes</classifier> + </dependency> + </dependencies> + +</project> http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/console/server-undertow/src/main/java/org/apache/edgent/console/server/HttpServer.java ---------------------------------------------------------------------- diff --git a/console/server-undertow/src/main/java/org/apache/edgent/console/server/HttpServer.java b/console/server-undertow/src/main/java/org/apache/edgent/console/server/HttpServer.java new file mode 100644 index 0000000..801f15b --- /dev/null +++ b/console/server-undertow/src/main/java/org/apache/edgent/console/server/HttpServer.java @@ -0,0 +1,189 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +package org.apache.edgent.console.server; + +import io.undertow.Handlers; +import io.undertow.Undertow; +import io.undertow.server.HttpHandler; +import io.undertow.server.handlers.PathHandler; +import io.undertow.servlet.Servlets; +import io.undertow.servlet.api.DeploymentInfo; +import io.undertow.servlet.api.DeploymentManager; +import org.apache.edgent.console.servlets.ConsoleJobServlet; +import org.apache.edgent.console.servlets.ConsoleMetricsServlet; +import org.apache.edgent.console.servlets.ConsoleServlet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.InetSocketAddress; +import java.util.List; + +/** + * The "Edgent Console". + * <p> + * The Console's HTTP server starts with a random available port unless + * a port is specified via the {@code edgent.console.port} system property. + */ +public class HttpServer { + + private static final Logger logger = LoggerFactory.getLogger(HttpServer.class); + + /** + * The only constructor. A private no-argument constructor. Called only once from the static HttpServerHolder class. + */ + private HttpServer() { + } + + /** + * The static class that creates the singleton HttpServer object. + */ + private static class HttpServerHolder { + private static String context = "/console"; + private static int port = Integer.getInteger("edgent.console.port", 0); + // use port 0 if system prop not set, so we know the server will always start + private static Undertow SERVER; + + private static final HttpServer INSTANCE = new HttpServer(); + private static boolean INITIALIZED = false; + } + + /** + * Gets the undertow server associated with this class + * @return the io.undertow.Undertow + */ + private static Undertow getUndertowServer() { + return HttpServerHolder.SERVER; + } + + /** + * Initialization of the context path for the web application "/console" occurs in this method + * and the handler for the web application is set. This only occurs once. + * @return HttpServer: the singleton instance of this class + */ + public static HttpServer getInstance() throws Exception { + if (!HttpServerHolder.INITIALIZED) { + logger.info("initializing"); + + DeploymentInfo servletBuilder = Servlets.deployment() + .setClassLoader(HttpServer.class.getClassLoader()) + .setContextPath("/console") + .setDeploymentName("console.war") + .addServlets( + Servlets.servlet(ConsoleServlet.class.getSimpleName(), ConsoleServlet.class) + .addMapping("/console/*"), + Servlets.servlet(ConsoleJobServlet.class.getSimpleName(), ConsoleJobServlet.class) + .addMapping("/console/jobs/*"), + Servlets.servlet(ConsoleMetricsServlet.class.getSimpleName(), ConsoleMetricsServlet.class) + .addMapping("/console/metrics/*") + ); + + DeploymentManager manager = Servlets.defaultContainer().addDeployment(servletBuilder); + manager.deploy(); + + HttpHandler servletHandler = manager.start(); + PathHandler path = Handlers.path(Handlers.redirect(HttpServerHolder.context)) + .addPrefixPath(HttpServerHolder.context, servletHandler); + + HttpServerHolder.SERVER = Undertow.builder() + .addHttpListener(HttpServerHolder.port, "localhost") + .setHandler(path) + .build(); + + HttpServerHolder.INITIALIZED = true; + } + return HttpServerHolder.INSTANCE; + } + + /** + * + * @return a String containing the context path to the console web application + */ + public String getConsoleContextPath() { + return HttpServerHolder.context; + } + + /** + * Starts the tomcat web server + */ + public void startServer() { + if(!isServerStarted()) { + getUndertowServer().start(); + } + } + + /** + * Stops the tomcat web server + * @throws Exception on failure + */ + @SuppressWarnings("unused") + private static void stopServer() { + getUndertowServer().stop(); + } + + /** + * Checks to see if the tomcat web server is started + * @return a boolean: true if the server is started, false if not + */ + public boolean isServerStarted() { + try { + HttpServerHolder.SERVER.getListenerInfo(); + return true; + } catch(IllegalStateException e) { + if ("UT000138: Server not started".equals(e.getMessage())) { + return false; + } else { + throw e; + } + } + } + + /** + * Checks to see if the server is in a "stopping" or "stopped" state + * @return a boolean: true if the server is stopping or stopped, false otherwise + */ + public boolean isServerStopped() { + return !isServerStarted(); + } + + /** + * Returns the port number the console is running on. Each time the console is started a different port number may be returned. + * @return an int: the port number the jetty server is listening on + */ + public int getConsolePortNumber() { + List<Undertow.ListenerInfo> listenerInfos = HttpServerHolder.SERVER.getListenerInfo(); + if(!listenerInfos.isEmpty()) { + Undertow.ListenerInfo listenerInfo = listenerInfos.iterator().next(); + if(listenerInfo.getAddress() instanceof InetSocketAddress) { + InetSocketAddress address = (InetSocketAddress) listenerInfo.getAddress(); + return address.getPort(); + } + } + return HttpServerHolder.port; + } + + /** + * Returns the url for the web application at the "console" context path. Localhost is always assumed + * @return the url for the web application at the "console" context path. + */ + public String getConsoleUrl() { + return "http://localhost" + ":" + getConsolePortNumber() + getConsoleContextPath(); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/console/server-undertow/src/main/remote-resources/META-INF/LICENSE ---------------------------------------------------------------------- diff --git a/console/server-undertow/src/main/remote-resources/META-INF/LICENSE b/console/server-undertow/src/main/remote-resources/META-INF/LICENSE new file mode 100644 index 0000000..8d0e1a0 --- /dev/null +++ b/console/server-undertow/src/main/remote-resources/META-INF/LICENSE @@ -0,0 +1,42 @@ + +=============================================================================== +APACHE EDGENT SUBCOMPONENTS: + +This binary includes a number of subcomponents with separate +copyright notices and license terms. Your use of this binary +is subject to the terms and conditions of the following licenses. + +=============================================================================== +License: Apache License Version 2.0 +For details, see META-INF/licenses/apache-license-version-2.0.txt + +gson (com.google.code.gson:gson:2.2.4) +metrics-core (io.dropwizard.metrics:metrics-core:3.1.2) + +=============================================================================== +License: MIT + +jquery (org.webjars:jquery:1.11.2) + For details, see META-INF/licenses/jquery-1_11_2-MIT.txt. + +jquery-ui (org.webjars:jquery-ui:1.11.4) + For details, see META-INF/licenses/jquery-ui-1_11_4-MIT.txt. + +d3.legend.js (included inside the resources/servlets.war!/js/ext/d3.legend/d3.legend.js) + https://gist.githubusercontent.com/ZJONSSON/3918369/raw/bf9bce6b68a3b70f87450f155436ca4a84af1ba4/d3.legend.js + With Edgent specific modifications. + For details, see META-INF/licenses/d3.legend-MIT.txt. + +=============================================================================== +License: BSD 3-Clause + +d3 (org.webjars.bower:d3:3.3.9) + For details, see META-INF/licenses/d3-3_3_9-BSD.txt. + +=============================================================================== +License: BSD 2-Clause + +d3-plugins-sankey (org.webjars.bower:d3-plugins-sankey:1.1.0) + For details, see META-INF/licenses/d3-plugins-sankey-1_1_0-BSD.txt. + +=============================================================================== http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/console/server-undertow/src/main/remote-resources/META-INF/NOTICE ---------------------------------------------------------------------- diff --git a/console/server-undertow/src/main/remote-resources/META-INF/NOTICE b/console/server-undertow/src/main/remote-resources/META-INF/NOTICE new file mode 100644 index 0000000..9c9e7e9 --- /dev/null +++ b/console/server-undertow/src/main/remote-resources/META-INF/NOTICE @@ -0,0 +1,28 @@ +=============================================================================== + +Portions of this software were developed by IBM Corp. +Copyright IBM Corp. 2015, 2016 + +=============================================================================== + +APACHE EDGENT SUBCOMPONENTS: + +This product includes a number of subcomponents with separate +copyright notices and license terms. The following notices apply. + +------------------------------------------------------------------------------- +metrics-core (io.dropwizard.metrics:metrics-core:3.1.2) + +Metrics +Copyright 2010-2013 Coda Hale and Yammer, Inc. + +This product includes software developed by Coda Hale and Yammer, Inc. + +This product includes code derived from the JSR-166 project (ThreadLocalRandom, +Striped64, LongAdder) with the following comments: + + Written by Doug Lea with assistance from members of JCP JSR-166 + Expert Group and released to the public domain, as explained at + http://creativecommons.org/publicdomain/zero/1.0/ + +=============================================================================== http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/d07dff67/console/server-undertow/src/test/java/org/apache/edgent/test/console/server/HttpServerPortTest.java ---------------------------------------------------------------------- diff --git a/console/server-undertow/src/test/java/org/apache/edgent/test/console/server/HttpServerPortTest.java b/console/server-undertow/src/test/java/org/apache/edgent/test/console/server/HttpServerPortTest.java new file mode 100644 index 0000000..82fc79a --- /dev/null +++ b/console/server-undertow/src/test/java/org/apache/edgent/test/console/server/HttpServerPortTest.java @@ -0,0 +1,58 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ +package org.apache.edgent.test.console.server; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assume.assumeTrue; + +import java.io.IOException; +import java.net.Socket; + +import org.apache.edgent.console.server.HttpServer; +import org.junit.Test; + +/** + * This is a separate test because the HttpServer implementation + * precludes changing the console port within a jvm instance. + */ +public class HttpServerPortTest { + + int getAvailablePort() throws IOException { + try (Socket s = new Socket()) { + s.bind(null); + return s.getLocalPort(); + } + } + + @Test + public void testOverridePortNumber() throws Exception { + // count on the OS not immediately reusing an available local port. + int port = getAvailablePort(); + int port2 = getAvailablePort(); + assumeTrue(port != port2); + + System.setProperty("edgent.console.port", String.valueOf(port)); + HttpServer myHttpServer = HttpServer.getInstance(); + myHttpServer.startServer(); + + int portNum = myHttpServer.getConsolePortNumber(); + assertEquals(port, portNum); + } + +}