Search in sources :

Example 1 with CommandSubscribe

use of com.yahoo.pulsar.common.api.proto.PulsarApi.CommandSubscribe in project pulsar by yahoo.

the class ServerCnx method handleSubscribe.

@Override
protected void handleSubscribe(final CommandSubscribe subscribe) {
    checkArgument(state == State.Connected);
    CompletableFuture<Boolean> authorizationFuture;
    if (service.isAuthorizationEnabled()) {
        authorizationFuture = service.getAuthorizationManager().canConsumeAsync(DestinationName.get(subscribe.getTopic()), authRole);
    } else {
        authorizationFuture = CompletableFuture.completedFuture(true);
    }
    final String topicName = subscribe.getTopic();
    final String subscriptionName = subscribe.getSubscription();
    final long requestId = subscribe.getRequestId();
    final long consumerId = subscribe.getConsumerId();
    final SubType subType = subscribe.getSubType();
    final String consumerName = subscribe.getConsumerName();
    final int priorityLevel = subscribe.hasPriorityLevel() ? subscribe.getPriorityLevel() : 0;
    authorizationFuture.thenApply(isAuthorized -> {
        if (isAuthorized) {
            if (log.isDebugEnabled()) {
                log.debug("[{}] Client is authorized to subscribe with role {}", remoteAddress, authRole);
            }
            log.info("[{}] Subscribing on topic {} / {}", remoteAddress, topicName, subscriptionName);
            CompletableFuture<Consumer> consumerFuture = new CompletableFuture<>();
            CompletableFuture<Consumer> existingConsumerFuture = consumers.putIfAbsent(consumerId, consumerFuture);
            if (existingConsumerFuture != null) {
                if (existingConsumerFuture.isDone() && !existingConsumerFuture.isCompletedExceptionally()) {
                    Consumer consumer = existingConsumerFuture.getNow(null);
                    log.info("[{}] Consumer with the same id is already created: {}", remoteAddress, consumer);
                    ctx.writeAndFlush(Commands.newSuccess(requestId));
                    return null;
                } else {
                    log.warn("[{}][{}][{}] Consumer is already present on the connection", remoteAddress, topicName, subscriptionName);
                    ServerError error = !existingConsumerFuture.isDone() ? ServerError.ServiceNotReady : getErrorCode(existingConsumerFuture);
                    ;
                    ctx.writeAndFlush(Commands.newError(requestId, error, "Consumer is already present on the connection"));
                    return null;
                }
            }
            service.getTopic(topicName).thenCompose(topic -> topic.subscribe(ServerCnx.this, subscriptionName, consumerId, subType, priorityLevel, consumerName)).thenAccept(consumer -> {
                if (consumerFuture.complete(consumer)) {
                    log.info("[{}] Created subscription on topic {} / {}", remoteAddress, topicName, subscriptionName);
                    ctx.writeAndFlush(Commands.newSuccess(requestId), ctx.voidPromise());
                } else {
                    try {
                        consumer.close();
                        log.info("[{}] Cleared consumer created after timeout on client side {}", remoteAddress, consumer);
                    } catch (BrokerServiceException e) {
                        log.warn("[{}] Error closing consumer created after timeout on client side {}: {}", remoteAddress, consumer, e.getMessage());
                    }
                    consumers.remove(consumerId, consumerFuture);
                }
            }).exceptionally(exception -> {
                log.warn("[{}][{}][{}] Failed to create consumer: {}", remoteAddress, topicName, subscriptionName, exception.getCause().getMessage());
                if (consumerFuture.completeExceptionally(exception)) {
                    ctx.writeAndFlush(Commands.newError(requestId, BrokerServiceException.getClientErrorCode(exception.getCause()), exception.getCause().getMessage()));
                }
                consumers.remove(consumerId, consumerFuture);
                return null;
            });
        } else {
            String msg = "Client is not authorized to subscribe";
            log.warn("[{}] {} with role {}", remoteAddress, msg, authRole);
            ctx.writeAndFlush(Commands.newError(requestId, ServerError.AuthorizationError, msg));
        }
        return null;
    });
}
Also used : SubType(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandSubscribe.SubType) CommandProducer(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandProducer) ServerError(com.yahoo.pulsar.common.api.proto.PulsarApi.ServerError) ProtocolVersion.v5(com.yahoo.pulsar.common.api.proto.PulsarApi.ProtocolVersion.v5) SocketAddress(java.net.SocketAddress) ChannelOption(io.netty.channel.ChannelOption) ConsumerStats(com.yahoo.pulsar.common.policies.data.ConsumerStats) LoggerFactory(org.slf4j.LoggerFactory) CompletableFuture(java.util.concurrent.CompletableFuture) CommandConsumerStats(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandConsumerStats) AuthenticationException(javax.naming.AuthenticationException) CommandUnsubscribe(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandUnsubscribe) BacklogQuota(com.yahoo.pulsar.common.policies.data.BacklogQuota) PersistentTopics.getPartitionedTopicMetadata(com.yahoo.pulsar.broker.admin.PersistentTopics.getPartitionedTopicMetadata) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) SSLSession(javax.net.ssl.SSLSession) CommandCloseProducer(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandCloseProducer) ByteBuf(io.netty.buffer.ByteBuf) Commands(com.yahoo.pulsar.common.api.Commands) DestinationName(com.yahoo.pulsar.common.naming.DestinationName) AuthenticationDataCommand(com.yahoo.pulsar.broker.authentication.AuthenticationDataCommand) CommandRedeliverUnacknowledgedMessages(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandRedeliverUnacknowledgedMessages) Logger(org.slf4j.Logger) PersistentSubscription(com.yahoo.pulsar.broker.service.persistent.PersistentSubscription) CommandSend(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandSend) Commands.newLookupResponse(com.yahoo.pulsar.common.api.Commands.newLookupResponse) PulsarHandler(com.yahoo.pulsar.common.api.PulsarHandler) DestinationLookup.lookupDestinationAsync(com.yahoo.pulsar.broker.lookup.DestinationLookup.lookupDestinationAsync) ServiceUnitNotReadyException(com.yahoo.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) TimeUnit(java.util.concurrent.TimeUnit) CommandAck(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandAck) ProtocolVersion(com.yahoo.pulsar.common.api.proto.PulsarApi.ProtocolVersion) CommandPartitionedTopicMetadata(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandPartitionedTopicMetadata) MessageMetadata(com.yahoo.pulsar.common.api.proto.PulsarApi.MessageMetadata) SslHandler(io.netty.handler.ssl.SslHandler) CommandFlow(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandFlow) ConcurrentLongHashMap(com.yahoo.pulsar.common.util.collections.ConcurrentLongHashMap) PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) PulsarClientException(com.yahoo.pulsar.client.api.PulsarClientException) CommandConnect(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandConnect) CommandLookupTopic(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandLookupTopic) CommandSubscribe(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandSubscribe) ChannelHandler(io.netty.channel.ChannelHandler) CommandCloseConsumer(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandCloseConsumer) CommandConsumerStatsResponse(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandConsumerStatsResponse) CompletableFuture(java.util.concurrent.CompletableFuture) SubType(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandSubscribe.SubType) CommandCloseConsumer(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandCloseConsumer) ServerError(com.yahoo.pulsar.common.api.proto.PulsarApi.ServerError)

