use of org.apache.pulsar.common.api.proto.CommandAck.AckType in project pulsar by apache.
the class MLPendingAckReplyCallBack method handleMetadataEntry.
@Override
public void handleMetadataEntry(PendingAckMetadataEntry pendingAckMetadataEntry) {
TxnID txnID = new TxnID(pendingAckMetadataEntry.getTxnidMostBits(), pendingAckMetadataEntry.getTxnidLeastBits());
AckType ackType = pendingAckMetadataEntry.getAckType();
switch(pendingAckMetadataEntry.getPendingAckOp()) {
case ABORT:
pendingAckHandle.handleAbort(txnID, ackType);
break;
case COMMIT:
pendingAckHandle.handleCommit(txnID, ackType, Collections.emptyMap());
break;
case ACK:
if (ackType == AckType.Cumulative) {
PendingAckMetadata pendingAckMetadata = pendingAckMetadataEntry.getPendingAckMetadatasList().get(0);
pendingAckHandle.handleCumulativeAckRecover(txnID, PositionImpl.get(pendingAckMetadata.getLedgerId(), pendingAckMetadata.getEntryId()));
} else {
List<MutablePair<PositionImpl, Integer>> positions = new ArrayList<>();
pendingAckMetadataEntry.getPendingAckMetadatasList().forEach(pendingAckMetadata -> {
if (pendingAckMetadata.getAckSetsCount() == 0) {
positions.add(new MutablePair<>(PositionImpl.get(pendingAckMetadata.getLedgerId(), pendingAckMetadata.getEntryId()), pendingAckMetadata.getBatchSize()));
} else {
PositionImpl position = PositionImpl.get(pendingAckMetadata.getLedgerId(), pendingAckMetadata.getEntryId());
if (pendingAckMetadata.getAckSetsCount() > 0) {
long[] ackSets = new long[pendingAckMetadata.getAckSetsCount()];
for (int i = 0; i < pendingAckMetadata.getAckSetsCount(); i++) {
ackSets[i] = pendingAckMetadata.getAckSetAt(i);
}
position.setAckSet(ackSets);
}
positions.add(new MutablePair<>(position, pendingAckMetadata.getBatchSize()));
}
});
pendingAckHandle.handleIndividualAckRecover(txnID, positions);
}
break;
default:
throw new IllegalStateException("Transaction pending ack replay " + "error with illegal state : " + pendingAckMetadataEntry.getPendingAckOp());
}
}
use of org.apache.pulsar.common.api.proto.CommandAck.AckType in project pulsar by apache.
the class ConsumerImpl method doReconsumeLater.
@SuppressWarnings("unchecked")
@Override
protected CompletableFuture<Void> doReconsumeLater(Message<?> message, AckType ackType, Map<String, String> customProperties, long delayTime, TimeUnit unit) {
MessageId messageId = message.getMessageId();
if (messageId == null) {
return FutureUtil.failedFuture(new PulsarClientException.InvalidMessageException("Cannot handle message with null messageId"));
}
if (messageId instanceof TopicMessageIdImpl) {
messageId = ((TopicMessageIdImpl) messageId).getInnerMessageId();
}
checkArgument(messageId instanceof MessageIdImpl);
if (getState() != State.Ready && getState() != State.Connecting) {
stats.incrementNumAcksFailed();
PulsarClientException exception = new PulsarClientException("Consumer not ready. State: " + getState());
if (AckType.Individual.equals(ackType)) {
onAcknowledge(messageId, exception);
} else if (AckType.Cumulative.equals(ackType)) {
onAcknowledgeCumulative(messageId, exception);
}
return FutureUtil.failedFuture(exception);
}
if (delayTime < 0) {
delayTime = 0;
}
if (retryLetterProducer == null) {
createProducerLock.writeLock().lock();
try {
if (retryLetterProducer == null) {
retryLetterProducer = client.newProducer(schema).topic(this.deadLetterPolicy.getRetryLetterTopic()).enableBatching(false).blockIfQueueFull(false).create();
}
} catch (Exception e) {
log.error("Create retry letter producer exception with topic: {}", deadLetterPolicy.getRetryLetterTopic(), e);
} finally {
createProducerLock.writeLock().unlock();
}
}
CompletableFuture<Void> result = new CompletableFuture<>();
if (retryLetterProducer != null) {
try {
MessageImpl<T> retryMessage = (MessageImpl<T>) getMessageImpl(message);
String originMessageIdStr = getOriginMessageIdStr(message);
String originTopicNameStr = getOriginTopicNameStr(message);
SortedMap<String, String> propertiesMap = getPropertiesMap(message, originMessageIdStr, originTopicNameStr);
if (customProperties != null) {
propertiesMap.putAll(customProperties);
}
int reconsumetimes = 1;
if (propertiesMap.containsKey(RetryMessageUtil.SYSTEM_PROPERTY_RECONSUMETIMES)) {
reconsumetimes = Integer.parseInt(propertiesMap.get(RetryMessageUtil.SYSTEM_PROPERTY_RECONSUMETIMES));
reconsumetimes = reconsumetimes + 1;
}
propertiesMap.put(RetryMessageUtil.SYSTEM_PROPERTY_RECONSUMETIMES, String.valueOf(reconsumetimes));
propertiesMap.put(RetryMessageUtil.SYSTEM_PROPERTY_DELAY_TIME, String.valueOf(unit.toMillis(delayTime)));
MessageId finalMessageId = messageId;
if (reconsumetimes > this.deadLetterPolicy.getMaxRedeliverCount() && StringUtils.isNotBlank(deadLetterPolicy.getDeadLetterTopic())) {
initDeadLetterProducerIfNeeded();
deadLetterProducer.thenAccept(dlqProducer -> {
TypedMessageBuilder<byte[]> typedMessageBuilderNew = dlqProducer.newMessage(Schema.AUTO_PRODUCE_BYTES(retryMessage.getReaderSchema().get())).value(retryMessage.getData()).properties(propertiesMap);
typedMessageBuilderNew.sendAsync().thenAccept(msgId -> {
doAcknowledge(finalMessageId, ackType, Collections.emptyMap(), null).thenAccept(v -> {
result.complete(null);
}).exceptionally(ex -> {
result.completeExceptionally(ex);
return null;
});
}).exceptionally(ex -> {
result.completeExceptionally(ex);
return null;
});
}).exceptionally(ex -> {
result.completeExceptionally(ex);
deadLetterProducer = null;
return null;
});
} else {
TypedMessageBuilder<T> typedMessageBuilderNew = retryLetterProducer.newMessage().value(retryMessage.getValue()).properties(propertiesMap);
if (delayTime > 0) {
typedMessageBuilderNew.deliverAfter(delayTime, unit);
}
if (message.hasKey()) {
typedMessageBuilderNew.key(message.getKey());
}
typedMessageBuilderNew.sendAsync().thenAccept(__ -> doAcknowledge(finalMessageId, ackType, Collections.emptyMap(), null).thenAccept(v -> result.complete(null))).exceptionally(ex -> {
result.completeExceptionally(ex);
return null;
});
}
} catch (Exception e) {
log.error("Send to retry letter topic exception with topic: {}, messageId: {}", retryLetterProducer.getTopic(), messageId, e);
Set<MessageId> messageIds = Collections.singleton(messageId);
unAckedMessageTracker.remove(messageId);
redeliverUnacknowledgedMessages(messageIds);
}
}
MessageId finalMessageId = messageId;
result.exceptionally(ex -> {
Set<MessageId> messageIds = Collections.singleton(finalMessageId);
unAckedMessageTracker.remove(finalMessageId);
redeliverUnacknowledgedMessages(messageIds);
return null;
});
return result;
}
use of org.apache.pulsar.common.api.proto.CommandAck.AckType in project pulsar by apache.
the class MultiTopicsConsumerImpl method doAcknowledge.
@Override
protected CompletableFuture<Void> doAcknowledge(List<MessageId> messageIdList, AckType ackType, Map<String, Long> properties, TransactionImpl txn) {
List<CompletableFuture<Void>> resultFutures = new ArrayList<>();
if (ackType == AckType.Cumulative) {
messageIdList.forEach(messageId -> resultFutures.add(doAcknowledge(messageId, ackType, properties, txn)));
return CompletableFuture.allOf(resultFutures.toArray(new CompletableFuture[0]));
} else {
if (getState() != State.Ready) {
return FutureUtil.failedFuture(new PulsarClientException("Consumer already closed"));
}
Map<String, List<MessageId>> topicToMessageIdMap = new HashMap<>();
for (MessageId messageId : messageIdList) {
if (!(messageId instanceof TopicMessageIdImpl)) {
return FutureUtil.failedFuture(new IllegalArgumentException("messageId is not instance of TopicMessageIdImpl"));
}
TopicMessageIdImpl topicMessageId = (TopicMessageIdImpl) messageId;
topicToMessageIdMap.putIfAbsent(topicMessageId.getTopicPartitionName(), new ArrayList<>());
topicToMessageIdMap.get(topicMessageId.getTopicPartitionName()).add(topicMessageId.getInnerMessageId());
}
topicToMessageIdMap.forEach((topicPartitionName, messageIds) -> {
ConsumerImpl<T> consumer = consumers.get(topicPartitionName);
resultFutures.add(consumer.doAcknowledgeWithTxn(messageIds, ackType, properties, txn).thenAccept((res) -> messageIdList.forEach(unAckedMessageTracker::remove)));
});
return CompletableFuture.allOf(resultFutures.toArray(new CompletableFuture[0]));
}
}
use of org.apache.pulsar.common.api.proto.CommandAck.AckType in project pulsar by apache.
the class PersistentSubscriptionTest method setup.
@BeforeMethod
public void setup() throws Exception {
executor = OrderedExecutor.newBuilder().numThreads(1).name("persistent-subscription-test").build();
eventLoopGroup = new NioEventLoopGroup();
ServiceConfiguration svcConfig = spy(ServiceConfiguration.class);
svcConfig.setBrokerShutdownTimeoutMs(0L);
svcConfig.setTransactionCoordinatorEnabled(true);
svcConfig.setClusterName("pulsar-cluster");
pulsarMock = spyWithClassAndConstructorArgs(PulsarService.class, svcConfig);
PulsarResources pulsarResources = mock(PulsarResources.class);
doReturn(pulsarResources).when(pulsarMock).getPulsarResources();
NamespaceResources namespaceResources = mock(NamespaceResources.class);
doReturn(namespaceResources).when(pulsarResources).getNamespaceResources();
doReturn(Optional.of(new Policies())).when(namespaceResources).getPoliciesIfCached(any());
doReturn(new InMemTransactionBufferProvider()).when(pulsarMock).getTransactionBufferProvider();
doReturn(new TransactionPendingAckStoreProvider() {
@Override
public CompletableFuture<PendingAckStore> newPendingAckStore(PersistentSubscription subscription) {
return CompletableFuture.completedFuture(new PendingAckStore() {
@Override
public void replayAsync(PendingAckHandleImpl pendingAckHandle, ScheduledExecutorService executorService) {
try {
Field field = PendingAckHandleState.class.getDeclaredField("state");
field.setAccessible(true);
field.set(pendingAckHandle, PendingAckHandleState.State.Ready);
} catch (NoSuchFieldException | IllegalAccessException e) {
fail();
}
}
@Override
public CompletableFuture<Void> closeAsync() {
return CompletableFuture.completedFuture(null);
}
@Override
public CompletableFuture<Void> appendIndividualAck(TxnID txnID, List<MutablePair<PositionImpl, Integer>> positions) {
return CompletableFuture.completedFuture(null);
}
@Override
public CompletableFuture<Void> appendCumulativeAck(TxnID txnID, PositionImpl position) {
return CompletableFuture.completedFuture(null);
}
@Override
public CompletableFuture<Void> appendCommitMark(TxnID txnID, AckType ackType) {
return CompletableFuture.completedFuture(null);
}
@Override
public CompletableFuture<Void> appendAbortMark(TxnID txnID, AckType ackType) {
return CompletableFuture.completedFuture(null);
}
});
}
@Override
public CompletableFuture<Boolean> checkInitializedBefore(PersistentSubscription subscription) {
return CompletableFuture.completedFuture(true);
}
}).when(pulsarMock).getTransactionPendingAckStoreProvider();
doReturn(svcConfig).when(pulsarMock).getConfiguration();
doReturn(mock(Compactor.class)).when(pulsarMock).getCompactor();
mlFactoryMock = mock(ManagedLedgerFactory.class);
doReturn(mlFactoryMock).when(pulsarMock).getManagedLedgerFactory();
ZooKeeper zkMock = createMockZooKeeper();
doReturn(createMockBookKeeper(executor)).when(pulsarMock).getBookKeeperClient();
store = new ZKMetadataStore(zkMock);
doReturn(store).when(pulsarMock).getLocalMetadataStore();
doReturn(store).when(pulsarMock).getConfigurationMetadataStore();
brokerMock = spyWithClassAndConstructorArgs(BrokerService.class, pulsarMock, eventLoopGroup);
doNothing().when(brokerMock).unloadNamespaceBundlesGracefully();
doReturn(brokerMock).when(pulsarMock).getBrokerService();
ledgerMock = mock(ManagedLedgerImpl.class);
cursorMock = mock(ManagedCursorImpl.class);
managedLedgerConfigMock = mock(ManagedLedgerConfig.class);
doReturn(new ManagedCursorContainer()).when(ledgerMock).getCursors();
doReturn("mockCursor").when(cursorMock).getName();
doReturn(new PositionImpl(1, 50)).when(cursorMock).getMarkDeletedPosition();
doReturn(ledgerMock).when(cursorMock).getManagedLedger();
doReturn(managedLedgerConfigMock).when(ledgerMock).getConfig();
doReturn(false).when(managedLedgerConfigMock).isAutoSkipNonRecoverableData();
topic = new PersistentTopic(successTopicName, ledgerMock, brokerMock);
consumerMock = mock(Consumer.class);
persistentSubscription = new PersistentSubscription(topic, subName, cursorMock, false);
}
Aggregations