next up previous contents
Next: B.5 VoyagerProxyAgentMobileAgent Up: B Source-Code des Voyager-MASA-Gateways Previous: B.3 NamingGateway

B.4 VoyagerAgentManager

package de.unimuenchen.informatik.mnm.masa.agentSystem.voyagerintegration;

import com.objectspace.voyager.*;
import com.objectspace.voyager.agent.*;
import com.objectspace.voyager.message.*;
import com.objectspace.lib.util.*;

import org.omg.CosNaming.*;
import java.util.*;

import CfMAF.*;
import de.unimuenchen.informatik.mnm.masa.tools.*;
import de.unimuenchen.informatik.mnm.masa.agentSystem.*;
import de.unimuenchen.informatik.mnm.masa.agent.voyagerproxyagent.*;

public class VoyagerAgentManager extends GenericAgentManager
{
		/**
		 * CfMAF.Type of the Voyager-Agentsystem
		 */
		private Short VOYAGER_TYPE = new Short (System.getProperty("de.unimuenchen.informatik.mnm.masa.voyager.type","5"));

		/**
		 * running _agentsVoyagerName
		 * form: (String agent_name, String //voyagerhost:port/agent_name)
		 */
		private Hashtable _agentsVoyagerName = new Hashtable();

		/**
		 * proxy agents in masa
		 * form: (String agent_name, CfMAF.Name proxy)
		 */
		private Hashtable _voyagerProxy = new Hashtable();

		/**
		 * MASA-AgnetSystem     
		 */
		private AgentSystemService _masaAgentSystemService;

		/**
		 * voyager naming context in masa
		 */
		private NamingContext _voyagerContext;

		/**
		 * context in which VoyagerMasaGateway bound to
		 */
		private NamingContext _ownContext;


		/**
		 * Constructor
		 */
		public VoyagerAgentManager(AgentSystemService masaAgentSystemService, NamingContext voyagerContext, NamingContext ownContext)
    {
				Debug.debug("VoyagerAgentManager.<init>");
				// init attirbutes
				this._masaAgentSystemService = masaAgentSystemService;
				this._voyagerContext = voyagerContext;
				this._ownContext = ownContext;
    }

    
		/**
		 * @see AgentManager.connectToAgent()
		 */
		public org.omg.CORBA.Object connectToAgent(Name agent_name) 
				throws AgentNotFound
    {
				return null; // not supported
    }
  

		/**
		 * @see AgentManager.getAgentSystemURL()
		 */
		protected String getAgentSystemURL(){
				return null; // not supported
		}
  
		/** 
		 * Creates a voyageragent and a voyagerproxyagent:
		 * 1. get agent arguments
		 * 2. get agent's classname
		 * 3. create proxy agent in MASA
		 * 4. create Voyager agent
		 * 5. update internal data
		 * If creation of Voyager agent fails then the 
		 * already created voyagerproxyagent will be terminated 
		 * because its easier to terminate a voyagerproxyagent 
		 * in MASA than a Voyager agent
		 *
		 * @param agent_name    Agentname
		 * @param agent_profile not used
		 * @param agent         not used 
		 * @param place_name    Voyager server on which remote object will be created
		 * @param arguments     not used 
		 * @param class_names   List of classnames to instantiate agent,
		 *                      only necessary if classname different from agentname 
		 * @param code_base     not used
		 * @param class_provider not used
		 *
		 */
		
