Search in sources :

Example 1 with CommandPartitionedTopicMetadata

use of org.apache.pulsar.common.api.proto.PulsarApi.CommandPartitionedTopicMetadata in project incubator-pulsar by apache.

the class LookupProxyHandler method handlePartitionMetadataResponse.

private void handlePartitionMetadataResponse(CommandPartitionedTopicMetadata partitionMetadata, long clientRequestId) {
    TopicName topicName = TopicName.get(partitionMetadata.getTopic());
    if (isBlank(brokerServiceURL)) {
        service.getDiscoveryProvider().getPartitionedTopicMetadata(service, topicName, proxyConnection.clientAuthRole, proxyConnection.authenticationData).thenAccept(metadata -> {
            if (log.isDebugEnabled()) {
                log.debug("[{}] Total number of partitions for topic {} is {}", proxyConnection.clientAuthRole, topicName, metadata.partitions);
            }
            proxyConnection.ctx().writeAndFlush(Commands.newPartitionMetadataResponse(metadata.partitions, clientRequestId));
        }).exceptionally(ex -> {
            log.warn("[{}] Failed to get partitioned metadata for topic {} {}", clientAddress, topicName, ex.getMessage(), ex);
            proxyConnection.ctx().writeAndFlush(Commands.newPartitionMetadataResponse(ServerError.ServiceNotReady, ex.getMessage(), clientRequestId));
            return null;
        });
    } else {
        URI brokerURI;
        try {
            brokerURI = new URI(brokerServiceURL);
        } catch (URISyntaxException e) {
            proxyConnection.ctx().writeAndFlush(Commands.newPartitionMetadataResponse(ServerError.MetadataError, e.getMessage(), clientRequestId));
            return;
        }
        InetSocketAddress addr = new InetSocketAddress(brokerURI.getHost(), brokerURI.getPort());
        if (log.isDebugEnabled()) {
            log.debug("Getting connections to '{}' for Looking up topic '{}' with clientReq Id '{}'", addr, topicName.getPartitionedTopicName(), clientRequestId);
        }
        service.getConnectionPool().getConnection(addr).thenAccept(clientCnx -> {
            // Connected to backend broker
            long requestId = service.newRequestId();
            ByteBuf command;
            if (service.getConfiguration().isAuthenticationEnabled()) {
                command = Commands.newPartitionMetadataRequest(topicName.toString(), requestId, proxyConnection.clientAuthRole, proxyConnection.clientAuthData, proxyConnection.clientAuthMethod);
            } else {
                command = Commands.newPartitionMetadataRequest(topicName.toString(), requestId);
            }
            clientCnx.newLookup(command, requestId).thenAccept(lookupDataResult -> {
                proxyConnection.ctx().writeAndFlush(Commands.newPartitionMetadataResponse(lookupDataResult.partitions, clientRequestId));
            }).exceptionally((ex) -> {
                log.warn("[{}] failed to get Partitioned metadata : {}", topicName.toString(), ex.getCause().getMessage(), ex);
                proxyConnection.ctx().writeAndFlush(Commands.newLookupErrorResponse(ServerError.ServiceNotReady, ex.getMessage(), clientRequestId));
                return null;
            });
        }).exceptionally(ex -> {
            // Failed to connect to backend broker
            proxyConnection.ctx().writeAndFlush(Commands.newPartitionMetadataResponse(ServerError.ServiceNotReady, ex.getMessage(), clientRequestId));
            return null;
        });
    }
}
Also used : Commands(org.apache.pulsar.common.api.Commands) TopicName(org.apache.pulsar.common.naming.TopicName) Logger(org.slf4j.Logger) SocketAddress(java.net.SocketAddress) URISyntaxException(java.net.URISyntaxException) LoggerFactory(org.slf4j.LoggerFactory) LookupType(org.apache.pulsar.common.api.proto.PulsarApi.CommandLookupTopicResponse.LookupType) ServiceLookupData(org.apache.pulsar.policies.data.loadbalancer.ServiceLookupData) InetSocketAddress(java.net.InetSocketAddress) CommandLookupTopic(org.apache.pulsar.common.api.proto.PulsarApi.CommandLookupTopic) Counter(io.prometheus.client.Counter) ServerError(org.apache.pulsar.common.api.proto.PulsarApi.ServerError) ByteBuf(io.netty.buffer.ByteBuf) StringUtils.isBlank(org.apache.commons.lang3.StringUtils.isBlank) CommandPartitionedTopicMetadata(org.apache.pulsar.common.api.proto.PulsarApi.CommandPartitionedTopicMetadata) URI(java.net.URI) InetSocketAddress(java.net.InetSocketAddress) URISyntaxException(java.net.URISyntaxException) ByteBuf(io.netty.buffer.ByteBuf) URI(java.net.URI) TopicName(org.apache.pulsar.common.naming.TopicName)

