Coverage Report - org.mule.endpoint.AbstractEndpoint
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractEndpoint
78%
56/72
19%
13/68
1.462
 
 1  
 /*
 2  
  * $Id: AbstractEndpoint.java 11319 2008-03-12 00:54:21Z aperepel $
 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.endpoint;
 12  
 
 13  
 import org.mule.api.MuleContext;
 14  
 import org.mule.api.endpoint.EndpointURI;
 15  
 import org.mule.api.endpoint.ImmutableEndpoint;
 16  
 import org.mule.api.routing.filter.Filter;
 17  
 import org.mule.api.security.EndpointSecurityFilter;
 18  
 import org.mule.api.transaction.TransactionConfig;
 19  
 import org.mule.api.transformer.Transformer;
 20  
 import org.mule.api.transport.ConnectionStrategy;
 21  
 import org.mule.api.transport.Connector;
 22  
 import org.mule.util.ClassUtils;
 23  
 
 24  
 import java.net.URI;
 25  
 import java.util.HashMap;
 26  
 import java.util.Iterator;
 27  
 import java.util.List;
 28  
 import java.util.Map;
 29  
 import java.util.regex.Matcher;
 30  
 import java.util.regex.Pattern;
 31  
 
 32  
 import edu.emory.mathcs.backport.java.util.Collections;
 33  
 import org.apache.commons.logging.Log;
 34  
 import org.apache.commons.logging.LogFactory;
 35  
 
 36  
 /**
 37  
  * <code>ImmutableMuleEndpoint</code> describes a Provider in the Mule Server. A
 38  
  * endpoint is a grouping of an endpoint, an endpointUri and a transformer.
 39  
  */
 40  
 public abstract class AbstractEndpoint implements ImmutableEndpoint
 41  
 {
 42  
 
 43  
     private static final long serialVersionUID = -1650380871293160973L;
 44  
 
 45  
     /**
 46  
      * logger used by this class
 47  
      */
 48  2
     protected static final Log logger = LogFactory.getLog(AbstractEndpoint.class);
 49  
 
 50  
     /**
 51  
      * The endpoint used to communicate with the external system
 52  
      */
 53  
     private final Connector connector;
 54  
 
 55  
     /**
 56  
      * The endpointUri on which to send or receive information
 57  
      */
 58  
     private final EndpointURI endpointUri;
 59  
 
 60  
     /**
 61  
      * The transformers used to transform the incoming or outgoing data
 62  
      */
 63  
     private final List transformers;
 64  
 
 65  
     /**
 66  
      * The transformers used to transform the incoming or outgoing data
 67  
      */
 68  
     private final List responseTransformers;
 69  
 
 70  
     /**
 71  
      * The name for the endpoint
 72  
      */
 73  
     private final String name;
 74  
 
 75  
     /**
 76  
      * Any additional properties for the endpoint 
 77  
      * // TODO This should be final. See MULE-3105
 78  
      * // TODO Shouldn't this be guarded from concurrent writes?
 79  
      */
 80  486
     private Map properties = new HashMap();
 81  
 
 82  
     /**
 83  
      * The transaction configuration for this endpoint
 84  
      */
 85  
     private final TransactionConfig transactionConfig;
 86  
 
 87  
     /**
 88  
      * event filter for this endpoint
 89  
      */
 90  
     private final Filter filter;
 91  
 
 92  
     /**
 93  
      * determines whether unaccepted filtered events should be removed from the
 94  
      * source. If they are not removed its up to the Message receiver to handle
 95  
      * recieving the same message again
 96  
      */
 97  
     private final boolean deleteUnacceptedMessages;
 98  
 
 99  
     /**
 100  
      * The security filter to apply to this endpoint
 101  
      */
 102  
     private final EndpointSecurityFilter securityFilter;
 103  
 
 104  
     /**
 105  
      * whether events received by this endpoint should execute in a single thread
 106  
      */
 107  
     private final boolean synchronous;
 108  
 
 109  
     /**
 110  
      * Determines whether a synchronous call should block to obtain a response from a
 111  
      * remote server (if the transport supports it). For example for Jms endpoints,
 112  
      * setting remote sync will cause a temporary destination to be set up as a
 113  
      * replyTo destination and will send the message a wait for a response on the
 114  
      * replyTo destination. If the JMSReplyTo is already set on the message that
 115  
      * destination will be used instead.
 116  
      */
 117  
     private final boolean remoteSync;
 118  
 
 119  
     /**
 120  
      * How long to block when performing a remote synchronisation to a remote host.
 121  
      * This property is optional and will be set to the default Synchonous MuleEvent
 122  
      * time out value if not set
 123  
      */
 124  
     private final int remoteSyncTimeout;
 125  
 
 126  
     /**
 127  
      * The state that the endpoint is initialised in such as started or stopped
 128  
      */
 129  
     private final String initialState;
 130  
 
 131  
     private final String endpointEncoding;
 132  
 
 133  
     private final MuleContext muleContext;
 134  
 
 135  
     private final ConnectionStrategy connectionStrategy;
 136  
 
 137  
     public AbstractEndpoint(Connector connector,
 138  
                             EndpointURI endpointUri,
 139  
                             List transformers,
 140  
                             List responseTransformers,
 141  
                             String name,
 142  
                             Map properties,
 143  
                             TransactionConfig transactionConfig,
 144  
                             Filter filter,
 145  
                             boolean deleteUnacceptedMessages,
 146  
                             EndpointSecurityFilter securityFilter,
 147  
                             boolean synchronous,
 148  
                             boolean remoteSync,
 149  
                             int remoteSyncTimeout,
 150  
                             String initialState,
 151  
                             String endpointEncoding,
 152  
                             MuleContext muleContext,
 153  
                             ConnectionStrategy connectionStrategy)
 154  486
     {
 155  486
         this.connector = connector;
 156  486
         this.endpointUri = endpointUri;
 157  486
         if (transformers == null)
 158  
         {
 159  0
             this.transformers = Collections.unmodifiableList(java.util.Collections.EMPTY_LIST);
 160  
         }
 161  
         else
 162  
         {
 163  486
             updateTransformerEndpoints(transformers);
 164  486
             this.transformers = Collections.unmodifiableList(transformers);
 165  
         }
 166  486
         if (responseTransformers == null)
 167  
         {
 168  0
             this.responseTransformers = Collections.unmodifiableList(java.util.Collections.EMPTY_LIST);
 169  
         }
 170  
         else
 171  
         {
 172  486
             updateTransformerEndpoints(responseTransformers);
 173  486
             this.responseTransformers = Collections.unmodifiableList(responseTransformers);
 174  
         }
 175  486
         this.name = name;
 176  
         // TODO Properties should be immutable. See MULE-3105
 177  
         // this.properties = Collections.unmodifiableMap(properties);
 178  486
         this.properties.putAll(properties);
 179  486
         this.transactionConfig = transactionConfig;
 180  486
         this.filter = filter;
 181  486
         this.deleteUnacceptedMessages = deleteUnacceptedMessages;
 182  486
         this.securityFilter = securityFilter;
 183  486
         if (this.securityFilter != null)
 184  
         {
 185  0
             this.securityFilter.setEndpoint(this);
 186  
         }
 187  486
         this.synchronous = synchronous;
 188  486
         this.remoteSync = remoteSync;
 189  486
         this.remoteSyncTimeout = remoteSyncTimeout;
 190  486
         this.initialState = initialState;
 191  486
         this.endpointEncoding = endpointEncoding;
 192  486
         this.muleContext = muleContext;
 193  486
         this.connectionStrategy = connectionStrategy;
 194  486
     }
 195  
 
 196  
     public EndpointURI getEndpointURI()
 197  
     {
 198  1648
         return endpointUri;
 199  
     }
 200  
 
 201  
     public String getEncoding()
 202  
     {
 203  4
         return endpointEncoding;
 204  
     }
 205  
 
 206  
     public Connector getConnector()
 207  
     {
 208  92
         return connector;
 209  
     }
 210  
 
 211  
     public String getName()
 212  
     {
 213  38
         return name;
 214  
     }
 215  
 
 216  
     public List getTransformers()
 217  
     {
 218  116
         return transformers;
 219  
     }
 220  
 
 221  
     public Map getProperties()
 222  
     {
 223  1240
         return properties;
 224  
     }
 225  
 
 226  
     public boolean isReadOnly()
 227  
     {
 228  0
         return true;
 229  
     }
 230  
 
 231  
     public String toString()
 232  
     {
 233  
         // Use the interface to retrieve the string and set
 234  
         // the endpoint uri to a default value
 235  976
         String sanitizedEndPointUri = null;
 236  976
         URI uri = null;
 237  976
         if (endpointUri != null)
 238  
         {
 239  976
             sanitizedEndPointUri = endpointUri.toString();
 240  976
             uri = endpointUri.getUri();
 241  
         }
 242  
         // The following will further sanitize the endpointuri by removing
 243  
         // the embedded password. This will only remove the password if the
 244  
         // uri contains all the necessary information to successfully rebuild the url
 245  976
         if (uri != null && (uri.getRawUserInfo() != null) && (uri.getScheme() != null) && (uri.getHost() != null)
 246  
             && (uri.getRawPath() != null))
 247  
         {
 248  
             // build a pattern up that matches what we need tp strip out the password
 249  0
             Pattern sanitizerPattern = Pattern.compile("(.*):.*");
 250  0
             Matcher sanitizerMatcher = sanitizerPattern.matcher(uri.getRawUserInfo());
 251  0
             if (sanitizerMatcher.matches())
 252  
             {
 253  0
                 sanitizedEndPointUri = new StringBuffer(uri.getScheme()).append("://")
 254  
                     .append(sanitizerMatcher.group(1))
 255  
                     .append(":<password>")
 256  
                     .append("@")
 257  
                     .append(uri.getHost())
 258  
                     .append(uri.getRawPath())
 259  
                     .toString();
 260  
             }
 261  0
             if (uri.getRawQuery() != null)
 262  
             {
 263  0
                 sanitizedEndPointUri = sanitizedEndPointUri + "?" + uri.getRawQuery();
 264  
             }
 265  
 
 266  
         }
 267  
 
 268  976
         return ClassUtils.getClassName(getClass()) + "{endpointUri=" + sanitizedEndPointUri + ", connector="
 269  
                + connector + ", transformer=" + transformers + ", name='" + name + "'" + ", properties=" + properties
 270  
                + ", transactionConfig=" + transactionConfig + ", filter=" + filter + ", deleteUnacceptedMessages="
 271  
                + deleteUnacceptedMessages + ", securityFilter=" + securityFilter + ", synchronous=" + synchronous
 272  
                + ", initialState=" + initialState + ", remoteSync=" + remoteSync + ", remoteSyncTimeout="
 273  
                + remoteSyncTimeout + ", endpointEncoding=" + endpointEncoding + "}";
 274  
     }
 275  
 
 276  
     public String getProtocol()
 277  
     {
 278  0
         return connector.getProtocol();
 279  
     }
 280  
 
 281  
     public TransactionConfig getTransactionConfig()
 282  
     {
 283  114
         return transactionConfig;
 284  
     }
 285  
 
 286  
     protected static boolean equal(Object a, Object b)
 287  
     {
 288  0
         return ClassUtils.equal(a, b);
 289  
     }
 290  
 
 291  
     public boolean equals(Object obj)
 292  
     {
 293  94
         if (this == obj) return true;
 294  0
         if (obj == null || getClass() != obj.getClass()) return false;
 295  
 
 296  0
         final AbstractEndpoint other = (AbstractEndpoint) obj;
 297  0
         return equal(connectionStrategy, other.connectionStrategy)
 298  
                && equal(connector, other.connector)
 299  
                && deleteUnacceptedMessages == other.deleteUnacceptedMessages
 300  
                && equal(endpointEncoding, other.endpointEncoding)
 301  
                && equal(endpointUri, other.endpointUri)
 302  
                && equal(filter, other.filter)
 303  
                && equal(initialState, other.initialState)
 304  
                // don't include lifecycle state as lifecycle code includes hashing
 305  
                // && equal(initialised, other.initialised)
 306  
                && equal(name, other.name) && equal(properties, other.properties) && remoteSync == other.remoteSync
 307  
                && remoteSyncTimeout == other.remoteSyncTimeout
 308  
                && equal(responseTransformers, other.responseTransformers)
 309  
                && equal(securityFilter, other.securityFilter) && synchronous == other.synchronous
 310  
                && equal(transactionConfig, other.transactionConfig) && equal(transformers, other.transformers);
 311  
     }
 312  
 
 313  
     public int hashCode()
 314  
     {
 315  980
         return ClassUtils.hash(new Object[]{this.getClass(), connectionStrategy, connector,
 316  
             deleteUnacceptedMessages ? Boolean.TRUE : Boolean.FALSE,
 317  
             endpointEncoding,
 318  
             endpointUri,
 319  
             filter,
 320  
             initialState,
 321  
             // don't include lifecycle state as lifecycle code includes hashing
 322  
             // initialised,
 323  
             name, properties, remoteSync ? Boolean.TRUE : Boolean.FALSE, new Integer(remoteSyncTimeout),
 324  
             responseTransformers, securityFilter, synchronous ? Boolean.TRUE : Boolean.FALSE, transactionConfig,
 325  
             transformers});
 326  
     }
 327  
 
 328  
     public Filter getFilter()
 329  
     {
 330  66
         return filter;
 331  
     }
 332  
 
 333  
     public boolean isDeleteUnacceptedMessages()
 334  
     {
 335  4
         return deleteUnacceptedMessages;
 336  
     }
 337  
 
 338  
     // TODO - remove (or fix)
 339  
     protected void updateTransformerEndpoints(List transformers)
 340  
     {
 341  972
         Iterator transformer = transformers.iterator();
 342  1528
         while (transformer.hasNext())
 343  
         {
 344  556
             ((Transformer) transformer.next()).setEndpoint(this);
 345  
         }
 346  972
     }
 347  
 
 348  
     /**
 349  
      * Returns an EndpointSecurityFilter for this endpoint. If one is not set, there
 350  
      * will be no authentication on events sent via this endpoint
 351  
      * 
 352  
      * @return EndpointSecurityFilter responsible for authenticating message flow via
 353  
      *         this endpoint.
 354  
      * @see org.mule.api.security.EndpointSecurityFilter
 355  
      */
 356  
     public EndpointSecurityFilter getSecurityFilter()
 357  
     {
 358  12
         return securityFilter;
 359  
     }
 360  
 
 361  
     /**
 362  
      * Determines if requests originating from this endpoint should be synchronous
 363  
      * i.e. execute in a single thread and possibly return an result. This property
 364  
      * is only used when the endpoint is of type 'receiver'
 365  
      * 
 366  
      * @return whether requests on this endpoint should execute in a single thread.
 367  
      *         This property is only used when the endpoint is of type 'receiver'
 368  
      */
 369  
     public boolean isSynchronous()
 370  
     {
 371  10
         return synchronous;
 372  
     }
 373  
 
 374  
     /**
 375  
      * For certain providers that support the notion of a backchannel such as sockets
 376  
      * (outputStream) or Jms (ReplyTo) Mule can automatically wait for a response
 377  
      * from a backchannel when dispatching over these protocols. This is different
 378  
      * for synchronous as synchronous behavior only applies to in
 379  
      * 
 380  
      * @return
 381  
      */
 382  
     public boolean isRemoteSync()
 383  
     {
 384  12
         return remoteSync;
 385  
     }
 386  
 
 387  
     /**
 388  
      * The timeout value for remoteSync invocations
 389  
      * 
 390  
      * @return the timeout in milliseconds
 391  
      */
 392  
     public int getRemoteSyncTimeout()
 393  
     {
 394  290
         return remoteSyncTimeout;
 395  
     }
 396  
 
 397  
     /**
 398  
      * Sets the state the endpoint will be loaded in. The States are 'stopped' and
 399  
      * 'started' (default)
 400  
      * 
 401  
      * @return the endpoint starting state
 402  
      */
 403  
     public String getInitialState()
 404  
     {
 405  12
         return initialState;
 406  
     }
 407  
 
 408  
     public List getResponseTransformers()
 409  
     {
 410  8
         return responseTransformers;
 411  
     }
 412  
 
 413  
     public Object getProperty(Object key)
 414  
     {
 415  0
         return properties.get(key);
 416  
     }
 417  
 
 418  
     public MuleContext getMuleContext()
 419  
     {
 420  2
         return muleContext;
 421  
     }
 422  
 
 423  
     /**
 424  
      * Getter for property 'connectionStrategy'.
 425  
      * 
 426  
      * @return Value for property 'connectionStrategy'.
 427  
      */
 428  
     public ConnectionStrategy getConnectionStrategy()
 429  
     {
 430  14
         return connectionStrategy;
 431  
     }
 432  
 
 433  
 }