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;
});
}
}
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));
}
}
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;
}
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;
});
}
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;
}
}
Aggregations