Posted by: Camilo Torres | August 19, 2011

Mañana es el día Debian en Caracas

Mañana sábado 20 de Agosto de 2011:

Dirección: Av. Principal de la Floresta cruce con Av. Francisco de Miranda Urb. La Floresta, Edificio Sucre. a una cuadra de la estación de metro “Altamira”, frente a Centro Plaza. Chacao Estado Miranda.

Desde las 8:30 am hasta las 5:30 pm.


http://www.ciudadccs.info/?p=202601

http://www.diadebian.org.ve/

Demostraciones, talleres, charlas, instalaciones y mas…

Posted by: Camilo Torres | August 11, 2011

El día Debian será la próxima semana

Y habrá charlas y mucha información técnica sobre la distro. Será muy interesante.

http://www.diadebian.org.ve/

Posted by: Camilo Torres | August 9, 2011

RTL8191SEvB Wireless LAN Controller con kernel 3 en VIT M2400

Hace un tiempo compré una computadora VIT M2400 para reemplazar una Toshiba A215. Antes que nada, debo decir que la computadora VIT es muchísimo mejor que la Toshiba, por lo que recomiendo VIT. Además que se tiene la garantía en el propio país y se apoya la industria nacional de ensamblaje de computadoras.

El punto es que hoy se me actualizó el Kernel de Linux a la versión 3.0.0. Esto implica que el wireless deja de funcionar ya que se necesitan unos firmwares privativos para funcionar, pero al menos se puede uno descargar el driver libre desde Realtek que incluye el firmware.

uname -a
Linux cubagua 3.0.0-1-amd64 #1 SMP Sun Jul 24 02:24:44 UTC 2011 x86_64 GNU/Linux

lspci
02:00.0 Network controller: Realtek Semiconductor Co., Ltd. RTL8191SEvB Wireless LAN Controller (rev 10)

Driver a descargar:

http://152.104.125.41/downloads/downloadsView.aspx?Langid=1&PNid=48&PFid=48&Level=5&Conn=4&DownTypeID=3&GetDown=false&Downloads=true#2302

Seleccionar el driver que indica ‘Linux driver for kernel 2.6.35 (and later)’, ya que el driver anterior no compila con este nuevo kernel. Yo tenía antes el driver anterior que lo venía compilando para los kernels 2.6, pero con el kernel 3 falló y fui a descargarlo de nuevo.

El driver tiene un error porque hubo una variable que cambiaron en el kernel a partir del 2.6.39. Todo esto lo explican en está página:

http://www.linuxquestions.org/questions/slackware-14/make-error-wireless-realtek-driver-883400/

Entonces hay que hacer un comando para cambiar el nombre de variable:

sed -i 's|RX_FLAG_TSFT|RX_FLAG_MACTIME_MPDU|g' base.c rtl8192{ce,se,de}/trx.c

verificar que se tengan instalados los linux-headers del kernel:

sudo aptitude install linux-headers-3.0.0-1-all-amd64

Luego si se puede compilar con los comandos que indica el archivo readme:

sudo su
make
make install
reboot

Posted by: Camilo Torres | August 8, 2011

Debian-ve se solidariza con Ubuntu-ve

El trabajo por tener mejor software libre se realiza en varios frentes. Es muy importante contar con Ubuntu, porque genera una distribución de GNU/Linux que incluye software libre en su inmensa mayoría, y que además resulta adecuada para las personas que se inician con GNU/Linux y personas básicos conocimientos técnicos de computación o informática.

Es por eso que la comunidad de Debian-ve está buscando dar apoyo a la comunidad de Ubuntu-ve.

Yo inicié en GNU/Linux y el software libre con Ubuntu, como muchos otros en la actualidad. Actualmente soy usuario de Debian y pienso que el apoyo es necesario entre las distintas comunidades de GNU/Linux y organizaciones que apoyen de alguna manera al software libre.

Posted by: Camilo Torres | March 16, 2011

Mañana será el 2do Festival de Software Libre del SAPI

Mañana será el II Festival de Software Libre 2011 organizado por el SAPI.

Lugar y hora:
UNIVERSIDAD NACIONAL EXPERIMENTAL POLITECNICA DE LAS FUERZAS
ARMADAS (UNEFA)
Jueves 17 de Marzo 2011
Entre la Av: la estancia y Av. Caracas , Con Calle Holanda
Frente al Edificio Banvenes (Cubo negro)
Chuao-Caracas.

Recuerde registrarse en la página web del SAPI: http://sapi.gob.ve/

Este es el cronograma del evento. Hay muchísimas charlas (guao) y algunas como las de la sala 4 son bastante avanzadas:

Programa II FSL

Este próximo Jueves 17/03/2011 se realizará el II Festival Software Libre 2011, evento organizado por el Servicio Autónomo de Propiedad Intelectual (SAPI).

