Search in sources :

Example 26 with DELETE

use of javax.ws.rs.DELETE in project pulsar by yahoo.

the class Namespaces method revokePermissionsOnNamespace.

@DELETE
@Path("/{property}/{cluster}/{namespace}/permissions/{role}")
@ApiOperation(value = "Revoke all permissions to a role on a namespace.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Property or cluster or namespace doesn't exist") })
public void revokePermissionsOnNamespace(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("role") String role) {
    validateAdminAccessOnProperty(property);
    validatePoliciesReadOnlyAccess();
    try {
        Stat nodeStat = new Stat();
        byte[] content = globalZk().getData(path("policies", property, cluster, namespace), 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", property, cluster, namespace), jsonMapper().writeValueAsBytes(policies), nodeStat.getVersion());
        policiesCache().invalidate(path("policies", property, cluster, namespace));
        log.info("[{}] Successfully revoked access for role {} - namespace {}/{}/{}", clientAppId(), role, property, cluster, namespace);
    } catch (KeeperException.NoNodeException e) {
        log.warn("[{}] Failed to revoke permissions for namespace {}/{}/{}: does not exist", clientAppId(), property, cluster, namespace);
        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(), property, cluster, namespace);
        throw new RestException(Status.CONFLICT, "Concurrent modification");
    } catch (Exception e) {
        log.error("[{}] Failed to revoke permissions on namespace {}/{}/{}", clientAppId(), property, cluster, namespace, e);
        throw new RestException(e);
    }
}
Also used : Stat(org.apache.zookeeper.data.Stat) Policies(com.yahoo.pulsar.common.policies.data.Policies) PersistencePolicies(com.yahoo.pulsar.common.policies.data.PersistencePolicies) RetentionPolicies(com.yahoo.pulsar.common.policies.data.RetentionPolicies) NoNodeException(org.apache.zookeeper.KeeperException.NoNodeException) RestException(com.yahoo.pulsar.broker.web.RestException) KeeperException(org.apache.zookeeper.KeeperException) RestException(com.yahoo.pulsar.broker.web.RestException) WebApplicationException(javax.ws.rs.WebApplicationException) SubscriptionBusyException(com.yahoo.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException) KeeperException(org.apache.zookeeper.KeeperException) PulsarAdminException(com.yahoo.pulsar.client.admin.PulsarAdminException) NoNodeException(org.apache.zookeeper.KeeperException.NoNodeException) PulsarServerException(com.yahoo.pulsar.broker.PulsarServerException) Path(javax.ws.rs.Path) DELETE(javax.ws.rs.DELETE) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 27 with DELETE

use of javax.ws.rs.DELETE in project pulsar by yahoo.

the class PersistentTopics method deletePartitionedTopic.

