Example usage for com.rabbitmq.client Channel getNextPublishSeqNo

List of usage examples for com.rabbitmq.client Channel getNextPublishSeqNo

Introduction

In this page you can find the example usage for com.rabbitmq.client Channel getNextPublishSeqNo.

Prototype

long getNextPublishSeqNo();

Source Link

Document

When in confirm mode, returns the sequence number of the next message to be published.

Usage

From source file:com.kurento.kmf.rabbitmq.RabbitTemplate.java

License:Apache License

/**
 * Send the given message to the specified exchange.
 *
 * @param channel//from  ww  w  . ja v  a  2s .  c  om
 *            The RabbitMQ Channel to operate within.
 * @param exchange
 *            The name of the RabbitMQ exchange to send to.
 * @param routingKey
 *            The routing key.
 * @param message
 *            The Message to send.
 * @param correlationData
 *            The correlation data.
 * @throws IOException
 *             If thrown by RabbitMQ API methods
 */
protected void doSend(Channel channel, String exchange, String routingKey, Message message,
        CorrelationData correlationData) throws Exception {
    if (logger.isDebugEnabled()) {
        logger.debug("Publishing message on exchange [" + exchange + "], routingKey = [" + routingKey + "]");
    }

    if (exchange == null) {
        // try to send to configured exchange
        exchange = this.exchange;
    }

    if (routingKey == null) {
        // try to send to configured routing key
        routingKey = this.routingKey;
    }
    if (this.confirmCallback != null && channel instanceof PublisherCallbackChannel) {
        PublisherCallbackChannel publisherCallbackChannel = (PublisherCallbackChannel) channel;
        publisherCallbackChannel.addPendingConfirm(this, channel.getNextPublishSeqNo(),
                new PendingConfirm(correlationData, System.currentTimeMillis()));
    }
    boolean mandatory = this.returnCallback != null && this.mandatory;
    MessageProperties messageProperties = message.getMessageProperties();
    if (mandatory) {
        messageProperties.getHeaders().put(PublisherCallbackChannel.RETURN_CORRELATION, this.uuid);
    }
    BasicProperties convertedMessageProperties = this.messagePropertiesConverter
            .fromMessageProperties(messageProperties, encoding);
    channel.basicPublish(exchange, routingKey, mandatory, convertedMessageProperties, message.getBody());
    // Check if commit needed
    if (isChannelLocallyTransacted(channel)) {
        // Transacted channel created by this template -> commit.
        RabbitUtils.commitIfNecessary(channel);
    }
}

From source file:net.lshift.accent.AccentConfirmPublisher.java

License:Apache License

/**
 * Attempt to reliably publish the given message to the given exchange. If this method returns, it is guaranteed
 * that the message is either completely delivered or that responsibility has been transferred to the broker. If an
 * exception is thrown, the message is not guaranteed to have been sent (though it is possible that it may have been
 * due to a possible communication failure just after delivery completed, but before acknowledgement was received).
 *
 * @param exchangeName/* ww  w .  j a v  a2s .c o  m*/
 * @param routingKey
 * @param props
 * @param data
 */
public void reliablePublish(final String exchangeName, final String routingKey,
        final AMQP.BasicProperties props, final byte[] data) {
    while (true) {
        Exception res = owner.executeWhenChannelValid(new ChannelCallback() {
            @Override
            public void runWithChannel(Channel channel) throws IOException {
                while (true) {
                    FeedbackHandle feedback;

                    synchronized (channelIdLock) {
                        // Create a handle to receive feedback, then publish the message. Lock this to the channel so that we can
                        // ensure the seqNo and the publish are the same ones.
                        feedback = feedbackListener.createFeedbackHandle(channel.getNextPublishSeqNo());
                        channel.basicPublish(exchangeName, routingKey, props, data);
                    }

                    // Once the feedback is positive, we can stop resending
                    if (feedback.await())
                        break;
                }
            }
        });

        if (res == null)
            break;
    }
}

