use of org.apache.pulsar.common.policies.data.Policies in project incubator-pulsar by apache.
the class NamespacesBase method internalGetRetention.
protected RetentionPolicies internalGetRetention() {
validateAdminAccessOnProperty(namespaceName.getProperty());
Policies policies = getNamespacePolicies(namespaceName);
if (policies.retention_policies == null) {
return new RetentionPolicies(config().getDefaultRetentionTimeInMinutes(), config().getDefaultRetentionSizeInMB());
} else {
return policies.retention_policies;
}
}
use of org.apache.pulsar.common.policies.data.Policies 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
}
}
use of org.apache.pulsar.common.policies.data.Policies in project incubator-pulsar by apache.
the class NamespacesBase method internalSetNamespaceMessageTTL.
protected void internalSetNamespaceMessageTTL(int messageTTL) {
validateAdminAccessOnProperty(namespaceName.getProperty());
validatePoliciesReadOnlyAccess();
if (messageTTL < 0) {
throw new RestException(Status.PRECONDITION_FAILED, "Invalid value for message TTL");
}
Entry<Policies, Stat> policiesNode = null;
try {
// Force to read the data s.t. the watch to the cache content is setup.
policiesNode = policiesCache().getWithStat(path(POLICIES, namespaceName.toString())).orElseThrow(() -> new RestException(Status.NOT_FOUND, "Namespace " + namespaceName + " does not exist"));
policiesNode.getKey().message_ttl_in_seconds = messageTTL;
// Write back the new policies into zookeeper
globalZk().setData(path(POLICIES, namespaceName.toString()), jsonMapper().writeValueAsBytes(policiesNode.getKey()), policiesNode.getValue().getVersion());
policiesCache().invalidate(path(POLICIES, namespaceName.toString()));
log.info("[{}] Successfully updated the message TTL on namespace {}", clientAppId(), namespaceName);
} catch (KeeperException.NoNodeException e) {
log.warn("[{}] Failed to update the message TTL 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 update the message TTL on namespace {} expected policy node version={} : concurrent modification", clientAppId(), namespaceName, policiesNode.getValue().getVersion());
throw new RestException(Status.CONFLICT, "Concurrent modification");
} catch (Exception e) {
log.error("[{}] Failed to update the message TTL on namespace {}", clientAppId(), namespaceName, e);
throw new RestException(e);
}
}
use of org.apache.pulsar.common.policies.data.Policies in project incubator-pulsar by apache.
the class NamespacesBase method internalRevokePermissionsOnNamespace.
protected void internalRevokePermissionsOnNamespace(String role) {
validateAdminAccessOnProperty(namespaceName.getProperty());
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);
}
}
use of org.apache.pulsar.common.policies.data.Policies in project incubator-pulsar by apache.
the class NamespacesBase method internalSetNamespaceReplicationClusters.
protected void internalSetNamespaceReplicationClusters(List<String> clusterIds) {
validateAdminAccessOnProperty(namespaceName.getProperty());
validatePoliciesReadOnlyAccess();
Set<String> replicationClusterSet = Sets.newHashSet(clusterIds);
if (!namespaceName.isGlobal()) {
throw new RestException(Status.PRECONDITION_FAILED, "Cannot set replication on a non-global namespace");
}
if (replicationClusterSet.contains("global")) {
throw new RestException(Status.PRECONDITION_FAILED, "Cannot specify global in the list of replication clusters");
}
Set<String> clusters = clusters();
for (String clusterId : replicationClusterSet) {
if (!clusters.contains(clusterId)) {
throw new RestException(Status.FORBIDDEN, "Invalid cluster id: " + clusterId);
}
validatePeerClusterConflict(clusterId, replicationClusterSet);
}
for (String clusterId : replicationClusterSet) {
validateClusterForProperty(namespaceName.getProperty(), clusterId);
}
Entry<Policies, Stat> policiesNode = null;
try {
// Force to read the data s.t. the watch to the cache content is setup.
policiesNode = policiesCache().getWithStat(path(POLICIES, namespaceName.toString())).orElseThrow(() -> new RestException(Status.NOT_FOUND, "Namespace " + namespaceName + " does not exist"));
policiesNode.getKey().replication_clusters = clusterIds;
// Write back the new policies into zookeeper
globalZk().setData(path(POLICIES, namespaceName.toString()), jsonMapper().writeValueAsBytes(policiesNode.getKey()), policiesNode.getValue().getVersion());
policiesCache().invalidate(path(POLICIES, namespaceName.toString()));
log.info("[{}] Successfully updated the replication clusters on namespace {}", clientAppId(), namespaceName);
} catch (KeeperException.NoNodeException e) {
log.warn("[{}] Failed to update the replication clusters 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 update the replication clusters on namespace {} expected policy node version={} : concurrent modification", clientAppId(), namespaceName, policiesNode.getValue().getVersion());
throw new RestException(Status.CONFLICT, "Concurrent modification");
} catch (Exception e) {
log.error("[{}] Failed to update the replication clusters on namespace {}", clientAppId(), namespaceName, e);
throw new RestException(e);
}
}
Aggregations