Search in sources :

Example 56 with WebApplicationException

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

the class HttpDestinationLookupv2Test method crossColoLookup.

@Test
public void crossColoLookup() throws Exception {
    DestinationLookup destLookup = spy(new DestinationLookup());
    doReturn(false).when(destLookup).isRequestHttps();
    destLookup.setPulsar(pulsar);
    doReturn("null").when(destLookup).clientAppId();
    Field uriField = PulsarWebResource.class.getDeclaredField("uri");
    uriField.setAccessible(true);
    UriInfo uriInfo = mock(UriInfo.class);
    uriField.set(destLookup, uriInfo);
    URI uri = URI.create("http://localhost:8080/lookup/v2/destination/topic/myprop/usc/ns2/topic1");
    doReturn(uri).when(uriInfo).getRequestUri();
    doReturn(true).when(config).isAuthorizationEnabled();
    AsyncResponse asyncResponse = mock(AsyncResponse.class);
    destLookup.lookupDestinationAsync("myprop", "usc", "ns2", "topic1", false, asyncResponse);
    ArgumentCaptor<Throwable> arg = ArgumentCaptor.forClass(Throwable.class);
    verify(asyncResponse).resume(arg.capture());
    assertEquals(arg.getValue().getClass(), WebApplicationException.class);
    WebApplicationException wae = (WebApplicationException) arg.getValue();
    assertEquals(wae.getResponse().getStatus(), Status.TEMPORARY_REDIRECT.getStatusCode());
}
Also used : Field(java.lang.reflect.Field) WebApplicationException(javax.ws.rs.WebApplicationException) DestinationLookup(com.yahoo.pulsar.broker.lookup.DestinationLookup) AsyncResponse(javax.ws.rs.container.AsyncResponse) URI(java.net.URI) UriInfo(javax.ws.rs.core.UriInfo) Test(org.testng.annotations.Test)

Example 57 with WebApplicationException

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

the class Namespaces method unsubscribeNamespace.

@POST
@Path("/{property}/{cluster}/{namespace}/unsubscribe/{subscription}")
@ApiOperation(value = "Unsubscribes the given subscription on all destinations on a namespace.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Namespace does not exist") })
public void unsubscribeNamespace(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("subscription") String subscription, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) {
    validateAdminAccessOnProperty(property);
    NamespaceName nsName = new NamespaceName(property, cluster, namespace);
    try {
        NamespaceBundles bundles = pulsar().getNamespaceService().getNamespaceBundleFactory().getBundles(nsName);
        Exception exception = null;
        for (NamespaceBundle nsBundle : bundles.getBundles()) {
            try {
                // check if the bundle is owned by any broker, if not then there are no subscriptions
                if (pulsar().getNamespaceService().getOwner(nsBundle).isPresent()) {
                    // TODO: make this admin call asynchronous
                    pulsar().getAdminClient().namespaces().unsubscribeNamespaceBundle(nsName.toString(), nsBundle.getBundleRange(), subscription);
                }
            } catch (Exception e) {
                if (exception == null) {
                    exception = e;
                }
            }
        }
        if (exception != null) {
            if (exception instanceof PulsarAdminException) {
                throw new RestException((PulsarAdminException) exception);
            } else {
                throw new RestException(exception.getCause());
            }
        }
    } catch (WebApplicationException wae) {
        throw wae;
    } catch (Exception e) {
        throw new RestException(e);
    }
    log.info("[{}] Successfully unsubscribed {} on all the bundles for namespace {}", clientAppId(), subscription, nsName.toString());
}
Also used : NamespaceBundle(com.yahoo.pulsar.common.naming.NamespaceBundle) NamespaceName(com.yahoo.pulsar.common.naming.NamespaceName) WebApplicationException(javax.ws.rs.WebApplicationException) NamespaceBundles(com.yahoo.pulsar.common.naming.NamespaceBundles) RestException(com.yahoo.pulsar.broker.web.RestException) PulsarAdminException(com.yahoo.pulsar.client.admin.PulsarAdminException) 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) POST(javax.ws.rs.POST) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 58 with WebApplicationException

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

