Skip to content

Commit

Permalink
Reference and app config. Undertow options. Add modules.
Browse files Browse the repository at this point in the history
  • Loading branch information
noboomu committed Apr 26, 2017
1 parent 81e75ff commit 21ddc86
Show file tree
Hide file tree
Showing 5 changed files with 279 additions and 134 deletions.
30 changes: 2 additions & 28 deletions conf/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ application {
version = "1.0"

name="Wurrly API"
# tmpdir
tmpdir = ${java.io.tmpdir}/${application.name}

# path (a.k.a. as contextPath)


path = "/v1"

# localhost
Expand All @@ -18,30 +16,6 @@ application {
# 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.server.handlers.ServerDefaultResponseListener"
# number format, system default. set it at runtime
# numberFormat = DecimalFormat.getInstance(${application.lang})).toPattern()

# comma separated list of locale using the language tag format. Default to: Locale.getDefault()
lang = Locale.getDefault()

# timezone, system default. set it at runtime
# tz = ZoneId.systemDefault().getId()

# redirect to/force https
# example: https://my.domain.com/{0}
redirect_https = ""


}
Expand Down
232 changes: 147 additions & 85 deletions src/main/java/io/sinistral/proteus/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
*
*/
package io.sinistral.proteus;
import java.util.HashSet;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
Expand All @@ -20,6 +22,7 @@
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.name.Named;
import com.jsoniter.DecodingMode;
import com.jsoniter.JsonIterator;
Expand Down Expand Up @@ -56,28 +59,56 @@ public class Application
@Named("registeredEndpoints")
protected Set<EndpointInfo> registeredEndpoints;

@Inject
@Named("registeredServices")
protected Set<Class<? extends Service>> registeredServices;

@Inject
protected RoutingHandler router;

@Inject
protected Config config;

protected List<com.google.inject.Module> registeredModules = new ArrayList<>();

protected Injector injector = null;
protected ServiceManager serviceManager = null;
protected Undertow undertow = null;

protected Set<Class<? extends Service>> registeredServices = new HashSet<>();

protected Undertow undertow = null;
protected Class<? extends HttpHandler> rootHandlerClass;

protected HttpHandler rootHandler;



public Application()
{

injector = Guice.createInjector(new ConfigModule());
injector.injectMembers(this);
injector = Guice.createInjector(new ConfigModule("application.conf"));
injector.injectMembers(this);

}

public Application(String configFile)
{

injector = Guice.createInjector(new ConfigModule(configFile));
injector.injectMembers(this);

}

public Application(URL configURL)
{

injector = Guice.createInjector(new ConfigModule(configURL));
injector.injectMembers(this);

}

public void start()
{
if( this.rootHandlerClass == null && this.rootHandler == null )

injector = injector.createChildInjector(registeredModules);

if( rootHandlerClass == null && rootHandler == null )
{
log.error("Cannot start the server without specifying the root handler class or a root HttpHandler!");
System.exit(1);
Expand All @@ -86,52 +117,61 @@ public void start()
log.info("Starting services...");

Set<Service> services = registeredServices.stream()
.map( sc -> injector.getInstance(sc))
.map( sc -> injector.getInstance(sc) )
.collect(Collectors.toSet());

this.serviceManager = new ServiceManager(services);

this.serviceManager.addListener(new Listener() {
public void stopped() {

}
public void healthy() {
log.info("Services are healthy...");

buildServer().start();
}
public void failure(Service service)
{
log.error("Error on service: " + service);
System.exit(1);
}
},
MoreExecutors.directExecutor());
serviceManager = new ServiceManager(services);

serviceManager.addListener(new Listener()
{
public void stopped()
{

}

public void healthy()
{
log.info("Services are healthy...");

buildServer().start();

printStatus();
}

public void failure(Service service)
{
log.error("Error on service: " + service);
System.exit(1);
}
}, MoreExecutors.directExecutor());

Runtime.getRuntime().addShutdownHook(new Thread()
{
@Override
public void run()
{
try
{
log.info("Shutting down...");

serviceManager.stopAsync().awaitStopped(5, TimeUnit.SECONDS);
undertow.stop();

log.info("Shutdown complete.");
} catch (TimeoutException timeout)
{
timeout.printStackTrace();
}
}
});

Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
try {
log.info("Shutting down...");

serviceManager.stopAsync().awaitStopped(5, TimeUnit.SECONDS);
undertow.stop();

log.info("Shutdown complete.");
} catch (TimeoutException timeout) {
timeout.printStackTrace();
}}});

serviceManager.startAsync();
}

}

public Undertow buildServer()
{

final Config rootConfig = injector.getInstance(Config.class);

final RoutingHandler router = injector.getInstance(RoutingHandler.class);


for(Class<?> controllerClass : registeredControllers)
{
HandlerGenerator generator = new HandlerGenerator("io.sinistral.proteus.controllers.handlers",controllerClass);
Expand All @@ -142,46 +182,31 @@ public Undertow buildServer()

router.addAll(generatedRouteSupplier.get());
}


Config globalHeaders = rootConfig.getConfig("globalHeaders");

Map<String,String> globalHeadersParameters = globalHeaders.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue().render()));


