org.apache.pulsar.client.api.Reader Java Examples

The following examples show how to use org.apache.pulsar.client.api.Reader. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ReaderTest.java    From pulsar with Apache License 2.0 6 votes vote down vote up
@Test
public void testReadFromPartition() throws Exception {
    String topic = "persistent://my-property/my-ns/testReadFromPartition";
    String partition0 = topic + "-partition-0";
    admin.topics().createPartitionedTopic(topic, 4);
    int numKeys = 10;

    Set<String> keys = publishMessages(partition0, numKeys, false);
    Reader<byte[]> reader = pulsarClient.newReader()
            .topic(partition0)
            .startMessageId(MessageId.earliest)
            .create();

    while (reader.hasMessageAvailable()) {
        Message<byte[]> message = reader.readNext();
        Assert.assertTrue(keys.remove(message.getKey()));
    }
    Assert.assertTrue(keys.isEmpty());
}
 
Example #2
Source File: GroupMetadataManager.java    From kop with Apache License 2.0 6 votes vote down vote up
private CompletableFuture<Void> doLoadGroupsAndOffsets(
    CompletableFuture<Reader<ByteBuffer>> metadataConsumer,
    MessageId endMessageId,
    Consumer<GroupMetadata> onGroupLoaded
) {
    final Map<GroupTopicPartition, CommitRecordMetadataAndOffset> loadedOffsets = new HashMap<>();
    final Map<Long, Map<GroupTopicPartition, CommitRecordMetadataAndOffset>> pendingOffsets = new HashMap<>();
    final Map<String, GroupMetadata> loadedGroups = new HashMap<>();
    final Set<String> removedGroups = new HashSet<>();
    final CompletableFuture<Void> resultFuture = new CompletableFuture<>();

    loadNextMetadataMessage(
        metadataConsumer,
        endMessageId,
        resultFuture,
        onGroupLoaded,
        loadedOffsets,
        pendingOffsets,
        loadedGroups,
        removedGroups);

    return resultFuture;
}
 
Example #3
Source File: GroupMetadataManager.java    From kop with Apache License 2.0 6 votes vote down vote up
private void loadNextMetadataMessage(CompletableFuture<Reader<ByteBuffer>> metadataConsumer,
                                     MessageId endMessageId,
                                     CompletableFuture<Void> resultFuture,
                                     Consumer<GroupMetadata> onGroupLoaded,
                                     Map<GroupTopicPartition, CommitRecordMetadataAndOffset> loadedOffsets,
                                     Map<Long, Map<GroupTopicPartition, CommitRecordMetadataAndOffset>>
                                         pendingOffsets,
                                     Map<String, GroupMetadata> loadedGroups,
                                     Set<String> removedGroups) {
    try {
        unsafeLoadNextMetadataMessage(
            metadataConsumer,
            endMessageId,
            resultFuture,
            onGroupLoaded,
            loadedOffsets,
            pendingOffsets,
            loadedGroups,
            removedGroups
        );
    } catch (Throwable cause) {
        log.error("Unknown exception caught when loading group and offsets from topic",
            cause);
        resultFuture.completeExceptionally(cause);
    }
}
 
Example #4
Source File: ReaderTest.java    From pulsar with Apache License 2.0 6 votes vote down vote up
private void testReadMessages(String topic, boolean enableBatch) throws Exception {
    int numKeys = 10;

    Set<String> keys = publishMessages(topic, numKeys, enableBatch);
    Reader<byte[]> reader = pulsarClient.newReader()
            .topic(topic)
            .startMessageId(MessageId.earliest)
            .readerName(subscription)
            .create();

    while (reader.hasMessageAvailable()) {
        Message<byte[]> message = reader.readNext();
        Assert.assertTrue(keys.remove(message.getKey()));
    }
    Assert.assertTrue(keys.isEmpty());

    Reader<byte[]> readLatest = pulsarClient.newReader().topic(topic).startMessageId(MessageId.latest)
                                            .readerName(subscription + "latest").create();
    Assert.assertFalse(readLatest.hasMessageAvailable());
}
 
