List of usage examples for com.rabbitmq.client Channel getNextPublishSeqNo
long getNextPublishSeqNo();
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(); }