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.service.persistent.PersistentTopic.java

private CompletableFuture<Void> checkReplicationAndRetryOnFailure() {
    CompletableFuture<Void> result = new CompletableFuture<Void>();
    checkReplication().thenAccept(res -> {
        log.info("[{}] Policies updated successfully", topic);
        result.complete(null);/*w  w  w. java 2 s .co  m*/
    }).exceptionally(th -> {
        log.error("[{}] Policies update failed {}, scheduled retry in {} seconds", topic, th.getMessage(),
                POLICY_UPDATE_FAILURE_RETRY_TIME_SECONDS, th);
        brokerService.executor().schedule(this::checkReplicationAndRetryOnFailure,
                POLICY_UPDATE_FAILURE_RETRY_TIME_SECONDS, TimeUnit.SECONDS);
        result.completeExceptionally(th);
        return null;
    });
    return result;
}

From source file:org.apache.pulsar.broker.service.persistent.PersistentTopic.java

private CompletableFuture<Void> checkPersistencePolicies() {
    TopicName topicName = TopicName.get(topic);
    CompletableFuture<Void> future = new CompletableFuture<>();
    brokerService.getManagedLedgerConfig(topicName).thenAccept(config -> {
        // update managed-ledger config and managed-cursor.markDeleteRate
        this.ledger.setConfig(config);
        future.complete(null);//from w w  w.  j  av  a2s. c o m
    }).exceptionally(ex -> {
        log.warn("[{}] Failed to update persistence-policies {}", topic, ex.getMessage());
        future.completeExceptionally(ex);
        return null;
    });
    return future;
}

From source file:org.apache.pulsar.broker.service.persistent.PersistentTopic.java

@Override
public CompletableFuture<Void> checkReplication() {
    TopicName name = TopicName.get(topic);
    if (!name.isGlobal()) {
        return CompletableFuture.completedFuture(null);
    }/*from   www . ja  v a  2s. co m*/

    if (log.isDebugEnabled()) {
        log.debug("[{}] Checking replication status", name);
    }

    Policies policies = null;
    try {
        policies = brokerService.pulsar().getConfigurationCache().policiesCache()
                .get(AdminResource.path(POLICIES, name.getNamespace()))
                .orElseThrow(() -> new KeeperException.NoNodeException());
    } catch (Exception e) {
        CompletableFuture<Void> future = new CompletableFuture<>();
        future.completeExceptionally(new ServerMetadataException(e));
        return future;
    }

    final int newMessageTTLinSeconds = policies.message_ttl_in_seconds;

    Set<String> configuredClusters;
    if (policies.replication_clusters != null) {
        configuredClusters = Sets.newTreeSet(policies.replication_clusters);
    } else {
        configuredClusters = Collections.emptySet();
    }

    String localCluster = brokerService.pulsar().getConfiguration().getClusterName();

    // if local cluster is removed from global namespace cluster-list : then delete topic forcefully because pulsar
    // doesn't serve global topic without local repl-cluster configured.
    if (TopicName.get(topic).isGlobal() && !configuredClusters.contains(localCluster)) {
        log.info("Deleting topic [{}] because local cluster is not part of global namespace repl list {}",
                configuredClusters);
        return deleteForcefully();
    }

    List<CompletableFuture<Void>> futures = Lists.newArrayList();

    // Check for missing replicators
    for (String cluster : configuredClusters) {
        if (cluster.equals(localCluster)) {
            continue;
        }

        if (!replicators.containsKey(cluster)) {
            futures.add(startReplicator(cluster));
        }
    }

    // Check for replicators to be stopped
    replicators.forEach((cluster, replicator) -> {
        // Update message TTL
        ((PersistentReplicator) replicator).updateMessageTTL(newMessageTTLinSeconds);

        if (!cluster.equals(localCluster)) {
            if (!configuredClusters.contains(cluster)) {
                futures.add(removeReplicator(cluster));
            }
        }

    });

    return FutureUtil.waitForAll(futures);
}

From source file:org.apache.pulsar.broker.service.persistent.PersistentTopic.java

CompletableFuture<Void> startReplicator(String remoteCluster) {
    log.info("[{}] Starting replicator to remote: {}", topic, remoteCluster);
    final CompletableFuture<Void> future = new CompletableFuture<>();

    String name = PersistentReplicator.getReplicatorName(replicatorPrefix, remoteCluster);
    ledger.asyncOpenCursor(name, new OpenCursorCallback() {
        @Override/*from w w w .j  av a2  s.  co m*/
        public void openCursorComplete(ManagedCursor cursor, Object ctx) {
            String localCluster = brokerService.pulsar().getConfiguration().getClusterName();
            boolean isReplicatorStarted = addReplicationCluster(remoteCluster, PersistentTopic.this, cursor,
                    localCluster);
            if (isReplicatorStarted) {
                future.complete(null);
            } else {
                future.completeExceptionally(new NamingException(
                        PersistentTopic.this.getName() + " Failed to start replicator " + remoteCluster));
            }
        }

        @Override
        public void openCursorFailed(ManagedLedgerException exception, Object ctx) {
            future.completeExceptionally(new PersistenceException(exception));
        }

    }, null);

    return future;
}

