예제 #1
0
 public void testConnectionRecoveryWithArrayOfAddresses()
     throws IOException, InterruptedException, TimeoutException {
   final Address[] addresses = {new Address("127.0.0.1"), new Address("127.0.0.1", 5672)};
   AutorecoveringConnection c = newRecoveringConnection(addresses);
   try {
     assertTrue(c.isOpen());
     closeAndWaitForRecovery(c);
     assertTrue(c.isOpen());
   } finally {
     c.abort();
   }
 }
예제 #2
0
  public void testConsumerRecoveryWithManyConsumers() throws IOException, InterruptedException {
    String q =
        channel.queueDeclare(UUID.randomUUID().toString(), false, false, false, null).getQueue();
    final int n = 1024;
    for (int i = 0; i < n; i++) {
      channel.basicConsume(q, new DefaultConsumer(channel));
    }
    final AtomicReference<String> tagA = new AtomicReference<String>();
    final AtomicReference<String> tagB = new AtomicReference<String>();
    final CountDownLatch listenerLatch = new CountDownLatch(n);
    ((AutorecoveringConnection) connection)
        .addConsumerRecoveryListener(
            new ConsumerRecoveryListener() {
              @Override
              public void consumerRecovered(String oldConsumerTag, String newConsumerTag) {
                tagA.set(oldConsumerTag);
                tagB.set(newConsumerTag);
                listenerLatch.countDown();
              }
            });

    assertConsumerCount(n, q);
    closeAndWaitForRecovery();
    wait(listenerLatch);
    assertTrue(tagA.get().equals(tagB.get()));
    expectChannelRecovery(channel);
    assertConsumerCount(n, q);
  }
예제 #3
0
  public void testServerNamedQueueRecovery() throws IOException, InterruptedException {
    String q = channel.queueDeclare("", false, false, false, null).getQueue();
    String x = "amq.fanout";
    channel.queueBind(q, x, "");

    final AtomicReference<String> nameBefore = new AtomicReference<String>();
    final AtomicReference<String> nameAfter = new AtomicReference<String>();
    final CountDownLatch listenerLatch = new CountDownLatch(1);
    ((AutorecoveringConnection) connection)
        .addQueueRecoveryListener(
            new QueueRecoveryListener() {
              @Override
              public void queueRecovered(String oldName, String newName) {
                nameBefore.set(oldName);
                nameAfter.set(newName);
                listenerLatch.countDown();
              }
            });

    closeAndWaitForRecovery();
    wait(listenerLatch);
    expectChannelRecovery(channel);
    channel.basicPublish(x, "", null, "msg".getBytes());
    assertDelivered(q, 1);
    assertFalse(nameBefore.get().equals(nameAfter.get()));
    channel.queueDelete(q);
  }
예제 #4
0
 // bug 26552
 public void testServerNamedTransientAutoDeleteQueueAndBindingRecovery()
     throws IOException, InterruptedException, TimeoutException {
   String x = "tmp-fanout";
   Channel ch = connection.createChannel();
   ch.exchangeDelete(x);
   ch.exchangeDeclare(x, "fanout");
   String q = ch.queueDeclare("", false, false, true, null).getQueue();
   final AtomicReference<String> nameBefore = new AtomicReference<String>(q);
   final AtomicReference<String> nameAfter = new AtomicReference<String>();
   final CountDownLatch listenerLatch = new CountDownLatch(1);
   ((AutorecoveringConnection) connection)
       .addQueueRecoveryListener(
           new QueueRecoveryListener() {
             @Override
             public void queueRecovered(String oldName, String newName) {
               nameBefore.set(oldName);
               nameAfter.set(newName);
               listenerLatch.countDown();
             }
           });
   ch.queueBind(nameBefore.get(), x, "");
   restartPrimaryAndWaitForRecovery();
   expectChannelRecovery(ch);
   ch.confirmSelect();
   ch.exchangeDeclare(x, "fanout");
   ch.basicPublish(x, "", null, "msg".getBytes());
   waitForConfirms(ch);
   AMQP.Queue.DeclareOk ok = ch.queueDeclarePassive(nameAfter.get());
   assertEquals(1, ok.getMessageCount());
   ch.queueDelete(nameAfter.get());
   ch.exchangeDelete(x);
 }