Example #5
Source File: ReaderBuilderImpl.java    From pulsar with Apache License 2.0 6 votes vote down vote up
@Override
public CompletableFuture<Reader<T>> createAsync() {
    if (conf.getTopicName() == null) {
        return FutureUtil
                .failedFuture(new IllegalArgumentException("Topic name must be set on the reader builder"));
    }

    if (conf.getStartMessageId() != null && conf.getStartMessageFromRollbackDurationInSec() > 0 ||
            conf.getStartMessageId() == null && conf.getStartMessageFromRollbackDurationInSec() <= 0) {
        return FutureUtil
                .failedFuture(new IllegalArgumentException(
                        "Start message id or start message from roll back must be specified but they cannot be specified at the same time"));
    }

    if (conf.getStartMessageFromRollbackDurationInSec() > 0) {
        conf.setStartMessageId(MessageId.earliest);
    }

    return client.createReaderAsync(conf, schema);
}
 
Example #6
Source File: ReaderTest.java    From pulsar with Apache License 2.0 6 votes vote down vote up
@Test
public void testReadMessageWithBatchingWithMessageInclusive() throws Exception {
    String topic = "persistent://my-property/my-ns/my-reader-topic-with-batching-inclusive";
    Set<String> keys = publishMessages(topic, 10, true);

    Reader<byte[]> reader = pulsarClient.newReader().topic(topic).startMessageId(MessageId.latest)
                                        .startMessageIdInclusive().readerName(subscription).create();

    while (reader.hasMessageAvailable()) {
        Assert.assertTrue(keys.remove(reader.readNext().getKey()));
    }
    // start from latest with start message inclusive should only read the last message in batch
    Assert.assertTrue(keys.size() == 9);
    Assert.assertFalse(keys.contains("key9"));
    Assert.assertFalse(reader.hasMessageAvailable());
}
 
Example #7
Source File: SharedPulsarClient.java    From pulsar with Apache License 2.0 6 votes vote down vote up
public Reader<byte[]> getSharedReader(ReaderConfigurationData<byte[]> readerConf) throws PulsarClientException {
    counter.incrementAndGet();
    synchronized (this) {
        if (reader == null) {
            try {
                reader = client.createReaderAsync(readerConf).join();
            } catch (CompletionException e) {
                throw (PulsarClientException) e.getCause();
            }
            LOG.info("[{}] Created a new Pulsar reader on {}", componentId, readerConf.getTopicName());
        } else {
            LOG.info("[{}] Using a shared reader on {}", componentId, readerConf.getTopicName());
        }
    }
    return reader;
}
 
Example #8
Source File: BrokersBase.java    From pulsar with Apache License 2.0 6 votes vote down vote up
private void healthcheckReadLoop(CompletableFuture<Reader<String>> readerFuture,
                                 CompletableFuture<?> completablePromise,
                                 String messageStr) {
    readerFuture.thenAccept((reader) -> {
            CompletableFuture<Message<String>> readFuture = reader.readNextAsync()
                .whenComplete((m, exception) -> {
                        if (exception != null) {
                            completablePromise.completeExceptionally(exception);
                        } else if (m.getValue().equals(messageStr)) {
                            completablePromise.complete(null);
                        } else {
                            healthcheckReadLoop(readerFuture, completablePromise, messageStr);
                        }
                    });
        });
}
 
Example #9
Source File: FunctionMetaDataTopicTailerTest.java    From pulsar with Apache License 2.0 5 votes vote down vote up
public FunctionMetaDataTopicTailerTest() throws Exception {
    this.reader = mock(Reader.class);
    this.readerBuilder = mock(ReaderBuilder.class);
    when(readerBuilder.topic(anyString())).thenReturn(readerBuilder);
    when(readerBuilder.startMessageId(any(MessageId.class))).thenReturn(readerBuilder);
    when(readerBuilder.readerName(anyString())).thenReturn(readerBuilder);
    when(readerBuilder.subscriptionRolePrefix(anyString())).thenReturn(readerBuilder);
    when(readerBuilder.create()).thenReturn(reader);
    this.fsm = mock(FunctionMetaDataManager.class);
    this.fsc = new FunctionMetaDataTopicTailer(fsm, readerBuilder, new WorkerConfig(), MessageId.earliest, ErrorNotifier.getDefaultImpl() );
}
 
