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);
}
}