KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > iiop > POARemoteReferenceFactory


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.iiop;
24
25 import java.rmi.Remote JavaDoc;
26 import java.rmi.RemoteException JavaDoc;
27 import java.net.URL JavaDoc;
28 import java.io.File JavaDoc;
29 import java.util.*;
30 import java.util.logging.*;
31 import java.lang.reflect.Method JavaDoc;
32
33 import javax.rmi.PortableRemoteObject JavaDoc;
34 import javax.rmi.CORBA.*;
35 import javax.transaction.*;
36 import javax.ejb.EJBHome JavaDoc;
37 import javax.ejb.EJBObject JavaDoc;
38 import javax.ejb.NoSuchObjectLocalException JavaDoc;
39 import javax.naming.*;
40
41 import org.omg.CORBA.*;
42 import org.omg.CORBA.portable.Delegate JavaDoc;
43 import org.omg.CosNaming.NamingContext JavaDoc;
44
45 import org.omg.PortableServer.POA JavaDoc ;
46 import org.omg.PortableServer.Servant JavaDoc ;
47 import org.omg.PortableServer.ServantLocator JavaDoc ;
48 import org.omg.PortableServer.ServantLocatorPackage.CookieHolder JavaDoc ;
49
50 import com.sun.logging.LogDomains;
51 import com.sun.enterprise.*;
52 import com.sun.enterprise.deployment.*;
53 import com.sun.enterprise.util.*;
54 import com.sun.enterprise.server.*;
55 import com.sun.enterprise.deployment.runtime.IASEjbExtraDescriptors;
56 import com.sun.ejb.*;
57
58 import com.sun.corba.ee.spi.ior.*;
59 import com.sun.corba.ee.spi.extension.ServantCachingPolicy;
60 import com.sun.corba.ee.spi.extension.ZeroPortPolicy;
61 import com.sun.corba.ee.spi.extension.CopyObjectPolicy;
62 import com.sun.corba.ee.spi.extension.RequestPartitioningPolicy;
63 import com.sun.corba.ee.spi.orbutil.threadpool.ThreadPoolManager;
64 import com.sun.corba.ee.spi.orbutil.threadpool.NoSuchThreadPoolException;
65 import com.sun.corba.ee.spi.presentation.rmi.PresentationManager ;
66 import com.sun.corba.ee.spi.presentation.rmi.DynamicStub;
67 import com.sun.corba.ee.spi.presentation.rmi.StubAdapter;
68 import com.sun.corba.ee.spi.oa.rfm.ReferenceFactory ;
69 import com.sun.corba.ee.spi.oa.rfm.ReferenceFactoryManager ;
70
71 import com.sun.corba.ee.impl.orbutil.ORBConstants;
72 import com.sun.corba.ee.impl.naming.cosnaming.TransientNameService;
73 import com.sun.corba.ee.impl.util.SUNVMCID;
74
75 import com.sun.enterprise.util.Utility;
76 /**
77  * This class implements the RemoteReferenceFactory interface for the
78  * RMI/IIOP ORB with POA (Portable Object Adapter).
79  * There is one instance of the POARemoteReferenceFactory for each
80  * EJB type.
81  *
82  * It also implements the preinvoke/postinvoke APIs in the
83  * POA's ServantLocator interface, which are called before/after
84  * every invocation (local or remote).
85  * It creates a RMI-IIOP-POA object reference (a stub) for every EJBObject
86  * and EJBHome in the EJB container.
87  *
88  * @author Kenneth Saks
89  */

