Search in sources :

Example 76 with TopicPartition

use of org.apache.kafka.common.TopicPartition in project streamsx.kafka by IBMStreams.

the class KafkaConsumerClient method seekToTimestamp.

private void seekToTimestamp(Map<TopicPartition, Long> topicPartitionTimestampMap) {
    Map<TopicPartition, OffsetAndTimestamp> offsetsForTimes = consumer.offsetsForTimes(topicPartitionTimestampMap);
    logger.debug("offsetsForTimes=" + offsetsForTimes);
    topicPartitionTimestampMap.forEach((tp, timestamp) -> {
        OffsetAndTimestamp ot = offsetsForTimes.get(tp);
        if (ot != null) {
            logger.debug("Seeking consumer for tp=" + tp + " to offsetAndTimestamp=" + ot);
            consumer.seek(tp, ot.offset());
        } else {
        // nothing...consumer will move to the offset as determined by the 'auto.offset.reset' config
        }
    });
}
Also used : TopicPartition(org.apache.kafka.common.TopicPartition) OffsetAndTimestamp(org.apache.kafka.clients.consumer.OffsetAndTimestamp)

Example 77 with TopicPartition

use of org.apache.kafka.common.TopicPartition in project streamsx.kafka by IBMStreams.

the class TransactionalKafkaProducerClient method checkpoint.

@Override
public void checkpoint(Checkpoint checkpoint) throws Exception {
    final long currentSequenceId = checkpoint.getSequenceId();
    if (logger.isDebugEnabled())
        logger.debug("TransactionalKafkaProducerClient -- CHECKPOINT id=" + currentSequenceId);
    // when we checkpoint, we must have a transaction. open a transaction if not yet done ...
    checkAndBeginTransaction();
    if (logger.isDebugEnabled())
        logger.debug("currentSequenceId=" + currentSequenceId + ", lastSuccessSequenceId=" + lastSuccessfulSequenceId);
    boolean doCommit = true;
    // that's why the second condition is checked first.
    if (currentSequenceId > lastSuccessfulSequenceId + 1) {
        // must be read with 'isolation.level=read_committed'
        long committedSequenceId = getCommittedSequenceIdFromCtrlTopic();
        if (logger.isDebugEnabled())
            logger.debug("committedSequenceId=" + committedSequenceId);
        if (lastSuccessfulSequenceId < committedSequenceId) {
            if (logger.isDebugEnabled())
                logger.debug("Aborting transaction due to lastSuccessfulSequenceId < committedSequenceId");
            // If the last successful sequence ID is less than
            // the committed sequence ID, this transaction has
            // been processed before and is a duplicate.
            // Discard this transaction.
            abortTransaction();
            doCommit = false;
            lastSuccessfulSequenceId = committedSequenceId;
        }
    }
    if (logger.isDebugEnabled())
        logger.debug("doCommit = " + doCommit);
    if (doCommit) {
        RecordMetadata lastCommittedControlRecordMetadata = commitTransaction(currentSequenceId);
        lastSuccessfulSequenceId = currentSequenceId;
        TopicPartition tp = new TopicPartition(lastCommittedControlRecordMetadata.topic(), lastCommittedControlRecordMetadata.partition());
        controlTopicInitialOffsets.put(tp, lastCommittedControlRecordMetadata.offset());
    // The 'controlTopicInitialOffsets' need not be synced back to the JCP. The CV is for reset to initial state.
    // this.startOffsetsCV.setValue (serializeObject (controlTopicInitialOffsets));
    }
    transactionInProgress.set(false);
    // save the last successful seq ID
    if (logger.isDebugEnabled())
        logger.debug("Checkpointing lastSuccessfulSequenceId: " + lastSuccessfulSequenceId);
    checkpoint.getOutputStream().writeLong(lastSuccessfulSequenceId);
    // save the control topic offsets
    if (logger.isDebugEnabled())
        logger.debug("Checkpointing control topic offsets: " + controlTopicInitialOffsets);
    checkpoint.getOutputStream().writeObject(controlTopicInitialOffsets);
    if (!lazyTransactionBegin) {
        // start a new transaction
        checkAndBeginTransaction();
    }
}
Also used : RecordMetadata(org.apache.kafka.clients.producer.RecordMetadata) TopicPartition(org.apache.kafka.common.TopicPartition)

Example 78 with TopicPartition

use of org.apache.kafka.common.TopicPartition in project streamsx.kafka by IBMStreams.

the class AbstractKafkaConsumerOperator method process.

