El «Producer»
Siguiendo los pasos del articulo anterior, ahora nos toca crear la aplicación que se encarga de solicitar la inclusión este objeto, que contiene el nombre del cliente y su dirección de correo electrónico en la base de datos remota. Según nuestro planteamiento inicial, esta aplicación es un CRUD completo que maneja tantas tablas como sean necesarias; para nuestro ejemplo, obviaremos todo ello, y únicamente crearemos un servicio para realizar la petición a nuestro servidor RabbitMQ
La aplicación
Vamos a crear una aplicación con Java17 y Spring, llamada AMQP-ProducerCrud
- Utilizaremos Maven
- Java 17
En eclipse, quedaría así
Los módulos a incluir en el package serán
- Spring for RabbitMQ
- Spring Boot DevTools
Añadiendo que solo el primero seria necesario. Insisto en que solo estamos teniendo en cuenta la recepción de los mensajes
Como vamos a utilizar JSON para enviar la clase, necesitaremos incorporar una clase mas, y directamente en el pom.xml podemos añadir
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.4</version>
</dependency>
Debemos configurar la conexión al servidor, para lo cual, en src/main/resources
abrimos el fichero application.properties
spring.rabbitmq.host=http://localhost
spring.rabbitmq.port=5679
spring.rabbitmq.username=blogCrud
spring.rabbitmq.password=<pass usuario>
spring.rabbitmq.virtual-host=HostCrud
rabbitmq.exchange.name=exchangeCRUD
rabbitmq.routing.key=guardaCli
Son los datos de conexión al servidor, y, los dos últimos son los datos de exchange y RoutingKey que necesitaremos mas adelante, y que son lo único que emplearemos para enviar el mensaje, ya que la decisión de a que cola entregarlo, esta en el servidor.
Podemos escribir la clase para configuración, en la que incorporamos en el rabbitTemplate una clase para realizar las conversiones a Json que necesitamos, y que podría ser asi
package com.rf.rabbit.config;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfig {
@Bean
public MessageConverter converter() {
return new Jackson2JsonMessageConverter();
}
@Bean
public AmqpTemplate amqpTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(converter());
return rabbitTemplate;
}
}
Tenemos que escribir la clase DTO que deberá ser idéntica a la clase que espera Consumer, y, que en nuestro caso, seria
package com.rf.rabbit.dto;
public class ClienteMail {
private int id;
private String nombreCliente;
private String correoElectronico;
public ClienteMail() {
super();
}
public ClienteMail(int id, String nombreCliente, String correoElectronico) {
super();
this.id = id;
this.nombreCliente = nombreCliente;
this.correoElectronico = correoElectronico;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNombreCliente() {
return nombreCliente;
}
public void setNombreCliente(String nombreCliente) {
this.nombreCliente = nombreCliente;
}
public String getCorreoElectronico() {
return correoElectronico;
}
public void setCorreoElectronico(String correoElectronico) {
this.correoElectronico = correoElectronico;
}
@Override
public String toString() {
return "ClienteMail [id=" + id + ", nombreCliente=" + nombreCliente + ", correoElectronico=" + correoElectronico
+ "]";
}
}
Como ya lo tenemos todo, vamos a escribir la clase que realizara el envio, como siempre apoyandose en el paquete AMPQ de Spring, y que puede ser
package com.rf.rabbit.producers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.rf.rabbit.dto.ClienteMail;
@Service
public class RabbitMqProducer {
@Value("${rabbitmq.exchange.name}")
private String exchange;
@Value("${rabbitmq.routing.key}")
private String routingKey;
private static final Logger LOGGER = LoggerFactory.getLogger(RabbitMqProducer.class);
private RabbitTemplate rabbitTemplate;
public RabbitMqProducer(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
}
public void sendMessage(ClienteMail cliente) {
LOGGER.info(String.format("Enviando mensaje JSON -> %s", cliente.toString()));
rabbitTemplate.convertAndSend(exchange, routingKey, cliente);
}
}
Si la analizáis, veréis que recibe los valores de application.properties
y desde Spring, y que con esos valores, se limita a realizar un «converterAndSend
» en donde especifica el exchange al que lo envía y la routingKey
Y aquí se acabaría el trabajo, ya que tenemos el servicio que realiza el envío, solo seria necesario crear un Controller que formateara el objeto ClienteMail y lo llamara, pero, como queremos poder hacer una prueba, podemos añadir una clase mas
La clase Demo que definimos a continuación, se arranca al finalizar la configuración de Spring, por lo que la podemos utilizar para cualquier cosa que deseemos, en este caso, lanzar un mensaje, y este podría ser el código
package com.rf.rabbit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import com.rf.rabbit.producers.RabbitMqProducer;
import com.rf.rabbit.dto.ClienteMail;
@Component
public class Demo implements CommandLineRunner {
@Autowired
RabbitMqProducer rmpq;
@Override
public void run(String... args) throws Exception {
System.out.println("Enviando mensaje...");
ClienteMail cm = new ClienteMail(1,"Miguel Garcia","[email protected]");
rmpq.sendMessage(cm);
}
}
Con todo esto, ya podemos realizar el Run de la aplicación, y veréis que tras arrancar, comunica que ha enviado un mensaje
Si tenéis arrancada la aplicación de consumer en una ventana CMD como hemos descrito antes, veréis también la recepción
Y cada vez que hagáis un restart del producer, veréis un nuevo mensaje en el cliente
Hasta aqui una sencilla presentacion de RabbitMQ y de alguna de sus posibilidades, si veis interesante el tema, podeis acudir a las paginas de RabbitMq
Relacionado
Descubre más desde Recursos para formacion
Suscríbete y recibe las últimas entradas en tu correo electrónico.