Search in sources :

Example 61 with RestException

use of com.yahoo.pulsar.broker.web.RestException in project pulsar by yahoo.

the class DestinationLookup method lookupDestinationAsync.

/**
     * 
     * Lookup broker-service address for a given namespace-bundle which contains given topic.
     * 
     * a. Returns broker-address if namespace-bundle is already owned by any broker
     * b. If current-broker receives lookup-request and if it's not a leader
     * then current broker redirects request to leader by returning leader-service address. 
     * c. If current-broker is leader then it finds out least-loaded broker to own namespace bundle and 
     * redirects request by returning least-loaded broker.
     * d. If current-broker receives request to own the namespace-bundle then it owns a bundle and returns 
     * success(connect) response to client.
     * 
     * @param pulsarService
     * @param fqdn
     * @param authoritative
     * @param clientAppId
     * @param requestId
     * @return
     */
public static CompletableFuture<ByteBuf> lookupDestinationAsync(PulsarService pulsarService, DestinationName fqdn, boolean authoritative, String clientAppId, long requestId) {
    final CompletableFuture<ByteBuf> validationFuture = new CompletableFuture<>();
    final CompletableFuture<ByteBuf> lookupfuture = new CompletableFuture<>();
    final String cluster = fqdn.getCluster();
    // (1) validate cluster
    getClusterDataIfDifferentCluster(pulsarService, cluster, clientAppId).thenAccept(differentClusterData -> {
        if (differentClusterData != null) {
            if (log.isDebugEnabled()) {
                log.debug("[{}] Redirecting the lookup call to {}/{} cluster={}", clientAppId, differentClusterData.getBrokerServiceUrl(), differentClusterData.getBrokerServiceUrlTls(), cluster);
            }
            validationFuture.complete(newLookupResponse(differentClusterData.getBrokerServiceUrl(), differentClusterData.getBrokerServiceUrlTls(), true, LookupType.Redirect, requestId));
        } else {
            try {
                checkAuthorization(pulsarService, fqdn, clientAppId);
            } catch (RestException authException) {
                log.warn("Failed to authorized {} on cluster {}", clientAppId, fqdn.toString());
                validationFuture.complete(newLookupResponse(ServerError.AuthorizationError, authException.getMessage(), requestId));
                return;
            } catch (Exception e) {
                log.warn("Unknown error while authorizing {} on cluster {}", clientAppId, fqdn.toString());
                validationFuture.completeExceptionally(e);
                return;
            }
            validateReplicationSettingsOnNamespaceAsync(pulsarService, fqdn.getNamespaceObject()).thenAccept(success -> {
                validationFuture.complete(null);
            }).exceptionally(ex -> {
                validationFuture.complete(newLookupResponse(ServerError.MetadataError, ex.getMessage(), requestId));
                return null;
            });
        }
    }).exceptionally(ex -> {
        validationFuture.completeExceptionally(ex);
        return null;
    });
    // Initiate lookup once validation completes
    validationFuture.thenAccept(validaitonFailureResponse -> {
        if (validaitonFailureResponse != null) {
            lookupfuture.complete(validaitonFailureResponse);
        } else {
            pulsarService.getNamespaceService().getBrokerServiceUrlAsync(fqdn, authoritative).thenAccept(lookupResult -> {
                if (log.isDebugEnabled()) {
                    log.debug("[{}] Lookup result {}", fqdn.toString(), lookupResult);
                }
                LookupData lookupData = lookupResult.getLookupData();
                if (lookupResult.isRedirect()) {
                    boolean newAuthoritative = isLeaderBroker(pulsarService);
                    lookupfuture.complete(newLookupResponse(lookupData.getBrokerUrl(), lookupData.getBrokerUrlTls(), newAuthoritative, LookupType.Redirect, requestId));
                } else {
                    lookupfuture.complete(newLookupResponse(lookupData.getBrokerUrl(), lookupData.getBrokerUrlTls(), true, LookupType.Connect, requestId));
                }
            }).exceptionally(e -> {
                log.warn("Failed to lookup {} for topic {} with error {}", clientAppId, fqdn.toString(), e.getMessage(), e);
                lookupfuture.complete(newLookupResponse(ServerError.ServiceNotReady, e.getMessage(), requestId));
                return null;
            });
        }
    }).exceptionally(ex -> {
        log.warn("Failed to lookup {} for topic {} with error {}", clientAppId, fqdn.toString(), ex.getMessage(), ex);
        lookupfuture.complete(newLookupResponse(ServerError.ServiceNotReady, ex.getMessage(), requestId));
        return null;
    });
    return lookupfuture;
}
Also used : PathParam(javax.ws.rs.PathParam) RestException(com.yahoo.pulsar.broker.web.RestException) ServerError(com.yahoo.pulsar.common.api.proto.PulsarApi.ServerError) Encoded(javax.ws.rs.Encoded) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) URISyntaxException(java.net.URISyntaxException) Path(javax.ws.rs.Path) LoggerFactory(org.slf4j.LoggerFactory) CompletableFuture(java.util.concurrent.CompletableFuture) LookupData(com.yahoo.pulsar.common.lookup.data.LookupData) MediaType(javax.ws.rs.core.MediaType) QueryParam(javax.ws.rs.QueryParam) ClusterData(com.yahoo.pulsar.common.policies.data.ClusterData) ByteBuf(io.netty.buffer.ByteBuf) DefaultValue(javax.ws.rs.DefaultValue) PulsarService(com.yahoo.pulsar.broker.PulsarService) URI(java.net.URI) Codec(com.yahoo.pulsar.common.util.Codec) LookupType(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandLookupTopicResponse.LookupType) Status(javax.ws.rs.core.Response.Status) DestinationName(com.yahoo.pulsar.common.naming.DestinationName) Logger(org.slf4j.Logger) AsyncResponse(javax.ws.rs.container.AsyncResponse) NoSwaggerDocumentation(com.yahoo.pulsar.broker.web.NoSwaggerDocumentation) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) Commands.newLookupResponse(com.yahoo.pulsar.common.api.Commands.newLookupResponse) Suspended(javax.ws.rs.container.Suspended) PulsarWebResource(com.yahoo.pulsar.broker.web.PulsarWebResource) Response(javax.ws.rs.core.Response) WebApplicationException(javax.ws.rs.WebApplicationException) PulsarClientException(com.yahoo.pulsar.client.api.PulsarClientException) CompletableFuture(java.util.concurrent.CompletableFuture) RestException(com.yahoo.pulsar.broker.web.RestException) ByteBuf(io.netty.buffer.ByteBuf) LookupData(com.yahoo.pulsar.common.lookup.data.LookupData) RestException(com.yahoo.pulsar.broker.web.RestException) URISyntaxException(java.net.URISyntaxException) WebApplicationException(javax.ws.rs.WebApplicationException) PulsarClientException(com.yahoo.pulsar.client.api.PulsarClientException)