Este evento se realizará en la sede de la UNEFA en Chuao, Caracas, a partir de las 8:30 AM.

Habrá feria de instalación de Software Libre. Lleva tu computadora para que te instalen una distro. Habrá charlas básicas y avanzadas, incluyendo charlas de Bases de datos Postgres y probablemente Python. Habrá stands con demostraciones de las distintas tecnologías.

Lo más importante la entrada es libre y gratis. Se pueden registrar para recibir su certificado de asistencia.

II Festival Software Libre 2011 - SAPI

II Festival Software Libre 2011 - SAPI

Posted by: Camilo Torres | January 31, 2011

Sosftware para linux con tu BB. Linberry.

Todas aquellas personas que poseen o utilizan teléfonos Blackberry al parecer tienen que utilizar el sistema operativo Windows para poder conectarse desde su computadora al teléfono Blackberry.

Ahora existe un programa para conectar tu Blackberry que corre en Debian y Ubuntu (aunque según su autor debería correr en otras distribuciones de Linux).

Israel Marrero ha diseñado y escrito Linberry (http://linberry.webcindario.com/), y ha hecho una petición a los bloggers venezolanos para que le ayuden a promocionar su software. No es software libre ni tampoco de código abierto, no me quedó claro cuál es la licencia con la cual distribuye el programa, pero en mensajes intercambiados con el autor del programa me aclaró que es código cerrado.

Linberry está en estado Alpha, lo que significa que no está suficiente maduro, probado y le faltan algunas características para que pueda pasar a ser considerado estable. El mismo autor advierte sobre esto en su página e indica que no se hace responsable por el uso que cada quien haga del programa, y menos si pierde datos o daña su computadora, o explota, o cualquier cosa mala que pase.

No he usado este programa y no lo voy a usar, por varias razones (sin pedantería, por favor :):

  1. No tengo Blackberry ni voy a comprar o usar uno en el futuro que puedo vislumbrar.
  2. La descarga es para arquitectura i386, y yo poseo es arquitectura AMD64.
  3. Puede ser un troyano, pero ¿cómo saberlo?.

La pesca de arrastre es ilegal.

Aunque se practicó durante casi 5 décadas, la pesca de arrastre era uno de los sistemas más dañinos para la explotación pesquera. Actualmente es ilegal, por lo que muchos ecologistas y amantes de la naturaleza tienen un triunfo que celebrar.

Recordar este evento.

Para recordar este evento y que no las futuras generaciones no crean que todo siempre fue así como es hoy, creé un juego de computadora. Bueno, lo medio-creé, porque no lo he terminado.

El año pasado se hizo un concurso por parte del Ministerio de Educación para generar contenidos educativos. Me inscribí en el concurso, pero como el juego estaba realmente muy crudo, no lo presenté. Me hubiera gustado avanzar más en la programación del juego, pero realmente con el trabajo y los tigres que tengo que matar no tuve tiempo suficiente. Me dio pena ir a presentar eso incompleto.

Atrapa la arrastradora.

Ese es el nombre del juego. Está hecho con Python y PyGame. No había tenido tiempo ni siquiera de publicarlo en algún lugar. Hoy por fin lo puse en Gitorious:

http://gitorious.org/atrapa-la-arrastradora/

Aún le falta mucho, pero si alguien lo prueba y cree que la idea es buena, acepto sugerencias.

Intro del juego.

Por las fechas que comencé a hacer el juego me compré una tableta digitalizadora (de esas que tienen un lápiz) para hacer los dibujos del juego. Es divertido. Lástima no tener más tiempo (y lástima que la bendita tableta no tenga drivers libres).

El juego está con licencia GPLv3. El contenido va con licencia Creative Commons BY-NC-SA. Solo falta completarlo.

=-=-=-=-=
Powered by Blogilo

Posted by: Camilo Torres | December 13, 2010

Pasar Datos del Header SOAP al Service Class de Axis2.

0. Introducción
En este artículo se explica como pasar datos que vienen en el HEADER de un mensaje SOAP hacia la clase que implementa el servicio con Axis2.

El problema es que se quieren enviar algunos datos en el encabezado SOAP, y esos datos podrían ser usados por la clase que implementa el servicio (en Axis2 esta clase se llama Service Class). Estos son los datos que se quieren enviar en el mensaje SOAP:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://www.example.org/ws/">
   <soapenv:Header>
     <a:Channel xmlns:a="asdf">Canal</a:Channel>
     <a:Username xmlns:a="asdf">username</a:Username>
     <a:messageID xmlns:a="asdf">mesageid</a:messageID>
   </soapenv:Header>
   <soapenv:Body>
      <ws:CatalogLookup>
         <CategoryCode>123</CategoryCode>
         <SearchTerm></SearchTerm>
         <MaximunPrizePoints>54</MaximunPrizePoints>
         <Channel>Canal</Channel>
         <Status>Active</Status>
      </ws:CatalogLookup>
   </soapenv:Body>
</soapenv:Envelope>

Básicamente son: Channel, Username y messageID. Ahora, esos datos deben ser pasados a la clase que implementa el servicio. En nuestro caso son varios los servicios que hay que hacer que deben obtener este encabezado, entonces estamos usando Eclipse 3.5 con los plugins de desarrollo web, primero generamos el WSDL con la herramienta de Eclipse.

1. Crear el servicio usando Axis2 con Eclipse.
Este excelente artículo Creando un servicio web a partir de su interfaz WSDL por Javier Cámara (http://www.adictosaltrabajo.com/tutoriales/tutoriales.php?pagina=WSDL2Java) tiene todas las instrucciones de como hacerlo.

2. Crear un cliente de pruebas.
Aquí hay un tutorial muy bueno Desarrollar un cliente webservice desde WSDL en Axis2 por Julio César Pérez Arques (http://jcesarperez.blogsome.com/2007/08/26/desarrollar-un-cliente-webservice-desde-wsdl-en-axis2/) que explica como crear el cliente. En nuestro caso solo nos interesan los clientes síncronos.

Luego de crear el cliente nos genera una clase Stub. Creamos una clase que contenga un método main() de Java y allí metemos nuestra prueba, incluyendo los encabezados:

package cliente;

import java.rmi.RemoteException;
import javax.xml.namespace.QName;
import org.apache.axis2.client.ServiceClient;
import cliente.WsStub.CatalogLookupResponse;
import cliente.WsStub.ItemType;

public class Prueba {
	public static void main(String[] args) throws RemoteException {
		// Se le indica el url donde se desplegó el servicio web
		WsStub ws = new WsStub("http://localhost:8080/PruebaWsdl4/services/ws?wsdl");
		
		// aquí pone los encabezados.
		ServiceClient sc = ws._getServiceClient();
		sc.addStringHeader(new QName("http://digitel.com.ve/", "Channel"), "mega");
		sc.addStringHeader(new QName("http://digitel.com.ve/", "Username"), "camilo");
		sc.addStringHeader(new QName("http://digitel.com.ve/", "messageID"), "msg23443");
		
		// aquí pone unos valores en el cuerpo del mensaje (los parámetros)
		WsStub.CatalogLookup cl = new WsStub.CatalogLookup();
		cl.setChannel("as");
		cl.setStatus(WsStub.Status_type1.Active);
		
		// hace la llamada al WS
		CatalogLookupResponse r = ws.CatalogLookup(cl);
		
		// nuestro WS retorna un arreglo de objetos, pero obtenemos
		// el primero y lo mostramos
		ItemType i = r.localItem[0];
		System.out.println(i.localChannel);
		System.out.println(i.localDisabled.getValue());
	}

}

Observe que poner los encabezados en el cliente es muy fácil, no así en el servidor. Hay otras formas de agregar encabezados al cliente como puedes ver en el artículo: Working with Custom SOAP Headers por Deepal Jayasingha (http://wso2.org/library/3156)

3. Crear el handler de Axis2 que leerá los encabezados en el Servicio.
Hay que crear un handler de Axis2 para poder leer los encabezados del servicio y pasarlos a la clase que implementa el servicio. En nuestro caso estamos implementando los servicios con el Skeleton que genera Axis2 mediante el plugin de Eclipse. Entonces creamos una clase dentro del proyecto web del servicio así:

package ve.com.ws.handler;

import java.util.Iterator;

import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.handlers.AbstractHandler;
import org.apache.log4j.Logger;

public class HeaderHandler extends AbstractHandler {
	public static final Logger log = Logger.getLogger(HeaderHandler.class);

	@Override
	public InvocationResponse invoke(MessageContext mc) throws AxisFault {
		String headerName = null;
		String headerValue = null;
		
		Iterator it = mc.getEnvelope().getHeader().getChildElements();
		while (it.hasNext()) {
			OMElement o = it.next();
			headerName = o.getQName().getLocalPart();
			headerValue = o.getText();
			if (log.isDebugEnabled())
				log.debug("SOAP Message Header: " + headerName + "=" + headerValue);
			mc.setProperty(headerName, headerValue);
		}
		return InvocationResponse.CONTINUE;
	}

}

Observe que los valores se guardan en el MessageContext de Axis2. Luego la clase del servicio los tomará de allí.

4. Agregar el handler al axis2.xml para que sea invocado.
Para que el handler pueda correr hay que agregarlo al archivo WebContent/WEB-INF/conf/axis2.xml dentro del proyecto web. Busque la sección phaseOrder type=”InFlow” y agregue este trozo de XML:

        <phase name="HeaderPhase">
            <handler name="HeaderHandler"
                     class="ve.com.ws.handler.HeaderHandler">
                <order phase="HeaderPhase"/>
            </handler>
        </phase>

Para que quede de la siguiente forma:

    <phaseOrder type="InFlow">
        <!--  System predefined phases       -->
        <phase name="Transport">
            <handler name="RequestURIBasedDispatcher"
                     class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher">
                <order phase="Transport"/>
            </handler>
            <handler name="SOAPActionBasedDispatcher"
                     class="org.apache.axis2.dispatchers.SOAPActionBasedDispatcher">
                <order phase="Transport"/>
            </handler>
        </phase>
        <phase name="Addressing">
             <handler name="AddressingBasedDispatcher"
                     class="org.apache.axis2.dispatchers.AddressingBasedDispatcher">
                 <order phase="Addressing"/>
            </handler>
        </phase>
        <phase name="Security"/>
        <phase name="PreDispatch"/>
        <phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase">
            <handler name="RequestURIBasedDispatcher"
                     class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher"/>
            <handler name="SOAPActionBasedDispatcher"
                     class="org.apache.axis2.dispatchers.SOAPActionBasedDispatcher"/>
            <handler name="RequestURIOperationDispatcher"
                     class="org.apache.axis2.dispatchers.RequestURIOperationDispatcher"/>
            <handler name="SOAPMessageBodyBasedDispatcher"
                     class="org.apache.axis2.dispatchers.SOAPMessageBodyBasedDispatcher"/>
            <handler name="HTTPLocationBasedDispatcher"
                     class="org.apache.axis2.dispatchers.HTTPLocationBasedDispatcher"/>
            <handler name="GenericProviderDispatcher"
                     class="org.apache.axis2.jaxws.dispatchers.GenericProviderDispatcher"/>
            <handler name="MustUnderstandValidationDispatcher"
                     class="org.apache.axis2.jaxws.dispatchers.MustUnderstandValidationDispatcher"/>
        </phase>
        <phase name="RMPhase"/>
        <!--  System predefined phases       -->
        <!--   After Postdispatch phase module author or service author can add any phase he want      -->
        <phase name="OperationInPhase">
            <handler name="MustUnderstandChecker"
                     class="org.apache.axis2.jaxws.dispatchers.MustUnderstandChecker">
                <order phase="OperationInPhase"/>
            </handler>
        </phase>
        <phase name="soapmonitorPhase"/>
        <phase name="HeaderPhase">
            <handler name="HeaderHandler"
                     class="ve.com.ws.handler.HeaderHandler">
                <order phase="HeaderPhase"/>
            </handler>
        </phase>
    </phaseOrder>

Este artículo Handler and Phase in Apache Axis2 por Deepal Jayasinghe (http://www.packtpub.com/article/handler-and-phase-in-apache-axis) explica como es los de las fases (phase) y handlers de Axis2.

5. Modificar el esqueleto del servicio para que lea los encabezados.
Finalmente podemos leer los encabezados en el servicio. Edite la clase Skeleton que generó Eclipse para obtener los encabezados desde el MessageContext:

package org.example.www.ws;

import org.apache.axis2.context.MessageContext;

public class WsSkeleton {
	public org.example.www.ws.CatalogLookupResponse CatalogLookup(
			org.example.www.ws.CatalogLookup cl) {
		// lee los encabezados
		MessageContext mc = MessageContext.getCurrentMessageContext();
		String channel = (String) mc.getProperty("Channel");
		String username = (String) mc.getProperty("Username");
		String messageId = (String) mc.getProperty("messageID");
		System.out.println("Canal del encabezado: " + channel);
		System.out.println("Username del encabezado: " + username);
		System.out.println("messageId del encabezado: " + messageId);
		
		// imprime los valores que normalmente vienen en el cuerpo
		// es decir los parámetros normales
		System.out.println(cl.getChannel());
		System.out.println(cl.getStatus().getValue());
		
		// Crea una respuesta y la envía al cliente
		CatalogLookupResponse clr = new CatalogLookupResponse();
		ItemType[] items = new ItemType[1];
		ItemType i = new ItemType();
		i.setBackgroundImage("as");
		i.setCategoryCode(34);
		i.setCategoryName("asd");
		i.setCategorySubSystem("asdf");
		i.setChannel("cha");
		i.setDisabled(Disabled_type1.value2);
		i.setExternalSystemId("extsis");
		i.setImage("img");
		i.setPrizePoints(1234);
		i.setProductCode(43);
		i.setShortDescription("short!");
		i.setType("typ");
		items[0] = i;
		clr.setItem(items);
		return clr;
	}

}

Este método para pasar los parámetros lo aprendí gracias a la respuesta de Nelson Minar a la pregunta How do I pass data from Handler to the service? que hizo Konstantinos Margaritis (http://www.mail-archive.com/axis-user@xml.apache.org/msg20035.html) en la lista axis-user http://ws.apache.org/axis/mail.html.

6. Conclusión
Es enredado leer los encabezados en Axis2 cuando usamos el esqueleto que genera la herramienta WSDL2Java o el Eclipse. Esto es así porque esa herramienta pretende ocultar las complicaciones de SOAP al programador que la utilice. Pero una vez configurado el handler podemos leero todos los encabezados y pasarlos a la clase que implementa el servicio.

Posted by: Camilo Torres | December 8, 2010

El protocolo de colas de mensajes STOMP

El presente artículo es una explicación basada en el ‘Stomp Protocol Specification, Version 1.0’ publicado por Codehaus en http://stomp.codehaus.org/Protocol.

1. El protocolo STOMP

El protocolo STOMP de colas de mensajes se utiliza para comunicación distribuida entre computadoras, principalmente en aplicaciones de informática. STOMP es el Protocolo de Mensajes Orientado a Texto y en Flujos (Streaming Text Oriented Messaging Protocol). Esto significa que los mensajes que se pueden crear y enviar por un lado, y recibir y procesar por el otro lado son mensajes de texto; puede ser cualquier documento de texto: plano, yaml, json, xml, etc. También significa que los mensajes se envían y reciben dentro de un flujo de datos, dicho de otra manera, mensajes van y mensajes vienen dentro de un mismo contexto de conexión.

Los servicios de colas de mensajes son utilizados desde hace mucho tiempo en aplicaciones dentro de bancos, empresas de telecomunicaciones y algunas otras industrias. Tienen mucha aplicación en la informática porque permiten una forma de computación distribuida con bajo acoplamiento, además es fácil de entender porque presenta un patrón de tipo productor-consumidor. Un caso fácil de entender sacado de morethanseven es cuando una web solicita información al cliente y cuando el cliente pulsa el botón de enviar la web le envía un correo electrónico, digamos con un resumen de su petición; si llegan muchos usuarios a enviar el formulario, el servidor se pondrá lento enviando correos, mientras que los usuarios irán notando que la página se vuelve lenta; esto ocurre porque el envío de correo toma un poco de tiempo y el servidor de web es quien está enviando cada correo (con la ayuda del servidor de correos).

Servidor de Colas

Servidor de Colas

Ahora, si en vez de que el servidor web envíe el mensaje directamente al servidor de correo, lo coloca en una cola, esta cola a su vez está en un servidor aparte, y luego de dejar el mensaje en cola el servidor web muestra una respuesta al usuario liberandose para los demás usuarios que envíen el formulario. Esto haría que el servidor web no se ponga lento tan rápido. Pero ¿qué pasa con el mensaje? aún no se ha enviado por correo. Es cierto, el mensaje está en una cola en un servidor de colas, pero no se queda allí, porque la magia del servidor de colas es que este despacha el mensaje a un servicio que está procesando los mensajes de la cola, y ese servicio si va a enviar el correo: toma el mensaje de la cola y lo manda por correo; si llegan muchos mensajes, no importa, el servidor de colas de mensajes los va agregando al final de la cola y va despachando uno a uno según el proceso que los consume los pueda ir tomando y enviando sin saturar los recursos ni del servidor de correos y menos del servidor web.

Entonces el sistema es muy sencillo, un proceso escribe mensajes en el servidor, el servidor los mete en una cola y los va despachando hacia otro proceso que los va consumiendo según tenga disponibilidad de recursos.

Existen otros protocolos de mensajes como XMPP, SMTP o JMS para nombrar solo algunos y dejar por fuera mucho más. STOMP es un protocolo sencillo y ligero, por lo tanto está condenado al éxito y a ser usado en muchas aplicaciones que requieran sencillez y facilidad de uso. A partir de este punto se va a explicar el funcionamiento del protocolo STOMP basado en la propia especificación del protocolo.

2. El cliente se conecta con el servidor STOMP.

Lo primero que debe hacer el cliente es abrir un socket al servidor. Es conveniente asumir que la conexión será con TCP ya que es lo más común y los servidores están hechos así. Para conectarse, un cliente debe enviar la siguiente trama:

CONNECT
login:usuario
passcode:clavesecreta

^@

El símbolo ^@ es un byte null (control-@ en ASCII). Se usa para definir el fin de mensaje. Toda trama inicia con un comando (en este caso CONNECT que significa conectar) en una línea, siguen los encabezados en forma ‘clave:valor’ cada uno en su propia línea (login y passcode en este ejemplo), se deja una línea en blanco y luego viene el cuerpo del mensaje, el cual termina con el byte ^@ (en este caso el cuerpo del mensaje está en blanco). El encabezado ‘login’ (entrar) se usa para enviar el usuario que se conecta, mientras que passcode (código de pase) se usa para enviar la clave secreta. Para separar las líneas se usa un caracter de nueva línea al final de cada línea.

Luego que el cliente envía la trama CONNECT el servidor responde con la siguiente trama:

CONNECTED
session:identificador de sesión

^@

CONNECTED significa conectado. El encabezado session es un identificador que puede ser cualquier texto con tal que sea distinto para cada conexión que se haga con el servidor (la especificación lo manda, pero no es usado para nada actualmente; en el futuro puede ser usado en otras tramas).

Ya con esto se establece una conexión al servidor y se pueden realizar varias acciones, cada una con su trama:

  • SEND – Enviar. Enviar mensajes a una cola en el servidor.
  • SUBSCRIBE – Suscribirse. Suscribirse para recibir mensajes que otros pongan en una cola.
  • UNSUBSCRIBE – Desuscribirse. Dejar de recibir mensajes que otros pongan en una cola.
  • BEGIN – Iniciar. Inicia una transacción.
  • COMMIT – Comprometer. Compromete (ejecuta definitivamente) las acciones que se hicieron en una transacción.
  • ABORT – Abortar. Deshacer las acciones hechas en una transacción.
  • ACK – Confirmación (Acknowledge). Confirma la recepción de un mensaje por parte del proceso que lo consume.
  • DISCONNECT – Desconectar. Para terminar una conexión con el servidor.

Entonces lo primero es conectarse, luego se pueden enviar o consumir muchos mensajes, dependiendo del lado donde esté el proceso (en el lado que pone mensajes o en el lado que los consume) y finalmente en algún momento se cierra la conexión. Esta es la parte de flujos del protocolo, como se puede ver todo ocurre dentro de un flujo de mensajes que van y vienen entre el servidor y los clientes que ponen mensajes y que consumen mensajes.

3. Comandos que pueden enviar los clientes.

SEND.

Significa enviar. Sirve para enviar o colocar mensajes hacia un destino en el servidor. Este lo usa el cliente que quiere poner un mensaje en una cola. Tiene un encabezado requerido: destination (destino) que indica donde se va a enviar el mensaje. El cuerpo de la trama SEND es el mensaje que se quiere enviar. Ejemplo:

SEND
destination:/cola/mensajes

Texto del mensaje puesto en la cola
^@

Esto envía el mensaje ‘Texto del mensaje puesto en la cola’ a la cola llamada ‘/cola/mensajes’. El nombre de la cola es totalmente arbitrario; en este ejemplo se usó la palabra ‘cola’ pero en el servidor no necesariamente es una cola, puede ser otra cosa que el servidor quiera implementar, no hay nada que obligue al servidor a usar una cola. Los nombres en ‘destination’ (destino) únicamente identifican un lugar en el servidor para poner los mensajes, cada nombre indica un lugar distinto, cada servidor puede implementar este mecanismo como quiera.

Las tramas SEND soportan un encabezado ‘transaction’ (transacción) que sirve para enviar el mensaje en el contexto de una transacción.

Se recomienda que las tramas SEND incluyan un encabezado ‘content-length’ (longitud del contenido) que es el número de bytes del cuerpo del mensaje. Esto sirve cuando el mensaje incluye caracteres de null (^@); si no se incluye un content-length el servidor tomará el mensaje hasta el primer null que encuentre e ignorará el resto del mensaje; por el contrario si tiene content-length el servidor leerá esa cantidad de bytes del mensaje, incluyendo los bytes que sean null (^@).

SUBSCRIBE

Significa suscribir. Se usa para registrar que se quieren consumir mensajes de un destino (‘destination’) dentro del servidor; por ejemplo consumir mensajes de una cola. Al igual que la trama SEND, la trama SUBSCRIBE requiere un encabezado ‘destination’ (destino) para indicar la cola a la que se quiere suscribir. De esa forma, cualquier mensaje que se reciba en la cola (porque otro proceso puso el mensaje) será enviado desde el servidor al proceso cliente que se suscribió a la cola como una trama MESSAGE (mensaje). Se puede colocar un encabezado ‘ack’ (confirmar, acknowledge), pero es opcional y si no se coloca el valor es ‘auto’. Ejemplo:

SUBSCRIBE
destination:/cola/mensajes
ack:client

^@

En este ejemplo el encabezado ‘ack’ (confirmar) está en ‘client’ (cliente) lo que significa que el mensaje será considerado como enviado al proceso cliente cuando el proceso cliente envíe al servidor una trama ACK (confirmación). Los valores válidos para el encabezado ‘ack’ son ‘auto’ (automático, que es el que se asume por defecto si no se manda encabezado ‘ack’) y ‘client’ (cliente).

El cuerpo de las tramas SUBSCRIBE (suscribir) es ignorado completamente.

Se puede agregar un encabezado ‘id’ (identificador) que podrá ser usado luego en una trama UNSUBSCRIBE (desuscribir), de esa forma, si un proceso tiene varias suscripciones a un mismo ‘destination’ (destino), puede elegir a cual de-suscribirse porque le asignó distinto ‘id’ (identificador) a cada proceso. Si se indica un encabezado ‘id’ entonces el servidor deberá agregar a su vez un encabezado ‘subscription’ (suscripción) a las tramas MESSAGE (mensaje) que él envía al cliente suscrito, de forma que el cliente podrá saber exactamente a cual suscripción se refiere la trama MESSAGE (mensaje). Si el servidor soporta comodines (wildcards) y selectores (selectors) el ‘id’ puede servir a los clientes de ayuda para saber cual suscripción originó el mensaje. Los comodines y selectores se explican más abajo. El servidor podría soportar un encabezado ‘selector’ que puede contener un selector de tipo SQL 92 como se explica hacia el final del artículo.

UNSUBSCRIBE

Significa de-suscribir. Esta trama se utiliza para remover una suscripción existente de forma que ya no se reciban más mensajes provenientes del destino (destination) al que previamente se suscribió. Requiere uno de estos dos encabezados: ‘destination’ (destino) o ‘id’ (identificador). Para usar el encabezado ‘id’ tuvo que haberse pasado también al momento de hacer la suscripción. Ejemplo:

UNSUBSCRIBE
destination:/cola/mensajes

^@

BEGIN

Significa iniciar. Se usa para iniciar una transacción. Las transacciones en este protocolo solo aplican a envío de mensajes y confirmación de recepción de mensajes. Cualquier mensaje enviado o al que se le confirme su recepción será manejado atómicamente durante la transacción. Ejemplo:

BEGIN
transaction:identificador

^@

El encabezado ‘transaction’ (transacción) es requerido y se refiere a un identificador que deberá ser usado en las tramas SEND, COMMIT, ABORT y ACK para indicar que están asociadas a la transacción por el nombre dado en el identificador.

COMMIT

Significa comprometer. Se usa para ejecutar definitivamente una transacción en curso, es decir, para indicar que la transacción terminó exitosamente y deben ejecutarse atómicamente todos comandos enviados desde el BEGIN. Ejemplo:

COMMIT
transaction:identificador

^@

El encabezado ‘transaction’ (transacción) es requerido y se refiere al identificador que se indicó al iniciar la transacción con la trama BEGIN.

ACK

Significa confirmar (acknowledge). Se utiliza para confirmar la recepción y consumo de un mensaje de parte del cliente, cuando el tipo de confirmación es ‘client’ (cliente). Cuando un cliente envía una trama SUBSCRIBE (suscribir) con un encabezado ‘ack’ (confirmación, acknowledge) con valor ‘client’ (cliente) entonces para que el servidor considere que el cliente ha consumido el mensaje, el cliente debe enviar una trama ACK de confirmación.

ACK tiene el encabezado ‘message-id’ (identificador del mensaje) como requerido, y el identificador debe coincidir con el que envía el servidor en la trama MESSAGE (mensaje) correspondiente para ser confirmada. Adicionalmente un encabezado ‘transaction’ (transacción) puede ser usado para indicar que la trama está dentro de una transacción. Ejemplo:

ACK
message-id:identificador
transaction:numero de transacción

^@

El encabezado ‘transaction’ es opcional.

ABORT

Significa Abortar. Se usa para indicar que se debe abortar o rechazar una transacción en curso. Es decir, que ningún mensaje dentro de la transacción debe ser enviado. Ejemplo:

ABORT
transaction:numero de transacción

^@

El encabezado ‘transaction’ (transacción) es requerido para identificar la transacción.

DISCONNECT

Significa desconectar. Se usa para desconectarse limpiamente del servidor. Es adecuado hacer una desconexión antes de cerrar el socket TCP. Ejemplo:

DISCONNECT

^@

4. Encabezados estándar.

Algunos encabezados pueden ser usados en la mayoría de las tramas y tienen un significado especial.

receipt

Significa recibo. Cualquier trama que envíe el cliente menos CONNECT puede hacer uso del encabezado ‘receipt’ con un valor arbitrario. Esto hará que el servidor confirme la recepción de la trama enviando al cliente una trama RECEIPT que contendrá el valor del este encabezado en el encabezado ‘receipt-id’ de la trama RECEIPT. Ejemplo:

SEND
destination:/cola/mensajes
receipt:mens876

Mensaje con confirmación de recibo.
^@

5. Tramas del servidor

El servidor enviará también tramas al cliente, adicional a la trama CONNECTED (conectado) que envía al momento de la conexión puede enviar también:

  • MESSAGE
  • RECEIPT
  • ERROR

MESSAGE

Significa mensaje. Estas tramas se usan para enviar los mensajes de las suscripciones a los clientes suscritos. Las tramas MESSAGE contienen un encabezado ‘destination’ (destino) indicando la cola destino que recibió el mensaje. También contendrá un encabezado ‘message-id’ (identificador del mensaje) con un identificador único. El cuerpo de la trama contiene el mensaje. Ejemplo:

MESSAGE
destination:/cola/de/ejemplo
message-id:identidad9001

Este es el mensaje^@

Se recomienda que las tramas MESSAGE incluyan un encabezado ‘content-lenght’ (longitud del contenido) con una cuenta de los bytes del cuerpo de la trama. Si viene el encabezado ‘content-length’ entonces se leerán esa cantidad de bytes. Esto permite tener caracteres null en el cuerpo del mensaje.

RECEIPT

Significa recibo. El servidor envía tramas de recepción cuando el cliente ha especificado un encabezado ‘receipt’ en algún comando. La trama RECEIPT contiene un encabezado ‘receipt-id’ que contiene el mismo que vino en el encabezado ‘receipt’ que envió el cliente. Ejemplo:

RECEIPT
receipt-id:mens876

^@

El cuerpo del mensaje debe estar vacío.

ERROR

El servidor podría enviar tramas ERROR si algo va mal. Las tramas de error contendrán un encabezado ‘message’ (mensaje) con una breve descripción del error, el cuerpo podrá contener todos los detalles del error o venir vacío. Ejemplo:

ERROR
message:trama no reconocida

El mensaje:
-----------
COLA
destination:colademensajes

Datos del mensaje
-----------
no contiene un comando válido del protocolo STOMP.
^@

Se recomienda que las tramas ERROR incluyan un encabezado ‘content-lenght’ (longitud del contenido) con una cuenta de los bytes del cuerpo de la trama. Si viene el encabezado ‘content-length’ entonces se leerán esa cantidad de bytes. Esto permite tener caracteres null en el cuerpo del error.

6. Comodines (wildcards)

Esta sección es una explicación basada en la página de Apache ActiveMQ sobre Wildcards de The Apache Software Foundation ubicada en http://activemq.apache.org/wildcards.html.

El soporte de comodines sirve para suscribirse en un solo comando SUBSCRIBE a varias colas. Un ejemplo clásico de esto es cuando existen varias colas cada una de las cuales lleva el control de los cambios de precios de una acción en particular, entonces se tendrían varias colas como por ejemplo:

  1. bolsavalores/rentavariable/MPA
  2. bolsavalores/rentavariable/CRM.A
  3. bolsavalores/rentavariable/MVZ.A
  4. bolsavalores/rentavariable/MVZ.B

Si se quiere que una sola suscripción consuma todas las colas de acciones clase A (CRM.A y MVZ.A) entonces puede suscribirse con el siguiente comodín:

SUBSCRIBE
destination:bolsavalores/rentavariable/*.A

^@

Se observa que el * significa que puede haber cualquier texto en ese lugar.

En otro ejemplo un proceso quiere suscribirse para consumir todas las colas de renta variable, puede hacer así:

SUBSCRIBE
destination:bolsavalores/rentavariable/>

^@

En este caso el símbolo > (mayor que) significa que puede haber cualquier texto de allí en adelante.

Entonces:

  • El símbolo * singnifica que puede coincidir con cualquier texto. Se usa para coincidir un trozo del nombre de la cola.
  • El símbolo > significa que puede coincidir cualquier texto que siga a partir de allí. Se usa para coincidir todas las colas en una jerarquía.

7. Selectores

Esta sección es una explicación basada en la página de Apache ActiveMQ sobre Selectors de The Apache Software Foundation ubicada en http://activemq.apache.org/selectors.html.

Los selectores se utilizan para recibir únicamente algunos mensajes de una suscripción y no todos. Normalmente se reciben todos los mensajes que llegan a una cola a la que se está suscrito, pero si se usan selectores se podrían filtrar algunos mensajes.

Los selectores utilizan sintaxis de SQL 92 y solo se pueden usar claves del encabezado, por ejemplo:

SUBSCRIBE
destination:/mi/cola/con/muchosMensajes
selector:id = 'cola080' and ack='client'

^@

Los selectores no pueden usarse con el cuerpo del mensaje, solo con los encabezados.

8. Algunos enlaces

Copyright 2010. Camilo Torres.

Licencia  Creative Commons
Este obra está bajo una licencia Creative Commons Reconocimiento 3.0 Unported.

« Newer Posts - Older Posts »

Categories