View Javadoc

1   /*
2    * $Id: DynamicOutboundEndpoint.java 22826 2011-09-02 07:30:19Z 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.DefaultMuleEvent;
14  import org.mule.MessageExchangePattern;
15  import org.mule.api.MuleContext;
16  import org.mule.api.MuleEvent;
17  import org.mule.api.MuleException;
18  import org.mule.api.MuleMessage;
19  import org.mule.api.endpoint.EndpointBuilder;
20  import org.mule.api.endpoint.EndpointException;
21  import org.mule.api.endpoint.EndpointMessageProcessorChainFactory;
22  import org.mule.api.endpoint.EndpointURI;
23  import org.mule.api.endpoint.MalformedEndpointException;
24  import org.mule.api.endpoint.OutboundEndpoint;
25  import org.mule.api.expression.ExpressionManager;
26  import org.mule.api.expression.ExpressionRuntimeException;
27  import org.mule.api.lifecycle.InitialisationException;
28  import org.mule.api.processor.MessageProcessor;
29  import org.mule.api.retry.RetryPolicyTemplate;
30  import org.mule.api.routing.filter.Filter;
31  import org.mule.api.security.EndpointSecurityFilter;
32  import org.mule.api.transaction.TransactionConfig;
33  import org.mule.api.transformer.Transformer;
34  import org.mule.api.transport.Connector;
35  import org.mule.api.transport.DispatchException;
36  import org.mule.config.i18n.CoreMessages;
37  
38  import java.util.List;
39  import java.util.Map;
40  
41  import org.apache.commons.logging.Log;
42  import org.apache.commons.logging.LogFactory;
43  import org.mule.processor.AbstractRedeliveryPolicy;
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      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      public DynamicOutboundEndpoint(EndpointBuilder builder, String uriTemplate) throws MalformedEndpointException
73      {
74          validateUriTemplate(uriTemplate);
75  
76          this.builder = builder;
77          this.uriTemplate = uriTemplate;
78  
79          try
80          {
81              prototypeEndpoint = builder.buildOutboundEndpoint();
82          }
83          catch (Exception e)
84          {
85              throw new RuntimeException(e);
86          }
87      }
88  
89      protected void validateUriTemplate(String uri) throws MalformedEndpointException
90      {
91          if (uri.indexOf(":") > uri.indexOf(ExpressionManager.DEFAULT_EXPRESSION_PREFIX))
92          {
93              throw new MalformedEndpointException(CoreMessages.dynamicEndpointsMustSpecifyAScheme(), uri);
94          }
95      }
96  
97      protected EndpointURI getEndpointURIForMessage(MuleEvent event) throws DispatchException
98      {
99          if (logger.isDebugEnabled())
100         {
101             logger.debug("Uri before parsing is: " + uriTemplate);
102         }
103 
104         String newUriString = uriTemplate;
105         try
106         {
107             newUriString = parseURIString(newUriString, event.getMessage());
108         }
109         catch (final ExpressionRuntimeException e)
110         {
111             throw new DispatchException(event, this, e);
112         }
113 
114         if (logger.isDebugEnabled())
115         {
116             logger.debug("Uri after parsing is: " + newUriString);
117         }
118 
119         try
120         {
121             final MuleEndpointURI resultUri = new MuleEndpointURI(newUriString, getMuleContext());
122             resultUri.initialise();
123 
124             return resultUri;
125         }
126         catch (final Exception e)
127         {
128             throw new DispatchException(CoreMessages.templateCausedMalformedEndpoint(uriTemplate, newUriString), event, this, e);
129         }
130     }
131 
132     protected String parseURIString(String uri, MuleMessage message)
133     {
134         return this.getMuleContext().getExpressionManager().parse(uri, message, true);
135     }
136 
137     public MuleEvent process(MuleEvent event) throws MuleException
138     {
139         EndpointURI endpointURIForMessage = getEndpointURIForMessage(event);
140         OutboundEndpoint outboundEndpoint = createStaticEndpoint(endpointURIForMessage);
141 
142         event = new DefaultMuleEvent(event.getMessage(), endpointURIForMessage.getUri(), event.getExchangePattern(), event.getSession());
143 
144         return outboundEndpoint.process(event);
145     }
146 
147     private synchronized OutboundEndpoint createStaticEndpoint(EndpointURI uri) throws DispatchException, EndpointException, InitialisationException
148     {
149         builder.setURIBuilder(new URIBuilder(uri));
150 
151         return builder.buildOutboundEndpoint();
152     }
153 
154     @Override
155     public boolean equals(Object o)
156     {
157         return this == o;
158     }
159 
160     @Override
161     public int hashCode()
162     {
163         return System.identityHashCode(this);
164     }
165 
166     public Connector getConnector()
167     {
168         throw new UnsupportedOperationException("No connector available");
169     }
170 
171     public EndpointURI getEndpointURI()
172     {
173         return null;
174     }
175 
176     @Override
177     public AbstractRedeliveryPolicy getRedeliveryPolicy()
178     {
179         return prototypeEndpoint.getRedeliveryPolicy();
180     }
181 
182     public String getAddress()
183     {
184         return uriTemplate;
185     }
186 
187     public RetryPolicyTemplate getRetryPolicyTemplate()
188     {
189         return prototypeEndpoint.getRetryPolicyTemplate();
190     }
191 
192 
193     public String getEncoding()
194     {
195         return prototypeEndpoint.getEncoding();
196     }
197 
198     public String getMimeType()
199     {
200         return prototypeEndpoint.getMimeType();
201     }
202 
203     public Filter getFilter()
204     {
205         return prototypeEndpoint.getFilter();
206     }
207 
208     public String getInitialState()
209     {
210         return prototypeEndpoint.getInitialState();
211     }
212 
213     public MuleContext getMuleContext()
214     {
215         return prototypeEndpoint.getMuleContext();
216     }
217 
218     public String getName()
219     {
220         return prototypeEndpoint.getName();
221     }
222 
223     public Map getProperties()
224     {
225         return prototypeEndpoint.getProperties();
226     }
227 
228     public Object getProperty(Object key)
229     {
230         return prototypeEndpoint.getProperty(key);
231     }
232 
233     public String getProtocol()
234     {
235         return prototypeEndpoint.getProtocol();
236     }
237 
238     public int getResponseTimeout()
239     {
240         return prototypeEndpoint.getResponseTimeout();
241     }
242 
243     public List<Transformer> getResponseTransformers()
244     {
245         return prototypeEndpoint.getResponseTransformers();
246     }
247 
248     public EndpointMessageProcessorChainFactory getMessageProcessorsFactory()
249     {
250         return prototypeEndpoint.getMessageProcessorsFactory();
251     }
252 
253     public List<MessageProcessor> getMessageProcessors()
254     {
255         return prototypeEndpoint.getMessageProcessors();
256     }
257 
258     public List<MessageProcessor> getResponseMessageProcessors()
259     {
260         return prototypeEndpoint.getResponseMessageProcessors();
261     }
262 
263     public EndpointSecurityFilter getSecurityFilter()
264     {
265         return prototypeEndpoint.getSecurityFilter();
266     }
267 
268     public TransactionConfig getTransactionConfig()
269     {
270         return prototypeEndpoint.getTransactionConfig();
271     }
272 
273     public List<Transformer> getTransformers()
274     {
275         return prototypeEndpoint.getTransformers();
276     }
277 
278     public boolean isDeleteUnacceptedMessages()
279     {
280         return prototypeEndpoint.isDeleteUnacceptedMessages();
281     }
282 
283     public boolean isReadOnly()
284     {
285         return prototypeEndpoint.isReadOnly();
286     }
287 
288     public MessageExchangePattern getExchangePattern()
289     {
290         return prototypeEndpoint.getExchangePattern();
291     }
292 
293     public List<String> getResponseProperties()
294     {
295         return prototypeEndpoint.getResponseProperties();
296     }
297 
298     public String getEndpointBuilderName()
299     {
300         return prototypeEndpoint.getEndpointBuilderName();
301     }
302 
303     public boolean isProtocolSupported(String protocol)
304     {
305         return prototypeEndpoint.isProtocolSupported(protocol);
306     }
307 
308     public boolean isDisableTransportTransformer()
309     {
310         return prototypeEndpoint.isDisableTransportTransformer();
311     }
312 }