Example 62 with RestException

use of com.yahoo.pulsar.broker.web.RestException in project pulsar by yahoo.

the class Brokers method updateDynamicConfigurationOnZk.

/**
     * if {@link ServiceConfiguration}-field is allowed to be modified dynamically, update configuration-map into zk, so
     * all other brokers get the watch and can see the change and take appropriate action on the change.
     * 
     * @param configName
     *            : configuration key
     * @param configValue
     *            : configuration value
     */
private synchronized void updateDynamicConfigurationOnZk(String configName, String configValue) {
    try {
        if (BrokerService.getDynamicConfigurationMap().containsKey(configName)) {
            ZooKeeperDataCache<Map<String, String>> dynamicConfigurationCache = pulsar().getBrokerService().getDynamicConfigurationCache();
            Map<String, String> configurationMap = dynamicConfigurationCache.get(BROKER_SERVICE_CONFIGURATION_PATH).orElse(null);
            if (configurationMap != null) {
                configurationMap.put(configName, configValue);
                byte[] content = ObjectMapperFactory.getThreadLocal().writeValueAsBytes(configurationMap);
                dynamicConfigurationCache.invalidate(BROKER_SERVICE_CONFIGURATION_PATH);
                serviceConfigZkVersion = localZk().setData(BROKER_SERVICE_CONFIGURATION_PATH, content, serviceConfigZkVersion).getVersion();
            } else {
                configurationMap = Maps.newHashMap();
                configurationMap.put(configName, configValue);
                byte[] content = ObjectMapperFactory.getThreadLocal().writeValueAsBytes(configurationMap);
                ZkUtils.createFullPathOptimistic(localZk(), BROKER_SERVICE_CONFIGURATION_PATH, content, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            }
            LOG.info("[{}] Updated Service configuration {}/{}", clientAppId(), configName, configValue);
        } else {
            if (LOG.isDebugEnabled()) {
                LOG.debug("[{}] Can't update non-dynamic configuration {}/{}", clientAppId(), configName, configValue);
            }
            throw new RestException(Status.PRECONDITION_FAILED, " Can't update non-dynamic configuration");
        }
    } catch (RestException re) {
        throw re;
    } catch (Exception ie) {
        LOG.error("[{}] Failed to update configuration {}/{}, {}", clientAppId(), configName, configValue, ie.getMessage(), ie);
        throw new RestException(ie);
    }
}
Also used : RestException(com.yahoo.pulsar.broker.web.RestException) Map(java.util.Map) RestException(com.yahoo.pulsar.broker.web.RestException)

Example 63 with RestException

use of com.yahoo.pulsar.broker.web.RestException in project pulsar by yahoo.

the class Brokers method getAllDynamicConfigurations.

@GET
@Path("/configuration/values")
@ApiOperation(value = "Get value of all dynamic configurations' value overridden on local config")
@ApiResponses(value = { @ApiResponse(code = 404, message = "Configuration not found") })
public Map<String, String> getAllDynamicConfigurations() throws Exception {
    ZooKeeperDataCache<Map<String, String>> dynamicConfigurationCache = pulsar().getBrokerService().getDynamicConfigurationCache();
    Map<String, String> configurationMap = null;
    try {
        configurationMap = dynamicConfigurationCache.get(BROKER_SERVICE_CONFIGURATION_PATH).orElseThrow(() -> new RestException(Status.NOT_FOUND, "Couldn't find configuration in zk"));
    } catch (RestException e) {
        LOG.error("[{}] couldn't find any configuration in zk {}", clientAppId(), e.getMessage(), e);
        throw e;
    } catch (Exception e) {
        LOG.error("[{}] Failed to retrieve configuration from zk {}", clientAppId(), e.getMessage(), e);
        throw new RestException(e);
    }
    return configurationMap;
}
Also used : RestException(com.yahoo.pulsar.broker.web.RestException) Map(java.util.Map) RestException(com.yahoo.pulsar.broker.web.RestException) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 64 with RestException

use of com.yahoo.pulsar.broker.web.RestException in project pulsar by yahoo.

the class PersistentTopics method getTopicReference.

/**
     * Get the Topic object reference from the Pulsar broker
     */
private PersistentTopic getTopicReference(DestinationName dn) {
    try {
        PersistentTopic topic = (PersistentTopic) pulsar().getBrokerService().getTopicReference(dn.toString());
        checkNotNull(topic);
        return topic;
    } catch (Exception e) {
        throw new RestException(Status.NOT_FOUND, "Topic not found");
    }
}
Also used : PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) RestException(com.yahoo.pulsar.broker.web.RestException) 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)

