raframeresourceadaptor.java

来自「RAFrame.基于SEP的资源管理器院码。」· Java 代码 · 共 572 行 · 第 1/2 页

JAVA
572
字号
/*
 * Project: RAFrameRA Resource Adaptor Framework - An example Resource Adaptor
 *          for Mobicents - the open source JAIN SLEE implementation.
 *          See www.mobicents.org for more detailed information on Mobicents.
 *
 * File: RAFrameResourceAdaptor.java
 * Author: Michael Maretzke
 * License: Distributable under LGPL license - see terms of license at gnu.org
 * Created: 2nd August 2005, 15:48
 * Version: 1.0
 */
package com.maretzke.raframe.ra;

import java.io.Serializable;
import java.util.Properties;
import java.util.HashMap;
import javax.naming.NamingException;
import javax.slee.Address;
import javax.slee.AddressPlan;
import javax.slee.UnrecognizedActivityException;
import javax.slee.UnrecognizedEventException;
import javax.slee.facilities.FacilityException;
import javax.slee.resource.ActivityIsEndingException;
import javax.slee.resource.ResourceAdaptorTypeID;
import javax.slee.resource.ResourceException;
import javax.slee.resource.ResourceAdaptor;
import javax.slee.resource.BootstrapContext;
import javax.slee.resource.SleeEndpoint;
import javax.slee.facilities.EventLookupFacility;
import org.apache.log4j.Logger;
import org.mobicents.slee.container.SleeContainer;
import org.mobicents.slee.resource.ResourceAdaptorActivityContextInterfaceFactory;
import org.mobicents.slee.resource.ResourceAdaptorEntity;
import com.maretzke.raframe.message.Message;
import com.maretzke.raframe.message.MessageEvent;
import com.maretzke.raframe.message.MessageParser;
import com.maretzke.raframe.message.RAFMessageParser;
import com.maretzke.raframe.message.MessageFactory;
import com.maretzke.raframe.message.MessageFactoryImpl;
import com.maretzke.raframe.message.IncorrectRequestFormatException;
import com.maretzke.raframe.stack.RAFStack;
import com.maretzke.raframe.stack.RAFStackListener;
import com.maretzke.raframe.ratype.RAFrameActivityContextInterfaceFactory;
import com.maretzke.raframe.ratype.RAFrameResourceAdaptorSbbInterface;
import javax.slee.resource.ActivityHandle;
import javax.slee.resource.FailureReason;
import com.maretzke.raframe.ratype.RAFActivity;

/**
 * RAFrameResourceAdaptor wraps the RAFrameStack and controls its lifecycle according
 * to the lifecycle of a resource adaptor. For more information on the lifecycle of 
 * a resource adaptor, please refer to JSLEE v1.1 Specification Early Draft Review
 * Page 297.
 * <br>
 * The resource adaptor class is referenced in the deployment descriptor file 
 * "resource-adaptor-jar.xml" in the tag <resource-adaptor-classes>, sub-tag
 * <resource-adaptor-class>, sub-tag <resource-adaptor-class-name>:
 * com.maretzke.raframe.ra.RAFrameResourceAdaptor
 * For further Information please refer to JAIN SLEE 1.0 Specification, Final Release 
 * Page 243 and JSLEE v1.1 Specification, Early Draft Review Page 292
 *
 * @author Michael Maretzke
 */
public class RAFrameResourceAdaptor implements RAFStackListener, ResourceAdaptor, Serializable {
    
    private static transient Logger logger = Logger.getLogger(RAFrameResourceAdaptor.class);
    // the local port to listen on - initial default value
    private int port = 40000; 
    // the remote port to send information to - initial default value
    private int remoteport = 40001;
    // the remote host to send information to - initial default value
    private String remotehost = "localhost";
    // the name of the resource adaptor entity - initial default value
    private String stackName = "RAFrameResourceAdaptor";
    // reference to properties for future usage
    private transient Properties properties = null;
    /**
     * The BootstrapContext provides the resource adaptor with the required capabilities in the 
     * SLEE to execute its work. The bootstrap context is implemented by the SLEE. The BootstrapContext 
     * object holds references to a number of objects that are of interest to many resource adaptors.
     * For further information see JSLEE v1.1 Specification, Early Draft Review Page 305.
     * The bootstrapContext will be set in entityCreated() method.
     */
    private transient BootstrapContext bootstrapContext = null;
    /** 
     * The SLEE endpoint defines the contract between the SLEE and the resource adaptor that enables 
     * the resource adaptor to deliver events asynchronously to SLEE endpoints residing in the SLEE. 
     * This contract serves as a generic contract that allows a wide range of resources to be plugged 
     * into a SLEE environment via the resource adaptor architecture.
     * For further information see JSLEE v1.1 Specification, Early Draft Review Page 307
     * The sleeEndpoint will be initialized in entityCreated() method.
     */
    private transient SleeEndpoint sleeEndpoint = null;
    // the EventLookupFacility is used to look up the event id of incoming events
    private transient EventLookupFacility eventLookup = null;
    // reference to the RAFStack - the stack which is controlled and wrapped by this resource adaptor
    private transient RAFStack stack = null;
    // The list of activites stored in this resource adaptor. If this resource adaptor were a distributed
    // and highly available solution, this storage were one of the candidates for distribution.
    private transient HashMap activities = null;
    // the activity context interface factory defined in RAFrameActivityContextInterfaceFactoryImpl
    private transient RAFrameActivityContextInterfaceFactory acif = null;
    // the message factory to create Message and MessageEvent objects
    private transient MessageFactory messageFactory = null;
    // a link to the RAFrameProvider which then will be exposed to Sbbs
    private transient RAFrameResourceAdaptorSbbInterface raProvider = null;
    // the message parser to validate incoming protocol messages
    private transient MessageParser messageParser;
       