the class Namespaces method clearNamespaceBacklogForSubscription.

@POST
@Path("/{property}/{cluster}/{namespace}/clearBacklog/{subscription}")
@ApiOperation(value = "Clear backlog for a given subscription on all destinations on a namespace.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Namespace does not exist") })
public void clearNamespaceBacklogForSubscription(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("subscription") String subscription, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) {
    validateAdminAccessOnProperty(property);
    NamespaceName nsName = new NamespaceName(property, cluster, namespace);
    try {
        NamespaceBundles bundles = pulsar().getNamespaceService().getNamespaceBundleFactory().getBundles(nsName);
        Exception exception = null;
        for (NamespaceBundle nsBundle : bundles.getBundles()) {
            try {
                // clear
                if (pulsar().getNamespaceService().getOwner(nsBundle).isPresent()) {
                    // TODO: make this admin call asynchronous
                    pulsar().getAdminClient().namespaces().clearNamespaceBundleBacklogForSubscription(nsName.toString(), nsBundle.getBundleRange(), subscription);
                }
            } catch (Exception e) {
                if (exception == null) {
                    exception = e;
                }
            }
        }
        if (exception != null) {
            if (exception instanceof PulsarAdminException) {
                throw new RestException((PulsarAdminException) exception);
            } else {
                throw new RestException(exception.getCause());
            }
        }
    } catch (WebApplicationException wae) {
        throw wae;
    } catch (Exception e) {
        throw new RestException(e);
    }
    log.info("[{}] Successfully cleared backlog for subscription {} on all the bundles for namespace {}", clientAppId(), subscription, nsName.toString());
}
Also used : NamespaceBundle(com.yahoo.pulsar.common.naming.NamespaceBundle) NamespaceName(com.yahoo.pulsar.common.naming.NamespaceName) WebApplicationException(javax.ws.rs.WebApplicationException) NamespaceBundles(com.yahoo.pulsar.common.naming.NamespaceBundles) RestException(com.yahoo.pulsar.broker.web.RestException) PulsarAdminException(com.yahoo.pulsar.client.admin.PulsarAdminException) 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) POST(javax.ws.rs.POST) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 59 with WebApplicationException

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

the class Namespaces method deleteNamespace.