From source file:org.apache.pulsar.broker.service.persistent.PersistentTopic.java

CompletableFuture<Void> removeReplicator(String remoteCluster) {
    log.info("[{}] Removing replicator to {}", topic, remoteCluster);
    final CompletableFuture<Void> future = new CompletableFuture<>();

    String name = PersistentReplicator.getReplicatorName(replicatorPrefix, remoteCluster);

    replicators.get(remoteCluster).disconnect().thenRun(() -> {

        ledger.asyncDeleteCursor(name, new DeleteCursorCallback() {
            @Override/*  ww w  . ja va 2s  .c om*/
            public void deleteCursorComplete(Object ctx) {
                replicators.remove(remoteCluster);
                future.complete(null);
            }

            @Override
            public void deleteCursorFailed(ManagedLedgerException exception, Object ctx) {
                log.error("[{}] Failed to delete cursor {} {}", topic, name, exception.getMessage(), exception);
                future.completeExceptionally(new PersistenceException(exception));
            }
        }, null);

    }).exceptionally(e -> {
        log.error("[{}] Failed to close replication producer {} {}", topic, name, e.getMessage(), e);
        future.completeExceptionally(e);
        return null;
    });

    return future;
}

From source file:org.apache.pulsar.broker.service.persistent.PersistentTopic.java

@Override
public void checkGC(int gcIntervalInSeconds) {
    if (isActive()) {
        lastActive = System.nanoTime();
    } else if (System.nanoTime() - lastActive < TimeUnit.SECONDS.toNanos(gcIntervalInSeconds)) {
        // Gc interval did not expire yet
        return;/*from   w w  w. j a va 2s.  co  m*/
    } else if (shouldTopicBeRetained()) {
        // Topic activity is still within the retention period
        return;
    } else {
        CompletableFuture<Void> replCloseFuture = new CompletableFuture<>();

        if (TopicName.get(topic).isGlobal()) {
            // For global namespace, close repl producers first.
            // Once all repl producers are closed, we can delete the topic,
            // provided no remote producers connected to the broker.
            if (log.isDebugEnabled()) {
                log.debug("[{}] Global topic inactive for {} seconds, closing repl producers.", topic,
                        gcIntervalInSeconds);
            }
            closeReplProducersIfNoBacklog().thenRun(() -> {
                if (hasRemoteProducers()) {
                    if (log.isDebugEnabled()) {
                        log.debug("[{}] Global topic has connected remote producers. Not a candidate for GC",
                                topic);
                    }
                    replCloseFuture.completeExceptionally(
                            new TopicBusyException("Topic has connected remote producers"));
                } else {
                    log.info("[{}] Global topic inactive for {} seconds, closed repl producers", topic,
                            gcIntervalInSeconds);
                    replCloseFuture.complete(null);
                }
            }).exceptionally(e -> {
                if (log.isDebugEnabled()) {
                    log.debug("[{}] Global topic has replication backlog. Not a candidate for GC", topic);
                }
                replCloseFuture.completeExceptionally(e.getCause());
                return null;
            });
        } else {
            replCloseFuture.complete(null);
        }

        replCloseFuture.thenCompose(v -> delete(true))
                .thenRun(() -> log.info("[{}] Topic deleted successfully due to inactivity", topic))
                .exceptionally(e -> {
                    if (e.getCause() instanceof TopicBusyException) {
                        // topic became active again
                        if (log.isDebugEnabled()) {
                            log.debug("[{}] Did not delete busy topic: {}", topic, e.getCause().getMessage());
                        }
                    } else {
                        log.warn("[{}] Inactive topic deletion failed", topic, e);
                    }
                    return null;
                });

    }
}

From source file:org.apache.pulsar.broker.service.persistent.PersistentTopic.java

public CompletableFuture<MessageId> terminate() {
    CompletableFuture<MessageId> future = new CompletableFuture<>();
    ledger.asyncTerminate(new TerminateCallback() {
        @Override//from  w ww . ja va 2 s. c o m
        public void terminateComplete(Position lastCommittedPosition, Object ctx) {
            producers.forEach(Producer::disconnect);
            subscriptions.forEach((name, sub) -> sub.topicTerminated());

            PositionImpl lastPosition = (PositionImpl) lastCommittedPosition;
            MessageId messageId = new MessageIdImpl(lastPosition.getLedgerId(), lastPosition.getEntryId(), -1);

            log.info("[{}] Topic terminated at {}", getName(), messageId);
            future.complete(messageId);
        }

        @Override
        public void terminateFailed(ManagedLedgerException exception, Object ctx) {
            future.completeExceptionally(exception);
        }
    }, null);

    return future;
}