    /** 
     * Constructor which accepts a Property object for further configuration of the resource adaptor.
     * The following properties have a meaning:
     * com.maretzke.raframe.stack.PORT sets the local port to listen on (serverport) (int)
     * com.maretzke.raframe.stack.REMOTEPORT sets the remote port to which information is send to (int)
     * com.maretzke.raframe.stack.REMOTEHOST is the remote computers' name to send information to (String)
     * com.maretzke.raframe.stack.STACK_NAME is the stack's name (String)
     *
     * @param properties a Property object containing further information to configure the resource adaptor
     */
    public RAFrameResourceAdaptor(Properties properties) {
        this.properties = properties;
        this.port = Integer.parseInt(properties.getProperty("com.maretzke.raframe.stack.PORT"));
        this.remoteport = Integer.parseInt(properties.getProperty("com.maretzke.raframe.stack.REMOTEPORT"));
        this.remotehost = properties.getProperty("com.maretzke.raframe.stack.REMOTEHOST");
        this.stackName = properties.getProperty("com.maretzke.raframe.stack.STACK_NAME");
        logger.debug("RAFrameResourceAdaptor(" + properties + ") called.");
    }
    
    /**
     * Constructor with the following parameters:
     * 
     * @param stackName sets the name of the stack
     * @param port sets the local port to listen on (serversocket)
     * @param remotehost sets the remote computers' name to which information should be send
     * @param remoteport sets the remote computers' port to which information should be send
     */
    public RAFrameResourceAdaptor(String stackName, int port, String remotehost, int remoteport) {
        this.port = port;
        this.remotehost = remotehost;
        this.remoteport = remoteport; 
        this.stackName = stackName;
        logger.debug("RAFrameResourceAdaptor(" + stackName + ", " + port + ", " + remotehost + ", " + remoteport + ") called.");
    }
    
    /**
     * Creates a new instance of RAFrameResourceAdaptor and leaves the default values for the 
     * resource adaptor configuration untouched. The default configuration looks like:
     * the local port to listen on - initial default value: 40000
     * the remote port to send information to - initial default value: 40001
     * the remote host to send information to - initial default value: localhost
     * the name of the resource adaptor entity - initial default value: RAFrameResourceAdaptor
     */
    public RAFrameResourceAdaptor() {
        logger.debug("RAFrameResourceAdaptor() called.");
    }
    