From source file:org.mule.transport.amqp.DefaultAmqpConfirmsManager.java

License:Open Source License

public void requestConfirm(Channel channel, MuleEvent event) throws Exception {
    if (!handlesConfirms()) {
        return;/*from w w w.  j ava 2s .c  o m*/
    }

    channel.addConfirmListener(new ConfirmListener() {
        public void handleAck(long deliveryTag, boolean multiple) throws IOException {
            confirm(deliveryTag, true);
        }

        public void handleNack(long deliveryTag, boolean multiple) throws IOException {
            confirm(deliveryTag, false);
        }
    });

    channel.confirmSelect();
    long nextSequence = channel.getNextPublishSeqNo();
    pendingConfirms.put(nextSequence, new ConfirmHandler());
    event.setFlowVariable(AmqpConstants.NEXT_PUBLISH_SEQ_NO, nextSequence);

}

From source file:org.mule.transport.amqp.internal.confirm.DefaultConfirmsManager.java

License:Open Source License

public void requestConfirm(Channel channel, MuleEvent event) throws Exception {
    if (!handlesConfirms()) {
        return;/*from   w w w . j av  a  2 s  .  co m*/
    }

    channel.addConfirmListener(new ConfirmListener() {
        public void handleAck(long deliveryTag, boolean multiple) throws IOException {
            confirm(deliveryTag, true);
        }

        public void handleNack(long deliveryTag, boolean multiple) throws IOException {
            confirm(deliveryTag, false);
        }
    });

    channel.confirmSelect();
    long nextSequence = channel.getNextPublishSeqNo();
    pendingConfirms.put(nextSequence, new ConfirmHandler());
    event.setFlowVariable(AmqpConnector.MESSAGE_PROPERTY_NEXT_PUBLISH_SEQ_NO, nextSequence);

}

From source file:org.springframework.amqp.rabbit.core.RabbitTemplatePublisherCallbacksIntegrationTests.java

License:Apache License

/**
 * AMQP-262/*from  w  w w  . ja  v  a 2s  . c om*/
 * Sets up a situation where we are processing 'multi' acks at the same
 * time as adding a new pending ack to the map. Test verifies we don't
 * get a {@link ConcurrentModificationException}.
 */
