/** * Returns the name of the persistence resource associated with the destination. * * @return the relative path to be used in persistence */ public String getPersistenceNamingEncoding() { // The convention is: domain://property/cluster/namespace/destination // We want to persist in the order: property/cluster/namespace/domain/destination return String.format("%s/%s/%s/%s/%s", property, cluster, namespacePortion, domain, getEncodedLocalName()); }
/** * Get a string suitable for destination lookup * <p> * Example: * <p> * persistent://property/cluster/namespace/destination -> persistent/property/cluster/namespace/destination * * @return */ public String getLookupName() { return String.format("%s/%s/%s/%s/%s", domain, property, cluster, namespacePortion, getEncodedLocalName()); }
@Override public CompletableFuture<Void> createPartitionedTopicAsync(String destination, int numPartitions) { checkArgument(numPartitions > 1, "Number of partitions should be more than 1"); DestinationName ds = validateTopic(destination); return asyncPutRequest( persistentTopics.path(ds.getNamespace()).path(ds.getEncodedLocalName()).path("partitions"), Entity.entity(numPartitions, MediaType.APPLICATION_JSON)); }
@Override public CompletableFuture<Void> updatePartitionedTopicAsync(String destination, int numPartitions) { checkArgument(numPartitions > 1, "Number of partitions must be more than 1"); DestinationName ds = validateTopic(destination); return asyncPostRequest( persistentTopics.path(ds.getNamespace()).path(ds.getEncodedLocalName()).path("partitions"), Entity.entity(numPartitions, MediaType.APPLICATION_JSON)); }
@Override public CompletableFuture<Void> resetCursorAsync(String destination, String subName, long timestamp) { DestinationName ds = validateTopic(destination); String encodedSubName = Codec.encode(subName); return asyncPostRequest( persistentTopics.path(ds.getNamespace()).path(ds.getEncodedLocalName()).path("subscription") .path(encodedSubName).path("resetcursor").path(String.valueOf(timestamp)), Entity.entity("", MediaType.APPLICATION_JSON)); }
@Override public CompletableFuture<Void> expireMessagesForAllSubscriptionsAsync(String destination, long expireTimeInSeconds) { DestinationName ds = validateTopic(destination); return asyncPostRequest( persistentTopics.path(ds.getNamespace()).path(ds.getEncodedLocalName()).path("all_subscription") .path("expireMessages").path(String.valueOf(expireTimeInSeconds)), Entity.entity("", MediaType.APPLICATION_JSON)); }
@Override public CompletableFuture<Void> skipMessagesAsync(String destination, String subName, long numMessages) { DestinationName ds = validateTopic(destination); String encodedSubName = Codec.encode(subName); return asyncPostRequest( persistentTopics.path(ds.getNamespace()).path(ds.getEncodedLocalName()).path("subscription") .path(encodedSubName).path("skip").path(String.valueOf(numMessages)), Entity.entity("", MediaType.APPLICATION_JSON)); }
@Override public CompletableFuture<Void> expireMessagesAsync(String destination, String subName, long expireTimeInSeconds) { DestinationName ds = validateTopic(destination); String encodedSubName = Codec.encode(subName); return asyncPostRequest( persistentTopics.path(ds.getNamespace()).path(ds.getEncodedLocalName()).path("subscription") .path(encodedSubName).path("expireMessages").path(String.valueOf(expireTimeInSeconds)), Entity.entity("", MediaType.APPLICATION_JSON)); }
@Override public void resetCursor(String destination, String subName, long timestamp) throws PulsarAdminException { try { DestinationName ds = validateTopic(destination); String encodedSubName = Codec.encode(subName); request( persistentTopics.path(ds.getNamespace()).path(ds.getEncodedLocalName()).path("subscription") .path(encodedSubName).path("resetcursor").path(String.valueOf(timestamp))).post( Entity.entity("", MediaType.APPLICATION_JSON), ErrorData.class); } catch (Exception e) { throw getApiException(e); } }
@Override public CompletableFuture<Void> skipAllMessagesAsync(String destination, String subName) { DestinationName ds = validateTopic(destination); String encodedSubName = Codec.encode(subName); return asyncPostRequest( persistentTopics.path(ds.getNamespace()).path(ds.getEncodedLocalName()).path("subscription") .path(encodedSubName).path("skip_all"), Entity.entity("", MediaType.APPLICATION_JSON)); }
@Override public CompletableFuture<Void> deleteSubscriptionAsync(String destination, String subName) { DestinationName ds = validateTopic(destination); String encodedSubName = Codec.encode(subName); return asyncDeleteRequest(persistentTopics.path(ds.getNamespace()).path(ds.getEncodedLocalName()) .path("subscription").path(encodedSubName)); }
@Override public CompletableFuture<Void> deletePartitionedTopicAsync(String destination) { DestinationName ds = validateTopic(destination); return asyncDeleteRequest(persistentTopics.path(ds.getNamespace()).path(ds.getEncodedLocalName()) .path("partitions")); }
@Override public CompletableFuture<Void> deleteAsync(String destination) { DestinationName ds = validateTopic(destination); return asyncDeleteRequest(persistentTopics.path(ds.getNamespace()).path(ds.getEncodedLocalName())); }
@Override public CompletableFuture<PersistentTopicStats> getStatsAsync(String destination) { DestinationName ds = validateTopic(destination); final CompletableFuture<PersistentTopicStats> future = new CompletableFuture<>(); asyncGetRequest(persistentTopics.path(ds.getNamespace()).path(ds.getEncodedLocalName()).path("stats"), new InvocationCallback<PersistentTopicStats>() { @Override public void completed(PersistentTopicStats response) { future.complete(response); } @Override public void failed(Throwable throwable) { future.completeExceptionally(getApiException(throwable.getCause())); } }); return future; }
@Override public CompletableFuture<PartitionedTopicMetadata> getPartitionedTopicMetadataAsync(String destination) { DestinationName ds = validateTopic(destination); final CompletableFuture<PartitionedTopicMetadata> future = new CompletableFuture<>(); asyncGetRequest(persistentTopics.path(ds.getNamespace()).path(ds.getEncodedLocalName()).path("partitions"), new InvocationCallback<PartitionedTopicMetadata>() { @Override public void completed(PartitionedTopicMetadata response) { future.complete(response); } @Override public void failed(Throwable throwable) { future.completeExceptionally(getApiException(throwable.getCause())); } }); return future; }
@Override public CompletableFuture<List<String>> getSubscriptionsAsync(String destination) { DestinationName ds = validateTopic(destination); final CompletableFuture<List<String>> future = new CompletableFuture<>(); asyncGetRequest(persistentTopics.path(ds.getNamespace()).path(ds.getEncodedLocalName()).path("subscriptions"), new InvocationCallback<List<String>>() { @Override public void completed(List<String> response) { future.complete(response); } @Override public void failed(Throwable throwable) { future.completeExceptionally(getApiException(throwable.getCause())); } }); return future; }
@Override public CompletableFuture<PersistentTopicInternalStats> getInternalStatsAsync(String destination) { DestinationName ds = validateTopic(destination); final CompletableFuture<PersistentTopicInternalStats> future = new CompletableFuture<>(); asyncGetRequest(persistentTopics.path(ds.getNamespace()).path(ds.getEncodedLocalName()).path("internalStats"), new InvocationCallback<PersistentTopicInternalStats>() { @Override public void completed(PersistentTopicInternalStats response) { future.complete(response); } @Override public void failed(Throwable throwable) { future.completeExceptionally(getApiException(throwable.getCause())); } }); return future; }
@Override public CompletableFuture<JsonObject> getInternalInfoAsync(String destination) { DestinationName ds = validateTopic(destination); final CompletableFuture<JsonObject> future = new CompletableFuture<>(); asyncGetRequest(persistentTopics.path(ds.getNamespace()).path(ds.getEncodedLocalName()).path("internal-info"), new InvocationCallback<String>() { @Override public void completed(String response) { JsonObject json = new Gson().fromJson(response, JsonObject.class); future.complete(json); } @Override public void failed(Throwable throwable) { future.completeExceptionally(getApiException(throwable.getCause())); } }); return future; }
@Override public CompletableFuture<PartitionedTopicStats> getPartitionedStatsAsync(String destination, boolean perPartition) { DestinationName ds = validateTopic(destination); final CompletableFuture<PartitionedTopicStats> future = new CompletableFuture<>(); asyncGetRequest( persistentTopics.path(ds.getNamespace()).path(ds.getEncodedLocalName()).path("partitioned-stats"), new InvocationCallback<PartitionedTopicStats>() { @Override public void completed(PartitionedTopicStats response) { if (!perPartition) { response.partitions.clear(); } future.complete(response); } @Override public void failed(Throwable throwable) { future.completeExceptionally(getApiException(throwable.getCause())); } }); return future; }
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; }