FileDocCategorySizeDatePackage
ConnectorMessageBeanClient.javaAPI DocGlassfish v2 API16403Tue Jul 31 04:33:34 BST 2007com.sun.enterprise.connectors.inflow

ConnectorMessageBeanClient

public final class ConnectorMessageBeanClient extends Object implements javax.resource.spi.endpoint.MessageEndpointFactory, com.sun.ejb.MessageBeanClient
Main helper implementation for message-beans associated with a queue. Uses connection consumer for concurrent message delivery.
author
Qingqing Ouyang

Fields Summary
private static final String
MESSAGE_ENDPOINT
private com.sun.enterprise.connectors.ConnectorRegistry
registry_
private com.sun.ejb.MessageBeanProtocolManager
messageBeanPM_
private final com.sun.enterprise.deployment.EjbMessageBeanDescriptor
descriptor_
private final BasicResourceAllocator
allocator_
private boolean
started_
private final int
CREATED
private final int
BLOCKED
private final int
UNBLOCKED
private int
myState
private final long
WAIT_TIME
private String
beanID_
private static final Logger
logger
Constructors Summary
public ConnectorMessageBeanClient(com.sun.enterprise.deployment.EjbMessageBeanDescriptor descriptor)
Creates an instance of ConnectorMessageBeanClient

param
descriptor EjbMessageBeanDescriptor object.


                   
       
        descriptor_ = descriptor;
        allocator_  = new BasicResourceAllocator(); 
        
        String appName = descriptor.getApplication().getName();
        
        String moduleID = 
            descriptor.getEjbBundleDescriptor().getModuleID();
        
        String beanName = descriptor.getName();
        
        beanID_ = appName + ":" + moduleID + ":" + beanName;

	try {
            registry_ = ConnectorRegistry.getInstance();
        } catch (Exception e) {
        }

    
Methods Summary
public voidclose()
Does endpoint deactivation with the resource adapter. Also remove sthe MessageEndpointFactoryInfo from house keeping.

        logger.logp(Level.FINEST, 
                "ConnectorMessageBeanClient", "close", "called...");
        
        started_ = false; //no longer available 
        
        
        String resourceAdapterMid = getDescriptor().getResourceAdapterMid();
        
        ActiveResourceAdapter activeRar = 
            registry_.getActiveResourceAdapter(resourceAdapterMid);

        if (activeRar instanceof ActiveInboundResourceAdapter) { //in case the RA is already undeployed
            ActiveInboundResourceAdapter rar = 
	       (ActiveInboundResourceAdapter) activeRar;
            MessageEndpointFactoryInfo info = 
                rar.getEndpointFactoryInfo(beanID_);
            
	    if (info != null) {
                rar.getResourceAdapter().endpointDeactivation(
                    info.getEndpointFactory(), info.getActivationSpec());
            
                rar.removeEndpointFactoryInfo(beanID_);
	    } else {
	        logger.log(Level.FINE,"Not de-activating the end point, since it is not activated");
	    }
        }
    
public javax.resource.spi.endpoint.MessageEndpointcreateEndpoint(javax.transaction.xa.XAResource xa)
Creates a MessageEndpoint. This method gets blocked either until start() is called or until one minute. This is the time for completion of MDB deployment. Internally this method creates a message bean listener from the MDB container and a proxy object fo delivering messages.

return
MessageEndpoint object.
throws
UnavailableException In case of any failure. This should change.

        
	// This is a temperory workaround for blocking the the create enpoint
        // until the deployment completes.  One thread would wait for maximum a
        // a minute. 
        synchronized (this) {
	    if (myState == BLOCKED) {
               try {
	           wait(WAIT_TIME); 
	       }catch (Exception e) {
	           // This exception should not affect the functionality.
	       }finally {

		   // Once the first thread comes out of wait, block is 
                   // is removed. This makes sure that the time for which the
	           // the block remains is limited. Max 2x6000.
	           myState = UNBLOCKED;
	       }
            }
        }
        
        if (!started_) {
            logger.log(Level.WARNING, "endpointfactory.unavailable");
            throw new UnavailableException(
                    "EndpointFactory is currently not available");
        }
        
        MessageEndpoint endpoint = null;
        try {
            ResourceHandle resourceHandle = allocator_.createResource(xa);
            
            MessageBeanListener listener = 
                messageBeanPM_.createMessageBeanListener(resourceHandle);

            //Use the MDB's application classloader to load the
            //message listener class.  If it is generic listener
            //class, it is expected to be packaged with the MDB application
            //or in the system classpath.
            String moduleID = getDescriptor().getApplication().getModuleID();
            Class endpointClass = null;
            ClassLoader loader = null;
            try {
		BundleDescriptor moduleDesc = 
			getDescriptor().getEjbBundleDescriptor();
		loader = moduleDesc.getClassLoader();
            }catch(Exception e){
            	logger.log(Level.WARNING, "endpointfactory.loader_not_found",e);
            }

            if (loader == null) {
                loader = Thread.currentThread().getContextClassLoader();
            }

            endpointClass = loader.loadClass(MESSAGE_ENDPOINT);
            

            String msgListenerType = getDescriptor().getMessageListenerType();
            if (msgListenerType == null || "".equals(msgListenerType))
                msgListenerType = "javax.jms.MessageListener";

            Class listenerClass = loader.loadClass(msgListenerType);

            MessageEndpointInvocationHandler handler = 
                new MessageEndpointInvocationHandler(listener, messageBeanPM_);
            endpoint = (MessageEndpoint) Proxy.newProxyInstance
                (loader, new Class[] {endpointClass, listenerClass}, handler);
            
        } catch (Exception ex) {
            throw (UnavailableException) 
                (new UnavailableException()).initCause(ex);
        }
            
        return endpoint;
    
