1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.waarp.common.service;
21
22 import org.apache.commons.daemon.Daemon;
23 import org.apache.commons.daemon.DaemonContext;
24 import org.apache.commons.daemon.DaemonController;
25 import org.waarp.common.exception.InvalidArgumentException;
26 import org.waarp.common.logging.SysErrLogger;
27 import org.waarp.common.logging.WaarpLogger;
28 import org.waarp.common.logging.WaarpLoggerFactory;
29 import org.waarp.common.logging.WaarpSlf4JLoggerFactory;
30 import org.waarp.common.utility.WaarpSystemUtil;
31 import org.waarp.common.utility.WaarpThreadFactory;
32
33 import java.util.Scanner;
34 import java.util.concurrent.ExecutorService;
35 import java.util.concurrent.Executors;
36
37
38
39
40
41
42
43 public abstract class ServiceLauncher implements Daemon {
44
45
46
47 protected static WaarpLogger logger;
48
49 protected static EngineAbstract engine;
50
51 protected static ServiceLauncher engineLauncherInstance;
52
53 protected ExecutorService executor;
54
55 protected static DaemonController controller;
56
57 protected static boolean stopCalledCorrectly;
58
59
60
61
62 protected abstract EngineAbstract getNewEngineAbstract();
63
64 protected ServiceLauncher() {
65 if (logger == null) {
66 logger = WaarpLoggerFactory.getLogger(ServiceLauncher.class);
67 }
68 if (executor == null) {
69 executor = Executors.newSingleThreadExecutor(
70 new WaarpThreadFactory("ServiceLauncher"));
71 }
72 engineLauncherInstance = this;
73 if (engine == null) {
74 engine = getNewEngineAbstract();
75 }
76 }
77
78 protected static void initStatic() {
79 WaarpLoggerFactory.setDefaultFactoryIfNotSame(
80 new WaarpSlf4JLoggerFactory(null));
81 if (logger == null) {
82 logger = WaarpLoggerFactory.getLogger(ServiceLauncher.class);
83 }
84 final String className =
85 Thread.currentThread().getStackTrace()[3].getClassName();
86
87 logger.debug("Engine {}", className);
88 try {
89 engineLauncherInstance =
90 (ServiceLauncher) WaarpSystemUtil.newInstance(className);
91 } catch (final Throwable e) {
92 logger.error("Engine not correctly initialized", e);
93 System.exit(2);
94 }
95 if (engineLauncherInstance == null || engine == null) {
96 logger.error("Engine not correctly initialized");
97 System.exit(1);
98 }
99 }
100
101
102
103
104
105
106 public static void _main(final String[] args) {
107 initStatic();
108
109 engineLauncherInstance.initialize();
110
111 final Scanner sc = new Scanner(System.in);
112
113 SysErrLogger.FAKE_LOGGER.sysout("Enter 'stop' to halt: ");
114 while (!"stop".equalsIgnoreCase(sc.nextLine())) {
115
116 }
117
118 if (!engine.isShutdown()) {
119 engineLauncherInstance.terminate();
120 }
121 sc.close();
122 }
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142 public static void _windowsService(final String[] args) throws Exception {
143 initStatic();
144 String cmd = "start";
145 if (args.length > 0) {
146 cmd = args[0];
147 }
148 if ("start".equals(cmd)) {
149 engineLauncherInstance.windowsStart();
150 } else {
151 engineLauncherInstance.windowsStop();
152 }
153 }
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170 public static void _windowsStart(final String[] args) throws Exception {
171 initStatic();
172 engineLauncherInstance.windowsStart();
173 }
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188 public static void _windowsStop(final String[] args) {
189 initStatic();
190 stopCalledCorrectly = true;
191 engineLauncherInstance.windowsStop();
192 }
193
194
195
196
197
198
199 protected void windowsStart() throws Exception {
200 logger.info("windowsStart called");
201 initialize();
202
203 boolean status = false;
204 try {
205 status = engine.waitShutdown();
206 } catch (final InterruptedException e) {
207 SysErrLogger.FAKE_LOGGER.ignoreLog(e);
208 }
209 if (!status || !stopCalledCorrectly) {
210
211 terminate();
212 if (controller != null) {
213 controller.fail("Service stopped abnormally");
214 } else {
215 throw new InvalidArgumentException("Service stopped abnormally");
216 }
217 }
218 }
219
220
221
222
223 protected void windowsStop() {
224 logger.info("windowsStop called from Service: {}", stopCalledCorrectly);
225 terminate();
226
227 }
228
229
230 @Override
231 public void init(final DaemonContext arg0) {
232 controller = arg0.getController();
233 logger.info("Daemon init");
234 }
235
236 @Override
237 public void start() {
238 logger.info("Daemon start");
239 initialize();
240 }
241
242 @Override
243 public void stop() {
244 logger.info("Daemon stop");
245 terminate();
246 }
247
248 @Override
249 public void destroy() {
250 logger.info("Daemon destroy");
251 terminate();
252 }
253
254
255
256
257 protected void initialize() {
258 if (engine != null) {
259 logger.info("Starting the Engine");
260 engine.setDaemon(true);
261 executor.execute(engine);
262 } else {
263 logger.error("Engine cannot be started since it is not initialized");
264 }
265 }
266
267
268
269
270 protected void terminate() {
271 if (engine != null) {
272 logger.info("Stopping the Engine");
273 engine.shutdown();
274 engine = null;
275 }
276 if (executor != null) {
277 executor.shutdown();
278 executor = null;
279 }
280 logger.info("Engine stopped");
281 }
282 }