package org.stokesdrift;
import io.undertow.Undertow;
import io.undertow.servlet.Servlets;
import io.undertow.servlet.api.DeploymentInfo;
import io.undertow.servlet.api.DeploymentManager;
import io.undertow.servlet.api.ListenerInfo;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;
import org.stokesdrift.config.ApplicationConfig;
import org.stokesdrift.config.Options;
import org.stokesdrift.config.ServerConfig;
import org.stokesdrift.container.Application;
import org.stokesdrift.container.ApplicationBuilder;
import org.stokesdrift.container.ApplicationBuilderFactory;
import org.stokesdrift.web.listeners.CdiServletRequestListener;
/**
* Main starting point of loading the container and populating the registry for
* the micro services to interact with each other
*
* @author driedtoast
*
*/
public class Server {
private static final Logger logger = Logger.getLogger(Server.class.getName());
private ServerConfig config;
private List<Application> applications;
private Undertow server;
private Weld weld;
private WeldContainer container;
public static void main(String[] args) {
Server server = new Server(args);
try {
server.start();
} catch (Throwable t) {
logger.log(Level.SEVERE, "stokesdrift:server:start[status=failed]", t);
server.stop();
}
}
public Server(String[] args) {
initialize(args);
}
public void initialize(String[] args) {
Options options = new Options(args);
config = createConfig(options);
}
public ServerConfig createConfig(Options options) {
logger.log(Level.INFO, "stokesdrift:server:load_configuration[status=in_progress]");
System.setProperty("org.jboss.weld.se.archive.isolation", "false");
ServerConfig serverConfig = new ServerConfig(options);
try {
serverConfig.load();
logger.log(Level.INFO, "stokesdrift:server:load_configuration[status=complete, root="+serverConfig.getRootPath() + "]");
} catch(Throwable t) {
logger.log(Level.SEVERE, "stokesdrift:server:load_configuration[status=failed]", t);
serverConfig = null;
}
return serverConfig;
}
/**
* Loads up the application configuration for an application
*
* @param config
* @return list of applications
*/
public List<Application> loadApplicationDefinitions(ServerConfig config) {
logger.log(Level.INFO, "stokesdrift:server:load_app_definitions[status=in_progress]");
ApplicationBuilderFactory factory = container.instance().select(ApplicationBuilderFactory.class).get();
List<Application> apps = new ArrayList<Application>();
List<ApplicationConfig> appConfigs = config.getApplicationConfigs();
for (ApplicationConfig appConfig : appConfigs) {
ApplicationBuilder appBuilder = factory.getBuilder(appConfig.getType());
Application app = appBuilder.addConfig(appConfig).build();
// TODO add some debugging if app isn't able to be setup
if (app != null) {
logger.log(Level.INFO, "stokesdrift:server:loaded_app_definition[app="+appConfig.getName()+", type="+ appConfig.getType() +"]");
apps.add(app);
}
}
logger.log(Level.INFO, "stokesdrift:server:load_app_definitions[status=complete]");
return apps;
}
/**
* Setup the deployment managers for a given set of applications
*
* @param apps
* @return list of deployment managers
*/
public List<DeploymentManager> deployApplications(List<Application> apps) {
List<DeploymentManager> deployManagers = new ArrayList<DeploymentManager>();
for (Application app : apps) {
DeploymentInfo deployInfo = app.getDeploymentInfo();
// Add default listeners
ListenerInfo cdiListener = Servlets.listener(CdiServletRequestListener.class);
deployInfo.addListener(cdiListener);
DeploymentManager deploymentManager = Servlets.defaultContainer().addDeployment(deployInfo);
try {
deploymentManager.deploy();
deployManagers.add(deploymentManager);
} catch (Exception e) {
logger.log(Level.SEVERE, "stokesdrift:server:start[status=app_deploy_fail,app_type=" + app.getClass().getSimpleName() + "]", e);
}
}
return deployManagers;
}
public void start() throws Exception {
logger.log(Level.INFO, "stokesdrift:server:start[status=in_progress]");
logger.log(Level.INFO, "stokesdrift:server:load_cdi_container[status=in_progress]");
weld = new Weld();
container = weld.initialize();
logger.log(Level.INFO, "stokesdrift:server:load_cdi_container[status=complete]");
applications = loadApplicationDefinitions(config);
Undertow.Builder builder = Undertow.builder().addHttpListener(config.getPort(), config.getHost());
List<DeploymentManager> managers = deployApplications(applications);
for (DeploymentManager deploymentManager : managers) {
builder.setHandler(deploymentManager.start());
}
server = builder.build();
server.start();
logger.log(Level.INFO, "stokesdrift:server:http[port="+config.getPort()+",host="+config.getHost()+"]");
logger.log(Level.INFO, "stokesdrift:server:start[status=complete]");
}
public void stop() {
logger.log(Level.WARNING, "stokesdrift:server:stop[status=in_progress]");
if (server != null) {
server.stop();
}
if (weld != null) weld.shutdown();
logger.log(Level.INFO, "stokesdrift:server:stop[status=complete]");
}
}