private void put(DestinationName destinationName, PendingBookieOpsStats bookieOpsStats) { String namespace = destinationName.getNamespace(); if (!nsBookieClientStatsMap.containsKey(namespace)) { Map<String, PendingBookieOpsStats> destBookieClientStatsMap = Maps.newTreeMap(); destBookieClientStatsMap.put(destinationName.toString(), bookieOpsStats); nsBookieClientStatsMap.put(namespace, destBookieClientStatsMap); } else { nsBookieClientStatsMap.get(namespace).put(destinationName.toString(), bookieOpsStats); } } }
@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> 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> 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> 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> deletePartitionedTopicAsync(String destination) { DestinationName ds = validateTopic(destination); return asyncDeleteRequest(persistentTopics.path(ds.getNamespace()).path(ds.getEncodedLocalName()) .path("partitions")); }
@Override public void grantPermission(String destination, String role, Set<AuthAction> actions) throws PulsarAdminException { try { DestinationName ds = DestinationName.get(destination); request(persistentTopics.path(ds.getNamespace()).path(ds.getLocalName()).path("permissions").path(role)) .post(Entity.entity(actions, 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 Map<String, Set<AuthAction>> getPermissions(String destination) throws PulsarAdminException { try { DestinationName ds = DestinationName.get(destination); return request(persistentTopics.path(ds.getNamespace()).path(ds.getLocalName()).path("permissions")).get( new GenericType<Map<String, Set<AuthAction>>>() { }); } catch (Exception e) { throw getApiException(e); } }
@Override public CompletableFuture<Void> deleteAsync(String destination) { DestinationName ds = validateTopic(destination); return asyncDeleteRequest(persistentTopics.path(ds.getNamespace()).path(ds.getEncodedLocalName())); }
@Override public void revokePermissions(String destination, String role) throws PulsarAdminException { try { DestinationName ds = DestinationName.get(destination); request(persistentTopics.path(ds.getNamespace()).path(ds.getLocalName()).path("permissions").path(role)) .delete(ErrorData.class); } catch (Exception e) { throw getApiException(e); } }
void checkTopicNsOwnership(final String topic) throws RuntimeException { DestinationName destination = DestinationName.get(topic); boolean ownedByThisInstance; try { ownedByThisInstance = pulsar.getNamespaceService().isServiceUnitOwned(destination); } catch (Exception e) { log.debug(String.format("Failed to check the ownership of the destination: %s", destination), e); throw new RuntimeException(new ServerMetadataException(e)); } if (!ownedByThisInstance) { String msg = String.format("Namespace not served by this instance. Please redo the lookup. " + "Request is denied: namespace=%s", destination.getNamespace()); log.warn(msg); throw new RuntimeException(new ServiceUnitNotReadyException(msg)); } }
/** * * @param topic * needing quota enforcement check * @return determine if quota enforcement needs to be done for topic */ public boolean isBacklogExceeded(PersistentTopic topic) { DestinationName destination = DestinationName.get(topic.getName()); long backlogQuotaLimitInBytes = getBacklogQuotaManager().getBacklogQuotaLimit(destination.getNamespace()); if (log.isDebugEnabled()) { log.debug("[{}] - backlog quota limit = [{}]", topic.getName(), backlogQuotaLimitInBytes); } // check if backlog exceeded quota long storageSize = topic.getBacklogSize(); if (log.isDebugEnabled()) { log.debug("[{}] Storage size = [{}], limit [{}]", topic.getName(), storageSize, backlogQuotaLimitInBytes); } return (storageSize >= backlogQuotaLimitInBytes); }
/** * * @return Backlog quota for topic */ @Override public BacklogQuota getBacklogQuota() { DestinationName destination = DestinationName.get(this.getName()); String namespace = destination.getNamespace(); String policyPath = AdminResource.path("policies", namespace); BacklogQuota backlogQuota = brokerService.getBacklogQuotaManager().getBacklogQuota(namespace, policyPath); return backlogQuota; }
@Override public void checkMessageExpiry() { DestinationName name = DestinationName.get(topic); Policies policies; try { policies = brokerService.pulsar().getConfigurationCache().policiesCache() .get(AdminResource.path("policies", name.getNamespace())) .orElseThrow(() -> new KeeperException.NoNodeException()); if (policies.message_ttl_in_seconds != 0) { subscriptions.forEach((subName, sub) -> sub.expireMessages(policies.message_ttl_in_seconds)); replicators.forEach((region, replicator) -> replicator.expireMessages(policies.message_ttl_in_seconds)); } } catch (Exception e) { if (log.isDebugEnabled()) { log.debug("[{}] Error getting policies", topic); } } }
private void addTopicToStatsMaps(DestinationName topicName, PersistentTopic topic) { try { NamespaceBundle namespaceBundle = pulsar.getNamespaceService().getBundle(topicName); if (namespaceBundle != null) { synchronized (multiLayerTopicsMap) { String serviceUnit = namespaceBundle.toString(); multiLayerTopicsMap // .computeIfAbsent(topicName.getNamespace(), k -> new ConcurrentOpenHashMap<>()) // .computeIfAbsent(serviceUnit, k -> new ConcurrentOpenHashMap<>()) // .put(topicName.toString(), topic); } } invalidateOfflineTopicStatCache(topicName); } catch (Exception e) { log.warn("Got exception when retrieving bundle name during create persistent topic", e); } }