Search in sources :

Example 1 with TopicBusyException

use of com.yahoo.pulsar.broker.service.BrokerServiceException.TopicBusyException in project pulsar by yahoo.

the class PersistentReplicator method disconnect.

public synchronized CompletableFuture<Void> disconnect(boolean failIfHasBacklog) {
    if (failIfHasBacklog && cursor.getNumberOfEntriesInBacklog() > 0) {
        CompletableFuture<Void> disconnectFuture = new CompletableFuture<>();
        disconnectFuture.completeExceptionally(new TopicBusyException("Cannot close a replicator with backlog"));
        log.debug("[{}][{} -> {}] Replicator disconnect failed since topic has backlog", topicName, localCluster, remoteCluster);
        return disconnectFuture;
    }
    if (STATE_UPDATER.get(this) == State.Stopping) {
        // which will at some point change the state to stopped
        return CompletableFuture.completedFuture(null);
    }
    if (producer != null && (STATE_UPDATER.compareAndSet(this, State.Starting, State.Stopping) || STATE_UPDATER.compareAndSet(this, State.Started, State.Stopping))) {
        log.info("[{}][{} -> {}] Disconnect replicator at position {} with backlog {}", topicName, localCluster, remoteCluster, cursor.getMarkDeletedPosition(), cursor.getNumberOfEntriesInBacklog());
        return closeProducerAsync();
    }
    STATE_UPDATER.set(this, State.Stopped);
    return CompletableFuture.completedFuture(null);
}
Also used : TopicBusyException(com.yahoo.pulsar.broker.service.BrokerServiceException.TopicBusyException) CompletableFuture(java.util.concurrent.CompletableFuture)

Example 2 with TopicBusyException

use of com.yahoo.pulsar.broker.service.BrokerServiceException.TopicBusyException in project pulsar by yahoo.

the class PersistentTopic method delete.

/**
     * Delete the managed ledger associated with this topic
     *
     * @param failIfHasSubscriptions
     *            Flag indicating whether delete should succeed if topic still has unconnected subscriptions. Set to
     *            false when called from admin API (it will delete the subs too), and set to true when called from GC
     *            thread
     *
     * @return Completable future indicating completion of delete operation Completed exceptionally with:
     *         IllegalStateException if topic is still active ManagedLedgerException if ledger delete operation fails
     */
private CompletableFuture<Void> delete(boolean failIfHasSubscriptions) {
    CompletableFuture<Void> deleteFuture = new CompletableFuture<>();
    lock.writeLock().lock();
    try {
        if (isFenced) {
            log.warn("[{}] Topic is already being closed or deleted", topic);
            deleteFuture.completeExceptionally(new TopicFencedException("Topic is already fenced"));
            return deleteFuture;
        }
        if (USAGE_COUNT_UPDATER.get(this) == 0) {
            isFenced = true;
            List<CompletableFuture<Void>> futures = Lists.newArrayList();
            if (failIfHasSubscriptions) {
                if (!subscriptions.isEmpty()) {
                    isFenced = false;
                    deleteFuture.completeExceptionally(new TopicBusyException("Topic has subscriptions"));
                    return deleteFuture;
                }
            } else {
                subscriptions.forEach((s, sub) -> futures.add(sub.delete()));
            }
            FutureUtil.waitForAll(futures).whenComplete((v, ex) -> {
                if (ex != null) {
                    log.error("[{}] Error deleting topic", topic, ex);
                    isFenced = false;
                    deleteFuture.completeExceptionally(ex);
                } else {
                    ledger.asyncDelete(new AsyncCallbacks.DeleteLedgerCallback() {

                        @Override
                        public void deleteLedgerComplete(Object ctx) {
                            brokerService.removeTopicFromCache(topic);
                            log.info("[{}] Topic deleted", topic);
                            deleteFuture.complete(null);
                        }

                        @Override
                        public void deleteLedgerFailed(ManagedLedgerException exception, Object ctx) {
                            isFenced = false;
                            log.error("[{}] Error deleting topic", topic, exception);
                            deleteFuture.completeExceptionally(new PersistenceException(exception));
                        }
                    }, null);
                }
            });
        } else {
            deleteFuture.completeExceptionally(new TopicBusyException("Topic has " + USAGE_COUNT_UPDATER.get(this) + " connected producers/consumers"));
        }
    } finally {
        lock.writeLock().unlock();
    }
    return deleteFuture;
}
Also used : TopicBusyException(com.yahoo.pulsar.broker.service.BrokerServiceException.TopicBusyException) CompletableFuture(java.util.concurrent.CompletableFuture) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) TopicFencedException(com.yahoo.pulsar.broker.service.BrokerServiceException.TopicFencedException) PersistenceException(com.yahoo.pulsar.broker.service.BrokerServiceException.PersistenceException) AsyncCallbacks(org.apache.bookkeeper.mledger.AsyncCallbacks)

