Я ищу модуль Spring, который может помочь мне интегрировать веб-службы Spring REST с шиной сообщений (RabbitMQ). Веб-служба REST выступает в роли потребителя сообщений AMQP от клиента. Всякий раз, когда сообщения отправляются по шине, это сообщение AMQP, и чтобы оно работало с REST, оно должно быть преобразовано в вызов REST. Кто-нибудь знает о существующем решении, чтобы заставить его работать?
Связь по шине сообщений Spring REST
Ответы (1)
Я лично не вижу смысла в этом, то есть в использовании синхронного интерфейса REST для использования некоторых асинхронных сообщений AMQP, поскольку вы как бы теряете цель / преимущества асинхронной системы сообщений, такой как RabbitMQ.
Отличительной особенностью AMQP является то, что это проводной протокол, не привязанный к одному языку (например, JMS в значительной степени привязан к Java). Это означает, что вы можете использовать библиотеку Java / Spring / AMQP, библиотеку Node.JS / AMQP, библиотеку C # / AMQP и т. Д. Эта статья объясняет преимущества лучше, чем я http://www.wmrichards.com/amqp.pdf Я хочу сказать, если вы ищете REST для создания моста между другим языком / системой и т. д. с RabbitMQ, тогда Я бы прежде всего исследовал, поддерживает ли другой язык / система библиотеку AMQP.
Однако, если у вас ДОЛЖЕН быть интерфейс REST, вы можете создать простой контроллер с помощью SpringMVC и ввести private AmqpTemplate amqpTemplate;
с помощью некоторых методов. Это эффективно создает мост / прокси-сервер REST-to-AMQP. Конфигурация пружины / Java-контроллер выглядит следующим образом (обратите внимание, что это было протестировано и работает): -
/spring/restAmqpContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">
<!-- Location of "config.properties" to override RabbitMQ connection details if required. -->
<context:property-placeholder ignore-resource-not-found="true"
location="classpath:/config.properties,
${DATA_HOME:}/config.properties" />
<bean class="com.bobmarks.controller.RestAmqpController">
<property name="amqpTemplate" ref="amqpTemplate"/>
</bean>
<mvc:default-servlet-handler />
<mvc:annotation-driven/>
<rabbit:connection-factory id="amqpConnectionFactory"
host="${rabbitmq.host:localhost}"
port="${rabbitmq.port:5672}"
username="${rabbitmq.username:guest}"
password="${rabbitmq.password:guest}"
publisher-confirms="${rabbitmq.publisher.confirms:true}"
publisher-returns="${rabbitmq.publisher.returns:true}" />
<rabbit:template id="amqpTemplate" connection-factory="amqpConnectionFactory" mandatory="true" />
<rabbit:admin id="rabbitAdmin" connection-factory="amqpConnectionFactory" />
<rabbit:queue name="my_queue" />
<rabbit:direct-exchange name="my_exchange">
<rabbit:bindings><rabbit:binding queue="my_queue" key="my_binding" /></rabbit:bindings>
</rabbit:direct-exchange>
RestAmqpController.java
package com.bobmarks.controller;
import java.util.Date;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
/**
* Simple Rest To AMQP Controller.
*/
@Controller
@RequestMapping(value = "/rest2amqp")
public class RestAmqpController {
private AmqpTemplate amqpTemplate;
public RestAmqpController() {}
public void setAmqpTemplate(AmqpTemplate amqpTemplate) {
this.amqpTemplate = amqpTemplate;
}
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<String> message(@RequestParam(value = "message") String message) {
try {
amqpTemplate.convertAndSend("my_exchange", "my_binding", message);
return new ResponseEntity<String>("Message sent to AMQP queue at: " + new Date(), HttpStatus.OK);
}
catch (AmqpException amqpEx) {
return new ResponseEntity<String>(amqpEx.getMessage(), HttpStatus.BAD_REQUEST);
}
}
}
Они упакованы обычным способом (Tomcat / Spring Boot / и т. Д.), И, например, если проект называется data, конечная точка REST для отправки сообщения будет следующей: -
http://localhost/data/rest2amqp?message=Hello_World
Наверное, лучше это показать на скриншотах.
Снимок экрана отправки сообщения (только с использованием FireFox)
Снимок экрана клиента администратора RabbitMQ, показывающего, что сообщение получено
Снимок экрана с фактическим сообщением
ПРИМЕЧАНИЕ. Это очень простой пример с одним обменом / очередью RabbitMQ, который не содержит безопасности или каких-либо других базовых вещей, которые вам, вероятно, могут понадобиться!