Skip to content

Commit

Permalink
Cleanup configuration. Added SSL support.
Browse files Browse the repository at this point in the history
  • Loading branch information
noboomu committed May 15, 2017
1 parent d951c43 commit 8450d2c
Show file tree
Hide file tree
Showing 13 changed files with 163 additions and 78 deletions.
60 changes: 41 additions & 19 deletions src/test/resources/reference.conf → conf/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,23 @@ application {
version = "1.0"

name="proteus"
# tmpdir
tmpdir =${java.io.tmpdir}

# path (a.k.a. as contextPath)
path = "/v1"

# localhost
host = "localhost"

ports {
http = 8090
https = 8443
}

# HTTP ports
port = 8090

# uncomment to enabled HTTPS
# securePort = 8443

# we do UTF-8
charset = UTF-8

# date format
dateFormat = dd-MMM-yyyy


fallbackHandler = "io.sinistral.proteus.server.handlers.ServerFallbackHandler"

defaultResponseListener = "io.sinistral.proteus.server.handlers.ServerDefaultResponseListener"
redirect_https = ""

tmpdir = ${java.io.tmpdir}/${application.name}

}

Expand All @@ -45,29 +36,49 @@ globalHeaders
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 {
swagger: "2.0"
# 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"]
schemes = ["http"]
port = ${application.ports.http}

}

undertow
Expand All @@ -84,6 +95,17 @@ undertow
socket {
backlog = 10000
}


ssl {
enabled=true
keystorePath="development.jks"
truststorePath="development.ts"
keystorePassword="password"
truststorePassword="password"
}


# x AvailableProcessors
ioThreads = 16
workerThreads = 200
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<filtering>false</filtering>
</resource>
</resources>
<testResources>
Expand Down
41 changes: 35 additions & 6 deletions src/main/java/io/sinistral/proteus/ProteusApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
package io.sinistral.proteus;
import java.net.URL;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -40,6 +41,7 @@
import io.sinistral.proteus.server.handlers.HandlerGenerator;
import io.sinistral.proteus.services.AssetsService;
import io.sinistral.proteus.services.SwaggerService;
import io.sinistral.proteus.utilities.SecurityOps;
import io.undertow.Undertow;
import io.undertow.UndertowOptions;
import io.undertow.server.HttpHandler;
Expand Down Expand Up @@ -78,6 +80,7 @@ public class ProteusApplication
protected Class<? extends HttpHandler> rootHandlerClass;
protected HttpHandler rootHandler;
protected AtomicBoolean running = new AtomicBoolean(false);
protected List<Integer> ports = new ArrayList<>();


public ProteusApplication()
Expand Down Expand Up @@ -229,19 +232,45 @@ public void buildServer()
handler = rootHandler;
}

this.undertow = Undertow.builder()
.addHttpListener(config.getInt("application.port"),config.getString("application.host"))
Undertow.Builder undertowBuilder = Undertow.builder()
.addHttpListener(config.getInt("application.ports.http"),config.getString("application.host"))
.setBufferSize(16 * 1024)
.setIoThreads( config.getInt("undertow.ioThreads") )
.setServerOption(UndertowOptions.ENABLE_HTTP2, true)
.setServerOption(UndertowOptions.ENABLE_HTTP2, false)
.setServerOption(UndertowOptions.ALWAYS_SET_DATE, true)
.setSocketOption(org.xnio.Options.BACKLOG, config.getInt("undertow.socket.backlog") )
.setServerOption(UndertowOptions.ALWAYS_SET_KEEP_ALIVE, false)
.setServerOption(UndertowOptions.RECORD_REQUEST_START_TIME, false)
.setServerOption(UndertowOptions.MAX_ENTITY_SIZE, config.getBytes("undertow.server.maxEntitySize") )
.setWorkerThreads( config.getInt("undertow.workerThreads") )
.setHandler( handler )
.build();
.setHandler( handler );

ports.add(config.getInt("application.ports.http"));

if( config.getBoolean("undertow.ssl.enabled") )
{
try
{
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"));

} catch (Exception e)
{
log.error(e.getMessage(),e);
}
}

