View Javadoc

1   /*
2    * $Id: MuleConfiguration.java 7976 2007-08-21 14:26:13Z dirk.olmes $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.config;
12  
13  import org.mule.MuleManager;
14  import org.mule.MuleRuntimeException;
15  import org.mule.config.i18n.CoreMessages;
16  import org.mule.providers.ConnectionStrategy;
17  import org.mule.providers.SingleAttemptConnectionStrategy;
18  import org.mule.umo.manager.DefaultWorkListener;
19  import org.mule.util.FileUtils;
20  import org.mule.util.StringUtils;
21  import org.mule.util.queue.EventFilePersistenceStrategy;
22  import org.mule.util.queue.QueuePersistenceStrategy;
23  
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.net.URL;
27  import java.security.AccessController;
28  import java.security.PrivilegedAction;
29  import java.util.Enumeration;
30  import java.util.jar.Attributes;
31  import java.util.jar.Manifest;
32  
33  import javax.resource.spi.work.WorkListener;
34  
35  import org.apache.commons.beanutils.BeanUtils;
36  import org.apache.commons.logging.Log;
37  import org.apache.commons.logging.LogFactory;
38  
39  /**
40   * <code>MuleConfiguration</code> holds the runtime configuration specific to the
41   * <code>MuleManager</code>. Once the <code>MuleManager</code> has been
42   * initialised this class is immutable.
43   */
44  public class MuleConfiguration
45  {
46      /**
47       * logger used by this class
48       */
49      protected transient Log logger = LogFactory.getLog(getClass());
50  
51      /**
52       * The default serverUrl used to receive incoming requests from clients
53       */
54      public static final String DEFAULT_SERVER_URL = "tcp://localhost:60504";
55  
56      /**
57       * Specifies that the transformer properties should be obtained from the Mule
58       * Manager properties
59       */
60      public static final String USE_MANAGER_PROPERTIES = "org.mule.useManagerProperties";
61  
62      /**
63       * Specifies whether mule should process messages sysnchonously, i.e. that a
64       * mule-model can only processone message at a time, or asynchonously. The
65       * default value is 'false'.
66       */
67      public static final String SYNCHRONOUS_PROPERTY = "synchronous";
68  
69      public static final String DEFAULT_ENCODING = "UTF-8";
70      /**
71       * Default encoding used in OS running Mule
72       */
73      public static final String DEFAULT_OS_ENCODING = System.getProperty("file.encoding");
74  
75      // /**
76      // * Determines the default inboundProvider that Mule uses to communicate
77      // between MuelUMO's when an
78      // * inboundProvider is not specified on a mule.
79      // * If this value is not specifed, Mule will create a default VM connection
80      // * called 'muleVMInboundProvider' which will use a VMConnector.
81      // */
82      // public static final String DEFAULT_INBOUND_PROVIDER_PROPERTY =
83      // "defaultInboundProvider";
84      //
85      // /**
86      // * Determines the default outboundProvider that Mule uses to communicate
87      // between MuelUMO's when an
88      // * outboundProvider is not specified on a mule.
89      // * If this value is not specifed, Mule will create a default VM connection
90      // * called 'muleVMOutbound' which will use a VMConnector.
91      // */
92      // public static final String DEFAULT_OUTBOUND_PROVIDER_PROPERTY =
93      // "defaultOutboundProvider";
94  
95      /**
96       * Default value for SYNCHRONOUS_PROPERTY
97       */
98      public static final boolean DEFAULT_SYNCHRONOUS = false;
99  
100     /**
101      * Default value for MAX_OUTSTANDING_MESSAGES_PROPERTY
102      */
103     public static final int DEFAULT_MAX_OUTSTANDING_MESSAGES = 1000;
104 
105     public static final int DEFAULT_TIMEOUT = 10000;
106 
107     public static final int DEFAULT_TRANSACTION_TIMEOUT = 30000;
108 
109     public static final String DEFAULT_SYSTEM_MODEL_TYPE = "seda";
110 
111     /**
112      * Where Mule stores any runtime files to disk
113      */
114     public static final String DEFAULT_WORKING_DIRECTORY = "./.mule";
115 
116     /**
117      * The default queueStore directory for persistence
118      */
119     public static final String DEFAULT_QUEUE_STORE = "queuestore";
120 
121     /**
122      * holds the value for SYNCHRONOUS
123      */
124     private boolean synchronous = DEFAULT_SYNCHRONOUS;
125 
126 
127     /**
128      * The type of model used for the internal system model where system created services are registered
129      */
130     private String systemModelType = DEFAULT_SYSTEM_MODEL_TYPE;
131 
132     /**
133      * Whether Mule should fire message events for every message sent and received
134      */
135     private boolean enableMessageEvents = false;
136 
137     /**
138      * Name of the model to use. If blank the first model will be used
139      */
140     private String model = null;
141 
142     private String encoding = DEFAULT_ENCODING;
143 
144     private String osEncoding = DEFAULT_OS_ENCODING;
145 
146     private PoolingProfile poolingProfile = new PoolingProfile();
147 
148     /**
149      * configuration for the threadpool used by message dispatchers
150      */
151     private ThreadingProfile messageDispatcherThreadingProfile = null;
152 
153     /**
154      * configuration for the threadpool used by message receivers
155      */
156     private ThreadingProfile messageReceiverThreadingProfile = null;
157 
158     /**
159      * configuration for the threadpool used by component pooling in mule
160      */
161     private ThreadingProfile componentPoolThreadingProfile = null;
162 
163     private QueueProfile queueProfile = new QueueProfile(DEFAULT_MAX_OUTSTANDING_MESSAGES, false);
164 
165     private QueuePersistenceStrategy persistenceStrategy = new EventFilePersistenceStrategy();
166 
167     /**
168      * When running sychonously, return events can be received over transports that
169      * support ack or replyTo This property determines how long to wait for a receive
170      */
171     private int synchronousEventTimeout = DEFAULT_TIMEOUT;
172 
173     /**
174      * The default transaction timeout value used if no specific transaction time out
175      * has been set on the transaction config
176      */
177     private int transactionTimeout = DEFAULT_TRANSACTION_TIMEOUT;
178 
179     /**
180      * Determines whether when running synchronously, return events are received
181      * before returning the call. i.e. in jms wait for a replyTo. Vm queues do this
182      * automatically
183      */
184     private boolean remoteSync = false;
185 
186     /**
187      * Determines whether internal vm queues are persistent. If they are, if the
188      * server dies unexpectedly it can resume it's current state and continue
189      * processing
190      */
191     private boolean recoverableMode = false;
192     /**
193      * A helper thread pool configuration that is used for all other thread pool
194      * configurations
195      */
196     private ThreadingProfile defaultThreadingProfile = new ThreadingProfile();
197 
198     /**
199      * Where mule will store any runtime files to disk
200      */
201     private String workingDirectory;
202 
203     /**
204      * The configuration resources used to configure the MuleManager instance
205      */
206     private String[] configResources = new String[]{};
207 
208     /**
209      * This is the url used by the server itself to receive incomming requests. This
210      * enables clients such as the Mule Client to marshal remote requests to a
211      * MuleManager instance. The default value is tcp://localhost:61616
212      */
213     private String serverUrl = DEFAULT_SERVER_URL;
214 
215     /**
216      * The Mule Jar manifest object
217      */
218     private Manifest manifest = null;
219 
220     /**
221      * Whether the server instance is running in client mode, which means that some
222      * services will not be started
223      */
224     private boolean clientMode = false;
225 
226     /**
227      * Whether the server is embedded by another framework and certain stand-alone
228      * features
229      */
230     private boolean embedded = false;
231 
232     /**
233      * The model type to use for component invocations
234      */
235     private String modelType = "default";
236 
237     /**
238      * The default connection Strategy used for a connector when one hasn't been
239      * defined for the connector
240      */
241     private ConnectionStrategy connectionStrategy = new SingleAttemptConnectionStrategy();
242 
243     private WorkListener workListener = new DefaultWorkListener();
244 
245     public MuleConfiguration()
246     {
247         super();
248         setWorkingDirectory(DEFAULT_WORKING_DIRECTORY);
249     }
250 
251     /**
252      * @return true if the model is running synchronously or false otherwise
253      */
254     public boolean isSynchronous()
255     {
256         return synchronous;
257     }
258 
259     public void setSynchronous(boolean synchronous)
260     {
261         this.synchronous = synchronous;
262     }
263     
264     public String getModel()
265     {
266         return model;
267     }
268 
269     public void setModel(String model)
270     {
271         this.model = model;
272     }
273 
274     public ThreadingProfile getMessageDispatcherThreadingProfile()
275     {
276         return getThreadingProfile(messageDispatcherThreadingProfile);
277     }
278 
279     public void setMessageDispatcherThreadingProfile(ThreadingProfile messageDispatcherThreadingProfile)
280     {
281         this.messageDispatcherThreadingProfile = messageDispatcherThreadingProfile;
282     }
283 
284     public ThreadingProfile getMessageReceiverThreadingProfile()
285     {
286         return getThreadingProfile(messageReceiverThreadingProfile);
287     }
288 
289     public void setMessageReceiverThreadingProfile(ThreadingProfile messageReceiverThreadingProfile)
290     {
291         this.messageReceiverThreadingProfile = messageReceiverThreadingProfile;
292     }
293 
294     public ThreadingProfile getComponentThreadingProfile()
295     {
296         return getThreadingProfile(componentPoolThreadingProfile);
297     }
298 
299     public void setComponentThreadingProfile(ThreadingProfile componentPoolThreadingProfile)
300     {
301         this.componentPoolThreadingProfile = componentPoolThreadingProfile;
302     }
303 
304     public ThreadingProfile getDefaultThreadingProfile()
305     {
306         return getThreadingProfile(defaultThreadingProfile);
307     }
308 
309     public void setDefaultThreadingProfile(ThreadingProfile defaultThreadingProfile)
310     {
311         if (defaultThreadingProfile == null)
312         {
313             return;
314         }
315         this.defaultThreadingProfile = defaultThreadingProfile;
316     }
317 
318     private ThreadingProfile getThreadingProfile(ThreadingProfile profile)
319     {
320         if (profile != null)
321         {
322             return new ThreadingProfile(profile);
323         }
324         return new ThreadingProfile(defaultThreadingProfile);
325     }
326 
327     public PoolingProfile getPoolingProfile()
328     {
329         return new PoolingProfile(poolingProfile);
330     }
331 
332     public void setPoolingProfile(PoolingProfile poolingProfile)
333     {
334         this.poolingProfile = poolingProfile;
335     }
336 
337     public int getSynchronousEventTimeout()
338     {
339         return synchronousEventTimeout;
340     }
341 
342     public void setSynchronousEventTimeout(int synchronousEventTimeout)
343     {
344         this.synchronousEventTimeout = synchronousEventTimeout;
345     }
346 
347     public boolean isRemoteSync()
348     {
349         return remoteSync;
350     }
351 
352     public void setRemoteSync(boolean remoteSync)
353     {
354         this.remoteSync = remoteSync;
355     }
356 
357     public QueueProfile getQueueProfile()
358     {
359         return new QueueProfile(queueProfile);
360     }
361 
362     public void setQueueProfile(QueueProfile queueProfile)
363     {
364         this.queueProfile = queueProfile;
365     }
366 
367     public boolean isRecoverableMode()
368     {
369         return recoverableMode;
370     }
371 
372     public void setRecoverableMode(boolean recoverableMode)
373     {
374         this.recoverableMode = recoverableMode;
375         if (recoverableMode)
376         {
377             queueProfile.setPersistent(true);
378         }
379     }
380 
381     public String getWorkingDirectory()
382     {
383         return workingDirectory;
384     }
385 
386     public void setWorkingDirectory(String workingDirectory)
387     {
388         // fix windows backslashes in absolute paths, convert them to forward ones 
389         this.workingDirectory = FileUtils.newFile(workingDirectory).getAbsolutePath().replaceAll("\\\\", "/");
390         updateApplicationProperty(MuleProperties.MULE_WORKING_DIRECTORY_PROPERTY, this.workingDirectory);
391     }
392 
393     public String[] getConfigResources()
394     {
395         return configResources;
396     }
397 
398     public void setConfigResources(String[] configResources)
399     {
400         if (configResources != null)
401         {
402             int current = this.configResources.length;
403             String[] newResources = new String[configResources.length + current];
404             System.arraycopy(this.configResources, 0, newResources, 0, current);
405             System.arraycopy(configResources, 0, newResources, current, configResources.length);
406             this.configResources = newResources;
407         }
408         else
409         {
410             this.configResources = configResources;
411         }
412     }
413 
414     public String getServerUrl()
415     {
416         return serverUrl;
417     }
418 
419     public void setServerUrl(String serverUrl)
420     {
421         if (embedded)
422         {
423             this.serverUrl = null;
424         }
425         else
426         {
427             this.serverUrl = serverUrl;
428         }
429     }
430 
431     public String getProductVersion()
432     {
433         return getManifestProperty("Implementation-Version");
434     }
435 
436     public String getVendorName()
437     {
438         return getManifestProperty("Specification-Vendor");
439     }
440 
441     public String getVendorUrl()
442     {
443         return getManifestProperty("Vendor-Url");
444     }
445 
446     public String getProductUrl()
447     {
448         return getManifestProperty("Product-Url");
449     }
450 
451     public String getProductName()
452     {
453         return getManifestProperty("Implementation-Title");
454     }
455 
456     public String getProductMoreInfo()
457     {
458         return getManifestProperty("More-Info");
459     }
460 
461     public String getProductSupport()
462     {
463         return getManifestProperty("Support");
464     }
465 
466     public String getProductLicenseInfo()
467     {
468         return getManifestProperty("License");
469     }
470 
471     public String getProductDescription()
472     {
473         return getManifestProperty("Description");
474     }
475 
476     public String getBuildDate()
477     {
478         return getManifestProperty("Build-Date");
479     }
480 
481     public Manifest getManifest()
482     {
483         if (manifest == null)
484         {
485             manifest = new Manifest();
486 
487             InputStream is = null;
488             try
489             {
490                 // We want to load the MANIFEST.MF from the mule-core jar. Sine we
491                 // don't the version we're using
492                 // we have to search for the jar on the classpath
493                 URL url = (URL) AccessController.doPrivileged(new PrivilegedAction()
494                 {
495                     public Object run()
496                     {
497                         try
498                         {
499                             Enumeration e = MuleConfiguration.class.getClassLoader().getResources(
500                                 ("META-INF/MANIFEST.MF"));
501                             while (e.hasMoreElements())
502                             {
503                                 URL url = (URL) e.nextElement();
504                                 if (url.toExternalForm().indexOf("mule-core") > -1)
505                                 {
506                                     return url;
507                                 }
508                             }
509                         }
510                         catch (IOException e1)
511                         {
512                             // TODO MULE-863: Is this sufficient (was printStackTrace) and correct?
513                             logger.debug("Failure reading manifest: " + e1.getMessage(), e1);
514                         }
515                         return null;
516                     }
517                 });
518 
519                 if (url != null)
520                 {
521                     is = url.openStream();
522                 }
523 
524                 if (is != null)
525                 {
526                     manifest.read(is);
527                 }
528 
529             }
530             catch (IOException e)
531             {
532                 // TODO MULE-863
533                 logger.warn("Failed to read manifest Info, Manifest information will not display correctly: "
534                             + e.getMessage());
535             }
536         }
537         return manifest;
538     }
539 
540     protected String getManifestProperty(String name)
541     {
542         return getManifest().getMainAttributes().getValue(new Attributes.Name(name));
543     }
544 
545     public int getTransactionTimeout()
546     {
547         return transactionTimeout;
548     }
549 
550     public void setTransactionTimeout(int transactionTimeout)
551     {
552         this.transactionTimeout = transactionTimeout;
553     }
554 
555     public boolean isClientMode()
556     {
557         return clientMode;
558     }
559 
560     public void setClientMode(boolean clientMode)
561     {
562         this.clientMode = clientMode;
563         if (clientMode)
564         {
565             setServerUrl("");
566         }
567     }
568 
569     public QueuePersistenceStrategy getPersistenceStrategy()
570     {
571         return persistenceStrategy;
572     }
573 
574     public void setPersistenceStrategy(QueuePersistenceStrategy persistenceStrategy)
575     {
576         this.persistenceStrategy = persistenceStrategy;
577     }
578 
579     /**
580      * Returns a clone of the default Connection strategy. The clone ensures that the
581      * connection strategy can be manipulated without affecting other connectors
582      * using the same strategy
583      * 
584      * @return a clone of the default Connection strategy
585      */
586     public ConnectionStrategy getConnectionStrategy()
587     {
588         try
589         {
590             return (ConnectionStrategy) BeanUtils.cloneBean(connectionStrategy);
591         }
592         catch (Exception e)
593         {
594             throw new MuleRuntimeException(
595                 CoreMessages.failedToClone("Connection Strategy"), e);
596         }
597     }
598 
599     /**
600      * Sets the connection strategy used by all connectors managed in this Mule
601      * instance if the connector has no connection strategy specifically set on it.
602      * 
603      * @param connectionStrategy the default strategy to use
604      */
605     public void setConnectionStrategy(ConnectionStrategy connectionStrategy)
606     {
607         this.connectionStrategy = connectionStrategy;
608     }
609 
610     public boolean isEmbedded()
611     {
612         return embedded;
613     }
614 
615     public void setEmbedded(boolean embedded)
616     {
617         this.embedded = embedded;
618         if (embedded)
619         {
620             serverUrl = null;
621         }
622     }
623 
624     public String getModelType()
625     {
626         return modelType;
627     }
628 
629     public void setModelType(String modelType)
630     {
631         this.modelType = modelType;
632     }
633 
634     public String getEncoding()
635     {
636         return encoding;
637     }
638 
639     public void setEncoding(String encoding)
640     {
641         if (StringUtils.isEmpty(encoding))
642         {
643             logger.warn("Cannot set encoding to null or empty String");
644             return;
645         }
646         this.encoding = encoding;
647     }
648 
649     public String getOSEncoding()
650     {
651         return osEncoding;
652     }
653 
654     public void setOSEncoding(String osEncoding)
655     {
656         this.osEncoding = osEncoding;
657     }
658 
659     public boolean isEnableMessageEvents()
660     {
661         return enableMessageEvents;
662     }
663 
664     public void setEnableMessageEvents(boolean enableMessageEvents)
665     {
666         this.enableMessageEvents = enableMessageEvents;
667     }
668 
669     public WorkListener getWorkListener()
670     {
671         return workListener;
672     }
673 
674     public void setWorkListener(WorkListener workListener)
675     {
676         if (workListener == null)
677         {
678             throw new IllegalArgumentException("workListener is null");
679         }
680         this.workListener = workListener;
681     }
682 
683     private void updateApplicationProperty(String name, Object value)
684     {
685         if (MuleManager.isInstanciated())
686         {
687             MuleManager.getInstance().setProperty(name, value);
688         }
689     }
690 
691 
692     public String getSystemModelType()
693     {
694         return systemModelType;
695     }
696 
697     public void setSystemModelType(String systemModelType)
698     {
699         this.systemModelType = systemModelType;
700     }
701 }