/*********************************************************************/
/* */
/* 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 AgentService.Agent;
using AgentService.Platform.AMS;
using AgentService.Platform.Modules;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace AgentService.Platform
{
///
/// Class DLLSetupData. Mantains the
/// basic information for a dll that
/// need to be loaded into the storage.
///
public class AssemblySetupData
{
///
/// path to the dll of the
/// assembly to load into
/// the storage
///
protected string path;
///
/// Gets, sets the path to
/// the dll of the assembly
/// to load into the storage.
///
public string Path
{
get
{
return this.path;
}
set
{
this.path = value;
}
}
///
/// assembly overwrite flag
///
protected bool bOverwrite;
///
/// Gets, sets the overwrite
/// behavior: if true the assembly
/// while loaded into the storage
/// overwrites a possible already
/// existing assembly.
///
public bool Overwrite
{
get
{
return this.bOverwrite;
}
set
{
this.bOverwrite = value;
}
}
///
/// Creates an instance of the
/// DLLSetupData type.
///
public AssemblySetupData()
{
// NOTE: not neeeded
//
// this.path = null;
// this.bOverwrite = false;
}
///
/// Creates an instance of the
/// DLLSetupData type by specifying the
/// path to the assembly and the overwrite
/// behaviour.
///
/// path to the dll of the assembly to load into the storage
/// assembly overwrite flag
public AssemblySetupData(string path, bool bOverwrite)
{
this.bOverwrite = bOverwrite;
this.path = path;
}
}
///
/// Class AgentSetupData. Mantains all the
/// setup values required for a generic
/// software agent creation and activation.
///
public class AgentSetupData
{
///
/// name of the agent
///
protected string name;
///
/// Gets, sets the name of the
/// agent.
///
public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
}
}
///
/// full type name of the agent prototype
///
protected string fullTypeName;
///
/// Gets, sets the full type name of the
/// agent prototype.
///
public string FullTypeName
{
get
{
return this.fullTypeName;
}
set
{
this.fullTypeName = value;
}
}
///
/// path to the agent configuration file
///
protected string configFile;
///
/// Gets, sets the path to the agent
/// configuration file.
///
public string ConfigFile
{
get
{
return this.configFile;
}
set
{
this.configFile = value;
}
}
///
/// agent domain name
///
protected string domainName;
///
/// Gets, sets the agent domain name.
///
public string DomainName
{
get
{
return this.domainName;
}
set
{
this.domainName = value;
}
}
///
/// domain flag
///
protected bool bDomain;
///
/// Gets, sets the domain flag.
///
public bool UseDomain
{
get
{
return this.bDomain;
}
set
{
this.bDomain = value;
}
}
///
/// persistence flag.
///
protected bool bPersist;
///
/// Gets, sets the agent persistence
/// behaviour. If true the agent will
/// be created as persistent.
///
public bool Persist
{
get
{
return this.bPersist;
}
set
{
this.bPersist = value;
}
}
///
/// Constructs an instance of the AgentSetupData by specifying the name, the full type name,
/// and the agent configuration file. The Persist property is set to false, the UseDomain
/// property is set to false and the DomainName to null.
///
/// agent name
/// agent's prototype full type name
/// agent configuration file
/// persistence flag
public AgentSetupData(string name, string fullTypeName, string configFile)
{
this.name = name;
this.fullTypeName = fullTypeName;
this.configFile = configFile;
// NOTE: not needed
//
// this.bPersist = false;
// this.bDomain = false;
// this.domainName = null;
}
///
/// Constructs an instance of the AgentSetupData by specifying the name, the full type name,
/// tha agent configuration flag and the persitence flag. The UseDomain property is set to
/// false and the DomainName to null.
///
/// agent name
/// agent's prototype full type name
/// agent configuration file
/// persistence flag
public AgentSetupData(string name, string fullTypeName, string configFile, bool bPersist)
{
this.name = name;
this.fullTypeName = fullTypeName;
this.configFile = configFile;
this.bPersist = bPersist;
// NOTE: not needed
//
// this.bDomain = false;
// this.domainName = null;
}
///
/// Constructs an instance of the AgentSetupData by specifying all the parameters.
/// The value of the UseDomain property will be set according to the value of the
/// domainName parameter: if null it will be set to false, if empty or other to true.
///
/// agent name
/// agent's prototype full type name
/// agent domain name
/// agent configuration file
/// persistence flag
public AgentSetupData(string name, string fullTypeName, string configFile, bool bPersist, string domainName)
{
this.name = name;
this.fullTypeName = fullTypeName;
this.configFile = configFile;
this.bPersist = bPersist;
this.bDomain = (domainName != null);
this.domainName = domainName;
}
}
///
/// Class BatchSetupData. Provides a default
/// model for implementing a configuration class
/// for storing setup data for a batch. The type
/// exposes two collections: the list of dll to
/// load and the list of agent setup data.
///
public class BatchSetupData
{
///
/// start behaviour
///
protected bool bWaitToStart;
///
/// Gets, sets the starting behaviour: if true
/// the batch waits for user to press [Enter]
/// to start the platform.
///
public bool WaitToStart
{
get
{
return this.bWaitToStart;
}
set
{
value = this.bWaitToStart;
}
}
///
/// collection of assemblies to load into
/// the storage.
///
protected Collection assemblies;
///
/// Gets, sets the collection of assemblies
/// to load into the storage.
///
public Collection Assemblies
{
get
{
return this.assemblies;
}
}
///
/// collections of agents to create
///
protected Collection agents;
///
/// Gets, sets the collection of agents to
/// create.
///
public Collection Agents
{
get
{
return this.agents;
}
}
///
/// Creates an instance of the DefaultBatchSetup
/// type.
///
public BatchSetupData()
{
this.agents = new Collection();
this.assemblies = new Collection();
}
}
///
/// Class DefaultBatch. Provides a default implementation
/// of the IPlatformBatch interface and can be used as a
/// base class for implementing custom application batches.
/// It provides an implementation of the two version of
/// the Run method and three methods to hooks for customizing
/// the creation of agents, the execution of the system, and the
/// read of configuration data.
///
/// A ready to use batch setup class is the
/// XmlBatchSetup class, which reads the setup from
/// an XML based file (see: project xmlconf)
public abstract class BatchBase : AgentService.Platform.IPlatformBatch
{
///
/// reference to the configuration file.
///
protected string conf;
///
/// batch setup data
///
protected BatchSetupData setup;
///
/// reference to the platform controller.
///
protected IPlatformController controller;
#region IPlatformBatch Members
///
/// Allows the execution of the batch from a configuration file.
///
/// the platform reference
/// configuration file for the batch
public void Run(PlatformController controller, string configFile)
{
this.conf = configFile;
this.setup = this.ReadSetup();
this.Run(controller);
}
///
/// Entry points for the batch
///
/// the platform reference
public void Run(PlatformController controller)
{
this.controller = controller;
if (this.setup.WaitToStart == true)
{
controller.Console.Main.WriteLine("[Batch] - Press [Return] to start...");
controller.Console.Input.ReadLine();
}
else
{
controller.Console.Main.WriteLine("[Batch] - Invoking platform start...");
}
controller.StartPlatform();
if (controller.PlatformState == PlatformState.Ready)
{
// first... try to load all the required assemblies.
IModuleError error = null;
foreach (AssemblySetupData dll in this.setup.Assemblies)
{
error = controller.Modules.UpLoadAssembly(dll.Path, dll.Overwrite);
if (error != null)
{
break;
}
}
#region if error == null
if (error == null)
{
controller.RunPlatform();
if (controller.PlatformState == PlatformState.Running)
{
bool bOkCreate = this.CreateAgents();
if (bOkCreate == true)
{
this.Execute();
}
else
{
controller.Console.Error.WriteLine("Some error occurred while creating agents");
}
}
else
{
controller.Console.Error.WriteLine("Some error occurred during platform activation.");
}
}
else
{
controller.Console.Error.WriteLine("Some error occurred when uploading the assembly: {0} - Details: {1}", error.Description, (error.Exception != null ? error.Exception.Message : "no details"));
}
#endregion
}
else
{
controller.Console.Error.WriteLine("Could not start platform");
}
// System.Threading.Thread.Sleep(2000);
controller.Console.Main.WriteLine("[Batch] - Press [Return] to shut down..");
controller.Console.Input.ReadLine();
controller.ShutdownPlatform();
}
#endregion
#region override methods
///
/// Handles agent creation. The default implementation just
/// iterates through the collection of agent setup data and
/// creates agents accordingly. If the UseDomain flag is set
/// the implementation checks the content of the DomainName
/// property. If a name has been provided it tries to create
/// the agent in the given domain, otherwise it will just set
/// the bDomain flag to true. If the UseDomain is not set it
/// will use the default method. The implementation stops and
/// returns false if the creation of an agent fails.
///
/// true if all the agents have been created false
/// otherwise
public virtual bool CreateAgents()
{
bool bOk = false;
if (this.setup != null)
{
foreach (AgentSetupData asd in this.setup.Agents)
{
AID aid = null;
// is the domain flag set?
if (asd.UseDomain == true)
{
// yes, is the domain name set?
if (string.IsNullOrEmpty(asd.DomainName) == true)
{
// yes... trying to create the agent in the given domain
aid = this.controller.Services.CreateAgent(asd.FullTypeName, asd.Name, asd.ConfigFile, asd.Persist, asd.UseDomain);
}
else
{
// no... use domain settings of the platform
aid = this.controller.Services.CreateAgent(asd.FullTypeName, asd.Name, asd.ConfigFile, asd.Persist, asd.DomainName);
}
}
else
{
// no... use simple instantiation
aid = this.controller.Services.CreateAgent(asd.FullTypeName, asd.Name, asd.ConfigFile, asd.Persist);
}
// has the agent been created?
if (aid == null)
{
// no, exit
return false;
}
}
}
// all agents have been created
return true;
}
///
/// Handles the execution of the system. Implementors
/// must override if they want to customize the activation
/// of the agents. The default implementation just activates
/// all the agents and waits for their termination.
///
public virtual void Execute()
{
this.controller.Services.ActivateAllAgents();
this.controller.Services.WaitForAllAgents();
}
///
/// Handles batch setup file read. Implementors
/// must override.
///
///
protected abstract BatchSetupData ReadSetup();
#endregion;
}
}