Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/mule/MuleManager.java


1   /* 
2    * $Header: /cvsroot/mule/mule/src/java/org/mule/MuleManager.java,v 1.11 2003/10/20 21:19:17 rossmason Exp $
3    * $Revision: 1.11 $
4    * $Date: 2003/10/20 21:19:17 $
5    * ------------------------------------------------------------------------------------------------------
6    * 
7    * Copyright (c) Cubis Limited. All rights reserved.
8    * http://www.cubis.co.uk 
9    * 
10   * The software in this package is published under the terms of the BSD
11   * style license a copy of which has been included with this distribution in
12   * the LICENSE.txt file. 
13   *
14   */
15  package org.mule;
16  
17  import java.io.IOException;
18  import java.net.URL;
19  import java.util.Date;
20  import java.util.HashMap;
21  import java.util.Iterator;
22  import java.util.Map;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.mule.digester.MuleDigester;
27  import org.mule.umo.UMODescriptor;
28  import org.mule.umo.UMOEvent;
29  import org.mule.umo.UMOException;
30  import org.mule.umo.UMOProviderDescriptor;
31  import org.mule.umo.UMOSession;
32  import org.mule.umo.impl.MuleProviderDescriptor;
33  import org.mule.umo.impl.MuleSessionManager;
34  import org.mule.umo.impl.ProviderList;
35  import org.mule.umo.provider.UMOConnector;
36  import org.mule.umo.transformer.UMOTransformer;
37  import org.xml.sax.SAXException;
38  
39  /**
40   *  <p><code>MuleManager</code> maintains and provides services for a Mule instance.
41   * All mules and tranformations are registered in the MuleManager.  The Transaction
42   * Manager and performance metric helpers is also accessible from here.
43   * The developer can use the Mulemanager to stop start or pause all or any specific mules
44   * in the system.
45   *
46   * @author <a href="mailto:ross.mason@cubis.co.uk">Ross Mason</a>
47   * @version $Revision: 1.2 $
48   */
49  
50  public class MuleManager implements MuleConstants
51  {
52  
53      /** singleton instance */
54      private static MuleManager instance = null;
55  
56      /** holds a reference to the session manager instance */
57      private MuleSessionManager sessionManager = null;
58  
59      /** Default configuration */
60      private MuleConfiguration config = new MuleConfiguration();
61  
62      /** Connectors registry */
63      private Map connectors = new HashMap();
64  
65      /** Endpoints registry */
66      private Map endpoints = new HashMap();
67  
68      /** Holds any environment properties set in the config */
69      private Map props = new HashMap();
70  
71      /** Holds a list of global providers accessible to any client code */
72      private ProviderList providers = new ProviderList();
73  
74      //  /** The transaction Manager to use for global transactions */
75      //  private TransactionManager transactionManager = null;
76  
77      /** Collection for transformers registered in this session */
78      private HashMap transformers = new HashMap();
79  
80      /** True once the Mule Manager is initialised */
81      private static boolean initialised = false;
82  
83      /** Holds a reference to the deamon running the Manager if any */
84      private static MuleServer server = null;
85  
86      /** logger used by this class */
87      private static transient Log log = LogFactory.getLog(MuleManager.class);
88  
89      /** Default Constructor */
90      private MuleManager()
91      {
92          sessionManager = MuleSessionManager.getInstance();
93      }
94  
95      /** A helper method to explicitly configure the CacheManager singleton
96        * from a given XML deployment configuration document
97        */
98      public static void configure(String xmlURL) throws IOException, SAXException
99      {
100         load(xmlURL);
101     }
102 
103     /** A helper method to explicitly configure the CacheManager singleton
104       * from a given XML deployment configuration document
105       */
106     public static void configure(String xmlURL, MuleServer muleServer) throws IOException, SAXException
107     {
108         server = muleServer;
109         configure(xmlURL);
110     }
111 
112     /** Factory method to create the singleton MuleManager instance */
113     protected static MuleManager createInstance()
114     {
115         String config = null;
116         try
117         {
118             config = System.getProperty("org.mule.config");
119         }
120         catch (Exception e)
121         {
122         }
123         try
124         {
125             if (config == null)
126             {
127                 URL url = MuleManager.class.getClassLoader().getResource("mule-config.xml");
128                 if (url != null)
129                 {
130                     config = url.toString();
131                 }
132                 else
133                 {
134                     log.warn("No mule-config.xml configuration document found on the CLASSPATH.");
135                 }
136             }
137             if (config != null)
138             {
139                 return load(config);
140 
141             }
142         }
143         catch (Exception e)
144         {
145             log.error("Could not load Mule configuration from mule-config.xml", e);
146         }
147         return new MuleManager();
148     }
149 
150     /** 
151      * Getter method for the current singleton MuleManager
152      *
153      * @return the current singleton MuleManager
154      */
155     public synchronized static MuleManager getInstance()
156     {
157         if (instance == null)
158         {
159             //instance = createInstance();
160             instance = new MuleManager();
161         }
162         return instance;
163     }
164 
165     /**
166      * A helper method to load the MuleManager 
167      * from a given XML deployment configuration document
168      *
169      * @param url the url String location of the mule-config.xml 
170      * @return the MuleManager instance
171      * @throws IOException is thrown if there is a problem loading the url
172      * @throws SAXException is thrown if there is a problem with the syntax of the 
173      * config file
174      */
175     public static MuleManager load(String url) throws IOException, SAXException
176     {
177         MuleDigester digester = new MuleDigester();
178         initialised = false;
179         instance = null;
180         instance = (MuleManager) digester.parse(url);
181         initialised = true;
182         return instance;
183     }
184 
185     //  Implementation methods
186     //-------------------------------------------------------------------------    
187 
188     /**
189      * Destroys the MuleManager and all resources it maintains
190      */
191     public void destroy() throws UMOException
192     {
193         destroyConnectors();
194         sessionManager.destroy();
195         transformers = null;
196         providers = null;
197         endpoints = null;
198         props = null;
199         initialised = false;
200         instance = null;
201     }
202 
203     /**
204      * Destroys all connectors
205      *
206      */
207     private void destroyConnectors()
208     {
209         UMOConnector temp;
210         for (Iterator i = connectors.values().iterator(); i.hasNext();)
211         {
212             temp = (UMOConnector) i.next();
213             try
214             {
215                 temp.shutdown();
216             }
217             catch (Exception e)
218             {
219                 log.error("Exception while shutting down connector: " + temp.getName() + ". Exception was " + e);
220             }
221             log.info("UMOConnector " + temp.toString() + " has been destroyed successfully");
222         }
223         connectors = null;
224     }
225 
226     /**
227      * 
228      * @return the MuleConfiguration for this MuleManager.  This object is immutable
229      * once the manager has initialised.
230      */
231     public MuleConfiguration getConfiguration()
232     {
233         return config;
234     }
235 
236     /**
237      * Getter for the envionment parameters declared in the nule-config.xml
238      * @param key the propery name
239      * @return the property value
240      */
241     public Object getProperty(Object key)
242     {
243         return props.get(key);
244     }
245 
246     /**
247      * 
248      * @return an Iterator of all environment property names
249      */
250     public Iterator getPropertyNames()
251     {
252         return props.keySet().iterator();
253     }
254 
255     //    /**
256     //     * 
257     //     * @return the transaction Manager configured on the Mule Manager
258     //     */
259     //  public TransactionManager getTransactionManager()
260     //  {
261     //    return transactionManager;
262     //  }
263 
264     /**
265      * 
266      * @param name the name of the Mule UMO to check for
267      * @return true if a Mule of the given name has been registered
268      */
269     public boolean isMuleRegistered(String name)
270     {
271         try
272         {
273             return getSession(name) != null;
274         }
275         catch (UMOException e)
276         {
277             log.warn("Failed to check Mule was registered: " + e);
278             return false;
279         }
280     }
281 
282     /**
283      * 
284      * @param logicalName the name of the connector to retrieve
285      * @return the connector instnace if it exists
286      * @throws MuleException if the UMOConnector is not found
287      */
288     public UMOConnector lookupConnector(String logicalName) throws MuleException
289     {
290         UMOConnector c = (UMOConnector) connectors.get(logicalName);
291         if (c == null)
292         {
293             throw new MuleException("No connector could be found named: " + logicalName);
294         }
295         return c;
296     }
297 
298     /**
299      * 
300      * @param logicalName the logical mapping name for an endpoint i.e.
301      * rather than specifing an endpoint to be someone@my.com you can supply 
302      * a more descriptive name such as <i>The System Administrator</i>
303      * @return the actual endpoint value or null if it is not found
304      */
305     public String lookupEndpoint(String logicalName)
306     {
307         return (String) endpoints.get(logicalName);
308     }
309 
310     /**
311      * Getter for a global provider.  Any providers returned from this method
312      * will be read-only as they may be shared by other components.  To change
313      * any details on the provider you must clone it first calling it's clone() method
314      * @param logicalName the name of the provider
315      * @return the <code>UMOProviderDescriptor</code> or null if it doesn't exist
316      */
317     public MuleProviderDescriptor lookupProvider(String logicalName)
318     {
319         return (MuleProviderDescriptor) providers.get(logicalName);
320     }
321 
322     //TODO doc
323     public void dispatch(String muleName, UMOEvent event) throws UMOException
324     {
325         UMOSession session = sessionManager.getSession(muleName);
326         if (session == null)
327         {
328             throw new MuleException("Failed to find mule with name: " + muleName);
329         }
330         session.dispatchEvent(event);
331     }
332 
333     /**
334      * Getter method for a Transformer.
335      * @param name the name of the transformer
336      * @return the Transformer instance if found, otherwise null
337      */
338     public UMOTransformer lookupTransformer(String name)
339     {
340         return (UMOTransformer) transformers.get(name);
341     }
342 
343     /**
344      * Registers a <code>UMOConnector</code> with the <code>MuleManager</code>.
345      * @param connector the <code>UMOConnector</code> to register
346      */
347     public void registerConnector(UMOConnector connector)
348     {
349         connectors.put(connector.getName(), connector);
350     }
351 
352     /**
353      * Registers an endpoint with a logical name
354      * @param logicalName the name of the endpoint
355      * @param endpoint the physical endpoint value
356      */
357     public void registerEndpoint(String logicalName, String endpoint)
358     {
359         endpoints.put(logicalName, endpoint);
360     }
361 
362     /**
363     * Registers a <code>UMODescriptor</code> with the <code>MuleManager</code>.
364     * The manager will take care of creating the Mule UMO and, it's session and proxies.
365     * @param muleDescriptor the <code>UMODescriptor</code> to register
366     */
367     public void registerMule(UMODescriptor muleDescriptor) throws UMOException
368     {
369         if (muleDescriptor == null)
370         {
371             throw new MuleException("Mule UMO to register was null");
372         }
373         //TODO Validate provider setting behaviour against documented behaviour
374 
375         //UniversalMessageObject muleUMO = descriptor.getFactory().create(descriptor);
376 
377         //        if (config != null && config.isSynchronous() && 
378         //                !(muleUMO instanceof UMOSyncChainSupport)) {
379         //            throw new MuleException("All Mules must have synchronous support when running synchronous");
380         //        }
381         UMOSession session = sessionManager.registerSession(muleDescriptor);
382         UMOProviderDescriptor provider = null;
383         String name = null;
384         for (Iterator i = muleDescriptor.getProviders().getReceiverNames(); i.hasNext();)
385         {
386             name = (String) i.next();
387             provider = muleDescriptor.getProviders().getReceiveProvider(name);
388             try
389             {
390                 provider.getConnector().registerListener(session, provider);
391             }
392             catch (Exception e)
393             {
394                 throw new UMOException(
395                     "Failed to register Mule UMO: " + muleDescriptor.getName() + " as a listener: " + e,
396                     e);
397             }
398         }
399 
400         log.debug("Added Mule UMO: " + muleDescriptor.getName());
401 
402     }
403 
404     /**
405      * Registers a shared/global provider with the <code>MuleManager</code>.
406      * @param provider the <code>UMOProviderDescriptor</code> to register.
407      */
408     public void registerProvider(MuleProviderDescriptor provider)
409     {
410         providers.add(provider, true);
411     }
412 
413     /**
414      * Registers a transformer with the <code>MuleManager</code>.
415      * @param transformer the <code>UMOTransformer</code> to register.
416      */
417     public void registerTransformer(UMOTransformer transformer)
418     {
419         transformers.put(transformer.getName(), transformer);
420     }
421 
422     /**
423      * Sets the configuration for the <code>MuleManager</code>.
424      * @param config the configuration object
425      * @throws IllegalAccessError if the <code>MuleManager</code> has already been
426      * initialised.
427      */
428     public void setConfiguration(MuleConfiguration config)
429     {
430         if (initialised)
431         {
432             throw new IllegalAccessError("Once initialised this property is read-only");
433         }
434         else
435         {
436             this.config = config;
437         }
438     }
439 
440     /**
441      * Sets an Mule environment parameter in the <code>MuleManager</code>.
442      * @param key the parameter name
443      * @param value the parameter value
444      */
445     public void setProperty(Object key, Object value)
446     {
447         props.put(key, value);
448     }
449 
450     //    /**
451     //     * Sests the XA transaction manager on the <code>MuleManager</code>.
452     //     * @param newManager the <code>TransactionManager</code> to use.
453     //     * @throws MuleException if the current transaction manager is not null and it's
454     //     * state is currently volatile
455     //     * NOTE: XA transactions are currently not supported
456     //     */
457     //  protected void setTransactionManager(TransactionManager newManager) throws MuleException
458     //  {
459     //    try
460     //    {
461     //      if (transactionManager != null
462     //        && (transactionManager.getStatus() != Status.STATUS_NO_TRANSACTION
463     //          || transactionManager.getStatus() != Status.STATUS_COMMITTED
464     //          || transactionManager.getStatus() != Status.STATUS_ROLLEDBACK))
465     //      {
466     //        throw new MuleException("Cannot set Transaction manager the current is in a transaction");
467     //      } else
468     //        if (transactionManager != null)
469     //        {
470     //          log.warn("Replacing current transaction manager " + transactionManager.getClass().getName());
471     //        }
472     //      transactionManager = newManager;
473     //
474     //      log.debug("Transaction manager is set to " + transactionManager.getClass().getName());
475     //    } catch (SystemException e)
476     //    {
477     //      log.error("Failed to get status of current transaction Manager: " + e);
478     //      throw new MuleException("Failed to get status of current transaction Manager", e);
479     //    }
480     //  }
481 
482     /**
483      * Start the <code>MuleManager</code>. This will start the connectors and sessions.
484      * @throws UMOException if the the connectors or sessions fail to start
485      */
486     public void start() throws UMOException
487     {
488         sessionManager.start();
489         startConnectors();
490     }
491 
492     /**
493      * Starts the connectors
494      * @throws MuleException if the connectors fail to start
495      */
496     private void startConnectors() throws MuleException
497     {
498         UMOConnector temp;
499         for (Iterator i = connectors.values().iterator(); i.hasNext();)
500         {
501             temp = (UMOConnector) i.next();
502             try
503             {
504                 temp.start();
505             }
506             catch (Exception e)
507             {
508                 throw new MuleException(
509                     "Exception occurred while shutting down connector: " + temp.getName() + ". Exception was " + e,
510                     e);
511             }
512             log.info("UMOConnector " + temp.toString() + " has been started successfully");
513         }
514     }
515 
516     /**
517      * Starts a single Mule.  This can be useful when stopping and starting some
518      * Mule UMOs while letting others continue
519      * @param name the name of the Mule UMO to start
520      * @throws UMOException if the MuleUMO is not registered
521      */
522     public void startMule(String name) throws UMOException
523     {
524         Object obj = sessionManager.getSession(name);
525         if (obj == null)
526         {
527             throw new MuleException("Cannot find mule " + name);
528         }
529         else
530         {
531             ((UMOSession) obj).start();
532             log.info("Mule " + obj.toString() + " has been started successfully");
533         }
534     }
535 
536     /**
537      * Stops the <code>MuleManager</code> which stops all sessions and connectors
538      * @throws UMOException if either any of the sessions or connectors fail to stop
539      */
540     public void stop() throws UMOException
541     {
542         log.debug("Stopping connectors...");
543         stopConnectors();
544         log.debug("Stopping sessions...");
545         sessionManager.stop();
546     }
547 
548     /**
549      * Stops the connectors
550      * @throws MuleException if any of the connectors fail to stop
551      */
552     private void stopConnectors() throws MuleException
553     {
554         UMOConnector temp;
555         for (Iterator i = connectors.values().iterator(); i.hasNext();)
556         {
557             temp = (UMOConnector) i.next();
558             try
559             {
560                 temp.stop();
561             }
562             catch (Exception e)
563             {
564                 throw new MuleException(
565                     "Exception occurred while stopping connector: " + temp.getName() + ". Exception was " + e,
566                     e);
567             }
568             log.info("UMOConnector " + temp.toString() + " has been stopped successfully");
569         }
570     }
571 
572     /**
573      * Stops a single Mule.  This can be useful when stopping and starting some
574      * Mule UMOs while letting others continue.
575      * @param name the name of the Mule UMO to stop
576      * @throws UMOException if the MuleUMO is not registered
577      */
578     public void stopMule(String name) throws UMOException
579     {
580         Object obj = sessionManager.getSession(name);
581         if (obj == null)
582         {
583             throw new MuleException("Cannot find mule " + name);
584         }
585         else
586         {
587             ((UMOSession) obj).stop();
588             log.info("mule " + name + " has been stopped successfully");
589         }
590     }
591 
592     /**
593      * If the <code>MuleManager</code> was started from the <code>MuleServer</code>
594      * daemon then this will be called by the Server 
595      * @param server a reference to the <code>MuleServer</code>.
596      */
597     void setServer(MuleServer server)
598     {
599         MuleManager.server = server;
600     }
601 
602     /**
603      * Shuts down the whole server tring to shut down all resources cleanly on the way
604      * @param e an exception that caused the <code>shutdown()</code> method
605      * to be called. If e is null the shutdown message will just display a time when
606      * the server was shutdown. Otherwise the exception information will also be displayed.
607      */
608     public void shutdown(Throwable e)
609     {
610 
611         try
612         {
613             destroy();
614         }
615         catch (UMOException e1)
616         {
617             log.fatal("Exception caught while destroying the Server: " + e);
618         }
619 
620         if (server != null)
621         {
622             if (e != null)
623             {
624                 server.shutdown(e);
625             }
626             else
627             {
628                 server.shutdown();
629             }
630         }
631         else
632         {
633             if (e != null)
634             {
635                 System.out.println("*************************************************************************");
636                 System.out.println("Mule is shutting down due to exception: " + e.getMessage());
637                 System.out.println("Shutdown time is: " + new Date().toString());
638                 System.out.println("*************************************************************************");
639             }
640             else
641             {
642                 System.out.println("*************************************************************************");
643                 System.out.println("Mule is shutting down due to normal shutdown request.");
644                 System.out.println("Shutdown time is: " + new Date().toString());
645                 System.out.println("*************************************************************************");
646             }
647         }
648         System.exit(0);
649     }
650 
651     /**
652      * A convenience method to obtain a reference to the Session Manager
653      * @return the <code>MuleSessionManager</code> instance
654      */
655     public MuleSessionManager getSessionManager()
656     {
657         return sessionManager;
658     }
659 
660     /**
661      * A convenience method to get a session from the session manager
662      * @param the Mule name for which the session is required
663      * @return a valid session
664      * @throws UMOException if the session fails to initialise or a descriptor
665      * for the specified name does not exist
666      */
667     public UMOSession getSession(String muleName) throws UMOException
668     {
669         return sessionManager.getSession(muleName);
670     }
671 
672     /**
673      * A convenience method to get a session from the session manager
674      * @param descriptor the descriptor for which the session is required
675      * @return a valid session
676      * @throws UMOException if the session fails to initialise
677      */
678     public UMOSession getSession(UMODescriptor descriptor) throws UMOException
679     {
680         return sessionManager.getSession(descriptor);
681     }
682 }