001: /*
002: * $Id: DefaultMuleSession.java 11343 2008-03-13 10:58:26Z tcarlson $
003: * --------------------------------------------------------------------------------------
004: * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com
005: *
006: * The software in this package is published under the terms of the CPAL v1.0
007: * license, a copy of which has been included with this distribution in the
008: * LICENSE.txt file.
009: */
010:
011: package org.mule;
012:
013: import org.mule.api.MuleContext;
014: import org.mule.api.MuleEvent;
015: import org.mule.api.MuleException;
016: import org.mule.api.MuleMessage;
017: import org.mule.api.MuleSession;
018: import org.mule.api.config.MuleProperties;
019: import org.mule.api.endpoint.EndpointNotFoundException;
020: import org.mule.api.endpoint.InboundEndpoint;
021: import org.mule.api.endpoint.OutboundEndpoint;
022: import org.mule.api.routing.OutboundRouterCollection;
023: import org.mule.api.security.SecurityContext;
024: import org.mule.api.service.Service;
025: import org.mule.api.transport.Connector;
026: import org.mule.api.transport.DispatchException;
027: import org.mule.api.transport.ReceiveException;
028: import org.mule.api.transport.SessionHandler;
029: import org.mule.config.i18n.CoreMessages;
030: import org.mule.transport.AbstractConnector;
031: import org.mule.util.UUID;
032:
033: import java.util.HashMap;
034: import java.util.Iterator;
035: import java.util.Map;
036:
037: import org.apache.commons.logging.Log;
038: import org.apache.commons.logging.LogFactory;
039:
040: /**
041: * <code>DefaultMuleSession</code> manages the interaction and distribution of events for
042: * Mule UMOs.
043: */
044:
045: public final class DefaultMuleSession implements MuleSession {
046: /**
047: * Serial version
048: */
049: private static final long serialVersionUID = 3380926585676521866L;
050:
051: /**
052: * logger used by this class
053: */
054: private static Log logger = LogFactory
055: .getLog(DefaultMuleSession.class);
056:
057: /**
058: * The Mule service associated with the session
059: */
060: private Service service = null;
061:
062: /**
063: * Determines if the service is valid
064: */
065: private boolean valid = true;
066:
067: private String id;
068:
069: private SecurityContext securityContext;
070:
071: private Map properties = null;
072:
073: private MuleContext muleContext;
074:
075: public DefaultMuleSession(Service service, MuleContext muleContext) {
076: this .muleContext = muleContext;
077: properties = new HashMap();
078: id = UUID.getUUID();
079: this .service = service;
080: }
081:
082: public DefaultMuleSession(MuleMessage message,
083: SessionHandler requestSessionHandler, Service service,
084: MuleContext muleContext) throws MuleException {
085: this (message, requestSessionHandler, muleContext);
086: if (service == null) {
087: throw new IllegalArgumentException(CoreMessages
088: .propertiesNotSet("service").toString());
089: }
090: this .service = service;
091: }
092:
093: public DefaultMuleSession(MuleMessage message,
094: SessionHandler requestSessionHandler,
095: MuleContext muleContext) throws MuleException {
096: this .muleContext = muleContext;
097:
098: if (requestSessionHandler == null) {
099: throw new IllegalArgumentException(CoreMessages
100: .propertiesNotSet("requestSessionHandler")
101: .toString());
102: }
103:
104: if (message == null) {
105: throw new IllegalArgumentException(CoreMessages
106: .propertiesNotSet("message").toString());
107: }
108:
109: properties = new HashMap();
110: requestSessionHandler.retrieveSessionInfoFromMessage(message,
111: this );
112: id = (String) getProperty(requestSessionHandler
113: .getSessionIDKey());
114: if (id == null) {
115: id = UUID.getUUID();
116: if (logger.isDebugEnabled()) {
117: logger
118: .debug("There is no session id on the request using key: "
119: + requestSessionHandler
120: .getSessionIDKey()
121: + ". Generating new session id: " + id);
122: }
123: } else if (logger.isDebugEnabled()) {
124: logger.debug("Got session with id: " + id);
125: }
126: }
127:
128: public void dispatchEvent(MuleMessage message) throws MuleException {
129: if (service == null) {
130: throw new IllegalStateException(CoreMessages.objectIsNull(
131: "Service").getMessage());
132: }
133:
134: OutboundRouterCollection router = service.getOutboundRouter();
135: if (router == null) {
136: throw new EndpointNotFoundException(CoreMessages
137: .noOutboundRouterSetOn(service.getName()));
138: }
139: router.route(message, this , false);
140: }
141:
142: public void dispatchEvent(MuleMessage message, String endpointName)
143: throws MuleException {
144: dispatchEvent(message, muleContext.getRegistry()
145: .lookupEndpointFactory().getOutboundEndpoint(
146: endpointName));
147: }
148:
149: public void dispatchEvent(MuleMessage message,
150: OutboundEndpoint endpoint) throws MuleException {
151: if (endpoint == null) {
152: logger
153: .warn("Endpoint argument is null, using outbound router to determine endpoint.");
154: dispatchEvent(message);
155: }
156:
157: if (logger.isDebugEnabled()) {
158: logger
159: .debug("MuleSession has received asynchronous event on: "
160: + endpoint);
161: }
162:
163: MuleEvent event = createOutboundEvent(message, endpoint, null);
164:
165: dispatchEvent(event);
166:
167: processResponse(event.getMessage());
168: }
169:
170: public MuleMessage sendEvent(MuleMessage message,
171: String endpointName) throws MuleException {
172: return sendEvent(message, muleContext.getRegistry()
173: .lookupEndpointFactory().getOutboundEndpoint(
174: endpointName));
175: }
176:
177: public MuleMessage sendEvent(MuleMessage message)
178: throws MuleException {
179: if (service == null) {
180: throw new IllegalStateException(CoreMessages.objectIsNull(
181: "Service").getMessage());
182: }
183: OutboundRouterCollection router = service.getOutboundRouter();
184: if (router == null) {
185: throw new EndpointNotFoundException(CoreMessages
186: .noOutboundRouterSetOn(service.getName()));
187: }
188: MuleMessage result = router.route(message, this , true);
189: if (result != null) {
190: processResponse(result);
191: }
192:
193: return result;
194: }
195:
196: public MuleMessage sendEvent(MuleMessage message,
197: OutboundEndpoint endpoint) throws MuleException {
198: if (endpoint == null) {
199: logger
200: .warn("Endpoint argument is null, using outbound router to determine endpoint.");
201: return sendEvent(message);
202: }
203:
204: if (logger.isDebugEnabled()) {
205: logger
206: .debug("MuleSession has received synchronous event on endpoint: "
207: + endpoint);
208: }
209:
210: MuleEvent event = createOutboundEvent(message, endpoint, null);
211: MuleMessage result = sendEvent(event);
212:
213: // Handles the situation where a response has been received via a remote
214: // ReplyTo channel.
215: if (endpoint.isRemoteSync() && result != null) {
216: result
217: .applyTransformers(endpoint
218: .getResponseTransformers());
219: }
220:
221: if (result != null) {
222: processResponse(result);
223: }
224:
225: return result;
226: }
227:
228: /*
229: * (non-Javadoc)
230: *
231: * @see org.mule.api.MuleSession#dispatchEvent(org.mule.api.MuleEvent)
232: */
233: public void dispatchEvent(MuleEvent event) throws MuleException {
234: if (event.getEndpoint() instanceof OutboundEndpoint) {
235: try {
236: if (logger.isDebugEnabled()) {
237: logger.debug("dispatching event: " + event);
238: }
239:
240: Connector connector = event.getEndpoint()
241: .getConnector();
242:
243: if (connector instanceof AbstractConnector) {
244: ((AbstractConnector) connector).getSessionHandler()
245: .storeSessionInfoToMessage(this ,
246: event.getMessage());
247: } else {
248: // TODO in Mule 2.0 we'll flatten the Connector hierachy
249: logger
250: .warn("A session handler could not be obtained, using default");
251: new MuleSessionHandler().storeSessionInfoToMessage(
252: this , event.getMessage());
253: }
254:
255: ((OutboundEndpoint) event.getEndpoint())
256: .dispatch(event);
257: } catch (Exception e) {
258: throw new DispatchException(event.getMessage(), event
259: .getEndpoint(), e);
260: }
261: } else if (service != null) {
262: if (logger.isDebugEnabled()) {
263: logger.debug("dispatching event to service: "
264: + service.getName() + ", event is: " + event);
265: }
266: service.dispatchEvent(event);
267: processResponse(event.getMessage());
268: } else {
269: throw new DispatchException(CoreMessages
270: .noComponentForEndpoint(), event.getMessage(),
271: event.getEndpoint());
272: }
273: }
274:
275: public String getId() {
276: return id;
277: }
278:
279: /*
280: * (non-Javadoc)
281: *
282: * @see org.mule.api.MuleSession#sendEvent(org.mule.api.MuleEvent)
283: */
284: // TODO This method is practically the same as dispatchEvent(MuleEvent event),
285: // so we could use some refactoring here.
286: public MuleMessage sendEvent(MuleEvent event) throws MuleException {
287: int timeout = event.getMessage().getIntProperty(
288: MuleProperties.MULE_EVENT_TIMEOUT_PROPERTY, -1);
289: if (timeout >= 0) {
290: event.setTimeout(timeout);
291: }
292:
293: if (event.getEndpoint() instanceof OutboundEndpoint) {
294: try {
295: if (logger.isDebugEnabled()) {
296: logger.debug("sending event: " + event);
297: }
298:
299: Connector connector = event.getEndpoint()
300: .getConnector();
301:
302: if (connector instanceof AbstractConnector) {
303: ((AbstractConnector) connector).getSessionHandler()
304: .storeSessionInfoToMessage(this ,
305: event.getMessage());
306: } else {
307: // TODO in Mule 2.0 we'll flatten the Connector hierachy
308: logger
309: .warn("A session handler could not be obtained, using default.");
310: new MuleSessionHandler().storeSessionInfoToMessage(
311: this , event.getMessage());
312: }
313:
314: MuleMessage response = ((OutboundEndpoint) event
315: .getEndpoint()).send(event);
316: // See MULE-2692
317: response = OptimizedRequestContext
318: .unsafeRewriteEvent(response);
319: processResponse(response);
320: return response;
321: } catch (MuleException e) {
322: throw e;
323: } catch (Exception e) {
324: throw new DispatchException(event.getMessage(), event
325: .getEndpoint(), e);
326: }
327:
328: } else if (service != null) {
329: if (logger.isDebugEnabled()) {
330: logger.debug("sending event to service: "
331: + service.getName() + " event is: " + event);
332: }
333: return service.sendEvent(event);
334:
335: } else {
336: throw new DispatchException(CoreMessages
337: .noComponentForEndpoint(), event.getMessage(),
338: event.getEndpoint());
339: }
340: }
341:
342: /**
343: * Once an event has been processed we need to romove certain properties so that
344: * they not propagated to the next request
345: *
346: * @param response The response from the previous request
347: */
348: protected void processResponse(MuleMessage response) {
349: if (response == null) {
350: return;
351: }
352: }
353:
354: /*
355: * (non-Javadoc)
356: *
357: * @see org.mule.api.MuleSession#isValid()
358: */
359: public boolean isValid() {
360: return valid;
361: }
362:
363: /*
364: * (non-Javadoc)
365: *
366: * @see org.mule.api.MuleSession#setValid(boolean)
367: */
368: public void setValid(boolean value) {
369: valid = value;
370: }
371:
372: /*
373: * (non-Javadoc)
374: *
375: * @see org.mule.api.MuleSession#receiveEvent(org.mule.api.endpoint.Endpoint,
376: * long, org.mule.api.MuleEvent)
377: */
378: public MuleMessage requestEvent(String endpointName, long timeout)
379: throws MuleException {
380: InboundEndpoint endpoint = RegistryContext.getRegistry()
381: .lookupEndpointFactory().getInboundEndpoint(
382: endpointName);
383: return requestEvent(endpoint, timeout);
384: }
385:
386: /*
387: * (non-Javadoc)
388: *
389: * @see org.mule.api.MuleSession#receiveEvent(org.mule.api.endpoint.Endpoint,
390: * long, org.mule.api.MuleEvent)
391: */
392: public MuleMessage requestEvent(InboundEndpoint endpoint,
393: long timeout) throws MuleException {
394: try {
395: return endpoint.request(timeout);
396: } catch (Exception e) {
397: throw new ReceiveException(endpoint, timeout, e);
398: }
399: }
400:
401: public MuleEvent createOutboundEvent(MuleMessage message,
402: OutboundEndpoint endpoint, MuleEvent previousEvent)
403: throws MuleException {
404: if (endpoint == null) {
405: throw new DispatchException(CoreMessages
406: .objectIsNull("Outbound Endpoint"), message,
407: endpoint);
408: }
409:
410: if (logger.isDebugEnabled()) {
411: logger.debug("Creating event with data: "
412: + message.getPayload().getClass().getName()
413: + ", for endpoint: " + endpoint);
414: }
415:
416: try {
417: MuleEvent event;
418: if (previousEvent != null) {
419: event = new DefaultMuleEvent(message, endpoint,
420: service, previousEvent);
421: } else {
422: event = new DefaultMuleEvent(message, endpoint, this ,
423: false, null);
424: }
425: return event;
426: } catch (Exception e) {
427: throw new DispatchException(CoreMessages
428: .failedToCreate("MuleEvent"), message, endpoint, e);
429: }
430: }
431:
432: /**
433: * @return Returns the service.
434: */
435: public Service getService() {
436: return service;
437: }
438:
439: void setService(Service service) {
440: this .service = service;
441: }
442:
443: /**
444: * The security context for this session. If not null outbound, inbound and/or
445: * method invocations will be authenticated using this context
446: *
447: * @param context the context for this session or null if the request is not
448: * secure.
449: */
450: public void setSecurityContext(SecurityContext context) {
451: securityContext = context;
452: }
453:
454: /**
455: * The security context for this session. If not null outbound, inbound and/or
456: * method invocations will be authenticated using this context
457: *
458: * @return the context for this session or null if the request is not secure.
459: */
460: public SecurityContext getSecurityContext() {
461: return securityContext;
462: }
463:
464: /**
465: * Will set a session level property. These will either be stored and retrieved
466: * using the underlying transport mechanism of stored using a default mechanism
467: *
468: * @param key the key for the object data being stored on the session
469: * @param value the value of the session data
470: */
471: public void setProperty(Object key, Object value) {
472: properties.put(key, value);
473: }
474:
475: /**
476: * Will retrieve a session level property.
477: *
478: * @param key the key for the object data being stored on the session
479: * @return the value of the session data or null if the property does not exist
480: */
481: public Object getProperty(Object key) {
482: return properties.get(key);
483: }
484:
485: /**
486: * Will retrieve a session level property and remove it from the session
487: *
488: * @param key the key for the object data being stored on the session
489: * @return the value of the session data or null if the property does not exist
490: */
491: public Object removeProperty(Object key) {
492: return properties.remove(key);
493: }
494:
495: /**
496: * Returns an iterater of property keys for the session properties on this
497: * session
498: *
499: * @return an iterater of property keys for the session properties on this
500: * session
501: */
502: public Iterator getPropertyNames() {
503: return properties.keySet().iterator();
504: }
505:
506: }
|