public PersistentMessageFinder(String topicName, ManagedCursor cursor) { this.topicName = topicName; this.cursor = cursor; this.subName = Codec.decode(cursor.getName()); }
@DELETE @Path("/{property}/{cluster}/{namespace}/{topic}/subscription/{subName}") @ApiOperation(hidden = true, value = "Delete a subscription.", notes = "There should not be any active consumers on the subscription.") @ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Topic does not exist"), @ApiResponse(code = 412, message = "Subscription has active consumers") }) public void deleteSubscription(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("topic") @Encoded String encodedTopic, @PathParam("subName") String encodedSubName, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) { validateTopicName(property, cluster, namespace, encodedTopic); internalDeleteSubscription(decode(encodedSubName), authoritative); }
@GET @Path("/{property}/{cluster}/{namespace}/{topic}/subscription/{subName}/position/{messagePosition}") @ApiOperation(hidden = true, value = "Peek nth message on a topic subscription.") @ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Topic, subscription or the message position does not exist") }) public Response peekNthMessage(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("topic") @Encoded String encodedTopic, @PathParam("subName") String encodedSubName, @PathParam("messagePosition") int messagePosition, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) { validateTopicName(property, cluster, namespace, encodedTopic); return internalPeekNthMessage(decode(encodedSubName), messagePosition, authoritative); }
@PUT @Path("/{tenant}/{namespace}/{topic}/subscription/{subscriptionName}") @ApiOperation(value = "Reset subscription to message position closest to given position.", notes = "Creates a subscription on the topic at the specified message id") @ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Topic/Subscription does not exist"), @ApiResponse(code = 405, message = "Not supported for partitioned topics") }) public void createSubscription(@PathParam("tenant") String tenant, @PathParam("namespace") String namespace, @PathParam("topic") @Encoded String topic, @PathParam("subscriptionName") String encodedSubName, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative, MessageIdImpl messageId) { validateTopicName(tenant, namespace, topic); internalCreateSubscription(decode(encodedSubName), messageId, authoritative); }
@DELETE @Path("/{tenant}/{namespace}/{topic}/subscription/{subName}") @ApiOperation(value = "Delete a subscription.", notes = "There should not be any active consumers on the subscription.") @ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Topic does not exist"), @ApiResponse(code = 412, message = "Subscription has active consumers") }) public void deleteSubscription(@PathParam("tenant") String tenant, @PathParam("namespace") String namespace, @PathParam("topic") @Encoded String encodedTopic, @PathParam("subName") String encodedSubName, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) { validateTopicName(tenant, namespace, encodedTopic); internalDeleteSubscription(decode(encodedSubName), authoritative); }
@POST @Path("/{tenant}/{namespace}/{topic}/subscription/{subName}/expireMessages/{expireTimeInSeconds}") @ApiOperation(value = "Expire messages on a topic subscription.") @ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Topic or subscription does not exist") }) public void expireTopicMessages(@PathParam("tenant") String tenant, @PathParam("namespace") String namespace, @PathParam("topic") @Encoded String encodedTopic, @PathParam("subName") String encodedSubName, @PathParam("expireTimeInSeconds") int expireTimeInSeconds, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) { validateTopicName(tenant, namespace, encodedTopic); internalExpireMessages(decode(encodedSubName), expireTimeInSeconds, authoritative); }
@POST @Path("/{tenant}/{namespace}/{topic}/subscription/{subName}/resetcursor/{timestamp}") @ApiOperation(value = "Reset subscription to message position closest to absolute timestamp (in ms).", notes = "It fence cursor and disconnects all active consumers before reseting cursor.") @ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Topic/Subscription does not exist") }) public void resetCursor(@PathParam("tenant") String tenant, @PathParam("namespace") String namespace, @PathParam("topic") @Encoded String encodedTopic, @PathParam("subName") String encodedSubName, @PathParam("timestamp") long timestamp, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) { validateTopicName(tenant, namespace, encodedTopic); internalResetCursor(decode(encodedSubName), timestamp, authoritative); }
@POST @Path("/{tenant}/{namespace}/{topic}/subscription/{subName}/skip/{numMessages}") @ApiOperation(value = "Skip messages on a topic subscription.") @ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Topic or subscription does not exist") }) public void skipMessages(@PathParam("tenant") String tenant, @PathParam("namespace") String namespace, @PathParam("topic") @Encoded String encodedTopic, @PathParam("subName") String encodedSubName, @PathParam("numMessages") int numMessages, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) { validateTopicName(tenant, namespace, encodedTopic); internalSkipMessages(decode(encodedSubName), numMessages, authoritative); }
@GET @Path("/{tenant}/{namespace}/{topic}/subscription/{subName}/position/{messagePosition}") @ApiOperation(value = "Peek nth message on a topic subscription.") @ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Topic, subscription or the message position does not exist") }) public Response peekNthMessage(@PathParam("tenant") String tenant, @PathParam("namespace") String namespace, @PathParam("topic") @Encoded String encodedTopic, @PathParam("subName") String encodedSubName, @PathParam("messagePosition") int messagePosition, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) { validateTopicName(tenant, namespace, encodedTopic); return internalPeekNthMessage(decode(encodedSubName), messagePosition, authoritative); }
@GET @Path("/{domain}/{tenant}/{namespace}/{topic}/stats") @ApiOperation(value = "Get the stats for the topic.") @ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Topic does not exist") }) public ProxyTopicStat getStats(@PathParam("domain") String domain, @PathParam("tenant") String tenant, @PathParam("namespace") String namespace, @PathParam("topic") @Encoded String encodedTopic) { return super.internalGetStats(TopicName.get(domain, tenant, namespace, decode(encodedTopic))); }
@POST @Path("/{property}/{cluster}/{namespace}/{topic}/subscription/{subName}/skip/{numMessages}") @ApiOperation(hidden = true, value = "Skip messages on a topic subscription.") @ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Topic or subscription does not exist") }) public void skipMessages(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("topic") @Encoded String encodedTopic, @PathParam("subName") String encodedSubName, @PathParam("numMessages") int numMessages, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) { validateTopicName(property, cluster, namespace, encodedTopic); internalSkipMessages(decode(encodedSubName), numMessages, authoritative); }
@POST @Path("/{tenant}/{namespace}/{topic}/subscription/{subName}/skip_all") @ApiOperation(value = "Skip all messages on a topic subscription.", notes = "Completely clears the backlog on the subscription.") @ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 405, message = "Operation not allowed on non-persistent topic"), @ApiResponse(code = 404, message = "Topic or subscription does not exist") }) public void skipAllMessages(@PathParam("tenant") String tenant, @PathParam("namespace") String namespace, @PathParam("topic") @Encoded String encodedTopic, @PathParam("subName") String encodedSubName, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) { validateTopicName(tenant, namespace, encodedTopic); internalSkipAllMessages(decode(encodedSubName), authoritative); }
@GET @Path("/{tenant}/{cluster}/{namespace}/{topic}/stats") @ApiOperation(value = "Get the stats for the topic.") @ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Topic does not exist") }) public ProxyTopicStat getStats(@PathParam("tenant") String tenant, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("topic") @Encoded String encodedTopic) { return super.internalGetStats(TopicName.get("persistent", tenant, cluster, namespace, decode(encodedTopic))); }
@Deprecated protected void validateTopicName(String property, String cluster, String namespace, String encodedTopic) { String topic = Codec.decode(encodedTopic); try { this.namespaceName = NamespaceName.get(property, cluster, namespace); this.topicName = TopicName.get(domain(), namespaceName, topic); } catch (IllegalArgumentException e) { log.warn("[{}] Failed to validate topic name {}://{}/{}/{}/{}", clientAppId(), domain(), property, cluster, namespace, topic, e); throw new RestException(Status.PRECONDITION_FAILED, "Topic name is not valid"); } }
protected TopicName getTopicName(String topicDomain, String tenant, String namespace, @Encoded String encodedTopic) { String decodedName = Codec.decode(encodedTopic); return TopicName.get(TopicDomain.getEnum(topicDomain).value(), tenant, namespace, decodedName); }
public PersistentReplicator(PersistentTopic topic, ManagedCursor cursor, String localCluster, String remoteCluster, BrokerService brokerService) throws NamingException { super(topic.getName(), topic.replicatorPrefix, localCluster, remoteCluster, brokerService); this.topic = topic; this.cursor = cursor; this.expiryMonitor = new PersistentMessageExpiryMonitor(topicName, Codec.decode(cursor.getName()), cursor); HAVE_PENDING_READ_UPDATER.set(this, FALSE); PENDING_MESSAGES_UPDATER.set(this, 0); readBatchSize = Math.min(producerQueueSize, MaxReadBatchSize); producerQueueThreshold = (int) (producerQueueSize * 0.9); startProducer(); }
protected TopicName getTopicName(String topicDomain, String tenant, String cluster, String namespace, @Encoded String encodedTopic) { String decodedName = Codec.decode(encodedTopic); return TopicName.get(TopicDomain.getEnum(topicDomain).value(), tenant, cluster, namespace, decodedName); }
protected void validateTopicName(String property, String namespace, String encodedTopic) { String topic = Codec.decode(encodedTopic); try { this.namespaceName = NamespaceName.get(property, namespace); this.topicName = TopicName.get(domain(), namespaceName, topic); } catch (IllegalArgumentException e) { log.warn("[{}] Failed to validate topic name {}://{}/{}/{}", clientAppId(), domain(), property, namespace, topic, e); throw new RestException(Status.PRECONDITION_FAILED, "Topic name is not valid"); } this.topicName = TopicName.get(domain(), namespaceName, topic); }
public PersistentDispatcherSingleActiveConsumer(ManagedCursor cursor, SubType subscriptionType, int partitionIndex, PersistentTopic topic) { super(subscriptionType, partitionIndex, topic.getName()); this.topic = topic; this.name = topic.getName() + " / " + (cursor.getName() != null ? Codec.decode(cursor.getName()) : ""/* NonDurableCursor doesn't have name */); this.cursor = cursor; this.readBatchSize = MaxReadBatchSize; this.serviceConfig = topic.getBrokerService().pulsar().getConfiguration(); this.dispatchRateLimiter = null; this.redeliveryTracker = RedeliveryTrackerDisabled.REDELIVERY_TRACKER_DISABLED; }
public PersistentDispatcherMultipleConsumers(PersistentTopic topic, ManagedCursor cursor) { this.cursor = cursor; this.name = topic.getName() + " / " + Codec.decode(cursor.getName()); this.topic = topic; this.messagesToReplay = new ConcurrentLongPairSet(512, 2); this.redeliveryTracker = new InMemoryRedeliveryTracker(); this.readBatchSize = MaxReadBatchSize; this.maxUnackedMessages = topic.getBrokerService().pulsar().getConfiguration() .getMaxUnackedMessagesPerSubscription(); this.serviceConfig = topic.getBrokerService().pulsar().getConfiguration(); this.dispatchRateLimiter = null; }