Example usage for java.util.concurrent CompletableFuture completeExceptionally

List of usage examples for java.util.concurrent CompletableFuture completeExceptionally

Introduction

In this page you can find the example usage for java.util.concurrent CompletableFuture completeExceptionally.

Prototype

public boolean completeExceptionally(Throwable ex) 

Source Link

Document

If not already completed, causes invocations of #get() and related methods to throw the given exception.

Usage

From source file:org.apache.pulsar.broker.admin.impl.PersistentTopicsBase.java

private CompletableFuture<Void> updatePartitionedTopic(TopicName topicName, int numPartitions) {
    final String path = ZkAdminPaths.partitionedTopicPath(topicName);

    CompletableFuture<Void> updatePartition = new CompletableFuture<>();
    createSubscriptions(topicName, numPartitions).thenAccept(res -> {
        try {//from w  ww. j  av  a  2 s.  c o  m
            byte[] data = jsonMapper().writeValueAsBytes(new PartitionedTopicMetadata(numPartitions));
            globalZk().setData(path, data, -1, (rc, path1, ctx, stat) -> {
                if (rc == KeeperException.Code.OK.intValue()) {
                    updatePartition.complete(null);
                } else {
                    updatePartition.completeExceptionally(KeeperException.create(KeeperException.Code.get(rc),
                            "failed to create update partitions"));
                }
            }, null);
        } catch (Exception e) {
            updatePartition.completeExceptionally(e);
        }
    }).exceptionally(ex -> {
        updatePartition.completeExceptionally(ex);
        return null;
    });

    return updatePartition;
}

From source file:org.apache.pulsar.broker.admin.impl.PersistentTopicsBase.java

/**
 * It creates subscriptions for new partitions of existing partitioned-topics
 *
 * @param topicName/* ww w.j  av a 2  s.  c  o  m*/
 *            : topic-name: persistent://prop/cluster/ns/topic
 * @param numPartitions
 *            : number partitions for the topics
 */
private CompletableFuture<Void> createSubscriptions(TopicName topicName, int numPartitions) {
    String path = path(PARTITIONED_TOPIC_PATH_ZNODE, topicName.getPersistenceNamingEncoding());
    CompletableFuture<Void> result = new CompletableFuture<>();
    fetchPartitionedTopicMetadataAsync(pulsar(), path).thenAccept(partitionMetadata -> {
        if (partitionMetadata.partitions <= 1) {
            result.completeExceptionally(new RestException(Status.CONFLICT, "Topic is not partitioned topic"));
            return;
        }

        if (partitionMetadata.partitions >= numPartitions) {
            result.completeExceptionally(new RestException(Status.CONFLICT,
                    "number of partitions must be more than existing " + partitionMetadata.partitions));
            return;
        }

        PulsarAdmin admin;
        try {
            admin = pulsar().getAdminClient();
        } catch (PulsarServerException e1) {
            result.completeExceptionally(e1);
            return;
        }

        admin.topics().getStatsAsync(topicName.getPartition(0).toString()).thenAccept(stats -> {
            stats.subscriptions.keySet().forEach(subscription -> {
                List<CompletableFuture<Void>> subscriptionFutures = new ArrayList<>();
                for (int i = partitionMetadata.partitions; i < numPartitions; i++) {
                    final String topicNamePartition = topicName.getPartition(i).toString();

                    subscriptionFutures.add(admin.topics().createSubscriptionAsync(topicNamePartition,
                            subscription, MessageId.latest));
                }

                FutureUtil.waitForAll(subscriptionFutures).thenRun(() -> {
                    log.info("[{}] Successfully created new partitions {}", clientAppId(), topicName);
                    result.complete(null);
                }).exceptionally(ex -> {
                    log.warn("[{}] Failed to create subscriptions on new partitions for {}", clientAppId(),
                            topicName, ex);
                    result.completeExceptionally(ex);
                    return null;
                });
            });
        }).exceptionally(ex -> {
            if (ex.getCause() instanceof PulsarAdminException.NotFoundException) {
                // The first partition doesn't exist, so there are currently to subscriptions to recreate
                result.complete(null);
            } else {
                log.warn("[{}] Failed to get list of subscriptions of {}", clientAppId(),
                        topicName.getPartition(0), ex);
                result.completeExceptionally(ex);
            }
            return null;
        });
    }).exceptionally(ex -> {
        log.warn("[{}] Failed to get partition metadata for {}", clientAppId(), topicName.toString());
        result.completeExceptionally(ex);
        return null;
    });
    return result;
}

