next up previous
Next: IV-B Mobile Agent for Up: IV Implementation of a Previous: IV Implementation of a

IV-A Adaptation Framework

Our prototype implementation assumes the programming language Java and a Java-based mobile agent environment, such as ObjectSpace Voyager. In the case of Java we specifically benefit from its functionality for dynamic class linking and reflection, as will be explained.

The adaptation framework includes three components. Two stand-alone tools - the adaptor generator and repository - and a library of classes which are introduced into the existing agent framework by their use in adaptor stubs. This covers functionality related to reconfiguration and context awareness, plus functionality related to the expression and comparison of profiles and profile values. Fig. 7 gives an overview of the components involved in adaptation, again refering to our standard example involving software configuration tasks.


 
Figure 7: Overview of the Adaptation Architecture for the Configuration Management Agent  

The adaptors are generated by the adaptor generator presuming that the adaptation design pattern has been followed by the mobile agent programmer. That means the adaptable parts are realized as implementation classes and the functionality interface between the core and the adaptable parts is described as a Java interface. The adaptor generator reads the Java byte code of the interface, and produces the adaptor class in Java source code format. The adaptor class is used in the core instead of the implementation classes. By convention the adaptor class name is derived by the adaptor generator from the functionality interface name as: $\hbox{{<TT\gt<adaptor name\gt</TT\gt}
{<tex2html_image_mark\gt ... .

As a more sophisticated alternative to the current adaptor generator, we foresee an implementation that operates transparently at runtime, in a mode similar to the one applied by ObjectSpace Voyager for its own remote communication stubs.

The adaptor class implements the methods as declared in the interface. The body of the method implementations contains the adaptation and the delegation of the method call to an implementation class instance. The adaptation includes the context awareness module and reconfiguration component. The name of the implementation class is resolved by the context awareness module and the right implementation class is loaded by the reconfiguration component. The actual method is executed by the instance of the loaded implementation class. Since the adaptor generator needs to retrieve the interface name and the method declarations from the interface, it introspects the interface by using Java reflection.

Fig. 7 shows that the methods setDiskCache() and setMemoryCache() are declared in the functionality interface IConfiguration and are implemented by the adaptor class IConfiguration_Adaptor. The adaptor class performs the adaptation by making use of functionality in ContextAwareness and Loader.

Assuming Configuration_XY is the right implementation class for the current environment where the core is running, the method calls, setDiskCache() and setMemoryCache(), are delegated by the adaptor class to the instance of implementation class Configuration_XY when a corresponding call is made by the core. Hence the actual adaptation occurs in between two events: first when the call through the interface commences, and second when the call reaches an implementation class.

The context awareness is realized by the class ContextAwareness which loads the implementation profiles of all available implementation classes from the repository and executes them. The execution of the implementation profiles includes the generation of environment profiles and the comparison of the profile values. The implementation profile is realized as a Java class containing the set of profile values. A profile value is also represented by a subclass of the abstract class ProfileValue.


  
Figure 8: Profile Value Classes

Fig. 8 shows the hierarchy of the profile values used for the operating system. The abstract super-class ProfileValue is refined into a concrete class OperatingSystem which implements the inherited method getEnvProfileValue() for retrieving the name of the operating system in the current environment. The class OperatingSystem represents a type of a profile value. For instance CpuArchitecture and DefaultWebBrowser might be other profile value types needed by the implementation class descriptions in the example of the configuration for the browser. Classes such as Linux, AIX, etc. are grouped together as Unix flavors under class UNIX and each of these can be used by the programmer of the implementation classes (component developer) for describing the necessary environment. The properties of the profile values can be mapped into the OO hierarchy as shown for the case of Unix. The component developer simply uses the class UNIX if the implementation class is suitable for any Unix flavor. In this way we achieve a flexible metric for comparing environment properties, at the price of defining few additional classes.

The implementation profile and the profile values must be integrated into the implementation class by the component developer. Every implementation class includes a method getProfile() which retrieves the profile values. The body of this method realizes the environment description of the suitable environment. Fig. 9 shows an example for an implementation class suitable for a x86 host running Windows NT and Netscape as configured default web browser.


 
Figure 9: getProfile() 

The loading of the implementation classes is done by a modified Java class loader. Loader loads the implementation class according to the class name delivered from the context awareness tool. The implementation class is loaded by the Loader class from the repository through the class RepositoryClient (Fig. 7). The same class is used by ContextAwareness for communication with the repository.

In our prototype implementation the repository is a stand-alone application serving the profiles and implementation classes. For keeping the autonomy of the mobile agent the chosen repository concept provides proxy repositories which are started along the route of the mobile agent. This maintains agent autonomy at a higher level, yet it also keeps the possible communication overhead caused by adaptation relatively low.

We distinguish between central repository and proxy repositories. Communications between a nascent mobile agent and repository should be "sufficiently local" to make efficient use of bandwith. For this purpose a neighborhood metric can be defined depending on the application scenario. Using this metric the agent can determine the "nearest" repository, with e.g. one repository proxy serving per subnet.


next up previous
Next: IV-B Mobile Agent for Up: IV Implementation of a Previous: IV Implementation of a
Copyright Munich Network Management Team