/*********************************************************************/
/* */
/* AgentService Framework */
/* www.agentservice.it */
/* */
/* Copyright (C) 2007 l.i.d.o. - DIST, University of Genoa, Italy */
/* GNU Lesser General Public License */
/* */
/* This library is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU Lesser General Public */
/* License as published by the Free Software Foundation, */
/* version 2.1 of the License. */
/* */
/* This library is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
/* Lesser General Public License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public */
/* License along with this library; if not, write to the */
/* Free Software Foundation, Inc., 59 Temple Place - Suite 330, */
/* Boston, MA 02111-1307, USA. */
/* */
/*********************************************************************/
using System;
using System.Reflection;
using AgentService.Platform;
using AgentService.Platform.DF;
using AgentService.Platform.AMS;
using AgentService.Platform.MTS;
using AgentService.Platform.Modules;
using AgentService.Agent.Behaviour;
using AgentService.Agent.Knowledge;
namespace AgentService.Agent.Runtime
{
///
/// Class AgentProxy. Proxy the agent class used
/// for accessing software agent instances that
/// are located in another domain.
///
public class AgentProxy : MarshalByRefObject, IAgent
{
///
/// Constructor, creates an agentproxy and an Agent in it. It also bind it to Runtime
///
/// persistence flag, put true for persistent agents
/// full type name of the template that characterize the agent
/// name of the assembly in which is the agent to Create
/// agent identifier
/// reference to the platform
/// reference to the MTS
/// reference to the LoggingModule
/// reference to the YellowPagesServer
/// reference to the WhitePagesServer
/// reference to the AMS
/// agent object
public AgentProxy(bool bPersist, string TemplateName, string assemblyFile,AID aid, Platform.IPlatform plat, Platform.MTS.IMTSGateway mtsp, Platform.Modules.ILoggingModule logp, IYellowPagesServer ypsp, IWhitePagesServer wpsp, IAMS amsp)
{
try
{
this.platform = plat;
this.mts = mtsp;
this.log = logp;
this.yps = ypsp;
this.wps = wpsp;
this.ams = amsp;
string basedir = System.IO.Path.GetDirectoryName(System.IO.Path.GetFullPath(assemblyFile));
System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(assemblyFile);
object zombie = assembly.CreateInstance(TemplateName,
true,
System.Reflection.BindingFlags.CreateInstance,
null,
new object[0] { },
System.Globalization.CultureInfo.CurrentCulture,
null);
AgentTemplate template = zombie as AgentTemplate;
if (template != null)
{
this.agent = new Agent(bPersist);
this.agent.SetTemplate(template);
this.agent.AID = aid;
this.Bind(null);
this.platform.Console.WriteLineMessage("Created agent [Name: " + aid.Name + "] in AppDomain [" + System.Threading.Thread.GetDomain().FriendlyName + "]");
}
}
catch(Exception e)
{
// TODO: Fix with Debug.WriteLine("[AgentProxy]" + e.Message + "\n" + e.StackTrace);
// System.Console.WriteLine("[AgentProxy]" + e.Message + "\n" + e.StackTrace);
throw (e);
}
}
#region Members
///
/// the Agent in the Domain
///
private IAgent agent;
private Platform.MTS.IMTSGateway mts;
private Platform.Modules.ILoggingModule log;
private IYellowPagesServer yps;
private IWhitePagesServer wps;
private Platform.AMS.IAMS ams;
private Platform.IPlatform platform;
#region Agent Related events
///
/// Thrown when the agent is activated.
///
public event AgentDelegate OnActivateAgent
{
add
{
this.agent.OnActivateAgent += value;
}
remove
{
this.agent.OnActivateAgent -= value;
}
}
///
/// Fires every time an agent has terminated
/// its activity either because it has been
/// stopped by the platform or because it has
/// terminated.
///
public event AgentDelegate OnReleaseAgent
{
add
{
this.agent.OnReleaseAgent += value;
}
remove
{
this.agent.OnReleaseAgent -= value;
}
}
///
/// thrown when the agent is stopped
///
public event AgentDelegate OnStopAgent
{
add
{
this.agent.OnStopAgent += value;
}
remove
{
this.agent.OnStopAgent -= value;
}
}
///
/// thrown when the agent terminates its execution
///
public event AgentDelegate OnTerminateAgent
{
add
{
this.agent.OnTerminateAgent += value;
}
remove
{
this.agent.OnTerminateAgent -= value;
}
}
///
/// thrown by a persistent agent, when its internal data
/// change
///
public event PersistAgentDelegate OnPersistAgent
{
add
{
this.agent.OnPersistAgent += value;
}
remove
{
this.agent.OnPersistAgent -= value;
}
}
#endregion
#region Behaviour related events
///
/// Fires every time a new behaviour is created.
///
public event BehaviourDelegate OnNewBehaviour
{
add
{
this.agent.OnNewBehaviour += value;
}
remove
{
this.agent.OnNewBehaviour -= value;
}
}
///
/// Fires every time a behaviour is started.
///
public event BehaviourDelegate OnStartBehaviour
{
add
{
this.agent.OnStartBehaviour += value;
}
remove
{
this.agent.OnStartBehaviour -= value;
}
}
///
/// Fires every time a behaviour is terminated.
///
public event BehaviourDelegate OnTerminateBehaviour
{
add
{
this.agent.OnTerminateBehaviour += value;
}
remove
{
this.agent.OnTerminateBehaviour -= value;
}
}
///
/// Fires every time a behaviour is suspended.
///
public event BehaviourDelegate OnSuspendBehaviour
{
add
{
this.agent.OnSuspendBehaviour += value;
}
remove
{
this.agent.OnSuspendBehaviour -= value;
}
}
///
/// Fires every time a behaviour is woken up.
///
public event BehaviourDelegate OnWakeUpBehaviour
{
add
{
this.agent.OnWakeUpBehaviour += value;
}
remove
{
this.agent.OnWakeUpBehaviour -= value;
}
}
#endregion
#region IAgent Members
public AID AID
{
get
{
return this.agent.AID;
}
set
{
this.agent.AID = value;
}
}
public AgentState State
{
get
{
return this.agent.State;
}
set
{
this.agent.State = value;
}
}
public bool IsPersistent
{
get
{
return this.agent.IsPersistent;
}
}
public AgentPersistent Persistent
{
get
{
return this.agent.Persistent;
}
set
{
this.agent.Persistent = value;
}
}
public KnowledgeCollection Knowledges
{
get
{
return this.agent.Knowledges;
}
}
///
/// Collection of Behaviour objects belonging to the Agent.
///
public BehaviourCollection Behaviours
{
get
{
return this.agent.Behaviours;
}
}
///
/// Collection of Knowledge type objects handled by the agent.
///
public TypeDescriptorCollection KnowledgeTypes
{
get
{
return this.agent.KnowledgeTypes;
}
}
///
/// Collection of Behaviour type objects handled by the agent.
///
public TypeDescriptorCollection BehaviourTypes
{
get
{
return this.agent.BehaviourTypes;
}
}
///
/// Profile of the agent
///
public AgentProfile Profile
{
get
{
return this.agent.Profile;
}
}
///
/// Name of agent's config file
///
public string ConfigFileName
{
get
{
return this.agent.ConfigFileName;
}
}
#endregion
#endregion
# region Agent Activity
///
/// Initialize the internal Agent's data structures.
///
/// configuration file for agent initialization including the full path
public void Initiate(string configFile)
{
this.agent.Initiate(configFile);
}
///
/// Starts the agent activity.
///
public void Activate()
{
this.agent.Activate();
}
///
/// Assigns an AgentTemplate to the Agent and gives him an AID.
///
/// full template name of the corresponding AgentTemplate subtype
/// name of the containing assembly of the AgentTemplate subtype
public void SetTemplate(AgentTemplate template)
{
this.agent.SetTemplate(template);
}
///
/// Commits the agent migration process
///
/// flag used to distinguish the source
/// and the target platform
public void CommitMove(bool bIsSourceInstance)
{
this.agent.CommitMove(bIsSourceInstance);
}
# endregion
# region Manage Platform Services
///
/// Binds the agent to the runtime environemt of the platform.
///
/// gives access to the runtime services of the platform
public void Bind(IRuntimeEx fake)
{
/* by now this function is not supported in AppDomain
IMsgClient msgClient = null;
if (this.platform.Messaging.HasClient == true)
{
msgClient = this.platform.Messaging.CreateClient(this.agent.AID);
}
else*/
// Todo: think about that
IMsgClient msgClient = new DefaultMsgClient(this.agent,this.mts);
ILogClient logClient = new DefaultLogClient(this.agent.AID, this.log, this.agent.GetHashCode()); //this.platform.Logging.CreateClient(this.agent.AID, this.agent.GetHashCode());
IPersistenceClient persistenceClient = new DefaultPersistenceClient();
IYellowPagesClient ypClient = new DefaultYellowPagesClient(this.agent.AID, this.yps);
IWhitePagesClient wpClient = new DefaultWhitePagesClient(this.agent.AID, this.wps);
IAgentConsole platformConsole = this.platform.Console.BlackBoard;
// CHANGE 30/01/2006: added support to the mobility client
IMobilityClient mobilityClient = new DefaultMobilityClient(this.ams);
ConsoleProxy console = new ConsoleProxy(this.agent.AID.Name, platformConsole);
IRuntimeEx runtime = new DefaultRuntime(this.agent,
msgClient,
persistenceClient,
logClient,
ypClient,
wpClient,
// CHANGE 30/01/2006: added support to the mobility client
mobilityClient,
console);
this.agent.Bind(runtime);
// registers the platform to the agent events
agent.OnPersistAgent += new PersistAgentDelegate(this.platform.persistAgent);
agent.OnActivateAgent += new AgentDelegate(this.platform.onActivateAgent);
agent.OnTerminateAgent += new AgentDelegate(this.platform.onTerminateAgent);
}
///
/// Loads agent data from its persisted version.
///
/// persisted version of the agent
public void ResumeFrom(AgentPersistent agentPersistent)
{
this.agent.ResumeFrom(agentPersistent);
}
///
/// Creates the persistent version of the agent.
///
/// persisted version of the agent
public AgentPersistent GetPersistent()
{
return this.agent.GetPersistent();
}
#endregion
#region Manage Agent Behaviours
///
/// Adds a new behaviour to the agent and starts it.
///
/// The Behaviour to be added to the Agent
/// if true starts the behaviour
public void SubmitBehaviour(Behaviour.Behaviour behaviour, bool bStart)
{
this.agent.SubmitBehaviour(behaviour, bStart);
}
///
/// Suspends a behaviour instance.
///
/// behaviour instances that will be suspended
public void SuspendBehaviour(Behaviour.Behaviour behaviour)
{
this.SuspendBehaviour(behaviour);
}
///
/// Suspends all the behaviour instances.
///
public void SuspendAllBehaviours()
{
this.agent.SuspendAllBehaviours();
}
///
/// Resumes a suspended behaviour instance.
///
/// suspended behaviour instance that will be resumed
public void WakeUpBehaviour(Behaviour.Behaviour behaviour)
{
this.agent.WakeUpBehaviour(behaviour);
}
///
/// Resumes all suspended behaviour instances.
///
public void WakeUpAllBehaviours()
{
this.agent.WakeUpAllBehaviours();
}
///
/// Removes a behaviour instance.
///
/// behaviour instance that will be removed
public void RemoveBehaviour(Behaviour.Behaviour behaviour)
{
this.agent.RemoveBehaviour(behaviour);
}
///
/// Removes all behaviours instances.
///
public void RemoveAllBehaviours()
{
this.agent.RemoveAllBehaviours();
}
///
/// Starts a collection of behaviours instances.
///
/// list of behaviour instances names that will be started
public void StartBehaviours(params string[] behaviourNames)
{
this.agent.StartBehaviours(behaviourNames);
}
///
/// Starts all the behaviour instances previously added.
///
public void StartAllBehaviours()
{
this.agent.StartAllBehaviours();
}
///
/// Kills all the threads belonging to the agent.
///
public void Stop()
{
this.agent.Stop();
}
///
/// Kills all the threads belonging to the agent.
///
/// stop reason, if true the agent terminated abnormally
public void Stop(bool bAbort)
{
this.agent.Stop(bAbort);
}
# endregion
# region Manage Agent Knowledges
///
/// Locks a knowledge instance to be used by a behaviour instance.
///
/// behaviour instance that wants to use the knowledge instances
/// list of knowledge instancess to be locked
public void LockKnowledge(Behaviour.Behaviour lockingBehaviour, params Knowledge.Knowledge[] myKnowledgeList)
{
this.agent.LockKnowledge(lockingBehaviour, myKnowledgeList);
}
///
/// Persists the changes for a given Knowledge's item.
///
///knowledge object which fired the update event
public void PersistChanges(object sender)
{
this.agent.PersistChanges(sender);
}
///
/// Releases the knowledge instances previously locked by a behaviour instance.
///
/// behaviour instance that releases the Knowledge
public void ReleaseKnowledge(Behaviour.Behaviour releaseBehaviour)
{
this.agent.ReleaseKnowledge(releaseBehaviour);
}
///
/// Finalizes the activity of the agent.
///
public void Terminate()
{
this.agent = null;
}
# endregion
}
}