From source file:org.apache.pulsar.broker.authorization.AuthorizationService.java

/**
 * Check whether the specified role can perform a lookup for the specified topic.
 *
 * For that the caller needs to have producer or consumer permission.
 *
 * @param topicName/*from w ww  . j a  v a2s. co  m*/
 * @param role
 * @return
 * @throws Exception
 */
public CompletableFuture<Boolean> canLookupAsync(TopicName topicName, String role,
        AuthenticationDataSource authenticationData) {
    CompletableFuture<Boolean> finalResult = new CompletableFuture<Boolean>();
    canProduceAsync(topicName, role, authenticationData).whenComplete((produceAuthorized, ex) -> {
        if (ex == null) {
            if (produceAuthorized) {
                finalResult.complete(produceAuthorized);
                return;
            }
        } else {
            if (log.isDebugEnabled()) {
                log.debug(
                        "Topic [{}] Role [{}] exception occured while trying to check Produce permissions. {}",
                        topicName.toString(), role, ex.getMessage());
            }
        }
        canConsumeAsync(topicName, role, null, null).whenComplete((consumeAuthorized, e) -> {
            if (e == null) {
                if (consumeAuthorized) {
                    finalResult.complete(consumeAuthorized);
                    return;
                }
            } else {
                if (log.isDebugEnabled()) {
                    log.debug(
                            "Topic [{}] Role [{}] exception occured while trying to check Consume permissions. {}",
                            topicName.toString(), role, e.getMessage());

                }
                finalResult.completeExceptionally(e);
                return;
            }
            finalResult.complete(false);
        });
    });
    return finalResult;
}

From source file:org.apache.pulsar.broker.authorization.PulsarAuthorizationProvider.java

/**
 * Check if the specified role has permission to receive messages from the specified fully qualified topic
 * name.//from ww w.  jav a  2 s.co  m
 *
 * @param topicName
 *            the fully qualified topic name associated with the topic.
 * @param role
 *            the app id used to receive messages from the topic.
 * @param subscription
 *            the subscription name defined by the client
 */
@Override
public CompletableFuture<Boolean> canConsumeAsync(TopicName topicName, String role,
        AuthenticationDataSource authenticationData, String subscription) {
    CompletableFuture<Boolean> permissionFuture = new CompletableFuture<>();
    try {
        configCache.policiesCache().getAsync(POLICY_ROOT + topicName.getNamespace()).thenAccept(policies -> {
            if (!policies.isPresent()) {
                if (log.isDebugEnabled()) {
                    log.debug("Policies node couldn't be found for topic : {}", topicName);
                }
            } else {
                if (isNotBlank(subscription)) {
                    // validate if role is authorize to access subscription. (skip validatation if authorization
                    // list is empty)
                    Set<String> roles = policies.get().auth_policies.subscription_auth_roles.get(subscription);
                    if (roles != null && !roles.isEmpty() && !roles.contains(role)) {
                        log.warn("[{}] is not authorized to subscribe on {}-{}", role, topicName, subscription);
                        PulsarServerException ex = new PulsarServerException(
                                String.format("%s is not authorized to access subscription %s on topic %s",
                                        role, subscription, topicName));
                        permissionFuture.complete(false);
                        return;
                    }

                    // validate if subscription-auth mode is configured
                    switch (policies.get().subscription_auth_mode) {
                    case Prefix:
                        if (!subscription.startsWith(role)) {
                            PulsarServerException ex = new PulsarServerException(String.format(
                                    "Failed to create consumer - The subscription name needs to be prefixed by the authentication role, like %s-xxxx for topic: %s",
                                    role, topicName));
                            permissionFuture.completeExceptionally(ex);
                            return;
                        }
                        break;
                    default:
                        break;
                    }
                }
            }
            // check namespace and topic level consume-permissions
            checkAuthorization(topicName, role, AuthAction.consume).thenAccept(isAuthorized -> {
                permissionFuture.complete(isAuthorized);
            });
        }).exceptionally(ex -> {
            log.warn("Client with Role - {} failed to get permissions for topic - {}. {}", role, topicName,
                    ex.getMessage());
            permissionFuture.completeExceptionally(ex);
            return null;
        });
    } catch (Exception e) {
        log.warn("Client  with Role - {} failed to get permissions for topic - {}. {}", role, topicName,
                e.getMessage());
        permissionFuture.completeExceptionally(e);
    }
    return permissionFuture;
}

