* @param epr The EPR to be used in the delivery attempt.
* @return Returns the message (or a reply message if synchronous) if the message was delivered
* without error, otherwise null.
*/
private Message attemptDelivery(Message message, EPR epr) throws FaultMessageException, MalformedEPRException, MessageDeliverException {
TwoWayCourier courier = null;
final EPR targetEPR ;
if ((extensions != null) && (extensions.size() > 0))
{
targetEPR = EPRHelper.copyEPR(epr, extensions) ;
}
else
{
targetEPR = epr ;
}
// Get a courier for the EPR...
try {
courier = getCourier(targetEPR);
} catch (CourierException e) {
if (logger.isDebugEnabled()) {
logger.debug("Courier lookup failed for EPR [" + targetEPR + "] for Service [" + service + "] and Message ["+message.getHeader()+"].", e);
}
} catch (MalformedEPRException e) {
// probably an ESB-unaware EPR in the registry!!
logger.info("Badly formed EPR [" + targetEPR + "] for Service [" + service + "] and Message ["+message.getHeader()+"]." + e.getMessage());
throw e;
} catch (Throwable t) {
logger.warn("Unexpected exception during Courier lookup for EPR [" + targetEPR + "] for Service [" + service + "] and Message ["+message.getHeader()+"].", t);
}
// 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 {