Example 2 with CommandPartitionedTopicMetadata

use of org.apache.pulsar.common.api.proto.PulsarApi.CommandPartitionedTopicMetadata in project incubator-pulsar by apache.

the class ServerCnx method handlePartitionMetadataRequest.

@Override
protected void handlePartitionMetadataRequest(CommandPartitionedTopicMetadata partitionMetadata) {
    final long requestId = partitionMetadata.getRequestId();
    if (log.isDebugEnabled()) {
        log.debug("[{}] Received PartitionMetadataLookup from {} for {}", partitionMetadata.getTopic(), remoteAddress, requestId);
    }
    TopicName topicName = validateTopicName(partitionMetadata.getTopic(), requestId, partitionMetadata);
    if (topicName == null) {
        return;
    }
    String originalPrincipal = null;
    if (authenticateOriginalAuthData && partitionMetadata.hasOriginalAuthData()) {
        originalPrincipal = validateOriginalPrincipal(partitionMetadata.hasOriginalAuthData() ? partitionMetadata.getOriginalAuthData() : null, partitionMetadata.hasOriginalAuthMethod() ? partitionMetadata.getOriginalAuthMethod() : null, partitionMetadata.hasOriginalPrincipal() ? partitionMetadata.getOriginalPrincipal() : this.originalPrincipal, requestId, partitionMetadata);
        if (originalPrincipal == null) {
            return;
        }
    } else {
        originalPrincipal = partitionMetadata.hasOriginalPrincipal() ? partitionMetadata.getOriginalPrincipal() : this.originalPrincipal;
    }
    final Semaphore lookupSemaphore = service.getLookupRequestSemaphore();
    if (lookupSemaphore.tryAcquire()) {
        if (invalidOriginalPrincipal(originalPrincipal)) {
            final String msg = "Valid Proxy Client role should be provided for getPartitionMetadataRequest ";
            log.warn("[{}] {} with role {} and proxyClientAuthRole {} on topic {}", remoteAddress, msg, authRole, originalPrincipal, topicName);
            ctx.writeAndFlush(Commands.newPartitionMetadataResponse(ServerError.AuthorizationError, msg, requestId));
            lookupSemaphore.release();
            return;
        }
        CompletableFuture<Boolean> isProxyAuthorizedFuture;
        if (service.isAuthorizationEnabled() && originalPrincipal != null) {
            isProxyAuthorizedFuture = service.getAuthorizationService().canLookupAsync(topicName, authRole, authenticationData);
        } else {
            isProxyAuthorizedFuture = CompletableFuture.completedFuture(true);
        }
        String finalOriginalPrincipal = originalPrincipal;
        isProxyAuthorizedFuture.thenApply(isProxyAuthorized -> {
            if (isProxyAuthorized) {
                getPartitionedTopicMetadata(getBrokerService().pulsar(), finalOriginalPrincipal != null ? finalOriginalPrincipal : authRole, authenticationData, topicName).handle((metadata, ex) -> {
                    if (ex == null) {
                        int partitions = metadata.partitions;
                        ctx.writeAndFlush(Commands.newPartitionMetadataResponse(partitions, requestId));
                    } else {
                        if (ex instanceof PulsarClientException) {
                            log.warn("Failed to authorize {} at [{}] on topic {} : {}", getRole(), remoteAddress, topicName, ex.getMessage());
                            ctx.writeAndFlush(Commands.newPartitionMetadataResponse(ServerError.AuthorizationError, ex.getMessage(), requestId));
                        } else {
                            log.warn("Failed to get Partitioned Metadata [{}] {}: {}", remoteAddress, topicName, ex.getMessage(), ex);
                            ServerError error = (ex instanceof RestException) && ((RestException) ex).getResponse().getStatus() < 500 ? ServerError.MetadataError : ServerError.ServiceNotReady;
                            ctx.writeAndFlush(Commands.newPartitionMetadataResponse(error, ex.getMessage(), requestId));
                        }
                    }
                    lookupSemaphore.release();
                    return null;
                });
            } else {
                final String msg = "Proxy Client is not authorized to Get Partition Metadata";
                log.warn("[{}] {} with role {} on topic {}", remoteAddress, msg, authRole, topicName);
                ctx.writeAndFlush(Commands.newPartitionMetadataResponse(ServerError.AuthorizationError, msg, requestId));
                lookupSemaphore.release();
            }
            return null;
        }).exceptionally(ex -> {
            final String msg = "Exception occured while trying to authorize get Partition Metadata";
            log.warn("[{}] {} with role {} on topic {}", remoteAddress, msg, authRole, topicName);
            ctx.writeAndFlush(Commands.newPartitionMetadataResponse(ServerError.AuthorizationError, msg, requestId));
            lookupSemaphore.release();
            return null;
        });
    } else {
        if (log.isDebugEnabled()) {
            log.debug("[{}] Failed Partition-Metadata lookup due to too many lookup-requests {}", remoteAddress, topicName);
        }
        ctx.writeAndFlush(Commands.newPartitionMetadataResponse(ServerError.TooManyRequests, "Failed due to too many pending lookup requests", requestId));
    }
}
Also used : PulsarApi(org.apache.pulsar.common.api.proto.PulsarApi) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) CommandUtils(org.apache.pulsar.common.api.CommandUtils) SocketAddress(java.net.SocketAddress) PersistentTopicsBase.getPartitionedTopicMetadata(org.apache.pulsar.broker.admin.impl.PersistentTopicsBase.getPartitionedTopicMetadata) SchemaVersion(org.apache.pulsar.common.schema.SchemaVersion) CommandAck(org.apache.pulsar.common.api.proto.PulsarApi.CommandAck) LoggerFactory(org.slf4j.LoggerFactory) AuthenticationException(javax.naming.AuthenticationException) StringUtils(org.apache.commons.lang3.StringUtils) CommandCloseConsumer(org.apache.pulsar.common.api.proto.PulsarApi.CommandCloseConsumer) CommandGetLastMessageId(org.apache.pulsar.common.api.proto.PulsarApi.CommandGetLastMessageId) CommandSend(org.apache.pulsar.common.api.proto.PulsarApi.CommandSend) ServerError(org.apache.pulsar.common.api.proto.PulsarApi.ServerError) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) PulsarHandler(org.apache.pulsar.common.api.PulsarHandler) Map(java.util.Map) RestException(org.apache.pulsar.broker.web.RestException) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) CommandGetTopicsOfNamespace(org.apache.pulsar.common.api.proto.PulsarApi.CommandGetTopicsOfNamespace) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) ProtocolVersion.v5(org.apache.pulsar.common.api.proto.PulsarApi.ProtocolVersion.v5) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) CommandConnect(org.apache.pulsar.common.api.proto.PulsarApi.CommandConnect) Commands(org.apache.pulsar.common.api.Commands) Commands.newLookupErrorResponse(org.apache.pulsar.common.api.Commands.newLookupErrorResponse) CommandSubscribe(org.apache.pulsar.common.api.proto.PulsarApi.CommandSubscribe) Set(java.util.Set) CommandRedeliverUnacknowledgedMessages(org.apache.pulsar.common.api.proto.PulsarApi.CommandRedeliverUnacknowledgedMessages) Position(org.apache.bookkeeper.mledger.Position) CommandCloseProducer(org.apache.pulsar.common.api.proto.PulsarApi.CommandCloseProducer) CommandFlow(org.apache.pulsar.common.api.proto.PulsarApi.CommandFlow) Collectors(java.util.stream.Collectors) AuthenticationDataSource(org.apache.pulsar.broker.authentication.AuthenticationDataSource) MessageIdImpl(org.apache.pulsar.client.impl.MessageIdImpl) List(java.util.List) StringUtils.isNotBlank(org.apache.commons.lang3.StringUtils.isNotBlank) BatchMessageIdImpl(org.apache.pulsar.client.impl.BatchMessageIdImpl) SafeRun(org.apache.bookkeeper.mledger.util.SafeRun) SslHandler(io.netty.handler.ssl.SslHandler) SchemaData(org.apache.pulsar.common.schema.SchemaData) CommandConsumerStatsResponse(org.apache.pulsar.common.api.proto.PulsarApi.CommandConsumerStatsResponse) CommandPartitionedTopicMetadata(org.apache.pulsar.common.api.proto.PulsarApi.CommandPartitionedTopicMetadata) MessageIdData(org.apache.pulsar.common.api.proto.PulsarApi.MessageIdData) ClientCnx(org.apache.pulsar.client.impl.ClientCnx) TopicName(org.apache.pulsar.common.naming.TopicName) ChannelOption(io.netty.channel.ChannelOption) CommandConsumerStats(org.apache.pulsar.common.api.proto.PulsarApi.CommandConsumerStats) GeneratedMessageLite(com.google.protobuf.GeneratedMessageLite) BacklogQuota(org.apache.pulsar.common.policies.data.BacklogQuota) CompletableFuture(java.util.concurrent.CompletableFuture) ProtocolVersion(org.apache.pulsar.common.api.proto.PulsarApi.ProtocolVersion) SchemaType(org.apache.pulsar.common.schema.SchemaType) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ServerMetadataException(org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException) SSLSession(javax.net.ssl.SSLSession) ByteBuf(io.netty.buffer.ByteBuf) MessageMetadata(org.apache.pulsar.common.api.proto.PulsarApi.MessageMetadata) CommandProducer(org.apache.pulsar.common.api.proto.PulsarApi.CommandProducer) CommandSeek(org.apache.pulsar.common.api.proto.PulsarApi.CommandSeek) AuthenticationDataCommand(org.apache.pulsar.broker.authentication.AuthenticationDataCommand) Metadata(org.apache.pulsar.common.naming.Metadata) Logger(org.slf4j.Logger) SubType(org.apache.pulsar.common.api.proto.PulsarApi.CommandSubscribe.SubType) Semaphore(java.util.concurrent.Semaphore) CommandLookupTopic(org.apache.pulsar.common.api.proto.PulsarApi.CommandLookupTopic) TimeUnit(java.util.concurrent.TimeUnit) CommandUnsubscribe(org.apache.pulsar.common.api.proto.PulsarApi.CommandUnsubscribe) ConcurrentLongHashMap(org.apache.pulsar.common.util.collections.ConcurrentLongHashMap) TopicLookup.lookupTopicAsync(org.apache.pulsar.broker.lookup.TopicLookup.lookupTopicAsync) PulsarServerException(org.apache.pulsar.broker.PulsarServerException) ConsumerBusyException(org.apache.pulsar.broker.service.BrokerServiceException.ConsumerBusyException) ChannelHandler(io.netty.channel.ChannelHandler) ConsumerStats(org.apache.pulsar.common.policies.data.ConsumerStats) InitialPosition(org.apache.pulsar.common.api.proto.PulsarApi.CommandSubscribe.InitialPosition) ServerError(org.apache.pulsar.common.api.proto.PulsarApi.ServerError) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) RestException(org.apache.pulsar.broker.web.RestException) Semaphore(java.util.concurrent.Semaphore) TopicName(org.apache.pulsar.common.naming.TopicName)

