Coverage Report - org.mule.endpoint.AbstractEndpoint
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractEndpoint
0%
0/102
0%
0/86
0
 
 1  
 /*
 2  
  * $Id: AbstractEndpoint.java 20781 2010-12-16 13:19:09Z dfeist $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.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.endpoint;
 12  
 
 13  
 import org.mule.MessageExchangePattern;
 14  
 import org.mule.api.MuleContext;
 15  
 import org.mule.api.MuleException;
 16  
 import org.mule.api.construct.FlowConstruct;
 17  
 import org.mule.api.endpoint.EndpointMessageProcessorChainFactory;
 18  
 import org.mule.api.endpoint.EndpointURI;
 19  
 import org.mule.api.endpoint.ImmutableEndpoint;
 20  
 import org.mule.api.lifecycle.Disposable;
 21  
 import org.mule.api.processor.MessageProcessor;
 22  
 import org.mule.api.processor.MessageProcessorChain;
 23  
 import org.mule.api.retry.RetryPolicyTemplate;
 24  
 import org.mule.api.routing.filter.Filter;
 25  
 import org.mule.api.security.EndpointSecurityFilter;
 26  
 import org.mule.api.transaction.TransactionConfig;
 27  
 import org.mule.api.transformer.Transformer;
 28  
 import org.mule.api.transport.Connector;
 29  
 import org.mule.processor.SecurityFilterMessageProcessor;
 30  
 import org.mule.routing.MessageFilter;
 31  
 import org.mule.util.ClassUtils;
 32  
 
 33  
 import java.net.URI;
 34  
 import java.util.HashMap;
 35  
 import java.util.LinkedList;
 36  
 import java.util.List;
 37  
 import java.util.Map;
 38  
 import java.util.regex.Matcher;
 39  
 import java.util.regex.Pattern;
 40  
 
 41  
 import edu.emory.mathcs.backport.java.util.Collections;
 42  
 
 43  
 import org.apache.commons.logging.Log;
 44  
 import org.apache.commons.logging.LogFactory;
 45  
 
 46  
 /**
 47  
  * <code>ImmutableMuleEndpoint</code> describes a Provider in the Mule Server. A
 48  
  * endpoint is a grouping of an endpoint, an endpointUri and a transformer.
 49  
  */
 50  
 public abstract class AbstractEndpoint implements ImmutableEndpoint, Disposable
 51  
 {
 52  
 
 53  
     private static final long serialVersionUID = -1650380871293160973L;
 54  
 
 55  
     public static final String PROPERTY_PROCESS_SYNCHRONOUSLY = "processSynchronously";
 56  
 
 57  
     /**
 58  
      * logger used by this class
 59  
      */
 60  0
     protected static final Log logger = LogFactory.getLog(AbstractEndpoint.class);
 61  
 
 62  
     /**
 63  
      * The endpoint used to communicate with the external system
 64  
      */
 65  
     private final Connector connector;
 66  
 
 67  
     /**
 68  
      * The endpointUri on which to send or receive information
 69  
      */
 70  
     private final EndpointURI endpointUri;
 71  
 
 72  
     private final EndpointMessageProcessorChainFactory messageProcessorsFactory;
 73  
 
 74  
     private final List <MessageProcessor> messageProcessors;
 75  
 
 76  
     private final List <MessageProcessor> responseMessageProcessors;
 77  
     
 78  
     private MessageProcessor messageProcessorChain;
 79  
 
 80  
     /**
 81  
      * The name for the endpoint
 82  
      */
 83  
     private final String name;
 84  
 
 85  
     /**
 86  
      * Any additional properties for the endpoint
 87  
      * // TODO This should be final. See MULE-3105
 88  
      * // TODO Shouldn't this be guarded from concurrent writes?
 89  
      */
 90  0
     private Map properties = new HashMap();
 91  
 
 92  
     /**
 93  
      * The transaction configuration for this endpoint
 94  
      */
 95  
     private final TransactionConfig transactionConfig;
 96  
 
 97  
     /**
 98  
      * determines whether unaccepted filtered events should be removed from the
 99  
      * source. If they are not removed its up to the Message receiver to handle
 100  
      * recieving the same message again
 101  
      */
 102  
     private final boolean deleteUnacceptedMessages;
 103  
 
 104  
     private final MessageExchangePattern messageExchangePattern;
 105  
     
 106  
     /**
 107  
      * How long to block when performing a remote synchronisation to a remote host.
 108  
      * This property is optional and will be set to the default Synchonous MuleEvent
 109  
      * time out value if not set
 110  
      */
 111  
     private final int responseTimeout;
 112  
 
 113  
     /**
 114  
      * The state that the endpoint is initialised in such as started or stopped
 115  
      */
 116  
     private final String initialState;
 117  
 
 118  
     private final String endpointEncoding;
 119  
 
 120  
     private MuleContext muleContext;
 121  
 
 122  
     protected RetryPolicyTemplate retryPolicyTemplate;
 123  
 
 124  
     private String endpointBuilderName;
 125  
 
 126  
     private final String endpointMimeType;
 127  
 
 128  0
     private boolean disableTransportTransformer = false;
 129  
 
 130  
     public AbstractEndpoint(Connector connector,
 131  
                             EndpointURI endpointUri,
 132  
                             String name,
 133  
                             Map properties,
 134  
                             TransactionConfig transactionConfig,
 135  
                             boolean deleteUnacceptedMessages,
 136  
                             MessageExchangePattern messageExchangePattern,
 137  
                             int responseTimeout,
 138  
                             String initialState,
 139  
                             String endpointEncoding,
 140  
                             String endpointBuilderName,
 141  
                             MuleContext muleContext,
 142  
                             RetryPolicyTemplate retryPolicyTemplate,
 143  
                             EndpointMessageProcessorChainFactory messageProcessorsFactory,
 144  
                             List <MessageProcessor> messageProcessors,
 145  
                             List <MessageProcessor> responseMessageProcessors,
 146  
                             boolean disableTransportTransformer,
 147  
                             String endpointMimeType)
 148  0
     {
 149  0
         this.connector = connector;
 150  0
         this.endpointUri = endpointUri;
 151  0
         this.name = name;
 152  
         // TODO Properties should be immutable. See MULE-3105
 153  
         // this.properties = Collections.unmodifiableMap(properties);
 154  0
         this.properties.putAll(properties);
 155  0
         this.transactionConfig = transactionConfig;
 156  0
         this.deleteUnacceptedMessages = deleteUnacceptedMessages;
 157  
 
 158  0
         this.responseTimeout = responseTimeout;
 159  0
         this.initialState = initialState;
 160  0
         this.endpointEncoding = endpointEncoding;
 161  0
         this.endpointBuilderName = endpointBuilderName;
 162  0
         this.muleContext = muleContext;
 163  0
         this.retryPolicyTemplate = retryPolicyTemplate;
 164  0
         this.endpointMimeType = endpointMimeType;
 165  0
         this.disableTransportTransformer = disableTransportTransformer;
 166  
 
 167  0
         if (transactionConfig != null && transactionConfig.getFactory() != null &&
 168  
             transactionConfig.getAction() != TransactionConfig.ACTION_NONE &&
 169  
             transactionConfig.getAction() != TransactionConfig.ACTION_NEVER)
 170  
         {
 171  0
             if (logger.isDebugEnabled())
 172  
             {
 173  0
                 logger.debug("Endpoint has a transaction configuration. Defaulting to REQUEST_RESPONSE. Endpoint is: " + toString());
 174  
             }
 175  0
             this.messageExchangePattern = MessageExchangePattern.REQUEST_RESPONSE;
 176  
         }
 177  
         else
 178  
         {
 179  0
             this.messageExchangePattern = messageExchangePattern;
 180  
         }
 181  
 
 182  0
         this.messageProcessorsFactory = messageProcessorsFactory;
 183  0
         if (messageProcessors == null)
 184  
         {
 185  0
             this.messageProcessors = Collections.emptyList();
 186  
         }
 187  
         else
 188  
         {
 189  0
             this.messageProcessors = messageProcessors;
 190  
         }
 191  0
         if (responseMessageProcessors == null)
 192  
         {
 193  0
             this.responseMessageProcessors = Collections.emptyList();
 194  
         }
 195  
         else
 196  
         {
 197  0
             this.responseMessageProcessors = responseMessageProcessors;
 198  
         }
 199  0
     }
 200  
 
 201  
     public EndpointURI getEndpointURI()
 202  
     {
 203  0
         return endpointUri;
 204  
     }
 205  
 
 206  
     public String getAddress()
 207  
     {
 208  0
         EndpointURI uri = getEndpointURI();
 209  0
         if (uri != null)
 210  
         {
 211  0
             return uri.getUri().toString();
 212  
         }
 213  
         else
 214  
         {
 215  0
             return null;
 216  
         }
 217  
     }
 218  
 
 219  
     public String getEncoding()
 220  
     {
 221  0
         return endpointEncoding;
 222  
     }
 223  
 
 224  
     public String getMimeType()
 225  
     {
 226  0
         return endpointMimeType;
 227  
     }
 228  
 
 229  
     public Connector getConnector()
 230  
     {
 231  0
         return connector;
 232  
     }
 233  
 
 234  
     public String getName()
 235  
     {
 236  0
         return name;
 237  
     }
 238  
 
 239  
     public EndpointMessageProcessorChainFactory getMessageProcessorsFactory()
 240  
     {
 241  0
         return messageProcessorsFactory;
 242  
     }
 243  
 
 244  
     public List <MessageProcessor> getMessageProcessors()
 245  
     {
 246  0
         return messageProcessors;
 247  
     }
 248  
 
 249  
     public List <MessageProcessor> getResponseMessageProcessors()
 250  
     {
 251  0
         return responseMessageProcessors;
 252  
     }
 253  
 
 254  
     /** @deprecated use getMessageProcessors() */
 255  
     public List<Transformer> getTransformers()
 256  
     {
 257  0
         return getTransformersFromProcessorList(messageProcessors);
 258  
     }
 259  
 
 260  
     public Map getProperties()
 261  
     {
 262  0
         return properties;
 263  
     }
 264  
 
 265  
     public boolean isReadOnly()
 266  
     {
 267  0
         return true;
 268  
     }
 269  
 
 270  
     @Override
 271  
     public String toString()
 272  
     {
 273  
         // Use the interface to retrieve the string and set
 274  
         // the endpoint uri to a default value
 275  0
         String sanitizedEndPointUri = null;
 276  0
         URI uri = null;
 277  0
         if (endpointUri != null)
 278  
         {
 279  0
             sanitizedEndPointUri = endpointUri.toString();
 280  0
             uri = endpointUri.getUri();
 281  
         }
 282  
         // The following will further sanitize the endpointuri by removing
 283  
         // the embedded password. This will only remove the password if the
 284  
         // uri contains all the necessary information to successfully rebuild the url
 285  0
         if (uri != null && (uri.getRawUserInfo() != null) && (uri.getScheme() != null) && (uri.getHost() != null)
 286  
                 && (uri.getRawPath() != null))
 287  
         {
 288  
             // build a pattern up that matches what we need tp strip out the password
 289  0
             Pattern sanitizerPattern = Pattern.compile("(.*):.*");
 290  0
             Matcher sanitizerMatcher = sanitizerPattern.matcher(uri.getRawUserInfo());
 291  0
             if (sanitizerMatcher.matches())
 292  
             {
 293  0
                 sanitizedEndPointUri = new StringBuffer(uri.getScheme()).append("://")
 294  
                         .append(sanitizerMatcher.group(1))
 295  
                         .append(":<password>")
 296  
                         .append("@")
 297  
                         .append(uri.getHost())
 298  
                         .append(uri.getRawPath())
 299  
                         .toString();
 300  
             }
 301  0
             if (uri.getRawQuery() != null)
 302  
             {
 303  0
                 sanitizedEndPointUri = sanitizedEndPointUri + "?" + uri.getRawQuery();
 304  
             }
 305  
 
 306  
         }
 307  
 
 308  0
         return ClassUtils.getClassName(getClass()) + "{endpointUri=" + sanitizedEndPointUri + ", connector="
 309  
                 + connector + ",  name='" + name + "', mep=" + messageExchangePattern + ", properties=" + properties
 310  
                 + ", transactionConfig=" + transactionConfig + ", deleteUnacceptedMessages=" + deleteUnacceptedMessages
 311  
                 + ", initialState=" + initialState + ", responseTimeout="
 312  
                 + responseTimeout + ", endpointEncoding=" + endpointEncoding + ", disableTransportTransformer="
 313  
                 + disableTransportTransformer + "}";
 314  
     }
 315  
 
 316  
     public String getProtocol()
 317  
     {
 318  0
         return connector.getProtocol();
 319  
     }
 320  
 
 321  
     public TransactionConfig getTransactionConfig()
 322  
     {
 323  0
         return transactionConfig;
 324  
     }
 325  
 
 326  
     protected static boolean equal(Object a, Object b)
 327  
     {
 328  0
         return ClassUtils.equal(a, b);
 329  
     }
 330  
 
 331  
     @Override
 332  
     public boolean equals(Object obj)
 333  
     {
 334  0
         if (this == obj)
 335  
         {
 336  0
             return true;
 337  
         }
 338  0
         if (obj == null || getClass() != obj.getClass())
 339  
         {
 340  0
             return false;
 341  
         }
 342  
 
 343  0
         final AbstractEndpoint other = (AbstractEndpoint) obj;
 344  0
         return equal(retryPolicyTemplate, other.retryPolicyTemplate)
 345  
                 && equal(connector, other.connector)
 346  
                 && deleteUnacceptedMessages == other.deleteUnacceptedMessages
 347  
                 && equal(endpointEncoding, other.endpointEncoding)
 348  
                 && equal(endpointUri, other.endpointUri)
 349  
                 && equal(initialState, other.initialState)
 350  
                 // don't include lifecycle state as lifecycle code includes hashing
 351  
                 // && equal(initialised, other.initialised)
 352  
                 && equal(messageExchangePattern, other.messageExchangePattern)
 353  
                 && equal(name, other.name) 
 354  
                 && equal(properties, other.properties)
 355  
                 && responseTimeout == other.responseTimeout
 356  
                 && equal(messageProcessors, other.messageProcessors)
 357  
                 && equal(responseMessageProcessors, other.responseMessageProcessors)
 358  
                 && equal(transactionConfig, other.transactionConfig)
 359  
                 && disableTransportTransformer == other.disableTransportTransformer;
 360  
     }
 361  
 
 362  
     @Override
 363  
     public int hashCode()
 364  
     {
 365  0
         return ClassUtils.hash(new Object[]{this.getClass(), retryPolicyTemplate, connector,
 366  
                 deleteUnacceptedMessages ? Boolean.TRUE : Boolean.FALSE,
 367  
                 endpointEncoding,
 368  
                 endpointUri,
 369  
                 initialState,
 370  
                 // don't include lifecycle state as lifecycle code includes hashing
 371  
                 // initialised,
 372  
                 messageExchangePattern,
 373  
                 name,
 374  
                 properties, 
 375  
                 Integer.valueOf(responseTimeout),
 376  
                 responseMessageProcessors,
 377  
                 transactionConfig,
 378  
                 messageProcessors,
 379  
                 disableTransportTransformer ? Boolean.TRUE : Boolean.FALSE});
 380  
     }
 381  
 
 382  
     public Filter getFilter()
 383  
     {
 384  
         // Call the first MessageFilter in the chain "the filter".
 385  0
         for (MessageProcessor mp : messageProcessors)
 386  
         {
 387  0
             if (mp instanceof MessageFilter)
 388  
             {
 389  0
                 return ((MessageFilter) mp).getFilter();
 390  
             }
 391  
         }
 392  0
         return null;
 393  
     }
 394  
 
 395  
     public boolean isDeleteUnacceptedMessages()
 396  
     {
 397  0
         return deleteUnacceptedMessages;
 398  
     }
 399  
 
 400  
     /**
 401  
      * Returns an EndpointSecurityFilter for this endpoint. If one is not set, there
 402  
      * will be no authentication on events sent via this endpoint
 403  
      *
 404  
      * @return EndpointSecurityFilter responsible for authenticating message flow via
 405  
      *         this endpoint.
 406  
      * @see org.mule.api.security.EndpointSecurityFilter
 407  
      */
 408  
     public EndpointSecurityFilter getSecurityFilter()
 409  
     {
 410  0
         for (MessageProcessor mp : messageProcessors)
 411  
         {
 412  0
             if (mp instanceof SecurityFilterMessageProcessor)
 413  
             {
 414  0
                 return ((SecurityFilterMessageProcessor)mp).getFilter();
 415  
             }
 416  
         }
 417  
 
 418  0
         return null;
 419  
     }
 420  
 
 421  
     public MessageExchangePattern getExchangePattern()
 422  
     {
 423  0
         return messageExchangePattern;
 424  
     }
 425  
 
 426  
     /**
 427  
      * The timeout value for remoteSync invocations
 428  
      *
 429  
      * @return the timeout in milliseconds
 430  
      */
 431  
     public int getResponseTimeout()
 432  
     {
 433  0
         return responseTimeout;
 434  
     }
 435  
 
 436  
     /**
 437  
      * Sets the state the endpoint will be loaded in. The States are 'stopped' and
 438  
      * 'started' (default)
 439  
      *
 440  
      * @return the endpoint starting state
 441  
      */
 442  
     public String getInitialState()
 443  
     {
 444  0
         return initialState;
 445  
     }
 446  
 
 447  
     /** @deprecated use getResponseMessageProcessors() */
 448  
     public List<Transformer> getResponseTransformers()
 449  
     {
 450  0
         return getTransformersFromProcessorList(responseMessageProcessors);
 451  
     }
 452  
 
 453  
     private List<Transformer> getTransformersFromProcessorList(List<MessageProcessor> processors)
 454  
     {
 455  0
         List<Transformer> transformers = new LinkedList<Transformer>();
 456  0
         for (MessageProcessor processor : processors)
 457  
         {
 458  0
             if (processor instanceof Transformer)
 459  
             {
 460  0
                 transformers.add((Transformer) processor);
 461  
             }
 462  0
             else if (processor instanceof MessageProcessorChain)
 463  
             {
 464  0
                 transformers.addAll(getTransformersFromProcessorList(((MessageProcessorChain) processor).getMessageProcessors()));
 465  
             }
 466  
         }
 467  0
         return transformers;
 468  
     }
 469  
 
 470  
     public Object getProperty(Object key)
 471  
     {
 472  0
         return properties.get(key);
 473  
     }
 474  
 
 475  
     public MuleContext getMuleContext()
 476  
     {
 477  0
         return muleContext;
 478  
     }
 479  
 
 480  
     public RetryPolicyTemplate getRetryPolicyTemplate()
 481  
     {
 482  0
         return retryPolicyTemplate;
 483  
     }
 484  
 
 485  
     public String getEndpointBuilderName()
 486  
     {
 487  0
         return endpointBuilderName;
 488  
     }
 489  
 
 490  
     public boolean isProtocolSupported(String protocol)
 491  
     {
 492  0
         return connector.supportsProtocol(protocol);
 493  
     }
 494  
     
 495  
     public boolean isDisableTransportTransformer() 
 496  
     {
 497  0
         return disableTransportTransformer;
 498  
     }
 499  
 
 500  
     public void dispose()
 501  
     {
 502  0
         this.muleContext = null;
 503  0
         this.messageProcessors.clear();
 504  0
         this.messageProcessorChain = null;
 505  0
     }
 506  
 
 507  
     public MessageProcessor getMessageProcessorChain(FlowConstruct flowContruct) throws MuleException
 508  
     {
 509  0
         if (messageProcessorChain == null)
 510  
         {
 511  0
             messageProcessorChain = createMessageProcessorChain(flowContruct);
 512  
         }
 513  0
         return messageProcessorChain;
 514  
     }
 515  
 
 516  
     abstract protected MessageProcessor createMessageProcessorChain(FlowConstruct flowContruct) throws MuleException;
 517  
 }