View Javadoc
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.MessageExchangePattern;
10  import org.mule.api.MuleContext;
11  import org.mule.api.MuleException;
12  import org.mule.api.MuleMessage;
13  import org.mule.api.construct.FlowConstruct;
14  import org.mule.api.construct.FlowConstructAware;
15  import org.mule.api.context.MuleContextAware;
16  import org.mule.api.endpoint.EndpointMessageProcessorChainFactory;
17  import org.mule.api.endpoint.EndpointURI;
18  import org.mule.api.endpoint.InboundEndpoint;
19  import org.mule.api.lifecycle.Initialisable;
20  import org.mule.api.lifecycle.LifecycleException;
21  import org.mule.api.lifecycle.Startable;
22  import org.mule.api.lifecycle.Stoppable;
23  import org.mule.api.processor.MessageProcessor;
24  import org.mule.api.retry.RetryPolicyTemplate;
25  import org.mule.api.transaction.TransactionConfig;
26  import org.mule.api.transport.Connector;
27  import org.mule.config.MuleManifest;
28  import org.mule.config.i18n.CoreMessages;
29  import org.mule.transport.ConnectException;
30  import org.mule.transport.polling.MessageProcessorPollingMessageReceiver;
31  
32  import java.beans.ExceptionListener;
33  import java.util.List;
34  import java.util.Map;
35  
36  public class DefaultInboundEndpoint extends AbstractEndpoint implements InboundEndpoint
37  {
38      private static final long serialVersionUID = -4752772777414636142L;
39      private MessageProcessor listener;
40      private FlowConstruct flowConstruct;
41      private ExceptionListener exceptionListener;
42  
43      public DefaultInboundEndpoint(Connector connector,
44                                    EndpointURI endpointUri,
45                                    String name,
46                                    Map properties,
47                                    TransactionConfig transactionConfig,
48                                    boolean deleteUnacceptedMessage,
49                                    MessageExchangePattern messageExchangePattern,
50                                    int responseTimeout,
51                                    String initialState,
52                                    String endpointEncoding,
53                                    String endpointBuilderName,
54                                    MuleContext muleContext,
55                                    RetryPolicyTemplate retryPolicyTemplate,
56                                    EndpointMessageProcessorChainFactory messageProcessorsFactory,
57                                    List <MessageProcessor> messageProcessors,
58                                    List <MessageProcessor> responseMessageProcessors,
59                                    boolean disableTransportTransformer,
60                                    String mimeType)
61      {
62          super(connector, endpointUri, name, properties, 
63              transactionConfig, deleteUnacceptedMessage,
64              messageExchangePattern, responseTimeout, initialState, endpointEncoding, 
65              endpointBuilderName, muleContext, retryPolicyTemplate,  messageProcessorsFactory, 
66              messageProcessors, responseMessageProcessors, disableTransportTransformer,
67              mimeType);
68      }
69  
70      public MuleMessage request(long timeout) throws Exception
71      {
72          if (getConnector() != null)
73          {
74              return getConnector().request(this, timeout);
75          }
76          else
77          {
78              // TODO Either remove because this should never happen or i18n the
79              // message
80              throw new IllegalStateException("The connector on the endpoint: " + toString()
81                                              + " is null. Please contact " + MuleManifest.getDevListEmail());
82          }
83      }
84  
85      public void setListener(MessageProcessor listener)
86      {
87          this.listener = listener;
88      }
89  
90      public void start() throws MuleException
91      {
92          try
93          {
94              if (getMessageProcessorChain(flowConstruct) instanceof Startable)
95              {
96                  ((Startable) getMessageProcessorChain(flowConstruct)).start();
97              }
98              getConnector().registerListener(this, getMessageProcessorChain(flowConstruct), flowConstruct);
99              MessageProcessor polledMp = getPolledMessageProcessor();
100             if (polledMp instanceof Startable)
101             {
102                  ((Startable)polledMp).start();
103             }
104         }
105         // Let connection exceptions bubble up to trigger the reconnection strategy.
106         catch (ConnectException ce)
107         {
108             throw ce;
109         }
110         catch (Exception e)
111         {
112             throw new LifecycleException(CoreMessages.failedToStartInboundEndpoint(this), e, this);
113         }
114     }
115 
116     public void stop() throws MuleException
117     {
118         try
119         {
120             getConnector().unregisterListener(this, flowConstruct);
121             if (getMessageProcessorChain(flowConstruct) instanceof Stoppable)
122             {
123                 ((Stoppable) getMessageProcessorChain(flowConstruct)).stop();
124             }
125             MessageProcessor polledMp = getPolledMessageProcessor();
126             if (polledMp instanceof Stoppable)
127             {
128                 ((Stoppable)polledMp).stop();
129             }
130         }
131         catch (Exception e)
132         {
133             throw new LifecycleException(CoreMessages.failedToStopInboundEndpoint(this), e, this);
134         }
135     }
136 
137     @Override
138     public MessageProcessor createMessageProcessorChain(FlowConstruct flowContruct) throws MuleException
139     {
140         EndpointMessageProcessorChainFactory factory = getMessageProcessorsFactory();
141         MessageProcessor processorChain = factory.createInboundMessageProcessorChain(this, flowConstruct,
142             listener);
143         if (processorChain instanceof MuleContextAware)
144         {
145             ((MuleContextAware) processorChain).setMuleContext(getMuleContext());
146         }
147         if (processorChain instanceof FlowConstructAware)
148         {
149             ((FlowConstructAware) processorChain).setFlowConstruct(flowContruct);
150         }
151         if (processorChain instanceof Initialisable)
152         {
153             ((Initialisable) processorChain).initialise();
154         }
155         MessageProcessor polledMp = getPolledMessageProcessor();
156         if (polledMp instanceof MuleContextAware)
157         {
158             ((MuleContextAware) polledMp).setMuleContext(getMuleContext());
159         }
160         if (polledMp instanceof FlowConstructAware)
161         {
162             ((FlowConstructAware) polledMp).setFlowConstruct(flowContruct);
163         }
164         if (polledMp instanceof Initialisable)
165         {
166             ((Initialisable) polledMp).initialise();
167         }
168         return processorChain;
169     }
170 
171     protected MessageProcessor getPolledMessageProcessor()
172     {
173         return (MessageProcessor) getProperty(MessageProcessorPollingMessageReceiver.SOURCE_MESSAGE_PROCESSOR_PROPERTY_NAME);
174     }
175 
176     public void setFlowConstruct(FlowConstruct flowConstruct)
177     {
178         this.flowConstruct = flowConstruct;
179     }
180 
181     public ExceptionListener getExceptionListener()
182     {
183         return exceptionListener;
184     }
185 
186     public void setExceptionListener(ExceptionListener exceptionListener)
187     {
188         this.exceptionListener = exceptionListener;
189     }
190 
191     @Override
192     public void dispose()
193     {
194         super.dispose();
195         this.flowConstruct = null;
196         this.listener = null;
197     }
198     
199     @Override
200     public int hashCode()
201     {
202         // We need unique hashcode for each inbound endpoint instance because flowConstuct and listener are not
203         // injected until after endpoint has been created and cached and the key used for caching is hashcode.
204         // If we don't do this then endpoints which are configured identically but used with different
205         // services get mixed up after deserialization of events
206         return System.identityHashCode(this);
207     }
208 }