A Mobile Code Framework and
Mobile Agent Facility
Specifications
Tony White
email: tony@sce.carleton.ca
URL: http://www.sce.carleton.ca/researchers/tony/index.html
Overview
• Introduction:
– taxonomies of mobile code.
• Mobile Code Framework (MCF):
– overview,
– applications.
• Programming mobile agents (MCF).
• Mobile Agent Facility Specification (MAF).
• Summary.
Taxonomies of mobile code
General
• POP technology or Code-on-demand (COD)
• PUSH technology or Remote Evaluation (REV)
• Autonomous Mobile Agent (AMA)
Application oriented
• applets - downloadable applications
• servlets - uploadable services
• extlets - uploadable or downloadable features
• deglets - delegated tasks
• netlets - autonomous tasks
piglets - malicious mobile code
Mobile Code Framework
Tony White
email: tony@sce.carleton.ca
URL:
http://www.sce.carleton.ca/researchers/tony/index.html
Transport infrastructure
compressed
code
NC compressed MCD
code JVM
listening on NC
a well-known port
(UDP or TCP)
MF
Sec Comm MCD
JVM
MCD NC
JVM NC - Network Component
JVM - Java Virtual Machine
Java
thread
MCD - Mobile Code Daemon
MF - Migration Facility
Comm - Communication Facility
Sec - Security Facility
Virtual Managed Component
Managed Resources
Security Interface to Management Recovery Provisioning
Managed
Methods Applets Procedures Procedures
Resources
Virtual Managed Component Interface (VMCI)
External parties
Communications
Local communications: FAC MCD
Remote communications: MED + FAC MED
FAC
JVM
MCD
NC
FAC
MCD
JVM
NC FAC
JVM
FAC Facilitator
MED Mediator
JVM Java Virtual Machine NC
MCD Mobile Code Daemon
Security
• Authentication
– DSA, RSA, or PGP
• Data Integrity
– MD5, SHA
• Data Privacy
– Encryption
• Authorization (Access Control)
– Access Control List
Flow Diagram of
Infrastructure’s Operation
NC (sender) NC (receiver)
request a connection receive and no
trusted discard the
and start migrating store the
code ? mobile code
mobile code
yes
inform inform
the manager has the manager
yes
migrated ?
call method:
onDestroy restore states
no
call method:
failed done
onFailedMigrate call method: call method:
start 1. onInit 1. onRestore
migrating 2. onStart 2. onStart
inform
the manager stop
wrap up migrate mobile code running
call method:
its states and performing its tasks
onMigrate
if requested
call method: start Mobile code call method:
onStart idle onStop
How it works...
WinMCTClient
Mobile Agent
Manager
Default migration patterns not shown
Deglets: Network
auto-discovery
Host browser
PC 1
Printer 1
NC 1
Applets: Component-supported
browsing
Host browser
PC 1
PC 2
Printer 1
Printer 2
NC 1
Router
Laptop
Plug-and-play components
Internet
Network
Printer vendor
printer driver (updates)
Servlets: Mobile servers
myTelnet
host 1
host 2
myTelnet myTelnet
handler myTelnet handler
Security server
Private Security
key server
repository
Virtual
Security
Managed
facilitator
Component
Communication server
Agent
registry
Local
communication
facilitator Communication
server
Migrating servers
Comm
server
clone
Communication
server
Dynamic applications
Application server
Basic
word-processing
component
Advanced function
Application server component
Need basic Need advanced
wordprocessor function
Universal message server
Message
Message + Message + +
Message
server message profile
message profile Device profile
User profile
Message +
message profile
Message handler
(e.g., voice memo) Device profile
User profile
Message handler
(e.g., virtual reality)
Presentation
server
Mobile Code Toolkit: An
Implementation of the Mobile
Code Framework
Tony White
email: tony@sce.carleton.ca
URL: http://www.sce.carleton.ca/researchers/tony/index.html
Directory Structure
mct
NetletDaemon.java
admin net mediator security users
Ctp
MobileCodeDaemon MobileCodeDatabase All interfaces,
MobileCodeManager Facilitator Sample code
StorageManager Mediator (Netlet, Extlet, VMC)
MobileCodeContainer
Instantiator
URL: http://www.sce.carleton.ca/netmanage/mctoolkit/
User Interfaces
MobileCode
getID () getInfo ()
getType () Netlet
setStub () private stub;
Migratable
migrate ()
onMigrate ()
MCDExtension
getMobileCodeManager () Class
getStorageManager ()
Parameters VMC
get/set Parameter () private stub; Interface
getParameterNames ()
VMCManagedResources
get/getBulk/getNext ()
set ()
delete ()
VMCAccess
getVMC () Extlet
getVMCList ()
Callback
private stub;
onStart ()
onInit ()
onRestore ()
Writing a netlet
public class MyNetlet implements MobileCode, Callback, ....., Serializable {
private MobileCodeStub stub = null; // Defined here but set by the MCM !
// Implement all methods of the MobileCode interface
public setStub (MobileCodeStub stub) { // Nobody but MCM should call this !
this.stub = stub;
}
......
// If you want your netlet to run, implement the Callback methods
public onStart () {
for (;;) { .... }
}
// Implement all methods of all other interfaces implemented
public aMethod (...) {
if (stub != null) {
stub.aMethod (...);
}
}
Implementing a VMC
public class myVMC implements VirtualMobileCode,
VMCManagedResources, ... , Serializable {
private MobileCodeStub stub = null; // Defined here but set by the MCM !
// Implement all methods of the (Virtual) MobileCode interface
public setStub (MobileCodeStub stub) { // Nobody but MCM should call this !
this.stub = stub;
}
.....
// Implement all methods of all other interfaces implemented
public aMethod (...) {
if (stub != null) {
stub.aMethod (...);
}
Launching your netlet
a) Must put your file in .jar format:
jar cvf YourNetlet.jar YourNetlet.class
b) Send your netlet to a running MCD:
1. Use WinMCTClient ... the pusher
2. Write an applet ...
You must read a .jar file into a mobileCodeContainer and
use the CodeTransferProtocol to send the container to a MCD.
eg. ctp.send (mcc);
Copy the code from WinMCTClient to do this.
3. Property Files used to pre-install code during the startup of a MCD
Properties Files I
# Set up a unique id for the netletdaemon
netletdaemon.id=ND0001
# Set up the listening ports for this netletdaemon
netletdaemon.listen.tcp.port=3100
netletdaemon.listen.udp.port=3200
# Set up the default migration facility
netletdaemon.default.migration.tcp.ip=localhost
netletdaemon.default.migration.tcp.port=3300
netletdaemon.default.migration.udp.ip=localhost
netletdaemon.default.migration.udp.port=3400
netletdaemon.default.protocol=tcp
# Set up the Facilitator (.... NOT the Mediator !)
netletdaemon.facilitator.enable=true
netletdaemon.facilitator.port=8888
netletdaemon.mediator.ip=localhost
netletdaemon.mediator.port=6666
Properties Files II
# Pre-install class files
netletdaemon.install.mobilecode.0=mct.mediator.Mediator
netletdaemon.install.mobilecode.1=ReceiveNetlet
netletdaemon.install.mobilecode.2=AnotherNetlet
# Pre-install mobile code jars file
netletdaemon.install.mobilecode.jar.0=SendNetlet
netletdaemon.install.mobilecode.jar.0.0=SendNetlet.jar
netletdaemon.install.mobilecode.jar.1=ReceiveNetlet
netletdaemon.install.mobilecode.jar.1.0=ReceiveNetlet.jar
#Security
netletdaemon.security.enable=false
#netletdaemon.security.enable.MCDSecurityManager=false
#netletdaemon.security.url.key.database=url
#netletdaemon.security.root=Admin
#netletdaemon.security.user.allows.access.mobilecodemanager.0=Admin
#netletdaemon.security.user.allows.access.storagemanager.0=Admin
The SuperNetlet
• Implements all interfaces:
– found in SuperNetlet.java,
– MobileCode, Callback, Parameters, Migratable,
– MCDExtension,VMCAccess,MessagingAccess
• Gives the netlet “super powers”
• Makes netlet code larger
• Provides default behaviour for everything!
• Good starting point for netlet development
The SuperNetlet I
public class SuperNetlet implements MobileCode,
Callback,
Parameters,
Migratable,
MCDExtension,
VMCAccess,
MessagingAccess {
// Declare the interface stub
private MobileCodeStub stub=null;
private String ID=null;
…
}
The MobileCode Interface
public String getID () { /**
if (ID==null) { * Called automatically when a
Random rand = new Random (); SuperNetlet is constructed
ID = "N"+rand.nextInt(); */
} final public void setStub
return ID; (MobileCodeStub stub) {
} this.stub = stub;
}
final public String getType() {
return "Netlet";
}
public String getInfo () {
return null;
}
public String getAlias() {
return
this.getClass().getName();
}
The Parameters Interface
public Object getParameter public Enumeration getParameterValues(){
(Object name) { if (stub!=null) return
if (stub!=null) return stub.getParameterValues();
stub.getParameter(name); return null;
return null; }
}
public Enumeration getParameterNames() {
public Object removeParameter if (stub!=null) return
(Object name) { stub.getParameterNames();
if (stub!=null) return return null;
stub.removeParameter (name); }
return null;
}
public void putParameter (Object
name, Object value) {
if (stub!=null)
stub.putParameter (name,value);
}
The Migratable Interface
public int onMigrate() { public void migrate (String name,
if (this instanceof Serializable){ boolean flag) {
return SERIALIZE; if (stub!=null)
} else { stub.migrate (name, flag);
return DONT_SERIALIZE; }
}
} public void migrate (String name,
InetAddress ip,
public void migrate (MobileCode int port,
mobileCode, boolean flag) { boolean flag) {
if (stub!=null) if (stub!=null)
stub.migrate (mobileCode, flag); stub.migrate (name, ip, port, flag);
} }
public void migrate (MobileCode public void onFailMigrate (InetAddress ip,
mobileCode,
int port,
InetAddress ip,
boolean isTCP){
int port, boolean flag) {
System.err.println
if (stub!=null)
("SuperNetlet::onFailMigrate");
stub.migrate (mobileCode, ip,
}
port, flag);
}
The Callback Interface
public void onRestore () {
public boolean isActive() { System.out.println ("SuperNetlet : onRestore");
}
if (stub!=null) return
stub.isActive(); public void start() {
return false; if (stub!=null) stub.start();
} }
public void onStart () {
public void init() { System.out.println ("SuperNetlet : onStart");
if (stub!=null) stub.init(); }
} public void stop() {
if (stub!=null) stub.stop();
public void onInit () { }
System.out.println ("SuperNetlet public void onStop () {
: onInit"); System.out.println ("SuperNetlet : onStop");
} }
public void restore() { public void destroy() {
if (stub!=null) if (stub!=null) stub.destroy();
}
stub.restore();
} public void onDestroy () {
System.out.println ("SuperNetlet : onDestroy");
}
The VMCAccess Interface
public MobileCode getVirtualManagedComponent(String name, boolean className) {
if (stub!=null) {
return stub.getVirtualManagedComponent(name, className);
} else {
return null;
}
}
public Enumeration getVirtualManagedComponentList() {
if (stub!=null)
return stub.getVirtualManagedComponentList();
return null;
}
The MessagingAccess Interface
public void onMessage () {
System.out.println ("SuperNetlet :
onMessage");
}
public void send (Message message) {
if (stub != null) {
stub.send (message);
} else {
return;
}
}
public Message[] receive () {
if (stub != null) {
return stub.receive ();
} else {
return null;
}
}
The MCDExtension Interface
public Object public void addJAR (String name,
getMobileCodeManager(){ byte bytes[]) {
if (stub!=null) return if (stub!=null)
stub.getMobileCodeManager(); stub.addJAR(name,bytes);
return null; }
}
public MobileCodeContainer
public StorageManager getMobileCodeContainer() {
getStorageManager(){ if (stub==null) return null;
if (stub!=null) return return stub.getMobileCodeContainer();
stub.getStorageManager(); }
return null;
} public boolean
verifyMobileCodeContainer(){
public void instantiate if (stub==null) return false;
(MobileCodeContainer mcc) { return
if (stub!=null) stub.verifyMobileCodeContainer();
stub.instantiate(mcc); }
}
tcpListener Instantiator
1
mcc = ctp.receive (..) queue
Code arrives 3
... Reads code from socket queues mcc
... Add code to queue addElement (mcc) {
queue.add (mcc)
2 resume ();
creates }
run () {
for (;;) {
MobileCodeContainer suspend;
mcc = queue.get (mcc)
onInit () onStart () verify mcc
Put mcc in storageManager
spawns Instantiate the mcc
MobileCodeRunner
extends Thread }
5 }
6 run () {
mcm.instantiate (mcc) 4
} puts mcc
runs mcc
MobileCodeManager StorageManager
vmcInstances 8 mcHandler
mcInstances
putContainer ()
instantiate () { 7 getContainer ()
Get mcc from storageManager gets mcc
Load mcc’s classes
If it’s a VMC
vmcInstances.add ()
Else it’s a MobileCode
mcInstances.add ()
9
set mcc’s state = RUNNING
call mcc’s onInit ()
What happens when Mobile Code
call mcc’s onStart ()
} Arrives at the MCD?
StorageManager (sm)
NetletDaemon
mcHandler
get/putContainer ()
MobileCodeDaemon
tcpListener stores MCC
udpListener
storageManager (sm)
mobileCodeManager (mcm) MobileCodeManager (mcm)
instantiator
mcDatabase (Faciliator)
installFacilitator () mcInstances access
installMobileCode () vmcInstances
installMobileCodeJar ()
get/putMobileCodeContainer ()
tcpListener udpListener instantiate ()
addElementToInstantiator ()
init (), start (), stop (), restore ()
migrate ()
queues get/putParameter ()
getVMC (), getVMCList ()
Instantiator send (), receive ()
queue instantiates .... MobileCodeStubImplemenation
addElement ()
run ()
uses
MCD (admin)
MobileCodeStub (Implementation)
User (netlet or vmc) init (), start (), stop (), restore ()
migrate ()
instantiate () .........
Major MCT Classes MobileCode
stub
VirtualMobile
Code
setStub ()
Netlet MobileCodeStub MobileCodeManager
stub
getParameter() {
stub.getParameter () mcm. getParameter ()_ getParameter () {
} mcc = sm.getContainer
return mcc.getParameter ()
}
Netlet MobileCodeStub MobileCodeManager
stub
getVMCList () {
stub.getVMCList () mcm.getVMCList() getVMCList() {
} return vmcInstances.keys ()
}
Netlet MobileCodeStub MobileCodeManager
stub
migrate () { migrate () {
stub.migrate () mcm. migrate ()
sm.getContainer (mcc)
} ctp.send (mcc)
sm.removeContainer (mcc)
}
NOTE : migrate () does not
Netlet interface call trace kill the current thread !!!
MobileCodeDatabase
table
Sending a Remote Message
mailbox
add/remove/get ()
Mediator
mcdDatabase
add/remote/getMCDRecord ()
spawns
HandleMediatorClient HandleMediatorClient
permanent mp
Facilitator Facilitator
mp mp
register () register ()
deliverMsg () deliverMsg ()
spawns
HandleFacilitatorClient
Sender
Receiver
send ()
onMessage ()
Mobile Agent Facility
Specification
Tony White
email: tony@sce.carleton.ca
URL: http://www.sce.carleton.ca/researchers/tony/index.html
MAF Specification
• Reasons for specification:
– INTEROPERABILITY,
– mobile agents require environment in which to
execute;
– various languages need to be supported, e.g.
Java, AgentTCL, Smalltalk, Scheme;
– various agent implementations need to be
supported, e.g. Aglets, Odyssey, Voyager;
– standard services need to be supported, e.g.
naming, authentication, communication,
notification, transfer.
MAF Architecture
Operating System Operating System
Agent System Agent System
Agent Agent
Non-agent
System
Communication Network Communication
infrastructure infrastructure
Basic Agent Definitions
• Authority: the person or organization for
whom/which the agent acts.
• Location: the address of a place (IP
address, port, and place name).
• State: code plus serializable attribute
values. May also contain execution state.
• System: a platform capable of supporting
agent authentication, execution and
migration.
More Agent Definitions
• Name: unique handle within the scope of
authority of the agent.
• Type: a standards-allocated identifier to
allow a system to determine the nature of
the agent, e.g. Aglet, AgentTCL.
• Place: context in which the agent executes;
allows for resource access control.
• Region: set of agent systems that have same
authority.
Agent Region
Agent Agent Region
System System
CI CI
Agent Agent
from System System
another
region
CI Agent CI
Agent
System System
CI CI
Mobile Agent Facilities
• Region interconnection
– region access points.
• Serialization and deserialization
– storage and retrieval of agents.
• Communications infrastructure
– RPC, naming, security, locating.
• Agent interaction
– remote agent creation;
– agent transfer;
– agent method invocation.
Agent Transfer I
• Initiating agent transfer:
– create trip request;
– suspend agent thread;
– identify portions of agent’s state to be
transferred;
– serialize agent’s class and state variables;
– encode serialized agent using transport protocol
(many may be defined);
– transfer agent;
– destroy agent locally if transfer successful,
continue otherwise.
Agent Transfer II
• Receiving agent transfer:
– decode agent;
– authenticate agent;
– deserialize the agent’s class and state;
– instantiate the agent;
– restore the agent’s state;
– resume agent execution.
Transfer of Agent Class
• Automatic transfer of all possible classes:
– send all classes needed to execute agent.
• Automatic transfer of agent’s class only:
– remaining classes transferred on demand.
• As above, but transfer all classes for remote
agent creation.
• Transfer class names only:
– receiving location requests classes for those not
cached.
Security Problems
• Threats:
– denial of service to legitimate agent;
– unauthorized access to agent system;
– corruption of agent or agent data;
– ...
• Techniques:
– flooding of system with excessive requests;
– falsification of identity;
– recording (and subsequent replay) of agent
activity;
– eavesdropping;
Security Solutions
• Agent providers want network to provide:
– confidentiality (identity and communications),
– integrity guarantees,
– authentication,
– replay detection.
• Agents need to provide:
– identities that can be authenticated;
– capabilities,
– resource consumption limits;
– access rights.
What the standard actually says...
• The MAF standard specifies agent:
– management,
– tracking,
– transport.
• Extensive use of CORBA services:
– IIOP,
– naming,
– lifecycle,
– externalization (or serializability),
– security (using Common Secure
Interoperability Specification).
MAF Interfaces
• Two interfaces defined for MAF module:
– MAFAgentSystemInterface
– MAFFinderInterface
MAFImplementation
MAFClient
MAFAgentSystem
MAFFinder
ORB
MAFFinder
• Naming service for agents
– registered as CORBA objects
– maybe shared between regions
– maybe arranged in hierarchies (?)
Agent MAFFinder MAFFinder
Agent
System A System C
Agent Agent
System B System D
MAF IDL Types (I)
typedef short AgentSystemType;
struct ClassName {
string name;
OctetString discriminator;
};
typedef sequence ClassNameList;
typedef sequence OctetString;
typedef OctetString Authority;
typedef OctetString Identity;
struct Name {
Authority authority;
Identity identity;
AgentSystemType agent_system_type;
};
MAF Location I
• Locations need to be described
mafuri := scheme “:” location
scheme := “CosNaming” (RFC 1630)
location := components | “/” location
components := component |
component “/” components
component := id “!” kind
id := xpalphas (RFC 1630)
kind := xpalphas
MAF Location II
mafuri := scheme “:” location
scheme := “mafiiop”
location := “//” [hostport “/”]
agentsystem [“/” place]*
hostport := host “:” port
host := hostname | hostnumber
port := digit+
agentsystem := uchar+
place := uchar+
MAF IDL Types (II)
typedef short languageID;
typedef short AgentSystemType;
typedef short Authenticator;
typedef short SerializationID;
typedef sequence SerializationIDList;
struct Property {
string name;
string value;
};
typedef sequence PropertyList;
struct LanguageMap {
LanguageID language_id;
SerializationIDList serializations;
};
typedef sequence LanguageMapList;
MAF IDL Types (III)
struct AgentSystemInfo {
Name system_name;
AgentSystemType system_type;
LanguageMapList language_maps;
string system_description;
short major_version;
short minor_version;
PropertyList properties;
};
struct AuthInfo {
boolean is_auth;
Authenticator authenticator;
};
MAF IDL Types (IV)
struct AgentProfile {
LanguageID language_id;
AgentSystemType agent_system_type;
string agent_system_description;
short major_version;
short minor_version;
SerializationID serialization;
PropertyList properties;
};
enum AgentStatus {Running,Suspended,Terminated};
typedef string Location;
typedef sequence Locations;
typedef sequence Arguments;
MAFAgentSystem interface
create_agent(
in Name agent_name,
in AgentProfile agent_profile,
in OctetString agent,
in string place_name,
in Arguments arguments,
in ClassNameList class_names,
in string code_base,
in MAFAgentSystem class_provider) raises
(ClassUnknown, ArgumentInvalid, SerializationFailed,
MAFExtendedException);
Creates agent within target agent system.
MAFAgentSystem Interface
OctetStrings fetch_class(
in ClassNameList class_name_list;
in string code_base;
in AgentProfile agent_profile) raises
(ClassUnknown, MAFExtendedException);
Fetches a list of classes from the target system.
MAFAgentSystem Interface
Location find_nearby_system_of_profile (in AgentProfile profile)
raises (EntryNotFound);
Asks the MAFFinder to find a nearby agent system that
can execute the agent the client wants to send.
Agent_Status get_agent_status (in Name agent_name) raises
(AgentNotFound);
Returns the status of an agent.
MAFAgentSystem Interface
AgentSystemInfo get_agent_system_info();
Returns the AgentSystemInfo structure.
AuthInfo get_authinfo(in Name agent_name) raises (NameInvalid);
Returns information about whether an agent was authenticated
and what authentication method was used.
MAFFinder get_MAFFinder() raises (MAFFinderNotFound);
Returns a reference to a MAFFinder, used for agent location.
void terminate_agent_system() raises (TerminateFailed)
Terminates the execution of the agent system.
MAFAgentSystem Interface
void receive_agent(
in Name agent_name,
in AgentProfile agent_profile,
in OctetString agent,
in string place_name,
in ClassNameList class_names,
in string code_base,
in MAFAgentSystem agent_sender) raises
(ClassUnknown, ArgumentInvalid, DeserializationFailed,
MAFExtendedException);
Used to receive a migrating agent and to instantiate it.
MAFAgentSystem Interface
void resume_agent(in Name agent_name) raises
(AgentNotFound, ResumeFailed, AgentIsRunning);
Resumes the agent (assuming suspended).
void suspend_agent(in Name agent_name) raises
(AgentNotFound, SuspendFailed, AgentIsSuspended);
Suspends the agent (assuming running).
void terminate_agent(in Name agent_name) raises
(AgentNotFound, TerminateFailed);
Terminates the agent.
MAFFinder Interface
Locations lookup_agent(
in Name agent_name;
in AgentProfile agent_profile) raises
(EntryNotFound);
Returns the locations of the specified agents, either found by name or
profile.
Locations lookup_agent_system(
in Name agent_system_name;
in AgentSystemInfo agent_system_info) raises
(EntryNotFound);
Returns the locations of the specified agent systems, either found by
name or profile.
MAFFinder Interface
Location lookup_place(in string place_name) raises(EntryNotFound);
Returns the location of the place indicated.
void register_agent(
in Name agent_name,
in Location agent_location,
in AgentProfile agent_profile) raises
(NameInvalid);
Registers the given agent with the MAF.
void register_place(
in string place_name,
in Location place_location) raises
(NameInvalid);
Registers the place with the MAF.
MAFFinder Interface
void register_agent_system(
in Name agent_system,
in Location agent_system_location,
in AgentSystemInfo agent_system_info) raises
(NameInvalid);
Registers the given agent system with the MAF.
void unregister_place(in string place_name) raises (NameInvalid);
Unregisters the place with the MAF.
void unregister_agent(in Name agent_name) raises (NameInvalid);
Unregisters the agent with the MAF.
void unregister_agent_system(in Name agent_system_name) raises
(NameInvalid);
Unregisters the agent system with the MAF.
MAF Scenario (I)
The search for widgets...
Agent
Agent
Agent System B
System A
register_agent_system,
register_agent_system, register_place
Stationary register_place
MAFFinder
Client
MAF Scenario (II)
An agent’s work is never done...
Agent
4. migrate_agent
3. register_agent
Agent
Agent System B
5. receive_agent
1. getMAFFinder
System A 6. fetch_class
7. unregister_agent
2. create_agent 8. register_agent
Stationary MAFFinder
Client
MAF Scenario (III)
Jim steps in… he wants to know what
widgets have been found!
Agent
Agent
Agent System B
System A 2. get_agent_status
3. client_authentication
4. return status
Stationary MAFFinder
Client 1. lookup_agent
Observations on the MAF
Specification
• Limited in scope.
• No notification services.
• No mechanism for interaction with agents.
• Interface(s) impoverished:
– can’t ask the question, “List all agents at X”
• Security NOT addressed at all!
• Some lack of clarity:
– unregister/register requirement.
References
• Aglets workbench
– http: //www.trl.ibm.co.jp/aglets
• Mubot
– http://www.crystaliz.com
• Odyssey
– http://www.genmagic.com/agents
• Mobile Objects and Agents
– http://www.opengroup.org/RI/java/moa/index.htm
• Perpetuum Mobile Procura
– http://www.sce.carleton.ca/netmanage/perpetuum.shtml
Mobile Code Toolkit
Extensions:
Messaging, Events, Rationalization
Important Changes
• “thread” attribute of stub moved to
MobileCodeStatus.
• mcInstances, vmcInstances merged to
mobileCodeInstances.
• MobileCode interface only contains
getType, other functionality provided by
MobileCodeObject.
• Status associated with MobileCodeStatus
expanded to include:
– migrating, communicating, migrated...
More Important Changes
• MobileCodeObject is used everywhere
throughout the MobileCodeManager;
MobileCode references removed.
• MCDExtension interface split into:
– MCDInterface: access MobileCodeManager
– MCDExtension: extend mobile code
• onInit(), onInit(Properties) invoked whenever
new MobileCodeObjects are instantiated.
• onRestore always called after first and
subsequent migrations.
MCIdentifier and
MobileCodeObject
public class MCIdentifier implements Serializable {
private String name;
private String className;
private String authority;
private static String delimeter = "@";
private static String[] authDelimeter= {“[“, “]”};
}
public class MobileCodeObject implements java.io.Serializable {
private MCIdentifier identifier;
// Declare the interface stub as transient in order to avoid it
// being serialized when written out.
public transient MobileCodeStub stub=null;
private String info="";
}
MCIdentifier Examples
• Three components:
– Blackboard[PUBLIC]@mct.blackboard.MsgBlackBoard
– Blackboard[MYBB]@mct.blackboard.MsgBlackBoard
– MyBB[PUBLIC]@mct.blackboard.MsgBlackBoard
– mct.admin.RemoteMigrationFacilitator
• Null authority not allowed
• Null class not allowed
MethodRunnerThread
public class MethodRunnerThread extends Thread {
private Receiver receiver;
private Object [] parameters;
}
public MethodRunnerThread (Object object, String methodName,
Object [] parameters, ThreadGroup threadGroup) {
super (threadGroup, object.toString()+"->"+methodName);
Class [] parameterTypes = new Class[parameters.length];
for (int i = 0; i < parameters.length; i++)
parameterTypes[i] = parameters[i].getClass();
this.receiver= new Receiver(object, methodName,
parameterTypes);
this.parameters = parameters;
start();
}
MethodRunnerThread
public void run() {
try {
receiver.invoke(parameters);
}
catch (java.lang.IllegalAccessException ex) {}
catch (java.lang.reflect.InvocationTargetException ex) {}
}
A handler can also be associated with these threads…
See mcd.admin.ExceptionHandler interface for details
Receiver
public class Receiver {
private Object object;
private Method method;
}
public Receiver ( Object object, String methodName,
Class [] parameterTypes) {
try {
this.method =
object.getClass().getMethod(methodName, parameterTypes);
this.object = object;
} catch (java.lang.NoSuchMethodException ex) {
this.method = null;
this.object = null;
}
Receiver
public void invoke (Object [] parameters )
throws java.lang.IllegalAccessException,
java.lang.reflect.InvocationTargetException {
Class [] parameterTypes = method.getParameterTypes();
int size1 = Array.getLength(parameters);
int size2 = Array.getLength(parameterTypes);
if (size1 != size2)
return;
else {
for (int i = 0; i < size1; i++) {
if (!(parameterTypes[i].isInstance(parameters[i])))
return;
}
}
method.invoke(object, parameters);
}
Events
MCTEvent
MCEvent MigratableEvent
MCTGenericEvent
CallbackEvent
Each event class has an associated listener class
EventListener
MCTEventListener
CallbackEventListener MigratableEventListener
netletInitialized migrated
netletResumed MCEventListener
netletStarted addMobileCode
netletStopped removeMobileCode
netletSuspended
MCTGenericEventListener
public class MCTGenericEventListener {
private MCTGenericEvent event;
private Receiver receiver;
}
public MCTGenericEventListener ( MCTGenericEvent event,
Object object, String methodName, Class [] parameterTypes) {
this.event = event;
this.receiver = new Receiver(object, methodName, parameterTypes);
}
MCTGenericEventListener
public void process (MCTGenericEvent event ) throws
java.lang.IllegalAccessException,
java.lang.reflect.InvocationTargetException {
if (interestedIn(event))
invoke(event);
}
public boolean interestedIn(MCTGenericEvent event) {
return this.event.equals(event);
}
public void invoke(MCTGenericEvent event) throws
java.lang.IllegalAccessException,
java.lang.reflect.InvocationTargetException {
receiver.invoke(event);
}
Events
MobileCodeManager MCTEventMulticaster
notify
Forwards an event to forward
all registered listeners
register
MessagingDirectory ? Agent Management
Messaging
Mediator
getMobileCodeRecord
addMobileCodeRecord/
removeMobileCodeRecord
addMobileCodeRecord/
getMobileCodeRecord()
removeMobileCodeRecord
MobileCodeDaemon MobileCodeDaemon
MCTEventMulticaster Mediator MCTEventMulticaster Mediator
Listener Listener
register event register event
LocalMCDirectory Facilitator LocalMCDirectory Facilitator
getMobileCodeRecord getMobileCodeRecord
forwardMsg
send/ send/
MobileCodeObject receive MobileCodeObject receive
implements implements
MessagingAccess MessagingAccess
MCD1 MCD2
Facilitator
MobileCodeDaemon
Mediator
LocalMCDirectory
MobileCodeObject
implements MessagingAccess
getMobileCodeRecord() onMessage() receive() send()
(1) (2)
Facilitator
receiveMbx
receiveMbx
sendMbx OR
MethodRunnerThread
extends Thread In Mailbox ACK Mailbox
spawns
synchronized synchronized
(1) sendMbx
Thread (2)
sendMbx
sendMbx OR
uses
(1)
getMobileCodeRecord
FacPort (2) sendMessage
Messaging Protocol
Protocol between two Facilitators
Incoming Messages
From Other
Facilitators
The WinMCTRMIClient
Inject code
Name of to mobile code
mobile code daemon
Authority used Add entry
for code to list
storage/
resolution Delete entry
from list
Name of Destination for
properties file mobile code
(local files only)
New Daemon Properties!
# Set up console
netletdaemon.console=true
# Set up the Facilitator and the Mediator
netletdaemon.facilitator.enable=true
netletdaemon.facilitator.mobilecode=F1@mct.mediator.Facilitator
netletdaemon.facilitator.properties=c:/mct/fac1.prop
# Set up the MigrationFacilitator
netletdaemon.migrator.enable=true
netletdaemon.migrator.mobilecode=MF1@mct.admin.RemoteMigrationFacilitator
# Set up RMI parameters (multiple possible)
netletdaemon.migration.rmi.host.0=localhost
netletdaemon.migration.rmi.name.0=MF2@mct.admin.RemoteMigrationFacilitator
Facilitator Properties
fac.directory.mobileCode=LMCD1@mct.mediator.LocalMCDirectory
fac.directory.properties=c:/mct/examples/messaging/dir.prop
fac.port=6667
fac.mediator.Port=8888
fac.mediator.IP=localhost
fac.mediator.Listener=RML1@mct.mediator.RemoteMediatorListener
Mediator (Directory) Properties
directory.display.enable=true
directory.display.name=“Remote Mediator”
directory.rmi.name=“Mediator”
Writing Mobile Code
• SuperNetlet
– base class where interfaces implemented for
mobility, callback, …
– Methods to be overloaded:
• onInit(java.util.Properties), onStart(), onStop(),
onDestroy()
• onMigrate(), onFailMigrate(InetAddress, int, int)
• onMessage()
• SuperVirtualManagedComponent
– base class for VMCs
– Overload onInit(java.util.Properties), ...
RMI-based Migration
MCD RMI registry
lookup(String)
MF lookup(String)
transfer(String, String)
MCD
send(MCIdentifier, BitSet, byte[], Properties, URL)
MF
MF
MigrationInterface defines the migration interface
RMI-based migration
• migrate(…) called by agent
– mobile code manager does lookup of remote
migration facilitator (cached)
– onMigrate called for agent
– send(…) called on remote migration facilitator
– authority checked, class loader obtained and
cloned
– class loader checked for class, if not present
lookup local migration facilitator
– transfer(…) called on local migration facilitator
– agent de-serialized and instantiated.
RMIInstantiator
1 RemoteMigrationFacilitator MCTNetworkClassLoader queue
Send(…) loadClass(…)
Code arrives
resolves classes resolves addElement (mco) {
deserializes mc 3 queue.add (mco)
calls onInit(Properties) MobileCodeObject resume ();
}
verifies, stores mcc
4 creates
2 run () {
stores for (;;) {
suspend;
MobileCodeContainer mco = queue.get (mco)
addByteCodes(…) spawn thread for the mco
spawns }
MethodRunnerThread
extends Thread }
7
5
run () {
Verifies, receiver.invoke();
}
creates and
stores
mobile code StorageManager
object MobileCodeManager 6
queues mco
mobileCodeInstances mcHandler
putContainer ()
getContainer ()
verifyMobileCode
What happens when Mobile Code
Arrives at the RMI MCD?
Communication Primitives
• send(Message)
– synchronous send, waits for receiver to read it
• sendAsync(Message)
– asynchronous send
• receive(), receiveAll()
– read message(s) or wait for a message to arrive
• receive(long), receiveAll(long)
– read message(s) or wait “long” msec for one
• peek()
– obtain message without actually reading it
• haveMessages()
– true if agent has waiting messages
Local Events
• Agent must implement MCDInterface
– getEventDispatcher()
– addEvent (String, String, MCTEvent)
• MCTEventMulticaster processes events
– addGenericEventListener(MCTGenericEventListener)
– removeGenericEventListener(MCTGenericEventListener)
Communication Example
RemoteMediator
MCD
PostNetlet
MF
EnquireNetlet
Fac
NotifyNetlet1
Fac MCD
MF MsgBlackboard
NotifyNetlet2