Example #10
Source File: IncrementPartitionsTest.java    From pulsar with Apache License 2.0 5 votes vote down vote up
@Test
public void testIncrementPartitionsWithReaders() throws Exception {
    TopicName partitionedTopicName = TopicName.get("persistent://prop-xyz/use/ns1/test-topic-" + System.nanoTime());

    admin.topics().createPartitionedTopic(partitionedTopicName.toString(), 1);
    assertEquals(admin.topics().getPartitionedTopicMetadata(partitionedTopicName.toString()).partitions, 1);

    @Cleanup
    Producer<String> consumer = pulsarClient.newProducer(Schema.STRING)
            .topic(partitionedTopicName.toString())
            .create();

    @Cleanup
    Reader<String> reader = pulsarClient.newReader(Schema.STRING)
        .topic(partitionedTopicName.getPartition(0).toString())
        .startMessageId(MessageId.earliest)
        .create();

    admin.topics().updatePartitionedTopic(partitionedTopicName.toString(), 2);
    assertEquals(admin.topics().getPartitionedTopicMetadata(partitionedTopicName.toString()).partitions, 2);

    assertEquals(admin.topics().getSubscriptions(partitionedTopicName.getPartition(0).toString()).size(), 1);

    // Partition-1 should not have subscriptions
    assertEquals(admin.topics().getSubscriptions(partitionedTopicName.getPartition(1).toString()),
            Collections.emptyList());
}
 
Example #11
Source File: TopicTerminationTest.java    From pulsar with Apache License 2.0 5 votes vote down vote up
@Test(timeOut = 20000)
public void testSimpleTerminationReader() throws Exception {
    Producer<byte[]> producer = pulsarClient.newProducer().topic(topicName)
        .enableBatching(false)
        .messageRoutingMode(MessageRoutingMode.SinglePartition)
        .create();

    MessageId msgId1 = producer.send("test-msg-1".getBytes());
    MessageId msgId2 = producer.send("test-msg-2".getBytes());
    MessageId msgId3 = producer.send("test-msg-3".getBytes());

    MessageId lastMessageId = admin.topics().terminateTopicAsync(topicName).get();
    assertEquals(lastMessageId, msgId3);

    Reader<byte[]> reader = pulsarClient.newReader().topic(topicName).startMessageId(MessageId.earliest).create();

    Message<byte[]> msg1 = reader.readNext();
    assertEquals(msg1.getMessageId(), msgId1);

    Message<byte[]> msg2 = reader.readNext();
    assertEquals(msg2.getMessageId(), msgId2);

    Message<byte[]> msg3 = reader.readNext();
    assertEquals(msg3.getMessageId(), msgId3);

    Message<byte[]> msg4 = reader.readNext(100, TimeUnit.MILLISECONDS);
    assertNull(msg4);

    Thread.sleep(100);
    assertTrue(reader.hasReachedEndOfTopic());
}
 
Example #12
Source File: FunctionAssignmentTailer.java    From pulsar with Apache License 2.0 5 votes vote down vote up
private Reader<byte[]> createReader(MessageId startMessageId) throws PulsarClientException {
    log.info("Assignment tailer will start reading from message id {}", startMessageId);

    return WorkerUtils.createReader(
            readerBuilder,
            workerConfig.getWorkerId() + "-function-assignment-tailer",
            workerConfig.getFunctionAssignmentTopic(),
            startMessageId);
}
 
Example #13
Source File: FunctionRuntimeManager.java    From pulsar with Apache License 2.0 5 votes vote down vote up
/**
 * Initializes the FunctionRuntimeManager.  Does the following:
 * 1. Consume all existing assignments to establish existing/latest set of assignments
 * 2. After current assignments are read, assignments belonging to this worker will be processed
 *
 * @return the message id of the message processed during init phase
 */