90
91 public final class POARemoteReferenceFactory extends org.omg.CORBA.LocalObject JavaDoc
92             implements RemoteReferenceFactory, ServantLocator JavaDoc
93 {
94     static final int PASS_BY_VALUE_ID = 0;
95     static final int PASS_BY_REFERENCE_ID = 1;
96
97     static final int OTS_POLICY_TYPE = SUNVMCID.value + 123;
98     static final int CSIv2_POLICY_TYPE = SUNVMCID.value + 124;
99     static final int REQUEST_DISPATCH_POLICY_TYPE = SUNVMCID.value + 125;
100     
101     private static final java.util.logging.Logger JavaDoc logger =
102         java.util.logging.Logger.getLogger(LogDomains.CORBA_LOGGER);
103     private static final int GET_TIE_EXCEPTION_CODE = 9999;
104
105     private Container container;
106     private EjbDescriptor ejbDescriptor;
107
108     private ORB orb;
109     private POAProtocolMgr protocolMgr;
110     private PresentationManager presentationMgr;
111
112     private ReferenceFactory ejbHomeReferenceFactory ;
113     private PresentationManager.StubFactory ejbHomeStubFactory;
114     private String JavaDoc ejbHomeRepositoryId;
115
116     private ReferenceFactory ejbObjectReferenceFactory ;
117     private PresentationManager.StubFactory ejbObjectStubFactory;
118     private String JavaDoc ejbObjectRepositoryId;
119
120     private String JavaDoc remoteBusinessIntf;
121     
122     // true if remote home view. false if remote business view.
123
// Used when getting target object for an invocation.
124
private boolean isRemoteHomeView;
125
126     private String JavaDoc poaId_EJBHome;
127     private String JavaDoc poaId_EJBObject;
128
129     // The EJB key format with field-name(size in bytes):
130
// -----------------------------------------
131
// | EJB ID(8) | INSTANCEKEY | INSTANCEKEY |
132
// | | LENGTH(4) | (unknown) |
133
// -----------------------------------------
134
// The following are the offsets for the fields in the EJB key.
135
static final int EJBID_OFFSET = 0;
136     private static final int INSTANCEKEYLEN_OFFSET = 8;
137     private static final int INSTANCEKEY_OFFSET = 12;
138  
139
140
141     POARemoteReferenceFactory(Container container, POAProtocolMgr protocolMgr,
142                   ORB orb, boolean remoteHomeView, String JavaDoc id) {
143     
144     this.protocolMgr = protocolMgr;
145     this.orb = orb;
146         this.poaId_EJBHome = id + "-EJBHome";
147         this.poaId_EJBObject = id + "-EJBObject";
148         this.presentationMgr =
149             ((com.sun.corba.ee.spi.orb.ORB) orb).getPresentationManager();
150     this.container = container;
151     this.ejbDescriptor = container.getEjbDescriptor();
152         this.isRemoteHomeView = remoteHomeView;
153
154     ClassLoader JavaDoc loader = container.getClassLoader();
155
156     // NOTE: ReferenceFactory creation happens in setRepositoryIds.
157

158     if (logger.isLoggable(Level.FINE)) {
159         logger.log(Level.FINE,
160                "POARemoteReferenceFactory:"
161                + " " + poaId_EJBHome
162                + " " + poaId_EJBObject
163                + " " + ejbDescriptor);
164     }
165     }
166
167     private String JavaDoc getRepositoryId(Class JavaDoc c) throws Exception JavaDoc {
168
169         // Using PresentationManager to get repository ID will always work,
170
// independent of whether we have generated static RMI-IIOP stubs.
171

172         PresentationManager.ClassData cData = presentationMgr.getClassData(c);
173         String JavaDoc[] typeIds = cData.getTypeIds();
174
175     if (logger.isLoggable(Level.FINE)) {
176         logger.log(Level.FINE, ".getRepositoryId: " + typeIds[0]);
177     }
178
179         // Repository id is always 1st element in array.
180
return typeIds[0];
181     }
182
183     public void setRepositoryIds(Class JavaDoc homeIntf, Class JavaDoc remoteIntf)
184     {
185
186         ClassLoader JavaDoc appClassLoader = container.getClassLoader();
187
188         PresentationManager.StubFactoryFactory sff =
189             ((com.sun.corba.ee.spi.orb.ORB) orb).getStubFactoryFactory();
190
191         // Home
192
ejbHomeStubFactory =
193             sff.createStubFactory( homeIntf.getName(), false,
194                                    "", null, appClassLoader);
195         String JavaDoc[] ejbHomeTypeIds = ejbHomeStubFactory.getTypeIds();
196         ejbHomeRepositoryId = ejbHomeTypeIds[0];
197
198         ejbObjectStubFactory =
199         sff.createStubFactory( remoteIntf.getName(), false,
200                    "", null, appClassLoader);
201         String JavaDoc[] ejbObjectTypeIds = ejbObjectStubFactory.getTypeIds();
202         ejbObjectRepositoryId = ejbObjectTypeIds[0];
203
204     if (logger.isLoggable(Level.FINE)) {
205         logger.log(Level.FINE,
206                ".setRepositoryIds:"
207                + " " + ejbHomeRepositoryId
208                + " " + ejbObjectRepositoryId);
209     }
210
211     try {
212     
213         ejbHomeReferenceFactory
214         = createReferenceFactory(poaId_EJBHome, ejbHomeRepositoryId);
215         ejbObjectReferenceFactory
216         = createReferenceFactory(poaId_EJBObject, ejbObjectRepositoryId);
217     } catch (Exception JavaDoc e) {
218         throw new RuntimeException JavaDoc(e);
219     }
220
221         if( !isRemoteHomeView ) {
222             remoteBusinessIntf = remoteIntf.getName();
223         }
224             
225     }
226
227     public void cleanupClass(Class JavaDoc clazz) {
228
229         try {
230             presentationMgr.flushClass(clazz);
231         } catch(Exception JavaDoc e) {
232             logger.log(Level.FINE, "cleanupClass error", e);
233         }
234     }
235
236     private ReferenceFactory createReferenceFactory(String JavaDoc poaId, String JavaDoc repoid ) throws Exception JavaDoc {
237       try {
238     if (logger.isLoggable(Level.FINE)) {
239         logger.log(Level.WARNING,
240                ".createReferenceFactory->: " + poaId + " " + repoid);
241     }
242
243     ReferenceFactoryManager rfm =
244         (ReferenceFactoryManager)orb.resolve_initial_references(
245         ORBConstants.REFERENCE_FACTORY_MANAGER ) ;
246
247     List<Policy> policies = new ArrayList<Policy>();
248
249     // Servant caching for local RMI-IIOP invocation performance
250
policies.add(ServantCachingPolicy.getPolicy());
251
252     // OTS Policy
253
policies.add(new OTSPolicy());
254
255     if (logger.isLoggable(Level.FINE)) {
256         logger.log(Level.WARNING,
257                ".createReferenceFactory: " + poaId + " " + repoid
258                + ": " + ejbDescriptor);
259     }
260
261     // CSIv2 Policy
262
policies.add(new CSIv2Policy(ejbDescriptor));
263
264     IASEjbExtraDescriptors extraDesc
265         = ejbDescriptor.getIASEjbExtraDescriptors();
266     String JavaDoc threadPoolName = extraDesc.getUseThreadPoolId();
267     int threadPoolNumericID = 0;
268     boolean usePassByReference = extraDesc.getPassByReference();
269
270     if (usePassByReference) {
271         policies.add(new CopyObjectPolicy(PASS_BY_REFERENCE_ID));
272     }
273
274     if (threadPoolName != null) {
275         ThreadPoolManager threadPoolManager
276         = S1ASThreadPoolManager.getThreadPoolManager();
277         try {
278         threadPoolNumericID = threadPoolManager.getThreadPoolNumericId(
279             threadPoolName);
280         policies.add(new RequestPartitioningPolicy(threadPoolNumericID));
281         } catch (Exception JavaDoc ex) {
282                 logger.log(Level.WARNING, "Not using threadpool-request-partitioning...", ex);
283         }
284     }
285
286     if (logger.isLoggable(Level.FINE)) {
287         String JavaDoc jndiName = ejbDescriptor.getJndiName();
288         logger.log(Level.FINE, "Using Thread-Pool: ["
289         + threadPoolName + " ==> " + threadPoolNumericID
290         + "] for jndi name: " + jndiName);
291         logger.log(Level.FINE, "Pass by reference: ["
292         + usePassByReference
293         + "] for jndi name: " + usePassByReference);
294     }
295
296     // DisableClearTextIIOP policy which sets IIOP Profile port to 0
297
// if EJB allows only SSL invocations
298
CSIV2TaggedComponentInfo ctc = new CSIV2TaggedComponentInfo(orb);
299     Set iorDescSet = ejbDescriptor.getIORConfigurationDescriptors();
300         if ( ctc.allMechanismsRequireSSL(iorDescSet) ) {
301         if (logger.isLoggable(Level.FINE)) {
302         logger.log(Level.WARNING,
303                ".createReferenceFactory: " + poaId + " " + repoid
304                + ": adding ZeroPortPolicy");
305         }
306         policies.add(ZeroPortPolicy.getPolicy());
307         }
308
309     if (logger.isLoggable(Level.FINE)) {
310         logger.log(Level.WARNING,
311                ".createReferenceFactory: " + poaId + " " + repoid
312                + ": policies: " + policies);
313     }
314     ReferenceFactory rf = rfm.create( poaId, repoid, policies, this ) ;
315     return rf ;
316
317       } finally {
318     if (logger.isLoggable(Level.FINE)) {
319         logger.log(Level.WARNING,
320                ".createReferenceFactory<-: " + poaId + " " + repoid);
321     }
322       }
323     }
324
325
326     public java.rmi.Remote JavaDoc createRemoteReference(byte[] instanceKey)
327     {
328     return createRef(instanceKey, ejbObjectReferenceFactory,
329         ejbObjectStubFactory, ejbObjectRepositoryId );
330     }
331
332
333     public EJBHome JavaDoc createHomeReference(byte[] homeKey)
334     {
335     return (EJBHome JavaDoc)createRef(homeKey, ejbHomeReferenceFactory,
336         ejbHomeStubFactory, ejbHomeRepositoryId ) ;
337     }
338
339     private Remote JavaDoc createRef(byte[] instanceKey, ReferenceFactory rf,
340     PresentationManager.StubFactory stubFactory, String JavaDoc repoid )
341     {
342     try {
343         PresentationManager.StubFactory stubFact = stubFactory;
344         org.omg.CORBA.Object JavaDoc ref = _createRef(rf, instanceKey,repoid);
345
346         org.omg.CORBA.Object JavaDoc stub = stubFact.makeStub();
347
348             Delegate JavaDoc delegate = StubAdapter.getDelegate(ref);
349             StubAdapter.setDelegate(stub, delegate);
350
351         return (Remote JavaDoc) stub;
352
353     } catch(Exception JavaDoc e) {
354             logger.log(Level.SEVERE, "iiop.createreference_exception",
355                        e.toString());
356
357         throw new RuntimeException JavaDoc("Unable to create reference ",e);
358     }
359     }
360
361     // NOTE: The repoid is only needed for logging.
362
private org.omg.CORBA.Object JavaDoc _createRef( ReferenceFactory rf,
363     byte[] instanceKey, String JavaDoc repoid ) throws Exception JavaDoc {
364
365         if ( logger.isLoggable(Level.FINE) ) {
366         logger.info("\t\tIn POARemoteReferenceFactory._createRef, " +
367                         "repositoryId = " + repoid);
368         }
369
370          // Create the ejbKey using EJB's unique id + instanceKey
371
byte[] ejbKey = createEJBKey(ejbDescriptor.getUniqueId(),
372                                      instanceKey);
373         
374     org.omg.CORBA.Object JavaDoc obj = rf.createReference( ejbKey ) ;
375
376         return obj;
377     }
378    
379     private byte[] createEJBKey(long ejbId, byte[] instanceKey)
380     {
381     byte[] ejbkey = new byte[INSTANCEKEY_OFFSET+instanceKey.length];
382
383     Utility.longToBytes(ejbId, ejbkey, EJBID_OFFSET);
384     Utility.intToBytes(instanceKey.length, ejbkey, INSTANCEKEYLEN_OFFSET);
385     System.arraycopy(instanceKey, 0, ejbkey, INSTANCEKEY_OFFSET,
386                                 instanceKey.length);
387     return ejbkey;
388     }
389
390
391
392     /**
393      * Disconnect an EJBObject or EJBHome from the ORB.
394      */

395     public void destroyReference(Remote JavaDoc remoteRef, Remote JavaDoc remoteObj)
396     {
397     // Note: the POAs have the NON_RETAIN policy so they dont maintain
398
// any state for objects. We only need to unexport the object from
399
// the RMI/IIOP machinery.
400
// The following call also does tie.deactivate() for the remoteObj's tie
401
try {
402         Util.unexportObject(remoteObj);
403     } catch ( RuntimeException JavaDoc ex ) {
404         // A bug in Util.unexportObject causes this exception
405
// Ignore it.
406
} catch ( java.lang.Exception JavaDoc nsoe ){
407         // eat it and ignore it.
408
}
409     }
410
411
412     /**
413      * This is the implementation of ServantLocator.preinvoke()
414      * It is called from the POA before every remote invocation.
415      * Return a POA Servant (which is the RMI/IIOP Tie for EJBObject/EJBHome).
416      */

417     public Servant JavaDoc preinvoke(byte[] ejbKey, POA JavaDoc adapter, String JavaDoc operation,
418                                 CookieHolder JavaDoc cookieHolder)
419                 throws org.omg.PortableServer.ForwardRequest JavaDoc
420     {
421     if (logger.isLoggable(Level.FINE)) {
422         logger.log(Level.FINE,"In preinvoke for operation:" + operation);
423     }
424
425     // get instance key
426
int keyLen = Utility.bytesToInt(ejbKey, INSTANCEKEYLEN_OFFSET);
427     byte[] instanceKey = new byte[keyLen];
428     System.arraycopy(ejbKey, INSTANCEKEY_OFFSET, instanceKey, 0, keyLen);
429
430         Servant JavaDoc servant = null;
431         try {
432             while ( servant == null ) {
433         // get the EJBObject / EJBHome
434
Remote JavaDoc targetObj =
435                     container.getTargetObject(instanceKey,
436                                               (isRemoteHomeView ? null :
437                                                remoteBusinessIntf));
438
439                 // This could be null in rare cases for sfsbs and entity
440
// beans. It would be preferable to push the retry logic
441
// within the sfsb container and entity container
442
// implementations of getTargetObject, but for now let's keep
443
// the looping logic the same as it has always been.
444
if( targetObj != null ) {
445                     // get the Tie which is the POA Servant
446
Tie tie = presentationMgr.getTie();
447                     tie.setTarget(targetObj);
448                     servant = (Servant JavaDoc) tie;
449                 }
450             }
451         } catch (NoSuchObjectLocalException JavaDoc e) {
452             logger.log(Level.SEVERE,"iiop.gettie_exception", e);
453             throw new OBJECT_NOT_EXIST( GET_TIE_EXCEPTION_CODE,
454                     CompletionStatus.COMPLETED_NO);
455         } catch (RuntimeException JavaDoc e) {
456             logger.log(Level.SEVERE,"iiop.runtime_exception", e);
457         throw e;
458     }
459         return servant;
460     }
461
462     public void postinvoke(byte[] ejbKey, POA JavaDoc adapter, String JavaDoc operation,
463                             java.lang.Object JavaDoc cookie, Servant JavaDoc servant)
464     {
465     Remote JavaDoc target = null;
466     if ( servant != null ) {
467         target = ((Tie)servant).getTarget();
468         }
469         // Always release, since that restores the previous context class
470
// loader.
471
container.releaseTargetObject(target);
472     }
473
474
475     public void destroy() {
476         try {
477
478         ejbHomeReferenceFactory.destroy() ;
479         ejbObjectReferenceFactory.destroy() ;
480         ejbHomeReferenceFactory = null ;
481         ejbObjectReferenceFactory = null ;
482
483             container = null;
484             ejbDescriptor = null;
485
486             orb = null;
487             protocolMgr = null;
488
489         } catch (Throwable JavaDoc th) {
490             logger.log(Level.SEVERE, "Exception during "
491                        + "POARemoteRefFactory::destroy()", th);
492         }
493     }
494
495     public boolean hasSameContainerID(org.omg.CORBA.Object JavaDoc obj)
496     throws Exception JavaDoc
497     {
498     boolean result = false;
499     try {
500         IOR ior = ((com.sun.corba.ee.spi.orb.ORB)orb).getIOR(obj, false);
501         java.util.Iterator JavaDoc iter = ior.iterator();
502
503         byte[] oid = null;
504         if (iter.hasNext()) {
505         TaggedProfile profile = (TaggedProfile) iter.next();
506         ObjectKey objKey = profile.getObjectKey();
507         oid = objKey.getId().getId();
508         }
509
510         if ((oid != null) && (oid.length > INSTANCEKEY_OFFSET)) {
511         long cid = Utility.bytesToLong(oid, EJBID_OFFSET);
512         //To be really sure that is indeed a ref generated
513
// by our container we do the following checks
514
int keyLen = Utility.bytesToInt(oid, INSTANCEKEYLEN_OFFSET);
515         if (oid.length == keyLen + INSTANCEKEY_OFFSET) {
516             result = (cid == ejbDescriptor.getUniqueId());
517         }
518         if (logger.isLoggable(Level.FINE)) {
519             StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc();
520             sbuf.append("hasSameContainerID() result: ").append(result)
521             .append("; because ==> oid.length: ").append(oid.length)
522             .append("; instance-key-length: ").append(keyLen)
523             .append("; expected oid.length: ")
524             .append(keyLen).append("+").append(INSTANCEKEY_OFFSET)
525             .append("; myContainrID: ")
526             .append(ejbDescriptor.getUniqueId())
527             .append("; obj.containerID: ")
528             .append(cid);
529             logger.log(Level.FINE, sbuf.toString());
530         }
531         } else {
532         if (logger.isLoggable(Level.FINE)) {
533             if (oid == null) {
534             logger.log(Level.FINE, "hasSameContainerID() failed because oid=null");
535             } else {
536             logger.log(Level.FINE, "hasSameContainerID() failed because "
537                 + "oid.length= " + oid.length
538                 + "; but INSTANCE_KEY_OFFSET= " + INSTANCEKEY_OFFSET);
539             }
540         }
541         }
542     } catch (Exception JavaDoc ex) {
543         logger.log(Level.FINE, "Exception while checking for same containerID", ex);
544         throw ex;
545     }
546     return result;
547     }
548
549 }
550
Popular Tags