Search in sources :

Example 1 with TransactionCoordinatorClient

use of org.apache.pulsar.client.api.transaction.TransactionCoordinatorClient in project flink by apache.

the class PulsarCommitter method commit.

@Override
public void commit(Collection<CommitRequest<PulsarCommittable>> requests) throws IOException, InterruptedException {
    TransactionCoordinatorClient client = transactionCoordinatorClient();
    for (CommitRequest<PulsarCommittable> request : requests) {
        PulsarCommittable committable = request.getCommittable();
        TxnID txnID = committable.getTxnID();
        String topic = committable.getTopic();
        LOG.debug("Start committing the Pulsar transaction {} for topic {}", txnID, topic);
        try {
            client.commit(txnID);
        } catch (TransactionCoordinatorClientException e) {
            // This is a known bug for Pulsar Transaction.
            // We have to use instanceof instead of catching them.
            TransactionCoordinatorClientException ex = PulsarTransactionUtils.unwrap(e);
            if (ex instanceof CoordinatorNotFoundException) {
                LOG.error("We couldn't find the Transaction Coordinator from Pulsar broker {}. " + "Check your broker configuration.", committable, ex);
                request.signalFailedWithKnownReason(ex);
            } else if (ex instanceof InvalidTxnStatusException) {
                LOG.error("Unable to commit transaction ({}) because it's in an invalid state. " + "Most likely the transaction has been aborted for some reason. " + "Please check the Pulsar broker logs for more details.", committable, ex);
                request.signalAlreadyCommitted();
            } else if (ex instanceof TransactionNotFoundException) {
                if (request.getNumberOfRetries() == 0) {
                    LOG.error("Unable to commit transaction ({}) because it's not found on Pulsar broker. " + "Most likely the checkpoint interval exceed the transaction timeout.", committable, ex);
                    request.signalFailedWithKnownReason(ex);
                } else {
                    LOG.warn("We can't find the transaction {} after {} retry committing. " + "This may mean that the transaction have been committed in previous but failed with timeout. " + "So we just mark it as committed.", txnID, request.getNumberOfRetries());
                    request.signalAlreadyCommitted();
                }
            } else if (ex instanceof MetaStoreHandlerNotExistsException) {
                LOG.error("We can't find the meta store handler by the mostSigBits from TxnID {}. " + "Did you change the metadata for topic {}?", committable, TRANSACTION_COORDINATOR_ASSIGN, ex);
                request.signalFailedWithKnownReason(ex);
            } else {
                LOG.error("Encountered retriable exception while committing transaction {} for topic {}.", committable, topic, ex);
                int maxRecommitTimes = sinkConfiguration.getMaxRecommitTimes();
                if (request.getNumberOfRetries() < maxRecommitTimes) {
                    request.retryLater();
                } else {
                    String message = String.format("Failed to commit transaction %s after retrying %d times", txnID, maxRecommitTimes);
                    request.signalFailedWithKnownReason(new FlinkRuntimeException(message, ex));
                }
            }
        } catch (Exception e) {
            LOG.error("Transaction ({}) encountered unknown error and data could be potentially lost.", committable, e);
            request.signalFailedWithUnknownReason(e);
        }
    }
}
Also used : InvalidTxnStatusException(org.apache.pulsar.client.api.transaction.TransactionCoordinatorClientException.InvalidTxnStatusException) TransactionNotFoundException(org.apache.pulsar.client.api.transaction.TransactionCoordinatorClientException.TransactionNotFoundException) FlinkRuntimeException(org.apache.flink.util.FlinkRuntimeException) MetaStoreHandlerNotExistsException(org.apache.pulsar.client.api.transaction.TransactionCoordinatorClientException.MetaStoreHandlerNotExistsException) TransactionCoordinatorClientException(org.apache.pulsar.client.api.transaction.TransactionCoordinatorClientException) IOException(java.io.IOException) InvalidTxnStatusException(org.apache.pulsar.client.api.transaction.TransactionCoordinatorClientException.InvalidTxnStatusException) CoordinatorNotFoundException(org.apache.pulsar.client.api.transaction.TransactionCoordinatorClientException.CoordinatorNotFoundException) TransactionNotFoundException(org.apache.pulsar.client.api.transaction.TransactionCoordinatorClientException.TransactionNotFoundException) TxnID(org.apache.pulsar.client.api.transaction.TxnID) FlinkRuntimeException(org.apache.flink.util.FlinkRuntimeException) MetaStoreHandlerNotExistsException(org.apache.pulsar.client.api.transaction.TransactionCoordinatorClientException.MetaStoreHandlerNotExistsException) TransactionCoordinatorClientException(org.apache.pulsar.client.api.transaction.TransactionCoordinatorClientException) TransactionCoordinatorClient(org.apache.pulsar.client.api.transaction.TransactionCoordinatorClient) CoordinatorNotFoundException(org.apache.pulsar.client.api.transaction.TransactionCoordinatorClientException.CoordinatorNotFoundException)

