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