From source file:org.apache.pulsar.broker.authorization.PulsarAuthorizationProvider.java

/**
 * Check whether the specified role can perform a lookup for the specified topic.
 *
 * For that the caller needs to have producer or consumer permission.
 *
 * @param topicName//w  ww  .j  av a 2s  .c  o  m
 * @param role
 * @return
 * @throws Exception
 */
@Override
public CompletableFuture<Boolean> canLookupAsync(TopicName topicName, String role,
        AuthenticationDataSource authenticationData) {
    CompletableFuture<Boolean> finalResult = new CompletableFuture<Boolean>();
    canProduceAsync(topicName, role, authenticationData).whenComplete((produceAuthorized, ex) -> {
        if (ex == null) {
            if (produceAuthorized) {
                finalResult.complete(produceAuthorized);
                return;
            }
        } else {
            if (log.isDebugEnabled()) {
                log.debug(
                        "Topic [{}] Role [{}] exception occured while trying to check Produce permissions. {}",
                        topicName.toString(), role, ex.getMessage());
            }
        }
        canConsumeAsync(topicName, role, authenticationData, null).whenComplete((consumeAuthorized, e) -> {
            if (e == null) {
                if (consumeAuthorized) {
                    finalResult.complete(consumeAuthorized);
                    return;
                }
            } else {
                if (log.isDebugEnabled()) {
                    log.debug(
                            "Topic [{}] Role [{}] exception occured while trying to check Consume permissions. {}",
                            topicName.toString(), role, e.getMessage());

                }
                finalResult.completeExceptionally(e);
                return;
            }
            finalResult.complete(false);
        });
    });
    return finalResult;
}

From source file:org.apache.pulsar.broker.authorization.PulsarAuthorizationProvider.java

@Override
public CompletableFuture<Void> grantPermissionAsync(NamespaceName namespaceName, Set<AuthAction> actions,
        String role, String authDataJson) {
    CompletableFuture<Void> result = new CompletableFuture<>();

    try {//from   www  .  ja va2  s  .c  om
        validatePoliciesReadOnlyAccess();
    } catch (Exception e) {
        result.completeExceptionally(e);
    }

    ZooKeeper globalZk = configCache.getZooKeeper();
    final String policiesPath = String.format("/%s/%s/%s", "admin", POLICIES, namespaceName.toString());

    try {
        Stat nodeStat = new Stat();
        byte[] content = globalZk.getData(policiesPath, null, nodeStat);
        Policies policies = getThreadLocal().readValue(content, Policies.class);
        policies.auth_policies.namespace_auth.put(role, actions);

        // Write back the new policies into zookeeper
        globalZk.setData(policiesPath, getThreadLocal().writeValueAsBytes(policies), nodeStat.getVersion());

        configCache.policiesCache().invalidate(policiesPath);

        log.info("[{}] Successfully granted access for role {}: {} - namespace {}", role, role, actions,
                namespaceName);
        result.complete(null);
    } catch (KeeperException.NoNodeException e) {
        log.warn("[{}] Failed to set permissions for namespace {}: does not exist", role, namespaceName);
        result.completeExceptionally(new IllegalArgumentException("Namespace does not exist" + namespaceName));
    } catch (KeeperException.BadVersionException e) {
        log.warn("[{}] Failed to set permissions for namespace {}: concurrent modification", role,
                namespaceName);
        result.completeExceptionally(new IllegalStateException(
                "Concurrent modification on zk path: " + policiesPath + ", " + e.getMessage()));
    } catch (Exception e) {
        log.error("[{}] Failed to get permissions for namespace {}", role, namespaceName, e);
        result.completeExceptionally(
                new IllegalStateException("Failed to get permissions for namespace " + namespaceName));
    }

    return result;
}

From source file:org.apache.pulsar.broker.authorization.PulsarAuthorizationProvider.java

