Coverage Report - org.mule.endpoint.DynamicOutboundEndpoint
 
Classes in this File Line Coverage Branch Coverage Complexity
DynamicOutboundEndpoint
0%
0/82
0%
0/16
0
 
 1  
 /*
 2  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 3  
  * The software in this package is published under the terms of the CPAL v1.0
 4  
  * license, a copy of which has been included with this distribution in the
 5  
  * LICENSE.txt file.
 6  
  */
 7  
 package org.mule.endpoint;
 8  
 
 9  
 import org.mule.DefaultMuleEvent;
 10  
 import org.mule.MessageExchangePattern;
 11  
 import org.mule.api.MuleContext;
 12  
 import org.mule.api.MuleEvent;
 13  
 import org.mule.api.MuleException;
 14  
 import org.mule.api.MuleMessage;
 15  
 import org.mule.api.endpoint.EndpointBuilder;
 16  
 import org.mule.api.endpoint.EndpointException;
 17  
 import org.mule.api.endpoint.EndpointMessageProcessorChainFactory;
 18  
 import org.mule.api.endpoint.EndpointURI;
 19  
 import org.mule.api.endpoint.MalformedEndpointException;
 20  
 import org.mule.api.endpoint.OutboundEndpoint;
 21  
 import org.mule.api.expression.ExpressionManager;
 22  
 import org.mule.api.expression.ExpressionRuntimeException;
 23  
 import org.mule.api.lifecycle.InitialisationException;
 24  
 import org.mule.api.processor.MessageProcessor;
 25  
 import org.mule.api.retry.RetryPolicyTemplate;
 26  
 import org.mule.api.routing.filter.Filter;
 27  
 import org.mule.api.security.EndpointSecurityFilter;
 28  
 import org.mule.api.transaction.TransactionConfig;
 29  
 import org.mule.api.transformer.Transformer;
 30  
 import org.mule.api.transport.Connector;
 31  
 import org.mule.api.transport.DispatchException;
 32  
 import org.mule.config.i18n.CoreMessages;
 33  
 import org.mule.transport.AbstractConnector;
 34  
 import org.mule.util.ObjectNameHelper;
 35  
 
 36  
 import java.util.Collections;
 37  
 import java.util.List;
 38  
 import java.util.Map;
 39  
 import java.util.Properties;
 40  
 
 41  
 import org.apache.commons.collections.map.LRUMap;
 42  
 import org.apache.commons.logging.Log;
 43  
 import org.apache.commons.logging.LogFactory;
 44  
 
 45  
 /**
 46  
  * An Outbound endpoint who's URI is a template used to created new non dynamic
 47  
  * endpoints based on the current message.
 48  
  * This allows for the destination of a message to change based on the contents
 49  
  * of the message. Note that this endpoint ONLY substitutes the URI, but other
 50  
  * config elements such as the transformers, filters, etc do not change. You
 51  
  * cannot change an endpoint scheme dynamically so you can't switch between
 52  
  * HTTP and JMS for example using the same dynamic endpoint.
 53  
  */
 54  
 public class DynamicOutboundEndpoint implements OutboundEndpoint
 55  
 {
 56  
 
 57  
     public static final String DYNAMIC_URI_PLACEHOLDER = "dynamic://endpoint";
 58  
 
 59  0
     protected transient final Log logger = LogFactory.getLog(DynamicOutboundEndpoint.class);
 60  
 
 61  
     private static final long serialVersionUID = 8861985949279708638L;
 62  
 
 63  
     /**
 64  
      * The URI template used to construct the actual URI to send the message to.
 65  
      */
 66  
     protected String uriTemplate;
 67  
 
 68  
     private final EndpointBuilder builder;
 69  
 
 70  
     private final OutboundEndpoint prototypeEndpoint;
 71  
 
 72  
     // Caches resolved static endpoints to improve performance
 73  0
     private Map<String, OutboundEndpoint> staticEndpoints = Collections.synchronizedMap(new LRUMap(64));
 74  
 
 75  
     public DynamicOutboundEndpoint(EndpointBuilder builder, String uriTemplate) throws MalformedEndpointException
 76  0
     {
 77  0
         validateUriTemplate(uriTemplate);
 78  
 
 79  0
         this.builder = builder;
 80  0
         this.uriTemplate = uriTemplate;
 81  
 
 82  
         try
 83  
         {
 84  0
             prototypeEndpoint = builder.buildOutboundEndpoint();
 85  
         }
 86  0
         catch (Exception e)
 87  
         {
 88  0
             throw new RuntimeException(e);
 89  0
         }
 90  0
     }
 91  
 
 92  
     protected void validateUriTemplate(String uri) throws MalformedEndpointException
 93  
     {
 94  0
         if (uri.indexOf(":") > uri.indexOf(ExpressionManager.DEFAULT_EXPRESSION_PREFIX))
 95  
         {
 96  0
             throw new MalformedEndpointException(CoreMessages.dynamicEndpointsMustSpecifyAScheme(), uri);
 97  
         }
 98  0
     }
 99  
 
 100  
     protected EndpointURI getEndpointURIForMessage(MuleEvent event) throws DispatchException
 101  
     {
 102  0
         if (logger.isDebugEnabled())
 103  
         {
 104  0
             logger.debug("Uri before parsing is: " + uriTemplate);
 105  
         }
 106  
 
 107  0
         String newUriString = uriTemplate;
 108  
         try
 109  
         {
 110  0
             newUriString = parseURIString(newUriString, event.getMessage());
 111  
         }
 112  0
         catch (final ExpressionRuntimeException e)
 113  
         {
 114  0
             throw new DispatchException(event, this, e);
 115  0
         }
 116  
 
 117  0
         if (logger.isDebugEnabled())
 118  
         {
 119  0
             logger.debug("Uri after parsing is: " + newUriString);
 120  
         }
 121  
 
 122  
         try
 123  
         {
 124  0
             final MuleEndpointURI resultUri = new MuleEndpointURI(newUriString, getMuleContext(), getServiceOverrides());
 125  0
             resultUri.initialise();
 126  
 
 127  0
             return resultUri;
 128  
         }
 129  0
         catch (final Exception e)
 130  
         {
 131  0
             throw new DispatchException(CoreMessages.templateCausedMalformedEndpoint(uriTemplate, newUriString), event, this, e);
 132  
         }
 133  
     }
 134  
 
 135  
     private Properties getServiceOverrides() throws EndpointException
 136  
     {
 137  0
         Properties properties = null;
 138  
 
 139  0
         if (builder instanceof AbstractEndpointBuilder)
 140  
         {
 141  0
             Connector connector = ((AbstractEndpointBuilder) this.builder).getConnector();
 142  
 
 143  0
             if (connector instanceof AbstractConnector && ((AbstractConnector) connector).getServiceOverrides() != null)
 144  
             {
 145  0
                 properties = new Properties();
 146  0
                 properties.putAll(((AbstractConnector) connector).getServiceOverrides());
 147  
             }
 148  
         }
 149  
 
 150  0
         return properties;
 151  
     }
 152  
 
 153  
     protected String parseURIString(String uri, MuleMessage message)
 154  
     {
 155  0
         return this.getMuleContext().getExpressionManager().parse(uri, message, true);
 156  
     }
 157  
 
 158  
     public MuleEvent process(MuleEvent event) throws MuleException
 159  
     {
 160  0
         EndpointURI endpointURIForMessage = getEndpointURIForMessage(event);
 161  0
         OutboundEndpoint outboundEndpoint = getStaticEndpointFor(endpointURIForMessage);
 162  
 
 163  0
         event = new DefaultMuleEvent(event.getMessage(), outboundEndpoint, event, event.getSession());
 164  
 
 165  0
         return outboundEndpoint.process(event);
 166  
     }
 167  
 
 168  
     private OutboundEndpoint getStaticEndpointFor(EndpointURI uri) throws EndpointException, InitialisationException
 169  
     {
 170  0
         OutboundEndpoint outboundEndpoint = staticEndpoints.get(uri.getAddress());
 171  
 
 172  0
         if (outboundEndpoint == null)
 173  
         {
 174  0
             outboundEndpoint = createStaticEndpoint(uri);
 175  0
             staticEndpoints.put(uri.getAddress(), outboundEndpoint);
 176  
         }
 177  
 
 178  0
         return outboundEndpoint;
 179  
     }
 180  
 
 181  
     private OutboundEndpoint createStaticEndpoint(EndpointURI uri) throws EndpointException, InitialisationException
 182  
     {
 183  
         try
 184  
         {
 185  0
             EndpointBuilder staticBuilder = (EndpointBuilder) builder.clone();
 186  0
             staticBuilder.setURIBuilder(new URIBuilder(uri));
 187  0
             String endpointName = ObjectNameHelper.getEndpointNameFor(uri);
 188  0
             staticBuilder.setName(endpointName);
 189  0
             return staticBuilder.buildOutboundEndpoint();
 190  
         }
 191  0
         catch (CloneNotSupportedException e)
 192  
         {
 193  
             // This cannot happen, because we implement Cloneable
 194  0
             throw new IllegalStateException("Unable to clone endpoint builder");
 195  
         }
 196  
     }
 197  
 
 198  
     @Override
 199  
     public boolean equals(Object o)
 200  
     {
 201  0
         return this == o;
 202  
     }
 203  
 
 204  
     @Override
 205  
     public int hashCode()
 206  
     {
 207  0
         return System.identityHashCode(this);
 208  
     }
 209  
 
 210  
     public Connector getConnector()
 211  
     {
 212  0
         throw new UnsupportedOperationException("No connector available");
 213  
     }
 214  
 
 215  
     public EndpointURI getEndpointURI()
 216  
     {
 217  0
         return null;
 218  
     }
 219  
 
 220  
     public String getAddress()
 221  
     {
 222  0
         return uriTemplate;
 223  
     }
 224  
 
 225  
     public RetryPolicyTemplate getRetryPolicyTemplate()
 226  
     {
 227  0
         return prototypeEndpoint.getRetryPolicyTemplate();
 228  
     }
 229  
 
 230  
     public String getEncoding()
 231  
     {
 232  0
         return prototypeEndpoint.getEncoding();
 233  
     }
 234  
 
 235  
     public String getMimeType()
 236  
     {
 237  0
         return prototypeEndpoint.getMimeType();
 238  
     }
 239  
 
 240  
     public Filter getFilter()
 241  
     {
 242  0
         return prototypeEndpoint.getFilter();
 243  
     }
 244  
 
 245  
     public String getInitialState()
 246  
     {
 247  0
         return prototypeEndpoint.getInitialState();
 248  
     }
 249  
 
 250  
     public MuleContext getMuleContext()
 251  
     {
 252  0
         return prototypeEndpoint.getMuleContext();
 253  
     }
 254  
 
 255  
     public String getName()
 256  
     {
 257  0
         return prototypeEndpoint.getName();
 258  
     }
 259  
 
 260  
     public Map getProperties()
 261  
     {
 262  0
         return prototypeEndpoint.getProperties();
 263  
     }
 264  
 
 265  
     public Object getProperty(Object key)
 266  
     {
 267  0
         return prototypeEndpoint.getProperty(key);
 268  
     }
 269  
 
 270  
     public String getProtocol()
 271  
     {
 272  0
         return prototypeEndpoint.getProtocol();
 273  
     }
 274  
 
 275  
     public int getResponseTimeout()
 276  
     {
 277  0
         return prototypeEndpoint.getResponseTimeout();
 278  
     }
 279  
 
 280  
     public List<Transformer> getResponseTransformers()
 281  
     {
 282  0
         return prototypeEndpoint.getResponseTransformers();
 283  
     }
 284  
 
 285  
     public EndpointMessageProcessorChainFactory getMessageProcessorsFactory()
 286  
     {
 287  0
         return prototypeEndpoint.getMessageProcessorsFactory();
 288  
     }
 289  
 
 290  
     public List<MessageProcessor> getMessageProcessors()
 291  
     {
 292  0
         return prototypeEndpoint.getMessageProcessors();
 293  
     }
 294  
 
 295  
     public List<MessageProcessor> getResponseMessageProcessors()
 296  
     {
 297  0
         return prototypeEndpoint.getResponseMessageProcessors();
 298  
     }
 299  
 
 300  
     public EndpointSecurityFilter getSecurityFilter()
 301  
     {
 302  0
         return prototypeEndpoint.getSecurityFilter();
 303  
     }
 304  
 
 305  
     public TransactionConfig getTransactionConfig()
 306  
     {
 307  0
         return prototypeEndpoint.getTransactionConfig();
 308  
     }
 309  
 
 310  
     public List<Transformer> getTransformers()
 311  
     {
 312  0
         return prototypeEndpoint.getTransformers();
 313  
     }
 314  
 
 315  
     public boolean isDeleteUnacceptedMessages()
 316  
     {
 317  0
         return prototypeEndpoint.isDeleteUnacceptedMessages();
 318  
     }
 319  
 
 320  
     public boolean isReadOnly()
 321  
     {
 322  0
         return prototypeEndpoint.isReadOnly();
 323  
     }
 324  
 
 325  
     public MessageExchangePattern getExchangePattern()
 326  
     {
 327  0
         return prototypeEndpoint.getExchangePattern();
 328  
     }
 329  
 
 330  
     public List<String> getResponseProperties()
 331  
     {
 332  0
         return prototypeEndpoint.getResponseProperties();
 333  
     }
 334  
 
 335  
     public String getEndpointBuilderName()
 336  
     {
 337  0
         return prototypeEndpoint.getEndpointBuilderName();
 338  
     }
 339  
 
 340  
     public boolean isProtocolSupported(String protocol)
 341  
     {
 342  0
         return prototypeEndpoint.isProtocolSupported(protocol);
 343  
     }
 344  
 
 345  
     public boolean isDisableTransportTransformer()
 346  
     {
 347  0
         return prototypeEndpoint.isDisableTransportTransformer();
 348  
     }
 349  
 }