@DELETE
@Path("/{property}/{cluster}/{namespace}/{destination}/partitions")
@ApiOperation(value = "Delete a partitioned topic.", notes = "It will also delete all the partitions of the topic if it exists.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Partitioned topic does not exist") })
public void deletePartitionedTopic(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("destination") @Encoded String destination, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) {
    destination = decode(destination);
    DestinationName dn = DestinationName.get(domain(), property, cluster, namespace, destination);
    validateAdminAccessOnProperty(dn.getProperty());
    PartitionedTopicMetadata partitionMetadata = getPartitionedTopicMetadata(property, cluster, namespace, destination, authoritative);
    int numPartitions = partitionMetadata.partitions;
    if (numPartitions > 0) {
        final CompletableFuture<Void> future = new CompletableFuture<>();
        final AtomicInteger count = new AtomicInteger(numPartitions);
        try {
            for (int i = 0; i < numPartitions; i++) {
                DestinationName dn_partition = dn.getPartition(i);
                pulsar().getAdminClient().persistentTopics().deleteAsync(dn_partition.toString()).whenComplete((r, ex) -> {
                    if (ex != null) {
                        if (ex instanceof NotFoundException) {
                            // partition is failed to be deleted
                            if (log.isDebugEnabled()) {
                                log.debug("[{}] Partition not found: {}", clientAppId(), dn_partition);
                            }
                        } else {
                            future.completeExceptionally(ex);
                            log.error("[{}] Failed to delete partition {}", clientAppId(), dn_partition, ex);
                            return;
                        }
                    } else {
                        log.info("[{}] Deleted partition {}", clientAppId(), dn_partition);
                    }
                    if (count.decrementAndGet() == 0) {
                        future.complete(null);
                    }
                });
            }
            future.get();
        } catch (Exception e) {
            Throwable t = e.getCause();
            if (t instanceof PreconditionFailedException) {
                throw new RestException(Status.PRECONDITION_FAILED, "Topic has active producers/subscriptions");
            } else {
                throw new RestException(t);
            }
        }
    }
    // Only tries to delete the znode for partitioned topic when all its partitions are successfully deleted
    String path = path(PARTITIONED_TOPIC_PATH_ZNODE, property, cluster, namespace, domain(), dn.getEncodedLocalName());
    try {
        globalZk().delete(path, -1);
        globalZkCache().invalidate(path);
        // we wait for the data to be synced in all quorums and the observers
        Thread.sleep(PARTITIONED_TOPIC_WAIT_SYNC_TIME_MS);
        log.info("[{}] Deleted partitioned topic {}", clientAppId(), dn);
    } catch (KeeperException.NoNodeException nne) {
        throw new RestException(Status.NOT_FOUND, "Partitioned topic does not exist");
    } catch (Exception e) {
        log.error("[{}] Failed to delete partitioned topic {}", clientAppId(), dn, e);
        throw new RestException(e);
    }
}
Also used : RestException(com.yahoo.pulsar.broker.web.RestException) NotFoundException(com.yahoo.pulsar.client.admin.PulsarAdminException.NotFoundException) RestException(com.yahoo.pulsar.broker.web.RestException) TopicBusyException(com.yahoo.pulsar.broker.service.BrokerServiceException.TopicBusyException) WebApplicationException(javax.ws.rs.WebApplicationException) PulsarClientException(com.yahoo.pulsar.client.api.PulsarClientException) PreconditionFailedException(com.yahoo.pulsar.client.admin.PulsarAdminException.PreconditionFailedException) SubscriptionBusyException(com.yahoo.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException) NotFoundException(com.yahoo.pulsar.client.admin.PulsarAdminException.NotFoundException) NotAllowedException(com.yahoo.pulsar.broker.service.BrokerServiceException.NotAllowedException) KeeperException(org.apache.zookeeper.KeeperException) IOException(java.io.IOException) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) DestinationName(com.yahoo.pulsar.common.naming.DestinationName) PreconditionFailedException(com.yahoo.pulsar.client.admin.PulsarAdminException.PreconditionFailedException) PartitionedTopicMetadata(com.yahoo.pulsar.common.partition.PartitionedTopicMetadata) KeeperException(org.apache.zookeeper.KeeperException) Path(javax.ws.rs.Path) DELETE(javax.ws.rs.DELETE) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 28 with DELETE

use of javax.ws.rs.DELETE in project pulsar by yahoo.

the class PersistentTopics method revokePermissionsOnDestination.

