package cloudone.internal;
import cloudone.ApplicationInfo;
import cloudone.C1Application;
import cloudone.C1Services;
import cloudone.LifecycleService;
import cloudone.internal.nimbostratus.CumulonimbusClient;
import cloudone.internal.nimbostratus.NimbostratusApp;
import org.apache.commons.cli.HelpFormatter;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.URI;
import java.util.stream.Stream;
/**
* Main class for all CloudOne application.
*
* @author Martin Mares (martin.mares at oracle.com)
*/
public class ServiceMain {
private static final Logger LOGGER = LoggerFactory.getLogger(ServiceMain.class);
private final ApplicationInfo nimbostratusAppInfo;
private ServiceMain() {
nimbostratusAppInfo = new ApplicationInfo() {
private final NimbostratusApp app = new NimbostratusApp();
@Override
public C1Application getApplication() {
return app;
}
@Override
public String getName() {
return "Nimbostratus";
}
@Override
public int getPort() {
return C1Services.getInstance().getRuntimeInfo().getAdminPort();
}
};
}
private Stream<ApplicationInfo> getAllAppInfoStream() {
return Stream.concat(C1Services.getInstance().getRuntimeInfo().getApplicationInfos().stream(),
Stream.of(this.nimbostratusAppInfo));
}
private void run() throws Exception{
final RuntimeInfoImpl runtimeInfo = (RuntimeInfoImpl) C1Services.getInstance().getRuntimeInfo();
//Help?
if (runtimeInfo.getCommandLine().hasOption('h')) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp(runtimeInfo.getServiceFullName().getArtifactId() + " Service",
RuntimeInfoImpl.getInstance().getCmdlOptions());
return;
}
//Port update
updatePortNumbers(runtimeInfo);
//Start all applications
LOGGER.info("STARTING: " + runtimeInfo.getServiceFullName());
LifecycleServiceImpl lifecycleService = (LifecycleServiceImpl) C1Services.getInstance().getLifecycleService();
getAllAppInfoStream().forEach(info -> {
try {
info.getApplication().init();
LOGGER.info("STARTING Application: " + info.getName() + " on " + info.getPort());
final ResourceConfig resourceConfig = ResourceConfig.forApplication(info.getApplication());
final URI uri = URI.create("http://localhost:" + info.getPort() + "/");
final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(uri, resourceConfig);
lifecycleService.registerListener(new LifecycleService.LifecycleListener() {
@Override
public void onStart() {
}
@Override
public void onShutdown() {
LOGGER.info("--------------- SHUTDOWN: " + info.getName() + " ---------------");
server.shutdown();
info.getApplication().shutDown();
}
});
} catch (Exception e) {
throw new RuntimeException(e);
}
});
//Register service
CumulonimbusClient.getInstance().register();
lifecycleService.registerListener(new LifecycleService.LifecycleListener() {
@Override
public void onStart() {
}
@Override
public void onShutdown() {
try {
CumulonimbusClient.getInstance().unregister();
} catch (Exception e) {
LOGGER.warn("Cannot uregister service from cumulonimbus!", e);
}
}
});
//Start
lifecycleService.start();
getAllAppInfoStream().forEach(info -> {
info.getApplication().started();
LOGGER.info("--------------- " + info.getName() + " is RUNNING on port " + info.getPort() + " ---------------");
});
//Wait for stop signal
lifecycleService.awaitForShutdown();
}
private void updatePortNumbers(final RuntimeInfoImpl runtimeInfo) {
if (runtimeInfo.getAdminPort() < 0) {
runtimeInfo.setAdminPort(CumulonimbusClient.getInstance().reservePort(true));
}
runtimeInfo
.getApplicationInfos()
.stream()
.filter(ai -> ai.getPort() < 0)
.forEach(info -> ((ApplicationInfoImpl) info).setPort(CumulonimbusClient.getInstance().reservePort(false)));
}
public static void main(String[] args) {
try {
(new RuntimeInfoImpl.Builder())
.findApplications()
.processCommandLineArgs(args)
.build();
} catch (Exception exc) {
LOGGER.error("Initialisation issue!", exc);
}
try {
ServiceMain serviceMain = new ServiceMain();
serviceMain.run();
} catch (Exception exc) {
LOGGER.error("Unexpected exception in main thread", exc);
System.exit(1);
}
}
}