Example 2 with CommandSubscribe

use of com.yahoo.pulsar.common.api.proto.PulsarApi.CommandSubscribe in project pulsar by yahoo.

the class Commands method newSubscribe.

public static ByteBuf newSubscribe(String topic, String subscription, long consumerId, long requestId, SubType subType, int priorityLevel, String consumerName) {
    CommandSubscribe.Builder subscribeBuilder = CommandSubscribe.newBuilder();
    subscribeBuilder.setTopic(topic);
    subscribeBuilder.setSubscription(subscription);
    subscribeBuilder.setSubType(subType);
    subscribeBuilder.setConsumerId(consumerId);
    subscribeBuilder.setConsumerName(consumerName);
    subscribeBuilder.setRequestId(requestId);
    subscribeBuilder.setPriorityLevel(priorityLevel);
    CommandSubscribe subscribe = subscribeBuilder.build();
    ByteBuf res = serializeWithSize(BaseCommand.newBuilder().setType(Type.SUBSCRIBE).setSubscribe(subscribe));
    subscribeBuilder.recycle();
    subscribe.recycle();
    return res;
}
Also used : CommandSubscribe(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandSubscribe) UnpooledHeapByteBuf(io.netty.buffer.UnpooledHeapByteBuf) RecyclableDuplicateByteBuf(io.netty.buffer.RecyclableDuplicateByteBuf) ByteBuf(io.netty.buffer.ByteBuf)

