
org.objectweb.jotm.ots.OTSInterceptor Maven / Gradle / Ivy
/*
* @(#) OTSInterceptor.java 1.0 02/07/15
*
* JOTM: Java Open Transaction Manager
*
* This module was originally developed by
* - INRIA inside the ObjectWeb Consortium(http://www.objectweb.org)
*
* The original code and portions created by INRIA are
* Copyright (C) 2002 - INRIA (www.inria.fr)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* -Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* --------------------------------------------------------------------------
* $Id: OTSInterceptor.java 903 2008-06-26 08:11:16Z durieuxp $
* --------------------------------------------------------------------------
*/
package org.objectweb.jotm.ots;
import javax.rmi.PortableRemoteObject;
import javax.transaction.xa.Xid;
import org.omg.CORBA.Any;
import org.omg.CORBA.LocalObject;
import org.omg.CORBA.ORB;
import org.omg.CORBA.TCKind;
import org.omg.CosTransactions.PropagationContext;
import org.omg.CosTransactions.PropagationContextHelper;
import org.omg.CosTransactions.TransIdentity;
import org.omg.CosTransactions.otid_t;
import org.omg.DynamicAny.DynAnyFactory;
import org.omg.DynamicAny.DynAnyFactoryHelper;
import org.omg.IOP.Codec;
import org.omg.IOP.ServiceContext;
import org.omg.PortableInterceptor.ForwardRequest;
import org.omg.PortableInterceptor.ORBInitInfo;
import org.omg.PortableInterceptor.ORBInitInfoPackage.InvalidName;
import org.objectweb.jotm.Coordinator;
import org.objectweb.jotm.InternalTransactionContext;
import org.objectweb.jotm.Terminator;
import org.objectweb.jotm.TransactionContext;
import org.objectweb.jotm.XidImpl;
public abstract class OTSInterceptor extends LocalObject {
// Used to encode/decode the call
protected Codec codec;
// for identifying client or server.
protected DynAnyFactory dynAnyFactoryS_;
// Service context identifier
protected final int TX_CTX_ID = org.omg.IOP.TransactionService.value; //100;
// ORB instance
protected static ORB orb = null ;
/**
* constructor
*/
public OTSInterceptor(ORBInitInfo info) {
// Get the codec factory
org.omg.IOP.CodecFactory factory = info.codec_factory();
if(factory == null) throw new RuntimeException();
// Create codec
org.omg.IOP.Encoding how = new org.omg.IOP.Encoding();
how.major_version = 1;
how.minor_version = 0;
how.format = org.omg.IOP.ENCODING_CDR_ENCAPS.value;
try {
codec = factory.create_codec(how);
} catch(org.omg.IOP.CodecFactoryPackage.UnknownEncoding ex) {
throw new RuntimeException();
}
if(codec == null) throw new RuntimeException();
//
// Get the dynamic any factory
//
DynAnyFactory dynAnyFactory = null;
try {
org.omg.CORBA.Object obj = info.resolve_initial_references("DynAnyFactory");
dynAnyFactory = DynAnyFactoryHelper.narrow(obj);
} catch(InvalidName ex) {
throw new RuntimeException();
} catch(org.omg.CORBA.BAD_PARAM ex) {
throw new RuntimeException();
}
dynAnyFactoryS_ = dynAnyFactory;
} // end constructor
protected Any create_any() throws org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode{
org.omg.DynamicAny.DynAny dynAny = dynAnyFactoryS_.create_dyn_any_from_type_code(PropagationContextHelper.type());
return dynAny.to_any();
}
/**
* Build and returns the CORBA PropagationContext (JTS)
*/
protected ServiceContext buildCorbaPropagationContext(TransactionContext txCtx) throws ForwardRequest {
try {
// Build a new CORBA Propagation context
// For the moment, JOTM does not implement tx interoperability EJB2.1 ?19.6 and
// so the fields CosTransactions:Coordinator and CosTransactions:Terminator are set
// to null in order to generate a 'null transaction ctx'
// The coordinator/terminator are propagated in the 'implementation_specific_data' field.
// Get Information of TransactionContext
Xid xid = txCtx.getXid();
int timeout = txCtx.getTimeout();
Coordinator coord = txCtx.getCoordinator();
// Xid is coded in the otid_t
byte[] gtrid = xid.getGlobalTransactionId();
byte[] bqual = xid.getBranchQualifier();
byte[] tid = new byte[gtrid.length + bqual.length];
System.arraycopy(bqual, 0, tid, 0, bqual.length);
System.arraycopy(gtrid, 0, tid, bqual.length, gtrid.length);
otid_t otid = new otid_t(xid.getFormatId(), bqual.length, tid);
// current holds only otid_t
TransIdentity curr = new TransIdentity(null, null, otid);
// Create the PropagationContext
PropagationContext pctx =
new PropagationContext(timeout, curr, new TransIdentity[0], null);
// In JOTM, the Coordinator and the terminator interface are implemented
// by the same class : ControlImpl. The stub is propagated to others JOnAS
// instances in the implementation_specific_data field. It is coded in an Any
// field
if (orb==null){
// Get ORB instance
orb=ORB.init(new String[]{}, null) ;
}
Any specific = orb.create_any();
if (coord != null) {
// Set the JOTM's coordinator in the 'specific' field
specific.insert_Object((javax.rmi.CORBA.Stub) PortableRemoteObject.toStub(coord));
pctx.implementation_specific_data = specific;
} else {
// If the coordinator is unknown, set a 'JONAS' pattern
// to allow the other side to recognize a
// JOTM context
specific.insert_string("JOnAS");
pctx.implementation_specific_data = specific;
}
Any pAny = create_any();
PropagationContextHelper.insert(pAny, pctx);
// encode the PropagationContext in a service context
byte[] propagationContextData = codec.encode_value(pAny);
return new ServiceContext(TX_CTX_ID, propagationContextData);
} catch (Exception e) {
throw new ForwardRequest();
}
}
/**
* decode the Corba Propagation Context and build an internal transaction context
* @param sCtx ServiceContext
*/
protected TransactionContext decodeCorbaPropagationContext(ServiceContext sCtx){
if (sCtx == null) { // no tx ctx
return null ;
}
Xid xid = null;
int timeout;
Any specific = null ;
// try to decode the corba tx context
try {
// unmarshall the Propagation Context
Any pctxAny = codec.decode_value(sCtx.context_data, PropagationContextHelper.type());
PropagationContext pctx = PropagationContextHelper.extract(pctxAny);
// get the propagation context values
specific = pctx.implementation_specific_data;
otid_t otid = pctx.current.otid;
timeout = pctx.timeout;
xid = new XidImpl(otid.formatID, otid.bqual_length, otid.tid);
} catch (Exception e) { // invalid tx ctx
return null;
}
// JOTM don't be able to detect whether the context is a valid or a null ctx
// If it isn't a JOTM's context (fail during decoding), it considers it's a null ctx
boolean isJotmCtx=false;
Coordinator coord = null;
Terminator term = null;
try {
if ((specific == null) || (specific.type().kind() == TCKind.tk_null) ||
(specific.type().kind() == TCKind.tk_octet)) {
// null ctx or valid ctx but sent from another app server
// isJotmCtx=false ;
} else if (specific.type().kind() == TCKind.tk_string) {
String pattern = specific.extract_string() ;
// Here, maybe we have received a JOTM context with an unknown coordinator
// In this case, a JONAS pattern has been set
if (pattern.compareTo("JOnAS")==0) {
isJotmCtx=true ;
}
} else {
// Last try, it should be a typical JOTM context with the coordinator set in 'specific' field
coord = (Coordinator) PortableRemoteObject.narrow((java.rmi.Remote) specific.extract_Object(),
Coordinator.class);
term = (Terminator) PortableRemoteObject.narrow((java.rmi.Remote) specific.extract_Object(),
Terminator.class);
isJotmCtx=true ;
}
} catch (Exception e) {
// null ctx or valid ctx but sent from another app server
// isJotmCtx=false ;
}
TransactionContext tCtx = new InternalTransactionContext(timeout, coord, term, xid);
if ( isJotmCtx == false ) {
// flag the internal context to indicate the ctx comes from
// another vendor
tCtx.setNotJotmCtx();
}
return tCtx;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy