web-dev-qa-db-fra.com

AMQP intégré Java Broker

J'essaie de créer un test d'intégration pour une application Scala/Java qui se connecte à un courtier RabbitMQ. Pour y parvenir, je voudrais un courtier intégré qui parle AMQP que je démarre et arrête avant chaque test. À l'origine, j'essayais d'introduire ActiveMQ en tant que courtier intégré avec AMQP, mais l'application utilise RabbitMQ, donc ne parle qu'AMQP version 0.9.3 alors qu'ActiveMQ nécessite AMQP version 1.0.

Existe-t-il un autre courtier intégré que je peux utiliser à la place d'ActiveMQ?

18
ahjmorton

Une solution entièrement en mémoire. Remplace le spring.* propriétés selon les besoins.

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

Ajouter initial-config.json comme ressource:

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

J'ai développé un wrapper autour du processus de téléchargement, d'extraction, de démarrage et de gestion de RabbitMQ afin qu'il puisse fonctionner comme un service intégré contrôlé par n'importe quel projet JVM.

Découvrez-le: https://github.com/AlejandroRivera/embedded-rabbitmq

C'est aussi simple que:

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

Fonctionne sur Linux, Mac et Windows.

10
Alejandro

Voici la solution proposée par OrangeDog adaptée à Qpid Broker 7.x, inspirée de ici :

Ajoutez qpid 7.x comme dépendances de test. Dans 7.x ceux-ci ont été séparés en core + plugins, selon ce dont vous avez besoin. Pour la version RabbitMQ AMQP, vous aurez besoin de qpid-broker-plugins-amqp-0-8-protocol et pour exécuter en mémoire (suffisant pour les tests d'intégration) utilisez 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>
...

Ajoutez une configuration de courtier avec un utilisateur/mot de passe codé en dur et un hôte virtuel en mémoire par défaut mappé sur le port par défaut (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\" }"
    }
  ]
}

Définissez junit ExternalResource et déclarez comme ClassRule (ou démarrez et fermez votre courtier intégré dans votre IT @BeforeClass et @AfterClass méthodes):

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 d'intégration:

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

    ...
}
8
Timi

Je ne connais aucun serveur RabbitMQ intégré, donc je pense que vous avez quelques options pour contourner cela:

  1. Votre serveur RabbitMQ n'a pas besoin d'exister sur votre serveur CI, vous pouvez faire apparaître un nouveau serveur qui est votre serveur CI rabbitmq. Si vous ne pouvez pas en afficher un vous-même, vous pouvez consulter CloudAMQP . Le niveau gratuit offre aujourd'hui: 1 million de messages par mois, 20 connexions simultanées, 100 files d'attente, 10 000 messages en file d'attente. Cela pourrait être suffisant pour votre processus CI.

  2. Si vos tests ne sont effectués que des tests unitaires pour RabbitMQ, vous pouvez simuler la production de votre message RabbitMQ. C'est ce que nous faisons dans certains de nos tests unitaires. Nous vérifions simplement qu'une certaine opération appelle la méthode pour produire un message spécifique, mais nous nous moquons de cela afin de ne pas réellement publier un message. Ensuite, nous testons chacun des consommateurs en appelant explicitement les méthodes de consommation avec un message spécifique que nous avons créé.

3
Ian Dallas

Vous pouvez essayer Apache QPid Java broker . Cela peut être utilisé comme broker intégré.

Configuration dans Scala est décrit dans une autre SO - Exemple de test Junit Apache Qpid (amqp) autonome

2
Arnost Valicek