Application Deployment Guide
From Agent Factory
Contents |
Editorial History
15/12/08: Version 1 - Place Holder
21/05/09: Version 2 - Updated for AF2.0
01/02/10: Version 3 - Removed references to NB Module / Focus on Java-based deployment
Introduction
Writing an Agent Factory Deployment basically involves configuring the agent platform. Typically a platform configuration involves:
- Defining a name/domain for the platform
- Selecting a scheduling algorithm
- Installing required architecture factories
- Installing required platform services
- Creating any visualisation / monitoring / debugging tools
- Deploying and initialising an initial community of agents for thaet platform.
Configurations are specified programmatically in Java. Typically, this is done in a main method that looks something like the outline code below:
public class Main {
public static void main(String[] args) {
// Create a new agent platform with a basic name and domain
DefaultAgentPlatform platform = new DefaultAgentPlatform();
platform.setName("test");
platform.setDomain("ucd.ie");
// Install a scheduling algorithm for executing the agents
platform.setScheduler(new RoundRobinTimeSliceFixedScheduler());
// Install and register the AFAPL2 Architecture Factory:
// This enables support for instantiating AFAPL2 agents (i.e. agents
// whose source code is identified by a .agent extension)
AFAPL2ArchitectureFactory factory = new AFAPL2ArchitectureFactory();
Properties props = new Properties();
props.setProperty("TIMESLICE", "100");
factory.configure(props);
platform.getArchitectureService().registerArchitectureFactory(factory);
// Install and start the Agent Factory Debugger
Debugger debugger = new Debugger(platform);
debugger.registerInspectorFactory(new AFAPL2InspectorFactory());
debugger.registerStateManagerFactory(new AFAPL2StateManagerFactory());
debugger.start();
// Get a reference to the Agent Management Service so that the default
// agent community can be created...
AgentManagementService ams = (AgentManagementService) platform.getPlatformServiceManager().getServiceByName(AgentManagementService.NAME);
try {
// 1. Create an agent
IAgent agent = ams.createAgent("rem", "com/agentfactory/afapl2/core/agent/AMSSupport.agent");
// 2. Give it initial beliefs / goals
agent.initialise("BELIEF(happy)");
// 3. Resume the agent (start it)
ams.resumeAgent("rem");
} catch (NoSuchArchitectureException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
} catch (DuplicateAgentNameException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
More information regarding the individual parts that make up this configuration are explained in more detail below.
Creating the Agent Platform
Creating an agent platform programmatically takes three lines of code:
DefaultAgentPlatform platform = new DefaultAgentPlatform();
platform.setName("test");
platform.setDomain("ucd.ie");
The first line creates the basic agent platform, and the second and third lines define the name of the platform. In Agent Factory, a platform name is broken into two parts: the name and the domain. The idea is that related agent platforms have the same domain but different names.
Assigning a Scheduler
Once the platform has been created, the next step is to associate a scheduling algorithm with the platform. Agent Factory comes with four prefabricated agent scheduling algorithms:
- com.agentfactory.platform.impl.MultiThreadFixedScheduler: This is a multi-threaded implementation with a fixed time slice. Each agent runs in its own thread and a fixed amount of time is alloted to each execution step. If the allotted time is not used up, then the scheduler causes the agent thread to sleep for the outstanding portion of the timeslice.
- com.agentfactory.platform.impl.MultiThreadScheduler: This is a multi-threaded implementation with no fixed time slice. Each agent runs in its own thread and execution of the next step commences immediately after the current step finishes.
- com.agentfactory.platform.impl.RoundRobinTimeSliceScheduler: This is a single-threaded implementation with a fixed time slice. Each agent uses available time up to the allotted time slice. The next agent is scheduled immediately after the current agent finishes its execution step.
- com.agentfactory.platform.impl.RoundRobinTimeSliceFixedScheduler: This is a single-threaded implementation with a fixed time slice. Each agent uses available time up to the allotted time slice. The next agent is scheduled once the time slice of the current agent ends.
The default scheduling algorithm employed by the agent platform is com.agentfactory.platform.impl.RoundRobinTimeSliceScheduler. To change the scheduler, you use the following line of code:
platform.setScheduler(new RoundRobinTimeSliceFixedScheduler());
In addition to the prefabricated implementations, you can write your own scheduling algorithms. To do this, you implement the com.agentfactory.platform.coreIScheduler interface:
public interface IScheduler {
public void register(IAgent agent);
public void unregister(IAgent agent);
public void resume(String name);
public void suspend(String name);
public void step(String name);
}
The first two methods handle registration and deregistration of an agent with the scheduler. The latter three methods handle scheduling of the agent (i.e. resumption, suspension, and stepping of the agent).
Adding Platform Services
A Platform Service is a shared resource that is available for all agents residing on the platform to use. Access to and the creation of platform services is managed by the Platform Service Manager component of the agent platform. To retrieve a reference to this component, you simply call the getPlatformServiceManager() method on the agent platform (as is shown below). This method actually returns the object reference cast as the IPlatformServiceManager interface, and you should cast this to type PlatformServiceManager:
PlatformServiceManager manager = (PlatformServiceManager) platform.getPlatformServiceManager();
try {
manager.addService(VacWorldService.class, "vacbotworld");
} catch (NoSuchServiceException ex) {
Logger.getLogger(TestMain.class.getName()).log(Level.SEVERE, null, ex);
}
As can be seen above, adding a service involves two pieces of information:
- the class that implements the service, and
- a unique identifier for the service.
The above example installs the VacWorldService, a platform service that is used to deploy the Vac World demonstrator, and associated the identifier "vacbotworld" with this service. The identifier is used by the agents to bind to the service, and once bound, the agents are able to interact with that service as required.
Installing Agent Architectures
Agent Factory allows you to associate multiple agent architectures / interpreters with an agent platform. This is done by creating Architecture Factory classes that implement the IArchitectureFactory interface:
public interface IArchitectureFactory {
public void configure(Properties configuration);
public IAgent create(String name, Object design);
public boolean filter( Object design );
}
Architecture factories are used by the Agent Management Service to instantiate agents. They are registered with an architecture service that is associated with the agent platform and are invoked via this service. The service works by first using the filter(...) method to match the factory to a given agent design object (this can be a string, a java class reference, or any other object that you deem to be appropriate). When a match is made, the create(...) method is used to instantiate the agent.
An example of an architecture factory is the AFAPL2 architecture factory, which provides support for the instantiation of AFAPL2 agents. Outline code for creating and registering the AFAPL2 architecture factory is given below.
AFAPL2ArchitectureFactory factory = new AFAPL2ArchitectureFactory();
Properties props = new Properties();
props.setProperty("TIMESLICE", "100");
factory.configure(props);
platform.getArchitectureService().registerArchitectureFactory(factory);
In addition to developer driven factories, Agent Factory includes a default Java architecture factory that provides support for creating custom java-based agents that have implemented the IAgent interface. Further details on this can be found in the Creating Custom Java Agents Guide.
Adding Monitoring / Debugging Tools
With the new approach to deploying agent based applications, there are no constraints placed on the creation of tools for managing / monitoring / debugging agent platforms. All you need to do is pass in a reference to the agent platform and you are free to do what you want from that point onwards. One very useful tool that comes packaged with Agent Factory is the Agent Factory Debugger. This generic tool provides support for managing the agents on an agent platform and inspecting the state of the deployed agents. You can launch this tool by adding the following lines of code:
Debugger debugger = new Debugger(platform); debugger.registerInspectorFactory(new AgentSpeakInspectorFactory()); debugger.registerStateManagerFactory(new AgentSpeakStateManagerFactory()); debugger.registerInspectorFactory(new AFAPL2InspectorFactory()); debugger.registerStateManagerFactory(new AFAPL2StateManagerFactory()); debugger.start();
The first line creates the debugger; the next four lines configure the debugger to support debugging of AF-AgentSpeak and AFAPL2 agents respectively; and the final line launches the tool.
Creating the initial Community
To create the initial agent community, you need to get a reference to the pre-installed Agent Management Service. Through this service, you can programmatically create, terminate, resume or destroy agents.
To outline code to do this is:
AgentManagementService ams = (AgentManagementService) platform.getPlatformServiceManager().getServiceByName(AgentManagementService.NAME);
try {
// 1. Create an agent
IAgent agent = ams.createAgent("rem", "com/agentfactory/afapl2/core/agent/AMSSupport.agent");
// 2. Give it initial beliefs / goals
agent.initialise("BELIEF(happy)");
// 3. Resume the agent (start it)
ams.resumeAgent("rem");
} catch (NoSuchArchitectureException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
} catch (DuplicateAgentNameException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