private com.sun.enterprise.deployment.EjbMessageBeanDescriptorgetDescriptor()

        return descriptor_;
    
public booleanisDeliveryTransacted(java.lang.reflect.Method method)
Checks whether the message delivery is transacted for the method.

return
true or false.

        return messageBeanPM_.isDeliveryTransacted(method);
    
public voidsetup(com.sun.ejb.MessageBeanProtocolManager messageBeanPM)
Gets executed as part of message bean deployment. Creates the ActivationSpec javabean and does endpointfactory activation with the resource adapter. This code also converts all J2EE 1.3 MDB properties to MQ resource adapter activation spec properties, if user doesnt specifies resource adapter module name in sun-ejb-jar.xml of the MDB. This is done using com.sun.enterprise.connector.system.ActiveJmsResourceAdapter

param
pm MessageBeanProtocolManager object.

        boolean d = true;

        messageBeanPM_ = messageBeanPM;
        
        String resourceAdapterMid = descriptor_.getResourceAdapterMid();
        ActiveResourceAdapter activeRar = null;
        if (resourceAdapterMid == null) {
            resourceAdapterMid = ConnectorRuntime.DEFAULT_JMS_ADAPTER;
        }
        activeRar = registry_.getActiveResourceAdapter(resourceAdapterMid);
        
        if(activeRar == null && 
              resourceAdapterMid.equals(ConnectorRuntime.DEFAULT_JMS_ADAPTER)) {
            ConnectorRuntime crt = ConnectorRuntime.getRuntime();
            crt.loadDeferredResourceAdapter(resourceAdapterMid);
            activeRar = registry_.getActiveResourceAdapter(resourceAdapterMid);
        }

        if (activeRar == null) {
	    String msg = "Resource adapter "+resourceAdapterMid+ " is not deployed";
	    throw new ConnectorRuntimeException(msg);
        }

        if (activeRar instanceof ActiveJmsResourceAdapter) {
            ActiveJmsResourceAdapter jmsRa = (ActiveJmsResourceAdapter) activeRar;
            jmsRa.updateMDBRuntimeInfo(descriptor_, 
                                       messageBeanPM_.getPoolDescriptor());
        }

        if (!(activeRar instanceof ActiveInboundResourceAdapter)) {
            throw new Exception("Resource Adapter selected doesn't support Inflow");
        } 
        ActiveInboundResourceAdapter rar = (ActiveInboundResourceAdapter) activeRar;

        //the resource adapter this MDB client is deployed to
        ResourceAdapter ra =  rar.getResourceAdapter();
        
        ConnectorDescriptor desc = rar.getDescriptor();
        
        String msgListenerType = getDescriptor().getMessageListenerType();
        if (msgListenerType == null || "".equals(msgListenerType))
          msgListenerType = "javax.jms.MessageListener";

        Iterator i = 
            desc.getInboundResourceAdapter().getMessageListeners().iterator();

        MessageListener msgListener = null;
        while (i.hasNext()) {
            msgListener = (MessageListener) i.next();
            if (msgListenerType.equals(msgListener.getMessageListenerType()))
                break;
        }

        String activationSpecClassName = null;
        if (msgListener != null) {
            activationSpecClassName = msgListener.getActivationSpecClass();
        }

    
        if (activationSpecClassName != null) {
            if (logger.isLoggable(Level.FINEST)) {
                String msg = 
                    "ActivationSpecClassName = " + activationSpecClassName;
                logger.log(Level.FINEST, msg);
            }
            
            try {
                ClassLoader cl = rar.getClassLoader();
                Class aClass = cl.loadClass(activationSpecClassName);
                
                if (logger.isLoggable(Level.FINEST)) {
                    logger.log(Level.FINEST, "classloader = " 
                            + aClass.getClassLoader());
                    logger.log(Level.FINEST, "classloader parent = " 
                            + aClass.getClassLoader().getParent());
                }

                ActivationSpec activationSpec = 
                    (ActivationSpec) aClass.newInstance();
                Set props = RARUtils.getMergedActivationConfigProperties(getDescriptor());

                AccessController.doPrivileged 
                    (new SetMethodAction(activationSpec, props));
                    
                activationSpec.setResourceAdapter(ra);
                
                /*
                  AccessController.doPrivileged(new PrivilegedAction() {
                  public java.lang.Object run() {
                  activationSpec.setResourceAdapter(ra);
                  return null;
                  }
                  });
                */
                
                boolean validate = 
                    "true".equals(System.getProperty("validate.jms.ra"));
                if (validate) {
                    try {
                        activationSpec.validate();
                    } catch (Exception ex) {
                        logger.log(Level.SEVERE, 
                                "endpointfactory.as_validate_Failed", ex);
                    }
                }
                
                myState=BLOCKED;
                ra.endpointActivation(this, activationSpec);
            
                rar.addEndpointFactoryInfo(beanID_, 
                        new MessageEndpointFactoryInfo(this, activationSpec));
	    
                
            } catch (Exception ex) {
		
                ex.printStackTrace();
                throw (Exception) (new Exception()).initCause(ex);
            }
        } else {
            //FIXME  throw some exception here.
            throw new Exception("Unsupported message listener type");
        }
    
public voidstart()
Marks the completion of MDB deployment. Unblocks the createEndPoint method call.

throws
Exception

        logger.logp(Level.FINEST, 
                "ConnectorMessageBeanClient", "start", "called...");
        started_ = true;
	myState=UNBLOCKED;
        synchronized (this) {
	    notifyAll();
        }
    
public java.lang.StringtoString()

return
beanID of the message bean client

        return beanID_;