Example 3 with CommandPartitionedTopicMetadata

use of org.apache.pulsar.common.api.proto.PulsarApi.CommandPartitionedTopicMetadata in project incubator-pulsar by apache.

the class Commands method newPartitionMetadataRequest.

public static ByteBuf newPartitionMetadataRequest(String topic, long requestId, String originalAuthRole, String originalAuthData, String originalAuthMethod) {
    CommandPartitionedTopicMetadata.Builder partitionMetadataBuilder = CommandPartitionedTopicMetadata.newBuilder();
    partitionMetadataBuilder.setTopic(topic);
    partitionMetadataBuilder.setRequestId(requestId);
    if (originalAuthRole != null) {
        partitionMetadataBuilder.setOriginalPrincipal(originalAuthRole);
    }
    if (originalAuthData != null) {
        partitionMetadataBuilder.setOriginalAuthData(originalAuthData);
    }
    if (originalAuthMethod != null) {
        partitionMetadataBuilder.setOriginalAuthMethod(originalAuthMethod);
    }
    CommandPartitionedTopicMetadata partitionMetadata = partitionMetadataBuilder.build();
    ByteBuf res = serializeWithSize(BaseCommand.newBuilder().setType(Type.PARTITIONED_METADATA).setPartitionMetadata(partitionMetadata));
    partitionMetadataBuilder.recycle();
    partitionMetadata.recycle();
    return res;
}
Also used : ByteBuf(io.netty.buffer.ByteBuf) CommandPartitionedTopicMetadata(org.apache.pulsar.common.api.proto.PulsarApi.CommandPartitionedTopicMetadata)