public MessageId initialize() {
    try {
        Reader<byte[]> reader = WorkerUtils.createReader(
                workerService.getClient().newReader(),
                workerConfig.getWorkerId() + "-function-assignment-initialize",
                workerConfig.getFunctionAssignmentTopic(),
                MessageId.earliest);

        // start init phase
        this.isInitializePhase = true;
        // keep track of the last message read
        MessageId lastMessageRead = MessageId.earliest;
        // read all existing messages
        while (reader.hasMessageAvailable()) {
            Message<byte[]> message = reader.readNext();
            lastMessageRead = message.getMessageId();
            processAssignmentMessage(message);
        }
        // init phase is done
        this.isInitializePhase = false;
        // close reader
        reader.close();
        // realize existing assignments
        Map<String, Assignment> assignmentMap = workerIdToAssignments.get(this.workerConfig.getWorkerId());
        if (assignmentMap != null) {
            for (Assignment assignment : assignmentMap.values()) {
                if (needsStart(assignment)) {
                    startFunctionInstance(assignment);
                }
            }
        }
        // complete future to indicate initialization is complete
        isInitialized.complete(null);
        return lastMessageRead;
    } catch (Exception e) {
        log.error("Failed to initialize function runtime manager: {}", e.getMessage(), e);
        throw new RuntimeException(e);
    }
}
 
Example #14
Source File: WorkerUtils.java    From pulsar with Apache License 2.0 5 votes vote down vote up
public static Reader<byte[]> createReader(ReaderBuilder readerBuilder,
                                          String readerName,
                                          String topic,
                                          MessageId startMessageId) throws PulsarClientException {
    return readerBuilder
            .subscriptionRolePrefix(readerName)
            .readerName(readerName)
            .topic(topic)
            .readCompacted(true)
            .startMessageId(startMessageId)
            .create();
}
 
Example #15
Source File: FunctionMetaDataTopicTailer.java    From pulsar with Apache License 2.0 5 votes vote down vote up
public static Reader createReader(WorkerConfig workerConfig, ReaderBuilder readerBuilder,
                                  MessageId startMessageId) throws PulsarClientException {
    return readerBuilder
            .topic(workerConfig.getFunctionMetadataTopic())
            .startMessageId(startMessageId)
            .readerName(workerConfig.getWorkerId() + "-function-metadata-tailer")
            .subscriptionRolePrefix(workerConfig.getWorkerId() + "-function-metadata-tailer")
            .create();
}
 
Example #16
Source File: PulsarClientV1Impl.java    From pulsar with Apache License 2.0 5 votes vote down vote up
@Override
public CompletableFuture<Reader> createReaderAsync(String topic, MessageId startMessageId,
        ReaderConfiguration conf) {
    ReaderConfigurationData<byte[]> confData = conf.getReaderConfigurationData().clone();
    confData.setTopicName(topic);
    confData.setStartMessageId(startMessageId);
    return client.createReaderAsync(confData).thenApply(r -> new ReaderV1Impl(r));
}
 
Example #17
Source File: ReaderBuilderImpl.java    From pulsar with Apache License 2.0 5 votes vote down vote up
@Override
public Reader<T> create() throws PulsarClientException {
    try {
        return createAsync().get();
    } catch (Exception e) {
        throw PulsarClientException.unwrap(e);
    }
}
 
Example #18
Source File: BuildersTest.java    From pulsar with Apache License 2.0 5 votes vote down vote up
@Test(expectedExceptions = {PulsarClientException.class}, expectedExceptionsMessageRegExp = ".* must be specified but they cannot be specified at the same time.*")
public void shouldNotSetTwoOptAtTheSameTime() throws Exception {
    PulsarClient client = PulsarClient.builder().serviceUrl("pulsar://localhost:6650").build();
    try (Reader reader = client.newReader().topic("abc").startMessageId(MessageId.earliest).startMessageFromRollbackDuration(10, TimeUnit.HOURS).create()) {
        // no-op
    } finally {
        client.close();
    }
}
 
Example #19
Source File: BuildersTest.java    From pulsar with Apache License 2.0 5 votes vote down vote up
@Test(expectedExceptions = {PulsarClientException.class}, expectedExceptionsMessageRegExp = ".* must be specified but they cannot be specified at the same time.*")
public void shouldSetOneStartOpt() throws Exception {
    PulsarClient client = PulsarClient.builder().serviceUrl("pulsar://localhost:6650").build();
    try (Reader reader = client.newReader().topic("abc").create()) {
        // no-op
    } finally {
        client.close();
    }
}
 
Example #20
Source File: ReaderTest.java    From pulsar with Apache License 2.0 5 votes vote down vote up
@Test
public void testReadMessageWithoutBatchingWithMessageInclusive() throws Exception {
    String topic = "persistent://my-property/my-ns/my-reader-topic-inclusive";
    Set<String> keys = publishMessages(topic, 10, false);

    Reader<byte[]> reader = pulsarClient.newReader().topic(topic).startMessageId(MessageId.latest)
                                        .startMessageIdInclusive().readerName(subscription).create();

    Assert.assertTrue(reader.hasMessageAvailable());
    Assert.assertTrue(keys.remove(reader.readNext().getKey()));
    Assert.assertFalse(reader.hasMessageAvailable());
}
 