@DELETE
@Path("/{property}/{cluster}/{namespace}")
@ApiOperation(value = "Delete a namespace and all the destinations under it.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Property or cluster or namespace doesn't exist"), @ApiResponse(code = 409, message = "Namespace is not empty") })
public void deleteNamespace(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) {
    NamespaceName nsName = new NamespaceName(property, cluster, namespace);
    validateAdminAccessOnProperty(property);
    validatePoliciesReadOnlyAccess();
    // ensure that non-global namespace is directed to the correct cluster
    validateClusterOwnership(cluster);
    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", property, cluster, namespace)).orElseThrow(() -> new RestException(Status.NOT_FOUND, "Namespace " + nsName + " does not exist."));
        policies = policiesNode.getKey();
        if (cluster.equals(Namespaces.GLOBAL_CLUSTER)) {
            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 " + nsName + ". 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, "Cluser " + replCluster + " does not exist"));
                URL replClusterUrl;
                if (!config().isTlsEnabled()) {
                    replClusterUrl = new URL(replClusterData.getServiceUrl());
                } else if (!replClusterData.getServiceUrlTls().isEmpty()) {
                    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();
                log.debug("[{}] Redirecting the rest call to {}: cluster={}", clientAppId(), redirect, cluster);
                throw new WebApplicationException(Response.temporaryRedirect(redirect).build());
            }
        }
    } catch (WebApplicationException wae) {
        throw wae;
    } catch (Exception e) {
        throw new RestException(e);
    }
    List<String> destinations = getDestinations(property, cluster, namespace);
    if (!destinations.isEmpty()) {
        log.info("Found destinations: {}", destinations);
        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", property, cluster, namespace), jsonMapper().writeValueAsBytes(policies), policiesNode.getValue().getVersion());
        policiesCache().invalidate(path("policies", property, cluster, namespace));
    } catch (Exception e) {
        log.error("[{}] Failed to delete namespace on global ZK {}/{}/{}", clientAppId(), property, cluster, namespace, e);
        throw new RestException(e);
    }
    // remove from owned namespace map and ephemeral node from ZK
    try {
        NamespaceBundles bundles = pulsar().getNamespaceService().getNamespaceBundleFactory().getBundles(nsName);
        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(nsName.toString(), bundle.getBundleRange());
            }
        }
        // we have successfully removed all the ownership for the namespace, the policies znode can be deleted now
        globalZk().delete(path("policies", property, cluster, namespace), -1);
        policiesCache().invalidate(path("policies", property, cluster, namespace));
    } catch (PulsarAdminException cae) {
        throw new RestException(cae);
    } catch (Exception e) {
        log.error(String.format("[%s] Failed to remove owned namespace %s/%s/%s", clientAppId(), property, cluster, namespace), e);
    // avoid throwing exception in case of the second failure
    }
}
Also used : NamespaceBundle(com.yahoo.pulsar.common.naming.NamespaceBundle) Policies(com.yahoo.pulsar.common.policies.data.Policies) PersistencePolicies(com.yahoo.pulsar.common.policies.data.PersistencePolicies) RetentionPolicies(com.yahoo.pulsar.common.policies.data.RetentionPolicies) WebApplicationException(javax.ws.rs.WebApplicationException) NamespaceBundles(com.yahoo.pulsar.common.naming.NamespaceBundles) RestException(com.yahoo.pulsar.broker.web.RestException) URI(java.net.URI) URL(java.net.URL) 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) NamespaceName(com.yahoo.pulsar.common.naming.NamespaceName) Stat(org.apache.zookeeper.data.Stat) ClusterData(com.yahoo.pulsar.common.policies.data.ClusterData) PulsarAdminException(com.yahoo.pulsar.client.admin.PulsarAdminException) Path(javax.ws.rs.Path) DELETE(javax.ws.rs.DELETE) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 60 with WebApplicationException

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

the class PersistentTopics method peekNthMessage.