Example 2 with TransactionCoordinatorClient

use of org.apache.pulsar.client.api.transaction.TransactionCoordinatorClient in project flink by apache.

the class TopicProducerRegister method abortTransactions.

/**
 * Abort the existed transactions. This method would be used when closing PulsarWriter.
 */
private void abortTransactions() {
    if (transactionRegister.isEmpty()) {
        return;
    }
    TransactionCoordinatorClient coordinatorClient = ((PulsarClientImpl) pulsarClient).getTcClient();
    // This null check is used for making sure transaction is enabled in client.
    checkNotNull(coordinatorClient);
    try (Closer closer = Closer.create()) {
        for (Transaction transaction : transactionRegister.values()) {
            TxnID txnID = transaction.getTxnID();
            closer.register(() -> coordinatorClient.abort(txnID));
        }
        clearTransactions();
    } catch (IOException e) {
        throw new FlinkRuntimeException(e);
    }
}
Also used : Closer(org.apache.flink.shaded.guava30.com.google.common.io.Closer) TxnID(org.apache.pulsar.client.api.transaction.TxnID) PulsarTransactionUtils.createTransaction(org.apache.flink.connector.pulsar.common.utils.PulsarTransactionUtils.createTransaction) Transaction(org.apache.pulsar.client.api.transaction.Transaction) FlinkRuntimeException(org.apache.flink.util.FlinkRuntimeException) PulsarClientImpl(org.apache.pulsar.client.impl.PulsarClientImpl) IOException(java.io.IOException) TransactionCoordinatorClient(org.apache.pulsar.client.api.transaction.TransactionCoordinatorClient)

Example 3 with TransactionCoordinatorClient

use of org.apache.pulsar.client.api.transaction.TransactionCoordinatorClient in project flink by apache.

the class PulsarWriterTest method writeMessageWithoutGuarantee.

