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