@DELETE
@Path("/{property}/{cluster}/{namespace}/{destination}/permissions/{role}")
@ApiOperation(value = "Revoke permissions on a destination.", notes = "Revoke permissions to a role on a single destination. If the permission was not set at the destination" + "level, but rather at the namespace level, this operation will return an error (HTTP status code 412).")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Namespace doesn't exist"), @ApiResponse(code = 412, message = "Permissions are not set at the destination level") })
public void revokePermissionsOnDestination(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("destination") @Encoded String destination, @PathParam("role") String role) {
    destination = decode(destination);
    // This operation should be reading from zookeeper and it should be allowed without having admin privileges
    validateAdminAccessOnProperty(property);
    validatePoliciesReadOnlyAccess();
    String destinationUri = DestinationName.get(domain(), property, cluster, namespace, destination).toString();
    Stat nodeStat = new Stat();
    Policies policies;
    try {
        byte[] content = globalZk().getData(path("policies", property, cluster, namespace), null, nodeStat);
        policies = jsonMapper().readValue(content, Policies.class);
    } catch (KeeperException.NoNodeException e) {
        log.warn("[{}] Failed to revoke permissions on destination {}: Namespace does not exist", clientAppId(), destinationUri);
        throw new RestException(Status.NOT_FOUND, "Namespace does not exist");
    } catch (Exception e) {
        log.error("[{}] Failed to revoke permissions for destination {}", clientAppId(), destinationUri, e);
        throw new RestException(e);
    }
    if (!policies.auth_policies.destination_auth.containsKey(destinationUri) || !policies.auth_policies.destination_auth.get(destinationUri).containsKey(role)) {
        log.warn("[{}] Failed to revoke permission from role {} on destination: Not set at destination level", clientAppId(), role, destinationUri);
        throw new RestException(Status.PRECONDITION_FAILED, "Permissions are not set at the destination level");
    }
    policies.auth_policies.destination_auth.get(destinationUri).remove(role);
    try {
        // Write the new policies to zookeeper
        String namespacePath = path("policies", property, cluster, namespace);
        globalZk().setData(namespacePath, jsonMapper().writeValueAsBytes(policies), nodeStat.getVersion());
        // invalidate the local cache to force update
        policiesCache().invalidate(namespacePath);
        globalZkCache().invalidate(namespacePath);
        log.info("[{}] Successfully revoke access for role {} - destination {}", clientAppId(), role, destinationUri);
    } catch (Exception e) {
        log.error("[{}] Failed to revoke permissions for destination {}", clientAppId(), destinationUri, e);
        throw new RestException(e);
    }
}
Also used : Stat(org.apache.zookeeper.data.Stat) Policies(com.yahoo.pulsar.common.policies.data.Policies) AuthPolicies(com.yahoo.pulsar.common.policies.data.AuthPolicies) RestException(com.yahoo.pulsar.broker.web.RestException) KeeperException(org.apache.zookeeper.KeeperException) RestException(com.yahoo.pulsar.broker.web.RestException) TopicBusyException(com.yahoo.pulsar.broker.service.BrokerServiceException.TopicBusyException) WebApplicationException(javax.ws.rs.WebApplicationException) PulsarClientException(com.yahoo.pulsar.client.api.PulsarClientException) PreconditionFailedException(com.yahoo.pulsar.client.admin.PulsarAdminException.PreconditionFailedException) SubscriptionBusyException(com.yahoo.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException) NotFoundException(com.yahoo.pulsar.client.admin.PulsarAdminException.NotFoundException) NotAllowedException(com.yahoo.pulsar.broker.service.BrokerServiceException.NotAllowedException) KeeperException(org.apache.zookeeper.KeeperException) IOException(java.io.IOException) Path(javax.ws.rs.Path) DELETE(javax.ws.rs.DELETE) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 29 with DELETE

use of javax.ws.rs.DELETE in project pulsar by yahoo.

the class Properties method deleteProperty.