private CompletableFuture<Void> updateSubscriptionPermissionAsync(NamespaceName namespace,
        String subscriptionName, Set<String> roles, boolean remove) {
    CompletableFuture<Void> result = new CompletableFuture<>();

    try {/*from   ww  w . j  a  va2s.c  o m*/
        validatePoliciesReadOnlyAccess();
    } catch (Exception e) {
        result.completeExceptionally(e);
    }

    ZooKeeper globalZk = configCache.getZooKeeper();
    final String policiesPath = String.format("/%s/%s/%s", "admin", POLICIES, namespace.toString());

    try {
        Stat nodeStat = new Stat();
        byte[] content = globalZk.getData(policiesPath, null, nodeStat);
        Policies policies = getThreadLocal().readValue(content, Policies.class);
        if (remove) {
            if (policies.auth_policies.subscription_auth_roles.get(subscriptionName) != null) {
                policies.auth_policies.subscription_auth_roles.get(subscriptionName).removeAll(roles);
            } else {
                log.info("[{}] Couldn't find role {} while revoking for sub = {}", namespace, subscriptionName,
                        roles);
                result.completeExceptionally(new IllegalArgumentException("couldn't find subscription"));
                return result;
            }
        } else {
            policies.auth_policies.subscription_auth_roles.put(subscriptionName, roles);
        }

        // Write back the new policies into zookeeper
        globalZk.setData(policiesPath, getThreadLocal().writeValueAsBytes(policies), nodeStat.getVersion());

        configCache.policiesCache().invalidate(policiesPath);

        log.info("[{}] Successfully granted access for role {} for sub = {}", namespace, subscriptionName,
                roles);
        result.complete(null);
    } catch (KeeperException.NoNodeException e) {
        log.warn("[{}] Failed to set permissions for namespace {}: does not exist", subscriptionName,
                namespace);
        result.completeExceptionally(new IllegalArgumentException("Namespace does not exist" + namespace));
    } catch (KeeperException.BadVersionException e) {
        log.warn("[{}] Failed to set permissions for {} on namespace {}: concurrent modification",
                subscriptionName, roles, namespace);
        result.completeExceptionally(new IllegalStateException(
                "Concurrent modification on zk path: " + policiesPath + ", " + e.getMessage()));
    } catch (Exception e) {
        log.error("[{}] Failed to get permissions for role {} on namespace {}", subscriptionName, roles,
                namespace, e);
        result.completeExceptionally(
                new IllegalStateException("Failed to get permissions for namespace " + namespace));
    }

    return result;
}

From source file:org.apache.pulsar.broker.authorization.PulsarAuthorizationProvider.java

public CompletableFuture<Boolean> checkPermission(TopicName topicName, String role, AuthAction action) {
    CompletableFuture<Boolean> permissionFuture = new CompletableFuture<>();
    try {//from  w w  w . ja v  a  2  s  .  co m
        configCache.policiesCache().getAsync(POLICY_ROOT + topicName.getNamespace()).thenAccept(policies -> {
            if (!policies.isPresent()) {
                if (log.isDebugEnabled()) {
                    log.debug("Policies node couldn't be found for topic : {}", topicName);
                }
            } else {
                Map<String, Set<AuthAction>> namespaceRoles = policies.get().auth_policies.namespace_auth;
                Set<AuthAction> namespaceActions = namespaceRoles.get(role);
                if (namespaceActions != null && namespaceActions.contains(action)) {
                    // The role has namespace level permission
                    permissionFuture.complete(true);
                    return;
                }

                Map<String, Set<AuthAction>> topicRoles = policies.get().auth_policies.destination_auth
                        .get(topicName.toString());
                if (topicRoles != null) {
                    // Topic has custom policy
                    Set<AuthAction> topicActions = topicRoles.get(role);
                    if (topicActions != null && topicActions.contains(action)) {
                        // The role has topic level permission
                        permissionFuture.complete(true);
                        return;
                    }
                }

                // Using wildcard
                if (conf.isAuthorizationAllowWildcardsMatching()) {
                    if (checkWildcardPermission(role, action, namespaceRoles)) {
                        // The role has namespace level permission by wildcard match
                        permissionFuture.complete(true);
                        return;
                    }

                    if (topicRoles != null && checkWildcardPermission(role, action, topicRoles)) {
                        // The role has topic level permission by wildcard match
                        permissionFuture.complete(true);
                        return;
                    }
                }
            }
            permissionFuture.complete(false);
        }).exceptionally(ex -> {
            log.warn("Client  with Role - {} failed to get permissions for topic - {}. {}", role, topicName,
                    ex.getMessage());
            permissionFuture.completeExceptionally(ex);
            return null;
        });
    } catch (Exception e) {
        log.warn("Client  with Role - {} failed to get permissions for topic - {}. {}", role, topicName,
                e.getMessage());
        permissionFuture.completeExceptionally(e);
    }
    return permissionFuture;
}

