use of org.apache.pulsar.common.partition.PartitionedTopicMetadata in project incubator-pulsar by apache.
the class PersistentTopicsBase method internalPeekNthMessage.
protected Response internalPeekNthMessage(String subName, int messagePosition, boolean authoritative) {
if (topicName.isGlobal()) {
validateGlobalNamespaceOwnership(namespaceName);
}
PartitionedTopicMetadata partitionMetadata = getPartitionedTopicMetadata(topicName, authoritative);
if (partitionMetadata.partitions > 0) {
throw new RestException(Status.METHOD_NOT_ALLOWED, "Peek messages on a partitioned topic is not allowed");
}
validateAdminOperationOnTopic(authoritative);
if (!(getTopicReference(topicName) instanceof PersistentTopic)) {
log.error("[{}] Not supported operation of non-persistent topic {} {}", clientAppId(), topicName, subName);
throw new RestException(Status.METHOD_NOT_ALLOWED, "Skip messages on a non-persistent topic is not allowed");
}
PersistentTopic topic = (PersistentTopic) getTopicReference(topicName);
PersistentReplicator repl = null;
PersistentSubscription sub = null;
Entry entry = null;
if (subName.startsWith(topic.replicatorPrefix)) {
repl = getReplicatorReference(subName, topic);
} else {
sub = (PersistentSubscription) getSubscriptionReference(subName, topic);
}
try {
if (subName.startsWith(topic.replicatorPrefix)) {
entry = repl.peekNthMessage(messagePosition).get();
} else {
entry = sub.peekNthMessage(messagePosition).get();
}
checkNotNull(entry);
PositionImpl pos = (PositionImpl) entry.getPosition();
ByteBuf metadataAndPayload = entry.getDataBuffer();
// moves the readerIndex to the payload
MessageMetadata metadata = Commands.parseMessageMetadata(metadataAndPayload);
ResponseBuilder responseBuilder = Response.ok();
responseBuilder.header("X-Pulsar-Message-ID", pos.toString());
for (KeyValue keyValue : metadata.getPropertiesList()) {
responseBuilder.header("X-Pulsar-PROPERTY-" + keyValue.getKey(), keyValue.getValue());
}
if (metadata.hasPublishTime()) {
responseBuilder.header("X-Pulsar-publish-time", DateFormatter.format(metadata.getPublishTime()));
}
if (metadata.hasEventTime()) {
responseBuilder.header("X-Pulsar-event-time", DateFormatter.format(metadata.getEventTime()));
}
if (metadata.hasNumMessagesInBatch()) {
responseBuilder.header("X-Pulsar-num-batch-message", metadata.getNumMessagesInBatch());
}
// Decode if needed
CompressionCodec codec = CompressionCodecProvider.getCompressionCodec(metadata.getCompression());
ByteBuf uncompressedPayload = codec.decode(metadataAndPayload, metadata.getUncompressedSize());
// Copy into a heap buffer for output stream compatibility
ByteBuf data = PooledByteBufAllocator.DEFAULT.heapBuffer(uncompressedPayload.readableBytes(), uncompressedPayload.readableBytes());
data.writeBytes(uncompressedPayload);
uncompressedPayload.release();
StreamingOutput stream = new StreamingOutput() {
@Override
public void write(OutputStream output) throws IOException, WebApplicationException {
output.write(data.array(), data.arrayOffset(), data.readableBytes());
data.release();
}
};
return responseBuilder.entity(stream).build();
} catch (NullPointerException npe) {
throw new RestException(Status.NOT_FOUND, "Message not found");
} catch (Exception exception) {
log.error("[{}] Failed to get message at position {} from {} {}", clientAppId(), messagePosition, topicName, subName, exception);
throw new RestException(exception);
} finally {
if (entry != null) {
entry.release();
}
}
}
use of org.apache.pulsar.common.partition.PartitionedTopicMetadata in project incubator-pulsar by apache.
the class PersistentTopicsBase method internalDeleteSubscription.
protected void internalDeleteSubscription(String subName, boolean authoritative) {
if (topicName.isGlobal()) {
validateGlobalNamespaceOwnership(namespaceName);
}
PartitionedTopicMetadata partitionMetadata = getPartitionedTopicMetadata(topicName, authoritative);
if (partitionMetadata.partitions > 0) {
try {
for (int i = 0; i < partitionMetadata.partitions; i++) {
pulsar().getAdminClient().persistentTopics().deleteSubscription(topicName.getPartition(i).toString(), subName);
}
} catch (Exception e) {
if (e instanceof NotFoundException) {
throw new RestException(Status.NOT_FOUND, "Subscription not found");
} else if (e instanceof PreconditionFailedException) {
throw new RestException(Status.PRECONDITION_FAILED, "Subscription has active connected consumers");
} else {
log.error("[{}] Failed to delete subscription {} {}", clientAppId(), topicName, subName, e);
throw new RestException(e);
}
}
} else {
validateAdminOperationOnTopic(authoritative);
Topic topic = getTopicReference(topicName);
try {
Subscription sub = topic.getSubscription(subName);
checkNotNull(sub);
sub.delete().get();
log.info("[{}][{}] Deleted subscription {}", clientAppId(), topicName, subName);
} catch (Exception e) {
Throwable t = e.getCause();
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 {
log.error("[{}] Failed to delete subscription {} {}", clientAppId(), topicName, subName, e);
throw new RestException(t);
}
}
}
}
use of org.apache.pulsar.common.partition.PartitionedTopicMetadata in project incubator-pulsar by apache.
the class PersistentTopicsBase method internalTerminate.
protected MessageId internalTerminate(boolean authoritative) {
if (topicName.isGlobal()) {
validateGlobalNamespaceOwnership(namespaceName);
}
PartitionedTopicMetadata partitionMetadata = getPartitionedTopicMetadata(topicName, authoritative);
if (partitionMetadata.partitions > 0) {
throw new RestException(Status.METHOD_NOT_ALLOWED, "Termination of a partitioned topic is not allowed");
}
validateAdminOperationOnTopic(authoritative);
Topic topic = getTopicReference(topicName);
try {
return ((PersistentTopic) topic).terminate().get();
} catch (Exception exception) {
log.error("[{}] Failed to terminated topic {}", clientAppId(), topicName, exception);
throw new RestException(exception);
}
}
use of org.apache.pulsar.common.partition.PartitionedTopicMetadata in project incubator-pulsar by apache.
the class PersistentTopicsBase method internalExpireMessagesForAllSubscriptions.
protected void internalExpireMessagesForAllSubscriptions(int expireTimeInSeconds, boolean authoritative) {
if (topicName.isGlobal()) {
validateGlobalNamespaceOwnership(namespaceName);
}
PartitionedTopicMetadata partitionMetadata = getPartitionedTopicMetadata(topicName, authoritative);
if (partitionMetadata.partitions > 0) {
try {
// expire messages for each partition topic
for (int i = 0; i < partitionMetadata.partitions; i++) {
pulsar().getAdminClient().persistentTopics().expireMessagesForAllSubscriptions(topicName.getPartition(i).toString(), expireTimeInSeconds);
}
} catch (Exception e) {
log.error("[{}] Failed to expire messages up to {} on {} {}", clientAppId(), expireTimeInSeconds, topicName, e);
throw new RestException(e);
}
} else {
// validate ownership and redirect if current broker is not owner
validateAdminOperationOnTopic(authoritative);
PersistentTopic topic = (PersistentTopic) getTopicReference(topicName);
topic.getReplicators().forEach((subName, replicator) -> {
internalExpireMessages(subName, expireTimeInSeconds, authoritative);
});
topic.getSubscriptions().forEach((subName, subscriber) -> {
internalExpireMessages(subName, expireTimeInSeconds, authoritative);
});
}
}
use of org.apache.pulsar.common.partition.PartitionedTopicMetadata in project incubator-pulsar by apache.
the class PersistentTopicsBase method internalGetSubscriptions.
protected List<String> internalGetSubscriptions(boolean authoritative) {
if (topicName.isGlobal()) {
validateGlobalNamespaceOwnership(namespaceName);
}
List<String> subscriptions = Lists.newArrayList();
PartitionedTopicMetadata partitionMetadata = getPartitionedTopicMetadata(topicName, authoritative);
if (partitionMetadata.partitions > 0) {
try {
// get the subscriptions only from the 1st partition since all the other partitions will have the same
// subscriptions
subscriptions.addAll(pulsar().getAdminClient().persistentTopics().getSubscriptions(topicName.getPartition(0).toString()));
} catch (Exception e) {
throw new RestException(e);
}
} else {
validateAdminOperationOnTopic(authoritative);
Topic topic = getTopicReference(topicName);
try {
topic.getSubscriptions().forEach((subName, sub) -> subscriptions.add(subName));
} catch (Exception e) {
log.error("[{}] Failed to get list of subscriptions for {}", clientAppId(), topicName);
throw new RestException(e);
}
}
return subscriptions;
}
Aggregations