StringBuilder sb = new StringBuilder();

sb.append("\n\nUsing the following global headers: \n\n");
sb.append(globalHeadersParameters.entrySet().stream().map( e -> "\t" + e.getKey() + " = " + e.getValue() ).collect(Collectors.joining("\n")));
sb.append("\n\nRegistered the following endpoints: \n\n");
sb.append(this.registeredEndpoints.stream().sorted().map(EndpointInfo::toString).collect(Collectors.joining("\n")));
sb.append("\n");

log.info(sb.toString());

final HttpHandler handler;

if( this.rootHandlerClass != null )
if( rootHandlerClass != null )
{
handler = this.injector.getInstance(this.rootHandlerClass);
handler = injector.getInstance(rootHandlerClass);
}
else
{
handler = this.rootHandler;
handler = rootHandler;
}

undertow = Undertow.builder()
.addHttpListener(rootConfig.getInt("application.port"),rootConfig.getString("application.host"))
.setBufferSize(1024 * 16)
.setIoThreads(Runtime.getRuntime().availableProcessors()*2)
.setServerOption(UndertowOptions.ENABLE_HTTP2, true)
.setServerOption(UndertowOptions.ALWAYS_SET_DATE, true)
// .setServerOption(UndertowOptions.BUFFER_PIPELINED_DATA, true)
.setSocketOption(org.xnio.Options.BACKLOG, 10000)
.setServerOption(UndertowOptions.ALWAYS_SET_KEEP_ALIVE, false)
.setServerOption(UndertowOptions.RECORD_REQUEST_START_TIME, false)
.setServerOption(UndertowOptions.MAX_ENTITY_SIZE, 1000000L * 200 )
.setWorkerThreads(Runtime.getRuntime().availableProcessors()*8)
.addHttpListener(config.getInt("application.port"),config.getString("application.host"))
.setServerOption(UndertowOptions.ENABLE_HTTP2, config.getBoolean("undertow.server.enableHttp2"))
.setServerOption(UndertowOptions.ALWAYS_SET_DATE, config.getBoolean("undertow.server.alwaysSetDate"))
.setServerOption(UndertowOptions.BUFFER_PIPELINED_DATA, config.getBoolean("undertow.server.bufferPipelinedData"))
.setServerOption(UndertowOptions.ALWAYS_SET_KEEP_ALIVE, config.getBoolean("undertow.server.alwaysSetKeepAlive"))
.setServerOption(UndertowOptions.RECORD_REQUEST_START_TIME, config.getBoolean("undertow.server.recordRequestStartTime"))
.setServerOption(UndertowOptions.MAX_ENTITY_SIZE, config.getBytes("undertow.server.maxEntitySize") )
.setSocketOption(org.xnio.Options.BACKLOG, config.getInt("undertow.socket.backlog"))
.setWorkerThreads(config.getInt("undertow.workerThreads"))
.setBufferSize(config.getBytes("undertow.bufferSize").intValue())
.setIoThreads(config.getInt("undertow.ioThreads"))
.setDirectBuffers( config.getBoolean("undertow.directBuffers"))
.setHandler( handler )
.build();

Expand All @@ -192,13 +217,19 @@ public Undertow buildServer()

public Application addService(Class<? extends Service> serviceClass)
{
this.registeredServices.add(serviceClass);
registeredServices.add(serviceClass);
return this;
}

public Application addController(Class<?> controllerClass)
{
this.registeredControllers.add(controllerClass);
registeredControllers.add(controllerClass);
return this;
}

public Application addModule(Module module)
{
registeredModules.add(module);
return this;
}

Expand All @@ -212,16 +243,47 @@ public void setRootHandler( HttpHandler rootHandler )
this.rootHandler = rootHandler;
}


/**
* @return the undertow
*/

public Undertow getUndertow()
{
return undertow;
}


/**
* @return the serviceManager
*/
public ServiceManager getServiceManager()
{
return serviceManager;
}

/**
* @return the config
*/
public Config getConfig()
{
return config;
}

public void printStatus()
{
Config globalHeaders = config.getConfig("globalHeaders");

Map<String,String> globalHeadersParameters = globalHeaders.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue().render()));


StringBuilder sb = new StringBuilder();

sb.append("\n\nUsing the following global headers: \n\n");
sb.append(globalHeadersParameters.entrySet().stream().map( e -> "\t" + e.getKey() + " = " + e.getValue() ).collect(Collectors.joining("\n")));
sb.append("\n\nRegistered the following endpoints: \n\n");
sb.append(this.registeredEndpoints.stream().sorted().map(EndpointInfo::toString).collect(Collectors.joining("\n")));
sb.append("\n");

log.info(sb.toString());
}

public static void main(String[] args)
{

Expand Down
Loading

0 comments on commit 21ddc86

Please sign in to comment.