예제 #5
0
 private CountDownLatch prepareForRecovery(Connection conn) {
   final CountDownLatch latch = new CountDownLatch(1);
   ((AutorecoveringConnection) conn)
       .addRecoveryListener(
           new RecoveryListener() {
             public void handleRecovery(Recoverable recoverable) {
               latch.countDown();
             }
           });
   return latch;
 }
  /**
   * Create a new broker connection with a client-provided name, picking the first available address
   * from the list provided by the {@link AddressResolver}.
   *
   * <p>If <a href="http://www.rabbitmq.com/api-guide.html#recovery">automatic connection
   * recovery</a> is enabled, the connection returned by this method will be {@link Recoverable}.
   * Future reconnection attempts will pick a random accessible address provided by the {@link
   * AddressResolver}.
   *
   * @param executor thread execution service for consumers on the connection
   * @param addressResolver discovery service to list potential addresses (hostname/port pairs) to
   *     connect to
   * @param clientProvidedName application-specific connection name, will be displayed in the
   *     management UI if RabbitMQ server supports it. This value doesn't have to be unique and
   *     cannot be used as a connection identifier e.g. in HTTP API requests. This value is supposed
   *     to be human-readable.
   * @return an interface to the connection
   * @throws java.io.IOException if it encounters a problem
   * @see <a href="http://www.rabbitmq.com/api-guide.html#recovery">Automatic Recovery</a>
   */
  public Connection newConnection(
      ExecutorService executor, AddressResolver addressResolver, String clientProvidedName)
      throws IOException, TimeoutException {
    if (this.metricsCollector == null) {
      this.metricsCollector = new NoOpMetricsCollector();
    }
    // make sure we respect the provided thread factory
    FrameHandlerFactory fhFactory = createFrameHandlerFactory();
    ConnectionParams params = params(executor);
    // set client-provided via a client property
    if (clientProvidedName != null) {
      Map<String, Object> properties = new HashMap<String, Object>(params.getClientProperties());
      properties.put("connection_name", clientProvidedName);
      params.setClientProperties(properties);
    }

    if (isAutomaticRecoveryEnabled()) {
      // see com.rabbitmq.client.impl.recovery.RecoveryAwareAMQConnectionFactory#newConnection
      AutorecoveringConnection conn =
          new AutorecoveringConnection(params, fhFactory, addressResolver, metricsCollector);

      conn.init();
      return conn;
    } else {
      List<Address> addrs = addressResolver.getAddresses();
      IOException lastException = null;
      for (Address addr : addrs) {
        try {
          FrameHandler handler = fhFactory.create(addr);
          AMQConnection conn = new AMQConnection(params, handler, metricsCollector);
          conn.start();
          this.metricsCollector.newConnection(conn);
          return conn;
        } catch (IOException e) {
          lastException = e;
        }
      }
      throw (lastException != null) ? lastException : new IOException("failed to connect");
    }
  }
예제 #7
0
 public void testConnectionRecoveryWithDisabledTopologyRecovery()
     throws IOException, InterruptedException, TimeoutException {
   AutorecoveringConnection c = newRecoveringConnection(true);
   Channel ch = c.createChannel();
   String q = "java-client.test.recovery.q2";
   ch.queueDeclare(q, false, true, false, null);
   ch.queueDeclarePassive(q);
   assertTrue(c.isOpen());
   try {
     CountDownLatch shutdownLatch = prepareForShutdown(c);
     CountDownLatch recoveryLatch = prepareForRecovery(c);
     Host.closeConnection(c);
     wait(shutdownLatch);
     wait(recoveryLatch);
     assertTrue(c.isOpen());
     ch.queueDeclarePassive(q);
     fail("expected passive declaration to throw");
   } catch (java.io.IOException e) {
     // expected
   } finally {
     c.abort();
   }
 }
예제 #8
0
  public void testBasicAckAfterChannelRecovery()
      throws IOException, InterruptedException, TimeoutException {
    final AtomicInteger consumed = new AtomicInteger(0);
    int n = 5;
    final CountDownLatch latch = new CountDownLatch(n);
    Consumer consumer =
        new DefaultConsumer(channel) {
          @Override
          public void handleDelivery(
              String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
              throws IOException {
            try {
              if (consumed.intValue() > 0 && consumed.intValue() % 4 == 0) {
                CountDownLatch recoveryLatch = prepareForRecovery(connection);
                Host.closeConnection((AutorecoveringConnection) connection);
                ConnectionRecovery.wait(recoveryLatch);
              }
              channel.basicAck(envelope.getDeliveryTag(), false);
            } catch (InterruptedException e) {
              // ignore
            } finally {
              consumed.incrementAndGet();
              latch.countDown();
            }
          }
        };

    String q = channel.queueDeclare().getQueue();
    channel.basicConsume(q, consumer);
    AutorecoveringConnection publishingConnection = newRecoveringConnection(false);
    Channel publishingChannel = publishingConnection.createChannel();
    for (int i = 0; i < n; i++) {
      publishingChannel.basicPublish("", q, null, "msg".getBytes());
    }
    wait(latch);
    publishingConnection.abort();
  }
예제 #9
0
 public void testNamedConnectionRecovery()
     throws IOException, InterruptedException, TimeoutException {
   String connectionName = "custom name";
   AutorecoveringConnection c = newRecoveringConnection(connectionName);
   try {
     assertTrue(c.isOpen());
     assertEquals(connectionName, c.getClientProvidedName());
     closeAndWaitForRecovery(c);
     assertTrue(c.isOpen());
     assertEquals(connectionName, c.getClientProvidedName());
   } finally {
     c.abort();
   }
 }