Example 4 with CommandPartitionedTopicMetadata

use of org.apache.pulsar.common.api.proto.PulsarApi.CommandPartitionedTopicMetadata in project incubator-pulsar by apache.

the class ServerConnection method sendPartitionMetadataResponse.

private void sendPartitionMetadataResponse(CommandPartitionedTopicMetadata partitionMetadata) {
    final long requestId = partitionMetadata.getRequestId();
    TopicName topicName = TopicName.get(partitionMetadata.getTopic());
    service.getDiscoveryProvider().getPartitionedTopicMetadata(service, topicName, authRole, authenticationData).thenAccept(metadata -> {
        if (LOG.isDebugEnabled()) {
            LOG.debug("[{}] Total number of partitions for topic {} is {}", authRole, topicName, metadata.partitions);
        }
        ctx.writeAndFlush(Commands.newPartitionMetadataResponse(metadata.partitions, requestId));
    }).exceptionally(ex -> {
        LOG.warn("[{}] Failed to get partitioned metadata for topic {} {}", remoteAddress, topicName, ex.getMessage(), ex);
        ctx.writeAndFlush(Commands.newPartitionMetadataResponse(ServerError.ServiceNotReady, ex.getMessage(), requestId));
        return null;
    });
}
Also used : CommandConnect(org.apache.pulsar.common.api.proto.PulsarApi.CommandConnect) AuthenticationDataCommand(org.apache.pulsar.broker.authentication.AuthenticationDataCommand) Commands(org.apache.pulsar.common.api.Commands) TopicName(org.apache.pulsar.common.naming.TopicName) Logger(org.slf4j.Logger) LoggerFactory(org.slf4j.LoggerFactory) AuthenticationException(javax.naming.AuthenticationException) CommandLookupTopic(org.apache.pulsar.common.api.proto.PulsarApi.CommandLookupTopic) AuthenticationDataSource(org.apache.pulsar.broker.authentication.AuthenticationDataSource) Redirect(org.apache.pulsar.common.api.proto.PulsarApi.CommandLookupTopicResponse.LookupType.Redirect) TimeUnit(java.util.concurrent.TimeUnit) ServerError(org.apache.pulsar.common.api.proto.PulsarApi.ServerError) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) SSLSession(javax.net.ssl.SSLSession) SslHandler(io.netty.handler.ssl.SslHandler) PulsarServerException(org.apache.pulsar.broker.PulsarServerException) PulsarHandler(org.apache.pulsar.common.api.PulsarHandler) LoadManagerReport(org.apache.pulsar.policies.data.loadbalancer.LoadManagerReport) CommandPartitionedTopicMetadata(org.apache.pulsar.common.api.proto.PulsarApi.CommandPartitionedTopicMetadata) ChannelHandler(io.netty.channel.ChannelHandler) TopicName(org.apache.pulsar.common.naming.TopicName)