@Override
public void process(StreamingInput<Tuple> stream, Tuple tuple) throws Exception {
    boolean interrupted = false;
    try {
        String jsonString = tuple.getString(0);
        JsonObject jsonObj = gson.fromJson(jsonString, JsonObject.class);
        TopicPartitionUpdateAction action = null;
        if (jsonObj.has("action")) {
            // $NON-NLS-1$
            // $NON-NLS-1$
            action = TopicPartitionUpdateAction.valueOf(jsonObj.get("action").getAsString().toUpperCase());
        } else {
            // $NON-NLS-1$ //$NON-NLS-2$
            logger.error(Messages.getString("INVALID_JSON_MISSING_KEY", "action", jsonString));
            return;
        }
        Map<TopicPartition, Long> topicPartitionOffsetMap = null;
        if (jsonObj.has("topicPartitionOffsets")) {
            // $NON-NLS-1$
            topicPartitionOffsetMap = new HashMap<TopicPartition, Long>();
            // $NON-NLS-1$
            JsonArray arr = jsonObj.get("topicPartitionOffsets").getAsJsonArray();
            Iterator<JsonElement> it = arr.iterator();
            while (it.hasNext()) {
                JsonObject tpo = it.next().getAsJsonObject();
                if (!tpo.has("topic")) {
                    // $NON-NLS-1$
                    // $NON-NLS-1$ //$NON-NLS-2$
                    logger.error(Messages.getString("INVALID_JSON_MISSING_KEY", "topic", jsonString));
                    return;
                }
                if (!tpo.has("partition")) {
                    // $NON-NLS-1$
                    // $NON-NLS-1$ //$NON-NLS-2$
                    logger.error(Messages.getString("INVALID_JSON_MISSING_KEY", "partition", jsonString));
                    return;
                }
                if (action == TopicPartitionUpdateAction.ADD && !tpo.has("offset")) {
                    // $NON-NLS-1$
                    // $NON-NLS-1$ //$NON-NLS-2$
                    logger.error(Messages.getString("INVALID_JSON_MISSING_KEY", "offset", jsonString));
                    return;
                }
                // $NON-NLS-1$
                String topic = tpo.get("topic").getAsString();
                // $NON-NLS-1$
                int partition = tpo.get("partition").getAsInt();
                // $NON-NLS-1$ //$NON-NLS-2$
                long offset = tpo.has("offset") ? tpo.get("offset").getAsLong() : 0l;
                topicPartitionOffsetMap.put(new TopicPartition(topic, partition), offset);
            }
        }
        consumer.sendStopPollingEvent();
        consumer.sendUpdateTopicAssignmentEvent(new TopicPartitionUpdate(action, topicPartitionOffsetMap));
    } catch (InterruptedException e) {
        // interrupted during shutdown
        interrupted = true;
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
    } finally {
        if (!interrupted)
            consumer.sendStartPollingEvent(consumerPollTimeout);
    }
}
Also used : JsonObject(com.google.gson.JsonObject) RString(com.ibm.streams.operator.types.RString) Checkpoint(com.ibm.streams.operator.state.Checkpoint) JsonArray(com.google.gson.JsonArray) TopicPartitionUpdate(com.ibm.streamsx.kafka.clients.consumer.TopicPartitionUpdate) TopicPartitionUpdateAction(com.ibm.streamsx.kafka.clients.consumer.TopicPartitionUpdateAction) TopicPartition(org.apache.kafka.common.TopicPartition) JsonElement(com.google.gson.JsonElement)

Example 79 with TopicPartition

use of org.apache.kafka.common.TopicPartition in project apex-malhar by apache.

the class KafkaSinglePortExactlyOnceOutputOperator method rebuildPartialWindow.

