Embedded AMQP Java Broker

Próbuję stworzyć test integracji dla aplikacji Scala / Java, która łączy się z brokerem RabbitMQ. Aby to osiągnąć, chciałbym wbudowanego brokera, który mówi AMQP, który rozpoczynam i Zatrzymuję przed każdym testem. Początkowo próbowałem wprowadzić ActiveMQ jako wbudowany broker z AMQP jednak aplikacja używa RabbitMQ więc tylko mówi AMQP wersja 0.9.3 podczas gdy ActiveMQ wymaga AMQP Wersja 1.0.

Czy jest inny wbudowany broker, którego mogę użyć zamiast ActiveMQ?

Author: Umberto Raimondi, 2015-06-18

5 answers

Rozwiązanie całkowicie w pamięci. Wymień właściwości spring.* zgodnie z wymaganiami.

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

Dodaj initial-config.json jako zasób:

{
  "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\" }"
  }]
}
 14
Author: OrangeDog,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-09 16:31:05

Opracowałem wrapper wokół procesu pobierania, wyodrębniania, uruchamiania i zarządzania RabbitMQ, aby mógł działać jak wbudowana usługa kontrolowana przez dowolny projekt JVM.

Zobacz: https://github.com/AlejandroRivera/embedded-rabbitmq

To tak proste jak:

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

Działa na Linuksie, Mac i Windows.

 10
Author: Alejandro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-12 14:02:43

Oto rozwiązanie zaproponowane przez OrangeDog dostosowane do Qpid Broker 7.x, zainspirowany tutaj :

Dodaj qpid 7.x jako zależne od testu. W 7.x zostały one oddzielone w core + plugins, w zależności od tego, czego potrzebujesz. Dla wersji RabbitMQ AMQP potrzebujesz qpid-broker-plugins-amqp-0-8-protocol, A do uruchomienia w pamięci (wystarczająca do testów integracyjnych) użyj qpid-broker-plugins-memory-store.

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>
...

Dodaj konfigurację brokera z zakodowanym użytkownikiem / hasłem i domyślnym hostem wirtualnym w pamięci odwzorowanym na port domyślny (5672):

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\" }"
    }
  ]
}

Zdefiniuj junit ExternalResource i zadeklaruj jako ClassRule (lub uruchom i zamknij wbudowany broker w metodach IT @BeforeClass i @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();
    }
}

Test integracyjny:

public class MessagingIT{
    @ClassRule
    public static EmbeddedAMQPBroker embeddedAMQPBroker = new EmbeddedAMQPBroker();

    ...
}
 9
Author: Timi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-12 12:01:48

Nie znam żadnych wbudowanych serwerów RabbitMQ więc myślę, że masz kilka opcji, aby to obejść:

  1. Twój serwer RabbitMQ nie musi istnieć na twoim serwerze CI, możesz wywołać nowy serwer, który jest twoim serwerem rabbitmq. Jeśli nie możesz sam go podnieść, możesz zajrzeć do CloudAMQP . Darmowa warstwa oferuje: 1m wiadomości miesięcznie, 20 jednoczesnych połączeń, 100 kolejek, 10 000 wiadomości w kolejce. Może wystarczyć dla Twojego CI proces.

  2. Jeśli twoje testy są wykonywane tylko testy jednostkowe dla RabbitMQ, możesz wyśmiewać produkcję wiadomości RabbitMQ. To właśnie robimy w niektórych naszych testach jednostkowych. Po prostu sprawdzamy, czy pewna operacja powoduje wywołanie metody, aby wytworzyć konkretną wiadomość, ale wyśmiewamy to, aby nie publikować wiadomości. Następnie testujemy każdego z konsumentów, jawnie wywołując metody konsumenckie z określonym komunikatem, który stworzyliśmy.

 3
Author: Ian Dallas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-30 19:54:59

Możesz wypróbować Apache QPid Java broker . Może to być używane jako wbudowany broker.

Konfiguracja w Scali opisana jest w innym so question - przykład samodzielnego testu Apache Qpid (amqp) Junit

 2
Author: Arnost Valicek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-20 15:07:05