From source file:org.apache.pulsar.broker.service.persistent.PersistentTopic.java

public synchronized void triggerOffload(MessageIdImpl messageId) throws AlreadyRunningException {
    if (currentOffload.isDone()) {
        CompletableFuture<MessageIdImpl> promise = currentOffload = new CompletableFuture<>();
        getManagedLedger().asyncOffloadPrefix(PositionImpl.get(messageId.getLedgerId(), messageId.getEntryId()),
                new OffloadCallback() {
                    @Override//from  w w w.  jav a2s  . co  m
                    public void offloadComplete(Position pos, Object ctx) {
                        PositionImpl impl = (PositionImpl) pos;

                        promise.complete(new MessageIdImpl(impl.getLedgerId(), impl.getEntryId(), -1));
                    }

                    @Override
                    public void offloadFailed(ManagedLedgerException exception, Object ctx) {
                        promise.completeExceptionally(exception);
                    }
                }, null);
    } else {
        throw new AlreadyRunningException("Offload already in progress");
    }
}

From source file:org.apache.pulsar.broker.web.PulsarWebResource.java

protected static CompletableFuture<ClusterData> getClusterDataIfDifferentCluster(PulsarService pulsar,
        String cluster, String clientAppId) {

    CompletableFuture<ClusterData> clusterDataFuture = new CompletableFuture<>();

    if (!isValidCluster(pulsar, cluster)) {
        try {/*from   ww  w .ja v a  2  s. co m*/
            // this code should only happen with a v1 namespace format prop/cluster/namespaces
            if (!pulsar.getConfiguration().getClusterName().equals(cluster)) {
                // redirect to the cluster requested
                pulsar.getConfigurationCache().clustersCache().getAsync(path("clusters", cluster))
                        .thenAccept(clusterDataResult -> {
                            if (clusterDataResult.isPresent()) {
                                clusterDataFuture.complete(clusterDataResult.get());
                            } else {
                                log.warn("[{}] Cluster does not exist: requested={}", clientAppId, cluster);
                                clusterDataFuture.completeExceptionally(new RestException(Status.NOT_FOUND,
                                        "Cluster does not exist: cluster=" + cluster));
                            }
                        }).exceptionally(ex -> {
                            clusterDataFuture.completeExceptionally(ex);
                            return null;
                        });
            } else {
                clusterDataFuture.complete(null);
            }
        } catch (Exception e) {
            clusterDataFuture.completeExceptionally(e);
        }
    } else {
        clusterDataFuture.complete(null);
    }
    return clusterDataFuture;
}

From source file:org.apache.pulsar.broker.web.PulsarWebResource.java

public static CompletableFuture<ClusterData> checkLocalOrGetPeerReplicationCluster(PulsarService pulsarService,
        NamespaceName namespace) {// w ww .j  av  a 2  s.co m
    if (!namespace.isGlobal()) {
        return CompletableFuture.completedFuture(null);
    }
    final CompletableFuture<ClusterData> validationFuture = new CompletableFuture<>();
    final String localCluster = pulsarService.getConfiguration().getClusterName();
    final String path = AdminResource.path(POLICIES, namespace.toString());

    pulsarService.getConfigurationCache().policiesCache().getAsync(path).thenAccept(policiesResult -> {
        if (policiesResult.isPresent()) {
            Policies policies = policiesResult.get();
            if (policies.replication_clusters.isEmpty()) {
                String msg = String.format(
                        "Namespace does not have any clusters configured : local_cluster=%s ns=%s",
                        localCluster, namespace.toString());
                log.warn(msg);
                validationFuture.completeExceptionally(new RestException(Status.PRECONDITION_FAILED, msg));
            } else if (!policies.replication_clusters.contains(localCluster)) {
                ClusterData ownerPeerCluster = getOwnerFromPeerClusterList(pulsarService,
                        policies.replication_clusters);
                if (ownerPeerCluster != null) {
                    // found a peer that own this namespace
                    validationFuture.complete(ownerPeerCluster);
                    return;
                }
                String msg = String.format(
                        "Namespace missing local cluster name in clusters list: local_cluster=%s ns=%s clusters=%s",
                        localCluster, namespace.toString(), policies.replication_clusters);

                log.warn(msg);
                validationFuture.completeExceptionally(new RestException(Status.PRECONDITION_FAILED, msg));
            } else {
                validationFuture.complete(null);
            }
        } else {
            String msg = String.format("Policies not found for %s namespace", namespace.toString());
            log.error(msg);
            validationFuture.completeExceptionally(new RestException(Status.NOT_FOUND, msg));
        }
    }).exceptionally(ex -> {
        String msg = String.format(
                "Failed to validate global cluster configuration : cluster=%s ns=%s  emsg=%s", localCluster,
                namespace, ex.getMessage());
        log.error(msg);
        validationFuture.completeExceptionally(new RestException(ex));
        return null;
    });
    return validationFuture;
}