Example 3 with TopicBusyException

use of com.yahoo.pulsar.broker.service.BrokerServiceException.TopicBusyException in project pulsar by yahoo.

the class PersistentTopics method deleteTopic.

@DELETE
@Path("/{property}/{cluster}/{namespace}/{destination}")
@ApiOperation(value = "Delete a topic.", notes = "The topic cannot be deleted if there's any active subscription or producer connected to the it.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Topic does not exist"), @ApiResponse(code = 412, message = "Topic has active producers/subscriptions") })
public void deleteTopic(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("destination") @Encoded String destination, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) {
    destination = decode(destination);
    DestinationName dn = DestinationName.get(domain(), property, cluster, namespace, destination);
    validateAdminOperationOnDestination(dn, authoritative);
    PersistentTopic topic = getTopicReference(dn);
    if (dn.isGlobal()) {
        // Delete is disallowed on global topic
        log.error("[{}] Delete topic is forbidden on global namespace {}", clientAppId(), dn);
        throw new RestException(Status.FORBIDDEN, "Delete forbidden on global namespace");
    }
    try {
        topic.delete().get();
        log.info("[{}] Successfully removed topic {}", clientAppId(), dn);
    } catch (Exception e) {
        Throwable t = e.getCause();
        log.error("[{}] Failed to get delete topic {}", clientAppId(), dn, t);
        if (t instanceof TopicBusyException) {
            throw new RestException(Status.PRECONDITION_FAILED, "Topic has active producers/subscriptions");
        } else {
            throw new RestException(t);
        }
    }
}
Also used : TopicBusyException(com.yahoo.pulsar.broker.service.BrokerServiceException.TopicBusyException) PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) DestinationName(com.yahoo.pulsar.common.naming.DestinationName) 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) Path(javax.ws.rs.Path) DELETE(javax.ws.rs.DELETE) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Aggregations

TopicBusyException (com.yahoo.pulsar.broker.service.BrokerServiceException.TopicBusyException)3 CompletableFuture (java.util.concurrent.CompletableFuture)2 NotAllowedException (com.yahoo.pulsar.broker.service.BrokerServiceException.NotAllowedException)1 PersistenceException (com.yahoo.pulsar.broker.service.BrokerServiceException.PersistenceException)1 SubscriptionBusyException (com.yahoo.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException)1 TopicFencedException (com.yahoo.pulsar.broker.service.BrokerServiceException.TopicFencedException)1 PersistentTopic (com.yahoo.pulsar.broker.service.persistent.PersistentTopic)1 RestException (com.yahoo.pulsar.broker.web.RestException)1 NotFoundException (com.yahoo.pulsar.client.admin.PulsarAdminException.NotFoundException)1 PreconditionFailedException (com.yahoo.pulsar.client.admin.PulsarAdminException.PreconditionFailedException)1 PulsarClientException (com.yahoo.pulsar.client.api.PulsarClientException)1 DestinationName (com.yahoo.pulsar.common.naming.DestinationName)1 ApiOperation (io.swagger.annotations.ApiOperation)1 ApiResponses (io.swagger.annotations.ApiResponses)1 IOException (java.io.IOException)1 DELETE (javax.ws.rs.DELETE)1 Path (javax.ws.rs.Path)1 WebApplicationException (javax.ws.rs.WebApplicationException)1 AsyncCallbacks (org.apache.bookkeeper.mledger.AsyncCallbacks)1 ManagedLedgerException (org.apache.bookkeeper.mledger.ManagedLedgerException)1