Conectando AppServer a RabbitMQ con Spring-AMQP

By | 11 diciembre 2014

Como he mencionado en el post principal de esta secuencia de tutoriales, el AppServer (Spring Framework), es el producer de los mensajes.

Para conectar el AppServer con RabbitMQ, Spring nos brinda el modulo Spring-AMQP, que implementa todo lo necesario para conectar y configurar queues, topics y exchanges.

Para añadir Spring-AMQP a nuestro proyecto podemos utilizar la siguiente dependencia en Maven.

<dependency>
    <groupId>org.springframework.amqp</groupId>
    <artifactId>spring-rabbit</artifactId>
    <version>${spring-amqp-version}</version>
</dependency>

Para establecer la conexion con RabbitMQ, podemos agregar en el aplicacion-context.xml un import a un xml nuevo que cree los beans necesarios.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:rabbit="http://www.springframework.org/schema/rabbit"
       xsi:schemaLocation="http://www.springframework.org/schema/rabbit

http://www.springframework.org/schema/rabbit/spring-rabbit.xsd


http://www.springframework.org/schema/beans


http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- Conexión con RabbitMQ -->
    <rabbit:connection-factory id="connectionFactory" host="localhost" port="5672" username="admin" password="adminp"/> 

    <!-- Configura RabbitTemplate -->
    <rabbit:template id="amqpTemplate" connection-factory="connectionFactory" /> 

    <!-- Configura RabbitAdmin -->
    <rabbit:admin connection-factory="connectionFactory"/>
</beans>

RabbitTemplate nos provee de la API necesaria para enviar y recibir mensajes.

RabbitAdmin (tiene como dependencia RabbitTemplate, accesible desde su getter), nos provee la API para crear queues, topics y exchanges.

Para crear programaticamente la estructura de queues, topcis y exchanges, en mi caso lo hago desde el @PostConstruct de un @Service.

Queue queue = new Queue("messages");

this.rabbitAdmin.declareQueue(queue);

TopicExchange topicExchange = new TopicExchange("messages");

this.rabbitAdmin.declareExchange(topicExchange);

this.rabbitAdmin
    .declareBinding(
        BindingBuilder
            .bind(queue)
            .to(topicExchange)
            .with("messages");

Creamos la queue, la enlazamos con su topic, y en este caso también con un exchange, realmente desde los clientes en MQTT acabaremos haciendo uso de los topcis, pero los exchanges nos aportar mayor flexibilidad de cara al producer, que conecta mediante AMQP.

Una vez creado el sistema de colas, para el ejemplo, vamos a utilizar una interface Rest simple, un método que reciba un parámetro mediante HTTP Post y lo envíe como mensaje. La interface en nuestro @RestController podría quedar tal que así.

@RequestMapping(value = "/send", method = RequestMethod.POST)
public boolean sendMesage(@RequestParam(value = "message", required = true) String message) {

    try{

        this.rabbitService.sendMessage(message);

        return true;
    }catch(Exception ex){

        //Logging.
    }

    return false;
}

No hay mucho que comentar, se recibe el parámetro message, y se invoca al método sendMessage de RabbitService.

@Override
public boolean sendMessage(String message){ 

    try{ 

        this.rabbitTemplate.convertAndSend("amq.topic", "amq.topic.*", message); 

        return true;
    }catch(Exception ex){ 

        //Logging.
    } 

    return false;
}

En la implementación de RabbitService, que tiene la dependencia de RabbitTemplate, se envía el mensaje a los clientes de todas las colas del exchange “amq.topic” (exchange por defecto del plugin RabbitMQ-mqtt para mqtt).

Comparte esta entrada enShare on LinkedIn0Tweet about this on Twitter0Share on Facebook0Share on Google+0

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *