// Try delivering the message using the courier we just looked up....
if (courier != null) {
// make sure the message header does not change when we exit
final Call call = message.getHeader().getCall() ;
final EPR currentToEpr = call.getTo() ;
final EPR currentReplyToEpr = call.getReplyTo() ;
try {
call.setTo(targetEPR);
final EPR replyToEPR ;
if (synchronous) {
/*
* Currently all couriers that have transactional semantics work in a manner similar
* to JMS, i.e., messages are not delivered on to a queue (or to an endpoint) until
* the enclosing transaction has committed. In a synchronous invocation this will
* result in timeouts if the sending thread is also the terminating thread. We check
* for this here and throw an exception before we try to do a send so the application can
* figure it out.
*
* Note: if the transactional semantics change (e.g., to support true distributed transactions)
* then this will need to be modified too.
*/
if (isTransactional())
throw new IncompatibleTransactionScopeException("Request-response attempt within running transaction controlling request delivery! Using epr [" + targetEPR + "] for Service [" + service + "] and Message ["+message.getHeader()+"]");
replyToEPR = (currentReplyToEpr == null ? getReplyToAddress(targetEPR) : currentReplyToEpr) ;
if (replyToEPR == null) {
if (logger.isDebugEnabled()) {
logger.debug("Not using epr [" + targetEPR + "] for Service [" + service + "] and Message ["+message.getHeader()+"]. No reply-to address available for synchronous response.");
}
return null;
}
call.setReplyTo(replyToEPR);
} else {
replyToEPR = null ;
}
if (courier.deliver(message)) {
if (synchronous) {
courier.cleanup() ;
// JBESB-1016 replyToEPR has to be non-null or we'd have dropped out by this point!
// do we need to do this for synchronous calls? Vagueries of Couriers?
courier.setReplyToEpr(replyToEPR);
final Message response = courier.pickup(timeout);
if (response == null) {
throw new ResponseTimeoutException("No response received within timeout period") ;
}
return response ;
} else {
return message;
}
}
} catch (FaultMessageException e) {
throw e;
} catch (final CourierServiceBindException e) {
// meant to be masked by the SI fail-over
if (logger.isDebugEnabled()) {
logger.debug("Caught service lookup exception for EPR [" + targetEPR + "] and Service [" + service + "] and Message ["+message.getHeader()+"]. ", e);
}
// could be stale EPR, so move on to next entry in registry.
} catch (final CourierMarshalUnmarshalException e) {
logger.warn("Courier indicated (un)marshal related error "+e+" during delivery to EPR [" + targetEPR + "] for Service [" + service + "] and Message ["+message.getHeader()+"]. " + e.getMessage());
throw new MessageDeliverException("Caught (un)marshal related exception during attempted send/receive.", e);
} catch (final CourierTransportException e) {
// meant to be masked by the SI fail-over
if (logger.isDebugEnabled()) {
logger.debug("Courier indicated transport related error "+e+" during send/receive with EPR [" + targetEPR + "] for Service [" + service + "] and Message ["+message.getHeader()+"]. ", e);
}
} catch (CourierException e) {
// probable config error. Log it and move on to next EPR/service entry.
logger.warn("Possible configuration error while using Courier for EPR [" + targetEPR + "] and Service [" + service + "] and Message ["+message.getHeader()+"]. " + e.getMessage());
} catch (MalformedEPRException e) {
// Hmmmm???... Can this really happen? The Courier has already been created. Haven't we already validated the EPR during the Courier lookup (above)??
logger.error("Unexpected error. Badly formed EPR [" + targetEPR + "] for Service [" + service + "]. But the EPR has already been validated!!");
throw e;
} catch (final CourierTimeoutException ex) {
logger.error("Response timeout using Courier for EPR [" + targetEPR + "] for Service [" + service + "] and Message ["+message.getHeader()+"].");
// timeout from synchronous invocation
// would like to make this an independent exception (not inherit from MDE). But signatures and applications would break.
throw new ResponseTimeoutException("Caught response timeout!", ex);
} catch (final MessageDeliverException mde) {
throw mde ;
} catch (Throwable t) {
logger.error("Unexpected throwable during attempted message delivery using Courier for EPR [" + targetEPR + "] for Service [" + service + "] and Message ["+message.getHeader()+"].", t);
// we don't know what state we're in so better to bail-out now!
throw new MessageDeliverException("Caught unexpected throwable during send. Bailing-out!", t);
} finally {
CourierUtil.cleanCourier(courier);
// put back the old To since we will have changed it.
call.setTo(currentToEpr) ;
call.setReplyTo(currentReplyToEpr) ;
}
}
return null;
}