View Javadoc
1   /*
2    * Copyright 2016 The Lannister Project
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package net.anyflow.lannister;
18  
19  import java.util.concurrent.ThreadFactory;
20  
21  import io.netty.channel.EventLoopGroup;
22  import io.netty.channel.epoll.EpollEventLoopGroup;
23  import io.netty.channel.nio.NioEventLoopGroup;
24  import io.netty.util.concurrent.DefaultThreadFactory;
25  import net.anyflow.lannister.cluster.Hazelcast;
26  import net.anyflow.lannister.http.WebServer;
27  import net.anyflow.lannister.server.MqttServer;
28  import net.anyflow.lannister.topic.Topic;
29  
30  public class Application {
31  
32  	private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(Application.class);
33  
34  	public static final Application INSTANCE = new Application();
35  
36  	private EventLoopGroup bossGroup;
37  	private EventLoopGroup workerGroup;
38  
39  	private MqttServer mqttServer;
40  	private WebServer webServer;
41  
42  	private Application() {
43  		// Do nothing
44  	}
45  
46  	public boolean start() {
47  		try {
48  			configureLog4j();
49  
50  			logger.info("Lannister bootstrapping started");
51  
52  			Topic.NEXUS.get(""); // TODO Just for initializing Topic.NEXUS. If
53  									// absent, NoClassDefFound Error occur in
54  									// Statistics.. I don't know why
55  
56  			startServers();
57  
58  			Runtime.getRuntime().addShutdownHook(new Thread() {
59  				@Override
60  				public void run() {
61  					shutdown();
62  				}
63  			});
64  
65  			logger.info("Lannister bootstrapping completed");
66  			logger.info("build version  : {}", Settings.INSTANCE.version());
67  			logger.info("build time     : {}", Settings.INSTANCE.buildTime());
68  			logger.info("commit ID      : {}", Settings.INSTANCE.commitId());
69  			logger.info("commit ID desc : {}", Settings.INSTANCE.commitIdDescribe());
70  			logger.info("commit message : {}", Settings.INSTANCE.commitMessage());
71  			logger.info("Netty transport mode : {}", Settings.INSTANCE.nettyTransportMode());
72  			logger.info("Clustering mode : {}", Settings.INSTANCE.clusteringMode());
73  
74  			return true;
75  		}
76  		catch (Exception e) {
77  			logger.error(e.getMessage(), e);
78  			return false;
79  		}
80  	}
81  
82  	public void startServers() throws Exception {
83  		int bossThreadCount = Settings.INSTANCE.getInt("netty.bossThreadCount", 0);
84  		int workerThreadCount = Settings.INSTANCE.getInt("netty.workerThreadCount", 0);
85  
86  		ThreadFactory bossThreadFactory = new DefaultThreadFactory("lannister/boss");
87  		ThreadFactory workerThreadFactory = new DefaultThreadFactory("lannister/worker");
88  
89  		if (Literals.NETTY_EPOLL.equals(Settings.INSTANCE.nettyTransportMode())) {
90  			bossGroup = new EpollEventLoopGroup(bossThreadCount, bossThreadFactory);
91  			workerGroup = new EpollEventLoopGroup(workerThreadCount, workerThreadFactory);
92  		}
93  		else {
94  			bossGroup = new NioEventLoopGroup(bossThreadCount, bossThreadFactory);
95  			workerGroup = new NioEventLoopGroup(workerThreadCount, workerThreadFactory);
96  		}
97  
98  		mqttServer = new MqttServer(bossGroup, workerGroup);
99  		mqttServer.start();
100 
101 		webServer = new WebServer(bossGroup, workerGroup);
102 		webServer.start("net.anyflow");
103 	}
104 
105 	public void shutdown() {
106 		logger.info("Lannister shutting down...");
107 
108 		try {
109 			if (bossGroup != null) {
110 				bossGroup.shutdownGracefully().awaitUninterruptibly();
111 				logger.debug("Boss event loop group shutdowned");
112 			}
113 
114 			if (workerGroup != null) {
115 				workerGroup.shutdownGracefully().awaitUninterruptibly();
116 				logger.debug("Worker event loop group shutdowned");
117 			}
118 
119 			Hazelcast.INSTANCE.shutdown();
120 		}
121 		catch (Exception e) {
122 			logger.error(e.getMessage(), e);
123 		}
124 
125 		logger.info("Lannister shutdowned gracefully");
126 	}
127 
128 	public static void main(String[] args) {
129 		Thread.currentThread().setName("main thread");
130 
131 		if (!INSTANCE.start()) {
132 			System.exit(-1);
133 		}
134 	}
135 
136 	public static void configureLog4j() {
137 		org.apache.log4j.xml.DOMConfigurator
138 				.configure(Application.class.getClassLoader().getResource("lannister.log4j.xml"));
139 	}
140 }