Example 5 with CommandPartitionedTopicMetadata

use of org.apache.pulsar.common.api.proto.PulsarApi.CommandPartitionedTopicMetadata in project incubator-pulsar by apache.

the class ServerCnx method validateOriginalPrincipal.

private String validateOriginalPrincipal(String originalAuthData, String originalAuthMethod, String originalPrincipal, Long requestId, GeneratedMessageLite request) {
    ChannelHandler sslHandler = ctx.channel().pipeline().get(PulsarChannelInitializer.TLS_HANDLER);
    SSLSession sslSession = null;
    if (sslHandler != null) {
        sslSession = ((SslHandler) sslHandler).engine().getSession();
    }
    try {
        return getOriginalPrincipal(originalAuthData, originalAuthMethod, originalPrincipal, sslSession);
    } catch (AuthenticationException e) {
        String msg = "Unable to authenticate original authdata ";
        log.warn("[{}] {}: {}", remoteAddress, msg, e.getMessage());
        if (request instanceof CommandLookupTopic) {
            ctx.writeAndFlush(newLookupErrorResponse(ServerError.AuthenticationError, msg, requestId));
        } else if (request instanceof CommandPartitionedTopicMetadata) {
            ctx.writeAndFlush(Commands.newPartitionMetadataResponse(ServerError.AuthenticationError, msg, requestId));
        }
        return null;
    }
}
Also used : CommandLookupTopic(org.apache.pulsar.common.api.proto.PulsarApi.CommandLookupTopic) AuthenticationException(javax.naming.AuthenticationException) SSLSession(javax.net.ssl.SSLSession) ChannelHandler(io.netty.channel.ChannelHandler) SslHandler(io.netty.handler.ssl.SslHandler) CommandPartitionedTopicMetadata(org.apache.pulsar.common.api.proto.PulsarApi.CommandPartitionedTopicMetadata)

