use of org.apache.pulsar.broker.web.RestException in project incubator-pulsar by apache.
the class PersistentTopicsBase method internalGetSubscriptions.
protected List<String> internalGetSubscriptions(boolean authoritative) {
if (topicName.isGlobal()) {
validateGlobalNamespaceOwnership(namespaceName);
}
List<String> subscriptions = Lists.newArrayList();
PartitionedTopicMetadata partitionMetadata = getPartitionedTopicMetadata(topicName, authoritative);
if (partitionMetadata.partitions > 0) {
try {
// get the subscriptions only from the 1st partition since all the other partitions will have the same
// subscriptions
subscriptions.addAll(pulsar().getAdminClient().persistentTopics().getSubscriptions(topicName.getPartition(0).toString()));
} catch (Exception e) {
throw new RestException(e);
}
} else {
validateAdminOperationOnTopic(authoritative);
Topic topic = getTopicReference(topicName);
try {
topic.getSubscriptions().forEach((subName, sub) -> subscriptions.add(subName));
} catch (Exception e) {
log.error("[{}] Failed to get list of subscriptions for {}", clientAppId(), topicName);
throw new RestException(e);
}
}
return subscriptions;
}
use of org.apache.pulsar.broker.web.RestException in project incubator-pulsar by apache.
the class PersistentTopicsBase method internalGetList.
protected List<String> internalGetList() {
validateAdminAccessOnProperty(namespaceName.getProperty());
// Validate that namespace exists, throws 404 if it doesn't exist
try {
policiesCache().get(path(POLICIES, namespaceName.toString()));
} catch (KeeperException.NoNodeException e) {
log.warn("[{}] Failed to get topic list {}: Namespace does not exist", clientAppId(), namespaceName);
throw new RestException(Status.NOT_FOUND, "Namespace does not exist");
} catch (Exception e) {
log.error("[{}] Failed to get topic list {}", clientAppId(), namespaceName, e);
throw new RestException(e);
}
List<String> topics = Lists.newArrayList();
try {
String path = String.format("/managed-ledgers/%s/%s", namespaceName.toString(), domain());
for (String topic : managedLedgerListCache().get(path)) {
if (domain().equals(TopicDomain.persistent.toString())) {
topics.add(TopicName.get(domain(), namespaceName, decode(topic)).toString());
}
}
} catch (KeeperException.NoNodeException e) {
// NoNode means there are no topics in this domain for this namespace
} catch (Exception e) {
log.error("[{}] Failed to get topics list for namespace {}", clientAppId(), namespaceName, e);
throw new RestException(e);
}
topics.sort(null);
return topics;
}
use of org.apache.pulsar.broker.web.RestException in project incubator-pulsar by apache.
the class PersistentTopicsBase method internalGrantPermissionsOnTopic.
protected void internalGrantPermissionsOnTopic(String role, Set<AuthAction> actions) {
// This operation should be reading from zookeeper and it should be allowed without having admin privileges
validateAdminAccessOnProperty(namespaceName.getProperty());
validatePoliciesReadOnlyAccess();
String topicUri = topicName.toString();
try {
Stat nodeStat = new Stat();
byte[] content = globalZk().getData(path(POLICIES, namespaceName.toString()), null, nodeStat);
Policies policies = jsonMapper().readValue(content, Policies.class);
if (!policies.auth_policies.destination_auth.containsKey(topicUri)) {
policies.auth_policies.destination_auth.put(topicUri, new TreeMap<String, Set<AuthAction>>());
}
policies.auth_policies.destination_auth.get(topicUri).put(role, actions);
// Write the new policies to zookeeper
globalZk().setData(path(POLICIES, namespaceName.toString()), jsonMapper().writeValueAsBytes(policies), nodeStat.getVersion());
// invalidate the local cache to force update
policiesCache().invalidate(path(POLICIES, namespaceName.toString()));
log.info("[{}] Successfully granted access for role {}: {} - topic {}", clientAppId(), role, actions, topicUri);
} catch (KeeperException.NoNodeException e) {
log.warn("[{}] Failed to grant permissions on topic {}: Namespace does not exist", clientAppId(), topicUri);
throw new RestException(Status.NOT_FOUND, "Namespace does not exist");
} catch (Exception e) {
log.error("[{}] Failed to grant permissions for topic {}", clientAppId(), topicUri, e);
throw new RestException(e);
}
}
use of org.apache.pulsar.broker.web.RestException in project incubator-pulsar by apache.
the class PersistentTopicsBase method unloadTopic.
protected void unloadTopic(TopicName topicName, boolean authoritative) {
validateSuperUserAccess();
validateTopicOwnership(topicName, authoritative);
try {
Topic topic = getTopicReference(topicName);
topic.close().get();
log.info("[{}] Successfully unloaded topic {}", clientAppId(), topicName);
} catch (NullPointerException e) {
log.error("[{}] topic {} not found", clientAppId(), topicName);
throw new RestException(Status.NOT_FOUND, "Topic does not exist");
} catch (Exception e) {
log.error("[{}] Failed to unload topic {}, {}", clientAppId(), topicName, e.getCause().getMessage(), e);
throw new RestException(e.getCause());
}
}
use of org.apache.pulsar.broker.web.RestException 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));
}
}
Aggregations