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.module.jca;
8   
9   import org.mule.DefaultMuleEvent;
10  import org.mule.DefaultMuleMessage;
11  import org.mule.MessageExchangePattern;
12  import org.mule.api.MuleContext;
13  import org.mule.api.MuleEvent;
14  import org.mule.api.MuleException;
15  import org.mule.api.MuleMessage;
16  import org.mule.api.MuleSession;
17  import org.mule.api.config.MuleProperties;
18  import org.mule.api.endpoint.EndpointBuilder;
19  import org.mule.api.endpoint.InboundEndpoint;
20  import org.mule.api.endpoint.OutboundEndpoint;
21  import org.mule.api.transport.DispatchException;
22  import org.mule.api.transport.ReceiveException;
23  import org.mule.module.client.i18n.ClientMessages;
24  import org.mule.module.jca.i18n.JcaMessages;
25  import org.mule.security.MuleCredentials;
26  import org.mule.session.DefaultMuleSession;
27  import org.mule.transport.AbstractConnector;
28  
29  import java.util.Map;
30  
31  import javax.resource.ResourceException;
32  
33  /**
34   * <code>MuleConnection</code> TODO
35   */
36  public class DefaultMuleConnection implements MuleConnection
37  {
38      private final MuleCredentials credentials;
39      private final MuleContext muleContext;
40      private MuleManagedConnection managedConnection;
41  
42      public DefaultMuleConnection(MuleManagedConnection managedConnection,
43                                   MuleContext muleContext,
44                                   MuleCredentials credentials)
45      {
46          this.muleContext = muleContext;
47          this.credentials = credentials;
48          this.managedConnection = managedConnection;
49      }
50  
51      /**
52       * Dispatches an event asynchronously to a endpointUri via a mule server. the Url
53       * determines where to dispathc the event to, this can be in the form of
54       *
55       * @param url the Mule url used to determine the destination and transport of the
56       *            message
57       * @param payload the object that is the payload of the event
58       * @param messageProperties any properties to be associated with the payload. In
59       *            the case of Jms you could set the JMSReplyTo property in these
60       *            properties.
61       * @throws org.mule.api.MuleException
62       */
63      public void dispatch(String url, Object payload, Map messageProperties) throws MuleException
64      {
65          MuleMessage message = new DefaultMuleMessage(payload, messageProperties, muleContext);
66          OutboundEndpoint endpoint = muleContext.getEndpointFactory().getOutboundEndpoint(url);
67          MuleEvent event = getEvent(message,endpoint);
68          try
69          {
70              endpoint.process(event);
71          }
72          catch (MuleException e)
73          {
74              throw e;
75          }
76          catch (Exception e)
77          {
78              throw new DispatchException(ClientMessages.failedToDispatchClientEvent(), event,
79                  endpoint, e);
80          }
81      }
82  
83      /**
84       * Sends an object (payload) synchronous to the given url and returns a
85       * MuleMessage response back.
86       *
87       * @param url the Mule url used to determine the destination and transport of the
88       *            message
89       * @param payload the object that is the payload of the event
90       * @param messageProperties any properties to be associated with the payload. In
91       *            the case of Jms you could set the JMSReplyTo property in these
92       *            properties.
93       * @return a response.
94       * @throws org.mule.api.MuleException
95       */
96      public MuleMessage send(String url, Object payload, Map messageProperties) throws MuleException
97      {
98          MuleMessage message = new DefaultMuleMessage(payload, messageProperties, muleContext);
99          OutboundEndpoint endpoint = getOutboundEndpoint(url, MessageExchangePattern.REQUEST_RESPONSE);
100         MuleEvent event = getEvent(message, endpoint);
101 
102         try
103         {
104             MuleEvent resultEvent = endpoint.process(event);
105             if (resultEvent != null)
106             {
107                 return resultEvent.getMessage();
108             }
109             else
110             {
111                 return null;
112             }
113         }
114         catch (MuleException e)
115         {
116             throw e;
117         }
118         catch (Exception e)
119         {
120             throw new DispatchException(ClientMessages.failedToDispatchClientEvent(), event,
121                 endpoint, e);
122         }
123     }
124 
125     /**
126      * Will receive an event from an endpointUri determined by the url
127      *
128      * @param url the Mule url used to determine the destination and transport of the
129      *            message
130      * @param timeout how long to block waiting to receive the event, if set to 0 the
131      *            receive will not wait at all and if set to -1 the receive will wait
132      *            forever
133      * @return the message received or null if no message was received
134      * @throws org.mule.api.MuleException
135      */
136     public MuleMessage request(String url, long timeout) throws MuleException
137     {
138         InboundEndpoint endpoint = muleContext.getEndpointFactory().getInboundEndpoint(url);
139 
140         try
141         {
142             return endpoint.request(timeout);
143         }
144         catch (Exception e)
145         {
146             throw new ReceiveException(endpoint, timeout, e);
147         }
148     }
149 
150     protected OutboundEndpoint getOutboundEndpoint(String uri, MessageExchangePattern exchangePattern)
151         throws MuleException
152     {
153         EndpointBuilder endpointBuilder = muleContext.getEndpointFactory().getEndpointBuilder(uri);
154         endpointBuilder.setExchangePattern(exchangePattern);
155         return muleContext.getEndpointFactory().getOutboundEndpoint(endpointBuilder);
156     }
157 
158     /**
159      * Packages a mule event for the current request
160      */
161     protected MuleEvent getEvent(MuleMessage message, OutboundEndpoint endpoint)
162         throws MuleException
163     {
164         MuleSession session = new DefaultMuleSession(message, ((AbstractConnector)endpoint.getConnector()).getSessionHandler(), muleContext);
165 
166         if (credentials != null)
167         {
168             message.setOutboundProperty(MuleProperties.MULE_USER_PROPERTY, "Plain " + credentials.getToken());
169         }
170 
171         return new DefaultMuleEvent(message, endpoint, session);
172     }
173 
174     /**
175      * Retrieves a ManagedConnection.
176      *
177      * @return a ManagedConnection instance representing the physical connection to
178      *         the EIS
179      */
180 
181     public MuleManagedConnection getManagedConnection()
182     {
183         return managedConnection;
184     }
185 
186     /**
187      * Closes the connection.
188      */
189     public void close() throws ResourceException
190     {
191         if (managedConnection == null)
192         {
193             return; // connection is already closed
194         }
195         managedConnection.removeConnection(this);
196 
197         // Send a close event to the App Server
198         managedConnection.fireCloseEvent(this);
199         managedConnection = null;
200     }
201 
202     /**
203      * Associates connection handle with new managed connection.
204      *
205      * @param newMc new managed connection
206      */
207 
208     public void associateConnection(MuleManagedConnection newMc) throws ResourceException
209     {
210         checkIfValid();
211         // dissociate handle from current managed connection
212         managedConnection.removeConnection(this);
213         // associate handle with new managed connection
214         newMc.addConnection(this);
215         managedConnection = newMc;
216     }
217 
218     /**
219      * Checks the validity of the physical connection to the EIS.
220      *
221      * @throws javax.resource.ResourceException in case of any error
222      */
223 
224     void checkIfValid() throws ResourceException
225     {
226         if (managedConnection == null)
227         {
228             throw new ResourceException(
229                 JcaMessages.objectMarkedInvalid("muleManagedConnection").toString());
230         }
231     }
232 
233     /**
234      * Sets the physical connection to the EIS as invalid. The physical connection to
235      * the EIS cannot be used any more.
236      */
237 
238     void invalidate()
239     {
240         managedConnection = null;
241     }
242 }