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.transport;
8   
9   import org.mule.api.MuleException;
10  import org.mule.api.MuleMessage;
11  import org.mule.api.context.WorkManager;
12  import org.mule.api.endpoint.InboundEndpoint;
13  import org.mule.api.lifecycle.InitialisationException;
14  import org.mule.api.transformer.Transformer;
15  import org.mule.api.transport.MessageRequester;
16  import org.mule.api.transport.ReceiveException;
17  import org.mule.context.notification.EndpointMessageNotification;
18  
19  import java.util.List;
20  
21  /**
22   * The Message Requester is used to explicitly request messages from a message channel or
23   * resource rather than subscribing to inbound events or polling for messages.
24   * This is often used programatically but will not be used for inbound endpoints
25   * configured on services.
26   */
27  public abstract class AbstractMessageRequester extends AbstractTransportMessageHandler implements MessageRequester
28  {
29      private List<Transformer> defaultInboundTransformers;
30  
31      public AbstractMessageRequester(InboundEndpoint endpoint)
32      {
33          super(endpoint);
34      }
35  
36      @Override
37      protected ConnectableLifecycleManager createLifecycleManager()
38      {
39          return new ConnectableLifecycleManager<MessageRequester>(getRequesterName(), this);
40      }
41  
42      /**
43       * Method used to perform any initialisation work. If a fatal error occurs during
44       * initialisation an <code>InitialisationException</code> should be thrown,
45       * causing the Mule instance to shutdown. If the error is recoverable, say by
46       * retrying to connect, a <code>RecoverableException</code> should be thrown.
47       * There is no guarantee that by throwing a Recoverable exception that the Mule
48       * instance will not shut down.
49       * 
50       * @throws org.mule.api.lifecycle.InitialisationException if a fatal error occurs
51       *             causing the Mule instance to shutdown
52       * @throws org.mule.api.lifecycle.RecoverableException if an error occurs that
53       *             can be recovered from
54       */
55      @Override
56      public final void initialise() throws InitialisationException
57      {
58          defaultInboundTransformers = connector.getDefaultInboundTransformers(endpoint);               
59          super.initialise();
60      }
61  
62      protected String getRequesterName()
63      {
64          return getConnector().getName() + ".requester." + System.identityHashCode(this);
65      }
66  
67      /**
68       * Make a specific request to the underlying transport
69       *
70       * @param timeout the maximum time the operation should block before returning.
71       *            The call should return immediately if there is data available. If
72       *            no data becomes available before the timeout elapses, null will be
73       *            returned
74       * @return the result of the request wrapped in a MuleMessage object. Null will be
75       *         returned if no data was available
76       * @throws Exception if the call to the underlying protocol causes an exception
77       */
78      public final MuleMessage request(long timeout) throws Exception
79      {
80          try
81          {
82              // Make sure we are connected
83              connect();
84              MuleMessage result = null;
85              result = doRequest(timeout);
86              if (result != null && !endpoint.isDisableTransportTransformer())
87              {
88                  applyInboundTransformers(result);
89              }
90  
91              if (result != null && connector.isEnableMessageEvents())
92              {
93                  connector.fireNotification(new EndpointMessageNotification(result, endpoint, null,
94                      EndpointMessageNotification.MESSAGE_REQUESTED));
95              }
96              return result;
97          }
98          catch (ReceiveException e)
99          {
100             disposeAndLogException();
101             throw e;
102         }
103         catch (Exception e)
104         {
105             disposeAndLogException();
106             throw new ReceiveException(endpoint, timeout, e);
107         }
108     }
109 
110     protected void applyInboundTransformers(MuleMessage message) throws MuleException
111     {
112         message.applyTransformers(null, defaultInboundTransformers);
113     }
114 
115     @Override
116     protected WorkManager getWorkManager() throws MuleException
117     {
118         return connector.getRequesterWorkManager();
119     }
120     
121     public InboundEndpoint getEndpoint()
122     {
123         return (InboundEndpoint) super.getEndpoint();
124     }
125     
126     /**
127      * Make a specific request to the underlying transport
128      *
129      * @param timeout the maximum time the operation should block before returning.
130      *            The call should return immediately if there is data available. If
131      *            no data becomes available before the timeout elapses, null will be
132      *            returned
133      * @return the result of the request wrapped in a MuleMessage object. Null will be
134      *         returned if no data was avaialable
135      * @throws Exception if the call to the underlying protocal cuases an exception
136      */
137     protected abstract MuleMessage doRequest(long timeout) throws Exception;
138 
139 }