Search in sources :

Example 1 with TopicDomain

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

the class TopicLookup method lookupTopicAsync.

@GET
@Path("{topic-domain}/{property}/{cluster}/{namespace}/{topic}")
@Produces(MediaType.APPLICATION_JSON)
public void lookupTopicAsync(@PathParam("topic-domain") String topicDomain, @PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("topic") @Encoded String encodedTopic, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative, @Suspended AsyncResponse asyncResponse) {
    String topicName = Codec.decode(encodedTopic);
    TopicDomain domain = null;
    try {
        domain = TopicDomain.getEnum(topicDomain);
    } catch (IllegalArgumentException e) {
        log.error("[{}] Invalid topic-domain {}", clientAppId(), topicDomain, e);
        throw new RestException(Status.METHOD_NOT_ALLOWED, "Unsupported topic domain " + topicDomain);
    }
    TopicName topic = TopicName.get(domain.value(), property, cluster, namespace, topicName);
    if (!pulsar().getBrokerService().getLookupRequestSemaphore().tryAcquire()) {
        log.warn("No broker was found available for topic {}", topic);
        asyncResponse.resume(new WebApplicationException(Response.Status.SERVICE_UNAVAILABLE));
        return;
    }
    try {
        validateClusterOwnership(topic.getCluster());
        checkConnect(topic);
        validateGlobalNamespaceOwnership(topic.getNamespaceObject());
    } catch (WebApplicationException we) {
        // Validation checks failed
        log.error("Validation check failed: {}", we.getMessage());
        completeLookupResponseExceptionally(asyncResponse, we);
        return;
    } catch (Throwable t) {
        // Validation checks failed with unknown error
        log.error("Validation check failed: {}", t.getMessage(), t);
        completeLookupResponseExceptionally(asyncResponse, new RestException(t));
        return;
    }
    CompletableFuture<Optional<LookupResult>> lookupFuture = pulsar().getNamespaceService().getBrokerServiceUrlAsync(topic, authoritative);
    lookupFuture.thenAccept(optionalResult -> {
        if (optionalResult == null || !optionalResult.isPresent()) {
            log.warn("No broker was found available for topic {}", topic);
            completeLookupResponseExceptionally(asyncResponse, new WebApplicationException(Response.Status.SERVICE_UNAVAILABLE));
            return;
        }
        LookupResult result = optionalResult.get();
        // We have found either a broker that owns the topic, or a broker to which we should redirect the client to
        if (result.isRedirect()) {
            boolean newAuthoritative = this.isLeaderBroker();
            URI redirect;
            try {
                String redirectUrl = isRequestHttps() ? result.getLookupData().getHttpUrlTls() : result.getLookupData().getHttpUrl();
                checkNotNull(redirectUrl, "Redirected cluster's service url is not configured");
                redirect = new URI(String.format("%s%s%s?authoritative=%s", redirectUrl, "/lookup/v2/destination/", topic.getLookupName(), newAuthoritative));
            } catch (URISyntaxException | NullPointerException e) {
                log.error("Error in preparing redirect url for {}: {}", topic, e.getMessage(), e);
                completeLookupResponseExceptionally(asyncResponse, e);
                return;
            }
            if (log.isDebugEnabled()) {
                log.debug("Redirect lookup for topic {} to {}", topic, redirect);
            }
            completeLookupResponseExceptionally(asyncResponse, new WebApplicationException(Response.temporaryRedirect(redirect).build()));
        } else {
            // Found broker owning the topic
            if (log.isDebugEnabled()) {
                log.debug("Lookup succeeded for topic {} -- broker: {}", topic, result.getLookupData());
            }
            completeLookupResponseSuccessfully(asyncResponse, result.getLookupData());
        }
    }).exceptionally(exception -> {
        log.warn("Failed to lookup broker for topic {}: {}", topic, exception.getMessage(), exception);
        completeLookupResponseExceptionally(asyncResponse, exception);
        return null;
    });
}
Also used : PathParam(javax.ws.rs.PathParam) Encoded(javax.ws.rs.Encoded) TopicName(org.apache.pulsar.common.naming.TopicName) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) URISyntaxException(java.net.URISyntaxException) Path(javax.ws.rs.Path) LoggerFactory(org.slf4j.LoggerFactory) LookupType(org.apache.pulsar.common.api.proto.PulsarApi.CommandLookupTopicResponse.LookupType) CompletableFuture(java.util.concurrent.CompletableFuture) ApiResponses(io.swagger.annotations.ApiResponses) StringUtils(dlshade.org.apache.commons.lang3.StringUtils) ServerError(org.apache.pulsar.common.api.proto.PulsarApi.ServerError) MediaType(javax.ws.rs.core.MediaType) QueryParam(javax.ws.rs.QueryParam) ByteBuf(io.netty.buffer.ByteBuf) DefaultValue(javax.ws.rs.DefaultValue) RestException(org.apache.pulsar.broker.web.RestException) NoSwaggerDocumentation(org.apache.pulsar.broker.web.NoSwaggerDocumentation) URI(java.net.URI) NamespaceBundle(org.apache.pulsar.common.naming.NamespaceBundle) TopicDomain(org.apache.pulsar.common.naming.TopicDomain) Status(javax.ws.rs.core.Response.Status) Logger(org.slf4j.Logger) Commands.newLookupErrorResponse(org.apache.pulsar.common.api.Commands.newLookupErrorResponse) PulsarWebResource(org.apache.pulsar.broker.web.PulsarWebResource) AsyncResponse(javax.ws.rs.container.AsyncResponse) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) LookupData(org.apache.pulsar.common.lookup.data.LookupData) CompletionException(java.util.concurrent.CompletionException) PulsarService(org.apache.pulsar.broker.PulsarService) Suspended(javax.ws.rs.container.Suspended) AuthenticationDataSource(org.apache.pulsar.broker.authentication.AuthenticationDataSource) Response(javax.ws.rs.core.Response) ApiResponse(io.swagger.annotations.ApiResponse) Codec(org.apache.pulsar.common.util.Codec) Optional(java.util.Optional) WebApplicationException(javax.ws.rs.WebApplicationException) Commands.newLookupResponse(org.apache.pulsar.common.api.Commands.newLookupResponse) TopicDomain(org.apache.pulsar.common.naming.TopicDomain) WebApplicationException(javax.ws.rs.WebApplicationException) Optional(java.util.Optional) RestException(org.apache.pulsar.broker.web.RestException) URI(java.net.URI) TopicName(org.apache.pulsar.common.naming.TopicName) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET)

