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