嵌入式 AMQP Java 代理
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30918557/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Embedded AMQP Java Broker
提问by ahjmorton
I am trying to create integration test for a Scala / Java application that connects to a RabbitMQ broker. To achieve this I would like an embedded broker that speaks AMQP that I start and stop before each test. Originally I tried to introduce ActiveMQ as an embedded broker with AMQP however the application uses RabbitMQ so only speaks AMQP version 0.9.3 whereas ActiveMQ requires AMQP version 1.0.
我正在尝试为连接到 RabbitMQ 代理的 Scala/Java 应用程序创建集成测试。为了实现这一点,我想要一个使用 AMQP 的嵌入式代理,我在每次测试之前启动和停止。最初我尝试将 ActiveMQ 作为带有 AMQP 的嵌入式代理引入,但是该应用程序使用 RabbitMQ,因此只使用 AMQP 0.9.3 版,而 ActiveMQ 需要 AMQP 1.0 版。
Is there another embedded broker I can use in place of ActiveMQ?
我可以使用另一个嵌入式代理来代替 ActiveMQ 吗?
采纳答案by OrangeDog
A completely in-memory solution. Replace the spring.*
properties as required.
完全在内存中的解决方案。spring.*
根据需要替换属性。
<dependency>
<groupId>org.apache.qpid</groupId>
<artifactId>qpid-broker</artifactId>
<version>6.1.1</version>
<scope>test</scope>
</dependency>
public class EmbeddedBroker {
public void start() {
Broker broker = new Broker();
BrokerOptions brokerOptions = new BrokerOptions();
brokerOptions.setConfigProperty("qpid.amqp_port", environment.getProperty("spring.rabbitmq.port"));
brokerOptions.setConfigProperty("qpid.broker.defaultPreferenceStoreAttributes", "{\"type\": \"Noop\"}");
brokerOptions.setConfigProperty("qpid.vhost", environment.getProperty("spring.rabbitmq.virtual-host"));
brokerOptions.setConfigurationStoreType("Memory");
brokerOptions.setStartupLoggedToSystemOut(false);
broker.startup(brokerOptions);
}
}
Add initial-config.json
as a resource:
添加initial-config.json
为资源:
{
"name": "Embedded Test Broker",
"modelVersion": "6.1",
"authenticationproviders" : [{
"name": "password",
"type": "Plain",
"secureOnlyMechanisms": [],
"users": [{"name": "guest", "password": "guest", "type": "managed"}]
}],
"ports": [{
"name": "AMQP",
"port": "${qpid.amqp_port}",
"authenticationProvider": "password",
"protocols": [ "AMQP_0_9_1" ],
"transports": [ "TCP" ],
"virtualhostaliases": [{
"name": "${qpid.vhost}",
"type": "nameAlias"
}]
}],
"virtualhostnodes" : [{
"name": "${qpid.vhost}",
"type": "Memory",
"virtualHostInitialConfiguration": "{ \"type\": \"Memory\" }"
}]
}
回答by Alejandro
I've developed a wrapper around the process of downloading, extracting, starting and managing RabbitMQ so it can work like an embedded service controlled by any JVM project.
我已经围绕下载、提取、启动和管理 RabbitMQ 的过程开发了一个包装器,因此它可以像任何 JVM 项目控制的嵌入式服务一样工作。
Check it out: https://github.com/AlejandroRivera/embedded-rabbitmq
看看:https: //github.com/AlejandroRivera/embedded-rabbitmq
It's as simple as:
这很简单:
EmbeddedRabbitMqConfig config = new EmbeddedRabbitMqConfig.Builder()
.version(PredefinedVersion.V3_5_7)
.build();
EmbeddedRabbitMq rabbitMq = new EmbeddedRabbitMq(config);
rabbitMq.start();
...
rabbitMq.stop();
Works on Linux, Mac and Windows.
适用于 Linux、Mac 和 Windows。
回答by Timi
Here's the solution proposed by OrangeDog adapted to Qpid Broker 7.x, inspired from here:
这是 OrangeDog 提出的适用于 Qpid Broker 7.x 的解决方案,灵感来自此处:
Add qpid 7.x as test dependecies. In 7.x these have been separated in core + plugins, depending on what you need. For RabbitMQ AMQP version you'll need qpid-broker-plugins-amqp-0-8-protocol
and for running in-memory (sufficient for integration tests) use qpid-broker-plugins-memory-store
.
添加 qpid 7.x 作为测试依赖。在 7.x 中,这些已在核心 + 插件中分开,具体取决于您的需要。对于 RabbitMQ AMQP 版本,您将需要qpid-broker-plugins-amqp-0-8-protocol
并在内存中运行(足以进行集成测试)使用qpid-broker-plugins-memory-store
.
pom.xml
:
pom.xml
:
...
<properties>
...
<qpid-broker.version>7.0.2</qpid-broker.version>
</properties>
<dependencies>
...
<dependency>
<groupId>org.apache.qpid</groupId>
<artifactId>qpid-broker-core</artifactId>
<version>${qpid-broker.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.qpid</groupId>
<artifactId>qpid-broker-plugins-amqp-0-8-protocol</artifactId>
<version>${qpid-broker.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.qpid</groupId>
<artifactId>qpid-broker-plugins-memory-store</artifactId>
<version>${qpid-broker.version}</version>
<scope>test</scope>
</dependency>
</dependecies>
...
Add broker configuration with hard-coded user/password and default in-memory virtual host mapped to default port (5672):
添加具有硬编码用户/密码和映射到默认端口 (5672) 的默认内存虚拟主机的代理配置:
qpid-config.json
:
qpid-config.json
:
{
"name": "EmbeddedBroker",
"modelVersion": "7.0",
"authenticationproviders": [
{
"name": "password",
"type": "Plain",
"secureOnlyMechanisms": [],
"users": [{"name": "guest", "password": "guest", "type": "managed"}]
}
],
"ports": [
{
"name": "AMQP",
"port": "${qpid.amqp_port}",
"authenticationProvider": "password",
"virtualhostaliases": [
{
"name": "defaultAlias",
"type": "defaultAlias"
}
]
}
],
"virtualhostnodes": [
{
"name": "default",
"defaultVirtualHostNode": "true",
"type": "Memory",
"virtualHostInitialConfiguration": "{\"type\": \"Memory\" }"
}
]
}
Define junit ExternalResource
and declare as ClassRule
(or start and close your embedded broker in your IT @BeforeClass
and @AfterClass
methods):
定义 junitExternalResource
并声明为ClassRule
(或在您的 IT@BeforeClass
和@AfterClass
方法中启动和关闭您的嵌入式代理):
EmbeddedAMQPBroker.java
:
EmbeddedAMQPBroker.java
:
public class EmbeddedAMQPBroker extends ExternalResource {
private final SystemLauncher broker = new SystemLauncher();
@Override
protected void before() throws Throwable {
startQpidBroker();
//createExchange();
}
@Override
protected void after() {
broker.shutdown();
}
private void startQpidBroker() throws Exception {
Map<String, Object> attributes = new HashMap<>();
attributes.put("type", "Memory");
attributes.put("initialConfigurationLocation", findResourcePath("qpid-config.json"));
broker.startup(attributes);
}
private String findResourcePath(final String fileName) {
return EmbeddedAMQPBroker.class.getClassLoader().getResource(fileName).toExternalForm();
}
}
Integration test:
集成测试:
public class MessagingIT{
@ClassRule
public static EmbeddedAMQPBroker embeddedAMQPBroker = new EmbeddedAMQPBroker();
...
}
回答by Ian Dallas
I'm not aware of any embedded RabbitMQ servers so I think you have a couple options to workaround this:
我不知道有任何嵌入式 RabbitMQ 服务器,所以我认为您有几个选项可以解决这个问题:
Your RabbitMQ server does not need to exist on your CI server, you can bring up a new server that is your CI rabbitmq server. If you can't bring one up yourself you could look into CloudAMQP. The free tier today offers: 1M messages per month, 20 concurrent connections, 100 queues, 10,000 queued messages. Could be enough for your CI process.
If your testing is only being done unit tests for RabbitMQ you could mock out your RabbitMQ message production. This is what we do in some of our unit tests. We just check that a certain operation make the method call to produce a specific message, but we mock this out so we don't actually publish a message. Then we test each of the consumers by explicitly calling the consumer methods with a specific message we created.
您的 RabbitMQ 服务器不需要存在于您的 CI 服务器上,您可以启动一个新服务器,即您的 CI rabbitmq 服务器。如果你不能自己提出来,你可以看看CloudAMQP。今天的免费套餐提供:每月 100 万条消息、20 个并发连接、100 个队列、10,000 条排队消息。对于您的 CI 过程来说可能就足够了。
如果您的测试仅针对 RabbitMQ 进行单元测试,您可以模拟出您的 RabbitMQ 消息生产。这就是我们在一些单元测试中所做的。我们只是检查某个操作是否使方法调用以生成特定消息,但我们对此进行了模拟,因此我们实际上并未发布消息。然后我们通过使用我们创建的特定消息显式调用消费者方法来测试每个消费者。
回答by Arnost Valicek
You can try Apache QPid Java broker. This can be used as embedded broker.
你可以试试Apache QPid Java broker。这可以用作嵌入式代理。
Setup in Scala is described in another SO question - Example of standalone Apache Qpid (amqp) Junit Test
在另一个 SO 问题中描述了 Scala 中的设置 -独立 Apache Qpid (amqp) Junit 测试示例