    /**
     * implements com.maretzke.raframe.stack.RAFStackListener
     * This method is invoked by the underlying RAFStack whenever incoming data is received.
     */
    public void onEvent(String incomingData) {
        MessageEvent event;
        Address address;
        int eventID;
        
        logger.debug("Incoming request: " + incomingData);
        
        // parse the incoming data
        try {
            Message message = messageParser.parse(incomingData);
            event = messageFactory.createMessageEvent(this, message);
        }
        catch (IncorrectRequestFormatException irfe) {
            // Unfortunately, the incoming messsage does not comply with the protocol / message 
            // format rules. The message is discarded.
            logger.debug("Incoming request: " + incomingData + " does not follow the defined message rules (ID COMMAND). Dropping the event.");
            return;
        }
        
        // generate the activity handle which uniquely identifies the appropriate activity context
        RAFActivityHandle handle = new RAFActivityHandle(event.getMessage().getId());
        // lookup the activity
        RAFActivity activity = (RAFActivity) activities.get(handle);
        
        // activity does not exist - let's create one
        if (activity == null) {
            activity = new RAFActivityImpl();
            activities.put(handle, activity);
        }
        
        if (!activity.isValid(event.getMessage().getCommandId())) {
            logger.debug("Not a valid command. Command corrupts rules defined for the protocol.");
            return;
        }       
        
        // the fireEvent() method needs a default address to where the events should be fired to
        address = new Address(AddressPlan.IP, "127.0.0.1");
                
        // get the eventID from the JNDI tree
        try {
            eventID = eventLookup.getEventID("com.maretzke.raframe.message.incoming." + event.getMessage().getCommand().toUpperCase(), "maretzke", "1.0");
        } 
        catch (FacilityException fe) {
            logger.error("Caught a FacilityException: ");
            fe.printStackTrace();
            throw new RuntimeException("RAFrameResourceAdapter.onEvent(): FacilityException caught. ", fe);
        } 
        catch (UnrecognizedEventException uee) {
            logger.error("Caught an UnrecognizedEventException: ");
            uee.printStackTrace();
            throw new RuntimeException("RAFrameResourceAdaptor.onEvent(): UnrecognizedEventException caught.", uee);
        }
        
        if (eventID == -1) {
            // Silently drop the message because this is not a registered event type.
            logger.debug("RAFrameResourceAdaptor.onEvent(): Event lookup -- could not find event mapping -- check xml/slee-events.xml");
            return;
        }
        
        try {
            if (event.getMessage().getCommand().toLowerCase().compareTo("end") == 0) {
                // if the command is an end command, the connected activity needs to end
                // this is signalled to the SLEE via activityEnding()
                logger.debug("RAFrameResourceAdaptor.onEvent(): RAFrameRA signals ending activity to SLEE. EventID: " + eventID + "; CallID:  " + event.getMessage().getId() + "; Command: " + event.getMessage().getCommand());
                sleeEndpoint.activityEnding(new RAFActivityHandle(event.getMessage().getId()));
            }
            else {
                // fire the event into the SLEE and proceed
                logger.debug("RAFrameResourceAdaptor.onEvent(): RAFrameRA fires event into SLEE. EventID: " + eventID + "; CallID:  " + event.getMessage().getId() + "; Command: " + event.getMessage().getCommand());
                sleeEndpoint.fireEvent(new RAFActivityHandle(event.getMessage().getId()), (Object) event, eventID, address);
            }                        
        } 
        catch (IllegalStateException ise) {
            logger.error("Caught an IllegalStateException: ");
            ise.printStackTrace();
        } 
        catch (ActivityIsEndingException aiee) {
            logger.error("Caught an ActivityIsEndingException: ");
            aiee.printStackTrace();
        } 
        catch (UnrecognizedActivityException uaee) {
            logger.error("Caught an UnrecognizedActivityException: ");            
            uaee.printStackTrace();
        }
    }
 
    
    /**
     * implements javax.slee.resource.ResourceAdaptor
     * Please refer to JSLEE v1.1 Specification, Early Draft Review Page 298 for further information.
     * <br>
     * This method is called by the SLEE when a resource adaptor object instance is bootstrapped, either when a
     * resource adaptor entity is created or during SLEE startup. The SLEE implementation will construct the 
     * resource adaptor object and then invoke the entityCreated method before any other operations can be invoked
     * on the resource adaptor object.
     */
    public void entityCreated(BootstrapContext bootstrapContext) throws ResourceException {
        logger.debug("RAFrameResourceAdaptor.entityCreated() called.");
        this.bootstrapContext = bootstrapContext;
        this.sleeEndpoint = bootstrapContext.getSleeEndpoint();
        this.eventLookup = bootstrapContext.getEventLookupFacility();
        
        stack = null;
    }
    
    /**
     * implements javax.slee.resource.ResourceAdaptor
     * Please refer to JSLEE v1.1 Specification, Early Draft Review Page 299 for further information.
     * <br>
     * This method is called by the SLEE when a resource adaptor object instance is being removed, either when a
     * resource adaptor entity is deleted or during SLEE shutdown. When receiving this invocation the resource
     * adaptor object is expected to close any system resources it has allocated.
     */
    public void entityRemoved() {
        logger.debug("RAFrameResourceAdaptor.entityRemoved() called.");
    }

    /**
     * implements javax.slee.resource.ResourceAdaptor    
     * Please refer to JSLEE v1.1 Specification, Early Draft Review Page 300 for further information.
     * <br>
     * The SLEE calls this method to inform the resource adaptor object that the specified event was processed
     * successfully by the SLEE. An event is considered to be processed successfully if the SLEE has attempted
     * to deliver the event to all interested SBBs.
     */
    public void eventProcessingSuccessful(ActivityHandle activityHandle, Object obj, int param, Address address, int flags) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?