Search in sources :

Example 31 with NamespaceBundle

use of org.apache.pulsar.common.naming.NamespaceBundle in project incubator-pulsar by apache.

the class NamespacesBase method internalSplitNamespaceBundle.

@SuppressWarnings("deprecation")
protected void internalSplitNamespaceBundle(String bundleRange, boolean authoritative, boolean unload) {
    log.info("[{}] Split namespace bundle {}/{}", clientAppId(), namespaceName, bundleRange);
    validateSuperUserAccess();
    Policies policies = getNamespacePolicies(namespaceName);
    if (namespaceName.isGlobal()) {
        // check cluster ownership for a given global namespace: redirect if peer-cluster owns it
        validateGlobalNamespaceOwnership(namespaceName);
    } else {
        validateClusterOwnership(namespaceName.getCluster());
        validateClusterForProperty(namespaceName.getProperty(), namespaceName.getCluster());
    }
    validatePoliciesReadOnlyAccess();
    NamespaceBundle nsBundle = validateNamespaceBundleOwnership(namespaceName, policies.bundles, bundleRange, authoritative, true);
    try {
        pulsar().getNamespaceService().splitAndOwnBundle(nsBundle, unload).get();
        log.info("[{}] Successfully split namespace bundle {}", clientAppId(), nsBundle.toString());
    } catch (IllegalArgumentException e) {
        log.error("[{}] Failed to split namespace bundle {}/{} due to {}", clientAppId(), namespaceName, bundleRange, e.getMessage());
        throw new RestException(Status.PRECONDITION_FAILED, "Split bundle failed due to invalid request");
    } catch (Exception e) {
        log.error("[{}] Failed to split namespace bundle {}/{}", clientAppId(), namespaceName, bundleRange, e);
        throw new RestException(e);
    }
}
Also used : NamespaceBundle(org.apache.pulsar.common.naming.NamespaceBundle) PersistencePolicies(org.apache.pulsar.common.policies.data.PersistencePolicies) RetentionPolicies(org.apache.pulsar.common.policies.data.RetentionPolicies) Policies(org.apache.pulsar.common.policies.data.Policies) RestException(org.apache.pulsar.broker.web.RestException) RestException(org.apache.pulsar.broker.web.RestException) SubscriptionBusyException(org.apache.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException) WebApplicationException(javax.ws.rs.WebApplicationException) KeeperException(org.apache.zookeeper.KeeperException) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) ExecutionException(java.util.concurrent.ExecutionException) PulsarServerException(org.apache.pulsar.broker.PulsarServerException)

Example 32 with NamespaceBundle

use of org.apache.pulsar.common.naming.NamespaceBundle in project incubator-pulsar by apache.

the class NamespacesBase method internalDeleteNamespace.