@GET
@Path("/{property}/{cluster}/{namespace}/{destination}/subscription/{subName}/position/{messagePosition}")
@ApiOperation(value = "Peek nth message on a topic subscription.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Topic, subscription or the message position does not exist") })
public Response peekNthMessage(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("destination") @Encoded String destination, @PathParam("subName") String subName, @PathParam("messagePosition") int messagePosition, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) {
    destination = decode(destination);
    DestinationName dn = DestinationName.get(domain(), property, cluster, namespace, destination);
    PartitionedTopicMetadata partitionMetadata = getPartitionedTopicMetadata(property, cluster, namespace, destination, authoritative);
    if (partitionMetadata.partitions > 0) {
        throw new RestException(Status.METHOD_NOT_ALLOWED, "Peek messages on a partitioned topic is not allowed");
    }
    validateAdminOperationOnDestination(dn, authoritative);
    PersistentTopic topic = getTopicReference(dn);
    PersistentReplicator repl = null;
    PersistentSubscription sub = null;
    Entry entry = null;
    if (subName.startsWith(topic.replicatorPrefix)) {
        repl = getReplicatorReference(subName, topic);
    } else {
        sub = getSubscriptionReference(subName, topic);
    }
    try {
        if (subName.startsWith(topic.replicatorPrefix)) {
            entry = repl.peekNthMessage(messagePosition).get();
        } else {
            entry = sub.peekNthMessage(messagePosition).get();
        }
        checkNotNull(entry);
        PositionImpl pos = (PositionImpl) entry.getPosition();
        ByteBuf metadataAndPayload = entry.getDataBuffer();
        // moves the readerIndex to the payload
        MessageMetadata metadata = Commands.parseMessageMetadata(metadataAndPayload);
        ResponseBuilder responseBuilder = Response.ok();
        responseBuilder.header("X-Pulsar-Message-ID", pos.toString());
        for (KeyValue keyValue : metadata.getPropertiesList()) {
            responseBuilder.header("X-Pulsar-PROPERTY-" + keyValue.getKey(), keyValue.getValue());
        }
        if (metadata.hasPublishTime()) {
            responseBuilder.header("X-Pulsar-publish-time", DATE_FORMAT.format(Instant.ofEpochMilli(metadata.getPublishTime())));
        }
        // Decode if needed
        CompressionCodec codec = CompressionCodecProvider.getCompressionCodec(metadata.getCompression());
        ByteBuf uncompressedPayload = codec.decode(metadataAndPayload, metadata.getUncompressedSize());
        // Copy into a heap buffer for output stream compatibility
        ByteBuf data = PooledByteBufAllocator.DEFAULT.heapBuffer(uncompressedPayload.readableBytes(), uncompressedPayload.readableBytes());
        data.writeBytes(uncompressedPayload);
        uncompressedPayload.release();
        StreamingOutput stream = new StreamingOutput() {

            @Override
            public void write(OutputStream output) throws IOException, WebApplicationException {
                output.write(data.array(), data.arrayOffset(), data.readableBytes());
                data.release();
            }
        };
        return responseBuilder.entity(stream).build();
    } catch (NullPointerException npe) {
        throw new RestException(Status.NOT_FOUND, "Message not found");
    } catch (Exception exception) {
        log.error("[{}] Failed to get message at position {} from {} {}", clientAppId(), messagePosition, dn, subName, exception);
        throw new RestException(exception);
    } finally {
        if (entry != null) {
            entry.release();
        }
    }
}
Also used : PersistentReplicator(com.yahoo.pulsar.broker.service.persistent.PersistentReplicator) KeyValue(com.yahoo.pulsar.common.api.proto.PulsarApi.KeyValue) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) OutputStream(java.io.OutputStream) RestException(com.yahoo.pulsar.broker.web.RestException) StreamingOutput(javax.ws.rs.core.StreamingOutput) ByteBuf(io.netty.buffer.ByteBuf) PersistentSubscription(com.yahoo.pulsar.broker.service.persistent.PersistentSubscription) 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) Entry(org.apache.bookkeeper.mledger.Entry) MessageMetadata(com.yahoo.pulsar.common.api.proto.PulsarApi.MessageMetadata) PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) DestinationName(com.yahoo.pulsar.common.naming.DestinationName) CompressionCodec(com.yahoo.pulsar.common.compression.CompressionCodec) ResponseBuilder(javax.ws.rs.core.Response.ResponseBuilder) PartitionedTopicMetadata(com.yahoo.pulsar.common.partition.PartitionedTopicMetadata) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Aggregations

WebApplicationException (javax.ws.rs.WebApplicationException)276 Produces (javax.ws.rs.Produces)77 GET (javax.ws.rs.GET)71 Path (javax.ws.rs.Path)69 IOException (java.io.IOException)47 POST (javax.ws.rs.POST)47 Consumes (javax.ws.rs.Consumes)44 ResponseBuilder (javax.ws.rs.core.Response.ResponseBuilder)43 Response (javax.ws.rs.core.Response)30 MediaType (javax.ws.rs.core.MediaType)26 URI (java.net.URI)25 HashMap (java.util.HashMap)20 JSONObject (org.codehaus.jettison.json.JSONObject)20 Test (org.junit.Test)19 JSONException (org.codehaus.jettison.json.JSONException)18 ApiOperation (io.swagger.annotations.ApiOperation)17 ArrayList (java.util.ArrayList)17 ByteArrayInputStream (java.io.ByteArrayInputStream)15 Viewable (org.apache.stanbol.commons.web.viewable.Viewable)15 List (java.util.List)14