package de.unimuenchen.informatik.mnm.masa.agent.voyagermasagateway; // MASA import de.unimuenchen.informatik.mnm.masa.agentSystem.voyagerintegration.*; import de.unimuenchen.informatik.mnm.masa.agentSystem.*; import de.unimuenchen.informatik.mnm.masa.agent.*; import CfMAF.*; import de.unimuenchen.informatik.mnm.masa.tools.*; // Voyager import com.objectspace.voyager.*; // VisiBroker import org.omg.CosNaming.*; // JDK import java.lang.reflect.*; import java.net.*; import java.util.*; /** * Gateway between Voyager-Agentsystem and MASA-Agentsystem. * Creates and registers a VoyagerAgentManager at startup at the MASA-System * and forwards messages to the MASA-System to create, migrate and terminate * Voyager-Agents. * Starts the NamingGateway and receives messages from it about * created or terminated agents * Accepts messages from the VoyagerNamingGateway about created or terminated * Voyager-Agents. */ public class VoyagerMasaGatewayStationaryAgent extends StationaryAgent implements VoyagerMasaGatewayOperations { /** * CfMAF.Type of the Voyager-Agentsystem */ private Short VOYAGER_TYPE = new Short (System.getProperty("de.unimuenchen.informatik.mnm.masa.voyager.type","5")); /** * VoyagerAgentManager, registered at MASA AgentSystem */ private VoyagerAgentManager _voyagerAgentManager; /** * Voyager agents created by myself, * the message agents_created/agents_terminated * about this agents will be ignorred */ private Vector _agentsCreatedByApplet = new Vector(); private Vector _agentsTerminatedByApplet = new Vector(); /** * Voyager server */ private String [] _voyagerServer; /** * Thread of the NamingGateway */ private Thread _namingGatewayThread; /** * Constructor, initialize ?voyagerServer by exntending hostnames with full domainname */ public VoyagerMasaGatewayStationaryAgent(){ // get voyager server StringTokenizer server = new StringTokenizer(System.getProperty("de.unimuenchen.informatik.mnm.masa.voyager.server","sunhegering10:8000,sunhegering2:8000"),","); _voyagerServer = new String [server.countTokens()]; for(int i=0; i<_voyagerServer.length && server.hasMoreTokens(); i++){ String vserv = server.nextToken(); // expand name to fulll domain try{ // get Internet address InetAddress iAddress = InetAddress.getByName(vserv.substring(0,vserv.indexOf(":"))); // get ip number String ip = iAddress.getHostAddress(); // build new internet address with full domain out of ip number String fullAddress = InetAddress.getByName(ip).toString(); _voyagerServer[i] = "//" + fullAddress.substring(0,fullAddress.indexOf("/")); _voyagerServer[i] += vserv.substring(vserv.indexOf(":"),vserv.length()); } catch(UnknownHostException unknownHost){ unknownHost.printStackTrace(); Debug.debug("VoyagerMasaGatewayStationaryAgent.<init> - " + vserv.substring(0,vserv.indexOf(":")-1)); _voyagerServer[i] = ""; } Debug.debug("VoyagerMasaGatewayStationaryAgent.<init> - voyagerServer: " + _voyagerServer[i]); } } /** * Stops voyager client via in _voyagerAgentManager and unbinds voyager namingcontext * @see Agent.cleanUp */ public void cleanUp() { Debug.debug("VoyagerMasaGatewayStationaryAgent.cleanUp()"); try{ // terminate voyager prox agents _voyagerAgentManager.cleanUp(); // unbind voyager namingcontext in masa NameComponent [] path_voyager = new NameComponent [] { new NameComponent("Agent",""), new NameComponent("voyager", "")}; _initContext.unbind(path_voyager); } catch (Exception e){ e.printStackTrace(); } } /** * @see Agent.checkSerialization */ public void checkSerialization() throws CouldNotMigrate { Debug.debug("VoyagerMasaGatewayStationaryAgent.checkSerialization()"); } /** * Starts the NamingGateway and registers VozagerAgentManager at AgentSystemService, * i.e. sends the message registerAgentManager to AgentSystemService * * @see Agent.run */ public void run() { Debug.debug("\n\n\nVoyagerMasaGatewayStationaryAgent.run()\n\n\n"); // Test whether global if (!_isGlobal){ try{ Debug.debug("\n\n\nVoyagerMasaGatewayStationaryAgent must be started global/exclusive\n\n\n"); // getAgentManager().terminate_agent(getAgentName()); setAgentStatus(CfMAF.AgentStatus._CfMAFSuspended); }catch(Exception e){ e.printStackTrace(); } return; } // create namingcontext in masa for voyager NamingContext voyagerContext = null; try{ NameComponent [] path_voyager = new NameComponent [] { new NameComponent("Agent",""), new NameComponent("voyager", "")}; voyagerContext = _initContext.bind_new_context(path_voyager); } catch (org.omg.CosNaming.NamingContextPackage.AlreadyBound alreadyBoundException){ // voyager context already bound System.err.println("VoyagerMasaGatewayStationaryAgent.run(): WARNING: voyager-NamingContext already bound to masa-NamingContext!"); // get voyager naming-context NameComponent name_voyager = new NameComponent("voyager", ""); NameComponent path_voyager[] = {name_voyager}; try{ voyagerContext = NamingContextHelper.narrow(_initContext.resolve(path_voyager)); } catch (Exception e){ e.printStackTrace(); } } catch (Exception e){ e.printStackTrace(); } // create AgentManager _voyagerAgentManager = new VoyagerAgentManager(_agentManager.getAgentSystemService(), voyagerContext, _ownAgentContext); // create Information about it CfMAF.Name name = new Name(); name.agent_system_type = VOYAGER_TYPE.shortValue(); // get CORBA - object reference of myself org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(); orb.connect(_voyagerAgentManager); // Register Voyager-AS in Masa AgentSystem for redirection of create, // terminate, etc. invocation _agentManager.getAgentSystemService().registerAgentManager(name,_voyagerAgentManager); Debug.debug("\n\n\nVoyagerAgentManager registered.\n\n\n"); // create and start NamingGateway _namingGatewayThread = new Thread(new Runnable () { /** * Implementation of the _namingGatewayThread */ public void run(){ try{ NamingGateway.main(_voyagerServer); }catch(Exception namingGatewayEsception){ namingGatewayEsception.printStackTrace(); } } }); try{ _namingGatewayThread.start(); }catch(Exception e){ e.printStackTrace(); } } /** * This method is called by the NamingGateway, * if Voyager agents are terminated. It terminates then the * VoyagerProxyAgents according to the terminated Voyager agents * * @param agent_names Names of the terminated Voyager agents * */ public void agents_terminated(String[] agent_names){ Debug.debug("VoyagerMasaGatewayStationaryAgent.agents_terminated()"); try{ for (int i=0; i<agent_names.length; i++) if (_agentsTerminatedByApplet.contains(agent_names[i])) // check whether agent terminated by applet _agentsTerminatedByApplet.removeElement(agent_names[i]); else _voyagerAgentManager.terminate_voyagerproxyagent(agent_names[i]); } catch(Exception e){ e.printStackTrace(); } } /** * This method is called by the NamingGateway, * if new Voyager agents are created. It creates then a * VoyagerProxyAgent for the created Voyager agents * * @param agent_names Names of the new created Voyager agents * */ public void agents_created(String[] agent_names, String place_name){ Debug.debug("VoyagerMasaGatewayStationaryAgent.agents_created()"); try{ for (int i=0; i<agent_names.length; i++) // check whether agent not created by applet and proxy already created if(_agentsCreatedByApplet.contains(agent_names[i])){ Debug.debug("VoyagerMasaGatewaySationaryAgent.agents_created() - contains " + agent_names[i]); _agentsCreatedByApplet.removeElement(agent_names[i]); } else _voyagerAgentManager.create_voyagerproxyagent(agent_names[i],place_name); } catch(Exception e){ e.printStackTrace(); } } /** * This method is called by the VoyagerMasaGatewayApplet to create an Voyager agent * It creates the necessary parameters and calls the create_agent()-Method of the * AgentSystemService * * @param agentname Name of the agent * @param classname Java-Classname of the agent * @param packagename Java-Packagename of the agentclass * @param place_name Voyager server on which the agent should be created, f.e. //hostname:portnumber * */ public String create_agent(String agentname, String classname, String packagename, String place_name) throws CfMAF.ArgumentInvalid, CfMAF.MAFExtendedException{ Debug.debug("VoyagerMasaGateway create_agent " + classname); // check whether classname different from agentname CfMAF.ClassName className[]; if(classname.length() != 0) className= new CfMAF.ClassName[] {new CfMAF.ClassName(classname,new byte[0])}; else className = new CfMAF.ClassName[0]; // create the parameters for the create_agent() call java.io.ByteArrayOutputStream agentBytes; NameWrapper nw; CfMAF.AgentProfile ap; java.io.ByteArrayOutputStream constructorArgs; try{ agentBytes = new java.io.ByteArrayOutputStream(); java.io.ObjectOutputStream outputAgent = new java.io.ObjectOutputStream(agentBytes); outputAgent.writeObject(packagename); // set type for voyager agent system nw = new NameWrapper(agentname); nw._name.agent_system_type = VOYAGER_TYPE.shortValue(); // create the profile of the agent // not supported, just dummy ap = new CfMAF.AgentProfile(); org.omg.CORBA.Any props[] = new org.omg.CORBA.Any[1]; org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(); org.omg.CORBA.Any any = orb.create_any(); any.insert_wstring("Property"); props[0]=any; ap.language_id=1; ap.serialization=1; ap.properties= props; ap.agent_system_description= "Agent System of MNM-Team"; constructorArgs = new java.io.ByteArrayOutputStream(); java.io.ObjectOutputStream constructorObject = new java.io.ObjectOutputStream(constructorArgs); }catch(Exception argumentException){ argumentException.printStackTrace(); throw new CfMAF.ArgumentInvalid(); } Debug.debug("\n\nVoyagerMasaGateway.create_agent() - place_name: " + place_name + "\n\n"); // create the agent CfMAF.Name res = null; try{ res = getAgentSystemService().create_agent(nw._name, ap, agentBytes.toByteArray(), place_name, constructorArgs.toByteArray(), className, "", getAgentSystemService()); // save agentname as agent created by the applet Debug.debug("VoyagerMasaGateway.create_agent() - save agent name as agent created by applet: " + new String(res.identity)); _agentsCreatedByApplet.addElement(new String(res.identity)); }catch(Exception createException){ createException.printStackTrace(); throw new CfMAF.MAFExtendedException(); } return new String(res.identity); } /** * Terminates a Voyager agent by calling terminate_agent of the AgentSystemService */ public void terminate_agent(String agent_name) throws CfMAF.TerminateFailed, CfMAF.AgentNotFound{ Debug.debug("VoyagerMasaGateway.terminate_agent() - agentname: " + agent_name); // masa system call: terminate_agent NameWrapper nw = new NameWrapper(agent_name); nw._name.agent_system_type = VOYAGER_TYPE.shortValue(); getAgentSystemService().terminate_agent(nw._name); // save agentname as agent terminated by the applet _agentsTerminatedByApplet.addElement(agent_name); } /** * migrates an agent ot the specified target and executes the method there * * @param agent_name Name of the Agent to migrate * @param target Vozager server to which agent to be migrated * @param execute Method which will be excuted after migration * @param arguments List of arguments that are used by method, e.g. "java.lang.String Hello World!,java.lang.Integer 1" */ public void migrate_agent(String agent_name, String target, String execute, String arguments) throws CfMAF.ArgumentInvalid, CfMAF.MAFExtendedException { Debug.debug("VoyagerMasaGateway.migrate_agent() - agentname: " + agent_name); // build arguments StringTokenizer declarations = new StringTokenizer(arguments,","); // pairs of type and value Object [] args = new Object[declarations.countTokens()]; int i=0; while(declarations.hasMoreTokens()){ String decl = declarations.nextToken(); // get type String type = decl.substring(0,decl.indexOf(" ")); // get value String value = decl.substring(decl.indexOf(" ")+1,decl.length()); Debug.debug("VoyagerMasaGateway.migrate_agent() - arguments: type: " + type + " value: " + value); // instantiate class of type with value, // class must have a constructor, // accepting string as argument try{ Debug.debug("VoyagerMasaGateway.migrate_agent() - search argument class"); Class typeClass = Class.forName(type); Debug.debug("VoyagerMasaGateway.migrate_agent() - get constructor"); Constructor typeConstruct = typeClass.getConstructor(new Class [] {Class.forName("java.lang.String")}); Debug.debug("VoyagerMasaGateway.migrate_agent() - create instance"); args[i] = typeConstruct.newInstance(new Object[]{value}); i++; }catch(Exception e){ e.printStackTrace(); throw new CfMAF.ArgumentInvalid(); } } // migrate agent _voyagerAgentManager.migrate_agent(agent_name, target, execute, args); // save migration as termination and creation by applet _agentsTerminatedByApplet.addElement(agent_name); _agentsCreatedByApplet.addElement(agent_name); } /** * list all voyager agents */ public String [] list_all_agents(){ CfMAF.Name [] agents = _voyagerAgentManager.list_all_agents(); String [] result = new String [agents.length];; for(int i=0; i<result.length; i++){ result[i] = new String (agents[i].identity); } return result; } /** * Lists all voyager server */ public String [] list_all_voyagerserver(){ return _voyagerServer; } /** * Exceutes a method of a Voyager agent * * @param agent_name Name of the Vozager agent * @param method Name of the Method to be executed * @param arguments Arguments for method, e.g. "java.lang.String Hello World!,java.lang.Integer 1" * */ public String execute_agent(String agent_name, String method, String arguments) throws CfMAF.ArgumentInvalid, CfMAF.MAFExtendedException{ // build arguments StringTokenizer declarations = new StringTokenizer(arguments,","); // pairs of type and value Object [] args = new Object[declarations.countTokens()]; int i=0; while(declarations.hasMoreTokens()){ String decl = declarations.nextToken(); // get type String type = decl.substring(0,decl.indexOf(" ")); // get value String value = decl.substring(decl.indexOf(" ")+1,decl.length()); Debug.debug("VoyagerMasaGateway.migrate_agent() - arguments: type: " + type + " value: " + value); // instantiate class of type with value, // class must have a constructor, // accepting string as argument try{ Debug.debug("VoyagerMasaGateway.migrate_agent() - search argument class"); Class typeClass = Class.forName(type); Debug.debug("VoyagerMasaGateway.migrate_agent() - get constructor"); Constructor typeConstruct = typeClass.getConstructor(new Class [] {Class.forName("java.lang.String")}); Debug.debug("VoyagerMasaGateway.migrate_agent() - create instance"); args[i] = typeConstruct.newInstance(new Object[]{value}); i++; }catch(Exception e){ e.printStackTrace(); throw new CfMAF.ArgumentInvalid(); } } // execute method return _voyagerAgentManager.execute_agent(agent_name, method, args); } /** * Returns voyager server of agent * * @param Name of the Voyager agent */ public String get_server(String agent_name){ return _voyagerAgentManager.get_server(agent_name); } }