@SuppressWarnings("deprecation")
protected void internalDeleteNamespace(boolean authoritative) {
    validateAdminAccessOnProperty(namespaceName.getProperty());
    validatePoliciesReadOnlyAccess();
    // ensure that non-global namespace is directed to the correct cluster
    if (!namespaceName.isGlobal()) {
        validateClusterOwnership(namespaceName.getCluster());
    }
    Entry<Policies, Stat> policiesNode = null;
    Policies policies = null;
    // ensure the local cluster is the only cluster for the global namespace configuration
    try {
        policiesNode = policiesCache().getWithStat(path(POLICIES, namespaceName.toString())).orElseThrow(() -> new RestException(Status.NOT_FOUND, "Namespace " + namespaceName + " does not exist."));
        policies = policiesNode.getKey();
        if (namespaceName.isGlobal()) {
            if (policies.replication_clusters.size() > 1) {
                // There are still more than one clusters configured for the global namespace
                throw new RestException(Status.PRECONDITION_FAILED, "Cannot delete the global namespace " + namespaceName + ". There are still more than one replication clusters configured.");
            }
            if (policies.replication_clusters.size() == 1 && !policies.replication_clusters.contains(config().getClusterName())) {
                // the only replication cluster is other cluster, redirect
                String replCluster = policies.replication_clusters.get(0);
                ClusterData replClusterData = clustersCache().get(AdminResource.path("clusters", replCluster)).orElseThrow(() -> new RestException(Status.NOT_FOUND, "Cluster " + replCluster + " does not exist"));
                URL replClusterUrl;
                if (!config().isTlsEnabled() || !isRequestHttps()) {
                    replClusterUrl = new URL(replClusterData.getServiceUrl());
                } else if (StringUtils.isNotBlank(replClusterData.getServiceUrlTls())) {
                    replClusterUrl = new URL(replClusterData.getServiceUrlTls());
                } else {
                    throw new RestException(Status.PRECONDITION_FAILED, "The replication cluster does not provide TLS encrypted service");
                }
                URI redirect = UriBuilder.fromUri(uri.getRequestUri()).host(replClusterUrl.getHost()).port(replClusterUrl.getPort()).replaceQueryParam("authoritative", false).build();
                if (log.isDebugEnabled()) {
                    log.debug("[{}] Redirecting the rest call to {}: cluster={}", clientAppId(), redirect, replCluster);
                }
                throw new WebApplicationException(Response.temporaryRedirect(redirect).build());
            }
        }
    } catch (WebApplicationException wae) {
        throw wae;
    } catch (Exception e) {
        throw new RestException(e);
    }
    boolean isEmpty;
    try {
        isEmpty = pulsar().getNamespaceService().getListOfTopics(namespaceName).isEmpty();
    } catch (Exception e) {
        throw new RestException(e);
    }
    if (!isEmpty) {
        log.debug("Found topics on namespace {}", namespaceName);
        throw new RestException(Status.CONFLICT, "Cannot delete non empty namespace");
    }
    // set the policies to deleted so that somebody else cannot acquire this namespace
    try {
        policies.deleted = true;
        globalZk().setData(path(POLICIES, namespaceName.toString()), jsonMapper().writeValueAsBytes(policies), policiesNode.getValue().getVersion());
        policiesCache().invalidate(path(POLICIES, namespaceName.toString()));
    } catch (Exception e) {
        log.error("[{}] Failed to delete namespace on global ZK {}", clientAppId(), namespaceName, e);
        throw new RestException(e);
    }
    // remove from owned namespace map and ephemeral node from ZK
    try {
        NamespaceBundles bundles = pulsar().getNamespaceService().getNamespaceBundleFactory().getBundles(namespaceName);
        for (NamespaceBundle bundle : bundles.getBundles()) {
            // check if the bundle is owned by any broker, if not then we do not need to delete the bundle
            if (pulsar().getNamespaceService().getOwner(bundle).isPresent()) {
                pulsar().getAdminClient().namespaces().deleteNamespaceBundle(namespaceName.toString(), bundle.getBundleRange());
            }
        }
        // we have successfully removed all the ownership for the namespace, the policies znode can be deleted now
        final String globalZkPolicyPath = path(POLICIES, namespaceName.toString());
        final String lcaolZkPolicyPath = joinPath(LOCAL_POLICIES_ROOT, namespaceName.toString());
        globalZk().delete(globalZkPolicyPath, -1);
        localZk().delete(lcaolZkPolicyPath, -1);
        policiesCache().invalidate(globalZkPolicyPath);
        localCacheService().policiesCache().invalidate(lcaolZkPolicyPath);
    } catch (PulsarAdminException cae) {
        throw new RestException(cae);
    } catch (Exception e) {
        log.error("[{}] Failed to remove owned namespace {}", clientAppId(), namespaceName, e);
    // avoid throwing exception in case of the second failure
    }
}
Also used : NamespaceBundle(org.apache.pulsar.common.naming.NamespaceBundle) PersistencePolicies(org.apache.pulsar.common.policies.data.PersistencePolicies) RetentionPolicies(org.apache.pulsar.common.policies.data.RetentionPolicies) Policies(org.apache.pulsar.common.policies.data.Policies) WebApplicationException(javax.ws.rs.WebApplicationException) NamespaceBundles(org.apache.pulsar.common.naming.NamespaceBundles) RestException(org.apache.pulsar.broker.web.RestException) URI(java.net.URI) URL(java.net.URL) RestException(org.apache.pulsar.broker.web.RestException) SubscriptionBusyException(org.apache.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException) WebApplicationException(javax.ws.rs.WebApplicationException) KeeperException(org.apache.zookeeper.KeeperException) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) ExecutionException(java.util.concurrent.ExecutionException) PulsarServerException(org.apache.pulsar.broker.PulsarServerException) Stat(org.apache.zookeeper.data.Stat) ClusterData(org.apache.pulsar.common.policies.data.ClusterData) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException)