From source file:org.apache.pulsar.broker.lookup.TopicLookup.java

/**
 *
 * 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./*from  w  w  w. j  a  v  a 2  s  . com*/
 *
 * @param pulsarService
 * @param topicName
 * @param authoritative
 * @param clientAppId
 * @param requestId
 * @return
 */
public static CompletableFuture<ByteBuf> lookupTopicAsync(PulsarService pulsarService, TopicName topicName,
        boolean authoritative, String clientAppId, AuthenticationDataSource authenticationData,
        long requestId) {

    final CompletableFuture<ByteBuf> validationFuture = new CompletableFuture<>();
    final CompletableFuture<ByteBuf> lookupfuture = new CompletableFuture<>();
    final String cluster = topicName.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,
                    false));
        } else {
            // (2) authorize client
            try {
                checkAuthorization(pulsarService, topicName, clientAppId, authenticationData);
            } catch (RestException authException) {
                log.warn("Failed to authorized {} on cluster {}", clientAppId, topicName.toString());
                validationFuture.complete(newLookupErrorResponse(ServerError.AuthorizationError,
                        authException.getMessage(), requestId));
                return;
            } catch (Exception e) {
                log.warn("Unknown error while authorizing {} on cluster {}", clientAppId, topicName.toString());
                validationFuture.completeExceptionally(e);
                return;
            }
            // (3) validate global namespace
            checkLocalOrGetPeerReplicationCluster(pulsarService, topicName.getNamespaceObject())
                    .thenAccept(peerClusterData -> {
                        if (peerClusterData == null) {
                            // (4) all validation passed: initiate lookup
                            validationFuture.complete(null);
                            return;
                        }
                        // if peer-cluster-data is present it means namespace is owned by that peer-cluster and
                        // request should be redirect to the peer-cluster
                        if (StringUtils.isBlank(peerClusterData.getBrokerServiceUrl())
                                && StringUtils.isBlank(peerClusterData.getBrokerServiceUrl())) {
                            validationFuture.complete(newLookupErrorResponse(ServerError.MetadataError,
                                    "Redirected cluster's brokerService url is not configured", requestId));
                            return;
                        }
                        validationFuture.complete(newLookupResponse(peerClusterData.getBrokerServiceUrl(),
                                peerClusterData.getBrokerServiceUrlTls(), true, LookupType.Redirect, requestId,
                                false));

                    }).exceptionally(ex -> {
                        validationFuture.complete(
                                newLookupErrorResponse(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(topicName, authoritative)
                    .thenAccept(lookupResult -> {

                        if (log.isDebugEnabled()) {
                            log.debug("[{}] Lookup result {}", topicName.toString(), lookupResult);
                        }

                        if (!lookupResult.isPresent()) {
                            lookupfuture.complete(newLookupErrorResponse(ServerError.ServiceNotReady,
                                    "No broker was available to own " + topicName, requestId));
                            return;
                        }

                        LookupData lookupData = lookupResult.get().getLookupData();
                        if (lookupResult.get().isRedirect()) {
                            boolean newAuthoritative = isLeaderBroker(pulsarService);
                            lookupfuture.complete(
                                    newLookupResponse(lookupData.getBrokerUrl(), lookupData.getBrokerUrlTls(),
                                            newAuthoritative, LookupType.Redirect, requestId, false));
                        } else {
                            // When running in standalone mode we want to redirect the client through the service
                            // url, so that the advertised address configuration is not relevant anymore.
                            boolean redirectThroughServiceUrl = pulsarService.getConfiguration()
                                    .isRunningStandalone();

                            lookupfuture.complete(newLookupResponse(lookupData.getBrokerUrl(),
                                    lookupData.getBrokerUrlTls(), true /* authoritative */, LookupType.Connect,
                                    requestId, redirectThroughServiceUrl));
                        }
                    }).exceptionally(ex -> {
                        if (ex instanceof CompletionException
                                && ex.getCause() instanceof IllegalStateException) {
                            log.info("Failed to lookup {} for topic {} with error {}", clientAppId,
                                    topicName.toString(), ex.getCause().getMessage());
                        } else {
                            log.warn("Failed to lookup {} for topic {} with error {}", clientAppId,
                                    topicName.toString(), ex.getMessage(), ex);
                        }
                        lookupfuture.complete(newLookupErrorResponse(ServerError.ServiceNotReady,
                                ex.getMessage(), requestId));
                        return null;
                    });
        }

    }).exceptionally(ex -> {
        if (ex instanceof CompletionException && ex.getCause() instanceof IllegalStateException) {
            log.info("Failed to lookup {} for topic {} with error {}", clientAppId, topicName.toString(),
                    ex.getCause().getMessage());
        } else {
            log.warn("Failed to lookup {} for topic {} with error {}", clientAppId, topicName.toString(),
                    ex.getMessage(), ex);
        }

        lookupfuture.complete(newLookupErrorResponse(ServerError.ServiceNotReady, ex.getMessage(), requestId));
        return null;
    });

    return lookupfuture;
}

From source file:org.apache.pulsar.broker.namespace.NamespaceService.java

private void searchForCandidateBroker(NamespaceBundle bundle, CompletableFuture<LookupResult> lookupFuture,
        boolean authoritative) {
    String candidateBroker = null;
    try {/*from w  w w. j a  v a 2s.co m*/
        // check if this is Heartbeat or SLAMonitor namespace
        candidateBroker = checkHeartbeatNamespace(bundle);
        if (candidateBroker == null) {
            String broker = getSLAMonitorBrokerName(bundle);
            // checking if the broker is up and running
            if (broker != null && isBrokerActive(broker)) {
                candidateBroker = broker;
            }
        }

        if (candidateBroker == null) {
            if (!this.loadManager.get().isCentralized() || pulsar.getLeaderElectionService().isLeader()) {
                candidateBroker = getLeastLoadedFromLoadManager(bundle);
            } else {
                if (authoritative) {
                    // leader broker already assigned the current broker as owner
                    candidateBroker = pulsar.getWebServiceAddress();
                } else {
                    // forward to leader broker to make assignment
                    candidateBroker = pulsar.getLeaderElectionService().getCurrentLeader().getServiceUrl();
                }
            }
        }
    } catch (Exception e) {
        LOG.warn("Error when searching for candidate broker to acquire {}: {}", bundle, e.getMessage(), e);
        lookupFuture.completeExceptionally(e);
        return;
    }

    try {
        checkNotNull(candidateBroker);

        if (pulsar.getWebServiceAddress().equals(candidateBroker)) {
            // Load manager decided that the local broker should try to become the owner
            ownershipCache.tryAcquiringOwnership(bundle).thenAccept(ownerInfo -> {
                if (ownerInfo.isDisabled()) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Namespace bundle {} is currently being unloaded", bundle);
                    }
                    lookupFuture.completeExceptionally(new IllegalStateException(
                            String.format("Namespace bundle %s is currently being unloaded", bundle)));
                } else {
                    // Found owner for the namespace bundle

                    // Schedule the task to pre-load destinations
                    pulsar.loadNamespaceDestinations(bundle);

                    lookupFuture.complete(new LookupResult(ownerInfo));
                }
            }).exceptionally(exception -> {
                LOG.warn("Failed to acquire ownership for namespace bundle {}: ", bundle,
                        exception.getMessage(), exception);
                lookupFuture.completeExceptionally(new PulsarServerException(
                        "Failed to acquire ownership for namespace bundle " + bundle, exception));
                return null;
            });

        } else {
            // Load managed decider some other broker should try to acquire ownership

            if (LOG.isDebugEnabled()) {
                LOG.debug("Redirecting to broker {} to acquire ownership of bundle {}", candidateBroker,
                        bundle);
            }

            // Now setting the redirect url
            createLookupResult(candidateBroker).thenAccept(lookupResult -> lookupFuture.complete(lookupResult))
                    .exceptionally(ex -> {
                        lookupFuture.completeExceptionally(ex);
                        return null;
                    });

        }
    } catch (Exception e) {
        LOG.warn("Error in trying to acquire namespace bundle ownership for {}: {}", bundle, e.getMessage(), e);
        lookupFuture.completeExceptionally(e);
    }
}