Example 65 with RestException

use of com.yahoo.pulsar.broker.web.RestException in project pulsar by yahoo.

the class PersistentTopics method deleteSubscription.

@DELETE
@Path("/{property}/{cluster}/{namespace}/{destination}/subscription/{subName}")
@ApiOperation(value = "Delete a subscription.", notes = "There should not be any active consumers on the subscription.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Topic does not exist"), @ApiResponse(code = 412, message = "Subscription has active consumers") })
public void deleteSubscription(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("destination") @Encoded String destination, @PathParam("subName") String subName, @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) {
        try {
            for (int i = 0; i < partitionMetadata.partitions; i++) {
                pulsar().getAdminClient().persistentTopics().deleteSubscription(dn.getPartition(i).toString(), subName);
            }
        } catch (Exception e) {
            throw new RestException(e);
        }
    } else {
        validateAdminOperationOnDestination(dn, authoritative);
        PersistentTopic topic = getTopicReference(dn);
        try {
            PersistentSubscription sub = topic.getPersistentSubscription(subName);
            checkNotNull(sub);
            sub.delete().get();
            log.info("[{}][{}] Deleted subscription {}", clientAppId(), dn, subName);
        } catch (Exception e) {
            Throwable t = e.getCause();
            log.error("[{}] Failed to delete subscription {} {}", clientAppId(), dn, subName, e);
            if (e instanceof NullPointerException) {
                throw new RestException(Status.NOT_FOUND, "Subscription not found");
            } else if (t instanceof SubscriptionBusyException) {
                throw new RestException(Status.PRECONDITION_FAILED, "Subscription has active connected consumers");
            } else {
                throw new RestException(t);
            }
        }
    }
}
Also used : PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) DestinationName(com.yahoo.pulsar.common.naming.DestinationName) RestException(com.yahoo.pulsar.broker.web.RestException) SubscriptionBusyException(com.yahoo.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException) PartitionedTopicMetadata(com.yahoo.pulsar.common.partition.PartitionedTopicMetadata) 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) Path(javax.ws.rs.Path) DELETE(javax.ws.rs.DELETE) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Aggregations

RestException (com.yahoo.pulsar.broker.web.RestException)79 KeeperException (org.apache.zookeeper.KeeperException)55 ApiOperation (io.swagger.annotations.ApiOperation)54 ApiResponses (io.swagger.annotations.ApiResponses)54 Path (javax.ws.rs.Path)54 WebApplicationException (javax.ws.rs.WebApplicationException)45 SubscriptionBusyException (com.yahoo.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException)40 IOException (java.io.IOException)26 NamespaceName (com.yahoo.pulsar.common.naming.NamespaceName)25 PulsarAdminException (com.yahoo.pulsar.client.admin.PulsarAdminException)23 Policies (com.yahoo.pulsar.common.policies.data.Policies)23 PulsarClientException (com.yahoo.pulsar.client.api.PulsarClientException)22 PulsarServerException (com.yahoo.pulsar.broker.PulsarServerException)21 NotAllowedException (com.yahoo.pulsar.broker.service.BrokerServiceException.NotAllowedException)20 TopicBusyException (com.yahoo.pulsar.broker.service.BrokerServiceException.TopicBusyException)20 NotFoundException (com.yahoo.pulsar.client.admin.PulsarAdminException.NotFoundException)20 PreconditionFailedException (com.yahoo.pulsar.client.admin.PulsarAdminException.PreconditionFailedException)20 NoNodeException (org.apache.zookeeper.KeeperException.NoNodeException)20 POST (javax.ws.rs.POST)19 DestinationName (com.yahoo.pulsar.common.naming.DestinationName)18