/** * Extract the namespace portion out of a completeTopicName name. * * Works both with old & new convention. * * @return the namespace */ public String getNamespace() { return namespaceName.toString(); }
this.localName = parts.get(2); this.partitionIndex = getPartitionIndex(completeTopicName); this.namespaceName = NamespaceName.get(tenant, namespacePortion); } else if (parts.size() == 4) { this.localName = parts.get(3); this.partitionIndex = getPartitionIndex(completeTopicName); this.namespaceName = NamespaceName.get(tenant, cluster, namespacePortion); } else { throw new IllegalArgumentException("Invalid topic name: " + completeTopicName);
@Override public CompletableFuture<List<String>> getTopicsUnderNamespace(NamespaceName namespace, Mode mode) { CompletableFuture<List<String>> future = new CompletableFuture<>(); String format = namespace.isV2() ? "admin/v2/namespaces/%s/topics?mode=%s" : "admin/namespaces/%s/destinations?mode=%s"; httpClient .get(String.format(format, namespace, mode.toString()), String[].class) .thenAccept(topics -> { List<String> result = Lists.newArrayList(); // do not keep partition part of topic name Arrays.asList(topics).forEach(topic -> { String filtered = TopicName.get(topic).getPartitionedTopicName(); if (!result.contains(filtered)) { result.add(filtered); } }); future.complete(result);}) .exceptionally(ex -> { log.warn("Failed to getTopicsUnderNamespace namespace: {}.", namespace, ex.getMessage()); future.completeExceptionally(ex); return null; }); return future; }
public static NamespaceName get(String tenant, String cluster, String namespace) { validateNamespaceName(tenant, cluster, namespace); return get(tenant + '/' + cluster + '/' + namespace); }
public JsonObject getBrokerResourceAvailability(String namespace) throws PulsarAdminException { try { NamespaceName ns = NamespaceName.get(namespace); WebTarget admin = ns.isV2() ? adminV2BrokerStats : adminBrokerStats; String json = request(admin.path("/broker-resource-availability").path(ns.toString())).get(String.class); return new Gson().fromJson(json, JsonObject.class); } catch (Exception e) { throw getApiException(e); } } }
private WebTarget namespacePath(String domain, NamespaceName namespace, String... parts) { final WebTarget base = namespace.isV2() ? adminV2Topics : adminTopics; WebTarget namespacePath = base.path(domain).path(namespace.toString()); namespacePath = WebTargets.addParts(namespacePath, parts); return namespacePath; }
protected void internalCreateNamespace(Policies policies) { validatePoliciesReadOnlyAccess(); validateAdminAccessForTenant(namespaceName.getTenant()); validatePolicies(namespaceName, policies); try { policiesCache().invalidate(path(POLICIES, namespaceName.toString())); zkCreateOptimistic(path(POLICIES, namespaceName.toString()), jsonMapper().writeValueAsBytes(policies)); log.info("[{}] Created namespace {}", clientAppId(), namespaceName); } catch (KeeperException.NodeExistsException e) { log.warn("[{}] Failed to create namespace {} - already exists", clientAppId(), namespaceName); throw new RestException(Status.CONFLICT, "Namespace already exists"); } catch (Exception e) { log.error("[{}] Failed to create namespace {}", clientAppId(), namespaceName, e); throw new RestException(e); } }
@Override public List<String> getTopics(String namespace) throws PulsarAdminException { try { NamespaceName ns = NamespaceName.get(namespace); String action = ns.isV2() ? "topics" : "destinations"; WebTarget path = namespacePath(ns, action); return request(path).get(new GenericType<List<String>>() { }); } catch (Exception e) { throw getApiException(e); } }
@SuppressWarnings("deprecation") protected void internalUnloadNamespace() { log.info("[{}] Unloading namespace {}", clientAppId()); validateSuperUserAccess(); if (namespaceName.isGlobal()) { // check cluster ownership for a given global namespace: redirect if peer-cluster owns it validateGlobalNamespaceOwnership(namespaceName); } else { validateClusterOwnership(namespaceName.getCluster()); validateClusterForTenant(namespaceName.getTenant(), namespaceName.getCluster()); } Policies policies = getNamespacePolicies(namespaceName); List<String> boundaries = policies.bundles.getBoundaries(); for (int i = 0; i < boundaries.size() - 1; i++) { String bundle = String.format("%s_%s", boundaries.get(i), boundaries.get(i + 1)); try { pulsar().getAdminClient().namespaces().unloadNamespaceBundle(namespaceName.toString(), bundle); } catch (PulsarServerException | PulsarAdminException e) { log.error(String.format("[%s] Failed to unload namespace %s", clientAppId(), namespaceName), e); throw new RestException(e); } } log.info("[{}] Successfully unloaded all the bundles in namespace {}/{}/{}", clientAppId(), namespaceName); }
@Override public boolean includes(TopicName topicName) { return this.equals(topicName.getNamespaceObject()); }
@Override public NamespaceName load(String name) throws Exception { return new NamespaceName(name); } });
protected void internalRevokePermissionsOnNamespace(String role) { validateAdminAccessForTenant(namespaceName.getTenant()); validatePoliciesReadOnlyAccess(); try { Stat nodeStat = new Stat(); byte[] content = globalZk().getData(path(POLICIES, namespaceName.toString()), null, nodeStat); Policies policies = jsonMapper().readValue(content, Policies.class); policies.auth_policies.namespace_auth.remove(role); // Write back the new policies into zookeeper globalZk().setData(path(POLICIES, namespaceName.toString()), jsonMapper().writeValueAsBytes(policies), nodeStat.getVersion()); policiesCache().invalidate(path(POLICIES, namespaceName.toString())); log.info("[{}] Successfully revoked access for role {} - namespace {}", clientAppId(), role, namespaceName); } catch (KeeperException.NoNodeException e) { log.warn("[{}] Failed to revoke permissions for namespace {}: does not exist", clientAppId(), namespaceName); throw new RestException(Status.NOT_FOUND, "Namespace does not exist"); } catch (KeeperException.BadVersionException e) { log.warn("[{}] Failed to revoke permissions on namespace {}: concurrent modification", clientAppId(), namespaceName); throw new RestException(Status.CONFLICT, "Concurrent modification"); } catch (Exception e) { log.error("[{}] Failed to revoke permissions on namespace {}", clientAppId(), namespaceName, e); throw new RestException(e); } }
@Override public void createNamespace(String namespace, Policies policies) throws PulsarAdminException { NamespaceName ns = NamespaceName.get(namespace); checkArgument(ns.isV2(), "Create namespace with policies is only supported on newer namespaces"); try { WebTarget path = namespacePath(ns); // For V2 API we pass full Policy class instance request(path).put(Entity.entity(policies, MediaType.APPLICATION_JSON), ErrorData.class); } catch (Exception e) { throw getApiException(e); } }
public static NamespaceName get(String tenant, String namespace) { validateNamespaceName(tenant, namespace); return get(tenant + '/' + namespace); }
@Override public boolean includes(TopicName topicName) { return this.equals(topicName.getNamespaceObject()); }
@Override public NamespaceName load(String name) throws Exception { return new NamespaceName(name); } });
private boolean namespaceMatches(NamespaceName namespace, NamespaceIsolationData nsPolicyData) { for (String nsnameRegex : nsPolicyData.namespaces) { if (namespace.toString().matches(nsnameRegex)) { return true; } } return false; }
public NamespaceBundle getBundle(String namespace, String bundleRange) { checkArgument(bundleRange.contains("_"), "Invalid bundle range"); String[] boundaries = bundleRange.split("_"); Long lowerEndpoint = Long.decode(boundaries[0]); Long upperEndpoint = Long.decode(boundaries[1]); Range<Long> hashRange = Range.range(lowerEndpoint, BoundType.CLOSED, upperEndpoint, (upperEndpoint.equals(NamespaceBundles.FULL_UPPER_BOUND)) ? BoundType.CLOSED : BoundType.OPEN); return getBundle(NamespaceName.get(namespace), hashRange); }