this.undertow = undertowBuilder.build();

}

Expand Down Expand Up @@ -327,7 +356,7 @@ public void printStatus()

sb.append("\n");

sb.append("\nListening on port " + config.getInt("application.port"));
sb.append("\nListening on: " + this.ports);

sb.append("\n");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,10 @@ public int hashCode()
public int compareTo(EndpointInfo other) {

return new CompareToBuilder()
.append(this.pathTemplate, other.pathTemplate)
.append(this.controllerName, other.controllerName)
.append(this.method, other.method)
.append(this.controllerMethod, other.controllerMethod)
.append(this.pathTemplate, other.pathTemplate)
.append(this.method, other.method)

.toComparison();
}
Expand All @@ -166,7 +166,7 @@ public int compareTo(EndpointInfo other) {
@Override
public String toString()
{
return String.format("%-8s %-40s %-26s %-26s %s", this.method, this.pathTemplate, "[" + this.consumes + "]", "[" + this.produces+ "]", "("+this.controllerName+"."+this.controllerMethod+ ")");
return String.format("\t%-8s %-40s %-26s %-26s %s", this.method, this.pathTemplate, "[" + this.consumes + "]", "[" + this.produces+ "]", "("+this.controllerName+"."+this.controllerMethod+ ")");
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public class SwaggerService extends BaseService implements Supplier<RoutingHan
protected String applicationName;

@Inject
@Named("application.port")
@Named("swagger.port")
protected Integer port;

@Inject
Expand Down
108 changes: 64 additions & 44 deletions src/main/java/io/sinistral/proteus/utilities/SecurityOps.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,64 +3,84 @@
*/
package io.sinistral.proteus.utilities;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.security.KeyStore;
import java.util.jar.JarFile;
import java.util.zip.ZipInputStream;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* @author jbauer
*
*/
public class SecurityOps
{
public static SSLContext createSSLContext(final KeyStore keyStore, final KeyStore trustStore, final String password) throws Exception {
KeyManager[] keyManagers;
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, password.toCharArray());
keyManagers = keyManagerFactory.getKeyManagers();

TrustManager[] trustManagers;
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
trustManagers = trustManagerFactory.getTrustManagers();

SSLContext sslContext;
sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagers, trustManagers, null);

return sslContext;
}

public static KeyStore loadKeyStore(String storePath, String password) throws Exception
{

try( final InputStream stream = Files.newInputStream(Paths.get(storePath)) )
{
if(stream == null) {
throw new RuntimeException("Could not load keystore");
}

try(InputStream is = stream)
{

KeyStore loadedKeystore = KeyStore.getInstance("JKS");
loadedKeystore.load(is, password.toCharArray());
return loadedKeystore;

} catch(Exception e)
{
throw new RuntimeException("Could not load keystore: " + e.getMessage());
}
}



}

@SuppressWarnings("resource")
public static KeyStore loadKeyStore(String name, String password) throws Exception
{

File storeFile = new File(name);

InputStream stream = null;

if (!storeFile.exists())
{
stream = SecurityOps.class.getResourceAsStream("/" + name);

}
else
{

stream = Files.newInputStream(Paths.get(name));
}

if (stream == null)
{
throw new RuntimeException("Could not load keystore");
}

try (InputStream is = stream)
{
KeyStore loadedKeystore = KeyStore.getInstance("JKS");
loadedKeystore.load(is, password.toCharArray());
return loadedKeystore;
}
}

public static SSLContext createSSLContext(final KeyStore keyStore, final KeyStore trustStore, final String password) throws Exception
{
KeyManager[] keyManagers;
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, password.toCharArray());
keyManagers = keyManagerFactory.getKeyManagers();

TrustManager[] trustManagers;
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
trustManagers = trustManagerFactory.getTrustManagers();

SSLContext sslContext;
sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagers, trustManagers, null);

return sslContext;
}

}
Binary file added src/main/resources/development.cer
Binary file not shown.
Binary file added src/main/resources/development.jks
Binary file not shown.
Binary file added src/main/resources/development.ts
Binary file not shown.
File renamed without changes
Loading

0 comments on commit 8450d2c

Please sign in to comment.