Example #21
Source File: SchemaDeleteTest.java    From pulsar with Apache License 2.0 5 votes vote down vote up
@Test
public void createTopicDeleteTopicCreateTopic() throws Exception {
    String namespace = "my-property/my-ns";
    String topic = namespace + "/topic1";
    String foobar = "foo";

    try (Producer<String> producer =
            pulsarClient.newProducer(Schema.STRING).topic(topic).create()) {
        producer.send(foobar);
    }

    admin.topics().delete(topic);
    admin.schemas().deleteSchema(topic);

    // creating a subscriber will check the schema against the latest
    // schema, which in this case should be a tombstone, which should
    // behave as if the schema never existed
    try (Reader<String> reader = pulsarClient.newReader(Schema.STRING)
            .topic(topic).startMessageId(MessageId.latest).create()) {
    }

    admin.namespaces().setSchemaAutoUpdateCompatibilityStrategy(namespace,
            SchemaAutoUpdateCompatibilityStrategy.BackwardTransitive);
    admin.topics().delete(topic);
    admin.schemas().deleteSchema(topic);

    // with a transitive policy we should check all previous schemas. But we
    // shouldn't check against those that were there before we deleted the schema.
    try (Reader<DummyPojo> reader = pulsarClient.newReader(Schema.AVRO(DummyPojo.class))
            .topic(topic).startMessageId(MessageId.latest).create()) {
    }
}
 
Example #22
Source File: ReaderTest.java    From pulsar with Apache License 2.0 5 votes vote down vote up
/**
 * We need to ensure that delete subscription of read also need to delete the
 * non-durable cursor, because data deletion depends on the mark delete position of all cursors.
 */
@Test
public void testRemoveSubscriptionForReaderNeedRemoveCursor() throws IOException, PulsarAdminException {

    final String topic = "persistent://my-property/my-ns/testRemoveSubscriptionForReaderNeedRemoveCursor";

    @Cleanup
    Reader<byte[]> reader1 = pulsarClient.newReader()
        .topic(topic)
        .startMessageId(MessageId.earliest)
        .create();

    @Cleanup
    Reader<byte[]> reader2 = pulsarClient.newReader()
        .topic(topic)
        .startMessageId(MessageId.earliest)
        .create();

    Assert.assertEquals(admin.topics().getStats(topic).subscriptions.size(), 2);
    Assert.assertEquals(admin.topics().getInternalStats(topic).cursors.size(), 2);

    reader1.close();

    Assert.assertEquals(admin.topics().getStats(topic).subscriptions.size(), 1);
    Assert.assertEquals(admin.topics().getInternalStats(topic).cursors.size(), 1);

    reader2.close();

    Assert.assertEquals(admin.topics().getStats(topic).subscriptions.size(), 0);
    Assert.assertEquals(admin.topics().getInternalStats(topic).cursors.size(), 0);

}
 
Example #23
Source File: PulsarDatabaseHistory.java    From pulsar with Apache License 2.0 5 votes vote down vote up
@Override
public boolean exists() {
    setupClientIfNeeded();
    try (Reader<String> historyReader = pulsarClient.newReader(Schema.STRING)
        .topic(topicName)
        .startMessageId(MessageId.earliest)
        .create()
    ) {
        return historyReader.hasMessageAvailable();
    } catch (IOException e) {
        log.error("Encountered issues on checking existence of database history", e);
        throw new RuntimeException("Encountered issues on checking existence of database history", e);
    }
}
 
Example #24
Source File: GroupMetadataManager.java    From kop with Apache License 2.0 5 votes vote down vote up
CompletableFuture<Reader<ByteBuffer>> getOffsetsTopicReader(int partitionId) {
    return offsetsReaders.computeIfAbsent(partitionId,
        id -> {
            if (log.isDebugEnabled()) {
                log.debug("Will create Partitioned reader: {}",
                    offsetConfig.offsetsTopicName() + PARTITIONED_TOPIC_SUFFIX + id);
            }
            return metadataTopicReaderBuilder.clone()
                .topic(offsetConfig.offsetsTopicName() + PARTITIONED_TOPIC_SUFFIX + partitionId)
                .createAsync();
        });
}
 