Example 3 with CommandSubscribe

use of com.yahoo.pulsar.common.api.proto.PulsarApi.CommandSubscribe in project pulsar by yahoo.

the class PersistentTopicTest method testDeleteTopicRaceConditions.

@Test
public void testDeleteTopicRaceConditions() throws Exception {
    PersistentTopic topic = (PersistentTopic) brokerService.getTopic(successTopicName).get();
    // override ledger deletion callback to slow down deletion
    doAnswer(new Answer<Object>() {

        @Override
        public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
            Thread.sleep(1000);
            ((DeleteLedgerCallback) invocationOnMock.getArguments()[0]).deleteLedgerComplete(null);
            return null;
        }
    }).when(ledgerMock).asyncDelete(any(DeleteLedgerCallback.class), anyObject());
    ExecutorService executor = Executors.newCachedThreadPool();
    executor.submit(() -> {
        topic.delete();
        return null;
    }).get();
    try {
        String role = "appid1";
        Thread.sleep(10);
        /* delay to ensure that the delete gets executed first */
        Producer producer = new Producer(topic, serverCnx, 1, /* producer id */
        "prod-name", role);
        topic.addProducer(producer);
        fail("Should have failed");
    } catch (BrokerServiceException e) {
        assertTrue(e instanceof BrokerServiceException.TopicFencedException);
    }
    CommandSubscribe cmd = CommandSubscribe.newBuilder().setConsumerId(1).setTopic(successTopicName).setSubscription(successSubName).setRequestId(1).setSubType(SubType.Exclusive).build();
    Future<Consumer> f = topic.subscribe(serverCnx, cmd.getSubscription(), cmd.getConsumerId(), cmd.getSubType(), 0, cmd.getConsumerName());
    try {
        f.get();
        fail("should have failed");
    } catch (ExecutionException ee) {
        assertTrue(ee.getCause() instanceof BrokerServiceException.TopicFencedException);
    // Expected
    }
}
Also used : Matchers.anyString(org.mockito.Matchers.anyString) CommandSubscribe(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandSubscribe) DeleteLedgerCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.DeleteLedgerCallback) PersistentDispatcherSingleActiveConsumer(com.yahoo.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer) InvocationOnMock(org.mockito.invocation.InvocationOnMock) PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) ExecutorService(java.util.concurrent.ExecutorService) Matchers.anyObject(org.mockito.Matchers.anyObject) ExecutionException(java.util.concurrent.ExecutionException) Test(org.testng.annotations.Test)

Example 4 with CommandSubscribe

use of com.yahoo.pulsar.common.api.proto.PulsarApi.CommandSubscribe in project pulsar by yahoo.

the class PersistentTopicTest method testDeleteTopic.

@Test
public void testDeleteTopic() throws Exception {
    // create topic
    PersistentTopic topic = (PersistentTopic) brokerService.getTopic(successTopicName).get();
    String role = "appid1";
    // 1. delete inactive topic
    topic.delete().get();
    assertNull(brokerService.getTopicReference(successTopicName));
    // 2. delete topic with producer
    topic = (PersistentTopic) brokerService.getTopic(successTopicName).get();
    Producer producer = new Producer(topic, serverCnx, 1, /* producer id */
    "prod-name", role);
    topic.addProducer(producer);
    assertTrue(topic.delete().isCompletedExceptionally());
    topic.removeProducer(producer);
    // 3. delete topic with subscriber
    CommandSubscribe cmd = CommandSubscribe.newBuilder().setConsumerId(1).setTopic(successTopicName).setSubscription(successSubName).setRequestId(1).setSubType(SubType.Exclusive).build();
    Future<Consumer> f1 = topic.subscribe(serverCnx, cmd.getSubscription(), cmd.getConsumerId(), cmd.getSubType(), 0, cmd.getConsumerName());
    f1.get();
    assertTrue(topic.delete().isCompletedExceptionally());
    topic.unsubscribe(successSubName);
}
Also used : CommandSubscribe(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandSubscribe) PersistentDispatcherSingleActiveConsumer(com.yahoo.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer) PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) Matchers.anyString(org.mockito.Matchers.anyString) Test(org.testng.annotations.Test)