Example 2 with TopicDomain

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

the class TopicLookup method getNamespaceBundle.

@GET
@Path("{topic-domain}/{property}/{cluster}/{namespace}/{topic}/bundle")
@Produces(MediaType.APPLICATION_JSON)
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 405, message = "Invalid topic domain type") })
public String getNamespaceBundle(@PathParam("topic-domain") String topicDomain, @PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("topic") @Encoded String topicName) {
    topicName = Codec.decode(topicName);
    TopicDomain domain = null;
    try {
        domain = TopicDomain.getEnum(topicDomain);
    } catch (IllegalArgumentException e) {
        log.error("[{}] Invalid topic-domain {}", clientAppId(), topicDomain, e);
        throw new RestException(Status.METHOD_NOT_ALLOWED, "Bundle lookup can not be done on topic domain " + topicDomain);
    }
    TopicName topic = TopicName.get(domain.value(), property, cluster, namespace, topicName);
    validateSuperUserAccess();
    try {
        NamespaceBundle bundle = pulsar().getNamespaceService().getBundle(topic);
        return bundle.getBundleRange();
    } catch (Exception e) {
        log.error("[{}] Failed to get namespace bundle for {}", clientAppId(), topic, e);
        throw new RestException(e);
    }
}
Also used : NamespaceBundle(org.apache.pulsar.common.naming.NamespaceBundle) TopicDomain(org.apache.pulsar.common.naming.TopicDomain) RestException(org.apache.pulsar.broker.web.RestException) URISyntaxException(java.net.URISyntaxException) RestException(org.apache.pulsar.broker.web.RestException) CompletionException(java.util.concurrent.CompletionException) WebApplicationException(javax.ws.rs.WebApplicationException) TopicName(org.apache.pulsar.common.naming.TopicName) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) ApiResponses(io.swagger.annotations.ApiResponses)

Aggregations

ApiResponses (io.swagger.annotations.ApiResponses)2 URISyntaxException (java.net.URISyntaxException)2 CompletionException (java.util.concurrent.CompletionException)2 GET (javax.ws.rs.GET)2 Path (javax.ws.rs.Path)2 Produces (javax.ws.rs.Produces)2 WebApplicationException (javax.ws.rs.WebApplicationException)2 RestException (org.apache.pulsar.broker.web.RestException)2 NamespaceBundle (org.apache.pulsar.common.naming.NamespaceBundle)2 TopicDomain (org.apache.pulsar.common.naming.TopicDomain)2 TopicName (org.apache.pulsar.common.naming.TopicName)2 Preconditions.checkNotNull (com.google.common.base.Preconditions.checkNotNull)1 StringUtils (dlshade.org.apache.commons.lang3.StringUtils)1 ByteBuf (io.netty.buffer.ByteBuf)1 ApiResponse (io.swagger.annotations.ApiResponse)1 URI (java.net.URI)1 Optional (java.util.Optional)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 DefaultValue (javax.ws.rs.DefaultValue)1 Encoded (javax.ws.rs.Encoded)1