diff --git a/pom.xml b/pom.xml index 226d44e..d52715a 100644 --- a/pom.xml +++ b/pom.xml @@ -128,7 +128,7 @@ - -Dconfig.file=src/main/resources/reference.conf + -Dconfig.file=src/test/resources/application.conf diff --git a/src/main/java/io/sinistral/proteus/ProteusApplication.java b/src/main/java/io/sinistral/proteus/ProteusApplication.java index d60bb1b..e1908f5 100644 --- a/src/main/java/io/sinistral/proteus/ProteusApplication.java +++ b/src/main/java/io/sinistral/proteus/ProteusApplication.java @@ -6,6 +6,7 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.InputStream; +import java.net.SocketAddress; import java.net.URL; import java.nio.ByteBuffer; import java.nio.file.Files; @@ -46,6 +47,7 @@ import io.sinistral.proteus.server.handlers.ServerDefaultHttpHandler; import io.sinistral.proteus.utilities.SecurityOps; import io.undertow.Undertow; +import io.undertow.Undertow.ListenerInfo; import io.undertow.UndertowOptions; import io.undertow.server.HttpHandler; import io.undertow.server.HttpServerExchange; @@ -155,6 +157,16 @@ public void healthy() buildServer(); undertow.start(); + + for(ListenerInfo info : undertow.getListenerInfo()) + { + SocketAddress address = info.getAddress(); + + if(address != null) + { + ports.add( ((java.net.InetSocketAddress) address).getPort()); + } + } printStatus(); @@ -191,8 +203,7 @@ public void shutdown() throws TimeoutException { if (!this.isRunning()) { - log.warn("Server is not running..."); - + log.warn("Server is not running..."); return; } @@ -242,8 +253,15 @@ public void buildServer() { handler = rootHandler; } - - Undertow.Builder undertowBuilder = Undertow.builder().addHttpListener(config.getInt("application.ports.http"), config.getString("application.host")) + + int httpPort = config.getInt("application.ports.http"); + + if(System.getProperty("http.port") != null) + { + httpPort = Integer.parseInt(System.getProperty("http.port")); + } + + Undertow.Builder undertowBuilder = Undertow.builder().addHttpListener(httpPort, config.getString("application.host")) .setBufferSize(16 * 1024) .setIoThreads(Runtime.getRuntime().availableProcessors() * 2) .setServerOption(UndertowOptions.ENABLE_HTTP2, config.getBoolean("undertow.enableHttp2")) @@ -255,18 +273,23 @@ public void buildServer() .setWorkerThreads(config.getInt("undertow.workerThreads")) .setHandler(handler); - ports.add(config.getInt("application.ports.http")); - + if (config.getBoolean("undertow.ssl.enabled")) { try { + int httpsPort = config.getInt("application.ports.https"); + + if(System.getProperty("https.port") != null) + { + httpsPort = Integer.parseInt(System.getProperty("https.port")); + } + KeyStore keyStore = SecurityOps.loadKeyStore(config.getString("undertow.ssl.keystorePath"), config.getString("undertow.ssl.keystorePassword")); KeyStore trustStore = SecurityOps.loadKeyStore(config.getString("undertow.ssl.truststorePath"), config.getString("undertow.ssl.truststorePassword")); - undertowBuilder.addHttpsListener(config.getInt("application.ports.https"), config.getString("application.host"), SecurityOps.createSSLContext(keyStore, trustStore, config.getString("undertow.ssl.keystorePassword"))); - - ports.add(config.getInt("application.ports.https")); + undertowBuilder.addHttpsListener(httpsPort, config.getString("application.host"), SecurityOps.createSSLContext(keyStore, trustStore, config.getString("undertow.ssl.keystorePassword"))); + } catch (Exception e) { @@ -481,6 +504,23 @@ public void handleRequest(HttpServerExchange exchange) throws Exception } } + /** + * @return the router + */ + public RoutingHandler getRouter() + { + return router; + } + + + /** + * @return the ports + */ + public List getPorts() + { + return ports; + } + } diff --git a/src/test/java/io/sinistral/proteus/server/DefaultServer.java b/src/test/java/io/sinistral/proteus/server/DefaultServer.java index e8e4eb1..5d34af9 100644 --- a/src/test/java/io/sinistral/proteus/server/DefaultServer.java +++ b/src/test/java/io/sinistral/proteus/server/DefaultServer.java @@ -3,13 +3,18 @@ */ package io.sinistral.proteus.server; +import java.util.List; + import org.junit.runner.Description; import org.junit.runner.Result; import org.junit.runner.notification.RunListener; import org.junit.runner.notification.RunNotifier; import org.junit.runners.BlockJUnit4ClassRunner; import org.junit.runners.model.InitializationError; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import io.restassured.RestAssured; import io.sinistral.proteus.ProteusApplication; import io.sinistral.proteus.controllers.Tests; import io.sinistral.proteus.services.AssetsService; @@ -20,17 +25,17 @@ */ public class DefaultServer extends BlockJUnit4ClassRunner { + private static Logger log = LoggerFactory.getLogger(DefaultServer.class.getCanonicalName()); - private static ProteusApplication app; private static boolean first = true; /** - * @param klass + * @param clazz * @throws InitializationError */ - public DefaultServer(Class klass) throws InitializationError + public DefaultServer(Class clazz) throws InitializationError { - super(klass); + super(clazz); } @Override @@ -60,18 +65,41 @@ public void testFinished(Description description) throws Exception private static void runInternal(final RunNotifier notifier) { - - System.out.println(System.getenv("config.file")); + if (first) - { + { + first = false; - app = new ProteusApplication(); + + final ProteusApplication app = new ProteusApplication(); + app.addService(SwaggerService.class); app.addService(AssetsService.class); app.addController(Tests.class); app.start(); - + + int port = 0; + + try + { + Thread.sleep(2000); + + List ports = app.getPorts(); + + port = ports.get(0); + + } catch (Exception e) + { + log.error(e.getMessage(),e); + } + + + + RestAssured.baseURI = String.format("http://localhost:%d/v1",port); + + RestAssured.enableLoggingOfRequestAndResponseIfValidationFails(); + while (!app.isRunning()) { try diff --git a/src/test/java/io/sinistral/proteus/server/TestControllerEndpoints.java b/src/test/java/io/sinistral/proteus/server/TestControllerEndpoints.java index 16115c2..accdb6e 100644 --- a/src/test/java/io/sinistral/proteus/server/TestControllerEndpoints.java +++ b/src/test/java/io/sinistral/proteus/server/TestControllerEndpoints.java @@ -27,7 +27,7 @@ import io.restassured.http.ContentType; import io.sinistral.proteus.models.User; import io.sinistral.proteus.models.User.UserType; - + /* * import static io.restassured.RestAssured.*; import static io.restassured.matcher.RestAssuredMatchers.*; import static org.hamcrest.Matchers.*; */ @@ -45,9 +45,7 @@ public void setUp() { try { - RestAssured.baseURI = "http://localhost:8090/v1"; - RestAssured.enableLoggingOfRequestAndResponseIfValidationFails(); - + file = new File(getClass().getClassLoader().getResource("data/video.mp4").toURI()); } catch (Exception e) diff --git a/src/test/resources/application.conf b/src/test/resources/application.conf new file mode 100644 index 0000000..ecb1910 --- /dev/null +++ b/src/test/resources/application.conf @@ -0,0 +1,145 @@ + +application { + + env = dev + + version = "1.0" + + name="proteus" + + path = "/v1" + + host = "localhost" + + ports { + http = 0 + # https = 8443 + } + + charset = UTF-8 + + fallbackHandler = "io.sinistral.proteus.server.handlers.ServerFallbackHandler" + + defaultResponseListener = "io.sinistral.proteus.server.handlers.ServerDefaultResponseListener" + + tmpdir = ${java.io.tmpdir}/${application.name} + + # path to default favicon file + favicon = "/io/sinistral/proteus/favicon.ico" + +} + +api.version="v1" + +globalHeaders +{ +# Access-Control-Allow-Origin: "*" +# Access-Control-Allow-Methods: "*" +# Access-Control-Allow-Headers: "*" + Server = ${application.name} +} + +health { + statusPath = "/internal/status" +} + + + +assets { + # the base path assets will be server from + path = "/public" + # the directory to load the assets from + dir = "./assets" + cache { + # cache timeout for the assets + time = 500 + } + + +} + + + +swagger { + # the path that has an index.html template and theme css files + resourcePrefix="io/sinistral/proteus/swagger" + # swagger version + swagger="2.0" + info { + # swagger info title + title = ${application.name} + # swagger info version + version = ${application.version} + } + # swagger-ui theme from ostranme's swagger-ui-themes, the following are built-in [feeling-blue, flattop, material, monokai, muted, newspaper, outline] + # specifying a different name causes the SwaggerService to search in {swagger.resourcePrefix}/themes for a file named "theme-{swagger.theme}.css" + theme="default" + # where the swagger endpoints will be mounted + basePath= ${application.path}"/swagger" + # where redoc will be mounted relative to swagger base path + redocPath= "redoc" + #the name of the spec file + specFilename="swagger.json" + consumes = ["application/json"] + produces = ["application/json"] + port = ${application.ports.http} + + security = + { + apiKeys = [ + { + key="defaultApiKey" + in="HEADER", + name="default-api-key" + value="123456789" + } + ] + +# basicRealms = +# [ +# { +# name = defaultBasic +# identities = +# [ +# "username:password" +# ] +# } +# ] + } + + +} + +undertow +{ + server { + enableHttp2 = false + alwaysSetDate = true + alwaysSetKeepAlive = false + recordRequestStartTime = false + maxEntitySize = 100M + bufferPipelinedData = false + } + + socket { + backlog = 10000 + } + + + ssl { + enabled=false + keystorePath="development.jks" + truststorePath="development.ts" + keystorePassword="password" + truststorePassword="password" + } + + enableHttp2=false + # x AvailableProcessors + ioThreads = 16 + workerThreads = 200 + bufferSize = 16K + directBuffers = true +} + + \ No newline at end of file