use of org.apache.pulsar.broker.service.BrokerServiceException.TopicBusyException in project incubator-pulsar by apache.
the class NonPersistentTopic method delete.
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 {
brokerService.removeTopicFromCache(topic);
log.info("[{}] Topic deleted", topic);
deleteFuture.complete(null);
}
});
} else {
deleteFuture.completeExceptionally(new TopicBusyException("Topic has " + USAGE_COUNT_UPDATER.get(this) + " connected producers/consumers"));
}
} finally {
lock.writeLock().unlock();
}
return deleteFuture;
}
use of org.apache.pulsar.broker.service.BrokerServiceException.TopicBusyException in project incubator-pulsar by apache.
the class PersistentTopicsBase method internalDeleteTopic.
protected void internalDeleteTopic(boolean authoritative) {
validateAdminOperationOnTopic(authoritative);
Topic topic = getTopicReference(topicName);
// v2 topics have a global name so check if the topic is replicated.
if (topic.isReplicated()) {
// Delete is disallowed on global topic
log.error("[{}] Delete topic is forbidden on global namespace {}", clientAppId(), topicName);
throw new RestException(Status.FORBIDDEN, "Delete forbidden on global namespace");
}
try {
topic.delete().get();
log.info("[{}] Successfully removed topic {}", clientAppId(), topicName);
} catch (Exception e) {
Throwable t = e.getCause();
log.error("[{}] Failed to get delete topic {}", clientAppId(), topicName, t);
if (t instanceof TopicBusyException) {
throw new RestException(Status.PRECONDITION_FAILED, "Topic has active producers/subscriptions");
} else {
throw new RestException(t);
}
}
}
use of org.apache.pulsar.broker.service.BrokerServiceException.TopicBusyException in project incubator-pulsar by apache.
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;
}
use of org.apache.pulsar.broker.service.BrokerServiceException.TopicBusyException in project incubator-pulsar by apache.
the class AbstractReplicator method disconnect.
public synchronized CompletableFuture<Void> disconnect(boolean failIfHasBacklog) {
if (failIfHasBacklog && 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, getReplicatorReadPosition(), getNumberOfEntriesInBacklog());
return closeProducerAsync();
}
STATE_UPDATER.set(this, State.Stopped);
return CompletableFuture.completedFuture(null);
}
Aggregations