@Override public List<String> getNamespaceReplicationClusters(String namespace) throws PulsarAdminException { try { NamespaceName ns = new NamespaceName(namespace); return request( namespaces.path(ns.getProperty()).path(ns.getCluster()).path(ns.getLocalName()).path("replication")) .get(new GenericType<List<String>>() { }); } catch (Exception e) { throw getApiException(e); } }
@Override public boolean includes(DestinationName dn) { return this.equals(dn.getNamespaceObject()); } }
/** * Extract the namespace portion out of a destination name. * * Works both with old & new convention. * * @return the namespace */ public String getNamespace() { return namespaceName.toString(); }
@POST @Path("/{property}/{cluster}/{namespace}/{bundle}/unsubscribe/{subscription}") @ApiOperation(value = "Unsubscribes the given subscription on all destinations on a namespace bundle.") @ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Namespace does not exist") }) public void unsubscribeNamespaceBundle(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("subscription") String subscription, @PathParam("bundle") String bundleRange, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) { validateAdminAccessOnProperty(property); Policies policies = getNamespacePolicies(property, cluster, namespace); if (!cluster.equals(Namespaces.GLOBAL_CLUSTER)) { validateClusterOwnership(cluster); validateClusterForProperty(property, cluster); } NamespaceName nsName = new NamespaceName(property, cluster, namespace); validateNamespaceBundleOwnership(nsName, policies.bundles, bundleRange, authoritative, true); unsubscribe(nsName, bundleRange, subscription); log.info("[{}] Successfully unsubscribed {} on namespace bundle {}/{}", clientAppId(), subscription, nsName.toString(), bundleRange); }
public static final NamespaceBundle suBundleFromPath(String path, NamespaceBundleFactory factory) { String[] parts = path.split("/"); checkArgument(parts.length > 2); checkArgument(parts[1].equals("namespace")); checkArgument(parts.length > 5); Range<Long> range = getHashRange(parts[5]); return factory.getBundle(new NamespaceName(parts[2], parts[3], parts[4]), range); }
if (namespace.isGlobal()) { String localCluster = pulsarService.getConfiguration().getClusterName(); String path = AdminResource.path("policies", namespace.getProperty(), namespace.getCluster(), namespace.getLocalName()); String msg = String.format( "Global namespace does not have any clusters configured : local_cluster=%s ns=%s", localCluster, namespace.toString()); log.warn(msg); validationFuture.completeExceptionally(new RestException(Status.PRECONDITION_FAILED, msg)); String msg = String.format( "Global namespace missing local cluster name in replication list : local_cluster=%s ns=%s repl_clusters=%s", localCluster, namespace.toString(), policies.replication_clusters); String msg = String.format("Policies not found for %s namespace", namespace.toString()); log.error(msg); validationFuture.completeExceptionally(new RestException(Status.NOT_FOUND, msg));
long topicLoadStart = System.nanoTime(); for (String topic : getNamespaceService().getListOfDestinations(nsName.getProperty(), nsName.getCluster(), nsName.getLocalName())) { try { DestinationName dn = DestinationName.get(topic);
@Override public void onUpdate(String path, Policies data, Stat stat) { final NamespaceName namespace = new NamespaceName(NamespaceBundleFactory.getNamespaceFromPoliciesPath(path)); log.info("Updated {}", path); topics.forEach((name, topicFuture) -> { if (namespace.includes(DestinationName.get(name))) { // If the topic is already created, immediately apply the updated policies, otherwise once the topic is // created it'll apply the policies update topicFuture.thenAccept(topic -> { if (log.isDebugEnabled()) { log.debug("Notifying topic that policies have changed: {}", name); } topic.onPoliciesUpdate(data); }); } }); }
this.partitionIndex = getPartitionIndex(destination); NamespaceName.validateNamespaceName(property, cluster, namespacePortion); if (checkNotNull(localName).isEmpty()) { throw new IllegalArgumentException("Invalid destination name: " + destination); throw new IllegalArgumentException("Invalid destination name: " + destination, e); namespaceName = new NamespaceName(property, cluster, namespacePortion);
public String getPersistentTopicName(String localTopic) { return getDestinationName(DestinationDomain.persistent, localTopic); }
@POST @Path("/{property}/{cluster}/{namespace}/{bundle}/clearBacklog") @ApiOperation(value = "Clear backlog for all destinations on a namespace bundle.") @ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Namespace does not exist") }) public void clearNamespaceBundleBacklog(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("bundle") String bundleRange, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) { validateAdminAccessOnProperty(property); Policies policies = getNamespacePolicies(property, cluster, namespace); if (!cluster.equals(Namespaces.GLOBAL_CLUSTER)) { validateClusterOwnership(cluster); validateClusterForProperty(property, cluster); } NamespaceName nsName = new NamespaceName(property, cluster, namespace); validateNamespaceBundleOwnership(nsName, policies.bundles, bundleRange, authoritative, true); clearBacklog(nsName, bundleRange, null); log.info("[{}] Successfully cleared backlog on namespace bundle {}/{}", clientAppId(), nsName.toString(), bundleRange); }
protected void validateBundleOwnership(String property, String cluster, String namespace, boolean authoritative, boolean readOnly, NamespaceBundle bundle) { NamespaceName fqnn = new NamespaceName(property, cluster, namespace); try { validateBundleOwnership(bundle, authoritative, readOnly); } catch (WebApplicationException wae) { // propagate already wrapped-up WebApplicationExceptions throw wae; } catch (Exception oe) { log.debug(String.format("Failed to find owner for namespace %s", fqnn), oe); throw new RestException(oe); } }
policies = pulsar .getConfigurationCache().policiesCache().get(AdminResource.path("policies", namespace.getProperty(), namespace.getCluster(), namespace.getLocalName())) .orElse(null); } catch (Throwable t) {
@Override public PersistencePolicies getPersistence(String namespace) throws PulsarAdminException { try { NamespaceName ns = new NamespaceName(namespace); return request( namespaces.path(ns.getProperty()).path(ns.getCluster()).path(ns.getLocalName()).path("persistence")) .get(PersistencePolicies.class); } catch (Exception e) { throw getApiException(e); } }
@POST @Path("/{property}/{cluster}/{namespace}/{bundle}/clearBacklog/{subscription}") @ApiOperation(value = "Clear backlog for a given subscription on all destinations on a namespace bundle.") @ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Namespace does not exist") }) public void clearNamespaceBundleBacklogForSubscription(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("subscription") String subscription, @PathParam("bundle") String bundleRange, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) { validateAdminAccessOnProperty(property); Policies policies = getNamespacePolicies(property, cluster, namespace); if (!cluster.equals(Namespaces.GLOBAL_CLUSTER)) { validateClusterOwnership(cluster); validateClusterForProperty(property, cluster); } NamespaceName nsName = new NamespaceName(property, cluster, namespace); validateNamespaceBundleOwnership(nsName, policies.bundles, bundleRange, authoritative, true); clearBacklog(nsName, bundleRange, subscription); log.info("[{}] Successfully cleared backlog for subscription {} on namespace bundle {}/{}", clientAppId(), subscription, nsName.toString(), bundleRange); }
@Override public void onUpdate(String path, LocalPolicies data, Stat stat) { final NamespaceName namespace = new NamespaceName(getNamespaceFromPoliciesPath(path)); try { LOG.info("Policy updated for namespace {}, refreshing the bundle cache.", namespace); // invalidate the bundle cache to fetch new bundle data from the policies bundlesCache.synchronous().invalidate(namespace); } catch (Exception e) { LOG.error("Failed to update the policy change for ns {}", namespace, e); } }
private boolean namespaceMatches(NamespaceName namespace, NamespaceIsolationData nsPolicyData) { for (String nsnameRegex : nsPolicyData.namespaces) { if (namespace.toString().matches(nsnameRegex)) { return true; } } return false; }
@Override public boolean includes(DestinationName dn) { if (!this.nsname.equals(dn.getNamespaceObject())) { return false; } return this.keyRange.contains(factory.getLongHashCode(dn.toString())); }
@Override public RetentionPolicies getRetention(String namespace) throws PulsarAdminException { try { NamespaceName ns = new NamespaceName(namespace); return request( namespaces.path(ns.getProperty()).path(ns.getCluster()).path(ns.getLocalName()).path("retention")) .get(RetentionPolicies.class); } catch (Exception e) { throw getApiException(e); } }
@PUT @Path("/{property}/{cluster}/{namespace}/{bundle}/split") @ApiOperation(value = "Split a namespace bundle") @ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission") }) public void splitNamespaceBundle(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("bundle") String bundleRange, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) { log.info("[{}] Split namespace bundle {}/{}/{}/{}", clientAppId(), property, cluster, namespace, bundleRange); validateSuperUserAccess(); Policies policies = getNamespacePolicies(property, cluster, namespace); if (!cluster.equals(Namespaces.GLOBAL_CLUSTER)) { validateClusterOwnership(cluster); validateClusterForProperty(property, cluster); } NamespaceName fqnn = new NamespaceName(property, cluster, namespace); validatePoliciesReadOnlyAccess(); NamespaceBundle nsBundle = validateNamespaceBundleOwnership(fqnn, policies.bundles, bundleRange, authoritative, true); try { pulsar().getNamespaceService().splitAndOwnBundle(nsBundle).get(); log.info("[{}] Successfully split namespace bundle {}", clientAppId(), nsBundle.toString()); } catch (Exception e) { log.error("[{}] Failed to split namespace bundle {}/{}", clientAppId(), fqnn.toString(), bundleRange, e); throw new RestException(e); } }