blob: 3fae1ddc921d38e6d72330f10870bd9533cd5f5d [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "apache/rocketmq/v2/definition.proto";
package apache.rocketmq.v2;
option csharp_namespace = "Apache.Rocketmq.V2";
option java_multiple_files = true;
option java_package = "apache.rocketmq.v2";
option java_generate_equals_and_hash = true;
option java_string_check_utf8 = true;
option java_outer_classname = "MQService";
// Topics are destination of messages to publish to or subscribe from. Similar
// to domain names, they will be addressable after resolution through the
// provided access point.
//
// Access points are usually the addresses of name servers, which fulfill
// service discovery, load-balancing and other auxiliary services. Name servers
// receive periodic heartbeats from affiliate brokers and erase those which
// failed to maintain alive status.
//
// Name servers answer queries of QueryRouteRequest, responding clients with
// addressable message-queues, which they may directly publish messages to or
// subscribe messages from.
//
// QueryRouteRequest shall include source endpoints, aka, configured
// access-point, which annotates tenant-id, instance-id or other
// vendor-specific settings. Purpose-built name servers may respond customized
// results based on these particular requirements.
message QueryRouteRequest {
Resource topic = 1;
Endpoints endpoints = 2;
}
message QueryRouteResponse {
Status status = 1;
repeated MessageQueue message_queues = 2;
}
message SendMessageRequest {
repeated Message messages = 1;
}
message SendResultEntry {
Status status = 1;
string message_id = 2;
string transaction_id = 3;
int64 offset = 4;
}
message SendMessageResponse {
Status status = 1;
// Some implementation may have partial failure issues. Client SDK developers are expected to inspect
// each entry for best certainty.
repeated SendResultEntry entries = 2;
}
message QueryAssignmentRequest {
Resource topic = 1;
Resource group = 2;
Endpoints endpoints = 3;
}
message QueryAssignmentResponse {
Status status = 1;
repeated Assignment assignments = 2;
}
message ReceiveMessageRequest {
Resource group = 1;
MessageQueue message_queue = 2;
FilterExpression filter_expression = 3;
int32 batch_size = 4;
// Required if client type is simple consumer.
optional google.protobuf.Duration invisible_duration = 5;
// For message auto renew and clean
bool auto_renew = 6;
}
message ReceiveMessageResponse {
oneof content {
Status status = 1;
Message message = 2;
// The timestamp that brokers start to deliver status line or message.
google.protobuf.Timestamp delivery_timestamp = 3;
}
}
message AckMessageEntry {
string message_id = 1;
string receipt_handle = 2;
}
message AckMessageRequest {
Resource group = 1;
Resource topic = 2;
repeated AckMessageEntry entries = 3;
}
message AckMessageResultEntry {
string message_id = 1;
string receipt_handle = 2;
// Acknowledge result may be acquired through inspecting
// `status.code`; In case acknowledgement failed, `status.message`
// is the explanation of the failure.
Status status = 3;
}
message AckMessageResponse {
// RPC tier status, which is used to represent RPC-level errors including
// authentication, authorization, throttling and other general failures.
Status status = 1;
repeated AckMessageResultEntry entries = 2;
}
message ForwardMessageToDeadLetterQueueRequest {
Resource group = 1;
Resource topic = 2;
string receipt_handle = 3;
string message_id = 4;
int32 delivery_attempt = 5;
int32 max_delivery_attempts = 6;
}
message ForwardMessageToDeadLetterQueueResponse { Status status = 1; }
message HeartbeatRequest {
optional Resource group = 1;
ClientType client_type = 2;
}
message HeartbeatResponse { Status status = 1; }
message EndTransactionRequest {
Resource topic = 1;
string message_id = 2;
string transaction_id = 3;
TransactionResolution resolution = 4;
TransactionSource source = 5;
string trace_context = 6;
}
message EndTransactionResponse { Status status = 1; }
message PrintThreadStackTraceCommand { string nonce = 1; }
message ThreadStackTrace {
string nonce = 1;
optional string thread_stack_trace = 2;
}
message VerifyMessageCommand {
string nonce = 1;
MessageQueue message_queue = 2;
Message message = 3;
}
message VerifyMessageResult {
string nonce = 1;
}
message RecoverOrphanedTransactionCommand {
MessageQueue message_queue = 1;
Message orphaned_transactional_message = 2;
string transaction_id = 3;
}
message Publishing {
// Publishing settings below here is appointed by client, thus it is
// unnecessary for server to push at present.
//
// List of topics to which messages will publish to.
repeated Resource topics = 1;
// Publishing settings below here are from server, it is essential for
// server to push.
//
// Body of message will be deflated if its size in bytes exceeds the
// threshold.
int32 compress_body_threshold = 2;
// If the message body size exceeds `max_body_size`, broker servers would
// reject the request. As a result, it is advisable that Producer performs
// client-side check validation.
int32 max_body_size = 3;
// When `validate_message_type` flag set `false`, no need to validate message's type
// with messageQueue's `accept_message_types` before publising.
bool validate_message_type = 4;
}
message Subscription {
// Subscription settings below here is appointed by client, thus it is
// unnecessary for server to push at present.
//
// Consumer group.
optional Resource group = 1;
// Subscription for consumer.
repeated SubscriptionEntry subscriptions = 2;
// Subscription settings below here are from server, it is essential for
// server to push.
//
// When FIFO flag is `true`, messages of the same message group are processed
// in first-in-first-out manner.
//
// Brokers will not deliver further messages of the same group utill prior
// ones are completely acknowledged.
optional bool fifo = 3;
// Message receive batch size here is essential for push consumer.
optional int32 receive_batch_size = 4;
// Long-polling timeout for `ReceiveMessageRequest`, which is essential for
// push consumer.
optional google.protobuf.Duration long_polling_timeout = 5;
}
message Metric {
// Indicates that if client should export local metrics to server.
bool on = 1;
// The endpoint that client metrics should be exported to, which is required if the switch is on.
optional Endpoints endpoints = 2;
}
message Settings {
// Configurations for all clients.
optional ClientType client_type = 1;
optional Endpoints access_point = 2;
// If publishing of messages encounters throttling or server internal errors,
// publishers should implement automatic retries after progressive longer
// back-offs for consecutive errors.
//
// When processing message fails, `backoff_policy` describes an interval
// after which the message should be available to consume again.
//
// For FIFO messages, the interval should be relatively small because
// messages of the same message group would not be readily available utill
// the prior one depletes its lifecycle.
optional RetryPolicy backoff_policy = 3;
// Request timeout for RPCs excluding long-polling.
optional google.protobuf.Duration request_timeout = 4;
oneof pub_sub {
Publishing publishing = 5;
Subscription subscription = 6;
}
// User agent details
UA user_agent = 7;
Metric metric = 8;
}
message TelemetryCommand {
optional Status status = 1;
oneof command {
// Client settings
Settings settings = 2;
// These messages are from client.
//
// Report thread stack trace to server.
ThreadStackTrace thread_stack_trace = 3;
// Report message verify result to server.
VerifyMessageResult verify_message_result = 4;
// There messages are from server.
//
// Request client to recover the orphaned transaction message.
RecoverOrphanedTransactionCommand recover_orphaned_transaction_command = 5;
// Request client to print thread stack trace.
PrintThreadStackTraceCommand print_thread_stack_trace_command = 6;
// Request client to verify the consumption of the appointed message.
VerifyMessageCommand verify_message_command = 7;
}
}
message NotifyClientTerminationRequest {
// Consumer group, which is absent for producer.
optional Resource group = 1;
}
message NotifyClientTerminationResponse { Status status = 1; }
message ChangeInvisibleDurationRequest {
Resource group = 1;
Resource topic = 2;
// Unique receipt handle to identify message to change
string receipt_handle = 3;
// New invisible duration
google.protobuf.Duration invisible_duration = 4;
// For message tracing
string message_id = 5;
}
message ChangeInvisibleDurationResponse {
Status status = 1;
// Server may generate a new receipt handle for the message.
string receipt_handle = 2;
}
// For all the RPCs in MessagingService, the following error handling policies
// apply:
//
// If the request doesn't bear a valid authentication credential, return a
// response with common.status.code == `UNAUTHENTICATED`. If the authenticated
// user is not granted with sufficient permission to execute the requested
// operation, return a response with common.status.code == `PERMISSION_DENIED`.
// If the per-user-resource-based quota is exhausted, return a response with
// common.status.code == `RESOURCE_EXHAUSTED`. If any unexpected server-side
// errors raise, return a response with common.status.code == `INTERNAL`.
service MessagingService {
// Queries the route entries of the requested topic in the perspective of the
// given endpoints. On success, servers should return a collection of
// addressable message-queues. Note servers may return customized route
// entries based on endpoints provided.
//
// If the requested topic doesn't exist, returns `NOT_FOUND`.
// If the specific endpoints is empty, returns `INVALID_ARGUMENT`.
rpc QueryRoute(QueryRouteRequest) returns (QueryRouteResponse) {}
// Producer or consumer sends HeartbeatRequest to servers periodically to
// keep-alive. Additionally, it also reports client-side configuration,
// including topic subscription, load-balancing group name, etc.
//
// Returns `OK` if success.
//
// If a client specifies a language that is not yet supported by servers,
// returns `INVALID_ARGUMENT`
rpc Heartbeat(HeartbeatRequest) returns (HeartbeatResponse) {}
// Delivers messages to brokers.
// Clients may further:
// 1. Refine a message destination to message-queues which fulfills parts of
// FIFO semantic;
// 2. Flag a message as transactional, which keeps it invisible to consumers
// until it commits;
// 3. Time a message, making it invisible to consumers till specified
// time-point;
// 4. And more...
//
// Returns message-id or transaction-id with status `OK` on success.
//
// If the destination topic doesn't exist, returns `NOT_FOUND`.
rpc SendMessage(SendMessageRequest) returns (SendMessageResponse) {}
// Queries the assigned route info of a topic for current consumer,
// the returned assignment result is decided by server-side load balancer.
//
// If the corresponding topic doesn't exist, returns `NOT_FOUND`.
// If the specific endpoints is empty, returns `INVALID_ARGUMENT`.
rpc QueryAssignment(QueryAssignmentRequest) returns (QueryAssignmentResponse) {
}
// Receives messages from the server in batch manner, returns a set of
// messages if success. The received messages should be acked or redelivered
// after processed.
//
// If the pending concurrent receive requests exceed the quota of the given
// consumer group, returns `UNAVAILABLE`. If the upstream store server hangs,
// return `DEADLINE_EXCEEDED` in a timely manner. If the corresponding topic
// or consumer group doesn't exist, returns `NOT_FOUND`. If there is no new
// message in the specific topic, returns `OK` with an empty message set.
// Please note that client may suffer from false empty responses.
//
// If failed to receive message from remote, server must return only one
// `ReceiveMessageResponse` as the reply to the request, whose `Status` indicates
// the specific reason of failure, otherwise, the reply is considered successful.
rpc ReceiveMessage(ReceiveMessageRequest) returns (stream ReceiveMessageResponse) {
}
// Acknowledges the message associated with the `receipt_handle` or `offset`
// in the `AckMessageRequest`, it means the message has been successfully
// processed. Returns `OK` if the message server remove the relevant message
// successfully.
//
// If the given receipt_handle is illegal or out of date, returns
// `INVALID_ARGUMENT`.
rpc AckMessage(AckMessageRequest) returns (AckMessageResponse) {}
// Forwards one message to dead letter queue if the max delivery attempts is
// exceeded by this message at client-side, return `OK` if success.
rpc ForwardMessageToDeadLetterQueue(ForwardMessageToDeadLetterQueueRequest)
returns (ForwardMessageToDeadLetterQueueResponse) {}
// Commits or rollback one transactional message.
rpc EndTransaction(EndTransactionRequest) returns (EndTransactionResponse) {}
// Once a client starts, it would immediately establishes bi-lateral stream
// RPCs with brokers, reporting its settings as the initiative command.
//
// When servers have need of inspecting client status, they would issue
// telemetry commands to clients. After executing received instructions,
// clients shall report command execution results through client-side streams.
rpc Telemetry(stream TelemetryCommand) returns (stream TelemetryCommand) {}
// Notify the server that the client is terminated.
rpc NotifyClientTermination(NotifyClientTerminationRequest) returns (NotifyClientTerminationResponse) {
}
// Once a message is retrieved from consume queue on behalf of the group, it
// will be kept invisible to other clients of the same group for a period of
// time. The message is supposed to be processed within the invisible
// duration. If the client, which is in charge of the invisible message, is
// not capable of processing the message timely, it may use
// ChangeInvisibleDuration to lengthen invisible duration.
rpc ChangeInvisibleDuration(ChangeInvisibleDurationRequest) returns (ChangeInvisibleDurationResponse) {
}
}