Aggregations

CommandPartitionedTopicMetadata (org.apache.pulsar.common.api.proto.PulsarApi.CommandPartitionedTopicMetadata)5 CommandLookupTopic (org.apache.pulsar.common.api.proto.PulsarApi.CommandLookupTopic)4 ByteBuf (io.netty.buffer.ByteBuf)3 ChannelHandler (io.netty.channel.ChannelHandler)3 SslHandler (io.netty.handler.ssl.SslHandler)3 AuthenticationException (javax.naming.AuthenticationException)3 SSLSession (javax.net.ssl.SSLSession)3 Commands (org.apache.pulsar.common.api.Commands)3 ServerError (org.apache.pulsar.common.api.proto.PulsarApi.ServerError)3 TopicName (org.apache.pulsar.common.naming.TopicName)3 Logger (org.slf4j.Logger)3 LoggerFactory (org.slf4j.LoggerFactory)3 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)2 SocketAddress (java.net.SocketAddress)2 TimeUnit (java.util.concurrent.TimeUnit)2 PulsarServerException (org.apache.pulsar.broker.PulsarServerException)2 AuthenticationDataCommand (org.apache.pulsar.broker.authentication.AuthenticationDataCommand)2 AuthenticationDataSource (org.apache.pulsar.broker.authentication.AuthenticationDataSource)2 GeneratedMessageLite (com.google.protobuf.GeneratedMessageLite)1 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)1