Coverage Report - org.mule.extras.client.MuleClient
 
Classes in this File Line Coverage Branch Coverage Complexity
MuleClient
0%
0/226
0%
0/36
2.543
MuleClient$1
0%
0/2
N/A
2.543
MuleClient$2
0%
0/2
N/A
2.543
 
 1  
 /*
 2  
  * $Id: MuleClient.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.extras.client;
 12  
 
 13  
 import org.mule.MuleManager;
 14  
 import org.mule.config.ConfigurationBuilder;
 15  
 import org.mule.config.ConfigurationException;
 16  
 import org.mule.config.MuleConfiguration;
 17  
 import org.mule.config.MuleProperties;
 18  
 import org.mule.config.builders.MuleXmlConfigurationBuilder;
 19  
 import org.mule.config.builders.QuickConfigurationBuilder;
 20  
 import org.mule.config.i18n.CoreMessages;
 21  
 import org.mule.extras.client.i18n.ClientMessages;
 22  
 import org.mule.impl.MuleEvent;
 23  
 import org.mule.impl.MuleMessage;
 24  
 import org.mule.impl.MuleSession;
 25  
 import org.mule.impl.endpoint.MuleEndpoint;
 26  
 import org.mule.impl.endpoint.MuleEndpointURI;
 27  
 import org.mule.impl.model.ModelHelper;
 28  
 import org.mule.impl.security.MuleCredentials;
 29  
 import org.mule.providers.AbstractConnector;
 30  
 import org.mule.providers.service.TransportFactory;
 31  
 import org.mule.umo.FutureMessageResult;
 32  
 import org.mule.umo.MessagingException;
 33  
 import org.mule.umo.UMODescriptor;
 34  
 import org.mule.umo.UMOEvent;
 35  
 import org.mule.umo.UMOException;
 36  
 import org.mule.umo.UMOMessage;
 37  
 import org.mule.umo.UMOSession;
 38  
 import org.mule.umo.endpoint.UMOEndpoint;
 39  
 import org.mule.umo.endpoint.UMOEndpointURI;
 40  
 import org.mule.umo.lifecycle.Disposable;
 41  
 import org.mule.umo.manager.UMOManager;
 42  
 import org.mule.umo.provider.DispatchException;
 43  
 import org.mule.umo.provider.ReceiveException;
 44  
 import org.mule.umo.provider.UMOConnector;
 45  
 import org.mule.umo.provider.UMOStreamMessageAdapter;
 46  
 import org.mule.umo.transformer.UMOTransformer;
 47  
 import org.mule.util.MuleObjectHelper;
 48  
 import org.mule.util.StringUtils;
 49  
 
 50  
 import java.util.ArrayList;
 51  
 import java.util.HashMap;
 52  
 import java.util.Iterator;
 53  
 import java.util.List;
 54  
 import java.util.Map;
 55  
 
 56  
 import edu.emory.mathcs.backport.java.util.concurrent.Callable;
 57  
 import edu.emory.mathcs.backport.java.util.concurrent.Executor;
 58  
 import org.apache.commons.logging.Log;
 59  
 import org.apache.commons.logging.LogFactory;
 60  
 
 61  
 /**
 62  
  * <code>MuleClient</code> is a simple interface for Mule clients to send and
 63  
  * receive events from a Mule Server. In most Mule applications events are triggered
 64  
  * by some external occurrence such as a message being received on a queue or file
 65  
  * being copied to a directory. The Mule client allows the user to send and receive
 66  
  * events programmatically through its Api.
 67  
  * <p>
 68  
  * The client defines a UMOEndpointURI which is used to determine how a message is
 69  
  * sent of received. The url defines the protocol, the endpointUri destination of the
 70  
  * message and optionally the endpoint to use when dispatching the event. For
 71  
  * example:
 72  
  * <p>
 73  
  * <code>vm://my.object</code> dispatches to a <code>my.object</code> destination
 74  
  * using the VM endpoint. There needs to be a global VM endpoint registered for the
 75  
  * message to be sent.
 76  
  * <p>
 77  
  * <code>jms://jmsProvider/orders.topic</code> dispatches a JMS message via the
 78  
  * globally registered jmsProvider over a topic destination called
 79  
  * <code>orders.topic</code>.
 80  
  * <p>
 81  
  * <code>jms://orders.topic</code> is equivalent to the above except that the
 82  
  * endpoint is determined by the protocol, so the first JMS endpoint is used.
 83  
  * <p>
 84  
  * Note that there must be a configured MuleManager for this client to work. It will
 85  
  * use the one available using <code>MuleManager.getInstance()</code>
 86  
  * 
 87  
  * @see org.mule.impl.endpoint.MuleEndpointURI
 88  
  */
 89  
 public class MuleClient implements Disposable
 90  
 {
 91  
     /**
 92  
      * logger used by this class
 93  
      */
 94  0
     protected static final Log logger = LogFactory.getLog(MuleClient.class);
 95  
 
 96  
     /**
 97  
      * the local UMOManager instance
 98  
      */
 99  
     private UMOManager manager;
 100  
 
 101  
     /**
 102  
      * an Executor for async messages (optional), currently always delegated to
 103  
      * MuleManager's default WorkManager
 104  
      */
 105  0
     private Executor asyncExecutor = null;
 106  
 
 107  0
     private List dispatchers = new ArrayList();
 108  
 
 109  
     // configuration helper for the client
 110  0
     QuickConfigurationBuilder builder = null;
 111  
 
 112  
     private MuleCredentials user;
 113  
 
 114  
     /**
 115  
      * Creates a default Mule client that will use the default serverEndpoint to
 116  
      * connect to a remote server instance.
 117  
      * 
 118  
      * @throws UMOException
 119  
      */
 120  
     public MuleClient() throws UMOException
 121  0
     {
 122  0
         init(/* startManager */true);
 123  0
     }
 124  
 
 125  
     /**
 126  
      * Creates a default Mule client that will use the default serverEndpoint to
 127  
      * connect to a remote server instance.
 128  
      * 
 129  
      * @param startManager start the Mule Manager if it has not yet been initialised
 130  
      * @throws UMOException
 131  
      */
 132  
     public MuleClient(boolean startManager) throws UMOException
 133  0
     {
 134  0
         init(startManager);
 135  0
     }
 136  
 
 137  
     /**
 138  
      * Configures a Mule CLient instance using the the default
 139  
      * MuleXmlConfigurationBuilder to parse the config resources
 140  
      * 
 141  
      * @param configResources a config resource location to configure this client
 142  
      *            with
 143  
      * @throws ConfigurationException is there is a MuleManager instance already
 144  
      *             running in this JVM or if the builder fails to configure the
 145  
      *             Manager
 146  
      */
 147  
     public MuleClient(String configResources) throws UMOException
 148  
     {
 149  0
         this(configResources, new MuleXmlConfigurationBuilder());
 150  0
     }
 151  
 
 152  
     /**
 153  
      * Configures a new MuleClient and either uses an existing Manager running in
 154  
      * this JVM or creates a new empty manager
 155  
      * 
 156  
      * @param user the username to use when connecting to a remote server instance
 157  
      * @param password the password for the user
 158  
      * @throws UMOException
 159  
      */
 160  
     public MuleClient(String user, String password) throws UMOException
 161  0
     {
 162  0
         init(/* startManager */true);
 163  0
         this.user = new MuleCredentials(user, password.toCharArray());
 164  0
     }
 165  
 
 166  
     /**
 167  
      * Configures a Mule Client instance
 168  
      * 
 169  
      * @param configResources a config resource location to configure this client
 170  
      *            with
 171  
      * @param builder the configuration builder to use
 172  
      * @throws ConfigurationException is there is a MuleManager instance already
 173  
      *             running in this JVM or if the builder fails to configure the
 174  
      *             Manager
 175  
      */
 176  
     public MuleClient(String configResources, ConfigurationBuilder builder) throws ConfigurationException
 177  0
     {
 178  0
         if (MuleManager.isInstanciated())
 179  
         {
 180  0
             throw new ConfigurationException(ClientMessages.managerIsAlreadyConfigured());
 181  
         }
 182  0
         if (builder == null)
 183  
         {
 184  0
             logger.info("Builder passed in was null, using default builder: "
 185  
                         + MuleXmlConfigurationBuilder.class.getName());
 186  0
             builder = new MuleXmlConfigurationBuilder();
 187  
         }
 188  0
         manager = builder.configure(configResources, null);
 189  0
     }
 190  
 
 191  
     /**
 192  
      * Configures a Mule Client instance
 193  
      * 
 194  
      * @param configResources a config resource location to configure this client
 195  
      *            with
 196  
      * @param builder the configuration builder to use
 197  
      * @param user the username to use when connecting to a remote server instance
 198  
      * @param password the password for the user
 199  
      * @throws ConfigurationException is there is a MuleManager instance already
 200  
      *             running in this JVM or if the builder fails to configure the
 201  
      *             Manager
 202  
      */
 203  
     public MuleClient(String configResources, ConfigurationBuilder builder, String user, String password)
 204  
         throws ConfigurationException
 205  
     {
 206  0
         this(configResources, builder);
 207  0
         this.user = new MuleCredentials(user, password.toCharArray());
 208  0
     }
 209  
 
 210  
     /**
 211  
      * Initialises a default MuleManager for use by the client.
 212  
      * 
 213  
      * @param startManager start the Mule Manager if it has not yet been initialised
 214  
      * @throws UMOException
 215  
      */
 216  
     private void init(boolean startManager) throws UMOException
 217  
     {
 218  
         // if we are creating a server for this client then set client mode
 219  
         // this will disable Admin connections by default;
 220  
         // If there is no local manager present create a default manager
 221  0
         if (MuleManager.isInstanciated())
 222  
         {
 223  0
             if (logger.isInfoEnabled())
 224  
             {
 225  0
                 logger.info("There is already a manager locally available to this client, no need to create a new one");
 226  
             }
 227  
         }
 228  
         else
 229  
         {
 230  0
             MuleManager.getConfiguration().setClientMode(true);
 231  0
             if (logger.isInfoEnabled())
 232  
             {
 233  0
                 logger.info("There is no manager instance locally available for this client, creating a new Manager");
 234  
             }
 235  
         }
 236  
 
 237  0
         manager = MuleManager.getInstance();
 238  0
         asyncExecutor = manager.getWorkManager();
 239  0
         builder = new QuickConfigurationBuilder();
 240  
 
 241  0
         if (!manager.isInitialised() && startManager == true)
 242  
         {
 243  0
             if (logger.isInfoEnabled()) logger.info("Starting Mule Manager for this client");
 244  0
             ((MuleManager)manager).start();
 245  
         }
 246  0
     }
 247  
 
 248  
     /**
 249  
      * Dispatches an event asynchronously to a endpointUri via a mule server. the Url
 250  
      * determines where to dispathc the event to, this can be in the form of
 251  
      * 
 252  
      * @param url the Mule url used to determine the destination and transport of the
 253  
      *            message
 254  
      * @param payload the object that is the payload of the event
 255  
      * @param messageProperties any properties to be associated with the payload. In
 256  
      *            the case of Jms you could set the JMSReplyTo property in these
 257  
      *            properties.
 258  
      * @throws org.mule.umo.UMOException
 259  
      */
 260  
     public void dispatch(String url, Object payload, Map messageProperties) throws UMOException
 261  
     {
 262  0
         dispatch(url, new MuleMessage(payload, messageProperties));
 263  0
     }
 264  
 
 265  
     /**
 266  
      * Dispatches an event asynchronously to a endpointUri via a mule server. the Url
 267  
      * determines where to dispathc the event to, this can be in the form of
 268  
      * 
 269  
      * @param url the Mule url used to determine the destination and transport of the
 270  
      *            message
 271  
      * @param message the message to send
 272  
      * @throws org.mule.umo.UMOException
 273  
      */
 274  
     public void dispatch(String url, UMOMessage message) throws UMOException
 275  
     {
 276  0
         UMOEvent event = getEvent(message, url, false, false);
 277  
         try
 278  
         {
 279  0
             event.getSession().dispatchEvent(event);
 280  
         }
 281  0
         catch (UMOException e)
 282  
         {
 283  0
             throw e;
 284  
         }
 285  0
         catch (Exception e)
 286  
         {
 287  0
             throw new DispatchException(ClientMessages.failedToDispatchClientEvent(), 
 288  
                 event.getMessage(), event.getEndpoint(), e);
 289  0
         }
 290  0
     }
 291  
 
 292  
     /**
 293  
      * Dispatches a Stream event asynchronously to a endpointUri via a mule server.
 294  
      * the Url determines where to dispathc the event to, this can be in the form of
 295  
      * 
 296  
      * @param url the Mule url used to determine the destination and transport of the
 297  
      *            message
 298  
      * @param message the message to send
 299  
      * @throws org.mule.umo.UMOException
 300  
      */
 301  
     public void dispatchStream(String url, UMOStreamMessageAdapter message) throws UMOException
 302  
     {
 303  0
         UMOEvent event = getEvent(new MuleMessage(message), url, false, true);
 304  
         try
 305  
         {
 306  0
             event.getSession().dispatchEvent(event);
 307  
         }
 308  0
         catch (UMOException e)
 309  
         {
 310  0
             throw e;
 311  
         }
 312  0
         catch (Exception e)
 313  
         {
 314  0
             throw new DispatchException(ClientMessages.failedToDispatchClientEvent(), 
 315  
                 event.getMessage(), event.getEndpoint(), e);
 316  0
         }
 317  0
     }
 318  
 
 319  
     public UMOStreamMessageAdapter sendStream(String url, UMOStreamMessageAdapter message)
 320  
         throws UMOException
 321  
     {
 322  0
         return sendStream(url, message, UMOEvent.TIMEOUT_NOT_SET_VALUE);
 323  
     }
 324  
 
 325  
     /**
 326  
      * Sends a streaming event synchronously to a endpointUri via a mule server and a
 327  
      * resulting stream is set on the passed Stream Mesage Adapter.
 328  
      * 
 329  
      * @param url the Mule url used to determine the destination and transport of the
 330  
      *            message
 331  
      * @param message The message to send
 332  
      * @param timeout The time in milliseconds the the call should block waiting for
 333  
      *            a response
 334  
      * @throws org.mule.umo.UMOException
 335  
      */
 336  
     public UMOStreamMessageAdapter sendStream(String url, UMOStreamMessageAdapter message, int timeout)
 337  
         throws UMOException
 338  
     {
 339  0
         UMOEvent event = getEvent(new MuleMessage(message), url, true, true);
 340  0
         event.setTimeout(timeout);
 341  
         try
 342  
         {
 343  0
             UMOMessage result = event.getSession().sendEvent(event);
 344  0
             if (result != null)
 345  
             {
 346  0
                 if (result.getAdapter() instanceof UMOStreamMessageAdapter)
 347  
                 {
 348  0
                     return (UMOStreamMessageAdapter)result.getAdapter();
 349  
                 }
 350  
                 else
 351  
                 {
 352  
                     // todo i18n (though this case should never happen...)
 353  0
                     throw new IllegalStateException(
 354  
                         "Mismatch of stream states. A stream was used for outbound channel, but a stream was not used for the response");
 355  
                 }
 356  
             }
 357  
         }
 358  0
         catch (UMOException e)
 359  
         {
 360  0
             throw e;
 361  
         }
 362  0
         catch (Exception e)
 363  
         {
 364  0
             throw new DispatchException(ClientMessages.failedToDispatchClientEvent(), 
 365  
                 event.getMessage(), event.getEndpoint(), e);
 366  0
         }
 367  0
         return null;
 368  
     }
 369  
 
 370  
     /**
 371  
      * sends an event synchronously to a components
 372  
      * 
 373  
      * @param component the name of the Mule components to send to
 374  
      * @param transformers a comma separated list of transformers to apply to the
 375  
      *            result message
 376  
      * @param payload the object that is the payload of the event
 377  
      * @param messageProperties any properties to be associated with the payload. as
 378  
      *            null
 379  
      * @return the result message if any of the invocation
 380  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 381  
      *             transfromers cannot be found
 382  
      */
 383  
     public UMOMessage sendDirect(String component, String transformers, Object payload, Map messageProperties)
 384  
         throws UMOException
 385  
     {
 386  0
         UMOMessage message = new MuleMessage(payload, messageProperties);
 387  0
         return sendDirect(component, transformers, message);
 388  
     }
 389  
 
 390  
     /**
 391  
      * sends an event synchronously to a components
 392  
      * 
 393  
      * @param component the name of the Mule components to send to
 394  
      * @param transformers a comma separated list of transformers to apply to the
 395  
      *            result message
 396  
      * @param message the message to send
 397  
      * @return the result message if any of the invocation
 398  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 399  
      *             transfromers cannot be found
 400  
      */
 401  
     public UMOMessage sendDirect(String component, String transformers, UMOMessage message)
 402  
         throws UMOException
 403  
     {
 404  0
         boolean compregistered = ModelHelper.isComponentRegistered(component);
 405  0
         if (!compregistered)
 406  
         {
 407  0
             throw new MessagingException(
 408  
                 CoreMessages.objectNotRegisteredWithManager("Component '" + component + "'"), 
 409  
                 message, null);
 410  
         }
 411  0
         UMOTransformer trans = null;
 412  0
         if (transformers != null)
 413  
         {
 414  0
             trans = MuleObjectHelper.getTransformer(transformers, ",");
 415  
         }
 416  
 
 417  0
         if (!MuleManager.getConfiguration().isSynchronous())
 418  
         {
 419  0
             logger.warn("The mule manager is running synchronously, a null message payload will be returned");
 420  
         }
 421  0
         UMOSession session = new MuleSession(ModelHelper.getComponent(component));
 422  0
         UMOEndpoint endpoint = getDefaultClientEndpoint(session.getComponent().getDescriptor(),
 423  
             message.getPayload());
 424  0
         UMOEvent event = new MuleEvent(message, endpoint, session, true);
 425  
 
 426  0
         if (logger.isDebugEnabled())
 427  
         {
 428  0
             logger.debug("MuleClient sending event direct to: " + component + ". Event is: " + event);
 429  
         }
 430  
 
 431  0
         UMOMessage result = event.getComponent().sendEvent(event);
 432  
 
 433  0
         if (logger.isDebugEnabled())
 434  
         {
 435  0
             logger.debug("Result of MuleClient sendDirect is: "
 436  
                          + (result == null ? "null" : result.getPayload()));
 437  
         }
 438  
 
 439  0
         if (result != null && trans != null)
 440  
         {
 441  0
             return new MuleMessage(trans.transform(result.getPayload()));
 442  
         }
 443  
         else
 444  
         {
 445  0
             return result;
 446  
         }
 447  
     }
 448  
 
 449  
     /**
 450  
      * dispatches an event asynchronously to the components
 451  
      * 
 452  
      * @param component the name of the Mule components to dispatch to
 453  
      * @param payload the object that is the payload of the event
 454  
      * @param messageProperties any properties to be associated with the payload. as
 455  
      *            null
 456  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 457  
      *             transfromers cannot be found
 458  
      */
 459  
     public void dispatchDirect(String component, Object payload, Map messageProperties) throws UMOException
 460  
     {
 461  0
         dispatchDirect(component, new MuleMessage(payload, messageProperties));
 462  0
     }
 463  
 
 464  
     /**
 465  
      * dispatches an event asynchronously to the components
 466  
      * 
 467  
      * @param component the name of the Mule components to dispatch to
 468  
      * @param message the message to send
 469  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 470  
      *             transfromers cannot be found
 471  
      */
 472  
     public void dispatchDirect(String component, UMOMessage message) throws UMOException
 473  
     {
 474  0
         boolean compregistered = ModelHelper.isComponentRegistered(component);
 475  0
         if (!compregistered)
 476  
         {
 477  0
             throw new MessagingException(
 478  
                 CoreMessages.objectNotRegisteredWithManager("Component '" + component + "'"), 
 479  
                 message, null);
 480  
         }
 481  0
         UMOSession session = new MuleSession(ModelHelper.getComponent(component));
 482  0
         UMOEndpoint endpoint = getDefaultClientEndpoint(session.getComponent().getDescriptor(),
 483  
             message.getPayload());
 484  0
         UMOEvent event = new MuleEvent(message, endpoint, session, true);
 485  
 
 486  0
         if (logger.isDebugEnabled())
 487  
         {
 488  0
             logger.debug("MuleClient dispatching event direct to: " + component + ". Event is: " + event);
 489  
         }
 490  
 
 491  0
         event.getComponent().dispatchEvent(event);
 492  0
     }
 493  
 
 494  
     /**
 495  
      * sends an event request to a Url, making the result of the event trigger
 496  
      * available as a Future result that can be accessed later by client code.
 497  
      * 
 498  
      * @param url the url to make a request on
 499  
      * @param payload the object that is the payload of the event
 500  
      * @param messageProperties any properties to be associated with the payload. as
 501  
      *            null
 502  
      * @return the result message if any of the invocation
 503  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 504  
      *             transfromers cannot be found
 505  
      */
 506  
     public FutureMessageResult sendAsync(final String url, final Object payload, final Map messageProperties)
 507  
         throws UMOException
 508  
     {
 509  0
         return sendAsync(url, payload, messageProperties, 0);
 510  
     }
 511  
 
 512  
     /**
 513  
      * sends an event request to a Url, making the result of the event trigger
 514  
      * available as a Future result that can be accessed later by client code.
 515  
      * 
 516  
      * @param url the url to make a request on
 517  
      * @param message the message to send
 518  
      * @return the result message if any of the invocation
 519  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 520  
      *             transfromers cannot be found
 521  
      */
 522  
     public FutureMessageResult sendAsync(final String url, final UMOMessage message) throws UMOException
 523  
     {
 524  0
         return sendAsync(url, message, UMOEvent.TIMEOUT_NOT_SET_VALUE);
 525  
     }
 526  
 
 527  
     /**
 528  
      * sends an event request to a Url, making the result of the event trigger
 529  
      * available as a Future result that can be accessed later by client code.
 530  
      * 
 531  
      * @param url the url to make a request on
 532  
      * @param payload the object that is the payload of the event
 533  
      * @param messageProperties any properties to be associated with the payload. as
 534  
      *            null
 535  
      * @param timeout how long to block in milliseconds waiting for a result
 536  
      * @return the result message if any of the invocation
 537  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 538  
      *             transfromers cannot be found
 539  
      */
 540  
     public FutureMessageResult sendAsync(final String url,
 541  
                                          final Object payload,
 542  
                                          final Map messageProperties,
 543  
                                          final int timeout) throws UMOException
 544  
     {
 545  0
         return sendAsync(url, new MuleMessage(payload, messageProperties), timeout);
 546  
     }
 547  
 
 548  
     /**
 549  
      * sends an event request to a Url, making the result of the event trigger
 550  
      * available as a Future result that can be accessed later by client code.
 551  
      * 
 552  
      * @param url the url to make a request on
 553  
      * @param message the message to send
 554  
      * @param timeout how long to block in milliseconds waiting for a result
 555  
      * @return the result message if any of the invocation
 556  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 557  
      *             transfromers cannot be found
 558  
      */
 559  
     public FutureMessageResult sendAsync(final String url, final UMOMessage message, final int timeout)
 560  
         throws UMOException
 561  
     {
 562  0
         Callable call = new Callable()
 563  
         {
 564  0
             public Object call() throws Exception
 565  
             {
 566  0
                 return send(url, message, timeout);
 567  
             }
 568  
         };
 569  
 
 570  0
         FutureMessageResult result = new FutureMessageResult(call);
 571  
 
 572  0
         if (asyncExecutor != null)
 573  
         {
 574  0
             result.setExecutor(asyncExecutor);
 575  
         }
 576  
 
 577  0
         result.execute();
 578  0
         return result;
 579  
     }
 580  
 
 581  
     /**
 582  
      * sends an event to a components on a local Mule instance, while making the
 583  
      * result of the event trigger available as a Future result that can be accessed
 584  
      * later by client code. If forwardDirectRequests flag s set and the components
 585  
      * is not found on the local Mule instance it will forward to a remote server.
 586  
      * Users can endpoint a url to a remote Mule server in the constructor of a Mule
 587  
      * client, by default the default Mule server url tcp://localhost:60504 is used.
 588  
      * 
 589  
      * @param component the name of the Mule components to send to
 590  
      * @param transformers a comma separated list of transformers to apply to the
 591  
      *            result message
 592  
      * @param payload the object that is the payload of the event
 593  
      * @param messageProperties any properties to be associated with the payload. as
 594  
      *            null
 595  
      * @return the result message if any of the invocation
 596  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 597  
      *             transfromers cannot be found
 598  
      */
 599  
     public FutureMessageResult sendDirectAsync(final String component,
 600  
                                                String transformers,
 601  
                                                final Object payload,
 602  
                                                final Map messageProperties) throws UMOException
 603  
     {
 604  0
         return sendDirectAsync(component, transformers, new MuleMessage(payload, messageProperties));
 605  
     }
 606  
 
 607  
     /**
 608  
      * sends an event to a components on a local Mule instance, while making the
 609  
      * result of the event trigger available as a Future result that can be accessed
 610  
      * later by client code. If forwardDirectRequests flag s set and the components
 611  
      * is not found on the local Mule instance it will forward to a remote server.
 612  
      * Users can endpoint a url to a remote Mule server in the constructor of a Mule
 613  
      * client, by default the default Mule server url tcp://localhost:60504 is used.
 614  
      * 
 615  
      * @param component the name of the Mule components to send to
 616  
      * @param transformers a comma separated list of transformers to apply to the
 617  
      *            result message
 618  
      * @param message the message to send
 619  
      * @return the result message if any of the invocation
 620  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 621  
      *             transfromers cannot be found
 622  
      */
 623  
     public FutureMessageResult sendDirectAsync(final String component,
 624  
                                                String transformers,
 625  
                                                final UMOMessage message) throws UMOException
 626  
     {
 627  0
         Callable call = new Callable()
 628  
         {
 629  0
             public Object call() throws Exception
 630  
             {
 631  0
                 return sendDirect(component, null, message);
 632  
             }
 633  
         };
 634  
 
 635  0
         FutureMessageResult result = new FutureMessageResult(call);
 636  
 
 637  0
         if (asyncExecutor != null)
 638  
         {
 639  0
             result.setExecutor(asyncExecutor);
 640  
         }
 641  
 
 642  0
         if (StringUtils.isNotBlank(transformers))
 643  
         {
 644  0
             result.setTransformer(MuleObjectHelper.getTransformer(transformers, ","));
 645  
         }
 646  
 
 647  0
         result.execute();
 648  0
         return result;
 649  
     }
 650  
 
 651  
     /**
 652  
      * Sends an event synchronously to a endpointUri via a mule server and a
 653  
      * resulting message is returned.
 654  
      * 
 655  
      * @param url the Mule url used to determine the destination and transport of the
 656  
      *            message
 657  
      * @param payload the object that is the payload of the event
 658  
      * @param messageProperties any properties to be associated with the payload. In
 659  
      *            the case of Jms you could set the JMSReplyTo property in these
 660  
      *            properties.
 661  
      * @return A return message, this could be null if the the components invoked
 662  
      *         explicitly sets a return as null
 663  
      * @throws org.mule.umo.UMOException
 664  
      */
 665  
     public UMOMessage send(String url, Object payload, Map messageProperties) throws UMOException
 666  
     {
 667  0
         return send(url, payload, messageProperties, UMOEvent.TIMEOUT_NOT_SET_VALUE);
 668  
     }
 669  
 
 670  
     /**
 671  
      * Sends an event synchronously to a endpointUri via a mule server and a
 672  
      * resulting message is returned.
 673  
      * 
 674  
      * @param url the Mule url used to determine the destination and transport of the
 675  
      *            message
 676  
      * @param message the Message for the event
 677  
      * @return A return message, this could be null if the the components invoked
 678  
      *         explicitly sets a return as null
 679  
      * @throws org.mule.umo.UMOException
 680  
      */
 681  
     public UMOMessage send(String url, UMOMessage message) throws UMOException
 682  
     {
 683  0
         return send(url, message, UMOEvent.TIMEOUT_NOT_SET_VALUE);
 684  
     }
 685  
 
 686  
     /**
 687  
      * Sends an event synchronously to a endpointUri via a mule server and a
 688  
      * resulting message is returned.
 689  
      * 
 690  
      * @param url the Mule url used to determine the destination and transport of the
 691  
      *            message
 692  
      * @param payload the object that is the payload of the event
 693  
      * @param messageProperties any properties to be associated with the payload. In
 694  
      *            the case of Jms you could set the JMSReplyTo property in these
 695  
      *            properties.
 696  
      * @param timeout The time in milliseconds the the call should block waiting for
 697  
      *            a response
 698  
      * @return A return message, this could be null if the the components invoked
 699  
      *         explicitly sets a return as null
 700  
      * @throws org.mule.umo.UMOException
 701  
      */
 702  
     public UMOMessage send(String url, Object payload, Map messageProperties, int timeout)
 703  
         throws UMOException
 704  
     {
 705  0
         if (messageProperties == null)
 706  
         {
 707  0
             messageProperties = new HashMap();
 708  
         }
 709  0
         if (messageProperties.get(MuleProperties.MULE_REMOTE_SYNC_PROPERTY) == null)
 710  
         {
 711  0
             messageProperties.put(MuleProperties.MULE_REMOTE_SYNC_PROPERTY, "true");
 712  
         }
 713  0
         UMOMessage message = new MuleMessage(payload, messageProperties);
 714  0
         return send(url, message, timeout);
 715  
     }
 716  
 
 717  
     /**
 718  
      * Sends an event synchronously to a endpointUri via a mule server and a
 719  
      * resulting message is returned.
 720  
      * 
 721  
      * @param url the Mule url used to determine the destination and transport of the
 722  
      *            message
 723  
      * @param message The message to send
 724  
      * @param timeout The time in milliseconds the the call should block waiting for
 725  
      *            a response
 726  
      * @return A return message, this could be null if the the components invoked
 727  
      *         explicitly sets a return as null
 728  
      * @throws org.mule.umo.UMOException
 729  
      */
 730  
     public UMOMessage send(String url, UMOMessage message, int timeout) throws UMOException
 731  
     {
 732  0
         UMOEvent event = getEvent(message, url, true, false);
 733  0
         event.setTimeout(timeout);
 734  
 
 735  
         try
 736  
         {
 737  0
             return event.getSession().sendEvent(event);
 738  
         }
 739  0
         catch (UMOException e)
 740  
         {
 741  0
             throw e;
 742  
         }
 743  0
         catch (Exception e)
 744  
         {
 745  0
             throw new DispatchException(ClientMessages.failedToDispatchClientEvent(), 
 746  
                 event.getMessage(), event.getEndpoint(), e);
 747  
         }
 748  
     }
 749  
 
 750  
     /**
 751  
      * Will receive an event from an endpointUri determined by the url
 752  
      * 
 753  
      * @param url the Mule url used to determine the destination and transport of the
 754  
      *            message
 755  
      * @param timeout how long to block waiting to receive the event, if set to 0 the
 756  
      *            receive will not wait at all and if set to -1 the receive will wait
 757  
      *            forever
 758  
      * @return the message received or null if no message was received
 759  
      * @throws org.mule.umo.UMOException
 760  
      */
 761  
     public UMOMessage receive(String url, long timeout) throws UMOException
 762  
     {
 763  0
         UMOEndpoint endpoint = getEndpoint(url, UMOEndpoint.ENDPOINT_TYPE_RECEIVER);
 764  
         try
 765  
         {
 766  0
             UMOMessage message = endpoint.receive(timeout);
 767  0
             if (message != null && endpoint.getTransformer() != null)
 768  
             {
 769  0
                 if (endpoint.getTransformer().isSourceTypeSupported(message.getPayload().getClass()))
 770  
                 {
 771  0
                     message = new MuleMessage(endpoint.getTransformer().transform(message.getPayload()),
 772  
                         message);
 773  
                 }
 774  
             }
 775  0
             return message;
 776  
         }
 777  0
         catch (Exception e)
 778  
         {
 779  0
             throw new ReceiveException(endpoint, timeout, e);
 780  
         }
 781  
     }
 782  
 
 783  
     /**
 784  
      * Will receive an event from an endpointUri determined by the url
 785  
      * 
 786  
      * @param url the Mule url used to determine the destination and transport of the
 787  
      *            message
 788  
      * @param transformers A comma separated list of transformers used to apply to
 789  
      *            the result message
 790  
      * @param timeout how long to block waiting to receive the event, if set to 0 the
 791  
      *            receive will not wait at all and if set to -1 the receive will wait
 792  
      *            forever
 793  
      * @return the message received or null if no message was received
 794  
      * @throws org.mule.umo.UMOException
 795  
      */
 796  
     public UMOMessage receive(String url, String transformers, long timeout) throws UMOException
 797  
     {
 798  0
         return receive(url, MuleObjectHelper.getTransformer(transformers, ","), timeout);
 799  
     }
 800  
 
 801  
     /**
 802  
      * Will receive an event from an endpointUri determined by the url
 803  
      * 
 804  
      * @param url the Mule url used to determine the destination and transport of the
 805  
      *            message
 806  
      * @param transformer A transformer used to apply to the result message
 807  
      * @param timeout how long to block waiting to receive the event, if set to 0 the
 808  
      *            receive will not wait at all and if set to -1 the receive will wait
 809  
      *            forever
 810  
      * @return the message received or null if no message was received
 811  
      * @throws org.mule.umo.UMOException
 812  
      */
 813  
     public UMOMessage receive(String url, UMOTransformer transformer, long timeout) throws UMOException
 814  
     {
 815  0
         UMOMessage message = receive(url, timeout);
 816  0
         if (message != null && transformer != null)
 817  
         {
 818  0
             return new MuleMessage(transformer.transform(message.getPayload()));
 819  
         }
 820  
         else
 821  
         {
 822  0
             return message;
 823  
         }
 824  
     }
 825  
 
 826  
     /**
 827  
      * Packages a mule event for the current request
 828  
      * 
 829  
      * @param message the event payload
 830  
      * @param uri the destination endpointUri
 831  
      * @param synchronous whether the event will be synchronously processed
 832  
      * @param streaming
 833  
      * @return the UMOEvent
 834  
      * @throws UMOException
 835  
      */
 836  
     protected UMOEvent getEvent(UMOMessage message, String uri, boolean synchronous, boolean streaming)
 837  
         throws UMOException
 838  
     {
 839  0
         UMOEndpoint endpoint = getEndpoint(uri, UMOEndpoint.ENDPOINT_TYPE_SENDER);
 840  0
         if (!endpoint.getConnector().isStarted() && manager.isStarted())
 841  
         {
 842  0
             endpoint.getConnector().startConnector();
 843  
         }
 844  0
         endpoint.setStreaming(streaming);
 845  
         try
 846  
         {
 847  0
             MuleSession session = new MuleSession(message,
 848  
                 ((AbstractConnector)endpoint.getConnector()).getSessionHandler());
 849  
 
 850  0
             if (user != null)
 851  
             {
 852  0
                 message.setProperty(MuleProperties.MULE_USER_PROPERTY, MuleCredentials.createHeader(
 853  
                     user.getUsername(), user.getPassword()));
 854  
             }
 855  0
             MuleEvent event = new MuleEvent(message, endpoint, session, synchronous);
 856  0
             return event;
 857  
         }
 858  0
         catch (Exception e)
 859  
         {
 860  0
             throw new DispatchException(CoreMessages.failedToCreate("Client event"), message, endpoint, e);
 861  
         }
 862  
     }
 863  
 
 864  
     protected UMOEndpoint getEndpoint(String uri, String type) throws UMOException
 865  
     {
 866  0
         UMOEndpoint endpoint = manager.lookupEndpoint(uri);
 867  0
         if (endpoint == null)
 868  
         {
 869  0
             endpoint = MuleEndpoint.getOrCreateEndpointForUri(uri, type);
 870  
         }
 871  0
         return endpoint;
 872  
     }
 873  
 
 874  
     protected UMOEndpoint getDefaultClientEndpoint(UMODescriptor descriptor, Object payload)
 875  
         throws UMOException
 876  
     {
 877  
         // as we are bypassing the message transport layer we need to check that
 878  0
         UMOEndpoint endpoint = descriptor.getInboundEndpoint();
 879  0
         if (endpoint != null)
 880  
         {
 881  0
             if (endpoint.getTransformer() != null)
 882  
             {
 883  0
                 if (endpoint.getTransformer().isSourceTypeSupported(payload.getClass()))
 884  
                 {
 885  0
                     return endpoint;
 886  
                 }
 887  
                 else
 888  
                 {
 889  0
                     endpoint = new MuleEndpoint(endpoint);
 890  0
                     endpoint.setTransformer(null);
 891  0
                     return endpoint;
 892  
                 }
 893  
             }
 894  
             else
 895  
             {
 896  0
                 return endpoint;
 897  
             }
 898  
         }
 899  
         else
 900  
         {
 901  0
             UMOConnector connector = null;
 902  0
             UMOEndpointURI defaultEndpointUri = new MuleEndpointURI("vm://mule.client");
 903  0
             connector = TransportFactory.createConnector(defaultEndpointUri);
 904  0
             manager.registerConnector(connector);
 905  0
             connector.startConnector();
 906  0
             endpoint = new MuleEndpoint("muleClientProvider", defaultEndpointUri, connector, null,
 907  
                 UMOEndpoint.ENDPOINT_TYPE_RECEIVER, 0, null, null);
 908  
         }
 909  
 
 910  0
         manager.registerEndpoint(endpoint);
 911  0
         return endpoint;
 912  
     }
 913  
 
 914  
     /**
 915  
      * Sends an event synchronously to a endpointUri via a mule server without
 916  
      * waiting for the result.
 917  
      * 
 918  
      * @param url the Mule url used to determine the destination and transport of the
 919  
      *            message
 920  
      * @param payload the object that is the payload of the event
 921  
      * @param messageProperties any properties to be associated with the payload. In
 922  
      *            the case of Jms you could set the JMSReplyTo property in these
 923  
      *            properties.
 924  
      * @throws org.mule.umo.UMOException
 925  
      */
 926  
     public void sendNoReceive(String url, Object payload, Map messageProperties) throws UMOException
 927  
     {
 928  0
         if (messageProperties == null)
 929  
         {
 930  0
             messageProperties = new HashMap();
 931  
         }
 932  0
         messageProperties.put(MuleProperties.MULE_REMOTE_SYNC_PROPERTY, "false");
 933  0
         UMOMessage message = new MuleMessage(payload, messageProperties);
 934  0
         UMOEvent event = getEvent(message, url, true, false);
 935  
         try
 936  
         {
 937  0
             event.getSession().sendEvent(event);
 938  
         }
 939  0
         catch (UMOException e)
 940  
         {
 941  0
             throw e;
 942  
         }
 943  0
         catch (Exception e)
 944  
         {
 945  0
             throw new DispatchException(ClientMessages.failedToDispatchClientEvent(), 
 946  
                 event.getMessage(), event.getEndpoint(), e);
 947  0
         }
 948  0
     }
 949  
 
 950  
     /**
 951  
      * Overriding methods may want to return a custom manager here
 952  
      * 
 953  
      * @return the UMOManager to use
 954  
      */
 955  
     public UMOManager getManager()
 956  
     {
 957  0
         return MuleManager.getInstance();
 958  
     }
 959  
 
 960  
     /**
 961  
      * Registers a java object as a Umo pcomponent that listens for events on the
 962  
      * given url. By default the ThreadingProfile for the components will be set so
 963  
      * that there will only be one thread of execution.
 964  
      * 
 965  
      * @param component any java object, Mule will it's endpointUri discovery to
 966  
      *            determine which event to invoke based on the evnet payload type
 967  
      * @param name The identifying name of the components. This can be used to later
 968  
      *            unregister it
 969  
      * @param listenerEndpoint The url endpointUri to listen to
 970  
      * @throws UMOException
 971  
      */
 972  
     public void registerComponent(Object component, String name, UMOEndpointURI listenerEndpoint)
 973  
         throws UMOException
 974  
     {
 975  0
         builder.registerComponentInstance(component, name, listenerEndpoint, null);
 976  0
     }
 977  
 
 978  
     /**
 979  
      * Registers a java object as a Umo pcomponent that listens for and sends events
 980  
      * on the given urls. By default the ThreadingProfile for the components will be
 981  
      * set so that there will only be one thread of execution.
 982  
      * 
 983  
      * @param component any java object, Mule will it's endpointUri discovery to
 984  
      *            determine which event to invoke based on the evnet payload type
 985  
      * @param name The identifying name of the components. This can be used to later
 986  
      *            unregister it
 987  
      * @param listenerEndpoint The url endpointUri to listen to
 988  
      * @param sendEndpoint The url endpointUri to dispatch to
 989  
      * @throws UMOException
 990  
      */
 991  
     public void registerComponent(Object component,
 992  
                                   String name,
 993  
                                   MuleEndpointURI listenerEndpoint,
 994  
                                   MuleEndpointURI sendEndpoint) throws UMOException
 995  
     {
 996  0
         builder.registerComponentInstance(component, name, listenerEndpoint, sendEndpoint);
 997  0
     }
 998  
 
 999  
     /**
 1000  
      * Registers a user configured MuleDescriptor of a components to the server. If
 1001  
      * users want to register object instances with the server rather than class
 1002  
      * names that get created at runtime or reference to objects in the container,
 1003  
      * the user must call the descriptors setImplementationInstance() method - <code>
 1004  
      * MyBean implementation = new MyBean();
 1005  
      * descriptor.setImplementationInstance(implementation);
 1006  
      * </code>
 1007  
      * Calling this method is equivilent to calling UMOModel.registerComponent(..)
 1008  
      * 
 1009  
      * @param descriptor the componet descriptor to register
 1010  
      * @throws UMOException the descriptor is invalid or cannot be initialised or
 1011  
      *             started
 1012  
      * @see org.mule.umo.model.UMOModel
 1013  
      */
 1014  
     public void registerComponent(UMODescriptor descriptor) throws UMOException
 1015  
     {
 1016  0
         builder.registerComponent(descriptor);
 1017  0
     }
 1018  
 
 1019  
     /**
 1020  
      * Unregisters a previously register components. This will also unregister any
 1021  
      * listeners for the components Calling this method is equivilent to calling
 1022  
      * UMOModel.unregisterComponent(..)
 1023  
      * 
 1024  
      * @param name the name of the componet to unregister
 1025  
      * @throws UMOException if unregistering the components fails, i.e. The
 1026  
      *             underlying transport fails to unregister a listener. If the
 1027  
      *             components does not exist, this method should not throw an
 1028  
      *             exception.
 1029  
      * @see org.mule.umo.model.UMOModel
 1030  
      */
 1031  
     public void unregisterComponent(String name) throws UMOException
 1032  
     {
 1033  0
         builder.unregisterComponent(name);
 1034  0
     }
 1035  
 
 1036  
     public RemoteDispatcher getRemoteDispatcher(String serverEndpoint) throws UMOException
 1037  
     {
 1038  0
         RemoteDispatcher rd = new RemoteDispatcher(serverEndpoint);
 1039  0
         rd.setExecutor(asyncExecutor);
 1040  0
         dispatchers.add(rd);
 1041  0
         return rd;
 1042  
     }
 1043  
 
 1044  
     public RemoteDispatcher getRemoteDispatcher(String serverEndpoint, String user, String password)
 1045  
         throws UMOException
 1046  
     {
 1047  0
         RemoteDispatcher rd = new RemoteDispatcher(serverEndpoint, new MuleCredentials(user,
 1048  
             password.toCharArray()));
 1049  0
         rd.setExecutor(asyncExecutor);
 1050  0
         dispatchers.add(rd);
 1051  0
         return rd;
 1052  
     }
 1053  
 
 1054  
     /**
 1055  
      * Will dispose the MuleManager instance *IF* a new instance was created for this
 1056  
      * client. Otherwise this method only cleans up resources no longer needed
 1057  
      */
 1058  
     public void dispose()
 1059  
     {
 1060  0
         synchronized (dispatchers)
 1061  
         {
 1062  0
             for (Iterator iterator = dispatchers.iterator(); iterator.hasNext();)
 1063  
             {
 1064  0
                 RemoteDispatcher remoteDispatcher = (RemoteDispatcher)iterator.next();
 1065  0
                 remoteDispatcher.dispose();
 1066  0
                 remoteDispatcher = null;
 1067  
             }
 1068  0
             dispatchers.clear();
 1069  0
         }
 1070  
         // Dispose the manager only if the manager was created for this client
 1071  0
         if (MuleManager.getConfiguration().isClientMode())
 1072  
         {
 1073  0
             manager.dispose();
 1074  
         }
 1075  0
     }
 1076  
 
 1077  
     public void setProperty(Object key, Object value)
 1078  
     {
 1079  0
         manager.setProperty(key, value);
 1080  0
     }
 1081  
 
 1082  
     public Object getProperty(Object key)
 1083  
     {
 1084  0
         return manager.getProperty(key);
 1085  
     }
 1086  
 
 1087  
     public MuleConfiguration getConfiguration()
 1088  
     {
 1089  0
         return MuleManager.getConfiguration();
 1090  
     }
 1091  
 }