Package com.sun.enterprise.iiop

Source Code of com.sun.enterprise.iiop.POARemoteReferenceFactory

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.enterprise.iiop;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.net.URL;
import java.io.File;
import java.util.*;
import java.util.logging.*;
import java.lang.reflect.Method;

import javax.rmi.PortableRemoteObject;
import javax.rmi.CORBA.*;
import javax.transaction.*;
import javax.ejb.EJBHome;
import javax.ejb.EJBObject;
import javax.ejb.NoSuchObjectLocalException;
import javax.naming.*;

import org.omg.CORBA.*;
import org.omg.CORBA.portable.Delegate;
import org.omg.CosNaming.NamingContext;

import org.omg.PortableServer.POA ;
import org.omg.PortableServer.Servant ;
import org.omg.PortableServer.ServantLocator ;
import org.omg.PortableServer.ServantLocatorPackage.CookieHolder ;

import com.sun.logging.LogDomains;
import com.sun.enterprise.*;
import com.sun.enterprise.deployment.*;
import com.sun.enterprise.util.*;
import com.sun.enterprise.server.*;
import com.sun.enterprise.deployment.runtime.IASEjbExtraDescriptors;
import com.sun.ejb.*;
import com.sun.ejb.base.sfsb.util.EJBServerConfigLookup;
import com.sun.ejb.containers.StatefulSessionContainer;

import com.sun.corba.ee.spi.ior.*;
import com.sun.corba.ee.spi.extension.ServantCachingPolicy;
import com.sun.corba.ee.spi.extension.ZeroPortPolicy;
import com.sun.corba.ee.spi.extension.CopyObjectPolicy;
import com.sun.corba.ee.spi.extension.RequestPartitioningPolicy;
import com.sun.corba.ee.spi.extension.LoadBalancingPolicy;
import com.sun.corba.ee.spi.orbutil.threadpool.ThreadPoolManager;
import com.sun.corba.ee.spi.orbutil.threadpool.NoSuchThreadPoolException;
import com.sun.corba.ee.spi.presentation.rmi.PresentationManager ;
import com.sun.corba.ee.spi.presentation.rmi.DynamicStub;
import com.sun.corba.ee.spi.presentation.rmi.StubAdapter;
import com.sun.corba.ee.spi.oa.rfm.ReferenceFactory ;
import com.sun.corba.ee.spi.oa.rfm.ReferenceFactoryManager ;

import com.sun.corba.ee.impl.orbutil.ORBConstants;
import com.sun.corba.ee.impl.naming.cosnaming.TransientNameService;
import com.sun.corba.ee.impl.util.SUNVMCID;

import com.sun.enterprise.util.Utility;
/**
* This class implements the RemoteReferenceFactory interface for the
* RMI/IIOP ORB with POA (Portable Object Adapter).
* There is one instance of the POARemoteReferenceFactory for each
* EJB type.
*
* It also implements the preinvoke/postinvoke APIs in the
* POA's ServantLocator interface, which are called before/after
* every invocation (local or remote).
* It creates a RMI-IIOP-POA object reference (a stub) for every EJBObject
* and EJBHome in the EJB container.
*
* @author Kenneth Saks
*/