		public synchronized Name create_agent(Name agent_name,     
																					AgentProfile agent_profile,     
																					byte[] agent, 
																					String place_name,     
																					byte[] arguments,     
																					ClassName[] class_names, 
																					String code_base,     
																					MAFAgentSystem class_provider) 
				throws ClassUnknown, ArgumentInvalid, 
							 DeserializationFailed, MAFExtendedException{
				/**************************
				 *  1. get agent arguments
				 **************************/
				java.util.Vector agentArgs= null;
				if ( agent.length > 0 ) { 
						agentArgs= new java.util.Vector(4);
						try {
								java.io.ObjectInputStream input= 
										new java.io.ObjectInputStream(new java.io.ByteArrayInputStream(agent));
								while( true ){
										agentArgs.addElement(input.readObject());
								}
						}
						catch(java.io.EOFException eofe){
								Debug.debug("VoyagerAgentManager.create_agent():Stream fully read!");
								//Ok, Stream full readed
						}
						catch(Throwable e){
								e.printStackTrace();
								throw new ArgumentInvalid();
						}
				}

				/**************************
				 * 2. get agent's classname
				 **************************/

				// get classname, if classname is different 
				// from agent_name then it is defined 
				// in class_names else class_names is empty
				String className;
				if (class_names.length != 0)
						className = class_names[0].name;
				else
						className = new String(agent_name.identity);
				int indexPackageName= 0;
				String packageName= (String)agentArgs.elementAt(indexPackageName);
				if ( packageName.length() > 0 )
						className= packageName + "." + className;
    
				// build agent name, 
				// if already agent_name exists 
				// then put <n> to the end of the name (voyager) convention
				Debug.debug("VoyagerAgentManager.create_agent() - build agent name");
				String agentName= new String(agent_name.identity);
				// check whether already exists
				if(_agentsVoyagerName.containsKey(agentName)){
						// have to change agent_name
						int i= 1;
						Debug.debug("VoyagerAgentManager.create_agent() - _agentsVoyagerName: " + _agentsVoyagerName.toString());
						while(_agentsVoyagerName.containsKey(new String(agentName + "<"+i+">"))){
								Debug.debug("VoyagerAgentManager.create_agent() - existing agent names: " + new String(agentName + "<"+i+">"));
								i++;
						}
						agentName = agentName + "<"+i+">";
				}
				Debug.debug("VoyagerAgentManager.create_agent() - agentName: " + agentName);
      

				/********************************
				 * 3. create proxy agent in MASA
				 ********************************/

				// create proxy for MASA
				try{
						create_voyagerproxyagent(agentName,place_name);
				}catch (Exception createProxyException){
						createProxyException.printStackTrace();
						throw new MAFExtendedException();
				}
    

				/********************************
				 * 4. create Voyager agent
				 ********************************/
				try{
						// start voyager client
						try{
								Voyager.startup();
						}catch(com.objectspace.voyager.StartupException e){
								Debug.debug("WARNING: " + e);
						}
    
						// create remote object in voyager
						java.lang.Object obj = null;
						Debug.debug("VoyagerAgentManager.create_agent() - className:" + className);
						Debug.debug("VoyagerAgentManager.create_agent() - place_name:" + place_name);
						obj = Factory.create(className,place_name);
      
						// bind voyager remote object to voyager-namespace
						Debug.debug("VoyagerAgentManager.create_agent() - Namespace.bind: " 
												+ place_name 
												+ "/" 
												+ new String(agent_name.identity));
						Namespace.bind(place_name + "/" + agentName,obj);

						// shutdown Voyager client
						Voyager.shutdown();
				} catch (Exception generalVoyagerException){
						generalVoyagerException.printStackTrace();
						try{
								Voyager.shutdown();
						}catch(Exception shutdownVoyagerException){
								shutdownVoyagerException.printStackTrace();
						}
						// could not create voyager agent so terminate voyager proxy agent in MASA
						try{
								terminate_voyagerproxyagent(agentName);
						} catch(CfMAF.TerminateFailed terminateException){
								terminateException.printStackTrace();
						}
						throw new MAFExtendedException();
				}
    
				Debug.debug("VoyagerAgentManager.create_agent() - _agentsVoyagerName: " + _agentsVoyagerName.toString());

				/************************
				 * 5. update internal data
				 ************************/

				// update agent_name
				agent_name.identity = agentName.getBytes();
				return agent_name;
		}
  

		/**
		 * @see AgentManager.get_agent_status()
		 */
		public AgentStatus get_agent_status(Name agent_name) 
				throws AgentNotFound{
				return null; // not supported
		}