Example 33 with NamespaceBundle

use of org.apache.pulsar.common.naming.NamespaceBundle in project incubator-pulsar by apache.

the class ResourceQuotasBase method internalGetNamespaceBundleResourceQuota.

@SuppressWarnings("deprecation")
protected ResourceQuota internalGetNamespaceBundleResourceQuota(String bundleRange) {
    validateSuperUserAccess();
    Policies policies = getNamespacePolicies(namespaceName);
    if (!namespaceName.isGlobal()) {
        validateClusterOwnership(namespaceName.getCluster());
        validateClusterForProperty(namespaceName.getProperty(), namespaceName.getCluster());
    }
    NamespaceBundle nsBundle = validateNamespaceBundleRange(namespaceName, policies.bundles, bundleRange);
    try {
        return pulsar().getLocalZkCacheService().getResourceQuotaCache().getQuota(nsBundle);
    } catch (Exception e) {
        log.error("[{}] Failed to get resource quota for namespace bundle {}", clientAppId(), nsBundle.toString());
        throw new RestException(e);
    }
}
Also used : NamespaceBundle(org.apache.pulsar.common.naming.NamespaceBundle) Policies(org.apache.pulsar.common.policies.data.Policies) RestException(org.apache.pulsar.broker.web.RestException) KeeperException(org.apache.zookeeper.KeeperException) RestException(org.apache.pulsar.broker.web.RestException)

Example 34 with NamespaceBundle

use of org.apache.pulsar.common.naming.NamespaceBundle in project incubator-pulsar by apache.

the class ResourceQuotasBase method internalRemoveNamespaceBundleResourceQuota.

@SuppressWarnings("deprecation")
protected void internalRemoveNamespaceBundleResourceQuota(String bundleRange) {
    validateSuperUserAccess();
    validatePoliciesReadOnlyAccess();
    Policies policies = getNamespacePolicies(namespaceName);
    if (!namespaceName.isGlobal()) {
        validateClusterOwnership(namespaceName.getCluster());
        validateClusterForProperty(namespaceName.getProperty(), namespaceName.getCluster());
    }
    NamespaceBundle nsBundle = validateNamespaceBundleRange(namespaceName, policies.bundles, bundleRange);
    try {
        pulsar().getLocalZkCacheService().getResourceQuotaCache().unsetQuota(nsBundle);
        log.info("[{}] Successfully unset resource quota for namespace bundle {}", clientAppId(), nsBundle.toString());
    } catch (KeeperException.NoNodeException e) {
        log.warn("[{}] Failed to unset resource quota for namespace bundle {}: concurrent modification", clientAppId(), nsBundle.toString());
        throw new RestException(Status.CONFLICT, "Cuncurrent modification on namespace bundle quota");
    } catch (Exception e) {
        log.error("[{}] Failed to unset resource quota for namespace bundle {}", clientAppId(), nsBundle.toString());
        throw new RestException(e);
    }
}
Also used : NamespaceBundle(org.apache.pulsar.common.naming.NamespaceBundle) Policies(org.apache.pulsar.common.policies.data.Policies) RestException(org.apache.pulsar.broker.web.RestException) KeeperException(org.apache.zookeeper.KeeperException) KeeperException(org.apache.zookeeper.KeeperException) RestException(org.apache.pulsar.broker.web.RestException)