private void rebuildPartialWindow() {
    logger.info("Rebuild the partial window after " + windowDataManager.getLargestCompletedWindow());
    Map<Integer, Long> storedOffsets;
    Map<Integer, Long> currentOffsets;
    try {
        storedOffsets = (Map<Integer, Long>) this.windowDataManager.retrieve(windowId);
        currentOffsets = getPartitionsAndOffsets(true);
    } catch (IOException | ExecutionException | InterruptedException e) {
        throw new RuntimeException(e);
    }
    if (currentOffsets == null) {
        logger.info("No tuples found while building partial window " + windowDataManager.getLargestCompletedWindow());
        return;
    }
    if (storedOffsets == null) {
        logger.info("Stored offset not available, seeking to the beginning of the Kafka Partition.");
        try {
            storedOffsets = getPartitionsAndOffsets(false);
        } catch (ExecutionException | InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
    List<TopicPartition> topicPartitions = new ArrayList<>();
    for (Map.Entry<Integer, Long> entry : currentOffsets.entrySet()) {
        topicPartitions.add(new TopicPartition(getTopic(), entry.getKey()));
    }
    consumer.assign(topicPartitions);
    for (Map.Entry<Integer, Long> entry : currentOffsets.entrySet()) {
        Long storedOffset = 0L;
        Integer currentPartition = entry.getKey();
        Long currentOffset = entry.getValue();
        if (storedOffsets.containsKey(currentPartition)) {
            storedOffset = storedOffsets.get(currentPartition);
        }
        if (storedOffset >= currentOffset) {
            continue;
        }
        try {
            consumer.seek(new TopicPartition(getTopic(), currentPartition), storedOffset);
        } catch (Exception ex) {
            logger.info("Rebuilding of the partial window is not complete, exactly once recovery is not possible.");
            throw new RuntimeException(ex);
        }
        int kafkaAttempt = 0;
        while (true) {
            ConsumerRecords<String, T> consumerRecords = consumer.poll(100);
            if (consumerRecords.count() == 0) {
                if (kafkaAttempt++ == KAFKA_CONNECT_ATTEMPT) {
                    break;
                }
            } else {
                kafkaAttempt = 0;
            }
            boolean crossedBoundary = false;
            for (ConsumerRecord<String, T> consumerRecord : consumerRecords) {
                if (consumerRecord.offset() >= currentOffset) {
                    crossedBoundary = true;
                    break;
                }
                if (!doesKeyBelongsToThisInstance(operatorId, consumerRecord.key())) {
                    continue;
                }
                T value = consumerRecord.value();
                if (partialWindowTuples.containsKey(value)) {
                    Integer count = partialWindowTuples.get(value);
                    partialWindowTuples.put(value, count + 1);
                } else {
                    partialWindowTuples.put(value, 1);
                }
            }
            if (crossedBoundary) {
                break;
            }
        }
    }
}
Also used : ArrayList(java.util.ArrayList) IOException(java.io.IOException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) TopicPartition(org.apache.kafka.common.TopicPartition) ExecutionException(java.util.concurrent.ExecutionException) HashMap(java.util.HashMap) Map(java.util.Map)

Example 80 with TopicPartition

use of org.apache.kafka.common.TopicPartition in project apex-malhar by apache.

the class KafkaSinglePortExactlyOnceOutputOperator method getPartitionsAndOffsets.

private Map<Integer, Long> getPartitionsAndOffsets(boolean latest) throws ExecutionException, InterruptedException {
    List<PartitionInfo> partitionInfoList = consumer.partitionsFor(getTopic());
    List<TopicPartition> topicPartitionList = new java.util.ArrayList<>();
    for (PartitionInfo partitionInfo : partitionInfoList) {
        topicPartitionList.add(new TopicPartition(getTopic(), partitionInfo.partition()));
    }
    Map<Integer, Long> parttionsAndOffset = new HashMap<>();
    consumer.assign(topicPartitionList);
    for (PartitionInfo partitionInfo : partitionInfoList) {
        try {
            TopicPartition topicPartition = new TopicPartition(getTopic(), partitionInfo.partition());
            if (latest) {
                consumer.seekToEnd(topicPartition);
            } else {
                consumer.seekToBeginning(topicPartition);
            }
            parttionsAndOffset.put(partitionInfo.partition(), consumer.position(topicPartition));
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
    return parttionsAndOffset;
}
Also used : HashMap(java.util.HashMap) TopicPartition(org.apache.kafka.common.TopicPartition) ArrayList(java.util.ArrayList) PartitionInfo(org.apache.kafka.common.PartitionInfo) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException)

Aggregations

TopicPartition (org.apache.kafka.common.TopicPartition)1729 HashMap (java.util.HashMap)744 Test (org.junit.Test)519 ArrayList (java.util.ArrayList)416 Map (java.util.Map)361 Test (org.junit.jupiter.api.Test)347 HashSet (java.util.HashSet)281 List (java.util.List)260 OffsetAndMetadata (org.apache.kafka.clients.consumer.OffsetAndMetadata)246 Set (java.util.Set)189 LinkedHashMap (java.util.LinkedHashMap)180 PartitionInfo (org.apache.kafka.common.PartitionInfo)170 ConsumerRecord (org.apache.kafka.clients.consumer.ConsumerRecord)155 TaskId (org.apache.kafka.streams.processor.TaskId)145 Node (org.apache.kafka.common.Node)140 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)109 KafkaException (org.apache.kafka.common.KafkaException)105 Errors (org.apache.kafka.common.protocol.Errors)105 ByteBuffer (java.nio.ByteBuffer)99 Properties (java.util.Properties)93