		/**
		 * @see AgentManager.get_authinfo()
		 */
		public AuthInfo get_authinfo(Name agent_name) 
				throws AgentNotFound{
				return null; // not supported
		}

		/**
		 * Lists all voyager agents
		 */
		public CfMAF.Name[] list_all_agents(){     
				CfMAF.Name [] result = new CfMAF.Name[0];
				try{
						Debug.debug("VoyagerAgentManager.list_all_agents() - proxys: " + _voyagerProxy.toString());
						result = new CfMAF.Name[_voyagerProxy.size()];
						Enumeration agents = _voyagerProxy.keys();
						Debug.debug("VoyagerAgentManager.list_all_agents() - got " 
												+ result.length + " keys from table");
						for(int i=0; i<result.length; i++){
								result[i] = new CfMAF.Name();
								result[i].identity = ((String) agents.nextElement()).getBytes();
						}
				} catch (Exception e){
						e.printStackTrace();
				}
				return result;
		}
  
		/**
		 * @see AgentManager.list_all_agents_of_authority()
		 */
		public CfMAF.Name[] list_all_agents_of_authority(byte [] authority){
				return null; // not supported
		}
  
		/**
		 *  @see AgentManager.receive_agent()
		 */ 
		public void receive_agent(Name agent_name,     
															AgentProfile agent_profile,     
															byte[] agent, 
															String place_name,     
															ClassName[] class_names,     
															String code_base, 
															MAFAgentSystem agent_sender) 
				throws ClassUnknown, ArgumentInvalid, 
							 DeserializationFailed, MAFExtendedException{
				// not supported
		}
  
		/**
		 *  @see AgentManager.resume_agent()
		 */ 
		public void resume_agent(Name agent_name) 
				throws AgentNotFound, ResumeFailed, AgentIsRunning{
				// not supported
		}
		
		/**
		 *  @see AgentManager.suspend_agent()
		 */ 
		public void suspend_agent(Name agent_name) 
				throws AgentNotFound, SuspendFailed, AgentIsSuspended{
				// not supported
		}
  
		/**
		 * Terminates a Voyager agent, i.e. unbins it 
		 * from Namespace and hopes that 
		 * Garbage Collection will delete it
		 * 
		 * @param agent_name name of the Voyager agent
		 */
		public synchronized void terminate_agent(Name agent_name) 
				throws AgentNotFound, TerminateFailed{
				// unbind agent in voyager
				try{
						try{
								Voyager.startup();
						}catch(com.objectspace.voyager.StartupException e){
								System.out.println("WARNING: " + e);
						}
						Namespace.unbind((String)_agentsVoyagerName.get(new String (agent_name.identity)));
						Voyager.shutdown();
				} catch(Exception e){
						e.printStackTrace();
						Voyager.shutdown();
						throw new TerminateFailed();
				}
				// terminate proxy agent
				try{
						terminate_voyagerproxyagent(new String (agent_name.identity));
				}catch(Exception e){
						e.printStackTrace();
						throw new TerminateFailed();
				}
		}
  
		/**
		 * @see AgentManager.terminateAgentManager()
		 */
		protected void terminateAgentManager()
				throws TerminateFailed{
				// not supported
		}

		/**
		 * @see AgentManager.setAgentSystemService()
		 */
		protected void setAgentSystemService(AgentSystemService ass){
				// not supported
		}
		
		/**
		 * @see AgentManager.writeAgentToFile()
		 */
		public void writeAgentToFile(CfMAF.Name agentName, java.lang.String file)
				throws WriteFailed{
				// not supported
		}

		/**
		 * @see AgentManager.readAgentFromFile()
		 */
		public CfMAF.Name readAgentFromFile(java.lang.String file)
				throws ReadFailed{
				return null; // not supported
		}
  