@DELETE
@Path("/{property}")
@ApiOperation(value = "elete a property and all namespaces and destinations under it.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Property does not exist"), @ApiResponse(code = 409, message = "The property still has active namespaces") })
public void deleteProperty(@PathParam("property") String property) {
    validateSuperUserAccess();
    validatePoliciesReadOnlyAccess();
    boolean isPropertyEmpty = false;
    try {
        isPropertyEmpty = getListOfNamespaces(property).isEmpty();
    } catch (KeeperException.NoNodeException e) {
        log.warn("[{}] Failed to delete property {}: does not exist", clientAppId(), property);
        throw new RestException(Status.NOT_FOUND, "The property does not exist");
    } catch (Exception e) {
        log.error("[{}] Failed to get property status {}", clientAppId(), property, e);
        throw new RestException(e);
    }
    if (!isPropertyEmpty) {
        log.warn("[{}] Failed to delete property {}: not empty", clientAppId(), property);
        throw new RestException(Status.CONFLICT, "The property still has active namespaces");
    }
    try {
        // First try to delete every cluster z-node
        for (String cluster : globalZk().getChildren(path("policies", property), false)) {
            globalZk().delete(path("policies", property, cluster), -1);
        }
        globalZk().delete(path("policies", property), -1);
        log.info("[{}] Deleted property {}", clientAppId(), property);
    } catch (Exception e) {
        log.error("[{}] Failed to delete property {}", clientAppId(), property, e);
        throw new RestException(e);
    }
}
Also used : RestException(com.yahoo.pulsar.broker.web.RestException) KeeperException(org.apache.zookeeper.KeeperException) RestException(com.yahoo.pulsar.broker.web.RestException) KeeperException(org.apache.zookeeper.KeeperException) Path(javax.ws.rs.Path) DELETE(javax.ws.rs.DELETE) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 30 with DELETE

use of javax.ws.rs.DELETE in project pulsar by yahoo.

the class ResourceQuotas method removeNamespaceBundleResourceQuota.

@DELETE
@Path("/{property}/{cluster}/{namespace}/{bundle}")
@ApiOperation(value = "Remove resource quota for a namespace.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 409, message = "Concurrent modification") })
public void removeNamespaceBundleResourceQuota(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("bundle") String bundleRange) {
    validateSuperUserAccess();
    validatePoliciesReadOnlyAccess();
    Policies policies = getNamespacePolicies(property, cluster, namespace);
    if (!cluster.equals(Namespaces.GLOBAL_CLUSTER)) {
        validateClusterOwnership(cluster);
        validateClusterForProperty(property, cluster);
    }
    NamespaceName fqnn = new NamespaceName(property, cluster, namespace);
    NamespaceBundle nsBundle = validateNamespaceBundleRange(fqnn, 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(com.yahoo.pulsar.common.naming.NamespaceBundle) NamespaceName(com.yahoo.pulsar.common.naming.NamespaceName) Policies(com.yahoo.pulsar.common.policies.data.Policies) RestException(com.yahoo.pulsar.broker.web.RestException) KeeperException(org.apache.zookeeper.KeeperException) RestException(com.yahoo.pulsar.broker.web.RestException) KeeperException(org.apache.zookeeper.KeeperException) Path(javax.ws.rs.Path) DELETE(javax.ws.rs.DELETE) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Aggregations

DELETE (javax.ws.rs.DELETE)202 Path (javax.ws.rs.Path)186 ApiOperation (io.swagger.annotations.ApiOperation)59 ApiResponses (io.swagger.annotations.ApiResponses)48 Produces (javax.ws.rs.Produces)43 Timed (com.codahale.metrics.annotation.Timed)31 AuditEvent (org.graylog2.audit.jersey.AuditEvent)25 IOException (java.io.IOException)20 Response (javax.ws.rs.core.Response)20 WebApplicationException (javax.ws.rs.WebApplicationException)17 HashMap (java.util.HashMap)15 NotFoundException (javax.ws.rs.NotFoundException)15 RestException (com.yahoo.pulsar.broker.web.RestException)12 Consumes (javax.ws.rs.Consumes)12 KeeperException (org.apache.zookeeper.KeeperException)12 ExceptionMetered (com.codahale.metrics.annotation.ExceptionMetered)11 ApiResponse (io.swagger.annotations.ApiResponse)11 NamespaceId (co.cask.cdap.proto.id.NamespaceId)9 ResponseBuilder (javax.ws.rs.core.Response.ResponseBuilder)9 Event (keywhiz.log.Event)9