View Javadoc

1   /*
2    * $Id: ProcessMessageReceiver.java 19710 2010-09-23 16:29:07Z 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.bpm;
12  
13  import org.mule.DefaultMuleEvent;
14  import org.mule.MessageExchangePattern;
15  import org.mule.RequestContext;
16  import org.mule.api.MuleEvent;
17  import org.mule.api.MuleException;
18  import org.mule.api.MuleMessage;
19  import org.mule.api.construct.FlowConstruct;
20  import org.mule.api.context.WorkManager;
21  import org.mule.api.endpoint.EndpointBuilder;
22  import org.mule.api.endpoint.InboundEndpoint;
23  import org.mule.api.endpoint.OutboundEndpoint;
24  import org.mule.api.lifecycle.CreateException;
25  import org.mule.api.transport.Connector;
26  import org.mule.api.transport.ConnectorException;
27  import org.mule.api.transport.PropertyScope;
28  import org.mule.config.i18n.MessageFactory;
29  import org.mule.module.bpm.Process;
30  import org.mule.session.DefaultMuleSession;
31  import org.mule.transport.AbstractMessageReceiver;
32  
33  import java.util.Map;
34  
35  import javax.resource.spi.work.Work;
36  import javax.resource.spi.work.WorkException;
37  
38  /** 
39   * Generates an incoming Mule event from an executing workflow process. 
40   * 
41   * @deprecated It is recommended to configure BPM as a component rather than a transport for 3.x
42   */
43  public class ProcessMessageReceiver extends AbstractMessageReceiver
44  {
45  
46      private ProcessConnector connector = null;
47  
48      public ProcessMessageReceiver(Connector connector, FlowConstruct flowConstruct, InboundEndpoint endpoint)
49              throws CreateException
50      {
51          super(connector, flowConstruct, endpoint);
52          this.connector = (ProcessConnector) connector;
53      }
54  
55      public MuleMessage generateSynchronousEvent(String endpoint, Object payload, Map messageProperties) throws MuleException
56      {
57          logger.debug("Executing process is sending an event (synchronously) to Mule endpoint = " + endpoint);
58          MuleMessage response = generateEvent(endpoint, payload, messageProperties, 
59              MessageExchangePattern.REQUEST_RESPONSE);
60          if (logger.isDebugEnabled())
61          {
62              logger.debug("Synchronous response is " + (response != null ? response.getPayload() : null));
63          }
64          return response;
65      }
66  
67      public void generateAsynchronousEvent(String endpoint, Object payload, Map messageProperties) throws MuleException, WorkException
68      {
69          logger.debug("Executing process is dispatching an event (asynchronously) to Mule endpoint = " + endpoint);
70          WorkManager workManager = getWorkManager();
71          if (workManager != null)
72          {
73              workManager.scheduleWork(new Worker(endpoint, payload, messageProperties));
74          }
75          else
76          {
77              throw new ConnectorException(MessageFactory.createStaticMessage("WorkManager not available"), getConnector());
78          }
79      }
80  
81      protected MuleMessage generateEvent(String endpoint, Object payload, Map messageProperties, MessageExchangePattern exchangePattern) throws MuleException
82      {
83          MuleMessage message;
84          if (payload instanceof MuleMessage)
85          {
86              message = (MuleMessage) payload;
87          }
88          else
89          {
90              message = createMuleMessage(payload, this.endpoint.getEncoding());
91          }
92          message.addProperties(messageProperties, PropertyScope.INBOUND);
93          message.addProperties(messageProperties, PropertyScope.INVOCATION);
94  
95          //TODO should probably cache this
96          EndpointBuilder endpointBuilder = connector.getMuleContext().getRegistry().lookupEndpointFactory().getEndpointBuilder(endpoint);
97          endpointBuilder.setExchangePattern(exchangePattern);
98          OutboundEndpoint ep = endpointBuilder.buildOutboundEndpoint();
99         
100         DefaultMuleEvent event = new DefaultMuleEvent(message, ep, new DefaultMuleSession(flowConstruct, connector.getMuleContext()));
101 
102         // Set correlation properties in SESSION scope so that they get propagated to response messages.
103         RequestContext.setEvent(event);
104         if (messageProperties.get(Process.PROPERTY_PROCESS_TYPE) != null)
105         {
106             event.getMessage().setSessionProperty(Process.PROPERTY_PROCESS_TYPE, messageProperties.get(Process.PROPERTY_PROCESS_TYPE));
107         }
108         if (messageProperties.get(Process.PROPERTY_PROCESS_ID) != null)
109         {
110             event.getMessage().setSessionProperty(Process.PROPERTY_PROCESS_ID, messageProperties.get(Process.PROPERTY_PROCESS_ID));
111         }
112         
113         MuleEvent resultEvent = ep.process(event);
114         
115         MuleMessage response = null;
116         if (resultEvent != null)
117         {
118             response = resultEvent.getMessage();
119             if (response.getExceptionPayload() != null)
120             {
121                 throw new ConnectorException(MessageFactory.createStaticMessage("Unable to send or route message"), getConnector(), response.getExceptionPayload().getRootException());
122             }
123         }
124         
125         return response;
126     }
127 
128     private class Worker implements Work
129     {
130         private String endpoint;
131         private Object payload;
132         private Map messageProperties;
133 
134         public Worker(String endpoint, Object payload, Map messageProperties)
135         {
136             this.endpoint = endpoint;
137             this.payload = payload;
138             this.messageProperties = messageProperties;
139         }
140 
141         public void run()
142         {
143             try
144             {
145                 generateEvent(endpoint, payload, messageProperties, MessageExchangePattern.ONE_WAY);
146             }
147             catch (Exception e)
148             {
149                 getConnector().getMuleContext().getExceptionListener().handleException(e);
150             }
151         }
152 
153         public void release()
154         { /*nop*/ }
155     }
156 }