Initial commit for Python client (#508)

* add protocol layer code & proto file

* add rpcClient.py

* add .gitignore & add license & fix timeout

* Add python git ignore files

* Delete redendant IDL files from python directory

* Add license header for python files

* Add comments for unfinished works

---------

Co-authored-by: Aaron Ai <yangkun.ayk@alibaba-inc.com>
diff --git a/.gitignore b/.gitignore
index 6383e08..683bcd4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -46,3 +46,9 @@
 golang/*.tests
 golang/*.test
 golang/*.exe
+
+# Python
+*.pyc
+*.pyo
+*.pyd
+python/__pycache__/
\ No newline at end of file
diff --git a/python/client/rpc_client.py b/python/client/rpc_client.py
new file mode 100644
index 0000000..9cd9b46
--- /dev/null
+++ b/python/client/rpc_client.py
@@ -0,0 +1,125 @@
+# 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.
+
+from grpc import ssl_channel_credentials, insecure_channel
+from datetime import timedelta
+import time
+from grpc_interceptor import ClientInterceptor,  ClientCallDetails
+import protocol.service_pb2 as pb2
+import protocol.service_pb2_grpc as servicegrpc
+
+class MetadataInterceptor(ClientInterceptor):
+    def __init__(self, metadata):
+        self.metadata = metadata
+
+    def intercept(self, request, metadata, client_call_details, next):
+        metadata.update(self.metadata)
+        new_client_call_details = ClientCallDetails(
+            client_call_details.method,
+            client_call_details.timeout,
+            metadata,
+            client_call_details.credentials,
+            client_call_details.wait_for_ready,
+            client_call_details.compression,
+        )
+        return next(request, new_client_call_details)
+
+
+class RpcClient:
+    CONNECT_TIMEOUT_MILLIS = 3*1000
+    GRPC_MAX_MESSAGE_SIZE = 2*31 - 1
+    def __init__(self, endpoints, sslEnabled):
+        channel_options = [
+            ('grpc.max_send_message_length', -1),
+            ('grpc.max_receive_message_length', -1),
+            ('grpc.keepalive_time_ms', 1000),
+            ('grpc.keepalive_timeout_ms', 5000),
+            ('grpc.keepalive_permit_without_calls', True),
+            ('grpc.connect_timeout_ms', self.CONNECT_TIMEOUT_MILLIS),
+        ]
+        if sslEnabled:
+            ssl_creds = ssl_channel_credentials()
+            self.channel = Channel(endpoints.getGrpcTarget(), ssl_creds, options=channel_options)
+        else:
+            self.channel = insecure_channel(endpoints.getGrpcTarget(), options=channel_options)
+
+        self.activityNanoTime = time.monotonic_ns()
+
+    def get_stub(self, metadata):
+        interceptor = MetadataInterceptor(metadata)
+
+        interceptor_channel = grpc.intercept_channel(self.channel, interceptor)
+        stub = servicegrpc.MessagingServiceStub(interceptor_channel)
+        return stub
+
+    def __del__(self):
+        self.channel.close()
+    
+    def idle_duration(activity_nano_time):
+        return timedelta(microseconds=(time.monotonic_ns() - activity_nano_time) / 1000)
+    
+    async def query_route(self, metadata, request, duration):
+        self.activity_nano_time = time.monotonic_ns()
+        stub = self.get_stub(self, metadata)
+        return await stub.QueryRoute(request, timeout=duration)
+
+    async def heartbeat(self, metadata, request, duration):
+        self.activity_nano_time = time.monotonic_ns()
+        stub = self.get_stub(self, metadata)
+        return await stub.Heartbeat(request, timeout=duration)
+
+    async def send_message(self, metadata, request, duration):
+        self.activity_nano_time = time.monotonic_ns()
+        stub = self.get_stub(self, metadata)
+        return await stub.SendMessage(request, timeout=duration)
+
+    async def query_assignment(self, metadata, request, duration):
+        self.activity_nano_time = time.monotonic_ns()
+        stub = self.get_stub(self, metadata)
+        return await stub.QueryAssignment(request, timeout=duration)
+
+    # TODO: Not yet imeplemented
+    async def receive_message(self, metadata, request, duration):
+        pass
+
+    async def ack_message(self, metadata, request, duration):
+        self.activity_nano_time = time.monotonic_ns()
+        stub = self.get_stub(self, metadata)
+        return await stub.AckMessage(request, timeout=duration)
+
+    async def change_invisible_duration(self, metadata, request, duration):
+        self.activity_nano_time = time.monotonic_ns()
+        stub = self.get_stub(self, metadata)
+        return await stub.ChangeInvisibleDuration(request, timeout=duration)
+
+    async def forward_message_to_dead_letter_queue(self, metadata, request, duration):
+        self.activity_nano_time = time.monotonic_ns()
+        stub = self.get_stub(self, metadata)
+        return await stub.ForwardMessageToDeadLetterQueue(request, timeout=duration)
+    
+    async def endTransaction(self, metadata, request, duration):
+        self.activity_nano_time = time.monotonic_ns()
+        stub = self.get_stub(self, metadata)
+        return await stub.EndTransaction(request, timeout=duration)
+    
+
+    async def notifyClientTermination(self, metadata, request, duration):
+        self.activity_nano_time = time.monotonic_ns()
+        stub = self.get_stub(self, metadata)
+        return await stub.NotifyClientTermination(request, timeout=duration)
+
+    async def telemetry(self, metadata, duration, response_observer):
+        stub = self.get_stub(self, metadata)
+        return await stub.Telemetry(response_observer, timeout=duration)
\ No newline at end of file
diff --git a/python/protocol/__init__.py b/python/protocol/__init__.py
new file mode 100644
index 0000000..2bbe709
--- /dev/null
+++ b/python/protocol/__init__.py
@@ -0,0 +1,14 @@
+# 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.
\ No newline at end of file
diff --git a/python/protocol/admin_pb2.py b/python/protocol/admin_pb2.py
new file mode 100644
index 0000000..20f5ab0
--- /dev/null
+++ b/python/protocol/admin_pb2.py
@@ -0,0 +1,47 @@
+# 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.
+
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: admin.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import builder as _builder
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import descriptor_pool as _descriptor_pool
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0b\x61\x64min.proto\x12\x12\x61pache.rocketmq.v2\"\x95\x01\n\x15\x43hangeLogLevelRequest\x12>\n\x05level\x18\x01 \x01(\x0e\x32/.apache.rocketmq.v2.ChangeLogLevelRequest.Level\"<\n\x05Level\x12\t\n\x05TRACE\x10\x00\x12\t\n\x05\x44\x45\x42UG\x10\x01\x12\x08\n\x04INFO\x10\x02\x12\x08\n\x04WARN\x10\x03\x12\t\n\x05\x45RROR\x10\x04\"(\n\x16\x43hangeLogLevelResponse\x12\x0e\n\x06remark\x18\x01 \x01(\t2r\n\x05\x41\x64min\x12i\n\x0e\x43hangeLogLevel\x12).apache.rocketmq.v2.ChangeLogLevelRequest\x1a*.apache.rocketmq.v2.ChangeLogLevelResponse\"\x00\x42=\n\x12\x61pache.rocketmq.v2B\x07MQAdminP\x01\xa0\x01\x01\xd8\x01\x01\xf8\x01\x01\xaa\x02\x12\x41pache.Rocketmq.V2b\x06proto3')
+
+_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
+_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'admin_pb2', globals())
+if _descriptor._USE_C_DESCRIPTORS == False:
+
+  DESCRIPTOR._options = None
+  DESCRIPTOR._serialized_options = b'\n\022apache.rocketmq.v2B\007MQAdminP\001\240\001\001\330\001\001\370\001\001\252\002\022Apache.Rocketmq.V2'
+  _CHANGELOGLEVELREQUEST._serialized_start=36
+  _CHANGELOGLEVELREQUEST._serialized_end=185
+  _CHANGELOGLEVELREQUEST_LEVEL._serialized_start=125
+  _CHANGELOGLEVELREQUEST_LEVEL._serialized_end=185
+  _CHANGELOGLEVELRESPONSE._serialized_start=187
+  _CHANGELOGLEVELRESPONSE._serialized_end=227
+  _ADMIN._serialized_start=229
+  _ADMIN._serialized_end=343
+# @@protoc_insertion_point(module_scope)
diff --git a/python/protocol/admin_pb2_grpc.py b/python/protocol/admin_pb2_grpc.py
new file mode 100644
index 0000000..a43fea3
--- /dev/null
+++ b/python/protocol/admin_pb2_grpc.py
@@ -0,0 +1,81 @@
+# 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.
+
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+import admin_pb2 as admin__pb2
+
+
+class AdminStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.ChangeLogLevel = channel.unary_unary(
+                '/apache.rocketmq.v2.Admin/ChangeLogLevel',
+                request_serializer=admin__pb2.ChangeLogLevelRequest.SerializeToString,
+                response_deserializer=admin__pb2.ChangeLogLevelResponse.FromString,
+                )
+
+
+class AdminServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def ChangeLogLevel(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_AdminServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'ChangeLogLevel': grpc.unary_unary_rpc_method_handler(
+                    servicer.ChangeLogLevel,
+                    request_deserializer=admin__pb2.ChangeLogLevelRequest.FromString,
+                    response_serializer=admin__pb2.ChangeLogLevelResponse.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'apache.rocketmq.v2.Admin', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class Admin(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def ChangeLogLevel(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/apache.rocketmq.v2.Admin/ChangeLogLevel',
+            admin__pb2.ChangeLogLevelRequest.SerializeToString,
+            admin__pb2.ChangeLogLevelResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/python/protocol/definition_pb2.py b/python/protocol/definition_pb2.py
new file mode 100644
index 0000000..ef2a38f
--- /dev/null
+++ b/python/protocol/definition_pb2.py
@@ -0,0 +1,99 @@
+# 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.
+
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: definition.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import builder as _builder
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import descriptor_pool as _descriptor_pool
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
+from google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2
+
+
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10\x64\x65\x66inition.proto\x12\x12\x61pache.rocketmq.v2\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/duration.proto\"T\n\x10\x46ilterExpression\x12,\n\x04type\x18\x01 \x01(\x0e\x32\x1e.apache.rocketmq.v2.FilterType\x12\x12\n\nexpression\x18\x02 \x01(\t\"\xbb\x01\n\x0bRetryPolicy\x12\x14\n\x0cmax_attempts\x18\x01 \x01(\x05\x12\x45\n\x13\x65xponential_backoff\x18\x02 \x01(\x0b\x32&.apache.rocketmq.v2.ExponentialBackoffH\x00\x12\x43\n\x12\x63ustomized_backoff\x18\x03 \x01(\x0b\x32%.apache.rocketmq.v2.CustomizedBackoffH\x00\x42\n\n\x08strategy\"|\n\x12\x45xponentialBackoff\x12*\n\x07initial\x18\x01 \x01(\x0b\x32\x19.google.protobuf.Duration\x12&\n\x03max\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x12\n\nmultiplier\x18\x03 \x01(\x02\"<\n\x11\x43ustomizedBackoff\x12\'\n\x04next\x18\x01 \x03(\x0b\x32\x19.google.protobuf.Duration\"4\n\x08Resource\x12\x1a\n\x12resource_namespace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"z\n\x11SubscriptionEntry\x12+\n\x05topic\x18\x01 \x01(\x0b\x32\x1c.apache.rocketmq.v2.Resource\x12\x38\n\nexpression\x18\x02 \x01(\x0b\x32$.apache.rocketmq.v2.FilterExpression\"%\n\x07\x41\x64\x64ress\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0c\n\x04port\x18\x02 \x01(\x05\"n\n\tEndpoints\x12\x31\n\x06scheme\x18\x01 \x01(\x0e\x32!.apache.rocketmq.v2.AddressScheme\x12.\n\taddresses\x18\x02 \x03(\x0b\x32\x1b.apache.rocketmq.v2.Address\"T\n\x06\x42roker\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\x05\x12\x30\n\tendpoints\x18\x03 \x01(\x0b\x32\x1d.apache.rocketmq.v2.Endpoints\"\xe6\x01\n\x0cMessageQueue\x12+\n\x05topic\x18\x01 \x01(\x0b\x32\x1c.apache.rocketmq.v2.Resource\x12\n\n\x02id\x18\x02 \x01(\x05\x12\x32\n\npermission\x18\x03 \x01(\x0e\x32\x1e.apache.rocketmq.v2.Permission\x12*\n\x06\x62roker\x18\x04 \x01(\x0b\x32\x1a.apache.rocketmq.v2.Broker\x12=\n\x14\x61\x63\x63\x65pt_message_types\x18\x05 \x03(\x0e\x32\x1f.apache.rocketmq.v2.MessageType\"H\n\x06\x44igest\x12,\n\x04type\x18\x01 \x01(\x0e\x32\x1e.apache.rocketmq.v2.DigestType\x12\x10\n\x08\x63hecksum\x18\x02 \x01(\t\"\xb4\x07\n\x10SystemProperties\x12\x10\n\x03tag\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x0c\n\x04keys\x18\x02 \x03(\t\x12\x12\n\nmessage_id\x18\x03 \x01(\t\x12/\n\x0b\x62ody_digest\x18\x04 \x01(\x0b\x32\x1a.apache.rocketmq.v2.Digest\x12\x33\n\rbody_encoding\x18\x05 \x01(\x0e\x32\x1c.apache.rocketmq.v2.Encoding\x12\x35\n\x0cmessage_type\x18\x06 \x01(\x0e\x32\x1f.apache.rocketmq.v2.MessageType\x12\x32\n\x0e\x62orn_timestamp\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x11\n\tborn_host\x18\x08 \x01(\t\x12\x38\n\x0fstore_timestamp\x18\t \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x01\x88\x01\x01\x12\x12\n\nstore_host\x18\n \x01(\t\x12;\n\x12\x64\x65livery_timestamp\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x02\x88\x01\x01\x12\x1b\n\x0ereceipt_handle\x18\x0c \x01(\tH\x03\x88\x01\x01\x12\x10\n\x08queue_id\x18\r \x01(\x05\x12\x19\n\x0cqueue_offset\x18\x0e \x01(\x03H\x04\x88\x01\x01\x12:\n\x12invisible_duration\x18\x0f \x01(\x0b\x32\x19.google.protobuf.DurationH\x05\x88\x01\x01\x12\x1d\n\x10\x64\x65livery_attempt\x18\x10 \x01(\x05H\x06\x88\x01\x01\x12\x1a\n\rmessage_group\x18\x11 \x01(\tH\x07\x88\x01\x01\x12\x1a\n\rtrace_context\x18\x12 \x01(\tH\x08\x88\x01\x01\x12N\n&orphaned_transaction_recovery_duration\x18\x13 \x01(\x0b\x32\x19.google.protobuf.DurationH\t\x88\x01\x01\x42\x06\n\x04_tagB\x12\n\x10_store_timestampB\x15\n\x13_delivery_timestampB\x11\n\x0f_receipt_handleB\x0f\n\r_queue_offsetB\x15\n\x13_invisible_durationB\x13\n\x11_delivery_attemptB\x10\n\x0e_message_groupB\x10\n\x0e_trace_contextB)\n\'_orphaned_transaction_recovery_duration\"\x86\x02\n\x07Message\x12+\n\x05topic\x18\x01 \x01(\x0b\x32\x1c.apache.rocketmq.v2.Resource\x12H\n\x0fuser_properties\x18\x02 \x03(\x0b\x32/.apache.rocketmq.v2.Message.UserPropertiesEntry\x12?\n\x11system_properties\x18\x03 \x01(\x0b\x32$.apache.rocketmq.v2.SystemProperties\x12\x0c\n\x04\x62ody\x18\x04 \x01(\x0c\x1a\x35\n\x13UserPropertiesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"E\n\nAssignment\x12\x37\n\rmessage_queue\x18\x01 \x01(\x0b\x32 .apache.rocketmq.v2.MessageQueue\"A\n\x06Status\x12&\n\x04\x63ode\x18\x01 \x01(\x0e\x32\x18.apache.rocketmq.v2.Code\x12\x0f\n\x07message\x18\x02 \x01(\t\"i\n\x02UA\x12.\n\x08language\x18\x01 \x01(\x0e\x32\x1c.apache.rocketmq.v2.Language\x12\x0f\n\x07version\x18\x02 \x01(\t\x12\x10\n\x08platform\x18\x03 \x01(\t\x12\x10\n\x08hostname\x18\x04 \x01(\t*Y\n\x15TransactionResolution\x12&\n\"TRANSACTION_RESOLUTION_UNSPECIFIED\x10\x00\x12\n\n\x06\x43OMMIT\x10\x01\x12\x0c\n\x08ROLLBACK\x10\x02*W\n\x11TransactionSource\x12\x16\n\x12SOURCE_UNSPECIFIED\x10\x00\x12\x11\n\rSOURCE_CLIENT\x10\x01\x12\x17\n\x13SOURCE_SERVER_CHECK\x10\x02*W\n\nPermission\x12\x1a\n\x16PERMISSION_UNSPECIFIED\x10\x00\x12\x08\n\x04NONE\x10\x01\x12\x08\n\x04READ\x10\x02\x12\t\n\x05WRITE\x10\x03\x12\x0e\n\nREAD_WRITE\x10\x04*;\n\nFilterType\x12\x1b\n\x17\x46ILTER_TYPE_UNSPECIFIED\x10\x00\x12\x07\n\x03TAG\x10\x01\x12\x07\n\x03SQL\x10\x02*T\n\rAddressScheme\x12\x1e\n\x1a\x41\x44\x44RESS_SCHEME_UNSPECIFIED\x10\x00\x12\x08\n\x04IPv4\x10\x01\x12\x08\n\x04IPv6\x10\x02\x12\x0f\n\x0b\x44OMAIN_NAME\x10\x03*]\n\x0bMessageType\x12\x1c\n\x18MESSAGE_TYPE_UNSPECIFIED\x10\x00\x12\n\n\x06NORMAL\x10\x01\x12\x08\n\x04\x46IFO\x10\x02\x12\t\n\x05\x44\x45LAY\x10\x03\x12\x0f\n\x0bTRANSACTION\x10\x04*G\n\nDigestType\x12\x1b\n\x17\x44IGEST_TYPE_UNSPECIFIED\x10\x00\x12\t\n\x05\x43RC32\x10\x01\x12\x07\n\x03MD5\x10\x02\x12\x08\n\x04SHA1\x10\x03*_\n\nClientType\x12\x1b\n\x17\x43LIENT_TYPE_UNSPECIFIED\x10\x00\x12\x0c\n\x08PRODUCER\x10\x01\x12\x11\n\rPUSH_CONSUMER\x10\x02\x12\x13\n\x0fSIMPLE_CONSUMER\x10\x03*<\n\x08\x45ncoding\x12\x18\n\x14\x45NCODING_UNSPECIFIED\x10\x00\x12\x0c\n\x08IDENTITY\x10\x01\x12\x08\n\x04GZIP\x10\x02*\xe2\t\n\x04\x43ode\x12\x14\n\x10\x43ODE_UNSPECIFIED\x10\x00\x12\x08\n\x02OK\x10\xa0\x9c\x01\x12\x16\n\x10MULTIPLE_RESULTS\x10\xb0\xea\x01\x12\x11\n\x0b\x42\x41\x44_REQUEST\x10\xc0\xb8\x02\x12\x1a\n\x14ILLEGAL_ACCESS_POINT\x10\xc1\xb8\x02\x12\x13\n\rILLEGAL_TOPIC\x10\xc2\xb8\x02\x12\x1c\n\x16ILLEGAL_CONSUMER_GROUP\x10\xc3\xb8\x02\x12\x19\n\x13ILLEGAL_MESSAGE_TAG\x10\xc4\xb8\x02\x12\x19\n\x13ILLEGAL_MESSAGE_KEY\x10\xc5\xb8\x02\x12\x1b\n\x15ILLEGAL_MESSAGE_GROUP\x10\xc6\xb8\x02\x12\"\n\x1cILLEGAL_MESSAGE_PROPERTY_KEY\x10\xc7\xb8\x02\x12\x1c\n\x16INVALID_TRANSACTION_ID\x10\xc8\xb8\x02\x12\x18\n\x12ILLEGAL_MESSAGE_ID\x10\xc9\xb8\x02\x12\x1f\n\x19ILLEGAL_FILTER_EXPRESSION\x10\xca\xb8\x02\x12\x1c\n\x16ILLEGAL_INVISIBLE_TIME\x10\xcb\xb8\x02\x12\x1b\n\x15ILLEGAL_DELIVERY_TIME\x10\xcc\xb8\x02\x12\x1c\n\x16INVALID_RECEIPT_HANDLE\x10\xcd\xb8\x02\x12)\n#MESSAGE_PROPERTY_CONFLICT_WITH_TYPE\x10\xce\xb8\x02\x12\x1e\n\x18UNRECOGNIZED_CLIENT_TYPE\x10\xcf\xb8\x02\x12\x17\n\x11MESSAGE_CORRUPTED\x10\xd0\xb8\x02\x12\x18\n\x12\x43LIENT_ID_REQUIRED\x10\xd1\xb8\x02\x12\x12\n\x0cUNAUTHORIZED\x10\xa4\xb9\x02\x12\x16\n\x10PAYMENT_REQUIRED\x10\x88\xba\x02\x12\x0f\n\tFORBIDDEN\x10\xec\xba\x02\x12\x0f\n\tNOT_FOUND\x10\xd0\xbb\x02\x12\x17\n\x11MESSAGE_NOT_FOUND\x10\xd1\xbb\x02\x12\x15\n\x0fTOPIC_NOT_FOUND\x10\xd2\xbb\x02\x12\x1e\n\x18\x43ONSUMER_GROUP_NOT_FOUND\x10\xd3\xbb\x02\x12\x15\n\x0fREQUEST_TIMEOUT\x10\xe0\xbe\x02\x12\x17\n\x11PAYLOAD_TOO_LARGE\x10\xd4\xc2\x02\x12\x1c\n\x16MESSAGE_BODY_TOO_LARGE\x10\xd5\xc2\x02\x12\x19\n\x13PRECONDITION_FAILED\x10\xb0\xce\x02\x12\x17\n\x11TOO_MANY_REQUESTS\x10\x94\xcf\x02\x12%\n\x1fREQUEST_HEADER_FIELDS_TOO_LARGE\x10\xdc\xd0\x02\x12\"\n\x1cMESSAGE_PROPERTIES_TOO_LARGE\x10\xdd\xd0\x02\x12\x14\n\x0eINTERNAL_ERROR\x10\xd0\x86\x03\x12\x1b\n\x15INTERNAL_SERVER_ERROR\x10\xd1\x86\x03\x12\x16\n\x10HA_NOT_AVAILABLE\x10\xd2\x86\x03\x12\x15\n\x0fNOT_IMPLEMENTED\x10\xb4\x87\x03\x12\x13\n\rPROXY_TIMEOUT\x10\xe0\x89\x03\x12 \n\x1aMASTER_PERSISTENCE_TIMEOUT\x10\xe1\x89\x03\x12\x1f\n\x19SLAVE_PERSISTENCE_TIMEOUT\x10\xe2\x89\x03\x12\x11\n\x0bUNSUPPORTED\x10\xc4\x8a\x03\x12\x19\n\x13VERSION_UNSUPPORTED\x10\xc5\x8a\x03\x12%\n\x1fVERIFY_FIFO_MESSAGE_UNSUPPORTED\x10\xc6\x8a\x03\x12\x1f\n\x19\x46\x41ILED_TO_CONSUME_MESSAGE\x10\xe0\xd4\x03*Z\n\x08Language\x12\x18\n\x14LANGUAGE_UNSPECIFIED\x10\x00\x12\x08\n\x04JAVA\x10\x01\x12\x07\n\x03\x43PP\x10\x02\x12\x0b\n\x07\x44OT_NET\x10\x03\x12\n\n\x06GOLANG\x10\x04\x12\x08\n\x04RUST\x10\x05\x42;\n\x12\x61pache.rocketmq.v2B\x08MQDomainP\x01\xa0\x01\x01\xd8\x01\x01\xaa\x02\x12\x41pache.Rocketmq.V2b\x06proto3')
+
+_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
+_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'definition_pb2', globals())
+if _descriptor._USE_C_DESCRIPTORS == False:
+
+  DESCRIPTOR._options = None
+  DESCRIPTOR._serialized_options = b'\n\022apache.rocketmq.v2B\010MQDomainP\001\240\001\001\330\001\001\252\002\022Apache.Rocketmq.V2'
+  _MESSAGE_USERPROPERTIESENTRY._options = None
+  _MESSAGE_USERPROPERTIESENTRY._serialized_options = b'8\001'
+  _TRANSACTIONRESOLUTION._serialized_start=2752
+  _TRANSACTIONRESOLUTION._serialized_end=2841
+  _TRANSACTIONSOURCE._serialized_start=2843
+  _TRANSACTIONSOURCE._serialized_end=2930
+  _PERMISSION._serialized_start=2932
+  _PERMISSION._serialized_end=3019
+  _FILTERTYPE._serialized_start=3021
+  _FILTERTYPE._serialized_end=3080
+  _ADDRESSSCHEME._serialized_start=3082
+  _ADDRESSSCHEME._serialized_end=3166
+  _MESSAGETYPE._serialized_start=3168
+  _MESSAGETYPE._serialized_end=3261
+  _DIGESTTYPE._serialized_start=3263
+  _DIGESTTYPE._serialized_end=3334
+  _CLIENTTYPE._serialized_start=3336
+  _CLIENTTYPE._serialized_end=3431
+  _ENCODING._serialized_start=3433
+  _ENCODING._serialized_end=3493
+  _CODE._serialized_start=3496
+  _CODE._serialized_end=4746
+  _LANGUAGE._serialized_start=4748
+  _LANGUAGE._serialized_end=4838
+  _FILTEREXPRESSION._serialized_start=105
+  _FILTEREXPRESSION._serialized_end=189
+  _RETRYPOLICY._serialized_start=192
+  _RETRYPOLICY._serialized_end=379
+  _EXPONENTIALBACKOFF._serialized_start=381
+  _EXPONENTIALBACKOFF._serialized_end=505
+  _CUSTOMIZEDBACKOFF._serialized_start=507
+  _CUSTOMIZEDBACKOFF._serialized_end=567
+  _RESOURCE._serialized_start=569
+  _RESOURCE._serialized_end=621
+  _SUBSCRIPTIONENTRY._serialized_start=623
+  _SUBSCRIPTIONENTRY._serialized_end=745
+  _ADDRESS._serialized_start=747
+  _ADDRESS._serialized_end=784
+  _ENDPOINTS._serialized_start=786
+  _ENDPOINTS._serialized_end=896
+  _BROKER._serialized_start=898
+  _BROKER._serialized_end=982
+  _MESSAGEQUEUE._serialized_start=985
+  _MESSAGEQUEUE._serialized_end=1215
+  _DIGEST._serialized_start=1217
+  _DIGEST._serialized_end=1289
+  _SYSTEMPROPERTIES._serialized_start=1292
+  _SYSTEMPROPERTIES._serialized_end=2240
+  _MESSAGE._serialized_start=2243
+  _MESSAGE._serialized_end=2505
+  _MESSAGE_USERPROPERTIESENTRY._serialized_start=2452
+  _MESSAGE_USERPROPERTIESENTRY._serialized_end=2505
+  _ASSIGNMENT._serialized_start=2507
+  _ASSIGNMENT._serialized_end=2576
+  _STATUS._serialized_start=2578
+  _STATUS._serialized_end=2643
+  _UA._serialized_start=2645
+  _UA._serialized_end=2750
+# @@protoc_insertion_point(module_scope)
diff --git a/python/protocol/definition_pb2_grpc.py b/python/protocol/definition_pb2_grpc.py
new file mode 100644
index 0000000..2cd6c81
--- /dev/null
+++ b/python/protocol/definition_pb2_grpc.py
@@ -0,0 +1,19 @@
+# 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.
+
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
diff --git a/python/protocol/service_pb2.py b/python/protocol/service_pb2.py
new file mode 100644
index 0000000..3b5ee27
--- /dev/null
+++ b/python/protocol/service_pb2.py
@@ -0,0 +1,110 @@
+# 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.
+
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: service.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import builder as _builder
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import descriptor_pool as _descriptor_pool
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2
+from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
+import definition_pb2 as definition__pb2
+
+
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\rservice.proto\x12\x12\x61pache.rocketmq.v2\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x10\x64\x65\x66inition.proto\"r\n\x11QueryRouteRequest\x12+\n\x05topic\x18\x01 \x01(\x0b\x32\x1c.apache.rocketmq.v2.Resource\x12\x30\n\tendpoints\x18\x02 \x01(\x0b\x32\x1d.apache.rocketmq.v2.Endpoints\"z\n\x12QueryRouteResponse\x12*\n\x06status\x18\x01 \x01(\x0b\x32\x1a.apache.rocketmq.v2.Status\x12\x38\n\x0emessage_queues\x18\x02 \x03(\x0b\x32 .apache.rocketmq.v2.MessageQueue\"C\n\x12SendMessageRequest\x12-\n\x08messages\x18\x01 \x03(\x0b\x32\x1b.apache.rocketmq.v2.Message\"y\n\x0fSendResultEntry\x12*\n\x06status\x18\x01 \x01(\x0b\x32\x1a.apache.rocketmq.v2.Status\x12\x12\n\nmessage_id\x18\x02 \x01(\t\x12\x16\n\x0etransaction_id\x18\x03 \x01(\t\x12\x0e\n\x06offset\x18\x04 \x01(\x03\"w\n\x13SendMessageResponse\x12*\n\x06status\x18\x01 \x01(\x0b\x32\x1a.apache.rocketmq.v2.Status\x12\x34\n\x07\x65ntries\x18\x02 \x03(\x0b\x32#.apache.rocketmq.v2.SendResultEntry\"\xa4\x01\n\x16QueryAssignmentRequest\x12+\n\x05topic\x18\x01 \x01(\x0b\x32\x1c.apache.rocketmq.v2.Resource\x12+\n\x05group\x18\x02 \x01(\x0b\x32\x1c.apache.rocketmq.v2.Resource\x12\x30\n\tendpoints\x18\x03 \x01(\x0b\x32\x1d.apache.rocketmq.v2.Endpoints\"z\n\x17QueryAssignmentResponse\x12*\n\x06status\x18\x01 \x01(\x0b\x32\x1a.apache.rocketmq.v2.Status\x12\x33\n\x0b\x61ssignments\x18\x02 \x03(\x0b\x32\x1e.apache.rocketmq.v2.Assignment\"\xb9\x02\n\x15ReceiveMessageRequest\x12+\n\x05group\x18\x01 \x01(\x0b\x32\x1c.apache.rocketmq.v2.Resource\x12\x37\n\rmessage_queue\x18\x02 \x01(\x0b\x32 .apache.rocketmq.v2.MessageQueue\x12?\n\x11\x66ilter_expression\x18\x03 \x01(\x0b\x32$.apache.rocketmq.v2.FilterExpression\x12\x12\n\nbatch_size\x18\x04 \x01(\x05\x12:\n\x12invisible_duration\x18\x05 \x01(\x0b\x32\x19.google.protobuf.DurationH\x00\x88\x01\x01\x12\x12\n\nauto_renew\x18\x06 \x01(\x08\x42\x15\n\x13_invisible_duration\"\xbb\x01\n\x16ReceiveMessageResponse\x12,\n\x06status\x18\x01 \x01(\x0b\x32\x1a.apache.rocketmq.v2.StatusH\x00\x12.\n\x07message\x18\x02 \x01(\x0b\x32\x1b.apache.rocketmq.v2.MessageH\x00\x12\x38\n\x12\x64\x65livery_timestamp\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00\x42\t\n\x07\x63ontent\"=\n\x0f\x41\x63kMessageEntry\x12\x12\n\nmessage_id\x18\x01 \x01(\t\x12\x16\n\x0ereceipt_handle\x18\x02 \x01(\t\"\xa3\x01\n\x11\x41\x63kMessageRequest\x12+\n\x05group\x18\x01 \x01(\x0b\x32\x1c.apache.rocketmq.v2.Resource\x12+\n\x05topic\x18\x02 \x01(\x0b\x32\x1c.apache.rocketmq.v2.Resource\x12\x34\n\x07\x65ntries\x18\x03 \x03(\x0b\x32#.apache.rocketmq.v2.AckMessageEntry\"o\n\x15\x41\x63kMessageResultEntry\x12\x12\n\nmessage_id\x18\x01 \x01(\t\x12\x16\n\x0ereceipt_handle\x18\x02 \x01(\t\x12*\n\x06status\x18\x03 \x01(\x0b\x32\x1a.apache.rocketmq.v2.Status\"|\n\x12\x41\x63kMessageResponse\x12*\n\x06status\x18\x01 \x01(\x0b\x32\x1a.apache.rocketmq.v2.Status\x12:\n\x07\x65ntries\x18\x02 \x03(\x0b\x32).apache.rocketmq.v2.AckMessageResultEntry\"\xe7\x01\n&ForwardMessageToDeadLetterQueueRequest\x12+\n\x05group\x18\x01 \x01(\x0b\x32\x1c.apache.rocketmq.v2.Resource\x12+\n\x05topic\x18\x02 \x01(\x0b\x32\x1c.apache.rocketmq.v2.Resource\x12\x16\n\x0ereceipt_handle\x18\x03 \x01(\t\x12\x12\n\nmessage_id\x18\x04 \x01(\t\x12\x18\n\x10\x64\x65livery_attempt\x18\x05 \x01(\x05\x12\x1d\n\x15max_delivery_attempts\x18\x06 \x01(\x05\"U\n\'ForwardMessageToDeadLetterQueueResponse\x12*\n\x06status\x18\x01 \x01(\x0b\x32\x1a.apache.rocketmq.v2.Status\"\x83\x01\n\x10HeartbeatRequest\x12\x30\n\x05group\x18\x01 \x01(\x0b\x32\x1c.apache.rocketmq.v2.ResourceH\x00\x88\x01\x01\x12\x33\n\x0b\x63lient_type\x18\x02 \x01(\x0e\x32\x1e.apache.rocketmq.v2.ClientTypeB\x08\n\x06_group\"?\n\x11HeartbeatResponse\x12*\n\x06status\x18\x01 \x01(\x0b\x32\x1a.apache.rocketmq.v2.Status\"\xfd\x01\n\x15\x45ndTransactionRequest\x12+\n\x05topic\x18\x01 \x01(\x0b\x32\x1c.apache.rocketmq.v2.Resource\x12\x12\n\nmessage_id\x18\x02 \x01(\t\x12\x16\n\x0etransaction_id\x18\x03 \x01(\t\x12=\n\nresolution\x18\x04 \x01(\x0e\x32).apache.rocketmq.v2.TransactionResolution\x12\x35\n\x06source\x18\x05 \x01(\x0e\x32%.apache.rocketmq.v2.TransactionSource\x12\x15\n\rtrace_context\x18\x06 \x01(\t\"D\n\x16\x45ndTransactionResponse\x12*\n\x06status\x18\x01 \x01(\x0b\x32\x1a.apache.rocketmq.v2.Status\"-\n\x1cPrintThreadStackTraceCommand\x12\r\n\x05nonce\x18\x01 \x01(\t\"Y\n\x10ThreadStackTrace\x12\r\n\x05nonce\x18\x01 \x01(\t\x12\x1f\n\x12thread_stack_trace\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x15\n\x13_thread_stack_trace\"S\n\x14VerifyMessageCommand\x12\r\n\x05nonce\x18\x01 \x01(\t\x12,\n\x07message\x18\x02 \x01(\x0b\x32\x1b.apache.rocketmq.v2.Message\"$\n\x13VerifyMessageResult\x12\r\n\x05nonce\x18\x01 \x01(\t\"i\n!RecoverOrphanedTransactionCommand\x12,\n\x07message\x18\x01 \x01(\x0b\x32\x1b.apache.rocketmq.v2.Message\x12\x16\n\x0etransaction_id\x18\x02 \x01(\t\"p\n\nPublishing\x12,\n\x06topics\x18\x01 \x03(\x0b\x32\x1c.apache.rocketmq.v2.Resource\x12\x15\n\rmax_body_size\x18\x02 \x01(\x05\x12\x1d\n\x15validate_message_type\x18\x03 \x01(\x08\"\xb3\x02\n\x0cSubscription\x12\x30\n\x05group\x18\x01 \x01(\x0b\x32\x1c.apache.rocketmq.v2.ResourceH\x00\x88\x01\x01\x12<\n\rsubscriptions\x18\x02 \x03(\x0b\x32%.apache.rocketmq.v2.SubscriptionEntry\x12\x11\n\x04\x66ifo\x18\x03 \x01(\x08H\x01\x88\x01\x01\x12\x1f\n\x12receive_batch_size\x18\x04 \x01(\x05H\x02\x88\x01\x01\x12<\n\x14long_polling_timeout\x18\x05 \x01(\x0b\x32\x19.google.protobuf.DurationH\x03\x88\x01\x01\x42\x08\n\x06_groupB\x07\n\x05_fifoB\x15\n\x13_receive_batch_sizeB\x17\n\x15_long_polling_timeout\"Y\n\x06Metric\x12\n\n\x02on\x18\x01 \x01(\x08\x12\x35\n\tendpoints\x18\x02 \x01(\x0b\x32\x1d.apache.rocketmq.v2.EndpointsH\x00\x88\x01\x01\x42\x0c\n\n_endpoints\"\x90\x04\n\x08Settings\x12\x38\n\x0b\x63lient_type\x18\x01 \x01(\x0e\x32\x1e.apache.rocketmq.v2.ClientTypeH\x01\x88\x01\x01\x12\x38\n\x0c\x61\x63\x63\x65ss_point\x18\x02 \x01(\x0b\x32\x1d.apache.rocketmq.v2.EndpointsH\x02\x88\x01\x01\x12<\n\x0e\x62\x61\x63koff_policy\x18\x03 \x01(\x0b\x32\x1f.apache.rocketmq.v2.RetryPolicyH\x03\x88\x01\x01\x12\x37\n\x0frequest_timeout\x18\x04 \x01(\x0b\x32\x19.google.protobuf.DurationH\x04\x88\x01\x01\x12\x34\n\npublishing\x18\x05 \x01(\x0b\x32\x1e.apache.rocketmq.v2.PublishingH\x00\x12\x38\n\x0csubscription\x18\x06 \x01(\x0b\x32 .apache.rocketmq.v2.SubscriptionH\x00\x12*\n\nuser_agent\x18\x07 \x01(\x0b\x32\x16.apache.rocketmq.v2.UA\x12*\n\x06metric\x18\x08 \x01(\x0b\x32\x1a.apache.rocketmq.v2.MetricB\t\n\x07pub_subB\x0e\n\x0c_client_typeB\x0f\n\r_access_pointB\x11\n\x0f_backoff_policyB\x12\n\x10_request_timeout\"\xaa\x04\n\x10TelemetryCommand\x12/\n\x06status\x18\x01 \x01(\x0b\x32\x1a.apache.rocketmq.v2.StatusH\x01\x88\x01\x01\x12\x30\n\x08settings\x18\x02 \x01(\x0b\x32\x1c.apache.rocketmq.v2.SettingsH\x00\x12\x42\n\x12thread_stack_trace\x18\x03 \x01(\x0b\x32$.apache.rocketmq.v2.ThreadStackTraceH\x00\x12H\n\x15verify_message_result\x18\x04 \x01(\x0b\x32\'.apache.rocketmq.v2.VerifyMessageResultH\x00\x12\x65\n$recover_orphaned_transaction_command\x18\x05 \x01(\x0b\x32\x35.apache.rocketmq.v2.RecoverOrphanedTransactionCommandH\x00\x12\\\n print_thread_stack_trace_command\x18\x06 \x01(\x0b\x32\x30.apache.rocketmq.v2.PrintThreadStackTraceCommandH\x00\x12J\n\x16verify_message_command\x18\x07 \x01(\x0b\x32(.apache.rocketmq.v2.VerifyMessageCommandH\x00\x42\t\n\x07\x63ommandB\t\n\x07_status\"\\\n\x1eNotifyClientTerminationRequest\x12\x30\n\x05group\x18\x01 \x01(\x0b\x32\x1c.apache.rocketmq.v2.ResourceH\x00\x88\x01\x01\x42\x08\n\x06_group\"M\n\x1fNotifyClientTerminationResponse\x12*\n\x06status\x18\x01 \x01(\x0b\x32\x1a.apache.rocketmq.v2.Status\"\xdd\x01\n\x1e\x43hangeInvisibleDurationRequest\x12+\n\x05group\x18\x01 \x01(\x0b\x32\x1c.apache.rocketmq.v2.Resource\x12+\n\x05topic\x18\x02 \x01(\x0b\x32\x1c.apache.rocketmq.v2.Resource\x12\x16\n\x0ereceipt_handle\x18\x03 \x01(\t\x12\x35\n\x12invisible_duration\x18\x04 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x12\n\nmessage_id\x18\x05 \x01(\t\"e\n\x1f\x43hangeInvisibleDurationResponse\x12*\n\x06status\x18\x01 \x01(\x0b\x32\x1a.apache.rocketmq.v2.Status\x12\x16\n\x0ereceipt_handle\x18\x02 \x01(\t2\xe0\t\n\x10MessagingService\x12]\n\nQueryRoute\x12%.apache.rocketmq.v2.QueryRouteRequest\x1a&.apache.rocketmq.v2.QueryRouteResponse\"\x00\x12Z\n\tHeartbeat\x12$.apache.rocketmq.v2.HeartbeatRequest\x1a%.apache.rocketmq.v2.HeartbeatResponse\"\x00\x12`\n\x0bSendMessage\x12&.apache.rocketmq.v2.SendMessageRequest\x1a\'.apache.rocketmq.v2.SendMessageResponse\"\x00\x12l\n\x0fQueryAssignment\x12*.apache.rocketmq.v2.QueryAssignmentRequest\x1a+.apache.rocketmq.v2.QueryAssignmentResponse\"\x00\x12k\n\x0eReceiveMessage\x12).apache.rocketmq.v2.ReceiveMessageRequest\x1a*.apache.rocketmq.v2.ReceiveMessageResponse\"\x00\x30\x01\x12]\n\nAckMessage\x12%.apache.rocketmq.v2.AckMessageRequest\x1a&.apache.rocketmq.v2.AckMessageResponse\"\x00\x12\x9c\x01\n\x1f\x46orwardMessageToDeadLetterQueue\x12:.apache.rocketmq.v2.ForwardMessageToDeadLetterQueueRequest\x1a;.apache.rocketmq.v2.ForwardMessageToDeadLetterQueueResponse\"\x00\x12i\n\x0e\x45ndTransaction\x12).apache.rocketmq.v2.EndTransactionRequest\x1a*.apache.rocketmq.v2.EndTransactionResponse\"\x00\x12]\n\tTelemetry\x12$.apache.rocketmq.v2.TelemetryCommand\x1a$.apache.rocketmq.v2.TelemetryCommand\"\x00(\x01\x30\x01\x12\x84\x01\n\x17NotifyClientTermination\x12\x32.apache.rocketmq.v2.NotifyClientTerminationRequest\x1a\x33.apache.rocketmq.v2.NotifyClientTerminationResponse\"\x00\x12\x84\x01\n\x17\x43hangeInvisibleDuration\x12\x32.apache.rocketmq.v2.ChangeInvisibleDurationRequest\x1a\x33.apache.rocketmq.v2.ChangeInvisibleDurationResponse\"\x00\x42<\n\x12\x61pache.rocketmq.v2B\tMQServiceP\x01\xa0\x01\x01\xd8\x01\x01\xaa\x02\x12\x41pache.Rocketmq.V2b\x06proto3')
+
+_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
+_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'service_pb2', globals())
+if _descriptor._USE_C_DESCRIPTORS == False:
+
+  DESCRIPTOR._options = None
+  DESCRIPTOR._serialized_options = b'\n\022apache.rocketmq.v2B\tMQServiceP\001\240\001\001\330\001\001\252\002\022Apache.Rocketmq.V2'
+  _QUERYROUTEREQUEST._serialized_start=120
+  _QUERYROUTEREQUEST._serialized_end=234
+  _QUERYROUTERESPONSE._serialized_start=236
+  _QUERYROUTERESPONSE._serialized_end=358
+  _SENDMESSAGEREQUEST._serialized_start=360
+  _SENDMESSAGEREQUEST._serialized_end=427
+  _SENDRESULTENTRY._serialized_start=429
+  _SENDRESULTENTRY._serialized_end=550
+  _SENDMESSAGERESPONSE._serialized_start=552
+  _SENDMESSAGERESPONSE._serialized_end=671
+  _QUERYASSIGNMENTREQUEST._serialized_start=674
+  _QUERYASSIGNMENTREQUEST._serialized_end=838
+  _QUERYASSIGNMENTRESPONSE._serialized_start=840
+  _QUERYASSIGNMENTRESPONSE._serialized_end=962
+  _RECEIVEMESSAGEREQUEST._serialized_start=965
+  _RECEIVEMESSAGEREQUEST._serialized_end=1278
+  _RECEIVEMESSAGERESPONSE._serialized_start=1281
+  _RECEIVEMESSAGERESPONSE._serialized_end=1468
+  _ACKMESSAGEENTRY._serialized_start=1470
+  _ACKMESSAGEENTRY._serialized_end=1531
+  _ACKMESSAGEREQUEST._serialized_start=1534
+  _ACKMESSAGEREQUEST._serialized_end=1697
+  _ACKMESSAGERESULTENTRY._serialized_start=1699
+  _ACKMESSAGERESULTENTRY._serialized_end=1810
+  _ACKMESSAGERESPONSE._serialized_start=1812
+  _ACKMESSAGERESPONSE._serialized_end=1936
+  _FORWARDMESSAGETODEADLETTERQUEUEREQUEST._serialized_start=1939
+  _FORWARDMESSAGETODEADLETTERQUEUEREQUEST._serialized_end=2170
+  _FORWARDMESSAGETODEADLETTERQUEUERESPONSE._serialized_start=2172
+  _FORWARDMESSAGETODEADLETTERQUEUERESPONSE._serialized_end=2257
+  _HEARTBEATREQUEST._serialized_start=2260
+  _HEARTBEATREQUEST._serialized_end=2391
+  _HEARTBEATRESPONSE._serialized_start=2393
+  _HEARTBEATRESPONSE._serialized_end=2456
+  _ENDTRANSACTIONREQUEST._serialized_start=2459
+  _ENDTRANSACTIONREQUEST._serialized_end=2712
+  _ENDTRANSACTIONRESPONSE._serialized_start=2714
+  _ENDTRANSACTIONRESPONSE._serialized_end=2782
+  _PRINTTHREADSTACKTRACECOMMAND._serialized_start=2784
+  _PRINTTHREADSTACKTRACECOMMAND._serialized_end=2829
+  _THREADSTACKTRACE._serialized_start=2831
+  _THREADSTACKTRACE._serialized_end=2920
+  _VERIFYMESSAGECOMMAND._serialized_start=2922
+  _VERIFYMESSAGECOMMAND._serialized_end=3005
+  _VERIFYMESSAGERESULT._serialized_start=3007
+  _VERIFYMESSAGERESULT._serialized_end=3043
+  _RECOVERORPHANEDTRANSACTIONCOMMAND._serialized_start=3045
+  _RECOVERORPHANEDTRANSACTIONCOMMAND._serialized_end=3150
+  _PUBLISHING._serialized_start=3152
+  _PUBLISHING._serialized_end=3264
+  _SUBSCRIPTION._serialized_start=3267
+  _SUBSCRIPTION._serialized_end=3574
+  _METRIC._serialized_start=3576
+  _METRIC._serialized_end=3665
+  _SETTINGS._serialized_start=3668
+  _SETTINGS._serialized_end=4196
+  _TELEMETRYCOMMAND._serialized_start=4199
+  _TELEMETRYCOMMAND._serialized_end=4753
+  _NOTIFYCLIENTTERMINATIONREQUEST._serialized_start=4755
+  _NOTIFYCLIENTTERMINATIONREQUEST._serialized_end=4847
+  _NOTIFYCLIENTTERMINATIONRESPONSE._serialized_start=4849
+  _NOTIFYCLIENTTERMINATIONRESPONSE._serialized_end=4926
+  _CHANGEINVISIBLEDURATIONREQUEST._serialized_start=4929
+  _CHANGEINVISIBLEDURATIONREQUEST._serialized_end=5150
+  _CHANGEINVISIBLEDURATIONRESPONSE._serialized_start=5152
+  _CHANGEINVISIBLEDURATIONRESPONSE._serialized_end=5253
+  _MESSAGINGSERVICE._serialized_start=5256
+  _MESSAGINGSERVICE._serialized_end=6504
+# @@protoc_insertion_point(module_scope)
diff --git a/python/protocol/service_pb2_grpc.py b/python/protocol/service_pb2_grpc.py
new file mode 100644
index 0000000..bc7050c
--- /dev/null
+++ b/python/protocol/service_pb2_grpc.py
@@ -0,0 +1,511 @@
+# 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.
+
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+import service_pb2 as service__pb2
+
+
+class MessagingServiceStub(object):
+    """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`.
+    """
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.QueryRoute = channel.unary_unary(
+                '/apache.rocketmq.v2.MessagingService/QueryRoute',
+                request_serializer=service__pb2.QueryRouteRequest.SerializeToString,
+                response_deserializer=service__pb2.QueryRouteResponse.FromString,
+                )
+        self.Heartbeat = channel.unary_unary(
+                '/apache.rocketmq.v2.MessagingService/Heartbeat',
+                request_serializer=service__pb2.HeartbeatRequest.SerializeToString,
+                response_deserializer=service__pb2.HeartbeatResponse.FromString,
+                )
+        self.SendMessage = channel.unary_unary(
+                '/apache.rocketmq.v2.MessagingService/SendMessage',
+                request_serializer=service__pb2.SendMessageRequest.SerializeToString,
+                response_deserializer=service__pb2.SendMessageResponse.FromString,
+                )
+        self.QueryAssignment = channel.unary_unary(
+                '/apache.rocketmq.v2.MessagingService/QueryAssignment',
+                request_serializer=service__pb2.QueryAssignmentRequest.SerializeToString,
+                response_deserializer=service__pb2.QueryAssignmentResponse.FromString,
+                )
+        self.ReceiveMessage = channel.unary_stream(
+                '/apache.rocketmq.v2.MessagingService/ReceiveMessage',
+                request_serializer=service__pb2.ReceiveMessageRequest.SerializeToString,
+                response_deserializer=service__pb2.ReceiveMessageResponse.FromString,
+                )
+        self.AckMessage = channel.unary_unary(
+                '/apache.rocketmq.v2.MessagingService/AckMessage',
+                request_serializer=service__pb2.AckMessageRequest.SerializeToString,
+                response_deserializer=service__pb2.AckMessageResponse.FromString,
+                )
+        self.ForwardMessageToDeadLetterQueue = channel.unary_unary(
+                '/apache.rocketmq.v2.MessagingService/ForwardMessageToDeadLetterQueue',
+                request_serializer=service__pb2.ForwardMessageToDeadLetterQueueRequest.SerializeToString,
+                response_deserializer=service__pb2.ForwardMessageToDeadLetterQueueResponse.FromString,
+                )
+        self.EndTransaction = channel.unary_unary(
+                '/apache.rocketmq.v2.MessagingService/EndTransaction',
+                request_serializer=service__pb2.EndTransactionRequest.SerializeToString,
+                response_deserializer=service__pb2.EndTransactionResponse.FromString,
+                )
+        self.Telemetry = channel.stream_stream(
+                '/apache.rocketmq.v2.MessagingService/Telemetry',
+                request_serializer=service__pb2.TelemetryCommand.SerializeToString,
+                response_deserializer=service__pb2.TelemetryCommand.FromString,
+                )
+        self.NotifyClientTermination = channel.unary_unary(
+                '/apache.rocketmq.v2.MessagingService/NotifyClientTermination',
+                request_serializer=service__pb2.NotifyClientTerminationRequest.SerializeToString,
+                response_deserializer=service__pb2.NotifyClientTerminationResponse.FromString,
+                )
+        self.ChangeInvisibleDuration = channel.unary_unary(
+                '/apache.rocketmq.v2.MessagingService/ChangeInvisibleDuration',
+                request_serializer=service__pb2.ChangeInvisibleDurationRequest.SerializeToString,
+                response_deserializer=service__pb2.ChangeInvisibleDurationResponse.FromString,
+                )
+
+
+class MessagingServiceServicer(object):
+    """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`.
+    """
+
+    def QueryRoute(self, request, context):
+        """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`.
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Heartbeat(self, request, context):
+        """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`
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def SendMessage(self, request, context):
+        """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`.
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def QueryAssignment(self, request, context):
+        """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`.
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def ReceiveMessage(self, request, context):
+        """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.
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def AckMessage(self, request, context):
+        """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`.
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def ForwardMessageToDeadLetterQueue(self, request, context):
+        """Forwards one message to dead letter queue if the max delivery attempts is
+        exceeded by this message at client-side, return `OK` if success.
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def EndTransaction(self, request, context):
+        """Commits or rollback one transactional message.
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Telemetry(self, request_iterator, context):
+        """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.
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def NotifyClientTermination(self, request, context):
+        """Notify the server that the client is terminated.
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def ChangeInvisibleDuration(self, request, context):
+        """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.
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_MessagingServiceServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'QueryRoute': grpc.unary_unary_rpc_method_handler(
+                    servicer.QueryRoute,
+                    request_deserializer=service__pb2.QueryRouteRequest.FromString,
+                    response_serializer=service__pb2.QueryRouteResponse.SerializeToString,
+            ),
+            'Heartbeat': grpc.unary_unary_rpc_method_handler(
+                    servicer.Heartbeat,
+                    request_deserializer=service__pb2.HeartbeatRequest.FromString,
+                    response_serializer=service__pb2.HeartbeatResponse.SerializeToString,
+            ),
+            'SendMessage': grpc.unary_unary_rpc_method_handler(
+                    servicer.SendMessage,
+                    request_deserializer=service__pb2.SendMessageRequest.FromString,
+                    response_serializer=service__pb2.SendMessageResponse.SerializeToString,
+            ),
+            'QueryAssignment': grpc.unary_unary_rpc_method_handler(
+                    servicer.QueryAssignment,
+                    request_deserializer=service__pb2.QueryAssignmentRequest.FromString,
+                    response_serializer=service__pb2.QueryAssignmentResponse.SerializeToString,
+            ),
+            'ReceiveMessage': grpc.unary_stream_rpc_method_handler(
+                    servicer.ReceiveMessage,
+                    request_deserializer=service__pb2.ReceiveMessageRequest.FromString,
+                    response_serializer=service__pb2.ReceiveMessageResponse.SerializeToString,
+            ),
+            'AckMessage': grpc.unary_unary_rpc_method_handler(
+                    servicer.AckMessage,
+                    request_deserializer=service__pb2.AckMessageRequest.FromString,
+                    response_serializer=service__pb2.AckMessageResponse.SerializeToString,
+            ),
+            'ForwardMessageToDeadLetterQueue': grpc.unary_unary_rpc_method_handler(
+                    servicer.ForwardMessageToDeadLetterQueue,
+                    request_deserializer=service__pb2.ForwardMessageToDeadLetterQueueRequest.FromString,
+                    response_serializer=service__pb2.ForwardMessageToDeadLetterQueueResponse.SerializeToString,
+            ),
+            'EndTransaction': grpc.unary_unary_rpc_method_handler(
+                    servicer.EndTransaction,
+                    request_deserializer=service__pb2.EndTransactionRequest.FromString,
+                    response_serializer=service__pb2.EndTransactionResponse.SerializeToString,
+            ),
+            'Telemetry': grpc.stream_stream_rpc_method_handler(
+                    servicer.Telemetry,
+                    request_deserializer=service__pb2.TelemetryCommand.FromString,
+                    response_serializer=service__pb2.TelemetryCommand.SerializeToString,
+            ),
+            'NotifyClientTermination': grpc.unary_unary_rpc_method_handler(
+                    servicer.NotifyClientTermination,
+                    request_deserializer=service__pb2.NotifyClientTerminationRequest.FromString,
+                    response_serializer=service__pb2.NotifyClientTerminationResponse.SerializeToString,
+            ),
+            'ChangeInvisibleDuration': grpc.unary_unary_rpc_method_handler(
+                    servicer.ChangeInvisibleDuration,
+                    request_deserializer=service__pb2.ChangeInvisibleDurationRequest.FromString,
+                    response_serializer=service__pb2.ChangeInvisibleDurationResponse.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'apache.rocketmq.v2.MessagingService', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class MessagingService(object):
+    """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`.
+    """
+
+    @staticmethod
+    def QueryRoute(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/apache.rocketmq.v2.MessagingService/QueryRoute',
+            service__pb2.QueryRouteRequest.SerializeToString,
+            service__pb2.QueryRouteResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Heartbeat(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/apache.rocketmq.v2.MessagingService/Heartbeat',
+            service__pb2.HeartbeatRequest.SerializeToString,
+            service__pb2.HeartbeatResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def SendMessage(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/apache.rocketmq.v2.MessagingService/SendMessage',
+            service__pb2.SendMessageRequest.SerializeToString,
+            service__pb2.SendMessageResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def QueryAssignment(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/apache.rocketmq.v2.MessagingService/QueryAssignment',
+            service__pb2.QueryAssignmentRequest.SerializeToString,
+            service__pb2.QueryAssignmentResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def ReceiveMessage(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_stream(request, target, '/apache.rocketmq.v2.MessagingService/ReceiveMessage',
+            service__pb2.ReceiveMessageRequest.SerializeToString,
+            service__pb2.ReceiveMessageResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def AckMessage(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/apache.rocketmq.v2.MessagingService/AckMessage',
+            service__pb2.AckMessageRequest.SerializeToString,
+            service__pb2.AckMessageResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def ForwardMessageToDeadLetterQueue(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/apache.rocketmq.v2.MessagingService/ForwardMessageToDeadLetterQueue',
+            service__pb2.ForwardMessageToDeadLetterQueueRequest.SerializeToString,
+            service__pb2.ForwardMessageToDeadLetterQueueResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def EndTransaction(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/apache.rocketmq.v2.MessagingService/EndTransaction',
+            service__pb2.EndTransactionRequest.SerializeToString,
+            service__pb2.EndTransactionResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Telemetry(request_iterator,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.stream_stream(request_iterator, target, '/apache.rocketmq.v2.MessagingService/Telemetry',
+            service__pb2.TelemetryCommand.SerializeToString,
+            service__pb2.TelemetryCommand.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def NotifyClientTermination(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/apache.rocketmq.v2.MessagingService/NotifyClientTermination',
+            service__pb2.NotifyClientTerminationRequest.SerializeToString,
+            service__pb2.NotifyClientTerminationResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def ChangeInvisibleDuration(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/apache.rocketmq.v2.MessagingService/ChangeInvisibleDuration',
+            service__pb2.ChangeInvisibleDurationRequest.SerializeToString,
+            service__pb2.ChangeInvisibleDurationResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)