next up previous contents
Next: C Listing der IDL-Schnittstelle Up: No Title Previous: A Listing der IDL-Schnittstelle

B Listing des ASManagementAgenten

package __MASA_PACKAGE_thisagent;

import __MASA_PACKAGE_agentSystem__(*);
import __MASA_PACKAGE_agent__(*);
import __MASA_PACKAGE_CfMAF__(*);
import __MASA_PACKAGE__(tools.NameWrapper);
import __MASA_PACKAGE__(tools.Debug);
import __MASA_PACKAGE__(tools.GlobalConstants);

import java.io.*;
import java.util.*;

import org.omg.CosEventComm.*;
import org.omg.CosEventChannelAdmin.*;
import org.omg.CosNaming.*;


/**
 * This is the class defining the ASManagementAgent.
 * <br>The ASManagementAgent is a stationary agent which primary task it is to provide methods
 * that allow applets to communicate with objects and CORBA services. In particular these are 
 * other agent systems, the CORBA Name Service and the CORBA Event Service, which are often not located
 * on the same machines as the applets. The ASManagementAgent therefore acts as a proxy for these applets.
 *
 *      @see StationaryAgent
 *      @author Stefan Gerber
 */

public class ASManagementAgentStationaryAgent extends StationaryAgent
    implements ASManagementAgentOperations {

    private org.omg.CosNaming.NamingContext agent_context; // CORBA naming context for agents
    private ThreadEventListener eventlistener = null;      //thread listening for CORBA events
    private Vector pushConsumerVector = new Vector(0,1);   //vector containing the pushConsumers that the applets register with the ASManagementAgent
    private int id_incr = 0;                               //used to determine the IDs for the applet-pushConsumers
    private Thread el_thread = null;  //thread that will run the ThreadEventListener



    public ASManagementAgentStationaryAgent() {
        super();
        //get_agent_context();  //doesn't work here, because _initContext = null at this moment
    }

    public void cleanUp() throws Throwable {
        System.err.println("ASManagementAgentMobileAgent.cleanUp()");
        el_thread.stop();  //stop the eventlistener thread
    }

    public void checkSerialization() 
        throws CouldNotMigrate {

    }

    /**
     * Calls methods to fetch the naming contexts of agents/agent systems and starts the EventListener thread.
     * <br>This method is called, when the agent is started.
     */

    public void run() {
        get_agent_context();
        //Start the Thread that listens for CORBA events
        eventlistener = new ThreadEventListener(_initContext);
        el_thread = new Thread(eventlistener);
        el_thread.start();
    }


    /**
     * Fetches the naming context containing the agents of the different agent systems.
     * <br>The naming context is saved into agent_context. This method is only for internal use.
     */

    void get_agent_context() {
        //get context of agents
        try {
            NameComponent comp1 = new NameComponent("Agent", "");
            NameComponent name[] = {comp1};
            agent_context = NamingContextHelper.narrow(_initContext.resolve(name));
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("\nfailed :" + e.toString());    
        }
        
    }


    /**
     * Registers a "clientīs" PushConsumer.
     * <br>Clients (e.g. applets), which want to use the ASManagementAgent as CORBA event service proxy,
     * call this method once to register their PushConsumers. An id number is returned to each client. This
     * number is used by clients to deregister their PushConsumers with disconnect_push_consumer().
     *
     * @param pushConsumer PushConsumer thatīs to be registered
     * @return ID number of type int
     */

    public int connect_push_consumer(org.omg.CosEventComm.PushConsumer pushConsumer) {
        //add the new pushConsumer and it's id to the global vector
        VectorElement ve = new VectorElement(pushConsumer, id_incr);
        pushConsumerVector.addElement(ve);

        System.err.println("\nconnect_push_consumer: pushConsumer added");
        System.err.println("connect_push_consumer: Now "+pushConsumerVector.size()+" PushConsumers registered");
        return id_incr++;  //return id for this new pushConsumer and increment id_incr afterwards
    }
    

    /**
     * Deregisters a "clientīs" PushConsumer.
     * <br>This method is invoked by clients (e.g. applets) that want to disconnect their PushConsumers from
     * the ASManagementAgent. The PushConsumer with the ID number "id" is removed from the global vector
     * containing all registered PushConsumers. If the client is an applet then its destroy()-method is
     * a good place to invoke this method from.
     *
     * @param id ID of PushConsumer to be deregistered
     */

    public void disconnect_push_consumer(int id) {
        int size = pushConsumerVector.size();  // get size of vector
        for (int i=0; i<size; i++) {
            VectorElement ve = (VectorElement) pushConsumerVector.elementAt(i); //get element at index i
            if (ve.id == id) {
                //if id has been found remove the vector element
                pushConsumerVector.removeElementAt(i);
                System.err.println("\n\nASManagementAgent: pushConsumer (id="+id+") removed");
                return;
            }
        }
        System.err.println("\n\nASManagementAgent: pushConsumer to remove has not been found");
    }


    /**
     * Returns a String[] containing a list of the names of the currently active agent systems.
     * <br>This list is determined using the NamingContext object agent_context, which also 
     * contains the name space "global". "global" lists all agents that have been started with
     * the option "exclusive". For further information consult the MASA manual.
     *
     * @return String[] containing the names of active agent systems
     */

    public String[] identify_agentsystems() {
        //get the naming context from the CORBA name service
        //get_agent_context();

        //get names of Agent Systems
        BindingListHolder bl_holder = new BindingListHolder();
        BindingIteratorHolder bi_holder = new BindingIteratorHolder();
        agent_context.list(1000000, bl_holder, bi_holder);
        Binding[] AS_bindings = bl_holder.value;
        String as_names[] = new String[AS_bindings.length];

        //copy the names separated by spaces into the String as_names
        for (int i=0; i<AS_bindings.length; i++) {
            as_names[i] = (String) AS_bindings[i].binding_name[AS_bindings[i].binding_name.length-1].id;
        }
        return as_names;        
    }


    /**
     * Returns a String array containing the parameter data types of all constructors of an agent.
     * <br>agent_name, agent_package and agent_type specify the class of the agent. The method finds
     * out all constructors of the agent and copies the set of parameters for each constructor into
     * a String array which is then returned.
     *
     * @param agent_name name of the agent
     * @param agent_package package containing the class of the agent
     * @param agent_type type of the agent (MobileAgent or StationaryAgent)
     * @return String array containing the parameter sets
     */

    public String[] get_agent_parameters(String agent_name, String agent_package, String agent_type) {
        String parametersets[] = new String[1]; //array to contain the parameter sets
        try {
            //get class of selected agent
            String code_base = System.getProperty( GlobalConstants.masa_property_prefix+"agentCodeBase");

            //get class of specified agent
            //Class agent_class = java.rmi.server.RMIClassLoader.loadClass(new java.net.URL(code_base), agent_package + "." + agent_name + agent_type);
                Class agent_class = AgentSystemClassLoader.loadClass( new java.net.URL( code_base), agent_package + "." + agent_name + agent_type);
            
            //get constructors of the agent
            java.lang.reflect.Constructor constructors[] = agent_class.getConstructors();

            //get types of parameters for each constructor
            int nr_of_parametersets = constructors.length;
            parametersets = new String[nr_of_parametersets]; //nr_of_parametersets is always at least 1
            for (int i=0; i<nr_of_parametersets; i++) {
                Class parameter_types[] = constructors[i].getParameterTypes();
                //create parameter set for one constructor (constructor[i])
                parametersets[i] = " "; //prevent null-Strings in parametersets[], otherwise marshalling-exceptions are generated
                    for (int j=0; j<parameter_types.length; j++) {
                        parametersets[i] += parameter_types[j].getName() + " ";
                    }
            }
        } catch (Exception e1) {
            if (e1 instanceof java.lang.ClassNotFoundException)
                parametersets[0] = "failed";
            else {
                parametersets[0] = "failed";
                e1.printStackTrace();
            }
        }
        return parametersets;
    }


    /**
     * Defines a thread that creates a PushConsumer and connects it to the CORBA event service.
     * <br>The method used is the so called "Push method".
     */

    class ThreadEventListener implements Runnable {
        org.omg.CosNaming.NamingContext initContext = null;

        ThreadEventListener(org.omg.CosNaming.NamingContext context) {
            initContext = context;
        }
        
        public void run() {
            try {
                // get event channel
                String channelName = System.getProperty( GlobalConstants.masa_property_prefix+"agent.channel", "AgentInitChannel");
                org.omg.CosNaming.NameComponent ch = new org.omg.CosNaming.NameComponent(channelName,"");
                org.omg.CosNaming.NameComponent[] arr_ch = new org.omg.CosNaming.NameComponent[1];
                arr_ch[0] = ch;
                org.omg.CosEventChannelAdmin.EventChannel eventChannel =
                    org.omg.CosEventChannelAdmin.EventChannelHelper.narrow(initContext.resolve(arr_ch));
                
#ifdef VISIBROKER30
                // Initialize the ORB.
                org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init();
                // Initialize the BOA.
                org.omg.CORBA.BOA boa = orb.BOA_init();
#endif
#ifdef ORBACUS311
                // Initialize the ORB.
                org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init( new String[0], new java.util.Properties());
                // Initialize the BOA.
            org.omg.CORBA.BOA boa= ((com.ooc.CORBA.ORB)orb).BOA_init( new String[0], new java.util.Properties());
#endif
                                
                
                // create PushConsumer
                PushConsumerImpl pushConsumer = new PushConsumerImpl();
#ifdef VISIBROKER30
                boa.obj_is_ready(pushConsumer);  //Export the newly created object
#endif
#ifdef ORBACUS311
                boa.obj_is_ready(pushConsumer, null);  //Export the newly created object
#endif
                
                //get ProxyPushSupplier from the CORBA event service
                org.omg.CosEventChannelAdmin.ProxyPushSupplier pushSupplier = eventChannel.for_consumers().obtain_push_supplier();
                //connect the PushConsumer to the ProxyPushSupplier
                pushSupplier.connect_push_consumer(pushConsumer);

                //wait for events
#ifdef VISIBROKER30
                boa.impl_is_ready();
#endif
#ifdef ORBACUS311
                boa.impl_is_ready( null);
#endif

            } catch (Exception el) {
                el.printStackTrace();
            }
        }
    }


    /**
     * Defines the behaviour of the ASManagementAgentīs PushConsumer.
     * <br>Apart from the PushConsumers that clients can register with the ASManagementAgent, this agent
     * has also its own PushConsumer. This one is connected directly to the CORBA event service using the 
     * "Push model". Whenever a CORBA event occurs the push() method of the PushConsumer is executed. In
     * this push() method the push() methods of all the PushConsumers that clients connected to the 
     * ASManagementAgent are called one after another. This way the CORBA event is forwarded to the clients
     * that cannot directly contact the CORBA event service.
     */

    class PushConsumerImpl extends _PushConsumerImplBase {
        
        public PushConsumerImpl() 
        {
            System.err.println("\n\nASManagementAgent: PushConsumer erstellt");
        }

        public void push(org.omg.CORBA.Any any) 
        {
            int nopc = pushConsumerVector.size();  //get the number of pushConsumers
            org.omg.CosEventComm.PushConsumer tmpPushConsumer = null;
            VectorElement ve = null;
            for (int i=0; i<nopc; i++) {
                try {
                    ve = (VectorElement) pushConsumerVector.elementAt(i);
                    System.err.println("\nASManagementAgent: executing push() for pushConsumer #"+ve.id);
                    tmpPushConsumer = ve.pushConsumer;
                    tmpPushConsumer.push(any);
                } catch (Exception e) {
                    System.err.println("\n\nASManagementagent: push() failed!");
                    if(e instanceof org.omg.CORBA.COMM_FAILURE) { //no communication possible
                        System.err.println("\n\nASManagementAgent: removing pushConsumer #"+ve.id);
                        pushConsumerVector.removeElement(ve);
                    }
                    e.printStackTrace();
                }
            }
        }

        public void disconnect_push_consumer() {
            try {
#ifdef VISIBROKER30
                // Initialize the ORB.
                org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init();
                // Initialize the BOA.
                org.omg.CORBA.BOA boa = orb.BOA_init();
#endif
#ifdef ORBACUS311
                // Initialize the ORB.
                org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init( new String[0], new java.util.Properties());
                // Initialize the BOA.
            org.omg.CORBA.BOA boa= ((com.ooc.CORBA.ORB)orb).BOA_init( new String[0], new java.util.Properties());
#endif

                System.err.println("\n\nDisconnecting push_consumer...\n");
            }
            catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }


    /**
     * Datatype for use in pushConsumerVector.
     * <br>This data type is used as a wrapper for the PushConsumers that clients connect to the
     * ASManagementAgent. It contains the PushConsumer itself and the ID number that is assigned
     * to it by connect_push_consumer().
     */

    class VectorElement {
        public org.omg.CosEventComm.PushConsumer pushConsumer = null;
        public int id = 0;

        //Constructor
        public VectorElement(org.omg.CosEventComm.PushConsumer _pushConsumer, int _id) {
            pushConsumer = _pushConsumer;
            id = _id;
        }
    }
}



Copyright Munich Network Management Team