Overview
This is the first of a 3 articles serie. See the 1st an 2nd part.
Uno de los campos más prometedores de los agentes móviles es el diseño de sistemas dinámicos complejos a partir de comportamientos sencillos. En este artículo, final de la serie, conoceremos el API Java del Aglets SDK y programaremos un par de Aglets que sorprenden por cómo tan poco puede hacer tanto.
Finalizaremos la serie con una breve comentario sobre la repercusión que los agentes móviles pueden tener dentro del comercio electrónico (e-commerce).
En el artículo anterior presentamos la arquitectura del ASDK, viendo sus elementos principales y su propósito.
Son muchas más las cosas que podrían decirse de dicha arquitectura pero al presente nivel es, con mucho, más importante aprender los mínimos dentro de la programación de Aglets.
Atacaremos el problema desde dos frentes. Presentaremos primero el API del ASDK a grandes rasgos, aunque con un claro enfoque práctico. En segundo lugar, veremos dos aglets sencillos que presentan una dinámica compleja: los analizaremos de arriba abajo, completando el conjunto con una ejemplo práctico.
Aglets
Los Aglets son objetos Java móviles que se mueven en una red de ordenadores habilitados con aplicaciones host que los gestionen. Para nosotros, un Aglet será todo aquel objeto que extienda directa o indirectamente (a través de otra clase derivada) la clase com.ibm.aglet.Aglet
:
La clase Aglet
provee todos los métodos necesarios para controlar el ciclo vital del agente, así como las actividades que realizará a lo largo del mismo. La Figura C muestra los diferentes grupos en los que podemos clasificar los métodos de la clase Aglet
.
El ciclo vital del Aglet
y su capacidad de respuesta a los eventos que en él ocurran están controlados por los grupos de métodos Operaciones sobre el Aglet y Respuesta y propagación de eventos.
El primer grupo, Operaciones sobre Aglets, contiene métodos declarados como finales (o sea, que no tenemos que implementar) como por ejemplo dispatch(URL destination)
que envía al Aglet al host indicado en el URL, o como dispose()
que lo destruye.
El segundo grupo, Respuesta y propagación de eventos, contiene métodos que manejan los eventos que acontecen al Aglet
. Tras la invocación del método dispatch()
, pero antes de enviar al Aglet, el entorno de ejecución invoca el método onDispatching(), que permite al agente prepararse para el viaje o negarse lanzando una excepción. Cuando el Aglet llegue al nuevo
AgletContext, el entorno de ejecución del sistema que lo ha recibido invocará su método
onArrival()`, informándolo así de su llegada a destino. Todos estos métodos serán los que deberemos reescribir para personalizar el comportamiento de nuestro agente.
La parte de propagación de eventos del segundo grupo contiene métodos para incluir observadores de eventos específicos. Por ejemplo, addCloneListener(CloneListener listener)
añade un observador a la lista de observadores del evento “clonar el aglet”.
El grupo de métodos dedicados a la mensajería permite, entre otras cosas, manejar los mensajes que le llegan al Aglet. Concretamente, el método handleMesage(Message message)
es el encargado de interpretar estos mensajes y realizar las tareas predefinidas para cada uno de ellos:
Obviamente éste, junto con los métodos de respuesta a eventos, será uno de los métodos claves para definir el comportamiento del Aglet.
Finalmente tenemos dos grupos, uno que proporciona información del Aglet o permite establecerla (con métodos como getAgletID()
o getAgletInfo()
), y otro que permite al agente interactuar con el contexto. Encontramos, por ejemplo, métodos para subscribirse a mensajes específicos del contexto, obtener imágenes desde URLs remotos, etc.
Pero el más significativo de este último grupo, y que nos permitirá explorar el entorno, es el método getAgletContext()
. Una vez obtenido el contexto podremos, como vamos a ver a continuación, interaccionar con el resto de Aglets.
El AgletContext
Si queremos lograr que nuestros agentes realicen tareas interesantes, debemos empezar por conocer bien el entorno en el que se moverán, y en el caso que nos ocupa el entorno no es otro que el contexto o AgletContext
. Dado que inicialmente el Aglet sólo tiene acceso (fuera de sí mismo) al contexto, conocer bien éste objeto será crítico para que podamos dotar al Aglet de autonomía en el entorno que lo acoge.
Aunque ya lo avanzábamos anteriormente, ahora vamos a profundizar un poco más en el API del AgletContext
. La Figura D nos muestra globalmente las diferentes posibilidades que ofrece el AgletContext
.
Cuando un Aglet
invoca su método getAgletContext()
, obtiene un objeto que implementa la interfaz AgletContext
, siendo capaz desde ese momento de invocar cualquiera de sus métodos. El agente puede pedirle al contexto, por ejemplo, que cree un nuevo Aglet con el método createAglet()
.
Como nos muestra la Figura D, podemos considerar que el Aglet
está inicialmente aislado dentro del contexto. Pero éste último, a través de sus métodos (como getAgletProxies()
), permite al agente acceder a la lista del resto de “habitantes”:
El contexto provee dos tipos de mecanismos para el flujo de información entre y para sus habitantes. El primero es el de mensajería por subscripción y su principio es el mismo que emplean actualmente las listas automáticas de e-mail (o la mayoría de modelos de gestión de eventos): si el agente se subscribe al servicio de mensajería (AgletEjemplo.subscribeMessage(String name)
), recibirá los mensajes del tipo elegido. El segundo es similar, pero en lugar de que le llegue la información, será el propio Aglet quien vaya a por ella (si sabe donde está, claro); en los AgletContext
dispondrá de propiedades públicas que podrá obtener y fijar (Context.getProperty()
, Context.setProperty()
).
AgletProxies
Los Aglet no interactúan directamente entre sí, pues es potencialmente peligroso. Empleando técnicas de introspección, un agente podría analizar de arriba abajo a otro y comenzar a jugar con su interfaz pública. Para evitar problemas, la arquitectura de Aglets introduce a los AgletProxy
, objetos “representantes” de otros Aglets.
Cada agente en el contexto tiene su AgletProxy
asociado; incluso pueden existir representantes locales de Aglets localizados en contextos remotos. Estos representantes presentan una visión uniforme del agente al resto de Aglets, escondiendo así la interfaz pública del mismo y proporcionando un estándar para la interacción entre agentes. Obtenemos un AgletProxy
, por ejemplo, cuando pedimos al contexto que cree un nuevo agente:
La Figura E muestra los tres grupos en los que podemos clasificar los métodos de la clase AgletProxy
. Métodos como clone()
, dispatch()
, dispose()
y deactivate()
son utilizados para controlar el Aglet
(si éste se deja, claro).
Un agente puede enviar, a cierto destino, a otro agente mediante su representante:
Otro grupo de métodos permite la comunicación de mensajes al agente representado. Un agente puede enviar un mensaje síncrono (envía el mensaje y queda a la espera de la respuesta) a otro agente:
O también puede enviar un mensaje asíncrono:
Por supuesto, si lo que queremos es información del agente, o el propio objeto agente si nos deja, podemos hacerlo con los métodos del último grupo de métodos:
Conclusiones
Con esta descripción de los diferentes elementos, debemos tener una idea más elaborada de cómo funcionan los AMAs, y cómo IBM Japón los ha implementado en Java. Si se ha conseguido, démonos por satisfechos.
En el artículo anterior hablábamos de AMAs en general; en éste nos hemos metido, de lleno, en una arquitectura de AMAs absolutamente funcional y que está comenzando a ser empleada en proyectos innovadores. En el próximo artículo vamos a dar vida a algunos agentes simples, pero que intentaremos tengan algún comportamiento social interesante; lanzaremos también a un explorador a indagar en algunos AgletContext que funcionan permanentemente en distintos puntos del globo. Veremos qué es lo que encuentra.