1
2
3
4
5
6
7 package org.mule;
8
9 import org.mule.api.DefaultMuleException;
10 import org.mule.api.MuleContext;
11 import org.mule.api.MuleException;
12 import org.mule.api.config.ConfigurationBuilder;
13 import org.mule.api.config.ConfigurationException;
14 import org.mule.api.config.MuleConfiguration;
15 import org.mule.api.context.MuleContextBuilder;
16 import org.mule.api.context.MuleContextFactory;
17 import org.mule.config.ExceptionHelper;
18 import org.mule.config.PropertiesMuleConfigurationFactory;
19 import org.mule.config.StartupContext;
20 import org.mule.config.builders.SimpleConfigurationBuilder;
21 import org.mule.config.i18n.CoreMessages;
22 import org.mule.config.i18n.Message;
23 import org.mule.context.DefaultMuleContextBuilder;
24 import org.mule.context.DefaultMuleContextFactory;
25 import org.mule.util.ClassUtils;
26 import org.mule.util.IOUtils;
27 import org.mule.util.MuleUrlStreamHandlerFactory;
28 import org.mule.util.PropertiesUtils;
29 import org.mule.util.StringMessageUtils;
30 import org.mule.util.SystemUtils;
31
32 import java.io.IOException;
33 import java.net.URL;
34 import java.util.ArrayList;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Properties;
38
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41
42
43
44
45
46 public class MuleServer implements Runnable
47 {
48 public static final String CLI_OPTIONS[][] = {
49 {"builder", "true", "Configuration Builder Type"},
50 {"config", "true", "Configuration File"},
51 {"appconfig", "true", "Application configuration File"},
52 {"idle", "false", "Whether to run in idle (unconfigured) mode"},
53 {"main", "true", "Main Class"},
54 {"mode", "true", "Run Mode"},
55 {"props", "true", "Startup Properties"},
56 {"production", "false", "Production Mode"},
57 {"debug", "false", "Configure Mule for JPDA remote debugging."}
58 };
59
60
61
62
63 protected static final String CLASSNAME_DEFAULT_CONFIG_BUILDER = "org.mule.config.builders.AutoConfigurationBuilder";
64
65
66
67
68
69 protected static final String CLASSNAME_DEFAULT_IDLE_CONFIG_BUILDER = "org.mule.config.builders.MuleIdleConfigurationBuilder";
70
71
72
73
74
75
76 protected static final String CLASSNAME_SPRING_CONFIG_BUILDER = "org.mule.config.spring.SpringXmlConfigurationBuilder";
77
78
79
80
81 public static final String CLASSNAME_ANNOTATIONS_CONFIG_BUILDER = "org.mule.config.AnnotationsConfigurationBuilder";
82
83
84
85
86 public static final String CLASSNAME_IBEANS_CONFIG_BUILDER = "org.mule.module.ibeans.config.IBeanHolderConfigurationBuilder";
87
88
89
90
91 private static final Log logger = LogFactory.getLog(MuleServer.class);
92
93 public static final String DEFAULT_CONFIGURATION = "mule-config.xml";
94
95 public static final String DEFAULT_APP_CONFIGURATION = "mule-app.properties";
96
97
98
99
100 private String configurationResources = null;
101
102 private String appConfigurationResource = null;
103
104
105
106
107
108 private static String configBuilderClassName = null;
109
110
111
112
113
114 private static String startupPropertiesFile = null;
115
116
117
118
119 private static MuleShutdownHook muleShutdownHook;
120
121
122
123
124
125
126
127 protected static MuleContext muleContext = null;
128
129
130
131
132
133
134
135 public static void main(String[] args) throws Exception
136 {
137 MuleServer server = new MuleServer(args);
138 server.start(false, true);
139
140 }
141
142 public MuleServer()
143 {
144 init(new String[]{});
145 }
146
147 public MuleServer(String configResources)
148 {
149
150 init(new String[]{"-config", configResources});
151 }
152
153
154
155
156
157
158 public MuleServer(String[] args) throws IllegalArgumentException
159 {
160 init(args);
161 }
162
163 protected void init(String[] args) throws IllegalArgumentException
164 {
165 Map<String, Object> commandlineOptions;
166
167 try
168 {
169 commandlineOptions = SystemUtils.getCommandLineOptions(args, CLI_OPTIONS);
170 }
171 catch (DefaultMuleException me)
172 {
173 throw new IllegalArgumentException(me.toString());
174 }
175
176
177
178 MuleUrlStreamHandlerFactory.installUrlStreamHandlerFactory();
179
180 String config = (String) commandlineOptions.get("config");
181
182 if (config == null && !commandlineOptions.containsKey("idle"))
183 {
184 logger.warn("A configuration file was not set, using default: " + DEFAULT_CONFIGURATION);
185
186 URL configUrl = IOUtils.getResourceAsUrl(DEFAULT_CONFIGURATION, MuleServer.class, true, false);
187 if (configUrl != null)
188 {
189 config = configUrl.toExternalForm();
190 }
191 else
192 {
193 System.out.println(CoreMessages.configNotFoundUsage());
194 System.exit(-1);
195 }
196 }
197
198 if (config != null)
199 {
200 setConfigurationResources(config);
201 }
202
203 String appconfig = (String) commandlineOptions.get("appconfig");
204 this.appConfigurationResource = appconfig;
205
206
207 String cfgBuilderClassName = (String) commandlineOptions.get("builder");
208
209 if (commandlineOptions.containsKey("idle"))
210 {
211 setConfigurationResources("IDLE");
212 cfgBuilderClassName = CLASSNAME_DEFAULT_IDLE_CONFIG_BUILDER;
213 }
214
215
216 if (cfgBuilderClassName != null)
217 {
218 try
219 {
220
221 if (cfgBuilderClassName.equalsIgnoreCase("spring"))
222 {
223 cfgBuilderClassName = CLASSNAME_SPRING_CONFIG_BUILDER;
224 }
225 setConfigBuilderClassName(cfgBuilderClassName);
226 }
227 catch (Exception e)
228 {
229 logger.fatal(e);
230 final Message message = CoreMessages.failedToLoad("Builder: " + cfgBuilderClassName);
231 System.err.println(StringMessageUtils.getBoilerPlate("FATAL: " + message.toString()));
232 System.exit(1);
233 }
234 }
235
236
237 String propertiesFile = (String) commandlineOptions.get("props");
238 if (propertiesFile != null)
239 {
240 setStartupPropertiesFile(propertiesFile);
241 }
242
243 StartupContext.get().setStartupOptions(commandlineOptions);
244 }
245
246
247
248
249
250
251
252
253
254 public void start(boolean ownThread, boolean registerShutdownHook)
255 {
256 if (registerShutdownHook)
257 {
258 registerShutdownHook();
259 }
260 if (ownThread)
261 {
262 Thread serverThread = new Thread(this, "MuleServer");
263 serverThread.setDaemon(true);
264 serverThread.start();
265 }
266 else
267 {
268 run();
269 }
270 }
271
272
273
274
275
276 public void run()
277 {
278 try
279 {
280 logger.info("Mule Server initializing...");
281 initialize();
282 logger.info("Mule Server starting...");
283 muleContext.start();
284 }
285 catch (Throwable e)
286 {
287 shutdown(e);
288 }
289 }
290
291
292
293
294
295
296
297
298
299
300 public static void setConfigBuilderClassName(String builderClassName) throws ClassNotFoundException
301 {
302 if (builderClassName != null)
303 {
304 Class<?> cls = ClassUtils.loadClass(builderClassName, MuleServer.class);
305 if (ConfigurationBuilder.class.isAssignableFrom(cls))
306 {
307 MuleServer.configBuilderClassName = builderClassName;
308 }
309 else
310 {
311 throw new IllegalArgumentException("Not a usable ConfigurationBuilder class: "
312 + builderClassName);
313 }
314 }
315 else
316 {
317 MuleServer.configBuilderClassName = null;
318 }
319 }
320
321
322
323
324
325
326
327 public static String getConfigBuilderClassName()
328 {
329 if (configBuilderClassName != null)
330 {
331 return configBuilderClassName;
332 }
333 else
334 {
335 return CLASSNAME_DEFAULT_CONFIG_BUILDER;
336 }
337 }
338
339
340
341
342
343
344
345 public void initialize() throws Exception
346 {
347 if (configurationResources == null)
348 {
349 logger.warn("A configuration file was not set, using default: " + DEFAULT_CONFIGURATION);
350 configurationResources = DEFAULT_CONFIGURATION;
351 }
352
353
354 ConfigurationBuilder cfgBuilder = createConfigurationBuilder();
355
356 if (!cfgBuilder.isConfigured())
357 {
358 List<ConfigurationBuilder> configBuilders = new ArrayList<ConfigurationBuilder>(3);
359
360
361
362 addAnnotationsConfigBuilder(configBuilders);
363 addStartupPropertiesConfigBuilder(configBuilders);
364 configBuilders.add(cfgBuilder);
365
366 MuleConfiguration configuration = createMuleConfiguration();
367
368 MuleContextBuilder contextBuilder = new DefaultMuleContextBuilder();
369 contextBuilder.setMuleConfiguration(configuration);
370
371 MuleContextFactory contextFactory = new DefaultMuleContextFactory();
372 muleContext = contextFactory.createMuleContext(configBuilders, contextBuilder);
373 }
374 }
375
376 protected ConfigurationBuilder createConfigurationBuilder() throws ConfigurationException
377 {
378 try
379 {
380 return (ConfigurationBuilder) ClassUtils.instanciateClass(getConfigBuilderClassName(),
381 new Object[]{ configurationResources }, MuleServer.class);
382 }
383 catch (Exception e)
384 {
385 throw new ConfigurationException(CoreMessages.failedToLoad(getConfigBuilderClassName()), e);
386 }
387 }
388
389
390
391
392
393 protected void addAnnotationsConfigBuilder(List<ConfigurationBuilder> builders) throws Exception
394 {
395 if (ClassUtils.isClassOnPath(CLASSNAME_ANNOTATIONS_CONFIG_BUILDER, getClass()))
396 {
397 Object configBuilder = ClassUtils.instanciateClass(CLASSNAME_ANNOTATIONS_CONFIG_BUILDER,
398 ClassUtils.NO_ARGS, getClass());
399 builders.add((ConfigurationBuilder) configBuilder);
400 }
401 }
402
403 protected void addStartupPropertiesConfigBuilder(List<ConfigurationBuilder> builders) throws IOException
404 {
405 Properties startupProperties = null;
406 if (getStartupPropertiesFile() != null)
407 {
408 startupProperties = PropertiesUtils.loadProperties(getStartupPropertiesFile(), getClass());
409 }
410
411 builders.add(new SimpleConfigurationBuilder(startupProperties));
412 }
413
414 protected MuleConfiguration createMuleConfiguration()
415 {
416 String appPropertiesFile = null;
417 if (this.appConfigurationResource == null)
418 {
419 appPropertiesFile = PropertiesMuleConfigurationFactory.getMuleAppConfiguration(this.configurationResources);
420 }
421 else
422 {
423 appPropertiesFile = this.appConfigurationResource;
424 }
425
426 return new PropertiesMuleConfigurationFactory(appPropertiesFile).createConfiguration();
427 }
428
429
430
431
432
433
434 public void shutdown(Throwable e)
435 {
436 doShutdown();
437 unregisterShutdownHook();
438
439 Message msg = CoreMessages.fatalErrorWhileRunning();
440 MuleException muleException = ExceptionHelper.getRootMuleException(e);
441 int exitCode = 1;
442 if (muleException != null)
443 {
444 logger.fatal(muleException.getDetailedMessage());
445 exitCode = muleException.getExceptionCode();
446 }
447 else
448 {
449 logger.fatal(msg.toString() + " " + e.getMessage(), e);
450 }
451 List<String> msgs = new ArrayList<String>();
452 msgs.add(msg.getMessage());
453 Throwable root = ExceptionHelper.getRootException(e);
454 msgs.add(root.getMessage() + " (" + root.getClass().getName() + ")");
455 msgs.add(" ");
456 msgs.add(CoreMessages.fatalErrorInShutdown().getMessage());
457 String shutdownMessage = StringMessageUtils.getBoilerPlate(msgs, '*', 80);
458 logger.fatal(shutdownMessage);
459
460 System.exit(exitCode);
461 }
462
463
464
465
466 public void shutdown()
467 {
468 logger.info("Mule server shutting down due to normal shutdown request");
469
470 unregisterShutdownHook();
471 doShutdown();
472 System.exit(0);
473 }
474
475 protected void doShutdown()
476 {
477 if (muleContext != null)
478 {
479 muleContext.dispose();
480 muleContext = null;
481 }
482 }
483
484 public Log getLogger()
485 {
486 return logger;
487 }
488
489 public void registerShutdownHook()
490 {
491 if (muleShutdownHook == null)
492 {
493 muleShutdownHook = new MuleShutdownHook();
494 }
495 else
496 {
497 Runtime.getRuntime().removeShutdownHook(muleShutdownHook);
498 }
499 Runtime.getRuntime().addShutdownHook(muleShutdownHook);
500 }
501
502 public void unregisterShutdownHook()
503 {
504 if (muleShutdownHook != null)
505 {
506 Runtime.getRuntime().removeShutdownHook(muleShutdownHook);
507 }
508 }
509
510
511
512
513
514
515
516
517
518
519 public String getConfigurationResources()
520 {
521 return configurationResources;
522 }
523
524
525
526
527
528
529 public void setConfigurationResources(String configurationResources)
530 {
531 this.configurationResources = configurationResources;
532 }
533
534 public static String getStartupPropertiesFile()
535 {
536 return startupPropertiesFile;
537 }
538
539 public static void setStartupPropertiesFile(String startupPropertiesFile)
540 {
541 MuleServer.startupPropertiesFile = startupPropertiesFile;
542 }
543
544 public MuleContext getMuleContext()
545 {
546 return muleContext;
547 }
548
549
550
551
552
553
554 private class MuleShutdownHook extends Thread
555 {
556 public MuleShutdownHook()
557 {
558 super();
559 }
560
561 @Override
562 public void run()
563 {
564 doShutdown();
565 System.exit(0);
566 }
567 }
568 }