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