protected void validateAdminOperationOnDestination(DestinationName fqdn, boolean authoritative) { validateAdminAccessOnProperty(fqdn.getProperty()); validateDestinationOwnership(fqdn, authoritative); }
try { propertyAdmin = service.getConfigurationCacheService().propertiesCache() .get(path("policies", destination.getProperty())) .orElseThrow(() -> new IllegalAccessException("Property does not exist")); } catch (KeeperException.NoNodeException e) { LOG.warn("Failed to get property admin data for non existing property {}", destination.getProperty()); throw new IllegalAccessException("Property does not exist"); } catch (Exception e) { LOG.error("Failed to get property admin data for property"); throw new IllegalAccessException(String.format("Failed to get property %s admin data due to %s", destination.getProperty(), e.getMessage())); LOG.debug("Successfully authorized {} on property {}", role, destination.getProperty());
@GET @Path("{property}/{cluster}/{namespace}/{destination}/internal-info") @ApiOperation(value = "Get the internal stats for the topic.") @ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Topic does not exist") }) public void getManagedLedgerInfo(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("destination") @Encoded String destination, @Suspended AsyncResponse asyncResponse) { destination = decode(destination); DestinationName dn = DestinationName.get(domain(), property, cluster, namespace, destination); validateAdminAccessOnProperty(dn.getProperty()); String managedLedger = dn.getPersistenceNamingEncoding(); pulsar().getManagedLedgerFactory().asyncGetManagedLedgerInfo(managedLedger, new ManagedLedgerInfoCallback() { @Override public void getInfoComplete(ManagedLedgerInfo info, Object ctx) { asyncResponse.resume((StreamingOutput) output -> { jsonMapper().writer().writeValue(output, info); }); } @Override public void getInfoFailed(ManagedLedgerException exception, Object ctx) { asyncResponse.resume(exception); } }, null); }
CompletableFuture<PartitionedTopicMetadata> getPartitionedTopicMetadata(DiscoveryService service, DestinationName destination, String role) { CompletableFuture<PartitionedTopicMetadata> metadataFuture = new CompletableFuture<>(); try { checkAuthorization(service, destination, role); final String path = path(PARTITIONED_TOPIC_PATH_ZNODE, destination.getProperty(), destination.getCluster(), destination.getNamespacePortion(), "persistent", destination.getEncodedLocalName()); // gets the number of partitions from the zk cache globalZkCache .getDataAsync(path, (key, content) -> getThreadLocal().readValue(content, PartitionedTopicMetadata.class)) .thenAccept(metadata -> { // if the partitioned topic is not found in zk, then the topic // is not partitioned if (metadata.isPresent()) { metadataFuture.complete(metadata.get()); } else { metadataFuture.complete(new PartitionedTopicMetadata()); } }).exceptionally(ex -> { metadataFuture.completeExceptionally(ex); return null; }); } catch (Exception e) { metadataFuture.completeExceptionally(e); } return metadataFuture; }
destination = decode(destination); DestinationName dn = DestinationName.get(domain(), property, cluster, namespace, destination); validateAdminAccessOnProperty(dn.getProperty()); if (dn.isGlobal()) { log.error("[{}] Update partitioned-topic is forbidden on global namespace {}", clientAppId(), dn);
} catch (RestException e) { try { validateAdminAccessOnProperty(pulsar, clientAppId, dn.getProperty()); } catch (RestException authException) { log.warn("Failed to authorize {} on cluster {}", clientAppId, dn.toString()); throw ex; String path = path(PARTITIONED_TOPIC_PATH_ZNODE, dn.getProperty(), dn.getCluster(), dn.getNamespacePortion(), "persistent", dn.getEncodedLocalName()); fetchPartitionedTopicMetadataAsync(pulsar, path).thenAccept(metadata -> {
protected void validateAdminAndClientPermission(DestinationName destination) { try { validateAdminAccessOnProperty(destination.getProperty()); } catch (Exception ve) { try { checkAuthorization(pulsar(), destination, clientAppId()); } catch (RestException re) { throw re; } catch (Exception e) { // unknown error marked as internal server error log.warn("Unexpected error while authorizing request. destination={}, role={}. Error: {}", destination, clientAppId(), e.getMessage(), e); throw new RestException(e); } } }
@PUT @Path("/{property}/{cluster}/{namespace}/{destination}/partitions") @ApiOperation(value = "Create a partitioned topic.", notes = "It needs to be called before creating a producer on a partitioned topic.") @ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 409, message = "Partitioned topic already exist") }) public void createPartitionedTopic(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("destination") @Encoded String destination, int numPartitions, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) { destination = decode(destination); DestinationName dn = DestinationName.get(domain(), property, cluster, namespace, destination); validateAdminAccessOnProperty(dn.getProperty()); if (numPartitions <= 1) { throw new RestException(Status.NOT_ACCEPTABLE, "Number of partitions should be more than 1"); } try { String path = path(PARTITIONED_TOPIC_PATH_ZNODE, property, cluster, namespace, domain(), dn.getEncodedLocalName()); byte[] data = jsonMapper().writeValueAsBytes(new PartitionedTopicMetadata(numPartitions)); zkCreateOptimistic(path, data); // we wait for the data to be synced in all quorums and the observers Thread.sleep(PARTITIONED_TOPIC_WAIT_SYNC_TIME_MS); log.info("[{}] Successfully created partitioned topic {}", clientAppId(), dn); } catch (KeeperException.NodeExistsException e) { log.warn("[{}] Failed to create already existing partitioned topic {}", clientAppId(), dn); throw new RestException(Status.CONFLICT, "Partitioned topic already exist"); } catch (Exception e) { log.error("[{}] Failed to create partitioned topic {}", clientAppId(), dn, e); throw new RestException(e); } }
private CompletableFuture<Void> updatePartitionedTopic(DestinationName dn, int numPartitions) { String path = path(PARTITIONED_TOPIC_PATH_ZNODE, dn.getProperty(), dn.getCluster(), dn.getNamespacePortion(), domain(), dn.getEncodedLocalName()); CompletableFuture<Void> updatePartition = new CompletableFuture<>(); createSubscriptions(dn, numPartitions).thenAccept(res -> { try { byte[] data = jsonMapper().writeValueAsBytes(new PartitionedTopicMetadata(numPartitions)); globalZk().setData(path, data, -1, (rc, path1, ctx, stat) -> { if (rc == KeeperException.Code.OK.intValue()) { updatePartition.complete(null); } else { updatePartition.completeExceptionally(KeeperException.create(KeeperException.Code.get(rc), "failed to create update partitions")); } }, null); } catch (Exception e) { updatePartition.completeExceptionally(e); } }).exceptionally(ex -> { updatePartition.completeExceptionally(ex); return null; }); return updatePartition; }
destination = decode(destination); DestinationName dn = DestinationName.get(domain(), property, cluster, namespace, destination); validateAdminAccessOnProperty(dn.getProperty()); PartitionedTopicMetadata partitionMetadata = getPartitionedTopicMetadata(property, cluster, namespace, destination, authoritative);
public PartitionedTopicMetadata getPartitionedTopicMetadata(String property, String cluster, String namespace, String destination, boolean authoritative) { DestinationName dn = DestinationName.get(domain(), property, cluster, namespace, destination); validateClusterOwnership(dn.getCluster()); try { checkConnect(dn); } catch (WebApplicationException e) { validateAdminAccessOnProperty(dn.getProperty()); } catch (Exception e) { // unknown error marked as internal server error log.warn("Unexpected error while authorizing lookup. destination={}, role={}. Error: {}", destination, clientAppId(), e.getMessage(), e); throw new RestException(e); } String path = path(PARTITIONED_TOPIC_PATH_ZNODE, property, cluster, namespace, domain(), dn.getEncodedLocalName()); PartitionedTopicMetadata partitionMetadata = fetchPartitionedTopicMetadata(pulsar(), path); if (log.isDebugEnabled()) { log.debug("[{}] Total number of partitions for topic {} is {}", clientAppId(), dn, partitionMetadata.partitions); } return partitionMetadata; }
String path = path(PARTITIONED_TOPIC_PATH_ZNODE, dn.getProperty(), dn.getCluster(), dn.getNamespacePortion(), domain(), dn.getEncodedLocalName()); CompletableFuture<Void> result = new CompletableFuture<>();