Example #25
Source File: PulsarKafkaSimpleConsumer.java    From pulsar with Apache License 2.0 5 votes vote down vote up
@Override
public PulsarFetchResponse fetch(FetchRequest request) {
    try {
        Map<String, Reader<byte[]>> topicReaderMap = createTopicReaders(request);
        return new PulsarFetchResponse(topicReaderMap, false);
    } catch (Exception e) {
        log.warn("Failed to process fetch request{}, {}", request, e.getMessage());
        return new PulsarFetchResponse(null, true);
    }
}
 
Example #26
Source File: PulsarKafkaSimpleConsumer.java    From pulsar with Apache License 2.0 5 votes vote down vote up
private Map<String, Reader<byte[]>> createTopicReaders(FetchRequest request) {
    Map<String, Reader<byte[]>> topicReaderMap = Maps.newHashMap();
    scala.collection.immutable.Map<String, scala.collection.immutable.Map<TopicAndPartition, PartitionFetchInfo>> reqInfo = request
            .requestInfoGroupedByTopic();
    Map<String, scala.collection.immutable.Map<TopicAndPartition, PartitionFetchInfo>> topicPartitionMap = scala.collection.JavaConverters
            .mapAsJavaMapConverter(reqInfo).asJava();
    for (Entry<String, scala.collection.immutable.Map<TopicAndPartition, PartitionFetchInfo>> topicPartition : topicPartitionMap
            .entrySet()) {
        final String topicName = topicPartition.getKey();
        Map<TopicAndPartition, PartitionFetchInfo> topicOffsetMap = scala.collection.JavaConverters
                .mapAsJavaMapConverter(topicPartition.getValue()).asJava();
        if (topicOffsetMap != null && !topicOffsetMap.isEmpty()) {
            // pulsar-kafka adapter doesn't deal with partition so, assuming only 1 topic-metadata per topic name
            Entry<TopicAndPartition, PartitionFetchInfo> topicOffset = topicOffsetMap.entrySet().iterator().next();
            long offset = topicOffset.getValue().offset();
            String topic = getTopicName(topicOffset.getKey());
            MessageId msgId = getMessageId(offset);
            try {
                Reader<byte[]> reader = client.newReader().readerName(clientId).topic(topic).startMessageId(msgId)
                        .create();
                log.info("Successfully created reader for {} at msg-id {}", topic, msgId);
                topicReaderMap.put(topicName, reader);
            } catch (PulsarClientException e) {
                log.warn("Failed to create reader for topic {}", topic, e);
                throw new RuntimeException("Failed to create reader for " + topic, e);
            }
        }
    }
    return topicReaderMap;
}
 
Example #27
Source File: GroupMetadataManager.java    From kop with Apache License 2.0 4 votes vote down vote up
public ConcurrentMap<Integer, CompletableFuture<Reader<ByteBuffer>>> getOffsetsReaders() {
    return offsetsReaders;
}
 
Example #28
Source File: GroupMetadataManager.java    From kop with Apache License 2.0 4 votes vote down vote up
/**
 * When this broker becomes a follower for an offsets topic partition clear out the cache for groups that belong to
 * that partition.
 *
 * @param offsetsPartition Groups belonging to this partition of the offsets topic will be deleted from the cache.
 */
