@Override public void handleConfirm(PendingConfirm pendingConfirm, boolean ack) { if (this.confirmCallback != null) { this.confirmCallback.confirm(pendingConfirm.getCorrelationData(), ack, pendingConfirm.getCause()); // NOSONAR never null } }
@Override public synchronized Collection<PendingConfirm> expire(Listener listener, long cutoffTime) { SortedMap<Long, PendingConfirm> pendingConfirmsForListener = this.pendingConfirms.get(listener); if (pendingConfirmsForListener == null) { return Collections.<PendingConfirm>emptyList(); } else { List<PendingConfirm> expired = new ArrayList<PendingConfirm>(); Iterator<Entry<Long, PendingConfirm>> iterator = pendingConfirmsForListener.entrySet().iterator(); while (iterator.hasNext()) { PendingConfirm pendingConfirm = iterator.next().getValue(); if (pendingConfirm.getTimestamp() < cutoffTime) { expired.add(pendingConfirm); iterator.remove(); CorrelationData correlationData = pendingConfirm.getCorrelationData(); if (correlationData != null && StringUtils.hasText(correlationData.getId())) { this.pendingReturns.remove(correlationData.getId()); // NOSONAR never null } } else { break; } } return expired; } }
private synchronized void generateNacksForPendingAcks(String cause) { for (Entry<Listener, SortedMap<Long, PendingConfirm>> entry : this.pendingConfirms.entrySet()) { Listener listener = entry.getKey(); for (Entry<Long, PendingConfirm> confirmEntry : entry.getValue().entrySet()) { confirmEntry.getValue().setCause(cause); if (this.logger.isDebugEnabled()) { this.logger.debug(this.toString() + " PC:Nack:(close):" + confirmEntry.getKey()); } processAck(confirmEntry.getKey(), false, false, false); } listener.revoke(this); } if (this.logger.isDebugEnabled()) { this.logger.debug("PendingConfirms cleared"); } this.pendingConfirms.clear(); this.listenerForSeq.clear(); this.listeners.clear(); }
private void setupConfirm(Channel channel, Message message, @Nullable CorrelationData correlationDataArg) { if ((this.publisherConfirms || this.confirmCallback != null) && channel instanceof PublisherCallbackChannel) { PublisherCallbackChannel publisherCallbackChannel = (PublisherCallbackChannel) channel; CorrelationData correlationData = this.correlationDataPostProcessor != null ? this.correlationDataPostProcessor.postProcess(message, correlationDataArg) : correlationDataArg; long nextPublishSeqNo = channel.getNextPublishSeqNo(); message.getMessageProperties().setPublishSequenceNumber(nextPublishSeqNo); publisherCallbackChannel.addPendingConfirm(this, nextPublishSeqNo, new PendingConfirm(correlationData, System.currentTimeMillis())); if (correlationData != null && StringUtils.hasText(correlationData.getId())) { message.getMessageProperties().setHeader(PublisherCallbackChannel.RETURNED_MESSAGE_CORRELATION_KEY, correlationData.getId()); } } else if (channel instanceof ChannelProxy && ((ChannelProxy) channel).isConfirmSelected()) { long nextPublishSeqNo = channel.getNextPublishSeqNo(); message.getMessageProperties().setPublishSequenceNumber(nextPublishSeqNo); } }
@Override public synchronized void addPendingConfirm(Listener listener, long seq, PendingConfirm pendingConfirm) { SortedMap<Long, PendingConfirm> pendingConfirmsForListener = this.pendingConfirms.get(listener); Assert.notNull(pendingConfirmsForListener, "Listener not registered: " + listener + " " + this.pendingConfirms.keySet()); pendingConfirmsForListener.put(seq, pendingConfirm); this.listenerForSeq.put(seq, listener); if (pendingConfirm.getCorrelationData() != null) { String returnCorrelation = pendingConfirm.getCorrelationData().getId(); // NOSONAR never null if (StringUtils.hasText(returnCorrelation)) { this.pendingReturns.put(returnCorrelation, pendingConfirm); } } }
private void setupConfirm(Channel channel, Message message, @Nullable CorrelationData correlationDataArg) { if ((this.publisherConfirms || this.confirmCallback != null) && channel instanceof PublisherCallbackChannel) { PublisherCallbackChannel publisherCallbackChannel = (PublisherCallbackChannel) channel; CorrelationData correlationData = this.correlationDataPostProcessor != null ? this.correlationDataPostProcessor.postProcess(message, correlationDataArg) : correlationDataArg; long nextPublishSeqNo = channel.getNextPublishSeqNo(); message.getMessageProperties().setPublishSequenceNumber(nextPublishSeqNo); publisherCallbackChannel.addPendingConfirm(this, nextPublishSeqNo, new PendingConfirm(correlationData, System.currentTimeMillis())); if (correlationData != null && StringUtils.hasText(correlationData.getId())) { message.getMessageProperties().setHeader(PublisherCallbackChannel.RETURNED_MESSAGE_CORRELATION_KEY, correlationData.getId()); } } else if (channel instanceof ChannelProxy && ((ChannelProxy) channel).isConfirmSelected()) { long nextPublishSeqNo = channel.getNextPublishSeqNo(); message.getMessageProperties().setPublishSequenceNumber(nextPublishSeqNo); } }
@Override public synchronized void addPendingConfirm(Listener listener, long seq, PendingConfirm pendingConfirm) { SortedMap<Long, PendingConfirm> pendingConfirmsForListener = this.pendingConfirms.get(listener); Assert.notNull(pendingConfirmsForListener, "Listener not registered: " + listener + " " + this.pendingConfirms.keySet()); pendingConfirmsForListener.put(seq, pendingConfirm); this.listenerForSeq.put(seq, listener); if (pendingConfirm.getCorrelationData() != null) { String returnCorrelation = pendingConfirm.getCorrelationData().getId(); // NOSONAR never null if (StringUtils.hasText(returnCorrelation)) { this.pendingReturns.put(returnCorrelation, pendingConfirm); } } }
@Override public void handleConfirm(PendingConfirm pendingConfirm, boolean ack) { if (this.confirmCallback != null) { this.confirmCallback.confirm(pendingConfirm.getCorrelationData(), ack, pendingConfirm.getCause()); // NOSONAR never null } }
@Override public synchronized Collection<PendingConfirm> expire(Listener listener, long cutoffTime) { SortedMap<Long, PendingConfirm> pendingConfirmsForListener = this.pendingConfirms.get(listener); if (pendingConfirmsForListener == null) { return Collections.<PendingConfirm>emptyList(); } else { List<PendingConfirm> expired = new ArrayList<PendingConfirm>(); Iterator<Entry<Long, PendingConfirm>> iterator = pendingConfirmsForListener.entrySet().iterator(); while (iterator.hasNext()) { PendingConfirm pendingConfirm = iterator.next().getValue(); if (pendingConfirm.getTimestamp() < cutoffTime) { expired.add(pendingConfirm); iterator.remove(); CorrelationData correlationData = pendingConfirm.getCorrelationData(); if (correlationData != null && StringUtils.hasText(correlationData.getId())) { this.pendingReturns.remove(correlationData.getId()); // NOSONAR never null } } else { break; } } return expired; } }
@Test public void testPublisherCallbackChannelImplCloseWithPending() throws Exception { Listener listener = mock(Listener.class); final CountDownLatch latch = new CountDownLatch(2); doAnswer(invocation -> { boolean ack = invocation.getArgument(1); if (!ack) { latch.countDown(); } return null; }).when(listener).handleConfirm(any(PendingConfirm.class), anyBoolean()); when(listener.getUUID()).thenReturn(UUID.randomUUID().toString()); when(listener.isConfirmListener()).thenReturn(true); Channel channelMock = mock(Channel.class); PublisherCallbackChannelImpl channel = new PublisherCallbackChannelImpl(channelMock, this.executorService); channel.addListener(listener); for (int i = 0; i < 2; i++) { long seq = i + 1000; channel.addPendingConfirm(listener, seq, new PendingConfirm(new CorrelationData(Long.toHexString(seq)), System.currentTimeMillis())); } channel.close(); assertTrue(latch.await(10, TimeUnit.SECONDS)); int n = 0; while (n++ < 100 && TestUtils.getPropertyValue(channel, "pendingConfirms", Map.class).size() > 0) { Thread.sleep(100); } assertEquals(0, TestUtils.getPropertyValue(channel, "pendingConfirms", Map.class).size()); }
/** * Gets unconfirmed correlation data older than age and removes them. * @param age in milliseconds * @return the collection of correlation data for which confirms have * not been received or null if no such confirms exist. */ @Nullable public Collection<CorrelationData> getUnconfirmed(long age) { Set<CorrelationData> unconfirmed = new HashSet<>(); long cutoffTime = System.currentTimeMillis() - age; for (Channel channel : this.publisherConfirmChannels.keySet()) { Collection<PendingConfirm> confirms = ((PublisherCallbackChannel) channel).expire(this, cutoffTime); for (PendingConfirm confirm : confirms) { unconfirmed.add(confirm.getCorrelationData()); } } return unconfirmed.size() > 0 ? unconfirmed : null; }
private synchronized void generateNacksForPendingAcks(String cause) { for (Entry<Listener, SortedMap<Long, PendingConfirm>> entry : this.pendingConfirms.entrySet()) { Listener listener = entry.getKey(); for (Entry<Long, PendingConfirm> confirmEntry : entry.getValue().entrySet()) { confirmEntry.getValue().setCause(cause); if (this.logger.isDebugEnabled()) { this.logger.debug(this.toString() + " PC:Nack:(close):" + confirmEntry.getKey()); } processAck(confirmEntry.getKey(), false, false, false); } listener.revoke(this); } if (this.logger.isDebugEnabled()) { this.logger.debug("PendingConfirms cleared"); } this.pendingConfirms.clear(); this.listenerForSeq.clear(); this.listeners.clear(); }
Entry<Long, PendingConfirm> entry = iterator.next(); PendingConfirm value = entry.getValue(); CorrelationData correlationData = value.getCorrelationData(); if (correlationData != null) { correlationData.getFuture().set(new Confirm(ack, value.getCause())); if (StringUtils.hasText(correlationData.getId())) { this.pendingReturns.remove(correlationData.getId()); // NOSONAR never null
/** * Gets unconfirmed correlation data older than age and removes them. * @param age in milliseconds * @return the collection of correlation data for which confirms have * not been received or null if no such confirms exist. */ @Nullable public Collection<CorrelationData> getUnconfirmed(long age) { Set<CorrelationData> unconfirmed = new HashSet<>(); long cutoffTime = System.currentTimeMillis() - age; for (Channel channel : this.publisherConfirmChannels.keySet()) { Collection<PendingConfirm> confirms = ((PublisherCallbackChannel) channel).expire(this, cutoffTime); for (PendingConfirm confirm : confirms) { unconfirmed.add(confirm.getCorrelationData()); } } return unconfirmed.size() > 0 ? unconfirmed : null; }
Entry<Long, PendingConfirm> entry = iterator.next(); PendingConfirm value = entry.getValue(); CorrelationData correlationData = value.getCorrelationData(); if (correlationData != null) { correlationData.getFuture().set(new Confirm(ack, value.getCause())); if (StringUtils.hasText(correlationData.getId())) { this.pendingReturns.remove(correlationData.getId()); // NOSONAR never null
MessageProperties messageProperties = converter.toMessageProperties(properties, new Envelope(0L, false, exchange, routingKey), StandardCharsets.UTF_8.name()); if (confirm.getCorrelationData() != null) { confirm.getCorrelationData().setReturnedMessage(new Message(body, messageProperties)); // NOSONAR never null
CorrelationData correlationData = pendingConfirm.getCorrelationData(); if (correlationData != null) { correlationData.getFuture().set(new Confirm(ack, pendingConfirm.getCause())); if (StringUtils.hasText(correlationData.getId())) { this.pendingReturns.remove(correlationData.getId()); // NOSONAR never null
MessageProperties messageProperties = converter.toMessageProperties(properties, new Envelope(0L, false, exchange, routingKey), StandardCharsets.UTF_8.name()); if (confirm.getCorrelationData() != null) { confirm.getCorrelationData().setReturnedMessage(new Message(body, messageProperties)); // NOSONAR never null
CorrelationData correlationData = pendingConfirm.getCorrelationData(); if (correlationData != null) { correlationData.getFuture().set(new Confirm(ack, pendingConfirm.getCause())); if (StringUtils.hasText(correlationData.getId())) { this.pendingReturns.remove(correlationData.getId()); // NOSONAR never null