InterceptorImplpublic class InterceptorImpl extends org.omg.CORBA.LocalObject implements ClientRequestInterceptor, ServerRequestInterceptorThis is the implementation of the JTS PI-based client/server interceptor.
This will be called during request/reply invocation path. |
Fields Summary |
---|
private static final String | name | private static final int | TransactionServiceId | private static final SystemException | SYS_EXC | public static final int | NO_REPLY_SLOT | public static final int | NULL_CTX_SLOT | public static final Integer | PROPER_CTX | public static final Integer | NULL_CTX | public static final Integer | REPLY | public static final Integer | NO_REPLY | public static final String | CLIENT_POLICY_CHECKING | public static final String | INTEROP_MODE | private static com.sun.corba.ee.spi.oa.rfm.ReferenceFactoryManager | rfm | static Logger | _logger | public static final ThreadLocal | otsThreadLocal | private static PropagationContext | nullContext | private static PropagationContext | dummyContext | public static ORB | txOrb | org.omg.PortableInterceptor.Current | pic | org.omg.IOP.Codec | codec | int[] | slotIds | TSIdentification | tsi | com.sun.corba.ee.impl.txpoa.TSIdentificationImpl | tsiImpl | org.omg.CosTSPortability.Sender | sender | org.omg.CosTSPortability.Receiver | receiver | private boolean | checkPolicy | private boolean | interopMode |
Constructors Summary |
---|
public InterceptorImpl(org.omg.PortableInterceptor.Current pic, org.omg.IOP.Codec codec, int[] slotIds, TSIdentification tsi)
// constructor
this.pic = pic;
this.codec = codec;
this.slotIds = slotIds;
this.tsi = tsi;
this.tsiImpl = (TSIdentificationImpl) tsi;
if (this.tsiImpl != null) {
this.sender = this.tsiImpl.getSender();
this.receiver = this.tsiImpl.getReceiver();
}
// check if client side checking is disabled. This allows client side
// policy checking to be disabled (for testing purposes).
String prop = System.getProperty(CLIENT_POLICY_CHECKING, "true");
this.checkPolicy = prop.equals("true");
// get the transaction interoperability mode.
prop = System.getProperty(INTEROP_MODE, "true");
this.interopMode = prop.equals("true");
if (_logger.isLoggable(Level.FINE))
_logger.log(Level.FINE, "Transaction INTEROP Mode: " + this.interopMode);
|
Methods Summary |
---|
public void | destroy()
| public static java.lang.Integer | getThreadLocalData(int slot)
Object[] threadLocalState = (Object[]) otsThreadLocal.get();
// IASRI 4698847 START
//return (Integer) ((Stack) threadLocalState[slot]).pop();
return (Integer) ((ArrayListStack) threadLocalState[slot]).pop();
// IASRI 4698847 END
| public static boolean | isDummyContext(PropagationContext ctx)
boolean proceed = false;
try {
proceed =
(ctx.implementation_specific_data.extract_boolean() == true);
} catch (BAD_OPERATION e) {
return false;
}
return (proceed && isNullContext(ctx) && ctx.timeout == -1);
| public static boolean | isEjbAdapterName(java.lang.String[] adapterName)
boolean result = false ;
if (rfm != null)
result = rfm.isRfmName( adapterName ) ;
return result ;
| public static boolean | isNullContext(PropagationContext ctx)
return (ctx.current.coord == null && ctx.current.term == null);
| public static boolean | isTxCtxtNull()
Object[] threadLocalState = (Object[]) otsThreadLocal.get();
// IASRI 4698847 START
//Stack stack = (Stack) threadLocalState[NULL_CTX_SLOT];
/*
if (stack.empty()) {
return true;
}
*/
// return ((Integer) stack.peek() == NULL_CTX);
ArrayListStack stack = (ArrayListStack) threadLocalState[NULL_CTX_SLOT];
return ((Integer) stack.peek() == NULL_CTX);
// IASRI 4698847 END
| public java.lang.String | name()
return InterceptorImpl.name;
| private void | processServerSendPoint(ServerRequestInfo ri, CompletionStatus completionStatus)
// clear the null ctx indicator
getThreadLocalData(NULL_CTX_SLOT);
// see if a reply ctx needs to be sent.
Integer no_reply = getThreadLocalData(NO_REPLY_SLOT);
if (no_reply == NO_REPLY) {
return;
}
// TransactionService is not available.
if (this.tsiImpl == null || this.receiver == null) {
if (no_reply == REPLY) {
// would the TransactionService go down during request
// processing ? Maybe.
throw new TRANSACTION_ROLLEDBACK(0, completionStatus);
}
return;
}
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE," sending_reply["+ ri.request_id() + "] : " +
ri.operation() + ", ThreadName : " +
Thread.currentThread().toString());
}
// call the proprietary OTS interceptor.
PropagationContextHolder ctxh = new PropagationContextHolder();
receiver.sending_reply(ri.request_id(), ctxh);
if (ctxh.value == null) {
// no tx context available. This should not happen since a tx ctx
// was received.
throw new TRANSACTION_ROLLEDBACK(0, completionStatus);
}
// create the service context and set it in the reply.
//Any any = ORB.init().create_any();
Any any = txOrb.create_any();
PropagationContextHelper.insert(any, ctxh.value);
byte[] ctxData = null;
try {
ctxData = this.codec.encode_value(any);
} catch (InvalidTypeForEncoding e) {
throw new INTERNAL(0, completionStatus);
}
ServiceContext svc = new ServiceContext(TransactionServiceId, ctxData);
ri.add_reply_service_context(svc, false);
| public void | receive_exception(ClientRequestInfo ri)
// check if a tx svc context was received.
ServiceContext svc = null;
try {
svc = ri.get_reply_service_context(TransactionServiceId);
} catch (BAD_PARAM e) {
return; // do nothing (no tx service context in reply).
// REVISIT Exception replies may not carry a tx context back,
// as a result checked transaction behaviour will cause the
// transaction to fail.
}
catch(Exception e){
return;
}
if (svc == null) {
return;
}
// a tx svc context is available.
// Set up the Environment instance with exception information.
// The exception can be a SystemException or an UnknownUserException.
Environment env = new com.sun.corba.ee.impl.corba.EnvironmentImpl();
SystemException exception = null;
Any any = ri.received_exception();
InputStream strm = any.create_input_stream();
String repId = ri.received_exception_id();
strm.read_string(); // read repId
int minorCode = strm.read_long(); // read minorCode
CompletionStatus completionStatus = // read completionStatus
CompletionStatus.from_int(strm.read_long());
if (repId.indexOf("UNKNOWN") != -1) { // user exception ?
if (minorCode == 1) { // read minorCode
// user exception
} else { // system exception
exception = SYS_EXC;
}
} else { // system exception
exception = SYS_EXC;
}
env.exception(exception);
// check if TransactionService is available.
if (this.tsiImpl == null || this.sender == null) {
throw new TRANSACTION_ROLLEDBACK(0, completionStatus);
}
// read the propagation context
try {
TypeCode typeCode = PropagationContextHelper.type();
any = this.codec.decode_value(svc.context_data, typeCode);
} catch (TypeMismatch e) {
throw new INTERNAL(0, completionStatus);
} catch (FormatMismatch e) {
throw new INTERNAL(0, completionStatus);
}
PropagationContext ctx = PropagationContextHelper.extract(any);
// call the OTS proprietary hook.
try {
sender.received_reply(ri.request_id(), ctx, env);
} catch (org.omg.CORBA.WrongTransaction ex) {
throw new INVALID_TRANSACTION(0, completionStatus);
}
| public void | receive_other(ClientRequestInfo ri)
// check if a tx svc context was received.
ServiceContext svc = null;
try {
svc = ri.get_reply_service_context(TransactionServiceId);
} catch (BAD_PARAM e) {
return; // do nothing (no tx service context in reply).
// REVISIT If a valid tx context was sent, and none was received
// back, then the checked transaction behaviour will cause the
// transaction to fail.
}
if (svc == null) {
return;
}
// a tx svc context is available.
// check if TransactionService is available.
if (this.tsiImpl == null || this.sender == null) {
throw new TRANSACTION_ROLLEDBACK(0, CompletionStatus.COMPLETED_NO);
}
// read the propagation context
Any any = null;
try {
TypeCode typeCode = PropagationContextHelper.type();
any = this.codec.decode_value(svc.context_data, typeCode);
} catch (TypeMismatch e) {
throw new INTERNAL(0, CompletionStatus.COMPLETED_NO);
} catch (FormatMismatch e) {
throw new INTERNAL(0, CompletionStatus.COMPLETED_NO);
}
PropagationContext ctx = PropagationContextHelper.extract(any);
// Set up the Environment instance with exception information.
// The exception can be a SystemException or an UnknownUserException.
Environment env = new EnvironmentImpl();
env.exception(null);
// call the OTS proprietary hook.
try {
sender.received_reply(ri.request_id(), ctx, env);
} catch (org.omg.CORBA.WrongTransaction ex) {
throw new INVALID_TRANSACTION(0, CompletionStatus.COMPLETED_NO);
}
| public void | receive_reply(ClientRequestInfo ri)
// check if a tx svc context was received.
ServiceContext svc = null;
try {
svc = ri.get_reply_service_context(TransactionServiceId);
} catch (BAD_PARAM e) {
return; // do nothing (no tx service context in reply).
// REVISIT If a valid tx context was sent, and none was received
// back, then the checked transaction behaviour will cause the
// transaction to fail.
}
if (svc == null) {
return;
}
// a tx svc context is available.
// check if TransactionService is available.
if (this.tsiImpl == null || this.sender == null) {
throw new TRANSACTION_ROLLEDBACK(0, CompletionStatus.COMPLETED_YES);
}
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE," received_reply[" + ri.request_id() + "] : " +
ri.operation() + ", ThreadName : " +
Thread.currentThread().toString());
}
// read the propagation context
Any any = null;
try {
TypeCode typeCode = PropagationContextHelper.type();
any = this.codec.decode_value(svc.context_data, typeCode);
} catch (TypeMismatch e) {
throw new INTERNAL(0, CompletionStatus.COMPLETED_YES);
} catch (FormatMismatch e) {
throw new INTERNAL(0, CompletionStatus.COMPLETED_YES);
}
PropagationContext ctx = PropagationContextHelper.extract(any);
// Set up the Environment instance with exception information.
// The exception can be a SystemException or an UnknownUserException.
Environment env = new EnvironmentImpl();
env.exception(null);
// call the OTS proprietary hook.
try {
sender.received_reply(ri.request_id(), ctx, env);
} catch (org.omg.CORBA.WrongTransaction ex) {
throw new INVALID_TRANSACTION(0, CompletionStatus.COMPLETED_YES);
}
| public void | receive_request(ServerRequestInfo ri)
// do nothing.
| public void | receive_request_service_contexts(ServerRequestInfo ri)
// since this could be called on a seperate thread, we need to
// transfer the svc context to the request PICurrent slots.
// But for now, since we know that this is called by the same thread
// as the target, we do not do it. But we should at some point.
// do policy checking.
OTSPolicy otsPolicy = null;
try {
otsPolicy = (OTSPolicy) ri.get_server_policy(OTS_POLICY_TYPE.value);
} catch (INV_POLICY e) {
// ignore. This will be treated as FORBIDS.
}
short otsPolicyValue = -1;
if (otsPolicy == null) {
// Once J2EE RI moves to POA based policy mechanism, default of
// FORBIDS shall be used. Until then, we will use ADAPTS.
//otsPolicyValue = OTSPolicyImpl._FORBIDS.value();
otsPolicyValue = OTSPolicyImpl._ADAPTS.value();
} else {
otsPolicyValue = otsPolicy.value();
}
// get the tx contxt, if one was received.
ServiceContext svc = null;
try {
svc = ri.get_request_service_context(TransactionServiceId);
} catch (BAD_PARAM e) {
// ignore, svc == null will be handled later.
}
// set threadLocal slot to indicate whether tx svc ctxt
// was received or not. (svc == null) ==> NO_REPLY is true.
if (svc == null) {
setThreadLocalData(NO_REPLY_SLOT, NO_REPLY);
} else {
setThreadLocalData(NO_REPLY_SLOT, REPLY);
}
// initially set the thread local slot to indicate proper ctxt.
// if the null ctx is received, then it will be set later in the method.
setThreadLocalData(NULL_CTX_SLOT, PROPER_CTX);
try {
// TransactionService is not available.
if (this.tsiImpl == null || this.receiver == null) {
if (svc != null || otsPolicyValue == REQUIRES.value) {
throw new TRANSACTION_UNAVAILABLE();
}
return;
}
// TransactionService is available.
// no tx context was received.
if (svc == null) {
if (otsPolicyValue == REQUIRES.value) {
throw new TRANSACTION_REQUIRED();
}
return;
}
// a tx ctx was received.
// check policy
if (otsPolicyValue == FORBIDS.value) {
throw new INVALID_TRANSACTION();
}
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE," received_request[" +
ri.request_id() + "] : " + ri.operation() +
", ThreadName : " + Thread.currentThread().toString());
}
// Create service context.
// sanity check.
if (svc.context_id != TransactionServiceId) {
throw new INVALID_TRANSACTION();
}
Any any = null;
try {
TypeCode typeCode = PropagationContextHelper.type();
any = this.codec.decode_value(svc.context_data, typeCode);
} catch (TypeMismatch e) {
throw new INTERNAL();
} catch (FormatMismatch e) {
throw new INTERNAL();
}
PropagationContext ctx = PropagationContextHelper.extract(any);
// check if a 'dummyContext' is present (local optimization).
// If so, return.
if (isDummyContext(ctx)) {
// do nothing, since it is the same client thread which already
// has the tx context association.
// NOTE There is a chance that the 'nullContext' could be mistaken
// to be a 'dummyContext', which may cause a valid 'nullContext'
// to be ignored (!). But let's hope there won't be a collision :)
// no need to send a reply ctx
getThreadLocalData(NO_REPLY_SLOT); // pop item
setThreadLocalData(NO_REPLY_SLOT, NO_REPLY); // push item
return;
}
// check if a 'nullContext' was received,
// and set the threadlocal data appropriately.
if (isNullContext(ctx)) {
// indicate a null context
getThreadLocalData(NULL_CTX_SLOT); // pop item
setThreadLocalData(NULL_CTX_SLOT, NULL_CTX); // push item
// no need to send a reply ctx
getThreadLocalData(NO_REPLY_SLOT); // pop item
setThreadLocalData(NO_REPLY_SLOT, NO_REPLY); // push item
return;
} else if (this.interopMode == false) {
getThreadLocalData(NULL_CTX_SLOT); // pop item
setThreadLocalData(NULL_CTX_SLOT, NULL_CTX); // push item
}
// call the proprietary hook
receiver.received_request(ri.request_id(), ctx);
} catch (RuntimeException r) {
// The server send point will not be called if the server receive
// point raises an exception. So, do the cleanup.
// ie., restore thread local data
getThreadLocalData(NO_REPLY_SLOT);
getThreadLocalData(NULL_CTX_SLOT);
throw r;
}
| public void | send_exception(ServerRequestInfo ri)
Any any = ri.sending_exception();
InputStream strm = any.create_input_stream();
strm.read_string(); // repId
strm.read_long(); // minorCode
CompletionStatus completionStatus =
CompletionStatus.from_int(strm.read_long());
processServerSendPoint(ri, completionStatus);
| public void | send_other(ServerRequestInfo ri)
processServerSendPoint(ri, CompletionStatus.COMPLETED_NO);
| public void | send_poll(ClientRequestInfo ri)
// do nothing.
| public void | send_reply(ServerRequestInfo ri)
processServerSendPoint(ri, CompletionStatus.COMPLETED_YES);
| public void | send_request(ClientRequestInfo ri)
// do IOR policy checking.
TaggedComponent otsComp = null;
try {
otsComp = ri.get_effective_component(TAG_OTS_POLICY.value);
} catch (BAD_PARAM e) {
// ignore
}
short otsPolicyValue = -1;
if (otsComp == null) {
// in the case of J2EE RI, all published IORs must have an
// associated OTS policy component. The only exception being the
// location forwarded IORs returned by ORBD. Until a time, the ORBD
// is capable of transcribing the target POA policies into the
// location forwarded IOR, treat the absence of an OTS policy
// component as being equivalent to ADAPTS. Once the ORBD is
// able to support OTS policy components, the absence of an OTS
// policy component must be treated as FORBIDS.
otsPolicyValue = OTSPolicyImpl._ADAPTS.value();
} else {
// TypeCode typeCode = ORB.init().get_primitive_tc(TCKind.tk_short);
TypeCode typeCode = txOrb.get_primitive_tc(TCKind.tk_short);
Any any = null;
try {
any = this.codec.decode_value(otsComp.component_data, typeCode);
} catch (TypeMismatch e) {
throw new INTERNAL();
} catch (FormatMismatch e) {
throw new INTERNAL();
}
otsPolicyValue = OTSPolicyValueHelper.extract(any);
}
// TransactionService is not available.
if (this.tsiImpl == null || this.sender == null) {
if (otsPolicyValue == REQUIRES.value && this.checkPolicy) {
throw new TRANSACTION_UNAVAILABLE();
}
return;
}
// TransactionService is available.
/*
// Call JTS proprietary interceptor to see if there is a current tx.
PropagationContextHolder hctx = new PropagationContextHolder();
sender.sending_request(ri.request_id(), hctx);
if (hctx.value == null) { // no tx context
if (otsPolicyValue == REQUIRES.value && this.checkPolicy) {
throw new TRANSACTION_REQUIRED();
}
return;
}
*/
// Check to see if there is a current transaction.
boolean isTxAssociated = CurrentTransaction.isTxAssociated();
if (!isTxAssociated) { // no tx context
if (otsPolicyValue == REQUIRES.value && this.checkPolicy) {
throw new TRANSACTION_REQUIRED();
}
return;
}
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE," sending_request["+ ri.request_id() +
"] : " + ri.operation() + ", ThreadName : " +
Thread.currentThread().toString());
}
// a current tx is available. Create service context.
if (otsPolicyValue == FORBIDS.value && this.checkPolicy) {
throw new INVALID_TRANSACTION();
}
PropagationContextHolder hctx = new PropagationContextHolder();
// if target object is co-located, no need to send tx context.
// This optimization uses a dummy context to flag the local case, so
// that the server receive point shall ignore the context (after doing
// appropriate policy checking). The net gain is that the activation of
// coordinator object is avoided.
// Note, this currently has issues with respect to checked behavior.
// Currently, checked behaviour is disabled and shall be reinstated
// once OTS RTF redrafts the OTS spec based on PI. An issue needs to be
// filed.
org.omg.CORBA.Object target = ri.effective_target();
if ( StubAdapter.isStub(target) && StubAdapter.isLocal(target) ) {
// target is local
// load a dummy context and discard the current tx context.
hctx.value = dummyContext;
} else if (this.interopMode == false) { // target is remote
// load a null context and discard the current tx context.
hctx.value = nullContext;
} else {
IOR ior = ((com.sun.corba.ee.spi.orb.ORB)txOrb).getIOR( target, false ) ;
IIOPProfile prof = ior.getProfile() ;
ObjectKeyTemplate oktemp = prof.getObjectKeyTemplate() ;
if (oktemp.getORBVersion().equals(ORBVersionFactory.getFOREIGN()))
{
hctx.value = nullContext;
} else {
/*
ObjectAdapterId oaid = oktemp.getObjectAdapterId() ;
String[] adapterName = oaid.getAdapterName() ;
boolean isEjbCall = isEjbAdapterName(adapterName);
if (!isEjbCall) {
hctx.value = nullContext;
} else {
// Call JTS proprietary interceptor to get current tx.
sender.sending_request(ri.request_id(), hctx);
} */
sender.sending_request(ri.request_id(), hctx);
}
}
// add service context.
//Any any = ORB.init().create_any();
Any any = txOrb.create_any();
PropagationContextHelper.insert(any, hctx.value);
byte[] ctxData = null;
try {
ctxData = this.codec.encode_value(any);
} catch (InvalidTypeForEncoding e) {
throw new INTERNAL();
}
ServiceContext svc = new ServiceContext(TransactionServiceId, ctxData);
ri.add_request_service_context(svc, false);
| public static void | setOrb(ORB orb)
txOrb = orb;
Any any = txOrb.create_any();
any.insert_boolean(false);
nullContext = new PropagationContext(
0,
new TransIdentity(null, null, new otid_t(0, 0, new byte[0])),
new TransIdentity[0],
any);
any.insert_boolean(true);
dummyContext = new PropagationContext(
-1,
new TransIdentity(null, null, new otid_t(-1, 0, new byte[0])),
new TransIdentity[0],
any);
try {
rfm = (ReferenceFactoryManager)orb.resolve_initial_references(
ORBConstants.REFERENCE_FACTORY_MANAGER ) ;
} catch (Exception ex) {
_logger.log(Level.WARNING,ex.getMessage(), ex);
}
| public void | setTSIdentification(TSIdentification tsi)
if (tsi == null) {
return;
}
this.tsi = tsi;
this.tsiImpl = (TSIdentificationImpl) tsi;
this.sender = this.tsiImpl.getSender();
this.receiver = this.tsiImpl.getReceiver();
| public static void | setThreadLocalData(int slot, java.lang.Integer data)
Object[] threadLocalState = (Object[]) otsThreadLocal.get();
// IASRI 4698847 START
//((Stack) threadLocalState[slot]).push(data);
((ArrayListStack) threadLocalState[slot]).push(data);
// IASRI 4698847 END
|
|