1
2
3
4
5
6
7
8
9
10
11 package org.mule.impl.internal.admin;
12
13 import org.mule.MuleException;
14 import org.mule.MuleManager;
15 import org.mule.config.MuleProperties;
16 import org.mule.config.i18n.CoreMessages;
17 import org.mule.impl.MuleDescriptor;
18 import org.mule.impl.MuleEvent;
19 import org.mule.impl.MuleMessage;
20 import org.mule.impl.MuleSession;
21 import org.mule.impl.RequestContext;
22 import org.mule.impl.endpoint.MuleEndpoint;
23 import org.mule.impl.endpoint.MuleEndpointURI;
24 import org.mule.impl.internal.notifications.AdminNotification;
25 import org.mule.impl.message.ExceptionPayload;
26 import org.mule.impl.model.ModelHelper;
27 import org.mule.providers.AbstractConnector;
28 import org.mule.providers.NullPayload;
29 import org.mule.transformers.wire.WireFormat;
30 import org.mule.umo.UMODescriptor;
31 import org.mule.umo.UMOEvent;
32 import org.mule.umo.UMOEventContext;
33 import org.mule.umo.UMOException;
34 import org.mule.umo.UMOMessage;
35 import org.mule.umo.UMOSession;
36 import org.mule.umo.endpoint.UMOEndpoint;
37 import org.mule.umo.endpoint.UMOEndpointURI;
38 import org.mule.umo.lifecycle.Callable;
39 import org.mule.umo.lifecycle.Initialisable;
40 import org.mule.umo.lifecycle.InitialisationException;
41 import org.mule.umo.provider.UMOConnector;
42 import org.mule.umo.transformer.UMOTransformer;
43
44 import java.io.ByteArrayInputStream;
45 import java.util.HashMap;
46 import java.util.Map;
47
48 import org.apache.commons.collections.MapUtils;
49 import org.apache.commons.io.output.ByteArrayOutputStream;
50 import org.apache.commons.logging.Log;
51 import org.apache.commons.logging.LogFactory;
52
53
54
55
56
57
58
59
60 public class MuleManagerComponent implements Callable, Initialisable
61 {
62
63
64
65 protected static final Log logger = LogFactory.getLog(MuleManagerComponent.class);
66
67 public static final String MANAGER_COMPONENT_NAME = "_muleManagerComponent";
68 public static final String MANAGER_ENDPOINT_NAME = "_muleManagerEndpoint";
69
70
71
72
73 protected WireFormat wireFormat;
74
75 public void initialise() throws InitialisationException
76 {
77 if (wireFormat == null)
78 {
79 throw new InitialisationException(CoreMessages.objectIsNull("wireFormat"), this);
80 }
81 }
82
83 public Object onCall(UMOEventContext context) throws Exception
84 {
85 Object result;
86 logger.debug("Message received by MuleManagerComponent");
87 ByteArrayInputStream in = new ByteArrayInputStream(context.getTransformedMessageAsBytes());
88 AdminNotification action = (AdminNotification) wireFormat.read(in);
89 if (AdminNotification.ACTION_INVOKE == action.getAction())
90 {
91 result = invokeAction(action, context);
92 }
93 else if (AdminNotification.ACTION_SEND == action.getAction() ||
94 AdminNotification.ACTION_DISPATCH == action.getAction())
95 {
96 result = sendAction(action, context);
97 }
98 else if (AdminNotification.ACTION_RECEIVE == action.getAction())
99 {
100 result = receiveAction(action, context);
101 }
102 else
103 {
104 result = handleException(null, new MuleException(
105 CoreMessages.eventTypeNotRecognised("AdminNotification:" + action.getAction())));
106 }
107 return result;
108 }
109
110 protected Object invokeAction(AdminNotification action, UMOEventContext context) throws UMOException
111 {
112 String destComponent = null;
113 UMOMessage result = null;
114 String endpoint = action.getResourceIdentifier();
115 if (action.getResourceIdentifier().startsWith("mule:"))
116 {
117 destComponent = endpoint.substring(endpoint.lastIndexOf("/") + 1);
118 }
119 else
120 {
121 destComponent = endpoint;
122 }
123
124 if (destComponent != null)
125 {
126 UMOSession session = new MuleSession(ModelHelper.getComponent(destComponent));
127
128
129
130
131 UMOEndpoint ep = new MuleEndpoint(RequestContext.getEvent().getEndpoint());
132 ep.setTransformer(null);
133 UMOEvent event = new MuleEvent(action.getMessage(), ep, context.getSession(),
134 context.isSynchronous());
135 event = RequestContext.setEvent(event);
136
137 if (context.isSynchronous())
138 {
139 result = session.getComponent().sendEvent(event);
140 ByteArrayOutputStream out = new ByteArrayOutputStream();
141 wireFormat.write(out, result);
142 return out.toByteArray();
143 }
144 else
145 {
146 session.getComponent().dispatchEvent(event);
147 return null;
148 }
149 }
150 else
151 {
152 return handleException(result, new MuleException(
153 CoreMessages.couldNotDetermineDestinationComponentFromEndpoint(endpoint)));
154 }
155 }
156
157 protected Object sendAction(AdminNotification action, UMOEventContext context) throws UMOException
158 {
159 UMOMessage result = null;
160 try
161 {
162 UMOEndpoint endpoint = new MuleEndpoint(action.getResourceIdentifier(), false);
163
164 if (AdminNotification.ACTION_DISPATCH == action.getAction())
165 {
166 context.dispatchEvent(action.getMessage(), endpoint);
167 return null;
168 }
169 else
170 {
171 endpoint.setRemoteSync(true);
172 result = context.sendEvent(action.getMessage(), endpoint);
173 if (result == null)
174 {
175 return null;
176 }
177 else
178 {
179 ByteArrayOutputStream out = new ByteArrayOutputStream();
180 wireFormat.write(out, result);
181 return out.toByteArray();
182 }
183 }
184 }
185 catch (Exception e)
186 {
187 return handleException(result, e);
188 }
189 }
190
191 protected Object receiveAction(AdminNotification action, UMOEventContext context) throws UMOException
192 {
193 UMOMessage result = null;
194 try
195 {
196 UMOEndpointURI endpointUri = new MuleEndpointURI(action.getResourceIdentifier());
197 UMOEndpoint endpoint = MuleEndpoint.getOrCreateEndpointForUri(endpointUri,
198 UMOEndpoint.ENDPOINT_TYPE_SENDER);
199
200 long timeout = MapUtils.getLongValue(action.getProperties(),
201 MuleProperties.MULE_EVENT_TIMEOUT_PROPERTY, MuleManager.getConfiguration()
202 .getSynchronousEventTimeout());
203
204 UMOEndpointURI ep = new MuleEndpointURI(action.getResourceIdentifier());
205 result = endpoint.getConnector().receive(ep, timeout);
206 if (result != null)
207 {
208
209 UMOTransformer trans = ((AbstractConnector) endpoint.getConnector()).getDefaultInboundTransformer();
210 if (trans != null)
211 {
212 Object payload = trans.transform(result.getPayload());
213 result = new MuleMessage(payload, result);
214 }
215 ByteArrayOutputStream out = new ByteArrayOutputStream();
216 wireFormat.write(out, result);
217 return out.toByteArray();
218 }
219 else
220 {
221 return null;
222 }
223 }
224 catch (Exception e)
225 {
226 return handleException(result, e);
227 }
228
229 }
230
231 public static final UMODescriptor getDescriptor(UMOConnector connector,
232 UMOEndpointURI endpointUri,
233 WireFormat wireFormat) throws UMOException
234 {
235 UMOEndpoint endpoint = new MuleEndpoint();
236 endpoint.setConnector(connector);
237 endpoint.setEndpointURI(endpointUri);
238 endpoint.setName(MANAGER_ENDPOINT_NAME);
239 endpoint.setType(UMOEndpoint.ENDPOINT_TYPE_RECEIVER);
240
241 MuleDescriptor descriptor = new MuleDescriptor();
242 descriptor.setName(MANAGER_COMPONENT_NAME);
243 descriptor.setInboundEndpoint(endpoint);
244 descriptor.setImplementation(MuleManagerComponent.class.getName());
245 descriptor.setContainerManaged(false);
246 Map props = new HashMap();
247 props.put("wireFormat", wireFormat);
248 descriptor.setProperties(props);
249 return descriptor;
250 }
251
252
253
254
255
256
257
258
259
260
261 protected String handleException(UMOMessage result, Throwable e)
262 {
263 logger.error("Failed to process admin request: " + e.getMessage(), e);
264 if (result == null)
265 {
266 result = new MuleMessage(NullPayload.getInstance(), (Map) null);
267 }
268 result.setExceptionPayload(new ExceptionPayload(e));
269 try
270 {
271 ByteArrayOutputStream out = new ByteArrayOutputStream();
272 wireFormat.write(out, result);
273 return out.toString(MuleManager.getConfiguration().getEncoding());
274 }
275 catch (Exception e1)
276 {
277
278 logger.error("Failed to format message, using direct string (details at debug level): " + e1.getMessage());
279 logger.debug(e1.toString(), e1);
280 return e.getMessage();
281 }
282 }
283
284 public WireFormat getWireFormat()
285 {
286 return wireFormat;
287 }
288
289 public void setWireFormat(WireFormat wireFormat)
290 {
291 this.wireFormat = wireFormat;
292 }
293 }