Coverage Report - org.mule.extras.client.RemoteDispatcher
 
Classes in this File Line Coverage Branch Coverage Complexity
RemoteDispatcher
0%
0/99
0%
0/15
1.739
RemoteDispatcher$1
0%
0/2
N/A
1.739
RemoteDispatcher$2
0%
0/2
N/A
1.739
RemoteDispatcher$3
0%
0/2
N/A
1.739
 
 1  
 /*
 2  
  * $Id: RemoteDispatcher.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.MuleProperties;
 15  
 import org.mule.impl.MuleEvent;
 16  
 import org.mule.impl.MuleMessage;
 17  
 import org.mule.impl.MuleSession;
 18  
 import org.mule.impl.MuleSessionHandler;
 19  
 import org.mule.impl.RequestContext;
 20  
 import org.mule.impl.endpoint.MuleEndpoint;
 21  
 import org.mule.impl.internal.notifications.AdminNotification;
 22  
 import org.mule.impl.security.MuleCredentials;
 23  
 import org.mule.providers.AbstractConnector;
 24  
 import org.mule.providers.service.TransportFactory;
 25  
 import org.mule.transformers.wire.SerializationWireFormat;
 26  
 import org.mule.transformers.wire.WireFormat;
 27  
 import org.mule.umo.FutureMessageResult;
 28  
 import org.mule.umo.UMOEvent;
 29  
 import org.mule.umo.UMOException;
 30  
 import org.mule.umo.UMOMessage;
 31  
 import org.mule.umo.endpoint.UMOEndpoint;
 32  
 import org.mule.umo.lifecycle.Disposable;
 33  
 import org.mule.umo.provider.DispatchException;
 34  
 import org.mule.umo.security.UMOCredentials;
 35  
 import org.mule.util.MuleObjectHelper;
 36  
 
 37  
 import java.io.ByteArrayInputStream;
 38  
 import java.io.ByteArrayOutputStream;
 39  
 import java.io.InputStream;
 40  
 import java.util.Map;
 41  
 
 42  
 import edu.emory.mathcs.backport.java.util.concurrent.Callable;
 43  
 import edu.emory.mathcs.backport.java.util.concurrent.Executor;
 44  
 import org.apache.commons.logging.Log;
 45  
 import org.apache.commons.logging.LogFactory;
 46  
 
 47  
 /**
 48  
  * <code>RemoteDispatcher</code> is used to make and receive requests to a remote
 49  
  * Mule instance. It is used to proxy requests to Mule using the Server URL as the
 50  
  * transport channel.
 51  
  */
 52  
 
 53  
 public class RemoteDispatcher implements Disposable
 54  
 {
 55  
 
 56  
     /**
 57  
      * logger used by this class
 58  
      */
 59  0
     protected static final Log logger = LogFactory.getLog(RemoteDispatcher.class);
 60  
 
 61  
     /**
 62  
      * dispatch destination
 63  
      */
 64  
     private UMOEndpoint serverEndpoint;
 65  0
     private UMOCredentials credentials = null;
 66  
 
 67  
     /**
 68  
      * an ExecutorService for async messages (optional)
 69  
      */
 70  
     private Executor asyncExecutor;
 71  
 
 72  
     /**
 73  
      * calls made to a remote server are serialised using a wireformat
 74  
      */
 75  
     private WireFormat wireFormat;
 76  
 
 77  
     protected RemoteDispatcher(String endpoint, UMOCredentials credentials) throws UMOException
 78  
     {
 79  0
         this(endpoint);
 80  0
         this.credentials = credentials;
 81  0
     }
 82  
 
 83  
     protected RemoteDispatcher(String endpoint) throws UMOException
 84  0
     {
 85  0
         serverEndpoint = new MuleEndpoint(endpoint, true);
 86  0
         wireFormat = new SerializationWireFormat();
 87  0
     }
 88  
 
 89  
     protected void setExecutor(Executor e)
 90  
     {
 91  0
         this.asyncExecutor = e;
 92  0
     }
 93  
 
 94  
     /**
 95  
      * Dispatcher an event asynchronously to a components on a remote Mule instance.
 96  
      * Users can endpoint a url to a remote Mule server in the constructor of a Mule
 97  
      * client, by default the default Mule server url tcp://localhost:60504 is used.
 98  
      * 
 99  
      * @param component the name of the Mule components to dispatch to
 100  
      * @param payload the object that is the payload of the event
 101  
      * @param messageProperties any properties to be associated with the payload. as
 102  
      *            null
 103  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 104  
      *             transfromers cannot be found
 105  
      */
 106  
     public void dispatchToRemoteComponent(String component, Object payload, Map messageProperties)
 107  
         throws UMOException
 108  
     {
 109  0
         doToRemoteComponent(component, payload, messageProperties, false);
 110  0
     }
 111  
 
 112  
     /**
 113  
      * sends an event synchronously to a components on a remote Mule instance. Users
 114  
      * can endpoint a url to a remote Mule server in the constructor of a Mule
 115  
      * client, by default the default Mule server url tcp://localhost:60504 is used.
 116  
      * 
 117  
      * @param component the name of the Mule components to send to
 118  
      * @param payload the object that is the payload of the event
 119  
      * @param messageProperties any properties to be associated with the payload. as
 120  
      *            null
 121  
      * @return the result message if any of the invocation
 122  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 123  
      *             transfromers cannot be found
 124  
      */
 125  
     public UMOMessage sendToRemoteComponent(String component, Object payload, Map messageProperties)
 126  
         throws UMOException
 127  
     {
 128  0
         return doToRemoteComponent(component, payload, messageProperties, true);
 129  
     }
 130  
 
 131  
     /**
 132  
      * sends an event to a components on a remote Mule instance, while making the
 133  
      * result of the event trigger available as a Future result that can be accessed
 134  
      * later by client code. Users can endpoint a url to a remote Mule server in the
 135  
      * constructor of a Mule client, by default the default Mule server url
 136  
      * tcp://localhost:60504 is used.
 137  
      * 
 138  
      * @param component the name of the Mule components to send to
 139  
      * @param transformers a comma separated list of transformers to apply to the
 140  
      *            result message
 141  
      * @param payload the object that is the payload of the event
 142  
      * @param messageProperties any properties to be associated with the payload. as
 143  
      *            null
 144  
      * @return the result message if any of the invocation
 145  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 146  
      *             transfromers cannot be found
 147  
      */
 148  
     public FutureMessageResult sendAsyncToRemoteComponent(final String component,
 149  
                                                           String transformers,
 150  
                                                           final Object payload,
 151  
                                                           final Map messageProperties) throws UMOException
 152  
     {
 153  0
         Callable callable = new Callable()
 154  
         {
 155  0
             public Object call() throws Exception
 156  
             {
 157  0
                 return doToRemoteComponent(component, payload, messageProperties, true);
 158  
             }
 159  
         };
 160  
 
 161  0
         FutureMessageResult result = new FutureMessageResult(callable);
 162  
 
 163  0
         if (asyncExecutor != null)
 164  
         {
 165  0
             result.setExecutor(asyncExecutor);
 166  
         }
 167  
 
 168  0
         if (transformers != null)
 169  
         {
 170  0
             result.setTransformer(MuleObjectHelper.getTransformer(transformers, ","));
 171  
         }
 172  
 
 173  0
         result.execute();
 174  0
         return result;
 175  
     }
 176  
 
 177  
     public UMOMessage sendRemote(String endpoint, Object payload, Map messageProperties, int timeout)
 178  
         throws UMOException
 179  
     {
 180  0
         return doToRemote(endpoint, payload, messageProperties, true, timeout);
 181  
     }
 182  
 
 183  
     public UMOMessage sendRemote(String endpoint, Object payload, Map messageProperties) throws UMOException
 184  
     {
 185  0
         return doToRemote(endpoint, payload, messageProperties, true, MuleManager.getConfiguration()
 186  
             .getSynchronousEventTimeout());
 187  
     }
 188  
 
 189  
     public void dispatchRemote(String endpoint, Object payload, Map messageProperties) throws UMOException
 190  
     {
 191  0
         doToRemote(endpoint, payload, messageProperties, false, -1);
 192  0
     }
 193  
 
 194  
     public FutureMessageResult sendAsyncRemote(final String endpoint,
 195  
                                                final Object payload,
 196  
                                                final Map messageProperties) throws UMOException
 197  
     {
 198  0
         Callable callable = new Callable()
 199  
         {
 200  0
             public Object call() throws Exception
 201  
             {
 202  0
                 return doToRemote(endpoint, payload, messageProperties, true, -1);
 203  
             }
 204  
         };
 205  
 
 206  0
         FutureMessageResult result = new FutureMessageResult(callable);
 207  
 
 208  0
         if (asyncExecutor != null)
 209  
         {
 210  0
             result.setExecutor(asyncExecutor);
 211  
         }
 212  
 
 213  0
         result.execute();
 214  0
         return result;
 215  
     }
 216  
 
 217  
     public UMOMessage receiveRemote(String endpoint, int timeout) throws UMOException
 218  
     {
 219  0
         AdminNotification action = new AdminNotification(null, AdminNotification.ACTION_RECEIVE, endpoint);
 220  0
         action.setProperty(MuleProperties.MULE_REMOTE_SYNC_PROPERTY, "true");
 221  0
         action.setProperty(MuleProperties.MULE_EVENT_TIMEOUT_PROPERTY, new Long(timeout));
 222  0
         UMOMessage result = dispatchAction(action, true, timeout);
 223  0
         return result;
 224  
     }
 225  
 
 226  
     public FutureMessageResult asyncReceiveRemote(final String endpoint, final int timeout)
 227  
         throws UMOException
 228  
     {
 229  0
         Callable callable = new Callable()
 230  
         {
 231  0
             public Object call() throws Exception
 232  
             {
 233  0
                 return receiveRemote(endpoint, timeout);
 234  
             }
 235  
         };
 236  
 
 237  0
         FutureMessageResult result = new FutureMessageResult(callable);
 238  
 
 239  0
         if (asyncExecutor != null)
 240  
         {
 241  0
             result.setExecutor(asyncExecutor);
 242  
         }
 243  
 
 244  0
         result.execute();
 245  0
         return result;
 246  
     }
 247  
 
 248  
     protected UMOMessage doToRemoteComponent(String component,
 249  
                                              Object payload,
 250  
                                              Map messageProperties,
 251  
                                              boolean synchronous) throws UMOException
 252  
     {
 253  0
         UMOMessage message = new MuleMessage(payload, messageProperties);
 254  0
         message.setBooleanProperty(MuleProperties.MULE_REMOTE_SYNC_PROPERTY, synchronous);
 255  0
         setCredentials(message);
 256  0
         AdminNotification action = new AdminNotification(message, AdminNotification.ACTION_INVOKE,
 257  
             "mule://" + component);
 258  0
         UMOMessage result = dispatchAction(action, synchronous, MuleManager.getConfiguration()
 259  
             .getSynchronousEventTimeout());
 260  0
         return result;
 261  
     }
 262  
 
 263  
     protected UMOMessage doToRemote(String endpoint,
 264  
                                     Object payload,
 265  
                                     Map messageProperties,
 266  
                                     boolean synchronous,
 267  
                                     int timeout) throws UMOException
 268  
     {
 269  0
         UMOMessage message = new MuleMessage(payload, messageProperties);
 270  0
         message.setProperty(MuleProperties.MULE_REMOTE_SYNC_PROPERTY, String.valueOf(synchronous));
 271  0
         setCredentials(message);
 272  0
         AdminNotification action = new AdminNotification(message, (synchronous
 273  
                         ? AdminNotification.ACTION_SEND : AdminNotification.ACTION_DISPATCH), endpoint);
 274  
 
 275  0
         UMOMessage result = dispatchAction(action, synchronous, timeout);
 276  0
         return result;
 277  
     }
 278  
 
 279  
     protected UMOMessage dispatchAction(AdminNotification action, boolean synchronous, int timeout)
 280  
         throws UMOException
 281  
     {
 282  
 
 283  0
         UMOEndpoint endpoint = TransportFactory.createEndpoint(serverEndpoint.getEndpointURI(),
 284  
             UMOEndpoint.ENDPOINT_TYPE_SENDER);
 285  0
         endpoint.setRemoteSync(synchronous);
 286  0
         updateContext(new MuleMessage(action), endpoint, synchronous);
 287  
 
 288  0
         ByteArrayOutputStream out = new ByteArrayOutputStream();
 289  0
         wireFormat.write(out, action);
 290  0
         byte[] payload = out.toByteArray();
 291  
 
 292  0
         UMOMessage message = action.getMessage();
 293  
 
 294  0
         if (message == null)
 295  
         {
 296  0
             message = new MuleMessage(payload);
 297  
         }
 298  
         else
 299  
         {
 300  0
             message = new MuleMessage(payload, message);
 301  
         }
 302  
 
 303  0
         message.addProperties(action.getProperties());
 304  0
         MuleSession session = new MuleSession(message,
 305  
             ((AbstractConnector)endpoint.getConnector()).getSessionHandler());
 306  
 
 307  0
         UMOEvent event = new MuleEvent(message, endpoint, session, true);
 308  0
         event.setTimeout(timeout);
 309  0
         if (logger.isDebugEnabled())
 310  
         {
 311  0
             logger.debug("MuleClient sending remote call to: " + action.getResourceIdentifier() + ". At "
 312  
                          + serverEndpoint.toString() + " . Event is: " + event);
 313  
         }
 314  
 
 315  
         UMOMessage result;
 316  
 
 317  
         try
 318  
         {
 319  0
             if (synchronous)
 320  
             {
 321  0
                 result = endpoint.send(event);
 322  
             }
 323  
             else
 324  
             {
 325  0
                 endpoint.dispatch(event);
 326  0
                 return null;
 327  
             }
 328  
 
 329  0
             if (result != null)
 330  
             {
 331  0
                 if (result.getPayload() != null)
 332  
                 {
 333  
                     Object response;
 334  0
                     if (result.getPayload() instanceof InputStream)
 335  
                     {
 336  0
                         response = wireFormat.read((InputStream)result.getPayload());
 337  
                     }
 338  
                     else
 339  
                     {
 340  0
                         ByteArrayInputStream in = new ByteArrayInputStream(result.getPayloadAsBytes());
 341  0
                         response = wireFormat.read(in);
 342  
                     }
 343  
 
 344  0
                     if (response instanceof AdminNotification)
 345  
                     {
 346  0
                         response = ((AdminNotification)response).getMessage();
 347  
                     }
 348  0
                     return (UMOMessage)response;
 349  
                 }
 350  
             }
 351  
         }
 352  0
         catch (Exception e)
 353  
         {
 354  0
             throw new DispatchException(event.getMessage(), event.getEndpoint(), e);
 355  0
         }
 356  
 
 357  0
         if (logger.isDebugEnabled())
 358  
         {
 359  0
             logger.debug("Result of MuleClient remote call is: "
 360  
                          + (result == null ? "null" : result.getPayload()));
 361  
         }
 362  
 
 363  0
         return result;
 364  
     }
 365  
 
 366  
     public void dispose()
 367  
     {
 368  
         // nothing to do here
 369  0
     }
 370  
 
 371  
     protected void setCredentials(UMOMessage message)
 372  
     {
 373  0
         if (credentials != null)
 374  
         {
 375  0
             message.setProperty(MuleProperties.MULE_USER_PROPERTY, MuleCredentials.createHeader(
 376  
                 credentials.getUsername(), credentials.getPassword()));
 377  
         }
 378  0
     }
 379  
 
 380  
     public WireFormat getWireFormat()
 381  
     {
 382  0
         return wireFormat;
 383  
     }
 384  
 
 385  
     public void setWireFormat(WireFormat wireFormat)
 386  
     {
 387  0
         this.wireFormat = wireFormat;
 388  0
     }
 389  
 
 390  
     protected void updateContext(UMOMessage message, UMOEndpoint endpoint, boolean synchronous)
 391  
         throws UMOException
 392  
     {
 393  
 
 394  0
         RequestContext.setEvent(new MuleEvent(message, endpoint, new MuleSession(message,
 395  
             new MuleSessionHandler()), synchronous));
 396  0
     }
 397  
 }