@SuppressWarnings({ "rawtypes", "unchecked", "deprecation" })
@Test
public void testConcurrentConfirms() throws Exception {
    ConnectionFactory mockConnectionFactory = mock(ConnectionFactory.class);
    Connection mockConnection = mock(Connection.class);
    Channel mockChannel = mock(Channel.class);
    when(mockChannel.getNextPublishSeqNo()).thenReturn(1L, 2L, 3L, 4L);

    when(mockConnectionFactory.newConnection((ExecutorService) null)).thenReturn(mockConnection);
    when(mockConnection.isOpen()).thenReturn(true);
    final PublisherCallbackChannelImpl channel = new PublisherCallbackChannelImpl(mockChannel);
    when(mockConnection.createChannel()).thenReturn(channel);

    final RabbitTemplate template = new RabbitTemplate(new SingleConnectionFactory(mockConnectionFactory));

    final CountDownLatch first2SentOnThread1Latch = new CountDownLatch(1);
    final CountDownLatch delayAckProcessingLatch = new CountDownLatch(1);
    final CountDownLatch startedProcessingMultiAcksLatch = new CountDownLatch(1);
    final CountDownLatch waitForAll3AcksLatch = new CountDownLatch(3);
    final CountDownLatch allSentLatch = new CountDownLatch(1);
    final AtomicInteger acks = new AtomicInteger();
    template.setConfirmCallback(new ConfirmCallback() {

        @Override
        public void confirm(CorrelationData correlationData, boolean ack, String cause) {
            try {
                startedProcessingMultiAcksLatch.countDown();
                // delay processing here; ensures thread 2 put would be concurrent
                delayAckProcessingLatch.await(2, TimeUnit.SECONDS);
                // only delay first time through
                delayAckProcessingLatch.countDown();
                waitForAll3AcksLatch.countDown();
                acks.incrementAndGet();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });
    Executors.newSingleThreadExecutor().execute(new Runnable() {
        @Override
        public void run() {
            template.convertAndSend(ROUTE, (Object) "message", new CorrelationData("abc"));
            template.convertAndSend(ROUTE, (Object) "message", new CorrelationData("def"));
            first2SentOnThread1Latch.countDown();
        }
    });
    Executors.newSingleThreadExecutor().execute(new Runnable() {
        @Override
        public void run() {
            try {
                startedProcessingMultiAcksLatch.await();
                template.convertAndSend(ROUTE, (Object) "message", new CorrelationData("ghi"));
                allSentLatch.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });
    assertTrue(first2SentOnThread1Latch.await(10, TimeUnit.SECONDS));
    // there should be no concurrent execution exception here
    channel.handleAck(2, true);
    assertTrue(allSentLatch.await(10, TimeUnit.SECONDS));
    channel.handleAck(3, false);
    assertTrue(waitForAll3AcksLatch.await(10, TimeUnit.SECONDS));
    assertEquals(3, acks.get());

    // 3.3.1 client
    channel.basicConsume("foo", false, (Map) null, (Consumer) null);
    verify(mockChannel).basicConsume("foo", false, (Map) null, (Consumer) null);

    channel.basicQos(3, false);
    verify(mockChannel).basicQos(3, false);

    doReturn(true).when(mockChannel).flowBlocked();
    assertTrue(channel.flowBlocked());

    try {
        channel.flow(true);
        fail("Expected exception");
    } catch (UnsupportedOperationException e) {
    }

    try {
        channel.getFlow();
        fail("Expected exception");
    } catch (UnsupportedOperationException e) {
    }

    // 3.2.4 client
    /*
          try {
             channel.basicConsume("foo", false, (Map) null, (Consumer) null);
             fail("Expected exception");
          }
          catch (UnsupportedOperationException e) {}
            
          try {
             channel.basicQos(3, false);
             fail("Expected exception");
          }
          catch (UnsupportedOperationException e) {}
            
          try {
             channel.flowBlocked();
             fail("Expected exception");
          }
          catch (UnsupportedOperationException e) {}
            
          channel.flow(true);
          verify(mockChannel).flow(true);
            
          channel.getFlow();
          verify(mockChannel).getFlow();
    */
}

From source file:reactor.rabbitmq.RabbitFluxTests.java

License:Open Source License

@Test
public void publishConfirmsErrorWhilePublishing() throws Exception {
    ConnectionFactory mockConnectionFactory = mock(ConnectionFactory.class);
    Connection mockConnection = mock(Connection.class);
    Channel mockChannel = mock(Channel.class);
    when(mockConnectionFactory.newConnection()).thenReturn(mockConnection);
    when(mockConnection.createChannel()).thenReturn(mockChannel);
    when(mockConnection.isOpen()).thenReturn(true);
    when(mockChannel.getConnection()).thenReturn(mockConnection);

    AtomicLong publishSequence = new AtomicLong();
    when(mockChannel.getNextPublishSeqNo()).thenAnswer(invocation -> publishSequence.incrementAndGet());
    when(mockChannel.isOpen()).thenReturn(true);

    CountDownLatch channelCloseLatch = new CountDownLatch(1);
    doAnswer(answer -> {/*from w w  w . ja  v  a2  s.  co m*/
        channelCloseLatch.countDown();
        return null;
    }).when(mockChannel).close();

    CountDownLatch serverPublishConfirmLatch = new CountDownLatch(1);
    doNothing().doAnswer(answer -> {
        // see https://github.com/reactor/reactor-rabbitmq/pull/67#issuecomment-472789735
        serverPublishConfirmLatch.await(5, TimeUnit.SECONDS);
        throw new IOException("simulated error while publishing");
    }).when(mockChannel).basicPublish(anyString(), anyString(), nullable(AMQP.BasicProperties.class),
            any(byte[].class));

    int nbMessages = 10;
    Flux<OutboundMessage> msgFlux = Flux.range(0, nbMessages)
            .map(i -> new OutboundMessage("", queue, "".getBytes()));
    int nbMessagesAckNack = 1 + 1; // first published message confirmed + "fake" confirmation because of sending failure
    CountDownLatch confirmLatch = new CountDownLatch(nbMessagesAckNack);
    sender = createSender(new SenderOptions().connectionFactory(mockConnectionFactory));
    sender.sendWithPublishConfirms(msgFlux, new SendOptions().exceptionHandler((ctx, e) -> {
        throw new RabbitFluxException(e);
    })).subscribe(outboundMessageResult -> {
        if (outboundMessageResult.getOutboundMessage() != null) {
            confirmLatch.countDown();
        }
    }, error -> {
    });

    // have to wait a bit the subscription propagates and add the confirm listener
    Thread.sleep(100L);

    ArgumentCaptor<ConfirmListener> confirmListenerArgumentCaptor = ArgumentCaptor
            .forClass(ConfirmListener.class);
    verify(mockChannel).addConfirmListener(confirmListenerArgumentCaptor.capture());
    ConfirmListener confirmListener = confirmListenerArgumentCaptor.getValue();

    ExecutorService ioExecutor = Executors.newSingleThreadExecutor();
    ioExecutor.submit(() -> {
        confirmListener.handleAck(1, false);
        serverPublishConfirmLatch.countDown();
        return null;
    });

    assertTrue(confirmLatch.await(1L, TimeUnit.SECONDS));
    assertTrue(channelCloseLatch.await(1L, TimeUnit.SECONDS));
    verify(mockChannel, times(1)).close();
}

From source file:reactor.rabbitmq.ReactorRabbitMqTests.java

License:Open Source License

@Test
public void publishConfirmsErrorWhilePublishing() throws Exception {
    ConnectionFactory mockConnectionFactory = mock(ConnectionFactory.class);
    Connection mockConnection = mock(Connection.class);
    Channel mockChannel = mock(Channel.class);
    when(mockConnectionFactory.newConnection()).thenReturn(mockConnection);
    when(mockConnection.createChannel()).thenReturn(mockChannel);

    AtomicLong publishSequence = new AtomicLong();
    when(mockChannel.getNextPublishSeqNo()).thenAnswer(invocation -> publishSequence.incrementAndGet());

    doNothing().doThrow(new IOException("simulated error while publishing")).when(mockChannel)
            .basicPublish(anyString(), anyString(), any(AMQP.BasicProperties.class), any(byte[].class));

    int nbMessages = 10;
    Flux<OutboundMessage> msgFlux = Flux.range(0, nbMessages)
            .map(i -> new OutboundMessage("", queue, "".getBytes()));
    int nbMessagesAckNack = 2;
    CountDownLatch confirmLatch = new CountDownLatch(nbMessagesAckNack);
    sender = ReactorRabbitMq.createSender(mockConnectionFactory);
    CountDownLatch subscriptionLatch = new CountDownLatch(1);
    sender.sendWithPublishConfirms(msgFlux).subscribe(outboundMessageResult -> confirmLatch.countDown(),
            error -> {/*w  w  w.  j  a va2 s  .c om*/
            });

    // have to wait a bit the subscription propagates and add the confirm listener
    Thread.sleep(100L);

    ArgumentCaptor<ConfirmListener> confirmListenerArgumentCaptor = ArgumentCaptor
            .forClass(ConfirmListener.class);
    verify(mockChannel).addConfirmListener(confirmListenerArgumentCaptor.capture());
    ConfirmListener confirmListener = confirmListenerArgumentCaptor.getValue();

    ExecutorService ioExecutor = Executors.newSingleThreadExecutor();
    ioExecutor.submit(() -> {
        confirmListener.handleAck(1, false);
        return null;
    });

    assertTrue(confirmLatch.await(1L, TimeUnit.SECONDS));
    verify(mockChannel, times(1)).close();
}