@ParameterizedTest
@EnumSource(value = DeliveryGuarantee.class, names = { "AT_LEAST_ONCE", "NONE" })
void writeMessageWithoutGuarantee(DeliveryGuarantee guarantee) throws Exception {
    String topic = randomAlphabetic(10);
    operator().createTopic(topic, 8);
    SinkConfiguration configuration = sinkConfiguration(guarantee);
    PulsarSerializationSchema<String> schema = pulsarSchema(STRING);
    TopicMetadataListener listener = new TopicMetadataListener(singletonList(topic));
    RoundRobinTopicRouter<String> router = new RoundRobinTopicRouter<>(configuration);
    FixedMessageDelayer<String> delayer = MessageDelayer.never();
    MockInitContext initContext = new MockInitContext();
    PulsarWriter<String> writer = new PulsarWriter<>(configuration, schema, listener, router, delayer, initContext);
    writer.flush(false);
    writer.prepareCommit();
    writer.flush(false);
    writer.prepareCommit();
    String message = randomAlphabetic(10);
    writer.write(message, CONTEXT);
    writer.flush(false);
    Collection<PulsarCommittable> committables = writer.prepareCommit();
    if (guarantee != EXACTLY_ONCE) {
        assertThat(committables).isEmpty();
    } else {
        assertThat(committables).hasSize(1);
        PulsarCommittable committable = committables.stream().findFirst().orElseThrow(IllegalArgumentException::new);
        TransactionCoordinatorClient coordinatorClient = operator().coordinatorClient();
        coordinatorClient.commit(committable.getTxnID());
    }
    String consumedMessage = operator().receiveMessage(topic, STRING).getValue();
    assertEquals(consumedMessage, message);
}
Also used : PulsarCommittable(org.apache.flink.connector.pulsar.sink.committer.PulsarCommittable) TopicMetadataListener(org.apache.flink.connector.pulsar.sink.writer.topic.TopicMetadataListener) SinkConfiguration(org.apache.flink.connector.pulsar.sink.config.SinkConfiguration) RoundRobinTopicRouter(org.apache.flink.connector.pulsar.sink.writer.router.RoundRobinTopicRouter) TransactionCoordinatorClient(org.apache.pulsar.client.api.transaction.TransactionCoordinatorClient) EnumSource(org.junit.jupiter.params.provider.EnumSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 4 with TransactionCoordinatorClient

use of org.apache.pulsar.client.api.transaction.TransactionCoordinatorClient in project flink by apache.

the class TopicProducerRegisterTest method createMessageBuilderForSendingMessage.

@ParameterizedTest
@EnumSource(DeliveryGuarantee.class)
void createMessageBuilderForSendingMessage(DeliveryGuarantee deliveryGuarantee) throws IOException {
    String topic = randomAlphabetic(10);
    operator().createTopic(topic, 8);
    SinkConfiguration configuration = sinkConfiguration(deliveryGuarantee);
    TopicProducerRegister register = new TopicProducerRegister(configuration);
    String message = randomAlphabetic(10);
    register.createMessageBuilder(topic, Schema.STRING).value(message).send();
    if (deliveryGuarantee == EXACTLY_ONCE) {
        List<PulsarCommittable> committables = register.prepareCommit();
        for (PulsarCommittable committable : committables) {
            TxnID txnID = committable.getTxnID();
            TransactionCoordinatorClient coordinatorClient = operator().coordinatorClient();
            coordinatorClient.commit(txnID);
        }
    }
    Message<String> receiveMessage = operator().receiveMessage(topic, Schema.STRING);
    assertEquals(receiveMessage.getValue(), message);
}
Also used : PulsarCommittable(org.apache.flink.connector.pulsar.sink.committer.PulsarCommittable) TxnID(org.apache.pulsar.client.api.transaction.TxnID) SinkConfiguration(org.apache.flink.connector.pulsar.sink.config.SinkConfiguration) TransactionCoordinatorClient(org.apache.pulsar.client.api.transaction.TransactionCoordinatorClient) EnumSource(org.junit.jupiter.params.provider.EnumSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 5 with TransactionCoordinatorClient

use of org.apache.pulsar.client.api.transaction.TransactionCoordinatorClient in project flink by apache.

the class PulsarSourceReaderFactory method create.

@SuppressWarnings("java:S2095")
public static <OUT> SourceReader<OUT, PulsarPartitionSplit> create(SourceReaderContext readerContext, PulsarDeserializationSchema<OUT> deserializationSchema, SourceConfiguration sourceConfiguration) {
    PulsarClient pulsarClient = createClient(sourceConfiguration);
    PulsarAdmin pulsarAdmin = createAdmin(sourceConfiguration);
    // Create a message queue with the predefined source option.
    int queueCapacity = sourceConfiguration.getMessageQueueCapacity();
    FutureCompletingBlockingQueue<RecordsWithSplitIds<PulsarMessage<OUT>>> elementsQueue = new FutureCompletingBlockingQueue<>(queueCapacity);
    // Create different pulsar source reader by subscription type.
    SubscriptionType subscriptionType = sourceConfiguration.getSubscriptionType();
    if (subscriptionType == SubscriptionType.Failover || subscriptionType == SubscriptionType.Exclusive) {
        // Create a ordered split reader supplier.
        Supplier<PulsarOrderedPartitionSplitReader<OUT>> splitReaderSupplier = () -> new PulsarOrderedPartitionSplitReader<>(pulsarClient, pulsarAdmin, sourceConfiguration, deserializationSchema);
        return new PulsarOrderedSourceReader<>(elementsQueue, splitReaderSupplier, readerContext, sourceConfiguration, pulsarClient, pulsarAdmin);
    } else if (subscriptionType == SubscriptionType.Shared || subscriptionType == SubscriptionType.Key_Shared) {
        TransactionCoordinatorClient coordinatorClient = ((PulsarClientImpl) pulsarClient).getTcClient();
        if (coordinatorClient == null && !sourceConfiguration.isEnableAutoAcknowledgeMessage()) {
            throw new IllegalStateException("Transaction is required but didn't enabled");
        }
        Supplier<PulsarUnorderedPartitionSplitReader<OUT>> splitReaderSupplier = () -> new PulsarUnorderedPartitionSplitReader<>(pulsarClient, pulsarAdmin, sourceConfiguration, deserializationSchema, coordinatorClient);
        return new PulsarUnorderedSourceReader<>(elementsQueue, splitReaderSupplier, readerContext, sourceConfiguration, pulsarClient, pulsarAdmin, coordinatorClient);
    } else {
        throw new UnsupportedOperationException("This subscription type is not " + subscriptionType + " supported currently.");
    }
}
Also used : PulsarAdmin(org.apache.pulsar.client.admin.PulsarAdmin) PulsarOrderedSourceReader(org.apache.flink.connector.pulsar.source.reader.source.PulsarOrderedSourceReader) PulsarOrderedPartitionSplitReader(org.apache.flink.connector.pulsar.source.reader.split.PulsarOrderedPartitionSplitReader) RecordsWithSplitIds(org.apache.flink.connector.base.source.reader.RecordsWithSplitIds) SubscriptionType(org.apache.pulsar.client.api.SubscriptionType) FutureCompletingBlockingQueue(org.apache.flink.connector.base.source.reader.synchronization.FutureCompletingBlockingQueue) Supplier(java.util.function.Supplier) PulsarClient(org.apache.pulsar.client.api.PulsarClient) TransactionCoordinatorClient(org.apache.pulsar.client.api.transaction.TransactionCoordinatorClient)

Aggregations

TransactionCoordinatorClient (org.apache.pulsar.client.api.transaction.TransactionCoordinatorClient)5 TxnID (org.apache.pulsar.client.api.transaction.TxnID)3 IOException (java.io.IOException)2 PulsarCommittable (org.apache.flink.connector.pulsar.sink.committer.PulsarCommittable)2 SinkConfiguration (org.apache.flink.connector.pulsar.sink.config.SinkConfiguration)2 FlinkRuntimeException (org.apache.flink.util.FlinkRuntimeException)2 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)2 EnumSource (org.junit.jupiter.params.provider.EnumSource)2 Supplier (java.util.function.Supplier)1 RecordsWithSplitIds (org.apache.flink.connector.base.source.reader.RecordsWithSplitIds)1 FutureCompletingBlockingQueue (org.apache.flink.connector.base.source.reader.synchronization.FutureCompletingBlockingQueue)1 PulsarTransactionUtils.createTransaction (org.apache.flink.connector.pulsar.common.utils.PulsarTransactionUtils.createTransaction)1 RoundRobinTopicRouter (org.apache.flink.connector.pulsar.sink.writer.router.RoundRobinTopicRouter)1 TopicMetadataListener (org.apache.flink.connector.pulsar.sink.writer.topic.TopicMetadataListener)1 PulsarOrderedSourceReader (org.apache.flink.connector.pulsar.source.reader.source.PulsarOrderedSourceReader)1 PulsarOrderedPartitionSplitReader (org.apache.flink.connector.pulsar.source.reader.split.PulsarOrderedPartitionSplitReader)1 Closer (org.apache.flink.shaded.guava30.com.google.common.io.Closer)1 PulsarAdmin (org.apache.pulsar.client.admin.PulsarAdmin)1 PulsarClient (org.apache.pulsar.client.api.PulsarClient)1 SubscriptionType (org.apache.pulsar.client.api.SubscriptionType)1