		/**
		 * Creates ProxyVoyagerAgents for the VoyagerAgents
		 *
		 * @param agent_names Name of the created Voyager agent
		 * @param voyager_server Voyager server on which Voyager agent has been created
		 */
		public void create_voyagerproxyagent(String agent_name, String place_name) throws CfMAF.ArgumentInvalid, CfMAF.DeserializationFailed, CfMAF.MAFExtendedException,CfMAF.ClassUnknown
    {
				// create the parameters for the create_agent() call
				java.io.ByteArrayOutputStream agentBytes = new java.io.ByteArrayOutputStream();
				
				java.io.ObjectOutputStream outputAgent;
				java.io.ObjectOutputStream constructorObject;
				java.io.ByteArrayOutputStream constructorArgs;
				CfMAF.ClassName [] className;
				try{
						outputAgent = new java.io.ObjectOutputStream(agentBytes);
						outputAgent.writeObject("de.unimuenchen.informatik.mnm.masa.agent.voyagerproxyagent");
						outputAgent.writeObject("MobileAgent");
						outputAgent.writeObject("_tie_");		
						outputAgent.writeObject("Operations");
						outputAgent.writeObject(new Boolean(false));
						outputAgent.writeObject("");
	  
						constructorArgs = new java.io.ByteArrayOutputStream();
						constructorObject = new java.io.ObjectOutputStream(constructorArgs);
						// set Classname of agent
						className = new CfMAF.ClassName[1];
						className[0] = new CfMAF.ClassName("VoyagerProxyAgent", new byte[0]);
						constructorObject.writeObject(agent_name); // write the values to constructorObject
				}catch(java.io.IOException ioException){
						ioException.printStackTrace();
						throw new ArgumentInvalid();
				}
			
				// agents names in MASA must NOT contain "."
				// change "." to "_"
				StringTokenizer token = new StringTokenizer(agent_name,".");
				String new_name = new String();
				while(token.hasMoreElements())
						{
								new_name = new_name + token.nextToken() + "_";
								if (!token.hasMoreElements())
										new_name = new_name.substring(0,new_name.length()-1);
						}
				agent_name = new_name;
				NameWrapper nw = new NameWrapper(agent_name);
      
				//create the profile of the agent
				CfMAF.AgentProfile 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= "Voyager Agent System of MNM-Team";
      
      // create the agent
				CfMAF.Name res = _masaAgentSystemService.create_agent(nw._name,
																															ap,
																															agentBytes.toByteArray(),
																															new String("default"),
																															constructorArgs.toByteArray(),
																															className,
																															"",
																															(CfMAF.MAFAgentSystem) _masaAgentSystemService);
				try{
						// get agent corba reference
						org.omg.CORBA.Object agentRef = _ownContext.resolve(NameWrapper.getNameComponents(res,false));
						// put agent in voyager namingcontext
						_voyagerContext.bind(new NameComponent [] {new NameComponent(new String(res.identity),"")}, agentRef);
						
						// save agent and its CfMAF name in table
						_voyagerProxy.put(agent_name,res);
	
						// save full voyager Name
						// put agent and its voyager name in agent-hashtable
						_agentsVoyagerName.put(agent_name,place_name + "/" + agent_name);
				}catch(Exception corbaException){
						corbaException.printStackTrace();
						// try to terminate proxy again
						try{
								terminate_voyagerproxyagent(agent_name);
						}catch(Exception terminateProxyException){
								terminateProxyException.printStackTrace();
								// can't do any thing more, user should restart VoyagerMasaGateway!
						}
						throw new CfMAF.MAFExtendedException();
				}
    }
  
		/**
		 * Terminates a Voyager Agent's proxyavoyageragent in Masa
		 *
		 * @param agent_name Name of the Voyager Agent
		 */
		public void terminate_voyagerproxyagent(String agent_name) throws TerminateFailed{
				Debug.debug("VoyagerAgentManager.terminate_voyagerproxyagent()");
				try{
						CfMAF.Name name = (CfMAF.Name) _voyagerProxy.remove(agent_name);
						// set voyager proxy ready for termination
						org.omg.CORBA.Object obj = _ownContext.resolve(NameWrapper.getNameComponents(name,false));
						VoyagerProxyAgent proxyAgent = VoyagerProxyAgentHelper.narrow(obj);
						proxyAgent.setReadyForTermination();

						// terminate voyager proxy
						_masaAgentSystemService.terminate_agent(name);
						// unbind it from voyager directory in MASA
						_voyagerContext.unbind(new NameComponent [] {new NameComponent(new String(name.identity),"")});
   
						// remove voyager agent name from table
						_agentsVoyagerName.remove(agent_name);
				}catch(Exception generalTerminateException){
						generalTerminateException.printStackTrace();
						throw new TerminateFailed();
				}
		}

