Miguel Ángel Ballesteros bio photo

Miguel Ángel Ballesteros

Maker, using software to bring great ideas to life. Manager, empowering and developing people to achieve meaningful goals. Father, devoted to family. Lifelong learner, with a passion for generative AI.

Email LinkedIn Github
RSS Feed

Agentes Móviles en Internet - Aglets SDK (y III) (ES)

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.

Figura C: Grupos de métodos que podemos encontrar en la definición de la clase com.ibm.aglet.Aglet

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:

import com.ibm.aglet.*

public class AgletExplorador extends 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:

public boolean handleMessage(Mesage mensaje) {

  if(mensaje.kind=Hello) {
    ... // Responder a “Hello”
    return true    // El mensaje fue tratado
  } else return false // Mensaje desconocido

}

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.

Figura D: Relación de grupos de métodos de los objetos AgletContext (que extienden la clase com.ibm.aglet.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”:

Enumeration e=getAgletContext().getAgletProxies()

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:

AgletProxy proxy = context.createAglet(...);

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).

Figura E: Los AgletProxies protegen a los Aglets de lainteracción directa con otros Agles, potencialmente maliciosos.

Un agente puede enviar, a cierto destino, a otro agente mediante su representante:

proxy.dispatch(new URL(..));

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:

Message msg = new Message(Hola!);
Object resultado = proxy.sendMessage(msg));

O también puede enviar un mensaje asíncrono:

FutureReply  resp = proxy.sendAsyncMessage(msg);

... // continuamos sin esperar la respuesta

Object resultado = resp.getReply();

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:

AgletIdentifier aid = proxy.getIdentifier();

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.