Example 5 with CommandSubscribe

use of com.yahoo.pulsar.common.api.proto.PulsarApi.CommandSubscribe in project pulsar by yahoo.

the class PersistentTopicTest method testDeleteAndUnsubscribeTopic.

@Test
public void testDeleteAndUnsubscribeTopic() throws Exception {
    // create topic
    final PersistentTopic topic = (PersistentTopic) brokerService.getTopic(successTopicName).get();
    CommandSubscribe cmd = CommandSubscribe.newBuilder().setConsumerId(1).setTopic(successTopicName).setSubscription(successSubName).setRequestId(1).setSubType(SubType.Exclusive).build();
    Future<Consumer> f1 = topic.subscribe(serverCnx, cmd.getSubscription(), cmd.getConsumerId(), cmd.getSubType(), 0, cmd.getConsumerName());
    f1.get();
    final CyclicBarrier barrier = new CyclicBarrier(2);
    final CountDownLatch counter = new CountDownLatch(2);
    final AtomicBoolean gotException = new AtomicBoolean(false);
    Thread deleter = new Thread() {

        @Override
        public void run() {
            try {
                barrier.await();
                assertFalse(topic.delete().isCompletedExceptionally());
            } catch (Exception e) {
                e.printStackTrace();
                gotException.set(true);
            } finally {
                counter.countDown();
            }
        }
    };
    Thread unsubscriber = new Thread() {

        @Override
        public void run() {
            try {
                barrier.await();
                // do topic unsubscribe
                topic.unsubscribe(successSubName);
            } catch (Exception e) {
                e.printStackTrace();
                gotException.set(true);
            } finally {
                counter.countDown();
            }
        }
    };
    deleter.start();
    unsubscriber.start();
    counter.await();
    assertEquals(gotException.get(), false);
}
Also used : CommandSubscribe(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandSubscribe) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) PersistentDispatcherSingleActiveConsumer(com.yahoo.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer) PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) CountDownLatch(java.util.concurrent.CountDownLatch) TimeoutException(java.util.concurrent.TimeoutException) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) ExecutionException(java.util.concurrent.ExecutionException) CyclicBarrier(java.util.concurrent.CyclicBarrier) Test(org.testng.annotations.Test)

Aggregations

CommandSubscribe (com.yahoo.pulsar.common.api.proto.PulsarApi.CommandSubscribe)8 PersistentTopic (com.yahoo.pulsar.broker.service.persistent.PersistentTopic)7 PersistentDispatcherSingleActiveConsumer (com.yahoo.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer)6 ExecutionException (java.util.concurrent.ExecutionException)5 Test (org.testng.annotations.Test)5 PersistentSubscription (com.yahoo.pulsar.broker.service.persistent.PersistentSubscription)3 Matchers.anyString (org.mockito.Matchers.anyString)3 ByteBuf (io.netty.buffer.ByteBuf)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 CyclicBarrier (java.util.concurrent.CyclicBarrier)2 TimeoutException (java.util.concurrent.TimeoutException)2 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 ManagedLedgerException (org.apache.bookkeeper.mledger.ManagedLedgerException)2 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)1 PersistentTopics.getPartitionedTopicMetadata (com.yahoo.pulsar.broker.admin.PersistentTopics.getPartitionedTopicMetadata)1 AuthenticationDataCommand (com.yahoo.pulsar.broker.authentication.AuthenticationDataCommand)1 DestinationLookup.lookupDestinationAsync (com.yahoo.pulsar.broker.lookup.DestinationLookup.lookupDestinationAsync)1 ServiceUnitNotReadyException (com.yahoo.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException)1 PulsarClientException (com.yahoo.pulsar.client.api.PulsarClientException)1 Commands (com.yahoo.pulsar.common.api.Commands)1