public void removeGroupsForPartition(int offsetsPartition,
                                     Consumer<GroupMetadata> onGroupUnloaded) {
    TopicPartition topicPartition = new TopicPartition(
        GROUP_METADATA_TOPIC_NAME, offsetsPartition
    );
    log.info("Scheduling unloading of offsets and group metadata from {}", topicPartition);
    scheduler.submit(() -> {
        AtomicInteger numOffsetsRemoved = new AtomicInteger();
        AtomicInteger numGroupsRemoved = new AtomicInteger();
        inLock(partitionLock, () -> {
            // we need to guard the group removal in cache in the loading partition lock
            // to prevent coordinator's check-and-get-group race condition
            ownedPartitions.remove(offsetsPartition);

            for (GroupMetadata group : groupMetadataCache.values()) {
                if (partitionFor(group.groupId()) == offsetsPartition) {
                    onGroupUnloaded.accept(group);
                    groupMetadataCache.remove(group.groupId(), group);
                    removeGroupFromAllProducers(group.groupId());
                    numGroupsRemoved.incrementAndGet();
                    numOffsetsRemoved.addAndGet(group.numOffsets());
                }
            }

            // remove related producers and readers
            CompletableFuture<Producer<ByteBuffer>> producer = offsetsProducers.remove(offsetsPartition);
            CompletableFuture<Reader<ByteBuffer>> reader = offsetsReaders.remove(offsetsPartition);
            if (producer != null) {
                producer.thenApplyAsync(p -> p.closeAsync()).whenCompleteAsync((ignore, t) -> {
                    if (t != null) {
                        log.error("Failed to close producer when remove partition {}.",
                            producer.join().getTopic());
                    }
                }, scheduler);
            }
            if (reader != null) {
                reader.thenApplyAsync(p -> p.closeAsync()).whenCompleteAsync((ignore, t) -> {
                    if (t != null) {
                        log.error("Failed to close reader when remove partition {}.",
                            reader.join().getTopic());
                    }
                }, scheduler);
            }

            return null;
        });

        log.info("Finished unloading {}. Removed {} cached offsets and {} cached groups.",
            topicPartition, numOffsetsRemoved, numGroupsRemoved);
    });
}
 
Example #29
Source File: PulsarClientImpl.java    From pulsar with Apache License 2.0 4 votes vote down vote up
<T> CompletableFuture<Reader<T>> doCreateReaderAsync(ReaderConfigurationData<T> conf, Schema<T> schema) {
    if (state.get() != State.Open) {
        return FutureUtil.failedFuture(new PulsarClientException.AlreadyClosedException("Client already closed"));
    }

    if (conf == null) {
        return FutureUtil.failedFuture(
                new PulsarClientException.InvalidConfigurationException("Consumer configuration undefined"));
    }

    String topic = conf.getTopicName();

    if (!TopicName.isValid(topic)) {
        return FutureUtil.failedFuture(new PulsarClientException.InvalidTopicNameException("Invalid topic name"));
    }

    if (conf.getStartMessageId() == null) {
        return FutureUtil
                .failedFuture(new PulsarClientException.InvalidConfigurationException("Invalid startMessageId"));
    }

    CompletableFuture<Reader<T>> readerFuture = new CompletableFuture<>();

    getPartitionedTopicMetadata(topic).thenAccept(metadata -> {
        if (log.isDebugEnabled()) {
            log.debug("[{}] Received topic metadata. partitions: {}", topic, metadata.partitions);
        }

        if (metadata.partitions > 0) {
            readerFuture.completeExceptionally(
                    new PulsarClientException("Topic reader cannot be created on a partitioned topic"));
            return;
        }

        CompletableFuture<Consumer<T>> consumerSubscribedFuture = new CompletableFuture<>();
        // gets the next single threaded executor from the list of executors
        ExecutorService listenerThread = externalExecutorProvider.getExecutor();
        ReaderImpl<T> reader = new ReaderImpl<>(PulsarClientImpl.this, conf, listenerThread, consumerSubscribedFuture, schema);

        synchronized (consumers) {
            consumers.put(reader.getConsumer(), Boolean.TRUE);
        }

        consumerSubscribedFuture.thenRun(() -> {
            readerFuture.complete(reader);
        }).exceptionally(ex -> {
            log.warn("[{}] Failed to get create topic reader", topic, ex);
            readerFuture.completeExceptionally(ex);
            return null;
        });
    }).exceptionally(ex -> {
        log.warn("[{}] Failed to get partitioned topic metadata", topic, ex);
        readerFuture.completeExceptionally(ex);
        return null;
    });

    return readerFuture;
}
 
Example #30
Source File: PulsarClientImpl.java    From pulsar with Apache License 2.0 4 votes vote down vote up
public <T> CompletableFuture<Reader<T>> createReaderAsync(ReaderConfigurationData<T> conf, Schema<T> schema) {
    return preProcessSchemaBeforeSubscribe(this, schema, conf.getTopicName())
        .thenCompose(schemaClone -> doCreateReaderAsync(conf, schemaClone));
}