Application.java
/*
* Copyright 2016 The Lannister Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.anyflow.lannister;
import java.util.concurrent.ThreadFactory;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.util.concurrent.DefaultThreadFactory;
import net.anyflow.lannister.cluster.Hazelcast;
import net.anyflow.lannister.http.WebServer;
import net.anyflow.lannister.server.MqttServer;
import net.anyflow.lannister.topic.Topic;
public class Application {
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(Application.class);
public static final Application INSTANCE = new Application();
private EventLoopGroup bossGroup;
private EventLoopGroup workerGroup;
private MqttServer mqttServer;
private WebServer webServer;
private Application() {
// Do nothing
}
public boolean start() {
try {
configureLog4j();
logger.info("Lannister bootstrapping started");
Topic.NEXUS.get(""); // TODO Just for initializing Topic.NEXUS. If
// absent, NoClassDefFound Error occur in
// Statistics.. I don't know why
startServers();
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
shutdown();
}
});
logger.info("Lannister bootstrapping completed");
logger.info("build version : {}", Settings.INSTANCE.version());
logger.info("build time : {}", Settings.INSTANCE.buildTime());
logger.info("commit ID : {}", Settings.INSTANCE.commitId());
logger.info("commit ID desc : {}", Settings.INSTANCE.commitIdDescribe());
logger.info("commit message : {}", Settings.INSTANCE.commitMessage());
logger.info("Netty transport mode : {}", Settings.INSTANCE.nettyTransportMode());
logger.info("Clustering mode : {}", Settings.INSTANCE.clusteringMode());
return true;
}
catch (Exception e) {
logger.error(e.getMessage(), e);
return false;
}
}
public void startServers() throws Exception {
int bossThreadCount = Settings.INSTANCE.getInt("netty.bossThreadCount", 0);
int workerThreadCount = Settings.INSTANCE.getInt("netty.workerThreadCount", 0);
ThreadFactory bossThreadFactory = new DefaultThreadFactory("lannister/boss");
ThreadFactory workerThreadFactory = new DefaultThreadFactory("lannister/worker");
if (Literals.NETTY_EPOLL.equals(Settings.INSTANCE.nettyTransportMode())) {
bossGroup = new EpollEventLoopGroup(bossThreadCount, bossThreadFactory);
workerGroup = new EpollEventLoopGroup(workerThreadCount, workerThreadFactory);
}
else {
bossGroup = new NioEventLoopGroup(bossThreadCount, bossThreadFactory);
workerGroup = new NioEventLoopGroup(workerThreadCount, workerThreadFactory);
}
mqttServer = new MqttServer(bossGroup, workerGroup);
mqttServer.start();
webServer = new WebServer(bossGroup, workerGroup);
webServer.start("net.anyflow");
}
public void shutdown() {
logger.info("Lannister shutting down...");
try {
if (bossGroup != null) {
bossGroup.shutdownGracefully().awaitUninterruptibly();
logger.debug("Boss event loop group shutdowned");
}
if (workerGroup != null) {
workerGroup.shutdownGracefully().awaitUninterruptibly();
logger.debug("Worker event loop group shutdowned");
}
Hazelcast.INSTANCE.shutdown();
}
catch (Exception e) {
logger.error(e.getMessage(), e);
}
logger.info("Lannister shutdowned gracefully");
}
public static void main(String[] args) {
Thread.currentThread().setName("main thread");
if (!INSTANCE.start()) {
System.exit(-1);
}
}
public static void configureLog4j() {
org.apache.log4j.xml.DOMConfigurator
.configure(Application.class.getClassLoader().getResource("lannister.log4j.xml"));
}
}