嵌入式AMQP Java代理

嵌入式AMQP Java代理,java,rabbitmq,automated-tests,integration-testing,amqp,Java,Rabbitmq,Automated Tests,Integration Testing,Amqp,我正在尝试为连接到RabbitMQ代理的Scala/Java应用程序创建集成测试。为了实现这一点,我希望有一个嵌入式代理,它能讲AMQP,我在每次测试之前启动和停止它。最初,我尝试将ActiveMQ作为一个带有AMQP的嵌入式代理引入,但是应用程序使用RabbitMQ,因此只使用AMQP版本0.9.3,而ActiveMQ需要AMQP版本1.0 我是否可以使用另一个嵌入式代理来代替ActiveMQ?我不知道有任何嵌入式RabbitMQ服务器,因此我认为您有两个解决方案: 您的RabbitMQ服务器

我正在尝试为连接到RabbitMQ代理的Scala/Java应用程序创建集成测试。为了实现这一点,我希望有一个嵌入式代理,它能讲AMQP,我在每次测试之前启动和停止它。最初,我尝试将ActiveMQ作为一个带有AMQP的嵌入式代理引入,但是应用程序使用RabbitMQ,因此只使用AMQP版本0.9.3,而ActiveMQ需要AMQP版本1.0


我是否可以使用另一个嵌入式代理来代替ActiveMQ?

我不知道有任何嵌入式RabbitMQ服务器,因此我认为您有两个解决方案:

  • 您的RabbitMQ服务器不需要存在于您的CI服务器上,您可以启动一个新服务器,即您的CI RabbitMQ服务器。如果你不能自己提出来,你可以调查一下。今天的免费层提供:每月100万条消息,20个并发连接,100个队列,10000条排队消息。对于您的CI流程来说可能足够了

  • 如果您的测试只针对RabbitMQ进行单元测试,那么您可以模拟RabbitMQ消息生成。这就是我们在一些单元测试中所做的。我们只是检查某个操作是否进行了方法调用以生成特定的消息,但我们模拟了这一点,因此我们实际上不发布消息。然后,我们通过使用我们创建的特定消息显式调用consumer方法来测试每个使用者

  • 你可以试试。这可以用作嵌入式代理


    Scala中的设置在另一个SO问题中进行了描述-

    我已经围绕下载、提取、启动和管理RabbitMQ的过程开发了一个包装器,因此它可以像任何JVM项目控制的嵌入式服务一样工作

    请查看:

    简单到:

    EmbeddedRabbitMqConfig config = new EmbeddedRabbitMqConfig.Builder()
        .version(PredefinedVersion.V3_5_7)
        .build();
    EmbeddedRabbitMq rabbitMq = new EmbeddedRabbitMq(config);
    rabbitMq.start();
    ...
    rabbitMq.stop();
    

    适用于Linux、Mac和Windows。

    完全在内存中的解决方案。根据需要更换
    弹簧。*
    属性

    <dependency>
      <groupId>org.apache.qpid</groupId>
      <artifactId>qpid-broker</artifactId>
      <version>6.1.1</version>
      <scope>test</scope>
    </dependency>
    
    添加
    initial config.json
    作为资源:


    以下是OrangeDog提出的适用于Qpid Broker 7.x的解决方案,其灵感来自:

    添加qpid 7.x作为测试依赖项。在7.x中,根据您的需要,它们在核心+插件中被分开。对于RabbitMQ AMQP版本,您需要
    qpid-broker-plugins-AMQP-0-8-protocol
    ,对于在内存中运行(足以进行集成测试),请使用
    qpid-broker-plugins内存存储

    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>
    ...
    
    定义junit
    ExternalResource
    并声明为
    ClassRule
    (或者在您的IT
    @BeforeClass
    @AfterClass
    方法中启动并关闭嵌入式代理):

    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();
        }
    }
    

    RabbitMQ实现AMQP0.8;0.9.1和AMQP 1.0。如果您使用的是mac,那么为测试启动/停止rabbitmq非常容易。这是针对PHP的,但可能会在您的用例中帮助您Hi@old_sound,谢谢您的关注。理想情况下,我希望避免要求机箱上的rabbitmq进行测试,我们的测试运行在无法轻松安装rabbitmq的CI服务器上。该CI服务器是否至少安装了Erlang?如果是的话,你可以下载兔子塔尔球,解压缩它,并开始/停止它的测试,因为你有一些答复下面似乎回答你的问题,请考虑将其中一个标记为“接受”点击滴答低于他们的选票计数(见)。这显示了哪个答案对你帮助最大,并为答案的作者(和你!)分配了声誉点数。它是的一部分。效果很好,但需要预先安装ERL对我来说是个问题。请注意,如果您的应用程序连接到prod中的RabbitMQ,那么如果您绑定到Apache QPid进行集成测试,您可能会发现不一致。RabbitMQ扩展了AMQP,以提供应用程序可能依赖的其他功能(例如TTLs、DLE/Qs、路由等)。更多信息QPid也有很多,只是名称不同。我不能使用它,因为他们硬编码logger类。真遗憾。。。org.apache.logging.slf4j.Log4jLogger不能强制转换为ch.qos.logback.classic.Logger java.lang.ClassCastException:org.apache.logging.slf4j.Log4jLogger不能强制转换为ch.qos.logback.classic。Logger@JanGoyvaerts呵呵?它使用slf4j——任何地方都没有硬编码。如果出于某种原因需要直接访问记录器实现,您可以将其配置为使用Logback。@OrangeDog,感谢您指出这一点!你能告诉我一些使用7.x的嵌入式示例吗?整个API似乎都改变了,我几乎找不到任何关于如何使用它的例子。这是我能找到的全部,但我无法让它与密码文件一起工作。
    ...
    <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>
    ...
    
    {
      "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\" }"
        }
      ]
    }
    
    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();
        }
    }
    
    public class MessagingIT{
        @ClassRule
        public static EmbeddedAMQPBroker embeddedAMQPBroker = new EmbeddedAMQPBroker();
    
        ...
    }