Example 35 with NamespaceBundle

use of org.apache.pulsar.common.naming.NamespaceBundle in project incubator-pulsar by apache.

the class NonPersistentTopics method getListFromBundle.

@GET
@Path("/{property}/{cluster}/{namespace}/{bundle}")
@ApiOperation(value = "Get the list of non-persistent topics under a namespace bundle.", response = String.class, responseContainer = "List")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Namespace doesn't exist") })
public List<String> getListFromBundle(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("bundle") String bundleRange) {
    log.info("[{}] list of topics on namespace bundle {}/{}/{}/{}", clientAppId(), property, cluster, namespace, bundleRange);
    validateAdminAccessOnProperty(property);
    Policies policies = getNamespacePolicies(property, cluster, namespace);
    if (!cluster.equals(Constants.GLOBAL_CLUSTER)) {
        validateClusterOwnership(cluster);
        validateClusterForProperty(property, cluster);
    } else {
        // check cluster ownership for a given global namespace: redirect if peer-cluster owns it
        validateGlobalNamespaceOwnership(NamespaceName.get(property, cluster, namespace));
    }
    NamespaceName fqnn = NamespaceName.get(property, cluster, namespace);
    if (!isBundleOwnedByAnyBroker(fqnn, policies.bundles, bundleRange)) {
        log.info("[{}] Namespace bundle is not owned by any broker {}/{}/{}/{}", clientAppId(), property, cluster, namespace, bundleRange);
        return null;
    }
    NamespaceBundle nsBundle = validateNamespaceBundleOwnership(fqnn, policies.bundles, bundleRange, true, true);
    try {
        final List<String> topicList = Lists.newArrayList();
        pulsar().getBrokerService().getTopics().forEach((name, topicFuture) -> {
            TopicName topicName = TopicName.get(name);
            if (nsBundle.includes(topicName)) {
                topicList.add(name);
            }
        });
        return topicList;
    } catch (Exception e) {
        log.error("[{}] Failed to unload namespace bundle {}/{}", clientAppId(), fqnn.toString(), bundleRange, e);
        throw new RestException(e);
    }
}
Also used : NamespaceBundle(org.apache.pulsar.common.naming.NamespaceBundle) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) Policies(org.apache.pulsar.common.policies.data.Policies) RestException(org.apache.pulsar.broker.web.RestException) RestException(org.apache.pulsar.broker.web.RestException) KeeperException(org.apache.zookeeper.KeeperException) ExecutionException(java.util.concurrent.ExecutionException) PulsarServerException(org.apache.pulsar.broker.PulsarServerException) TopicName(org.apache.pulsar.common.naming.TopicName) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Aggregations

NamespaceBundle (org.apache.pulsar.common.naming.NamespaceBundle)66 Test (org.testng.annotations.Test)42 NamespaceName (org.apache.pulsar.common.naming.NamespaceName)23 NamespaceBundles (org.apache.pulsar.common.naming.NamespaceBundles)18 TopicName (org.apache.pulsar.common.naming.TopicName)18 KeeperException (org.apache.zookeeper.KeeperException)17 Field (java.lang.reflect.Field)14 RestException (org.apache.pulsar.broker.web.RestException)14 PulsarServerException (org.apache.pulsar.broker.PulsarServerException)13 Policies (org.apache.pulsar.common.policies.data.Policies)13 PulsarAdminException (org.apache.pulsar.client.admin.PulsarAdminException)11 ExecutionException (java.util.concurrent.ExecutionException)10 URL (java.net.URL)9 List (java.util.List)9 CompletableFuture (java.util.concurrent.CompletableFuture)8 URI (java.net.URI)7 AtomicReference (java.util.concurrent.atomic.AtomicReference)7 WebApplicationException (javax.ws.rs.WebApplicationException)7 LoadManager (org.apache.pulsar.broker.loadbalance.LoadManager)7 PersistentTopic (org.apache.pulsar.broker.service.persistent.PersistentTopic)7