		/**
		 * Terminates all voyager proxy agents
		 * in MASA at termination of voyager masa gateway
		 */
		public void cleanUp() throws CfMAF.TerminateFailed{
				// terminate all proxy agents
				Enumeration proxyAgents = _voyagerProxy.keys();
				while(proxyAgents.hasMoreElements()){
						terminate_voyagerproxyagent((String) proxyAgents.nextElement());
				}
		}

		/**
		 * migrates a voyager agent
		 *
		 * @param agent_name Name pf the Voyager agent in MASA
		 * @param target     Voyager server to which the agent should be migrated
		 * @param execute    Name of the mathod which will be executed after migration
		 * @param args       Arguments for the method
		 */
		public synchronized void migrate_agent(String agent_name, String target, String execute, Object [] arguments) throws MAFExtendedException{
				// build agentname for voyager
				String voyager_agent_name = (String) _agentsVoyagerName.get(agent_name);
				try{
						try{
								Voyager.startup();
						}catch(com.objectspace.voyager.StartupException e){
								System.out.println("WARNING: " + e);
						}
						// get proxy
						Object remObj = Namespace.lookup(voyager_agent_name);
						// make agent of remote object
						IAgent agent = Agent.of(remObj);
						// migrate agent
						if(execute.length() > 0 && arguments.length > 0){
								agent.moveTo(target,execute,arguments);
						}
						else if (execute.length() > 0)
								agent.moveTo(target,execute);
						else
								agent.moveTo(new String(target));
						Namespace.unbind(voyager_agent_name);
						try{
								Namespace.bind(target + "/" + agent_name,remObj);
								// update entry in agent table with new location of voyager agent
								_agentsVoyagerName.put(agent_name,target + "/" + agent_name);
						}catch(NamespaceException bindException){
								//try to rebind to old location
								Namespace.bind(voyager_agent_name,remObj);
								throw new MAFExtendedException();
						}
						// shutdown voyager client
						Voyager.shutdown();
				} catch (Exception generalVoyagerException){
						generalVoyagerException.printStackTrace();
						Voyager.shutdown();
						throw new MAFExtendedException();
				}
		}

		/**
		 * Executes a method of a Voyager Agent
		 * @param agent_name Name of the Voyager agent
		 * @param method Methodname
		 * @param args List of Arguments for method
		 */
		public String execute_agent(String agent_name, String method, Object[] args)throws CfMAF.MAFExtendedException{
				try{
						Voyager.startup();
				}catch(StartupException e){
						System.out.println("WARNING: " + e);
				}
				try{
						String voyagerName = (String) _agentsVoyagerName.get(agent_name);
						if(voyagerName == null)
								throw new CfMAF.MAFExtendedException();
						Object ref = Namespace.lookup(voyagerName);
						Debug.debug("changed");
						Result result = result = Sync.invoke(ref,method,args);
						Voyager.shutdown();
						try{ return result.readObject().toString();}
						catch(NullPointerException voidReturnException){return "void";}
				}catch(Exception e){
						e.printStackTrace();
						throw new CfMAF.MAFExtendedException();
				}
		}

    /**
     * Returns the location of a Voyager server
		 *
		 * @param agent_name Name of the Voyager agent
     */
    public String get_server(String agent_name){
				String fullName = (String) _agentsVoyagerName.get(agent_name);
				fullName = fullName == null ? "" : fullName.substring(0,fullName.indexOf(agent_name));
				return fullName;
    }
}



Copyright Munich Network Management Team