TxClientPipepublic class TxClientPipe extends com.sun.xml.ws.tx.common.TxBasePipe This class process transactional context for client outgoing message. |
Fields Summary |
---|
private static com.sun.xml.ws.tx.common.TxLogger | logger | final QName | COORD_CTX_QNAME | private final com.sun.xml.ws.assembler.ClientPipeConfiguration | pipeConfigContains policy assertions | private final com.sun.xml.ws.api.SOAPVersion | soapVersion | private Marshaller | marshallerMarshaller | private static boolean | reportCheckCurrentJTAStacktrace |
Constructors Summary |
---|
public TxClientPipe(com.sun.xml.ws.assembler.ClientPipeConfiguration pcfg, com.sun.xml.ws.api.pipe.Pipe next)Construct a new outbound tx pipe.
/*,
SecurityPipeContext spctx*/
super(next);
this.pipeConfig = pcfg;
this.soapVersion = pcfg.getBinding().getSOAPVersion();
//this.spctx = spctx;
this.marshaller = TxJAXBContext.createMarshaller();
| private TxClientPipe(TxClientPipe orig, com.sun.xml.ws.api.pipe.PipeCloner cloner)Constructor used by copy method
super(cloner.copy(orig.next));
cloner.add(orig, this);
this.pipeConfig = orig.pipeConfig;
this.soapVersion = orig.soapVersion;
this.marshaller = TxJAXBContext.createMarshaller();
|
Methods Summary |
---|
private javax.transaction.Transaction | checkCurrentJTATransaction(com.sun.xml.ws.api.message.Message msg, com.sun.xml.ws.api.model.wsdl.WSDLPort wsdlModel)
Transaction currentTxn = null;
try {
currentTxn = txnMgr.getTransaction();
// workaround for glassfksh issue 2659, catch throwable instead of just SystemException.
// } catch (SystemException se) {
} catch (Throwable t) {
if (logger.isLogging(Level.FINEST)) {
if (reportCheckCurrentJTAStacktrace) {
reportCheckCurrentJTAStacktrace = false;
logger.finest("checkCurrentJTATransaction",
"handled exception thrown during checkCurrentJTATransaction",
t);
} else {
logger.finest("checkCurrentJTATransaction",
"handled exception thrown during checkCurrentJTATransaction");
}
}
}
if (currentTxn == null) {
// no current JTA transaction, so no work to do here
if (logger.isLogging(Level.FINEST)) {
logger.finest("process", "no current JTA transaction for invoked operation " +
msg.getOperation(wsdlModel).getName().toString());
}
}
return currentTxn;
| public com.sun.xml.ws.api.pipe.Pipe | copy(com.sun.xml.ws.api.pipe.PipeCloner cloner)Creates an identical clone of this Pipe.
return new TxClientPipe(this, cloner);
| private com.sun.xml.ws.tx.coordinator.CoordinationContextInterface | lookupOrCreateCoordinationContext(com.sun.xml.ws.tx.common.ATAssertion assertion)
Transaction currentTxn;
CoordinationContextInterface result = null;
try {
currentTxn = txnMgr.getTransaction();
} catch (SystemException e) {
throw new WebServiceException(e.getMessage(), e);
}
// wsat policy assertion validation when no current txn scope CC
if ((currentTxn == null) && (assertion == MANDATORY)) {
// txn scope MANDATORY to invoke this operation, notify user
throw new WebServiceException(LocalizationMessages.MISSING_TX_SCOPE_1000());
}
if (currentTxn != null) {
// see if a coordination context is already associated with the current JTA transaction.
result = txnMgr.getCoordinationContext();
if (result == null) {
// create & associate a coordination context with current thread's transaction context
final long EXPIRES = txnMgr.getRemainingTimeout() * 1000L;
result = ContextFactory.createContext(WSAT_2004_PROTOCOL, EXPIRES);
// create a new coordinator object for this context. Associate JTA transaction with ATCoordinator.
ATCoordinator coord = new ATCoordinator(result);
coord.setTransaction(currentTxn);
CoordinationManager.getInstance().putCoordinator(coord);
// cache the resulting context in the transaction context
txnMgr.setCoordinationContext(result);
}
}
return result;
| public com.sun.xml.ws.api.message.Packet | process(com.sun.xml.ws.api.message.Packet pkt)Process transactional context in outgoing message.
Transactional context is only flowed if the following conditions are met:
- current JTA Transaction
- wsdl:binding/wsdl:operation of this packet has wsat:ATAssertion
final Message msg = pkt.getMessage();
final WSDLPort wsdlModel = pipeConfig.getWSDLModel();
Packet responsePacket = null;
// TODO: minimizing process overhead for cases that do not flow a transaction.
// Current assumption is it is cheaper to check if there is a current JTA transaction
// than it is to check if a wsdl:binding/wsdl:operation has wsat:ATAssertion
// If that assumption is incorrect, exchange this check with one checking for
// existence of wsat policy assertion.
//
Transaction currentTxn = checkCurrentJTATransaction(msg, wsdlModel);
if (currentTxn == null) {
return next.process(pkt);
}
// get trust plugin from security pipe
// encryption through security pipe
final WSDLBoundOperation wsdlBoundOp = msg.getOperation(wsdlModel);
ATAssertion atAssertion = getOperationATPolicy(pipeConfig.getPolicyMap(),
wsdlModel,
wsdlBoundOp).atAssertion;
if (atAssertion == NOT_ALLOWED ) {
// no ws-at policy assertion on the wsdl:binding/wsdl:operation, so no work to do here
if (logger.isLogging(Level.FINE)) {
logger.fine("process", "no ws-at policy asssertion for " + wsdlBoundOp.getName().toString());
}
return next.process(pkt);
}
// TODO: Issue a warning if can not flow a WS-AT transaction context due to following implementation limitations
// 1. From an Application Container
// 2. On an asynchronous web service invocation (should be able to detect this statically)
// Recorded as wsit issue 471.
if ((atAssertion == MANDATORY || atAssertion == ALLOWED) ) {
// TODO: Is it possible to determine (2) in this pipe??
// Following conditional is true in application client OR when
// configuration of wstx service is invalid.
// Possible misconfigurations are wrong port for wstx_service,
// improper security certificates.
if (! StatefulWebserviceFactoryFactory.getInstance().isWSTXServiceAvailable()) {
logger.warning("TxClientPipe",
LocalizationMessages.
WSAT_TXN_CONTEXT_NOT_FLOWED_1001(
msg.getOperation(wsdlModel).getName().toString()));
return next.process(pkt);
}
}
// get the coordination context from JTS ThreadLocal data
CoordinationContextInterface context = lookupOrCreateCoordinationContext(atAssertion);
CoordinationContext CC = (CoordinationContext) context.getValue(); // TODO: fix cast
Header ccHeader;
if (atAssertion == MANDATORY || atAssertion == ALLOWED) {
// flow current txn scope CC with msg
// Generate <wst:IssuedToken> header.
// The <wscoor:Identifier> is passed as <wsp:AppliesTo> in the
// <wst:RequestSecurityTokenResponse>. The resulting <wst:IssuedToken>
// must be injected into the CoodinationContext and subsequently encrypted
CoordinationContextType.Identifier id = CC.getIdentifier(); // coordinated activity id
//IssuedTokenContext itCtx = spctx.processClientInitRSCTR(msg, id, scid /* what's scid? */);
// ISSUE: who will inject the <wst:IssuedToken> txser???
// add coordination context into message header
// Add soap:MustUnderstand.
CC.getOtherAttributes().put(new QName(soapVersion.nsUri, "mustUnderstand"), "true");
ccHeader = Headers.create(soapVersion, marshaller, COORD_CTX_QNAME, CC);
msg.getHeaders().add(ccHeader);
}
// Suspend transaction from current thread.
// If web service invocations is within same application server vm,
// then the same JTA transaction will be used and it must only be associated
// with one thread at any point in time. Will resume transaction when it returns.
try {
currentTxn = txnMgr.suspend();
} catch (SystemException ex) {
throw new WebServiceException(ex.getMessage(), ex);
}
Exception rethrow = null;
try {
responsePacket = next.process(pkt);
} catch (Exception e) {
rethrow = e;
} finally {
try {
// flow of control is transfered back from caller, resume transaction.
txnMgr.resume(currentTxn);
} catch (Exception ex) {
if (rethrow != null) {
rethrow.initCause(ex);
throw new WebServiceException(ex.getMessage(), rethrow);
} else {
rethrow = ex;
}
}
if (rethrow != null) {
throw new WebServiceException(rethrow.getMessage(), rethrow);
}
}
return responsePacket;
|
|