public final class POARemoteReferenceFactory extends org.omg.CORBA.LocalObject
      implements RemoteReferenceFactory, ServantLocator
{
    static final int PASS_BY_VALUE_ID = 0;
    static final int PASS_BY_REFERENCE_ID = 1;

    static final int OTS_POLICY_TYPE = SUNVMCID.value + 123;
    static final int CSIv2_POLICY_TYPE = SUNVMCID.value + 124;
    static final int REQUEST_DISPATCH_POLICY_TYPE = SUNVMCID.value + 125;
    static final int SFSB_VERSION_POLICY_TYPE = SUNVMCID.value + 126;
   
    private static final java.util.logging.Logger logger =
    java.util.logging.Logger.getLogger(LogDomains.CORBA_LOGGER);
    private static final int GET_TIE_EXCEPTION_CODE = 9999;

    private Container container;
    private EjbDescriptor ejbDescriptor;

    private ORB orb;
    private POAProtocolMgr protocolMgr;
    private PresentationManager presentationMgr;

    private ReferenceFactory ejbHomeReferenceFactory ;
    private PresentationManager.StubFactory ejbHomeStubFactory;
    private String ejbHomeRepositoryId;

    private ReferenceFactory ejbObjectReferenceFactory ;
    private PresentationManager.StubFactory ejbObjectStubFactory;
    private String ejbObjectRepositoryId;

    private String remoteBusinessIntf;
   
    // true if remote home view.  false if remote business view.
    // Used when getting target object for an invocation.
    private boolean isRemoteHomeView;

    private String poaId_EJBHome;
    private String poaId_EJBObject;

    // The EJB key format with field-name(size in bytes):
    // -----------------------------------------
    // | EJB ID(8) | INSTANCEKEY | INSTANCEKEY |
    // |           | LENGTH(4)   |   (unknown) |
    // -----------------------------------------
    // The following are the offsets for the fields in the EJB key.
    static final int EJBID_OFFSET = 0;
    private static final int INSTANCEKEYLEN_OFFSET = 8;
    private static final int INSTANCEKEY_OFFSET = 12;


    POARemoteReferenceFactory(Container container, POAProtocolMgr protocolMgr,
            ORB orb, boolean remoteHomeView, String id) {
   
  this.protocolMgr = protocolMgr;
  this.orb = orb;
        this.poaId_EJBHome   = id + "-EJBHome";
        this.poaId_EJBObject = id + "-EJBObject";
        this.presentationMgr =
            ((com.sun.corba.ee.spi.orb.ORB) orb).getPresentationManager();
  this.container = container;
  this.ejbDescriptor = container.getEjbDescriptor();
        this.isRemoteHomeView = remoteHomeView;

  ClassLoader loader = container.getClassLoader();

  // NOTE: ReferenceFactory creation happens in setRepositoryIds.
 
  if (logger.isLoggable(Level.FINE)) {
      logger.log(Level.FINE,
           "POARemoteReferenceFactory:"
           + " " + poaId_EJBHome
           + " " + poaId_EJBObject
           + " " + ejbDescriptor);
  }

    }

    private String getRepositoryId(Class c) throws Exception {

        // Using PresentationManager to get repository ID will always work,
        // independent of whether we have generated static RMI-IIOP stubs.

        PresentationManager.ClassData cData = presentationMgr.getClassData(c);
        String[] typeIds = cData.getTypeIds()

  if (logger.isLoggable(Level.FINE)) {
      logger.log(Level.FINE, ".getRepositoryId: " + typeIds[0]);
  }

        // Repository id is always 1st element in array.
        return typeIds[0];
    }

    public void setRepositoryIds(Class homeIntf, Class remoteIntf)
    {

        ClassLoader appClassLoader = container.getClassLoader();

        PresentationManager.StubFactoryFactory sff =
            ((com.sun.corba.ee.spi.orb.ORB) orb).getStubFactoryFactory();

        // Home
        ejbHomeStubFactory =
            sff.createStubFactory( homeIntf.getName(), false,
                                   "", null, appClassLoader);
        String[] ejbHomeTypeIds = ejbHomeStubFactory.getTypeIds();
        ejbHomeRepositoryId = ejbHomeTypeIds[0];

        ejbObjectStubFactory =
      sff.createStubFactory( remoteIntf.getName(), false,
           "", null, appClassLoader);
        String[] ejbObjectTypeIds = ejbObjectStubFactory.getTypeIds();
        ejbObjectRepositoryId = ejbObjectTypeIds[0];

  if (logger.isLoggable(Level.FINE)) {
      logger.log(Level.FINE,
           ".setRepositoryIds:"
           + " " + ejbHomeRepositoryId
           + " " + ejbObjectRepositoryId);
  }

  try {
 
      ejbHomeReferenceFactory
    = createReferenceFactory(poaId_EJBHome, ejbHomeRepositoryId, true);
      ejbObjectReferenceFactory
    = createReferenceFactory(poaId_EJBObject, ejbObjectRepositoryId, false);
  } catch (Exception e) {
      throw new RuntimeException(e);
  }

        if( !isRemoteHomeView ) {
            remoteBusinessIntf = remoteIntf.getName();
        }
           
    }

    public void cleanupClass(Class clazz) {

        try {
            presentationMgr.flushClass(clazz);
        } catch(Exception e) {
            logger.log(Level.FINE, "cleanupClass error", e);
        }
    }

    private ReferenceFactory createReferenceFactory(String poaId, String repoid, boolean home ) throws Exception {
      try {
  if (logger.isLoggable(Level.FINE)) {
      logger.log(Level.WARNING,
           ".createReferenceFactory->: " + poaId + " " + repoid);
  }

  ReferenceFactoryManager rfm =
      (ReferenceFactoryManager)orb.resolve_initial_references(
    ORBConstants.REFERENCE_FACTORY_MANAGER ) ;

  List<Policy> policies = new ArrayList<Policy>();

  // Servant caching for local RMI-IIOP invocation performance
        policies.add(ServantCachingPolicy.getPolicy());

  // OTS Policy
  policies.add(new OTSPolicy());

  if (logger.isLoggable(Level.FINE)) {
      logger.log(Level.WARNING,
           ".createReferenceFactory: " + poaId + " " + repoid
           + ": " + ejbDescriptor);
  }

  // CSIv2 Policy
  policies.add(new CSIv2Policy(ejbDescriptor));

  IASEjbExtraDescriptors extraDesc
      = ejbDescriptor.getIASEjbExtraDescriptors();
  String threadPoolName = extraDesc.getUseThreadPoolId();
  int threadPoolNumericID = 0;
  boolean usePassByReference = extraDesc.getPassByReference();

  if (usePassByReference) {
      policies.add(new CopyObjectPolicy(PASS_BY_REFERENCE_ID));
  }

        // Set per-request-load-balancing policy on ejb object references
        if( !home && extraDesc.hasPerRequestLoadBalancing() ) {
            policies.add( new LoadBalancingPolicy(ORBConstants.PER_REQUEST_LOAD_BALANCING));
            logger.log(Level.FINE, "Setting per-request-load-balancing policy " +
                       "for Ejb " + ejbDescriptor.getName());
        }


  if (threadPoolName != null) {
      ThreadPoolManager threadPoolManager
    = S1ASThreadPoolManager.getThreadPoolManager();
      try {
    threadPoolNumericID = threadPoolManager.getThreadPoolNumericId(
        threadPoolName);
    policies.add(new RequestPartitioningPolicy(threadPoolNumericID));
      } catch (Exception ex) {
                logger.log(Level.WARNING, "Not using threadpool-request-partitioning...", ex);
      }
  }

  if (logger.isLoggable(Level.FINE)) {
            logger.log(Level.FINE, "POARemoteRefFactory checking if SFSBVersionPolicy need to be added");
        }

    /* Findbugs
    EJBServerConfigLookup ejbConfigLookup =
        new EJBServerConfigLookup(ejbDescriptor);
    */
    boolean addSFSBVersionPolicy = EJBServerConfigLookup.needToAddSFSBVersionInterceptors();
    if (logger.isLoggable(Level.FINE)) {
        logger.log(Level.FINE, "POARemoteRefFactory addSFSBVersionPolicy? " + addSFSBVersionPolicy);
    }
    if (addSFSBVersionPolicy) {
        if (container instanceof StatefulSessionContainer) {
            StatefulSessionContainer sfsbCon = (StatefulSessionContainer) container;
            if (sfsbCon.isHAEnabled()) {
                policies.add(new SFSBVersionPolicy(ejbDescriptor.getUniqueId()));
            }
        }
    }


  if (logger.isLoggable(Level.FINE)) {
      String jndiName = ejbDescriptor.getJndiName();
      logger.log(Level.FINE, "Using Thread-Pool: ["
    + threadPoolName + " ==> " + threadPoolNumericID
    + "] for jndi name: " + jndiName);
      logger.log(Level.FINE, "Pass by reference: ["
    + usePassByReference
    + "] for jndi name: " + usePassByReference);
  }

  // DisableClearTextIIOP policy which sets IIOP Profile port to 0
  // if EJB allows only SSL invocations
  CSIV2TaggedComponentInfo ctc = new CSIV2TaggedComponentInfo(orb);
  Set iorDescSet = ejbDescriptor.getIORConfigurationDescriptors();
        if ( ctc.allMechanismsRequireSSL(iorDescSet) ) {
      if (logger.isLoggable(Level.FINE)) {
    logger.log(Level.WARNING,
         ".createReferenceFactory: " + poaId + " " + repoid
         + ": adding ZeroPortPolicy");
      }
      policies.add(ZeroPortPolicy.getPolicy());
        }

  if (logger.isLoggable(Level.FINE)) {
      logger.log(Level.WARNING,
           ".createReferenceFactory: " + poaId + " " + repoid
           + ": policies: " + policies);
  }
  ReferenceFactory rf = rfm.create( poaId, repoid, policies, this ) ;
  return rf ;

      } finally {
  if (logger.isLoggable(Level.FINE)) {
      logger.log(Level.WARNING,
           ".createReferenceFactory<-: " + poaId + " " + repoid);
  }
      }
    }


    public java.rmi.Remote createRemoteReference(byte[] instanceKey)
    {
  return createRef(instanceKey, ejbObjectReferenceFactory,
      ejbObjectStubFactory, ejbObjectRepositoryId );
    }


    public EJBHome createHomeReference(byte[] homeKey)
    {
  return (EJBHome)createRef(homeKey, ejbHomeReferenceFactory,
      ejbHomeStubFactory, ejbHomeRepositoryId ) ;
    }

    private Remote createRef(byte[] instanceKey, ReferenceFactory rf,
  PresentationManager.StubFactory stubFactory, String repoid )
    {
  try {
        PresentationManager.StubFactory stubFact = stubFactory;
      org.omg.CORBA.Object ref = _createRef(rf, instanceKey,repoid);

      org.omg.CORBA.Object stub = stubFact.makeStub();
            Delegate delegate = StubAdapter.getDelegate(ref);
            StubAdapter.setDelegate(stub, delegate);              

      return (Remote) stub;

  } catch(Exception e) {
            logger.log(Level.SEVERE, "iiop.createreference_exception",
                       e.toString());

      throw new RuntimeException("Unable to create reference ",e);
  }
    }

    // NOTE: The repoid is only needed for logging.
    private org.omg.CORBA.Object _createRef( ReferenceFactory rf,
  byte[] instanceKey, String repoid ) throws Exception {

        if ( logger.isLoggable(Level.FINE) ) {
      logger.info("\t\tIn POARemoteReferenceFactory._createRef, " +
                        "repositoryId = " + repoid);
        }

         // Create the ejbKey using EJB's unique id + instanceKey
        byte[] ejbKey = createEJBKey(ejbDescriptor.getUniqueId(),
                                     instanceKey);
       
  org.omg.CORBA.Object obj = rf.createReference( ejbKey ) ;

        return obj;
    }
  
    private byte[] createEJBKey(long ejbId, byte[] instanceKey)
    {
  byte[] ejbkey = new byte[INSTANCEKEY_OFFSET+instanceKey.length];

  Utility.longToBytes(ejbId, ejbkey, EJBID_OFFSET);
  Utility.intToBytes(instanceKey.length, ejbkey, INSTANCEKEYLEN_OFFSET);
  System.arraycopy(instanceKey, 0, ejbkey, INSTANCEKEY_OFFSET,
                  instanceKey.length);
  return ejbkey;
    }



    /**
     * Disconnect an EJBObject or EJBHome from the ORB.
     */
    public void destroyReference(Remote remoteRef, Remote remoteObj)
    {
  // Note: the POAs have the NON_RETAIN policy so they dont maintain
  // any state for objects. We only need to unexport the object from
  // the RMI/IIOP machinery.
  // The following call also does tie.deactivate() for the remoteObj's tie
  try {
      Util.unexportObject(remoteObj);
  } catch ( RuntimeException ex ) {
      // A bug in Util.unexportObject causes this exception
      // Ignore it.
  } catch ( java.lang.Exception nsoe ){
      // eat it and ignore it.
  }
    }


    /**
     * This is the implementation of ServantLocator.preinvoke()
     * It is called from the POA before every remote invocation.
     * Return a POA Servant (which is the RMI/IIOP Tie for EJBObject/EJBHome).
     */
    public Servant preinvoke(byte[] ejbKey, POA adapter, String operation,
                                CookieHolder cookieHolder)
                throws org.omg.PortableServer.ForwardRequest
    {
  if (logger.isLoggable(Level.FINE)) {
      logger.log(Level.FINE,"In preinvoke for operation:" + operation);
  }

  // get instance key
  int keyLen = Utility.bytesToInt(ejbKey, INSTANCEKEYLEN_OFFSET);
  byte[] instanceKey = new byte[keyLen];
  System.arraycopy(ejbKey, INSTANCEKEY_OFFSET, instanceKey, 0, keyLen);

        Servant servant = null;
        try {
            while ( servant == null ) {
    // get the EJBObject / EJBHome
          Remote targetObj =
                    container.getTargetObject(instanceKey,
                                              (isRemoteHomeView ? null :
                                               remoteBusinessIntf));

                // This could be null in rare cases for sfsbs and entity
                // beans.  It would be preferable to push the retry logic
                // within the sfsb container and entity container
                // implementations of getTargetObject, but for now let's keep
                // the looping logic the same as it has always been.
                if( targetObj != null ) {
                    // get the Tie which is the POA Servant
        //fix for bug 6484935
        Tie tie = (Tie)java.security.AccessController.doPrivileged(
            new java.security.PrivilegedAction() {
                        public Tie run()  {
          return presentationMgr.getTie();
      }
        });
                    tie.setTarget(targetObj);
                    servant = (Servant) tie;
                }
            }
        } catch (NoSuchObjectLocalException e) {
            logger.log(Level.SEVERE,"iiop.gettie_exception", e);
            throw new OBJECT_NOT_EXIST( GET_TIE_EXCEPTION_CODE,
          CompletionStatus.COMPLETED_NO);
        } catch (RuntimeException e) {
            logger.log(Level.SEVERE,"iiop.runtime_exception", e);
      throw e;
  }
        return servant;
    }

    public void postinvoke(byte[] ejbKey, POA adapter, String operation,
                            java.lang.Object cookie, Servant servant)
    {
  Remote target = null;
  if ( servant != null ) {
      target = ((Tie)servant).getTarget();
        }
        // Always release, since that restores the previous context class
        // loader.
  container.releaseTargetObject(target);
    }


    public void destroy() {
        try {

      ejbHomeReferenceFactory.destroy() ;
      ejbObjectReferenceFactory.destroy() ;
      ejbHomeReferenceFactory = null ;
      ejbObjectReferenceFactory = null ;

            container = null;
            ejbDescriptor = null;

            orb = null;
            protocolMgr = null;

        } catch (Throwable th) {
            logger.log(Level.SEVERE, "Exception during "
                       + "POARemoteRefFactory::destroy()", th);
        }
    }

    public boolean hasSameContainerID(org.omg.CORBA.Object obj)
  throws Exception
    {
  boolean result = false;
  try {
      IOR ior = ((com.sun.corba.ee.spi.orb.ORB)orb).getIOR(obj, false);
      java.util.Iterator iter = ior.iterator();

      byte[] oid = null;
      if (iter.hasNext()) {
    TaggedProfile profile = (TaggedProfile) iter.next();
    ObjectKey objKey = profile.getObjectKey();
    oid = objKey.getId().getId();
      }

      if ((oid != null) && (oid.length > INSTANCEKEY_OFFSET)) {
    long cid = Utility.bytesToLong(oid, EJBID_OFFSET);
    //To be really sure that is indeed a ref generated
    //  by our container we do the following checks
    int keyLen = Utility.bytesToInt(oid, INSTANCEKEYLEN_OFFSET);
    if (oid.length == keyLen + INSTANCEKEY_OFFSET) {
        result = (cid == ejbDescriptor.getUniqueId());
    }
    if (logger.isLoggable(Level.FINE)) {
        StringBuffer sbuf = new StringBuffer();
        sbuf.append("hasSameContainerID() result: ").append(result)
      .append("; because ==> oid.length: ").append(oid.length)
      .append("; instance-key-length: ").append(keyLen)
      .append("; expected oid.length: ")
      .append(keyLen).append("+").append(INSTANCEKEY_OFFSET)
      .append("; myContainrID: ")
      .append(ejbDescriptor.getUniqueId())
      .append("; obj.containerID: ")
      .append(cid);
        logger.log(Level.FINE, sbuf.toString());
    }
      } else {
    if (logger.isLoggable(Level.FINE)) {
        if (oid == null) {
      logger.log(Level.FINE, "hasSameContainerID() failed because oid=null");
        } else {
      logger.log(Level.FINE, "hasSameContainerID() failed because "
        + "oid.length= " + oid.length
        + "; but INSTANCE_KEY_OFFSET= " + INSTANCEKEY_OFFSET);
        }
    }
      }
  } catch (Exception ex) {
      logger.log(Level.FINE, "Exception while checking for same containerID", ex);
      throw ex;
  }
  return result;
    }

}
TOP

Related Classes of com.sun.enterprise.iiop.POARemoteReferenceFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.