You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rocketmq.apache.org by li...@apache.org on 2022/05/20 09:01:20 UTC

[rocketmq-client-cpp] branch main updated: Adopt protocol v2 (#414)

This is an automated email from the ASF dual-hosted git repository.

lizhanhui pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/rocketmq-client-cpp.git


The following commit(s) were added to refs/heads/main by this push:
     new a44a2c6  Adopt protocol v2 (#414)
a44a2c6 is described below

commit a44a2c611406e62bd8af66e1a2a7f2070b53f728
Author: Zhanhui Li <li...@gmail.com>
AuthorDate: Fri May 20 17:01:16 2022 +0800

    Adopt protocol v2 (#414)
---
 .bazelversion                                      |    2 +-
 .clang-format                                      |    6 +-
 .gitignore                                         |    5 +-
 .vscode/settings.json                              |   13 +
 WORKSPACE                                          |    5 +-
 api/BUILD.bazel                                    |    1 +
 api/rocketmq/AsyncCallback.h                       |   50 -
 api/rocketmq/BackoffPolicy.h                       |   70 ++
 api/rocketmq/Configuration.h                       |   71 ++
 .../rocketmq/ConfigurationDefaults.h               |   14 +-
 api/rocketmq/{MessageModel.h => ConsumeResult.h}   |   11 +-
 api/rocketmq/ConsumeType.h                         |   70 --
 api/rocketmq/DefaultMQProducer.h                   |  154 ---
 api/rocketmq/DefaultMQPullConsumer.h               |   63 --
 api/rocketmq/DefaultMQPushConsumer.h               |  120 ---
 api/rocketmq/ErrorCode.h                           |   17 +-
 .../include => api/rocketmq}/FilterExpression.h    |    8 +-
 api/rocketmq/MQMessage.h                           |  115 ---
 api/rocketmq/MQMessageExt.h                        |   60 --
 api/rocketmq/MQMessageQueue.h                      |  153 ---
 api/rocketmq/Message.h                             |  176 ++++
 api/rocketmq/MessageListener.h                     |   43 +-
 api/rocketmq/OffsetStore.h                         |   34 -
 api/rocketmq/Producer.h                            |   95 ++
 api/rocketmq/PullResult.h                          |   55 -
 api/rocketmq/PushConsumer.h                        |   94 ++
 api/rocketmq/{MessageModel.h => SendCallback.h}    |   12 +-
 api/rocketmq/{MessageModel.h => SendReceipt.h}     |   14 +-
 api/rocketmq/SendResult.h                          |  137 ---
 api/rocketmq/SimpleConsumer.h                      |  111 ++
 api/rocketmq/{MessageModel.h => Tracing.h}         |   12 +-
 api/rocketmq/Transaction.h                         |   17 +-
 .../rocketmq/TransactionChecker.h                  |   12 +-
 api/rocketmq/{MessageType.h => TransactionState.h} |    9 +-
 bazel/rocketmq_deps.bzl                            |   81 +-
 example/rocketmq/ExampleAsyncProducer.cpp          |  257 -----
 example/rocketmq/ExampleBroadcastPushConsumer.cpp  |   65 --
 example/rocketmq/ExamplePullConsumer.cpp           |   54 -
 example/rocketmq/ExamplePushConsumer.cpp           |   69 --
 {example/rocketmq => examples}/BUILD.bazel         |  142 ++-
 .../BenchmarkPushConsumer.cpp                      |    0
 .../ExampleAsyncProducer.cpp                       |   62 +-
 .../rocketmq => examples}/ExampleFifoProducer.cpp  |   49 +-
 .../ExampleFifoPushConsumer.cpp                    |    0
 {example/rocketmq => examples}/ExampleProducer.cpp |   43 +-
 .../ExamplePushConsumer.cpp                        |   52 +-
 examples/ExampleSimpleConsumer.cpp                 |   66 ++
 .../ExampleTransactionProducer.cpp                 |    0
 .../PushConsumerWithCustomExecutor.cpp             |    0
 .../PushConsumerWithThrottle.cpp                   |    0
 {example/rocketmq => examples}/SqlConsumer.cpp     |    0
 {example/rocketmq => examples}/SqlProducer.cpp     |    0
 proto/BUILD.bazel                                  |    6 +-
 proto/apache/rocketmq/v1/definition.proto          |  349 -------
 proto/apache/rocketmq/v1/service.proto             |  531 ----------
 proto/apache/rocketmq/{v1 => v2}/admin.proto       |   12 +-
 proto/apache/rocketmq/v2/definition.proto          |  447 +++++++++
 proto/apache/rocketmq/v2/service.proto             |  436 ++++++++
 src/main/cpp/admin/include/AdminClient.h           |    4 +-
 src/main/cpp/admin/include/AdminServerImpl.h       |    8 +-
 src/main/cpp/admin/include/AdminServiceImpl.h      |    7 +-
 src/main/cpp/admin/include/ServerCall.h            |    4 +-
 src/main/cpp/base/BUILD.bazel                      |    1 +
 .../cpp/base/Configuration.cpp}                    |   40 +-
 .../DigestType.h => ConfigurationDefaults.cpp}     |   15 +-
 .../cpp/{rocketmq => base}/CredentialsProvider.cpp |    0
 src/main/cpp/base/ErrorCategory.cpp                |   13 +-
 .../cpp/{rocketmq => base}/FilterExpression.cpp    |    7 +-
 src/main/cpp/base/MQMessage.cpp                    |  190 ----
 src/main/cpp/base/MQMessageExt.cpp                 |   77 --
 src/main/cpp/base/Message.cpp                      |   89 ++
 src/main/cpp/base/MessageAccessor.cpp              |   91 --
 .../cpp/base/MessageExt.cpp}                       |   17 +-
 src/main/cpp/base/MetadataConstants.cpp            |   42 +-
 src/main/cpp/base/MixAll.cpp                       |   37 +-
 src/main/cpp/base/Protocol.cpp                     |  136 ++-
 .../cpp/base/{include/DigestType.h => Tracing.cpp} |   18 +-
 src/main/cpp/base/include/InvocationContext.h      |    2 +-
 src/main/cpp/base/include/MessageAccessor.h        |   61 --
 .../main/cpp/base/include/MessageExt.h             |   14 +-
 src/main/cpp/base/include/MessageImpl.h            |   36 -
 src/main/cpp/base/include/MetadataConstants.h      |    3 +
 src/main/cpp/base/include/MixAll.h                 |   10 +-
 src/main/cpp/base/include/Protocol.h               |  126 +--
 src/main/cpp/base/include/RetryPolicy.h            |   81 ++
 .../include/StsCredentialsProviderImpl.h           |    0
 .../include/{DigestType.h => SubscriptionEntry.h}  |   11 +-
 src/main/cpp/base/tests/AssignmentTest.cpp         |   23 +
 src/main/cpp/base/tests/BUILD.bazel                |   54 +
 src/main/cpp/base/tests/ConfigurationTest.cpp      |   54 +
 src/main/cpp/base/tests/MessageBuilderTest.cpp     |   56 ++
 src/main/cpp/base/tests/MessageQueueTest.cpp       |   21 +
 .../cpp/base/tests/MixAllTest.cpp}                 |    8 +-
 .../cpp/base/tests/RetryPolicyTest.cpp}            |   23 +-
 src/main/cpp/client/ClientConfigImpl.cpp           |   97 --
 src/main/cpp/client/ClientManagerFactory.cpp       |   12 +-
 src/main/cpp/client/ClientManagerImpl.cpp          | 1056 +++++---------------
 src/main/cpp/client/ReceiveMessageStreamReader.cpp |  118 +++
 src/main/cpp/client/RpcClientImpl.cpp              |  195 ++--
 .../SessionImpl.cpp}                               |   39 +-
 src/main/cpp/client/Signature.cpp                  |   26 +-
 src/main/cpp/client/TelemetryBidiReactor.cpp       |  339 +++++++
 src/main/cpp/client/TlsHelper.cpp                  |  214 +---
 src/main/cpp/client/TopicAssignmentInfo.cpp        |   57 +-
 src/main/cpp/client/TopicPublishInfo.cpp           |  154 ---
 src/main/cpp/client/include/Assignment.h           |   51 -
 src/main/cpp/client/include/Broker.h               |   62 --
 src/main/cpp/client/include/Client.h               |   35 +-
 src/main/cpp/client/include/ClientConfig.h         |   50 +-
 src/main/cpp/client/include/ClientConfigImpl.h     |  146 ---
 src/main/cpp/client/include/ClientManager.h        |   48 +-
 src/main/cpp/client/include/ClientManagerImpl.h    |   77 +-
 .../client/include/InsecureCertificateVerifier.h   |   42 +
 .../Encoding.h => client/include/Metadata.h}       |   11 +-
 src/main/cpp/client/include/Partition.h            |   89 --
 .../cpp/client/include/ReceiveMessageCallback.h    |   10 +-
 .../cpp/client/include/ReceiveMessageContext.h     |   17 +-
 src/main/cpp/client/include/ReceiveMessageResult.h |    4 +-
 .../client/include/ReceiveMessageStreamReader.h    |   63 ++
 src/main/cpp/client/include/RpcClient.h            |   78 +-
 src/main/cpp/client/include/RpcClientImpl.h        |   49 +-
 src/main/cpp/client/include/SendMessageContext.h   |   16 +-
 src/main/cpp/client/include/ServiceAddress.h       |  124 ---
 .../DigestType.h => client/include/Session.h}      |   12 +-
 .../main/cpp/client/include/SessionImpl.h          |   24 +-
 src/main/cpp/client/include/Signature.h            |    2 +-
 src/main/cpp/client/include/TelemetryBidiReactor.h |  121 +++
 src/main/cpp/client/include/TlsHelper.h            |   33 +-
 src/main/cpp/client/include/TopicAssignmentInfo.h  |   29 +-
 src/main/cpp/client/include/TopicRouteData.h       |   47 +-
 src/main/cpp/client/mocks/RpcClientMock.cpp        |   30 -
 .../cpp/client/mocks/include/ClientConfigMock.h    |   39 -
 .../cpp/client/mocks/include/ClientManagerMock.h   |   46 +-
 src/main/cpp/client/mocks/include/ClientMock.h     |   12 +-
 src/main/cpp/client/mocks/include/RpcClientMock.h  |   42 +-
 .../cpp/rocketmq/AsyncReceiveMessageCallback.cpp   |   21 +-
 src/main/cpp/rocketmq/BUILD.bazel                  |    4 +-
 src/main/cpp/rocketmq/ClientImpl.cpp               |  518 ++++------
 .../cpp/rocketmq/ConsumeFifoMessageService.cpp     |  166 ++-
 .../cpp/rocketmq/ConsumeMessageServiceBase.cpp     |   10 +-
 .../cpp/rocketmq/ConsumeStandardMessageService.cpp |  193 ++--
 src/main/cpp/rocketmq/DefaultMQProducer.cpp        |  253 -----
 src/main/cpp/rocketmq/DefaultMQPullConsumer.cpp    |   78 --
 src/main/cpp/rocketmq/DefaultMQPushConsumer.cpp    |  134 ---
 .../cpp/rocketmq/MessageGroupQueueSelector.cpp     |    3 +-
 src/main/cpp/rocketmq/NamingScheme.cpp             |   12 +-
 src/main/cpp/rocketmq/ProcessQueueImpl.cpp         |  163 +--
 src/main/cpp/rocketmq/Producer.cpp                 |   96 ++
 src/main/cpp/rocketmq/ProducerImpl.cpp             |  611 ++++++-----
 src/main/cpp/rocketmq/PullConsumerImpl.cpp         |  189 ----
 src/main/cpp/rocketmq/PushConsumer.cpp             |   53 +
 src/main/cpp/rocketmq/PushConsumerImpl.cpp         |  434 ++++----
 .../{SendCallbacks.cpp => SendContext.cpp}         |   80 +-
 src/main/cpp/rocketmq/SimpleConsumer.cpp           |  141 +++
 src/main/cpp/rocketmq/SimpleConsumerImpl.cpp       |  400 ++++++++
 src/main/cpp/rocketmq/TopicPublishInfo.cpp         |  125 +++
 src/main/cpp/rocketmq/TransactionImpl.cpp          |   10 +-
 .../rocketmq/include/AsyncReceiveMessageCallback.h |   16 +-
 src/main/cpp/rocketmq/include/AwaitPullCallback.h  |   58 --
 src/main/cpp/rocketmq/include/ClientImpl.h         |  108 +-
 .../rocketmq/include/ConsumeFifoMessageService.h   |   24 +-
 .../cpp/rocketmq/include/ConsumeMessageService.h   |    4 +-
 .../rocketmq/include/ConsumeMessageServiceBase.h   |    9 +-
 .../include/ConsumeStandardMessageService.h        |   18 +-
 src/main/cpp/rocketmq/include/Consumer.h           |    2 +
 .../rocketmq/include/MessageGroupQueueSelector.h   |    9 +-
 src/main/cpp/rocketmq/include/NamingScheme.h       |    6 +-
 src/main/cpp/rocketmq/include/ProcessQueue.h       |   29 +-
 src/main/cpp/rocketmq/include/ProcessQueueImpl.h   |   86 +-
 src/main/cpp/rocketmq/include/ProducerImpl.h       |   95 +-
 .../cpp/rocketmq/include/PublishInfoCallback.h     |   11 +-
 src/main/cpp/rocketmq/include/PullConsumerImpl.h   |   60 --
 src/main/cpp/rocketmq/include/PushConsumer.h       |   64 --
 src/main/cpp/rocketmq/include/PushConsumerImpl.h   |  131 +--
 src/main/cpp/rocketmq/include/SendCallbacks.h      |  125 ---
 src/main/cpp/rocketmq/include/SendContext.h        |   77 ++
 src/main/cpp/rocketmq/include/SimpleConsumerImpl.h |   89 ++
 .../include/TopicPublishInfo.h                     |   37 +-
 src/main/cpp/rocketmq/include/TransactionImpl.h    |   37 +-
 .../mocks/include/ConsumeMessageServiceMock.h      |    4 +-
 .../cpp/rocketmq/mocks/include/PushConsumerMock.h  |    4 +-
 .../logger => main/cpp/rocketmq/tests}/BUILD.bazel |   23 +-
 src/main/cpp/rocketmq/tests/SendContextTest.cpp    |   17 +
 .../DigestType.h => rocketmq/tests/TimeTest.cpp}   |   17 +-
 .../ut/scheduler => main/cpp/stats}/BUILD.bazel    |   18 +-
 src/main/cpp/stats/PublishStats.cpp                |   56 ++
 .../include/PublishStats.h}                        |   32 +-
 .../ut/api => main/cpp/stats/tests}/BUILD.bazel    |    6 +-
 src/main/cpp/stats/tests/PublishStatsTest.cpp      |   98 ++
 src/main/cpp/{tracing => trace}/BUILD.bazel        |    4 +-
 src/main/cpp/{tracing => trace}/TracingUtility.cpp |   49 +-
 .../{tracing => trace}/include/TracingUtility.h    |    5 +-
 src/main/cpp/tracing/exporters/BUILD.bazel         |   34 -
 src/main/cpp/tracing/exporters/OtlpExporter.cpp    |  428 --------
 .../cpp/tracing/exporters/include/OtlpExporter.h   |  153 ---
 src/test/cpp/benchmark/BUILD.bazel                 |   27 -
 src/test/cpp/benchmark/BenchmarkTest.cpp           |   34 -
 src/test/cpp/it/BUILD.bazel                        |   51 -
 src/test/cpp/it/README.md                          |    4 -
 src/test/cpp/it/RpcClientTest.cpp                  |  374 -------
 src/test/cpp/it/TopAddressingTest.cpp              |  167 ----
 src/test/cpp/it/TopicPublishInfoTest.cpp           |  175 ----
 src/test/cpp/ut/BUILD                              |    1 -
 src/test/cpp/ut/BUILD.bazel                        |   17 -
 src/test/cpp/ut/README.md                          |    3 -
 src/test/cpp/ut/admin/AdminServerTest.cpp          |   67 --
 src/test/cpp/ut/admin/BUILD.bazel                  |   28 -
 src/test/cpp/ut/base/BUILD.bazel                   |  153 ---
 src/test/cpp/ut/base/HistogramTest.cpp             |   59 --
 src/test/cpp/ut/base/HostInfoTest.cpp              |   65 --
 src/test/cpp/ut/base/HttpClientTest.cpp            |   67 --
 src/test/cpp/ut/base/InvocationContextTest.cpp     |   37 -
 src/test/cpp/ut/base/MQMessageExtTest.cpp          |   68 --
 src/test/cpp/ut/base/MQMessageTest.cpp             |   60 --
 src/test/cpp/ut/base/MixAllTest.cpp                |  120 ---
 src/test/cpp/ut/base/RateLimiterTest.cpp           |   69 --
 src/test/cpp/ut/base/ThreadPoolTest.cpp            |   76 --
 src/test/cpp/ut/base/TopAddressingTest.cpp         |   74 --
 src/test/cpp/ut/base/UniqueIdGeneratorTest.cpp     |   46 -
 src/test/cpp/ut/base/UtilAllTest.cpp               |   91 --
 src/test/cpp/ut/client/BUILD.bazel                 |   86 --
 .../cpp/ut/client/ClientManagerFactoryTest.cpp     |   47 -
 src/test/cpp/ut/client/ClientManagerTest.cpp       |  357 -------
 src/test/cpp/ut/client/ClientTest.cpp              |   46 -
 src/test/cpp/ut/client/RpcClientTest.cpp           |   82 --
 src/test/cpp/ut/client/TlsHelperTest.cpp           |   31 -
 src/test/cpp/ut/client/TopicAssignmentInfoTest.cpp |  110 --
 src/test/cpp/ut/client/TracingUtilityTest.cpp      |   50 -
 src/test/cpp/ut/concurrent/BUILD.bazel             |   28 -
 src/test/cpp/ut/concurrent/CountdownLatchTest.cpp  |   49 -
 src/test/cpp/ut/logger/LoggerTest.cpp              |  109 --
 src/test/cpp/ut/remoting/BUILD.bazel               |   73 --
 src/test/cpp/ut/remoting/BrokerDataTest.cpp        |   44 -
 src/test/cpp/ut/remoting/QueueDataTest.cpp         |   38 -
 src/test/cpp/ut/remoting/RemotingCommandTest.cpp   |   62 --
 src/test/cpp/ut/remoting/TopicRouteDataTest.cpp    |   36 -
 src/test/cpp/ut/rocketmq/AwaitPullCallbackTest.cpp |   87 --
 src/test/cpp/ut/rocketmq/BUILD.bazel               |  264 -----
 src/test/cpp/ut/rocketmq/ClientImplTest.cpp        |  126 ---
 .../rocketmq/ConsumeStandardMessageServiceTest.cpp |  117 ---
 .../cpp/ut/rocketmq/CredentialsProviderTest.cpp    |   68 --
 src/test/cpp/ut/rocketmq/DefaultMQProducerTest.cpp |  212 ----
 .../cpp/ut/rocketmq/DefaultMQPushConsumerTest.cpp  |   37 -
 .../ut/rocketmq/DynamicNameServerResolverTest.cpp  |   75 --
 src/test/cpp/ut/rocketmq/ExecutorTest.cpp          |  157 ---
 .../ut/rocketmq/MessageGroupQueueSelectorTest.cpp  |   41 -
 src/test/cpp/ut/rocketmq/MessageTest.cpp           |   26 -
 src/test/cpp/ut/rocketmq/NamingSchemeTest.cpp      |   50 -
 src/test/cpp/ut/rocketmq/ProcessQueueTest.cpp      |  365 -------
 src/test/cpp/ut/rocketmq/ProducerImplTest.cpp      |  273 -----
 src/test/cpp/ut/rocketmq/PullConsumerImplTest.cpp  |  423 --------
 src/test/cpp/ut/rocketmq/PushConsumerImplTest.cpp  |  205 ----
 src/test/cpp/ut/rocketmq/SendCallbacksTest.cpp     |   43 -
 .../ut/rocketmq/StaticNameServerResolverTest.cpp   |   51 -
 .../ut/rocketmq/StsCredentialsProviderImplTest.cpp |   76 --
 src/test/cpp/ut/rocketmq/include/MQClientTest.h    |  105 --
 src/test/cpp/ut/scheduler/SchedulerTest.cpp        |  149 ---
 src/test/cpp/ut/tracing/exporters/BUILD.bazel      |   40 -
 .../cpp/ut/tracing/exporters/OtlpExportersTest.cpp |   70 --
 .../cpp/ut/tracing/exporters/SpanContextTest.cpp   |   25 -
 tools/trouble_shooting.sh                          |    2 +
 tools/use_clang.sh                                 |    2 +
 262 files changed, 6429 insertions(+), 15223 deletions(-)

diff --git a/.bazelversion b/.bazelversion
index 6aba2b2..af8c8ec 100644
--- a/.bazelversion
+++ b/.bazelversion
@@ -1 +1 @@
-4.2.0
+4.2.2
diff --git a/.clang-format b/.clang-format
index 6345fe1..fb63bcf 100644
--- a/.clang-format
+++ b/.clang-format
@@ -1,11 +1,14 @@
 ---
+BasedOnStyle: Google
+IndentWidth: 2
+---
 Language: Cpp
 AccessModifierOffset: -2
+BinPackParameters: false
 ColumnLimit: 120
 DerivePointerAlignment: false
 PointerAlignment: Left
 SortIncludes: true
-IndentWidth: 2
 NamespaceIndentation: Inner
 AlwaysBreakTemplateDeclarations: true
 AllowShortCaseLabelsOnASingleLine: false
@@ -13,6 +16,7 @@ AllowShortEnumsOnASingleLine: false
 AllowShortFunctionsOnASingleLine: false
 IndentCaseBlocks: false
 IndentCaseLabels: true
+ReflowComments: true
 ...
 
 ---
diff --git a/.gitignore b/.gitignore
index f3ec0b2..23e0e93 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,7 +5,6 @@ bazel-testlogs
 cmake-build-debug
 .clwb
 compile_commands.json
-.vscode
 logs
 _build
 cmake-build-debug-coverage
@@ -15,3 +14,7 @@ cmake-build-debug-coverage
 external
 bazel-apache_rocketmq_client_cpp
 bazel-rocketmq-client-cpp
+/external
+/bazel-*
+/compile_commands.json
+/.cache/
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..cb613f9
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,13 @@
+{
+    "C_Cpp.intelliSenseEngine": "Disabled",
+    "C_Cpp.autocomplete": "Disabled",  // So you don't get autocomplete from both extensions.
+    "C_Cpp.errorSquiggles": "Disabled", // So you don't get error squiggles from both extensions (clangd's seem to be more reliable anyway).
+    "clangd.arguments": [
+        "-log=verbose",
+        "-pretty",
+        "--background-index", 
+        "--header-insertion=never", 
+        "--compile-commands-dir=${workspaceFolder}/",
+        "--query-driver=/**/*",
+    ]
+}
\ No newline at end of file
diff --git a/WORKSPACE b/WORKSPACE
index 8648444..644b5d7 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -14,4 +14,7 @@ rules_proto_grpc_repos()
 
 load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
 rules_proto_dependencies()
-rules_proto_toolchains()
\ No newline at end of file
+rules_proto_toolchains()
+
+load("@hedron_compile_commands//:workspace_setup.bzl", "hedron_compile_commands_setup")
+hedron_compile_commands_setup()
\ No newline at end of file
diff --git a/api/BUILD.bazel b/api/BUILD.bazel
index b7eb594..f5d75d5 100644
--- a/api/BUILD.bazel
+++ b/api/BUILD.bazel
@@ -23,5 +23,6 @@ cc_library(
     visibility = ["//visibility:public"],
     deps = [
         "@com_google_absl//absl/strings",
+        "@io_opencensus_cpp//opencensus/trace",
     ],
 )
\ No newline at end of file
diff --git a/api/rocketmq/AsyncCallback.h b/api/rocketmq/AsyncCallback.h
deleted file mode 100644
index 8004ba0..0000000
--- a/api/rocketmq/AsyncCallback.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.
- */
-#pragma once
-
-#include <system_error>
-
-#include "MQClientException.h"
-#include "PullResult.h"
-#include "SendResult.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-class AsyncCallback {
-public:
-  virtual ~AsyncCallback() = default;
-};
-
-class SendCallback : public AsyncCallback {
-public:
-  ~SendCallback() override = default;
-
-  virtual void onSuccess(SendResult& send_result) noexcept = 0;
-
-  virtual void onFailure(const std::error_code& ec) noexcept = 0;
-};
-
-class PullCallback : public AsyncCallback {
-public:
-  ~PullCallback() override = default;
-
-  virtual void onSuccess(const PullResult& pull_result) noexcept = 0;
-
-  virtual void onFailure(const std::error_code& ec) noexcept = 0;
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/BackoffPolicy.h b/api/rocketmq/BackoffPolicy.h
new file mode 100644
index 0000000..89aa7d1
--- /dev/null
+++ b/api/rocketmq/BackoffPolicy.h
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+#pragma once
+
+#include "RocketMQ.h"
+#include <chrono>
+#include <cmath>
+#include <cstddef>
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+class BackoffPolicy {
+public:
+  virtual ~BackoffPolicy() = default;
+
+  virtual std::size_t maxAttempts() const = 0;
+
+  virtual std::chrono::milliseconds backoff(std::size_t attempt) const = 0;
+};
+
+class ExponentialBackoffPolicy : public BackoffPolicy {
+public:
+  ExponentialBackoffPolicy(std::size_t max_attempts, std::chrono::milliseconds initial_backoff,
+                           std::chrono::milliseconds max_backoff, std::size_t multiplier)
+      : max_attempts_(max_attempts), initial_backoff_(initial_backoff), max_backoff_(max_backoff),
+        multiplier_(multiplier) {
+  }
+
+  std::size_t maxAttempts() const override {
+    return max_attempts_;
+  }
+
+  std::chrono::milliseconds backoff(std::size_t attempt) const override {
+    if (attempt <= 1) {
+      return initial_backoff_;
+    }
+
+    if (attempt >= max_attempts_) {
+      return max_backoff_;
+    }
+
+    auto duration = initial_backoff_ * static_cast<std::size_t>(std::pow(multiplier_, attempt));
+    if (duration > max_backoff_) {
+      return max_backoff_;
+    }
+    return duration;
+  }
+
+private:
+  std::size_t max_attempts_;
+  std::chrono::milliseconds initial_backoff_;
+  std::chrono::milliseconds max_backoff_;
+  std::size_t multiplier_;
+};
+
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/Configuration.h b/api/rocketmq/Configuration.h
new file mode 100644
index 0000000..90cdf7d
--- /dev/null
+++ b/api/rocketmq/Configuration.h
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+#pragma once
+
+#include <chrono>
+#include <memory>
+#include <string>
+
+#include "ConfigurationDefaults.h"
+#include "CredentialsProvider.h"
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+class ConfigurationBuilder;
+
+class Configuration {
+public:
+  static ConfigurationBuilder newBuilder();
+
+  const std::string& endpoints() const {
+    return endpoints_;
+  }
+
+  CredentialsProviderPtr credentialsProvider() const {
+    return credentials_provider_;
+  }
+
+  std::chrono::milliseconds requestTimeout() const {
+    return request_timeout_;
+  }
+
+protected:
+  friend class ConfigurationBuilder;
+
+  Configuration() = default;
+
+private:
+  std::string               endpoints_;
+  CredentialsProviderPtr    credentials_provider_;
+  std::chrono::milliseconds request_timeout_{ConfigurationDefaults::RequestTimeout};
+};
+
+class ConfigurationBuilder {
+public:
+  ConfigurationBuilder& withEndpoints(std::string endpoints);
+
+  ConfigurationBuilder& withCredentialsProvider(std::shared_ptr<CredentialsProvider> provider);
+
+  ConfigurationBuilder& withRequestTimeout(std::chrono::milliseconds request_timeout);
+
+  Configuration build();
+
+private:
+  Configuration configuration_;
+};
+
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/client/include/OrphanTransactionCallback.h b/api/rocketmq/ConfigurationDefaults.h
similarity index 79%
rename from src/main/cpp/client/include/OrphanTransactionCallback.h
rename to api/rocketmq/ConfigurationDefaults.h
index 0e78db1..08a2567 100644
--- a/src/main/cpp/client/include/OrphanTransactionCallback.h
+++ b/api/rocketmq/ConfigurationDefaults.h
@@ -16,15 +16,19 @@
  */
 #pragma once
 
-#include "rocketmq/MQMessage.h"
+#include <chrono>
+
+#include "RocketMQ.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-class OrphanTransactionCallback {
+class ConfigurationDefaults {
 public:
-  virtual ~OrphanTransactionCallback() = default;
-
-  virtual void onOrphanTransaction(const MQMessage& message) = 0;
+  /**
+   * @brief Default request-timeout: 3.0 seconds.
+   *
+   */
+  static const std::chrono::milliseconds RequestTimeout;
 };
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/MessageModel.h b/api/rocketmq/ConsumeResult.h
similarity index 90%
copy from api/rocketmq/MessageModel.h
copy to api/rocketmq/ConsumeResult.h
index 2422d32..5dcdf77 100644
--- a/api/rocketmq/MessageModel.h
+++ b/api/rocketmq/ConsumeResult.h
@@ -16,16 +16,15 @@
  */
 #pragma once
 
-#include "RocketMQ.h"
-
 #include <cstdint>
 
+#include "RocketMQ.h"
+
 ROCKETMQ_NAMESPACE_BEGIN
 
-enum class MessageModel : int8_t
-{
-  BROADCASTING,
-  CLUSTERING,
+enum class ConsumeResult : uint8_t {
+  SUCCESS = 0,
+  FAILURE = 1
 };
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/ConsumeType.h b/api/rocketmq/ConsumeType.h
deleted file mode 100644
index 4cbf5a2..0000000
--- a/api/rocketmq/ConsumeType.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.
- */
-#pragma once
-
-#include <chrono>
-#include <cstdlib>
-#include <functional>
-
-#include "MQMessageQueue.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-enum ConsumeType
-{
-  CONSUME_ACTIVELY,
-  CONSUME_PASSIVELY,
-};
-
-enum ConsumeFromWhere
-{
-  CONSUME_FROM_LAST_OFFSET,
-  CONSUME_FROM_LAST_OFFSET_AND_FROM_MIN_WHEN_BOOT_FIRST,
-  CONSUME_FROM_MIN_OFFSET,
-  CONSUME_FROM_MAX_OFFSET,
-  CONSUME_FROM_FIRST_OFFSET,
-  CONSUME_FROM_TIMESTAMP,
-};
-
-enum ConsumeInitialMode
-{
-  MIN,
-  MAX,
-};
-
-enum QueryOffsetPolicy : uint8_t
-{
-  BEGINNING = 0,
-  END = 1,
-  TIME_POINT = 2,
-};
-
-struct OffsetQuery {
-  MQMessageQueue message_queue;
-  QueryOffsetPolicy policy;
-  std::chrono::system_clock::time_point time_point;
-};
-
-struct PullMessageQuery {
-  MQMessageQueue message_queue;
-  int64_t offset;
-  int32_t batch_size;
-  std::chrono::system_clock::duration await_time;
-  std::chrono::system_clock::duration timeout;
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/DefaultMQProducer.h b/api/rocketmq/DefaultMQProducer.h
deleted file mode 100644
index 97306d5..0000000
--- a/api/rocketmq/DefaultMQProducer.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * 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.
- */
-#pragma once
-
-#include <chrono>
-#include <memory>
-#include <system_error>
-#include <vector>
-
-#include "AsyncCallback.h"
-#include "CredentialsProvider.h"
-#include "ErrorCode.h"
-#include "LocalTransactionStateChecker.h"
-#include "Logger.h"
-#include "MQMessage.h"
-#include "MQSelector.h"
-#include "SendResult.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-/**
- * This class employs pointer-to-implementation paradigm to achieve the goal of stable ABI.
- * Refer https://en.cppreference.com/w/cpp/language/pimpl for an explanation.
- */
-class ProducerImpl;
-
-class DefaultMQProducer {
-public:
-  explicit DefaultMQProducer(const std::string& group_name);
-
-  ~DefaultMQProducer() = default;
-
-  void start();
-
-  void shutdown();
-
-  /**
-   * Acquire previous send timeout in milliseconds.
-   * @return Send timeout in milliseconds
-   */
-  std::chrono::milliseconds getSendMsgTimeout() const;
-
-  /**
-   * Set default send message timeout in milliseconds.
-   * @param timeout_millis Timeout used when sending messages.
-   */
-  void setSendMsgTimeout(std::chrono::milliseconds timeout);
-
-  SendResult send(MQMessage& message, const std::string& message_group);
-
-  /**
-   * Send message in synchronous manner.
-   * @param message  Message to send.
-   * @param filter_active_broker Do NOT rely on this parameter. it has been deprecated.
-   */
-  SendResult send(const MQMessage& message, bool filter_active_broker = true);
-
-  SendResult send(const MQMessage& message, std::error_code& ec) noexcept;
-
-  SendResult send(MQMessage& message, const MQMessageQueue& message_queue);
-  SendResult send(MQMessage& message, MessageQueueSelector* selector, void* arg);
-
-  /**
-   * @brief This function is deprecated.
-   *
-   * @param message
-   * @param selector
-   * @param arg
-   * @param retry_times retry_times is ignored with respect to member retry_times setting.
-   * @param select_active_broker
-   * @return SendResult
-   */
-  SendResult send(MQMessage& message, MessageQueueSelector* selector, void* arg, int retry_times,
-                  bool select_active_broker = false);
-
-  /**
-   * Send message in asynchronous manner.
-   * @param message  Message to send.
-   * @param send_callback Callback to execute on completion of message sending.
-   * @param select_active_broker Do NOT rely on this parameter. it has been deprecated.
-   */
-  void send(const MQMessage& message, SendCallback* send_callback, bool select_active_broker = false);
-  void send(MQMessage& message, const MQMessageQueue& message_queue, SendCallback* send_callback);
-  void send(MQMessage& message, MessageQueueSelector* selector, void* arg, SendCallback* send_callback);
-
-  /**
-   * send message in Oneway(The implementation is simply ignore the result of send message in synchronous).
-   * @param message  Message to send.
-   * @param select_active_broker Do NOT rely on this parameter. it has been deprecated.
-   */
-  void sendOneway(const MQMessage& message, bool select_active_broker = false);
-  void sendOneway(MQMessage& message, const MQMessageQueue& message_queue);
-  void sendOneway(MQMessage& message, MessageQueueSelector* selector, void* arg);
-
-  void setLocalTransactionStateChecker(LocalTransactionStateCheckerPtr checker);
-
-  void setNamesrvAddr(const std::string& name_server_address_list);
-
-  void setNameServerListDiscoveryEndpoint(const std::string& discovery_endpoint);
-
-  void setGroupName(const std::string& group_name);
-
-  void setInstanceName(const std::string& instance_name);
-
-  void enableTracing(bool enabled);
-
-  bool isTracingEnabled();
-
-  /**
-   * Number of attempts before claiming a send action as failure. By default, 3 attempts will be performed for sync and
-   * async send methods.
-   *
-   * @return
-   */
-  int getMaxAttemptTimes() const;
-
-  void setMaxAttemptTimes(int max_attempt_times);
-
-  std::vector<MQMessageQueue> getTopicMessageQueueInfo(const std::string& topic);
-
-  void setUnitName(std::string unit_name);
-
-  const std::string& getUnitName();
-
-  uint32_t compressBodyThreshold() const;
-  void compressBodyThreshold(uint32_t threshold);
-
-  void setResourceNamespace(const std::string& resource_namespace);
-
-  void setCredentialsProvider(CredentialsProviderPtr credentials_provider);
-
-  void setRegion(const std::string& region);
-
-  TransactionPtr prepare(MQMessage& message);
-
-private:
-  std::shared_ptr<ProducerImpl> impl_;
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/DefaultMQPullConsumer.h b/api/rocketmq/DefaultMQPullConsumer.h
deleted file mode 100644
index 9bbfc60..0000000
--- a/api/rocketmq/DefaultMQPullConsumer.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.
- */
-#pragma once
-
-#include <chrono>
-#include <future>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "AsyncCallback.h"
-#include "ConsumeType.h"
-#include "CredentialsProvider.h"
-#include "MQMessageExt.h"
-#include "MQMessageQueue.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-class PullConsumerImpl;
-
-class DefaultMQPullConsumer {
-public:
-  explicit DefaultMQPullConsumer(const std::string& group_name);
-
-  void start();
-
-  void shutdown();
-
-  std::future<std::vector<MQMessageQueue>> queuesFor(const std::string& topic);
-
-  std::future<int64_t> queryOffset(const OffsetQuery& query);
-
-  bool pull(const PullMessageQuery& request, PullResult& pull_result);
-
-  void pull(const PullMessageQuery& request, PullCallback* callback);
-
-  void setResourceNamespace(const std::string& resource_namespace);
-
-  void setNamesrvAddr(const std::string& name_srv);
-
-  void setNameServerListDiscoveryEndpoint(const std::string& discovery_endpoint);
-
-  void setCredentialsProvider(std::shared_ptr<CredentialsProvider> credentials_provider);
-
-private:
-  std::shared_ptr<PullConsumerImpl> impl_;
-};
-
-ROCKETMQ_NAMESPACE_END
diff --git a/api/rocketmq/DefaultMQPushConsumer.h b/api/rocketmq/DefaultMQPushConsumer.h
deleted file mode 100644
index 0693b8d..0000000
--- a/api/rocketmq/DefaultMQPushConsumer.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 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.
- */
-#pragma once
-
-#include <memory>
-#include <string>
-
-#include "AsyncCallback.h"
-#include "ConsumeType.h"
-#include "CredentialsProvider.h"
-#include "ExpressionType.h"
-#include "Logger.h"
-#include "MQMessageQueue.h"
-#include "MessageListener.h"
-#include "rocketmq/Executor.h"
-#include "rocketmq/MessageModel.h"
-#include "rocketmq/OffsetStore.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-class PushConsumerImpl;
-
-class DefaultMQPushConsumer {
-public:
-  explicit DefaultMQPushConsumer(const std::string& group_name);
-
-  ~DefaultMQPushConsumer() = default;
-
-  void start();
-
-  void shutdown();
-
-  void subscribe(const std::string& topic, const std::string& expression,
-                 ExpressionType expression_type = ExpressionType::TAG);
-
-  void setConsumeFromWhere(ConsumeFromWhere policy);
-
-  void registerMessageListener(MessageListener* listener);
-
-  void setNamesrvAddr(const std::string& name_srv);
-
-  void setNameServerListDiscoveryEndpoint(const std::string& discovery_endpoint);
-
-  void setGroupName(const std::string& group_name);
-
-  void setConsumeThreadCount(int thread_count);
-
-  void setInstanceName(const std::string& instance_name);
-
-  int getProcessQueueTableSize();
-
-  void setUnitName(std::string unit_name);
-
-  const std::string& getUnitName() const;
-
-  void enableTracing(bool enabled);
-
-  bool isTracingEnabled();
-
-  /**
-   * SDK of this version always uses asynchronous IO operation. As such, this
-   * function is no-op to keep backward compatibility.
-   */
-  void setAsyncPull(bool);
-
-  /**
-   * Maximum number of messages passed to each callback.
-   * @param batch_size Batch size
-   */
-  void setConsumeMessageBatchMaxSize(int batch_size);
-
-  /**
-   * Lifecycle of executor is managed by external application. Passed-in
-   * executor should remain valid after consumer start and before stopping.
-   * @param executor Executor pool used to invoke consume callback.
-   */
-  void setCustomExecutor(const Executor& executor);
-
-  /**
-   * This function sets maximum number of message that may be consumed per
-   * second.
-   * @param topic Topic to control
-   * @param threshold Threshold before throttling is enforced.
-   */
-  void setThrottle(const std::string& topic, uint32_t threshold);
-
-  /**
-   * Set abstract-resource-namespace, in which canonical name of topic, group
-   * remains unique.
-   * @param resource_namespace Abstract resource namespace.
-   */
-  void setResourceNamespace(const std::string& resource_namespace);
-
-  void setCredentialsProvider(CredentialsProviderPtr credentials_provider);
-
-  void setMessageModel(MessageModel message_model);
-
-  std::string groupName() const;
-
-  void setOffsetStore(std::unique_ptr<OffsetStore> offset_store);
-
-private:
-  std::shared_ptr<PushConsumerImpl> impl_;
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/ErrorCode.h b/api/rocketmq/ErrorCode.h
index c3ebb7a..5068c83 100644
--- a/api/rocketmq/ErrorCode.h
+++ b/api/rocketmq/ErrorCode.h
@@ -24,8 +24,7 @@
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-enum class ErrorCode : int
-{
+enum class ErrorCode : int {
   Success = 0,
 
   /**
@@ -34,6 +33,11 @@ enum class ErrorCode : int
    */
   IllegalState = 1,
 
+  /**
+   * @brief Broker has processed the request but is not going to return any content.
+   */
+  NoContent = 204,
+
   /**
    * @brief Bad configuration. For example, negative max-attempt-times.
    *
@@ -48,6 +52,11 @@ enum class ErrorCode : int
    */
   BadRequest = 400,
 
+  /**
+   * @brief To publish FIFO messages, only synchronous API is supported.
+   */
+  BadRequestAsyncPubFifoMessage = 40001,
+
   /**
    * @brief Authentication failed. Possibly caused by invalid credentials.
    *
@@ -68,6 +77,10 @@ enum class ErrorCode : int
    */
   NotFound = 404,
 
+  TopicNotFound = 404001,
+
+  GroupNotFound = 404002,
+
   /**
    * @brief Timeout when connecting, reading from or writing to brokers.
    *
diff --git a/src/main/cpp/rocketmq/include/FilterExpression.h b/api/rocketmq/FilterExpression.h
similarity index 84%
rename from src/main/cpp/rocketmq/include/FilterExpression.h
rename to api/rocketmq/FilterExpression.h
index 51cd89a..19e910a 100644
--- a/src/main/cpp/rocketmq/include/FilterExpression.h
+++ b/api/rocketmq/FilterExpression.h
@@ -18,8 +18,8 @@
 
 #include <string>
 
-#include "rocketmq/ExpressionType.h"
-#include "rocketmq/MQMessageExt.h"
+#include "ExpressionType.h"
+#include "Message.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
@@ -27,14 +27,14 @@ ROCKETMQ_NAMESPACE_BEGIN
  * Server supported message filtering expression. At present, two types are supported: tag and SQL92.
  */
 struct FilterExpression {
-  explicit FilterExpression(std::string expression, ExpressionType expression_type = ExpressionType::TAG)
+  FilterExpression(std::string expression, ExpressionType expression_type = ExpressionType::TAG)
       : content_(std::move(expression)), type_(expression_type), version_(std::chrono::steady_clock::now()) {
     if (ExpressionType::TAG == type_ && content_.empty()) {
       content_ = WILD_CARD_TAG;
     }
   }
 
-  bool accept(const MQMessageExt& message) const;
+  bool accept(const Message& message) const;
 
   std::string content_;
   ExpressionType type_;
diff --git a/api/rocketmq/MQMessage.h b/api/rocketmq/MQMessage.h
deleted file mode 100644
index e5d27fa..0000000
--- a/api/rocketmq/MQMessage.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.
- */
-#pragma once
-
-#include <chrono>
-#include <map>
-#include <sstream>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-
-#include "MQMessageQueue.h"
-#include "MessageType.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-class MessageImpl;
-
-class MessageAccessor;
-
-class MQMessage {
-public:
-  MQMessage();
-  MQMessage(const std::string& topic, const std::string& body);
-  MQMessage(const std::string& topic, const std::string& tags, const std::string& body);
-  MQMessage(const std::string& topic, const std::string& tags, const std::string& keys, const std::string& body);
-
-  virtual ~MQMessage();
-
-  MQMessage(const MQMessage& other);
-  MQMessage& operator=(const MQMessage& other);
-
-  const std::string& getMsgId() const;
-
-  void setProperty(const std::string& name, const std::string& value);
-  std::string getProperty(const std::string& name) const;
-
-  const std::string& getTopic() const;
-  void setTopic(const std::string& topic);
-  void setTopic(const char* data, int len);
-
-  std::string getTags() const;
-  void setTags(const std::string& tags);
-
-  const std::vector<std::string>& getKeys() const;
-
-  /**
-   * @brief Add a unique key for the message
-   * TODO: a message may be associated with multiple keys. setKey, actually mean
-   * attach the given key to the message. Better rename it.
-   * @param key Unique key in perspective of bussiness logic.
-   */
-  void setKey(const std::string& key);
-  void setKeys(const std::vector<std::string>& keys);
-
-  int getDelayTimeLevel() const;
-  void setDelayTimeLevel(int level);
-
-  const std::string& traceContext() const;
-  void traceContext(const std::string& trace_context);
-
-  std::string getBornHost() const;
-
-  std::chrono::system_clock::time_point deliveryTimestamp() const;
-
-  const std::string& getBody() const;
-  void setBody(const char* data, int len);
-  void setBody(const std::string& body);
-
-  uint32_t bodyLength() const;
-
-  const std::map<std::string, std::string>& getProperties() const;
-  void setProperties(const std::map<std::string, std::string>& properties);
-
-  void messageType(MessageType message_type);
-  MessageType messageType() const;
-
-  void bindMessageGroup(absl::string_view message_group);
-
-  void bindMessageQueue(const MQMessageQueue& message_queue) {
-    message_queue_ = message_queue;
-  }
-
-  const std::string& messageGroup() const;
-
-  const MQMessageQueue& messageQueue() const {
-    return message_queue_;
-  }
-
-protected:
-  MessageImpl* impl_;
-
-  friend class MessageAccessor;
-
-private:
-  MQMessageQueue message_queue_;
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/MQMessageExt.h b/api/rocketmq/MQMessageExt.h
deleted file mode 100644
index ed95484..0000000
--- a/api/rocketmq/MQMessageExt.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.
- */
-#pragma once
-
-#include <chrono>
-
-#include "MQMessage.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-class MessageAccessor;
-
-class MQMessageExt : public MQMessage {
-public:
-  MQMessageExt();
-
-  MQMessageExt(const MQMessageExt& other);
-
-  MQMessageExt& operator=(const MQMessageExt& other);
-
-  int32_t getQueueId() const;
-
-  /**
-   * @return Milli-seconds since epoch in perspective of system_clock.
-   */
-  int64_t getBornTimestamp() const;
-
-  std::chrono::system_clock::time_point bornTimestamp() const;
-
-  std::chrono::system_clock::time_point storeTimestamp() const;
-  int64_t getStoreTimestamp() const;
-
-  std::string getStoreHost() const;
-
-  int64_t getQueueOffset() const;
-
-  int32_t getDeliveryAttempt() const;
-
-  const std::string& receiptHandle() const;
-
-  bool operator==(const MQMessageExt& other);
-
-  friend class MessageAccessor;
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/MQMessageQueue.h b/api/rocketmq/MQMessageQueue.h
deleted file mode 100644
index ec62b3d..0000000
--- a/api/rocketmq/MQMessageQueue.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * 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.
- */
-#pragma once
-
-#include <functional>
-#include <sstream>
-#include <string>
-
-#include "RocketMQ.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-class MQMessageQueue {
-public:
-  MQMessageQueue() = default;
-
-  MQMessageQueue(std::string topic, std::string broker_name, int queue_id)
-      : topic_(std::move(topic)), broker_name_(std::move(broker_name)), queue_id_(queue_id) {
-  }
-
-  MQMessageQueue(const MQMessageQueue& other) {
-    this->operator=(other);
-  }
-
-  MQMessageQueue(MQMessageQueue&& other) noexcept {
-    topic_ = std::move(other.topic_);
-    broker_name_ = std::move(other.broker_name_);
-    queue_id_ = other.queue_id_;
-    service_address_ = other.service_address_;
-  }
-
-  MQMessageQueue& operator=(const MQMessageQueue& other) {
-    if (this == &other) {
-      return *this;
-    }
-
-    topic_ = other.topic_;
-    broker_name_ = other.broker_name_;
-    queue_id_ = other.queue_id_;
-    service_address_ = other.service_address_;
-    return *this;
-  }
-
-  const std::string& getTopic() const {
-    return topic_;
-  }
-
-  void setTopic(const std::string& topic) {
-    topic_ = topic;
-  }
-
-  const std::string& getBrokerName() const {
-    return broker_name_;
-  }
-
-  void setBrokerName(const std::string& broker_name) {
-    broker_name_ = broker_name;
-  }
-
-  int getQueueId() const {
-    return queue_id_;
-  }
-
-  void setQueueId(int queue_id) {
-    queue_id_ = queue_id;
-  }
-
-  bool operator!=(const MQMessageQueue& rhs) const {
-    return topic_ != rhs.topic_ || broker_name_ != rhs.broker_name_ || queue_id_ != rhs.queue_id_;
-  }
-
-  bool operator==(const MQMessageQueue& mq) const {
-    return topic_ == mq.topic_ && broker_name_ == mq.broker_name_ && queue_id_ == mq.queue_id_;
-  }
-
-  bool operator<(const MQMessageQueue& mq) const {
-    if (topic_ != mq.topic_) {
-      return topic_ < mq.topic_;
-    }
-
-    if (broker_name_ != mq.broker_name_) {
-      return broker_name_ < mq.broker_name_;
-    }
-
-    return queue_id_ < mq.queue_id_;
-  }
-
-  operator bool() const {
-    return !topic_.empty() && !broker_name_.empty() && queue_id_ >= 0;
-  }
-
-  int compareTo(const MQMessageQueue& mq) const {
-    if (this == &mq) {
-      return 0;
-    }
-
-    if (this->operator<(mq)) {
-      return -1;
-    }
-
-    if (mq.operator<(*this)) {
-      return 1;
-    }
-
-    return 0;
-  }
-
-  std::string simpleName() const {
-    return topic_ + "_" + broker_name_ + "_" + std::to_string(queue_id_);
-  }
-
-  std::string toString() const {
-    std::stringstream ss;
-    ss << "MessageQueue [topic=" << topic_ << ", brokerName=" << broker_name_ << ", queueId=" << queue_id_ << "]";
-    return ss.str();
-  }
-
-  template <typename H>
-  friend H AbslHashValue(H h, const MQMessageQueue& mq) {
-    return H::combine(std::move(h), mq.topic_, mq.broker_name_, mq.queue_id_);
-  }
-
-  const std::string& serviceAddress() const {
-    return service_address_;
-  }
-
-  void serviceAddress(std::string service_address) {
-    service_address_ = std::move(service_address);
-  }
-
-private:
-  std::string topic_;
-  std::string broker_name_;
-  int queue_id_{0};
-
-  std::string service_address_;
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/Message.h b/api/rocketmq/Message.h
new file mode 100644
index 0000000..0537fa4
--- /dev/null
+++ b/api/rocketmq/Message.h
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ */
+#pragma once
+
+#include <cassert>
+#include <chrono>
+#include <map>
+#include <memory>
+#include <sstream>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "RocketMQ.h"
+#include "absl/types/optional.h"
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+class MessageBuilder;
+
+/**
+ * @brief Extension is intended for internal use only, which is subject to change without notice.
+ */
+struct Extension {
+  std::chrono::system_clock::time_point store_time{std::chrono::system_clock::now()};
+  std::string store_host;
+  std::chrono::system_clock::time_point delivery_timepoint{std::chrono::system_clock::now()};
+  std::uint16_t delivery_attempt{0};
+  std::chrono::system_clock::time_point decode_time{std::chrono::system_clock::now()};
+  std::chrono::system_clock::duration invisible_period{0};
+  std::string receipt_handle;
+  std::string target_endpoint;
+  std::int32_t queue_id{0};
+  std::int64_t offset{0};
+  std::string nonce;
+  std::string transaction_id;
+};
+
+class Message {
+public:
+  const std::string& id() const {
+    return id_;
+  }
+
+  const std::string& topic() const {
+    return topic_;
+  }
+
+  absl::optional<std::string> tag() const {
+    if (tag_.empty()) {
+      return {};
+    }
+    return absl::make_optional(tag_);
+  }
+
+  const std::vector<std::string>& keys() const {
+    return keys_;
+  }
+
+  absl::optional<std::string> traceContext() const {
+    if (trace_context_.empty()) {
+      return {};
+    }
+    return absl::make_optional(trace_context_);
+  }
+
+  const std::string& bornHost() const {
+    return born_host_;
+  }
+
+  const std::chrono::system_clock::time_point& bornTime() const {
+    return born_time_;
+  }
+
+  absl::optional<std::chrono::system_clock::time_point> deliveryTimestamp() const {
+    return delivery_timestamp_;
+  }
+
+  const std::string& body() const {
+    return body_;
+  }
+
+  const std::unordered_map<std::string, std::string>& properties() const {
+    return properties_;
+  }
+
+  absl::optional<std::string> group() const {
+    if (group_.empty()) {
+      return {};
+    }
+    return absl::make_optional(group_);
+  }
+
+  const Extension& extension() const {
+    return extension_;
+  }
+
+  Extension& mutableExtension() {
+    return extension_;
+  }
+
+  static MessageBuilder newBuilder();
+
+protected:
+  friend std::unique_ptr<Message> absl::make_unique<Message>();
+  friend class MessageBuilder;
+
+  Message();
+
+private:
+  std::string id_;
+  std::string topic_;
+  std::string tag_;
+  std::vector<std::string> keys_;
+  std::string trace_context_;
+  std::string born_host_;
+  std::chrono::system_clock::time_point born_time_{std::chrono::system_clock::now()};
+  absl::optional<std::chrono::system_clock::time_point> delivery_timestamp_;
+  std::string body_;
+  std::unordered_map<std::string, std::string> properties_;
+  std::string group_;
+  Extension extension_;
+};
+
+using MessagePtr = std::unique_ptr<Message>;
+using MessageConstPtr = std::unique_ptr<const Message>;
+using MessageConstSharedPtr = std::shared_ptr<const Message>;
+using MessageSharedPtr = std::shared_ptr<Message>;
+
+class MessageBuilder {
+public:
+  MessageBuilder();
+
+  MessageBuilder& withTopic(std::string topic);
+
+  MessageBuilder& withTag(std::string tag);
+
+  MessageBuilder& withKeys(std::vector<std::string> keys);
+
+  MessageBuilder& withTraceContext(std::string trace_context);
+
+  MessageBuilder& withBody(std::string body);
+
+  MessageBuilder& withGroup(std::string group);
+
+  MessageBuilder& withProperties(std::unordered_map<std::string, std::string> properties);
+
+  MessageConstPtr build();
+
+private:
+  friend class ClientManagerImpl;
+
+  MessageBuilder& withId(std::string id);
+
+  MessageBuilder& withBornTime(std::chrono::system_clock::time_point born_time);
+
+  MessageBuilder& withBornHost(std::string born_host);
+
+  MessagePtr message_;
+};
+
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/MessageListener.h b/api/rocketmq/MessageListener.h
index 5fdf59d..cd5ef05 100644
--- a/api/rocketmq/MessageListener.h
+++ b/api/rocketmq/MessageListener.h
@@ -16,46 +16,13 @@
  */
 #pragma once
 
-#include "MQMessageExt.h"
-#include "MQMessageQueue.h"
+#include <functional>
 
-ROCKETMQ_NAMESPACE_BEGIN
-
-enum class ConsumeMessageResult : uint8_t
-{
-  SUCCESS = 0,
-  FAILURE = 1
-};
-
-enum class MessageListenerType : uint8_t
-{
-  STANDARD = 0,
-  FIFO = 1
-};
-
-class MessageListener {
-public:
-  virtual ~MessageListener() = default;
+#include "ConsumeResult.h"
+#include "Message.h"
 
-  virtual MessageListenerType listenerType() = 0;
-};
-
-class StandardMessageListener : public MessageListener {
-public:
-  virtual ConsumeMessageResult consumeMessage(const std::vector<MQMessageExt>& msgs) = 0;
-
-  MessageListenerType listenerType() override {
-    return MessageListenerType::STANDARD;
-  }
-};
-
-class FifoMessageListener : public MessageListener {
-public:
-  MessageListenerType listenerType() override {
-    return MessageListenerType::FIFO;
-  }
+ROCKETMQ_NAMESPACE_BEGIN
 
-  virtual ConsumeMessageResult consumeMessage(const MQMessageExt& msgs) = 0;
-};
+using MessageListener = std::function<ConsumeResult(const Message&)>;
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/OffsetStore.h b/api/rocketmq/OffsetStore.h
deleted file mode 100644
index 514d5da..0000000
--- a/api/rocketmq/OffsetStore.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.
- */
-#pragma once
-
-#include "MQMessageQueue.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-class OffsetStore {
-public:
-  virtual ~OffsetStore() = default;
-
-  virtual void load() = 0;
-
-  virtual void updateOffset(const MQMessageQueue& message_queue, int64_t offset) = 0;
-
-  virtual bool readOffset(const MQMessageQueue& message_queue, int64_t& offset) = 0;
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/Producer.h b/api/rocketmq/Producer.h
new file mode 100644
index 0000000..cb70065
--- /dev/null
+++ b/api/rocketmq/Producer.h
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+#pragma once
+
+#include <chrono>
+#include <functional>
+#include <memory>
+#include <system_error>
+#include <vector>
+
+#include "Configuration.h"
+#include "ErrorCode.h"
+#include "Logger.h"
+#include "Message.h"
+#include "SendCallback.h"
+#include "SendReceipt.h"
+#include "TransactionChecker.h"
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+/**
+ * This class employs pointer-to-implementation paradigm to achieve the goal of stable ABI.
+ * Refer https://en.cppreference.com/w/cpp/language/pimpl for an explanation.
+ */
+class ProducerImpl;
+
+class ProducerBuilder;
+
+/**
+ * @brief
+ *
+ */
+class Producer {
+public:
+  static ProducerBuilder newBuilder();
+
+  /**
+   * @brief Send message synchronously.
+   *
+   * @param message Message to publish. Note the pointer, std::unique_ptr<const Message>, is 'moved' into.
+   * @param ec Error code and message
+   * @return SendReceipt Receipt of the pub action if successful, which holds an identifier for the message.
+   */
+  SendReceipt send(MessageConstPtr message, std::error_code& ec) noexcept;
+
+  /**
+   * @brief Send message in asynchronous manner.
+   *
+   * @param message  Message to send. Note the pointer, std::unique_ptr<const Message>, is 'moved' into.
+   * @param callback Callback to execute on completion.
+   */
+  void send(MessageConstPtr message, const SendCallback& callback) noexcept;
+
+private:
+  explicit Producer(std::shared_ptr<ProducerImpl> impl) : impl_(std::move(impl)) {
+  }
+
+  void start();
+
+  std::shared_ptr<ProducerImpl> impl_;
+
+  friend class ProducerBuilder;
+};
+
+class ProducerBuilder {
+public:
+  ProducerBuilder();
+
+  ProducerBuilder& withConfiguration(Configuration configuration);
+
+  ProducerBuilder& withTopics(const std::vector<std::string>& topics);
+
+  ProducerBuilder& withTransactionChecker(const TransactionChecker& checker);
+
+  Producer build();
+
+private:
+  std::shared_ptr<ProducerImpl> impl_;
+};
+
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/PullResult.h b/api/rocketmq/PullResult.h
deleted file mode 100644
index 2e91ec4..0000000
--- a/api/rocketmq/PullResult.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.
- */
-#pragma once
-
-#include <cstdlib>
-#include <vector>
-
-#include "MQMessageExt.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-class PullResult {
-public:
-  PullResult(int64_t min, int64_t max, int64_t next, std::vector<MQMessageExt> messages)
-      : min_(min), max_(max), next_(next), messages_(std::move(messages)) {
-  }
-
-  int64_t min() const {
-    return min_;
-  }
-
-  int64_t max() const {
-    return max_;
-  }
-
-  int64_t next() const {
-    return next_;
-  }
-
-  const std::vector<MQMessageExt>& messages() const {
-    return messages_;
-  }
-
-private:
-  int64_t min_;
-  int64_t max_;
-  int64_t next_;
-  std::vector<MQMessageExt> messages_;
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/PushConsumer.h b/api/rocketmq/PushConsumer.h
new file mode 100644
index 0000000..500c34b
--- /dev/null
+++ b/api/rocketmq/PushConsumer.h
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+#pragma once
+
+#include <memory>
+#include <string>
+
+#include "Configuration.h"
+#include "CredentialsProvider.h"
+#include "Executor.h"
+#include "ExpressionType.h"
+#include "FilterExpression.h"
+#include "Logger.h"
+#include "MessageListener.h"
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+class PushConsumerImpl;
+class PushConsumerBuilder;
+
+class PushConsumer {
+public:
+  static PushConsumerBuilder newBuilder();
+
+  void subscribe(std::string topic, FilterExpression filter_expression);
+
+  void unsubscribe(const std::string& topic);
+
+private:
+  friend class PushConsumerBuilder;
+
+  PushConsumer(std::shared_ptr<PushConsumerImpl> impl)
+      : impl_(std::move(impl)) {
+  } 
+
+  std::shared_ptr<PushConsumerImpl> impl_;
+};
+
+class PushConsumerBuilder {
+public:
+  PushConsumerBuilder() : configuration_(Configuration::newBuilder().build()) {}
+  
+  PushConsumerBuilder &withConfiguration(Configuration configuration) {
+    configuration_ = std::move(configuration);
+    return *this;
+  }
+
+  PushConsumerBuilder &withGroup(std::string group) {
+    group_ = std::move(group);
+    return *this;
+  }
+
+  PushConsumerBuilder &withConsumeThreads(std::size_t consume_thread) {
+    consume_thread_ = consume_thread;
+    return *this;
+  }
+
+  PushConsumerBuilder &withListener(MessageListener listener) {
+    listener_ = std::move(listener);
+    return *this;
+  }
+
+  PushConsumerBuilder &subscribe(std::string topic,
+                                 FilterExpression filter_expression) {
+    subscriptions_.insert({topic, filter_expression});
+    return *this;
+  }
+
+  PushConsumer build();
+
+private:
+  std::string group_;
+  Configuration configuration_;
+  std::size_t consume_thread_;
+  MessageListener listener_;
+
+  std::unordered_map<std::string, FilterExpression> subscriptions_;
+};
+
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/MessageModel.h b/api/rocketmq/SendCallback.h
similarity index 82%
copy from api/rocketmq/MessageModel.h
copy to api/rocketmq/SendCallback.h
index 2422d32..8468f63 100644
--- a/api/rocketmq/MessageModel.h
+++ b/api/rocketmq/SendCallback.h
@@ -16,16 +16,14 @@
  */
 #pragma once
 
-#include "RocketMQ.h"
+#include <functional>
+#include <system_error>
 
-#include <cstdint>
+#include "RocketMQ.h"
+#include "SendReceipt.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-enum class MessageModel : int8_t
-{
-  BROADCASTING,
-  CLUSTERING,
-};
+using SendCallback = std::function<void(const std::error_code&, const SendReceipt&)>;
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/MessageModel.h b/api/rocketmq/SendReceipt.h
similarity index 86%
copy from api/rocketmq/MessageModel.h
copy to api/rocketmq/SendReceipt.h
index 2422d32..06a01cc 100644
--- a/api/rocketmq/MessageModel.h
+++ b/api/rocketmq/SendReceipt.h
@@ -16,16 +16,18 @@
  */
 #pragma once
 
-#include "RocketMQ.h"
-
 #include <cstdint>
+#include <string>
+#include <utility>
+
+#include "RocketMQ.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-enum class MessageModel : int8_t
-{
-  BROADCASTING,
-  CLUSTERING,
+struct SendReceipt {
+  std::string message_id;
+
+  std::string transaction_id;
 };
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/SendResult.h b/api/rocketmq/SendResult.h
deleted file mode 100644
index b491cc6..0000000
--- a/api/rocketmq/SendResult.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * 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.
- */
-#pragma once
-
-#include <utility>
-
-#include "MQMessageQueue.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-enum class SendStatus : int8_t
-{
-  SEND_OK,
-
-  // Deprecated. Remove in the next release.
-  SEND_FLUSH_DISK_TIMEOUT,
-
-  // Deprecated. Remove in the next release.
-  SEND_FLUSH_SLAVE_TIMEOUT,
-
-  // Deprecated. Remove in the next release.
-  SEND_SLAVE_NOT_AVAILABLE
-};
-
-class SendResult {
-public:
-  SendResult() = default;
-
-  SendResult(const SendStatus& send_status, std::string msg_id, MQMessageQueue message_queue, long long queue_offset,
-             std::string region_id)
-      : send_status_(send_status), message_id_(std::move(msg_id)), message_queue_(std::move(message_queue)),
-        queue_offset_(queue_offset), region_id_(std::move(region_id)) {
-  }
-
-  SendResult(const SendResult& other) {
-    this->operator=(other);
-  }
-
-  SendResult& operator=(const SendResult& other) {
-    if (this == &other) {
-      return *this;
-    }
-
-    send_status_ = other.send_status_;
-    message_id_ = other.message_id_;
-    message_queue_ = other.message_queue_;
-    queue_offset_ = other.queue_offset_;
-    transaction_id_ = other.transaction_id_;
-    region_id_ = other.region_id_;
-    return *this;
-  }
-
-  const std::string& getMsgId() const {
-    return message_id_;
-  }
-
-  void setMsgId(const std::string& msg_id) {
-    message_id_ = msg_id;
-  }
-
-  const std::string& getRegionId() const {
-    return region_id_;
-  }
-
-  void setRegionId(const std::string& region_id) {
-    region_id_ = region_id;
-  }
-
-  SendStatus getSendStatus() const {
-    return send_status_;
-  }
-
-  void setSendStatus(const SendStatus& send_status) {
-    send_status_ = send_status;
-  }
-
-  MQMessageQueue& getMessageQueue() const {
-    return message_queue_;
-  }
-
-  void setMessageQueue(const MQMessageQueue& message_queue) {
-    message_queue_ = message_queue;
-  }
-
-  long long getQueueOffset() const {
-    return queue_offset_;
-  }
-
-  void setQueueOffset(long long queue_offset) {
-    queue_offset_ = queue_offset;
-  }
-
-  const std::string& getTransactionId() const {
-    return transaction_id_;
-  }
-
-  void setTransactionId(const std::string& transaction_id) {
-    transaction_id_ = transaction_id;
-  }
-
-  const std::string& traceContext() const {
-    return trace_context_;
-  }
-
-  void traceContext(std::string trace_context) {
-    trace_context_ = std::move(trace_context);
-  }
-
-  operator bool() {
-    return !message_id_.empty();
-  }
-
-private:
-  SendStatus send_status_{SendStatus::SEND_OK};
-  std::string message_id_;
-  mutable MQMessageQueue message_queue_;
-  long long queue_offset_{0};
-  std::string transaction_id_;
-  std::string region_id_;
-  std::string trace_context_;
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/SimpleConsumer.h b/api/rocketmq/SimpleConsumer.h
new file mode 100644
index 0000000..0f7030f
--- /dev/null
+++ b/api/rocketmq/SimpleConsumer.h
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+#pragma once
+
+#include <chrono>
+#include <functional>
+#include <memory>
+#include <string>
+#include <system_error>
+#include <unordered_map>
+#include <vector>
+
+#include "Configuration.h"
+#include "FilterExpression.h"
+#include "Message.h"
+#include "RocketMQ.h"
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+using ReceiveCallback = std::function<void(const std::error_code&, const std::vector<MessageConstSharedPtr>&)>;
+
+using AckCallback = std::function<void(const std::error_code&)>;
+
+using ChangeInvisibleDurationCallback = std::function<void(const std::error_code&)>;
+
+class SimpleConsumerImpl;
+
+class SimpleConsumerBuilder;
+
+class SimpleConsumer {
+public:
+  ~SimpleConsumer();
+
+  static SimpleConsumerBuilder newBuilder();
+
+  void subscribe(std::string topic, FilterExpression filter_expression);
+
+  void unsubscribe(const std::string& topic);
+
+  void receive(std::size_t limit,
+               std::chrono::milliseconds invisible_duration,
+               std::error_code& ec,
+               std::vector<MessageConstSharedPtr>& messages);
+
+  void asyncReceive(std::size_t limit, std::chrono::milliseconds invisible_duration, ReceiveCallback callback);
+
+  void ack(const Message& message, std::error_code& ec);
+
+  void asyncAck(const Message& message, AckCallback callback);
+
+  void changeInvisibleDuration(const Message& message, std::chrono::milliseconds duration, std::error_code& ec);
+
+  void asyncChangeInvisibleDuration(const Message& message,
+                                    std::chrono::milliseconds duration,
+                                    ChangeInvisibleDurationCallback callback);
+
+private:
+  std::shared_ptr<SimpleConsumerImpl> impl_;
+
+  SimpleConsumer(std::string group);
+
+  void start();
+
+  friend class SimpleConsumerBuilder;
+};
+
+class SimpleConsumerBuilder {
+public:
+  SimpleConsumerBuilder();
+
+  SimpleConsumerBuilder& withGroup(std::string group) {
+    group_ = std::move(group);
+    return *this;
+  }
+
+  SimpleConsumerBuilder& subscribe(std::string topic, FilterExpression expression) {
+    subscriptions_.insert({std::move(topic), std::move(expression)});
+    return *this;
+  }
+
+  SimpleConsumerBuilder& withConfiguration(Configuration configuration) {
+    configuration_ = std::move(configuration);
+    return *this;
+  }
+
+  SimpleConsumer build();
+
+private:
+  // Group name the consumer belongs to
+  std::string group_;
+
+  Configuration configuration_;
+
+  std::unordered_map<std::string, FilterExpression> subscriptions_;
+};
+
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/MessageModel.h b/api/rocketmq/Tracing.h
similarity index 87%
copy from api/rocketmq/MessageModel.h
copy to api/rocketmq/Tracing.h
index 2422d32..bc12362 100644
--- a/api/rocketmq/MessageModel.h
+++ b/api/rocketmq/Tracing.h
@@ -16,16 +16,12 @@
  */
 #pragma once
 
-#include "RocketMQ.h"
+#include "opencensus/trace/sampler.h"
 
-#include <cstdint>
+#include "RocketMQ.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-enum class MessageModel : int8_t
-{
-  BROADCASTING,
-  CLUSTERING,
-};
+opencensus::trace::Sampler* traceSampler() __attribute__((weak));
 
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
+ROCKETMQ_NAMESPACE_END
diff --git a/api/rocketmq/Transaction.h b/api/rocketmq/Transaction.h
index 9a135a6..2728d12 100644
--- a/api/rocketmq/Transaction.h
+++ b/api/rocketmq/Transaction.h
@@ -34,17 +34,18 @@ public:
 
   virtual bool rollback() = 0;
 
-  virtual std::string messageId() const = 0;
+  virtual const std::string& topic() const = 0;
 
-  virtual std::string transactionId() const = 0;
-};
+  virtual const std::string& messageId() const = 0;
 
-using TransactionPtr = std::unique_ptr<Transaction>;
+  virtual const std::string& transactionId() const = 0;
+
+  virtual const std::string& traceContext() const = 0;
 
-enum class TransactionState : int8_t
-{
-  COMMIT = 0,
-  ROLLBACK = 1,
+  virtual const std::string& endpoint() const = 0;
 };
 
+using TransactionPtr = std::unique_ptr<Transaction>;
+using TransactionConstPtr = std::unique_ptr<const Transaction>;
+
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/base/include/DigestType.h b/api/rocketmq/TransactionChecker.h
similarity index 83%
copy from src/main/cpp/base/include/DigestType.h
copy to api/rocketmq/TransactionChecker.h
index e255d82..604e7bd 100644
--- a/src/main/cpp/base/include/DigestType.h
+++ b/api/rocketmq/TransactionChecker.h
@@ -16,17 +16,13 @@
  */
 #pragma once
 
-#include <cstdint>
+#include <functional>
 
-#include "rocketmq/RocketMQ.h"
+#include "Message.h"
+#include "TransactionState.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-enum class DigestType : int8_t
-{
-  CRC32 = 0,
-  MD5 = 1,
-  SHA1 = 2,
-};
+using TransactionChecker = std::function<TransactionState(const Message&)>;
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/MessageType.h b/api/rocketmq/TransactionState.h
similarity index 88%
rename from api/rocketmq/MessageType.h
rename to api/rocketmq/TransactionState.h
index 8d4ea26..decdf21 100644
--- a/api/rocketmq/MessageType.h
+++ b/api/rocketmq/TransactionState.h
@@ -22,12 +22,9 @@
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-enum class MessageType : int8_t
-{
-  NORMAL = 0,
-  FIFO = 1,
-  DELAY = 2,
-  TRANSACTION = 3,
+enum class TransactionState : int8_t {
+  COMMIT = 0,
+  ROLLBACK = 1,
 };
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/bazel/rocketmq_deps.bzl b/bazel/rocketmq_deps.bzl
index d593bee..7282dd7 100644
--- a/bazel/rocketmq_deps.bzl
+++ b/bazel/rocketmq_deps.bzl
@@ -9,6 +9,17 @@ def rocketmq_deps():
         actual = "@com_github_opentelemetry//api:api",
     )
 
+    if "rules_python" not in native.existing_rules():
+        http_archive(
+            name = "rules_python",
+            sha256 = "cdf6b84084aad8f10bf20b46b77cb48d83c319ebe6458a18e9d2cebf57807cdd",
+            strip_prefix = "rules_python-0.8.1",
+            urls = [
+                "https://shutian.oss-cn-hangzhou.aliyuncs.com/cdn/rules-python/rules_python-0.8.1.tar.gz",
+                "https://github.com/bazelbuild/rules_python/archive/refs/tags/0.8.1.tar.gz",
+            ],
+        )
+
     if "com_google_googletest" not in native.existing_rules():
          http_archive(
              name = "com_google_googletest",
@@ -55,60 +66,47 @@ def rocketmq_deps():
     if "com_google_protobuf" not in native.existing_rules():
         http_archive(
             name = "com_google_protobuf",
-            sha256 = "36f81e03a0702f8f935fffd5a486dac1c0fc6d4bae1cd02c7a32448ad6e63bcb",
-            strip_prefix = "protobuf-3.17.2",
+            sha256 = "8b28fdd45bab62d15db232ec404248901842e5340299a57765e48abe8a80d930",
+            strip_prefix = "protobuf-3.20.1",
             urls = [
-                "https://github.com/protocolbuffers/protobuf/archive/refs/tags/v3.17.2.tar.gz",
+                "https://shutian.oss-cn-hangzhou.aliyuncs.com/cdn/protobuf/protobuf-3.20.1.tar.gz",
+                "https://github.com/protocolbuffers/protobuf/archive/refs/tags/v3.20.1.tar.gz",
             ],
         )
 
     if "rules_proto_grpc" not in native.existing_rules():
         http_archive(
             name = "rules_proto_grpc",
-            sha256 = "7954abbb6898830cd10ac9714fbcacf092299fda00ed2baf781172f545120419",
-            strip_prefix = "rules_proto_grpc-3.1.1",
-            urls = ["https://github.com/rules-proto-grpc/rules_proto_grpc/archive/3.1.1.tar.gz"],
+            sha256 = "507e38c8d95c7efa4f3b1c0595a8e8f139c885cb41a76cab7e20e4e67ae87731",
+            strip_prefix = "rules_proto_grpc-4.1.1",
+            urls = [
+                "https://shutian.oss-cn-hangzhou.aliyuncs.com/cdn/rules_proto_grpc/rules_proto_grpc-4.1.1.tar.gz",
+                "https://github.com/rules-proto-grpc/rules_proto_grpc/archive/refs/tags/4.1.1.tar.gz"
+            ],
         )
 
     if "com_google_absl" not in native.existing_rules():
         http_archive(
             name = "com_google_absl",
-            sha256 = "59b862f50e710277f8ede96f083a5bb8d7c9595376146838b9580be90374ee1f",
-            strip_prefix = "abseil-cpp-20210324.2",
+            sha256 = "dcf71b9cba8dc0ca9940c4b316a0c796be8fab42b070bb6b7cab62b48f0e66c4",
+            strip_prefix = "abseil-cpp-20211102.0",
             urls = [
-                "https://github.com/abseil/abseil-cpp/archive/refs/tags/20210324.2.tar.gz",
+                "https://shutian.oss-cn-hangzhou.aliyuncs.com/cdn/abseil/abseil-cpp-20211102.0.tar.gz",
+                "https://github.com/abseil/abseil-cpp/archive/refs/tags/20211102.0.tar.gz",
             ],
         )
 
     if "com_github_grpc_grpc" not in native.existing_rules():
         http_archive(
             name = "com_github_grpc_grpc",
-            strip_prefix = "grpc-1.39.0",
-            sha256 = "b16992aa1c949c10d5d5ce2a62f9d99fa7de77da2943e643fb66dcaf075826d6",
-            urls = ["https://github.com/grpc/grpc/archive/v1.39.0.tar.gz"],
-        )
-
-    if "io_opentelemetry_cpp" not in native.existing_rules():
-        http_archive(
-            name = "io_opentelemetry_cpp",
-            sha256 = "24ba9b83f6cb8ba717ae30ebc570f5e8d0569008aee3c8b9a7ce6e4e1a5115b7",
-            strip_prefix = "opentelemetry-cpp-1.0.0-rc4",
+            strip_prefix = "grpc-1.46.0",
+            sha256 = "67423a4cd706ce16a88d1549297023f0f9f0d695a96dd684adc21e67b021f9bc",
             urls = [
-                "https://github.com/open-telemetry/opentelemetry-cpp/archive/refs/tags/v1.0.0-rc4.tar.gz",
+                "https://shutian.oss-cn-hangzhou.aliyuncs.com/cdn/grpc/grpc-1.46.0.tar.gz",
+                "https://github.com/grpc/grpc/archive/refs/tags/v1.46.0.tar.gz",
             ],
         )
 
-    maybe(
-        http_archive,
-        name = "com_github_opentelemetry_proto",
-        build_file = "@io_opentelemetry_cpp//bazel:opentelemetry_proto.BUILD",
-        sha256 = "08f090570e0a112bfae276ba37e9c45bf724b64d902a7a001db33123b840ebd6",
-        strip_prefix = "opentelemetry-proto-0.6.0",
-        urls = [
-            "https://github.com/open-telemetry/opentelemetry-proto/archive/v0.6.0.tar.gz",
-        ],
-    )
-
     maybe(
         http_archive,
         name = "asio",
@@ -137,4 +135,25 @@ def rocketmq_deps():
             "https://github.com/googleapis/googleapis/archive/af7fb72df59a814221b123a4d1acb3f6c3e6cc95.zip"
         ],
         strip_prefix = "googleapis-af7fb72df59a814221b123a4d1acb3f6c3e6cc95",
+    )
+
+    maybe(
+        http_archive,
+        name = "hedron_compile_commands",
+        sha256 = "4f69ccafa253825d93191977dcbcecee74e576aadbd21f1cfb25a19111ecdf21",
+        urls = [
+            "https://shutian.oss-cn-hangzhou.aliyuncs.com/cdn/bazel-compile-commands-extractor/bazel-compile-commands-extractor-1.0.tar.gz",
+            "https://github.com/lizhanhui/bazel-compile-commands-extractor/archive/refs/tags/v1.0.tar.gz",
+        ],
+        strip_prefix = "bazel-compile-commands-extractor-1.0",
+    )
+
+    maybe(
+        http_archive,
+        name = "rules_swift",
+        urls = [
+            "https://shutian.oss-cn-hangzhou.aliyuncs.com/cdn/rules_swift/rules_swift-0.27.0.tar.gz",
+            "https://github.com/bazelbuild/rules_swift/archive/refs/tags/0.27.0.tar.gz",
+        ],
+        strip_prefix = "rules_swift-0.27.0",
     )
\ No newline at end of file
diff --git a/example/rocketmq/ExampleAsyncProducer.cpp b/example/rocketmq/ExampleAsyncProducer.cpp
deleted file mode 100644
index 083cb34..0000000
--- a/example/rocketmq/ExampleAsyncProducer.cpp
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * 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.
- */
-#include "rocketmq/DefaultMQProducer.h"
-#include "rocketmq/ErrorCode.h"
-#include <algorithm>
-#include <array>
-#include <atomic>
-#include <condition_variable>
-#include <iostream>
-#include <mutex>
-#include <random>
-#include <system_error>
-
-using namespace rocketmq;
-
-int getAndReset(std::atomic_int& counter) {
-  int current;
-  while (true) {
-    current = counter.load(std::memory_order_relaxed);
-    if (counter.compare_exchange_weak(current, 0, std::memory_order_relaxed)) {
-      break;
-    }
-  }
-  return current;
-}
-
-const std::string& alphaNumeric() {
-  static std::string alpha_numeric("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
-  return alpha_numeric;
-}
-
-std::string randomString(std::string::size_type len) {
-  std::string result;
-  result.reserve(len);
-  std::random_device rd;
-  std::mt19937 generator(rd());
-  std::string source(alphaNumeric());
-  std::string::size_type generated = 0;
-  while (generated < len) {
-    std::shuffle(source.begin(), source.end(), generator);
-    std::string::size_type delta = std::min({len - generated, source.length()});
-    result.append(source.substr(0, delta));
-    generated += delta;
-  }
-  return result;
-}
-
-template <int PARTITION>
-class RateLimiter {
-public:
-  explicit RateLimiter(int permit) : permits_{0}, interval_(1000 / PARTITION), stopped_(false) {
-    int avg = permit / PARTITION;
-    for (auto& i : partition_) {
-      i = avg;
-    }
-
-    int r = permit % PARTITION;
-
-    if (r) {
-      int step = PARTITION / r;
-      for (int i = 0; i < r; ++i) {
-        partition_[i * step]++;
-      }
-    }
-
-    auto lambda_tick = [this]() {
-      while (!stopped_) {
-        tick();
-      }
-    };
-
-    thread_tick_ = std::thread(lambda_tick);
-  }
-
-  ~RateLimiter() {
-    stopped_.store(true, std::memory_order_relaxed);
-    if (thread_tick_.joinable()) {
-      thread_tick_.join();
-    }
-  }
-
-  std::array<int, PARTITION>& partition() {
-    return permits_;
-  }
-
-  int slot() {
-    auto current = std::chrono::steady_clock::now();
-    long ms = std::chrono::duration_cast<std::chrono::milliseconds>(current.time_since_epoch()).count();
-    return ms / interval_ % PARTITION;
-  }
-
-  void acquire() {
-    int idx = slot();
-    {
-      std::unique_lock<std::mutex> lk(mtx_);
-      if (permits_[idx] > 0) {
-        --permits_[idx];
-        return;
-      }
-
-      // Reuse quota of the past half of the cycle
-      for (int j = 1; j <= PARTITION / 2; ++j) {
-        int index = idx - j;
-        if (index < 0) {
-          index += PARTITION;
-        }
-        if (permits_[index] > 0) {
-          --permits_[index];
-          return;
-        }
-      }
-
-      cv_.wait(lk, [this]() {
-        int idx = slot();
-        return permits_[idx] > 0;
-      });
-      idx = slot();
-      --permits_[idx];
-    }
-  }
-
-  void tick() {
-    std::this_thread::sleep_for(std::chrono::milliseconds(1000 / PARTITION));
-    int idx = slot();
-    {
-      std::unique_lock<std::mutex> lk(mtx_);
-      permits_[idx] = partition_[idx];
-      cv_.notify_all();
-    }
-  }
-
-private:
-  std::array<int, PARTITION> partition_;
-  std::array<int, PARTITION> permits_;
-  int interval_;
-  std::mutex mtx_;
-  std::condition_variable cv_;
-
-  std::atomic_bool stopped_;
-  std::thread thread_tick_;
-};
-
-class SampleSendCallback : public rocketmq::SendCallback {
-public:
-  SampleSendCallback(std::atomic_int& counter, std::atomic_int& error) : counter_(counter), error_(error) {
-  }
-
-  void onSuccess(SendResult& send_result) noexcept override {
-    counter_.fetch_add(1, std::memory_order_relaxed);
-  }
-
-  void onFailure(const std::error_code& ec) noexcept override {
-    error_.fetch_add(1, std::memory_order_relaxed);
-  }
-
-private:
-  std::atomic_int& counter_;
-  std::atomic_int& error_;
-};
-
-int main(int argc, char* argv[]) {
-  std::string::size_type body_size = 1024;
-  int duration = 300;
-  int qps = 1000;
-
-  if (argc > 1) {
-    body_size = std::stoi(argv[1]);
-  }
-
-  if (argc > 2) {
-    duration = std::stoi(argv[2]);
-  }
-
-  if (argc > 3) {
-    qps = std::stoi(argv[3]);
-  }
-
-  Logger& logger = getLogger();
-  logger.setLevel(Level::Info);
-  logger.init();
-
-  const char* topic = "cpp_sdk_standard";
-  const char* tag = "TagA";
-  DefaultMQProducer producer("TestGroup");
-  producer.setNamesrvAddr("47.98.116.189:80");
-  producer.compressBodyThreshold(256);
-  const char* resource_namespace = "MQ_INST_1080056302921134_BXuIbML7";
-  producer.setCredentialsProvider(std::make_shared<ConfigFileCredentialsProvider>());
-  producer.setResourceNamespace(resource_namespace);
-  producer.setRegion("cn-hangzhou-pre");
-  MQMessage message;
-  message.setTopic(topic);
-  message.setTags(tag);
-  message.setKey("Yuck! Why-plural?");
-  message.setBody(randomString(body_size));
-
-  std::cout << "Message Body: " << message.getBody() << std::endl;
-
-  std::atomic_bool stopped(false);
-
-  auto lambda = [&stopped, duration]() {
-    std::cout << "Benchmark will stop in " << duration << " seconds!" << std::endl;
-    std::this_thread::sleep_for(std::chrono::seconds(duration));
-    stopped.store(true);
-  };
-
-  std::thread t(lambda);
-
-  std::atomic_int success(0);
-  std::atomic_int error(0);
-
-  auto stats_lambda = [&stopped, &success, &error]() {
-    while (!stopped) {
-      std::this_thread::sleep_for(std::chrono::seconds(1));
-      std::cout << "Success:" << getAndReset(success) << ", Error: " << getAndReset(error) << std::endl;
-    }
-  };
-
-  std::thread stats_thread(stats_lambda);
-
-  RateLimiter<10> rate_limiter(qps);
-  SampleSendCallback send_callback(success, error);
-
-  try {
-    producer.start();
-    while (!stopped) {
-      rate_limiter.acquire();
-      producer.send(message, &send_callback, true);
-    }
-  } catch (...) {
-    std::cerr << "Ah...No!!!" << std::endl;
-  }
-
-  if (stats_thread.joinable()) {
-    stats_thread.join();
-  }
-
-  if (t.joinable()) {
-    t.join();
-  }
-  producer.shutdown();
-  return EXIT_SUCCESS;
-}
\ No newline at end of file
diff --git a/example/rocketmq/ExampleBroadcastPushConsumer.cpp b/example/rocketmq/ExampleBroadcastPushConsumer.cpp
deleted file mode 100644
index 529f1e6..0000000
--- a/example/rocketmq/ExampleBroadcastPushConsumer.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.
- */
-#include "rocketmq/DefaultMQPushConsumer.h"
-
-#include "rocketmq/Logger.h"
-#include "spdlog/spdlog.h"
-
-#include <chrono>
-#include <iostream>
-#include <mutex>
-#include <thread>
-
-using namespace rocketmq;
-
-class SampleMQMessageListener : public StandardMessageListener {
-public:
-  ConsumeMessageResult consumeMessage(const std::vector<MQMessageExt>& msgs) override {
-    for (const MQMessageExt& msg : msgs) {
-      SPDLOG_INFO("Receive a message. MessageId={}", msg.getMsgId());
-      std::cout << "Received a message. MessageId: " << msg.getMsgId() << std::endl;
-      std::this_thread::sleep_for(std::chrono::milliseconds(10));
-    }
-    return ConsumeMessageResult::SUCCESS;
-  }
-};
-
-int main(int argc, char* argv[]) {
-  Logger& logger = getLogger();
-  logger.setLevel(Level::Debug);
-  logger.init();
-
-  const char* cid = "GID_cpp_sdk_standard";
-  const char* topic = "cpp_sdk_standard";
-  const char* resource_namespace = "MQ_INST_1080056302921134_BXuIbML7";
-
-  DefaultMQPushConsumer push_consumer(cid);
-  push_consumer.setMessageModel(MessageModel::BROADCASTING);
-  push_consumer.setResourceNamespace(resource_namespace);
-  push_consumer.setCredentialsProvider(std::make_shared<ConfigFileCredentialsProvider>());
-  push_consumer.setNamesrvAddr("121.43.42.193:80");
-  MessageListener* listener = new SampleMQMessageListener;
-  push_consumer.setGroupName(cid);
-  push_consumer.subscribe(topic, "*");
-  push_consumer.registerMessageListener(listener);
-  push_consumer.start();
-
-  std::this_thread::sleep_for(std::chrono::minutes(60));
-
-  push_consumer.shutdown();
-  return EXIT_SUCCESS;
-}
diff --git a/example/rocketmq/ExamplePullConsumer.cpp b/example/rocketmq/ExamplePullConsumer.cpp
deleted file mode 100644
index 7299633..0000000
--- a/example/rocketmq/ExamplePullConsumer.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.
- */
-#include <cstdlib>
-#include <iostream>
-
-#include "rocketmq/CredentialsProvider.h"
-#include "rocketmq/DefaultMQPullConsumer.h"
-#include "rocketmq/Logger.h"
-
-int main(int argc, char* argv[]) {
-  const char* group = "GID_group003";
-  const char* topic = "yc001";
-  const char* resource_namespace = "MQ_INST_1973281269661160_BXmPlOA6";
-  const char* name_server_list = "ipv4:11.165.223.199:9876";
-
-  rocketmq::Logger& logger = rocketmq::getLogger();
-  logger.setLevel(rocketmq::Level::Debug);
-  logger.init();
-
-  rocketmq::DefaultMQPullConsumer pull_consumer(group);
-  pull_consumer.setResourceNamespace(resource_namespace);
-  pull_consumer.setCredentialsProvider(std::make_shared<rocketmq::ConfigFileCredentialsProvider>());
-  pull_consumer.setNamesrvAddr(name_server_list);
-  pull_consumer.start();
-
-  std::future<std::vector<rocketmq::MQMessageQueue>> future = pull_consumer.queuesFor(topic);
-  auto queues = future.get();
-
-  for (const auto& queue : queues) {
-    rocketmq::OffsetQuery offset_query;
-    offset_query.message_queue = queue;
-    offset_query.policy = rocketmq::QueryOffsetPolicy::BEGINNING;
-    auto offset_future = pull_consumer.queryOffset(offset_query);
-    int64_t offset = offset_future.get();
-    std::cout << "offset: " << offset << std::endl;
-  }
-
-  pull_consumer.shutdown();
-  return EXIT_SUCCESS;
-}
\ No newline at end of file
diff --git a/example/rocketmq/ExamplePushConsumer.cpp b/example/rocketmq/ExamplePushConsumer.cpp
deleted file mode 100644
index d45e52a..0000000
--- a/example/rocketmq/ExamplePushConsumer.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.
- */
-#include <chrono>
-#include <iostream>
-#include <mutex>
-#include <thread>
-
-#include "rocketmq/Logger.h"
-
-#include "spdlog/spdlog.h"
-
-#include "rocketmq/DefaultMQPushConsumer.h"
-
-using namespace rocketmq;
-
-class SampleMQMessageListener : public StandardMessageListener {
-public:
-  ConsumeMessageResult consumeMessage(const std::vector<MQMessageExt>& msgs) override {
-    for (const MQMessageExt& msg : msgs) {
-      SPDLOG_INFO("Consume message[Topic={}, MessageId={}] OK", msg.getTopic(), msg.getMsgId());
-      std::cout << "Consume Message[MsgId=" << msg.getMsgId() << "] OK. Body Size: " << msg.getBody().size()
-                << std::endl;
-      // std::this_thread::sleep_for(std::chrono::seconds(1));
-    }
-    return ConsumeMessageResult::SUCCESS;
-  }
-};
-
-int main(int argc, char* argv[]) {
-
-  Logger& logger = getLogger();
-  logger.setLevel(Level::Debug);
-  logger.init();
-
-  const char* group_id = "GID_cpp_sdk_standard";
-  const char* topic = "cpp_sdk_standard";
-  const char* resource_namespace = "MQ_INST_1080056302921134_BXuIbML7";
-  const char* name_server = "mq-inst-1080056302921134-bxuibml7.mq.cn-hangzhou.aliyuncs.com:80";
-
-  DefaultMQPushConsumer push_consumer(group_id);
-  push_consumer.setResourceNamespace(resource_namespace);
-  push_consumer.setCredentialsProvider(std::make_shared<ConfigFileCredentialsProvider>());
-  push_consumer.setNamesrvAddr(name_server);
-  MessageListener* listener = new SampleMQMessageListener;
-  push_consumer.setInstanceName("instance_0");
-  push_consumer.subscribe(topic, "*");
-  push_consumer.registerMessageListener(listener);
-  push_consumer.setConsumeThreadCount(4);
-  push_consumer.start();
-
-  std::this_thread::sleep_for(std::chrono::minutes(30));
-
-  push_consumer.shutdown();
-  return EXIT_SUCCESS;
-}
diff --git a/example/rocketmq/BUILD.bazel b/examples/BUILD.bazel
similarity index 51%
rename from example/rocketmq/BUILD.bazel
rename to examples/BUILD.bazel
index 9c7508a..dfa114a 100644
--- a/example/rocketmq/BUILD.bazel
+++ b/examples/BUILD.bazel
@@ -47,15 +47,25 @@ cc_binary(
 )
 
 cc_binary(
-    name = "sql_producer",
+    name = "example_simple_consumer",
     srcs = [
-        "SqlProducer.cpp",
+        "ExampleSimpleConsumer.cpp",
     ],
     deps = [
         "//src/main/cpp/rocketmq:rocketmq_library",
     ],
 )
 
+# cc_binary(
+#     name = "sql_producer",
+#     srcs = [
+#         "SqlProducer.cpp",
+#     ],
+#     deps = [
+#         "//src/main/cpp/rocketmq:rocketmq_library",
+#     ],
+# )
+
 cc_binary(
     name = "example_push_consumer",
     srcs = [
@@ -66,82 +76,62 @@ cc_binary(
     ],
 )
 
-cc_binary(
-    name = "example_fifo_push_consumer",
-    srcs = [
-        "ExampleFifoPushConsumer.cpp",
-    ],
-    deps = [
-        "//src/main/cpp/rocketmq:rocketmq_library",
-    ],
-)
+# cc_binary(
+#     name = "example_fifo_push_consumer",
+#     srcs = [
+#         "ExampleFifoPushConsumer.cpp",
+#     ],
+#     deps = [
+#         "//src/main/cpp/rocketmq:rocketmq_library",
+#     ],
+# )
 
-cc_binary(
-    name = "push_consumer_with_custom_executor",
-    srcs = [
-        "PushConsumerWithCustomExecutor.cpp",
-    ],
-    deps = [
-        "//src/main/cpp/rocketmq:rocketmq_library",
-    ],
-)
-
-cc_binary(
-    name = "push_consumer_with_throttle",
-    srcs = [
-        "PushConsumerWithThrottle.cpp",
-    ],
-    deps = [
-        "//src/main/cpp/rocketmq:rocketmq_library",
-    ],
-)
-
-cc_binary(
-    name = "sql_consumer",
-    srcs = [
-        "SqlConsumer.cpp",
-    ],
-    deps = [
-        "//src/main/cpp/rocketmq:rocketmq_library",
-    ],
-)
+# cc_binary(
+#     name = "push_consumer_with_custom_executor",
+#     srcs = [
+#         "PushConsumerWithCustomExecutor.cpp",
+#     ],
+#     deps = [
+#         "//src/main/cpp/rocketmq:rocketmq_library",
+#     ],
+# )
 
-cc_binary(
-    name = "example_pull_consumer",
-    srcs = [
-        "ExamplePullConsumer.cpp",
-    ],
-    deps = [
-        "//src/main/cpp/rocketmq:rocketmq_library",
-    ],
-)
+# cc_binary(
+#     name = "push_consumer_with_throttle",
+#     srcs = [
+#         "PushConsumerWithThrottle.cpp",
+#     ],
+#     deps = [
+#         "//src/main/cpp/rocketmq:rocketmq_library",
+#     ],
+# )
 
-cc_binary(
-    name = "benchmark_push_consumer",
-    srcs = [
-        "BenchmarkPushConsumer.cpp",
-    ],
-    deps = [
-        "//src/main/cpp/rocketmq:rocketmq_library",
-    ],
-)
+# cc_binary(
+#     name = "sql_consumer",
+#     srcs = [
+#         "SqlConsumer.cpp",
+#     ],
+#     deps = [
+#         "//src/main/cpp/rocketmq:rocketmq_library",
+#     ],
+# )
 
-cc_binary(
-    name = "example_broadcast_push_consumer",
-    srcs = [
-        "ExampleBroadcastPushConsumer.cpp",
-    ],
-    deps = [
-        "//src/main/cpp/rocketmq:rocketmq_library",
-    ],
-)
+# cc_binary(
+#     name = "benchmark_push_consumer",
+#     srcs = [
+#         "BenchmarkPushConsumer.cpp",
+#     ],
+#     deps = [
+#         "//src/main/cpp/rocketmq:rocketmq_library",
+#     ],
+# )
 
-cc_binary(
-    name = "example_transaction_producer",
-    srcs = [
-        "ExampleTransactionProducer.cpp",
-    ],
-    deps = [
-        "//src/main/cpp/rocketmq:rocketmq_library",
-    ],
-)
\ No newline at end of file
+# cc_binary(
+#     name = "example_transaction_producer",
+#     srcs = [
+#         "ExampleTransactionProducer.cpp",
+#     ],
+#     deps = [
+#         "//src/main/cpp/rocketmq:rocketmq_library",
+#     ],
+# )
\ No newline at end of file
diff --git a/example/rocketmq/BenchmarkPushConsumer.cpp b/examples/BenchmarkPushConsumer.cpp
similarity index 100%
rename from example/rocketmq/BenchmarkPushConsumer.cpp
rename to examples/BenchmarkPushConsumer.cpp
diff --git a/example/rocketmq/ExampleProducer.cpp b/examples/ExampleAsyncProducer.cpp
similarity index 67%
copy from example/rocketmq/ExampleProducer.cpp
copy to examples/ExampleAsyncProducer.cpp
index 3e1cfc5..2d28d74 100644
--- a/example/rocketmq/ExampleProducer.cpp
+++ b/examples/ExampleAsyncProducer.cpp
@@ -14,13 +14,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include "rocketmq/DefaultMQProducer.h"
 #include <algorithm>
 #include <atomic>
+#include <condition_variable>
 #include <iostream>
+#include <mutex>
 #include <random>
+#include <system_error>
 
-using namespace rocketmq;
+#include "rocketmq/Message.h"
+#include "rocketmq/Producer.h"
+
+using namespace ROCKETMQ_NAMESPACE;
 
 const std::string& alphaNumeric() {
   static std::string alpha_numeric("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
@@ -44,21 +49,11 @@ std::string randomString(std::string::size_type len) {
 }
 
 int main(int argc, char* argv[]) {
-  Logger& logger = getLogger();
-  logger.setLevel(Level::Debug);
-  logger.init();
-
-  DefaultMQProducer producer("TestGroup");
-
   const char* topic = "cpp_sdk_standard";
-  const char* name_server = "mq-inst-1080056302921134-bxuibml7.mq.cn-hangzhou.aliyuncs.com:80";
+  const char* name_server = "11.166.42.94:8081";
 
-  producer.setNamesrvAddr(name_server);
-  producer.compressBodyThreshold(256);
-  const char* resource_namespace = "MQ_INST_1080056302921134_BXuIbML7";
-  producer.setRegion("cn-hangzhou-pre");
-  producer.setResourceNamespace(resource_namespace);
-  producer.setCredentialsProvider(std::make_shared<ConfigFileCredentialsProvider>());
+  auto producer =
+      Producer::newBuilder().withConfiguration(Configuration::newBuilder().withEndpoints(name_server).build()).build();
 
   std::atomic_bool stopped;
   std::atomic_long count(0);
@@ -79,29 +74,40 @@ int main(int argc, char* argv[]) {
   std::string body = randomString(1024 * 4);
   std::cout << "Message body size: " << body.length() << std::endl;
 
+  std::size_t total = 256;
+  std::size_t completed = 0;
+  std::mutex mtx;
+  std::condition_variable cv;
+
   try {
-    producer.start();
-    for (int i = 0; i < 16; ++i) {
-      MQMessage message;
-      message.setTopic(topic);
-      message.setTags("TagA");
-      message.setKey("Yuck! Why-plural?");
-      message.setBody(body);
-
-      SendResult sendResult = producer.send(message);
-      std::cout << sendResult.getMessageQueue().simpleName() << ": " << sendResult.getMsgId() << std::endl;
+    auto send_callback = [&](const std::error_code& ec, const SendReceipt& receipt) {
+      std::unique_lock<std::mutex> lk(mtx);
+      completed++;
       count++;
-      std::this_thread::sleep_for(std::chrono::seconds(1));
+      std::cout << "Message[id=" << receipt.message_id << "] sent" << std::endl;
+      if (completed >= total) {
+        cv.notify_all();
+      }
+    };
+
+    for (std::size_t i = 0; i < total; ++i) {
+      auto message = Message::newBuilder().withTopic(topic).withTag("TagA").withKeys({"Key-0"}).withBody(body).build();
+      producer.send(std::move(message), send_callback);
+    }
+
+    {
+      std::unique_lock<std::mutex> lk(mtx);
+      cv.wait(lk, [&]() { return completed >= total; });
     }
   } catch (...) {
     std::cerr << "Ah...No!!!" << std::endl;
   }
-
   stopped.store(true, std::memory_order_relaxed);
   if (stats_thread.joinable()) {
     stats_thread.join();
   }
 
-  producer.shutdown();
+  std::this_thread::sleep_for(std::chrono::seconds(1));
+
   return EXIT_SUCCESS;
 }
\ No newline at end of file
diff --git a/example/rocketmq/ExampleFifoProducer.cpp b/examples/ExampleFifoProducer.cpp
similarity index 66%
rename from example/rocketmq/ExampleFifoProducer.cpp
rename to examples/ExampleFifoProducer.cpp
index c4d9e23..947ae5d 100644
--- a/example/rocketmq/ExampleFifoProducer.cpp
+++ b/examples/ExampleFifoProducer.cpp
@@ -14,13 +14,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include "rocketmq/DefaultMQProducer.h"
 #include <algorithm>
 #include <atomic>
 #include <iostream>
 #include <random>
+#include <system_error>
 
-using namespace rocketmq;
+#include "rocketmq/Message.h"
+#include "rocketmq/Producer.h"
+
+using namespace ROCKETMQ_NAMESPACE;
 
 const std::string& alphaNumeric() {
   static std::string alpha_numeric("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
@@ -44,21 +47,11 @@ std::string randomString(std::string::size_type len) {
 }
 
 int main(int argc, char* argv[]) {
-  Logger& logger = getLogger();
-  logger.setLevel(Level::Debug);
-  logger.init();
-
-  DefaultMQProducer producer("TestGroup");
-
-  const char* topic = "lingchu_test_order_topic";
-  const char* name_server = "120.25.100.131:8081";
+  const char* topic = "cpp_sdk_standard";
+  const char* name_server = "11.166.42.94:8081";
 
-  producer.setNamesrvAddr(name_server);
-  producer.compressBodyThreshold(256);
-  const char* resource_namespace = "MQ_INST_1080056302921134_BXyTLppt";
-  // producer.setRegion("cn-hangzhou-pre");
-  producer.setResourceNamespace(resource_namespace);
-  producer.setCredentialsProvider(std::make_shared<ConfigFileCredentialsProvider>());
+  auto producer =
+      Producer::newBuilder().withConfiguration(Configuration::newBuilder().withEndpoints(name_server).build()).build();
 
   std::atomic_bool stopped;
   std::atomic_long count(0);
@@ -80,19 +73,18 @@ int main(int argc, char* argv[]) {
   std::cout << "Message body size: " << body.length() << std::endl;
 
   try {
-    producer.start();
-    for (int i = 0; i < 16; ++i) {
-      std::string sharding_key = "sharding-key-" + std::to_string(i);
-      MQMessage message;
-      message.setTopic(topic);
-      message.setTags("TagA");
-      message.setKey("Yuck! Why-plural?");
-      message.setBody(body);
-
-      SendResult sendResult = producer.send(message, sharding_key);
-      std::cout << sendResult.getMessageQueue().simpleName() << ": " << sendResult.getMsgId() << std::endl;
+    for (int i = 0; i < 256; ++i) {
+      auto message = Message::newBuilder()
+                         .withTopic(topic)
+                         .withTag("TagA")
+                         .withKeys({"Key-0"})
+                         .withBody(body)
+                         .withGroup("message-group-0")
+                         .build();
+      std::error_code ec;
+      SendReceipt send_receipt = producer.send(std::move(message), ec);
+      std::cout << "Message-ID: " << send_receipt.message_id << std::endl;
       count++;
-      std::this_thread::sleep_for(std::chrono::seconds(1));
     }
   } catch (...) {
     std::cerr << "Ah...No!!!" << std::endl;
@@ -103,6 +95,5 @@ int main(int argc, char* argv[]) {
     stats_thread.join();
   }
 
-  producer.shutdown();
   return EXIT_SUCCESS;
 }
\ No newline at end of file
diff --git a/example/rocketmq/ExampleFifoPushConsumer.cpp b/examples/ExampleFifoPushConsumer.cpp
similarity index 100%
rename from example/rocketmq/ExampleFifoPushConsumer.cpp
rename to examples/ExampleFifoPushConsumer.cpp
diff --git a/example/rocketmq/ExampleProducer.cpp b/examples/ExampleProducer.cpp
similarity index 68%
rename from example/rocketmq/ExampleProducer.cpp
rename to examples/ExampleProducer.cpp
index 3e1cfc5..fa86af7 100644
--- a/example/rocketmq/ExampleProducer.cpp
+++ b/examples/ExampleProducer.cpp
@@ -14,13 +14,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include "rocketmq/DefaultMQProducer.h"
 #include <algorithm>
 #include <atomic>
 #include <iostream>
 #include <random>
+#include <system_error>
 
-using namespace rocketmq;
+#include "rocketmq/Message.h"
+#include "rocketmq/Producer.h"
+
+using namespace ROCKETMQ_NAMESPACE;
 
 const std::string& alphaNumeric() {
   static std::string alpha_numeric("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
@@ -44,21 +47,11 @@ std::string randomString(std::string::size_type len) {
 }
 
 int main(int argc, char* argv[]) {
-  Logger& logger = getLogger();
-  logger.setLevel(Level::Debug);
-  logger.init();
-
-  DefaultMQProducer producer("TestGroup");
-
   const char* topic = "cpp_sdk_standard";
-  const char* name_server = "mq-inst-1080056302921134-bxuibml7.mq.cn-hangzhou.aliyuncs.com:80";
+  const char* name_server = "11.166.42.94:8081";
 
-  producer.setNamesrvAddr(name_server);
-  producer.compressBodyThreshold(256);
-  const char* resource_namespace = "MQ_INST_1080056302921134_BXuIbML7";
-  producer.setRegion("cn-hangzhou-pre");
-  producer.setResourceNamespace(resource_namespace);
-  producer.setCredentialsProvider(std::make_shared<ConfigFileCredentialsProvider>());
+  auto producer =
+      Producer::newBuilder().withConfiguration(Configuration::newBuilder().withEndpoints(name_server).build()).build();
 
   std::atomic_bool stopped;
   std::atomic_long count(0);
@@ -80,28 +73,22 @@ int main(int argc, char* argv[]) {
   std::cout << "Message body size: " << body.length() << std::endl;
 
   try {
-    producer.start();
-    for (int i = 0; i < 16; ++i) {
-      MQMessage message;
-      message.setTopic(topic);
-      message.setTags("TagA");
-      message.setKey("Yuck! Why-plural?");
-      message.setBody(body);
-
-      SendResult sendResult = producer.send(message);
-      std::cout << sendResult.getMessageQueue().simpleName() << ": " << sendResult.getMsgId() << std::endl;
+    for (int i = 0; i < 256; ++i) {
+      auto message = Message::newBuilder().withTopic(topic).withTag("TagA").withKeys({"Key-0"}).withBody(body).build();
+      std::error_code ec;
+      SendReceipt send_receipt = producer.send(std::move(message), ec);
+      std::cout << "Message-ID: " << send_receipt.message_id << std::endl;
       count++;
-      std::this_thread::sleep_for(std::chrono::seconds(1));
     }
   } catch (...) {
     std::cerr << "Ah...No!!!" << std::endl;
   }
-
   stopped.store(true, std::memory_order_relaxed);
   if (stats_thread.joinable()) {
     stats_thread.join();
   }
 
-  producer.shutdown();
+  // std::this_thread::sleep_for(std::chrono::seconds(1));
+
   return EXIT_SUCCESS;
 }
\ No newline at end of file
diff --git a/example/rocketmq/ExampleTransactionProducer.cpp b/examples/ExamplePushConsumer.cpp
similarity index 51%
copy from example/rocketmq/ExampleTransactionProducer.cpp
copy to examples/ExamplePushConsumer.cpp
index 1041b92..00954ff 100644
--- a/example/rocketmq/ExampleTransactionProducer.cpp
+++ b/examples/ExamplePushConsumer.cpp
@@ -14,39 +14,37 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include "rocketmq/DefaultMQProducer.h"
-#include <cstdlib>
+#include <chrono>
+#include <iostream>
+#include <mutex>
+#include <thread>
+
+#include "rocketmq/Logger.h"
+#include "rocketmq/PushConsumer.h"
+#include "spdlog/spdlog.h"
 
 using namespace ROCKETMQ_NAMESPACE;
 
 int main(int argc, char* argv[]) {
-  DefaultMQProducer producer("TestGroup");
-
   const char* topic = "cpp_sdk_standard";
-  const char* name_server = "47.98.116.189:80";
-
-  producer.setNamesrvAddr(name_server);
-  producer.compressBodyThreshold(256);
-  const char* resource_namespace = "MQ_INST_1080056302921134_BXuIbML7";
-  producer.setRegion("cn-hangzhou-pre");
-  producer.setResourceNamespace(resource_namespace);
-  producer.setCredentialsProvider(std::make_shared<ConfigFileCredentialsProvider>());
-
-  MQMessage message;
-  message.setTopic(topic);
-  message.setTags("TagA");
-  message.setKey("Yuck! Why-plural?");
-  message.setBody("ABC");
-
-  producer.start();
-
-  auto transaction = producer.prepare(message);
-
-  transaction->commit();
+  const char* name_server = "11.166.42.94:8081";
+  const char* group = "GID_cpp_sdk_standard";
+  std::string tag = "*";
+
+  auto listener = [](const Message& message) { return ConsumeResult::SUCCESS; };
+
+  auto push_consumer = PushConsumer::newBuilder()
+                           .withGroup(group)
+                           .withConfiguration(Configuration::newBuilder()
+                                                  .withEndpoints(name_server)
+                                                  .withRequestTimeout(std::chrono::seconds(3))
+                                                  .build())
+                           .withConsumeThreads(4)
+                           .withListener(listener)
+                           .subscribe(topic, tag)
+                           .build();
 
   std::this_thread::sleep_for(std::chrono::minutes(30));
 
-  producer.shutdown();
-
   return EXIT_SUCCESS;
-}
\ No newline at end of file
+}
diff --git a/examples/ExampleSimpleConsumer.cpp b/examples/ExampleSimpleConsumer.cpp
new file mode 100644
index 0000000..dc76718
--- /dev/null
+++ b/examples/ExampleSimpleConsumer.cpp
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+#include <chrono>
+#include <iostream>
+#include <thread>
+
+#include "rocketmq/SimpleConsumer.h"
+
+using namespace ROCKETMQ_NAMESPACE;
+
+int main(int argc, char* argv[]) {
+  const char* group = "ExampleSimpleGroup";
+  const char* topic = "cpp_sdk_standard";
+  const char* name_server = "11.166.42.94:8081";
+  std::string tag = "*";
+
+  auto simple_consumer = SimpleConsumer::newBuilder()
+                             .withGroup(group)
+                             .withConfiguration(Configuration::newBuilder().withEndpoints(name_server).build())
+                             .subscribe(topic, tag)
+                             .build();
+  std::vector<MessageConstSharedPtr> messages;
+  std::error_code ec;
+  simple_consumer.receive(4, std::chrono::seconds(3), ec, messages);
+
+  if (ec) {
+    std::cerr << "Failed to receive messages. Cause: " << ec.message() << std::endl;
+    return EXIT_FAILURE;
+  }
+
+  std::cout << "Received " << messages.size() << " messages" << std::endl;
+  std::size_t i = 0;
+  for (const auto& message : messages) {
+    std::cout << "Received a message[topic=" << message->topic() << ", message-id=" << message->id()
+              << ", receipt-handle='" << message->extension().receipt_handle << "']" << std::endl;
+
+    std::error_code ec;
+    if (++i % 2 == 0) {
+      simple_consumer.ack(*message, ec);
+      if (ec) {
+        std::cerr << "Failed to ack message. Cause: " << ec.message() << std::endl;
+      }
+    } else {
+      simple_consumer.changeInvisibleDuration(*message, std::chrono::milliseconds(100), ec);
+      if (ec) {
+        std::cerr << "Failed to change invisible duration of message. Cause: " << ec.message() << std::endl;
+      }
+    }
+  }
+
+  return EXIT_SUCCESS;
+}
\ No newline at end of file
diff --git a/example/rocketmq/ExampleTransactionProducer.cpp b/examples/ExampleTransactionProducer.cpp
similarity index 100%
rename from example/rocketmq/ExampleTransactionProducer.cpp
rename to examples/ExampleTransactionProducer.cpp
diff --git a/example/rocketmq/PushConsumerWithCustomExecutor.cpp b/examples/PushConsumerWithCustomExecutor.cpp
similarity index 100%
rename from example/rocketmq/PushConsumerWithCustomExecutor.cpp
rename to examples/PushConsumerWithCustomExecutor.cpp
diff --git a/example/rocketmq/PushConsumerWithThrottle.cpp b/examples/PushConsumerWithThrottle.cpp
similarity index 100%
rename from example/rocketmq/PushConsumerWithThrottle.cpp
rename to examples/PushConsumerWithThrottle.cpp
diff --git a/example/rocketmq/SqlConsumer.cpp b/examples/SqlConsumer.cpp
similarity index 100%
rename from example/rocketmq/SqlConsumer.cpp
rename to examples/SqlConsumer.cpp
diff --git a/example/rocketmq/SqlProducer.cpp b/examples/SqlProducer.cpp
similarity index 100%
rename from example/rocketmq/SqlProducer.cpp
rename to examples/SqlProducer.cpp
diff --git a/proto/BUILD.bazel b/proto/BUILD.bazel
index 3416bf4..80a2b6d 100644
--- a/proto/BUILD.bazel
+++ b/proto/BUILD.bazel
@@ -21,7 +21,7 @@ load("@rules_proto_grpc//cpp:defs.bzl", "cpp_grpc_library", "cpp_grpc_compile")
 proto_library(
     name = "apache_rocketmq_definition",
     srcs = [
-        "apache/rocketmq/v1/definition.proto",
+        "apache/rocketmq/v2/definition.proto",
     ],
     deps = [
         "@com_google_protobuf//:empty_proto",
@@ -38,7 +38,7 @@ proto_library(
 proto_library(
     name = "apache_rocketmq_admin",
     srcs = [
-        "apache/rocketmq/v1/admin.proto",
+        "apache/rocketmq/v2/admin.proto",
     ],
     deps = [
         ":apache_rocketmq_definition",
@@ -51,7 +51,7 @@ proto_library(
 proto_library(
     name = "apache_rocketmq_service",
     srcs = [
-        "apache/rocketmq/v1/service.proto",
+        "apache/rocketmq/v2/service.proto",
     ],
     deps = [
         ":apache_rocketmq_definition",
diff --git a/proto/apache/rocketmq/v1/definition.proto b/proto/apache/rocketmq/v1/definition.proto
deleted file mode 100644
index b6cb24b..0000000
--- a/proto/apache/rocketmq/v1/definition.proto
+++ /dev/null
@@ -1,349 +0,0 @@
-// 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/timestamp.proto";
-import "google/protobuf/duration.proto";
-
-package apache.rocketmq.v1;
-
-option java_multiple_files = true;
-option java_package = "apache.rocketmq.v1";
-option java_generate_equals_and_hash = true;
-option java_string_check_utf8 = true;
-option java_outer_classname = "MQDomain";
-
-enum Permission {
-  NONE = 0;
-  READ = 1;
-  WRITE = 2;
-  READ_WRITE = 3;
-
-  reserved 4 to 64;
-}
-
-enum FilterType {
-  TAG = 0;
-  SQL = 1;
-
-  reserved 2 to 64;
-}
-
-message FilterExpression {
-  FilterType type = 1;
-  string expression = 2;
-
-  reserved 3 to 64;
-}
-
-// Dead lettering is done on a best effort basis. The same message might be
-// dead lettered multiple times.
-//
-// If validation on any of the fields fails at subscription creation/update,
-// the create/update subscription request will fail.
-message DeadLetterPolicy {
-  // The maximum number of delivery attempts for any message.
-  //
-  // This field will be honored on a best effort basis.
-  //
-  // If this parameter is 0, a default value of 16 is used.
-  int32 max_delivery_attempts = 1;
-
-  reserved 2 to 64;
-}
-
-message Resource {
-  string resource_namespace = 1;
-
-  // Resource name identifier, which remains unique within the abstract resource
-  // namespace.
-  string name = 2;
-
-  reserved 3 to 64;
-}
-
-enum ConsumeModel {
-  CLUSTERING = 0;
-  BROADCASTING = 1;
-
-  reserved 2 to 64;
-}
-
-message ProducerData {
-  Resource group = 1;
-
-  reserved 2 to 64;
-}
-
-enum ConsumePolicy {
-  RESUME = 0;
-  PLAYBACK = 1;
-  DISCARD = 2;
-  TARGET_TIMESTAMP = 3;
-
-  reserved 4 to 64;
-}
-
-enum ConsumeMessageType {
-  ACTIVE = 0;
-  PASSIVE = 1;
-
-  reserved 2 to 64;
-}
-
-message ConsumerData {
-  Resource group = 1;
-
-  repeated SubscriptionEntry subscriptions = 2;
-
-  ConsumeModel consume_model = 3;
-
-  ConsumePolicy consume_policy = 4;
-
-  DeadLetterPolicy dead_letter_policy = 5;
-
-  ConsumeMessageType consume_type = 6;
-
-  reserved 7 to 64;
-}
-
-message SubscriptionEntry {
-  Resource topic = 1;
-  FilterExpression expression = 2;
-
-  reserved 3 to 64;
-}
-
-enum AddressScheme {
-  IPv4 = 0;
-  IPv6 = 1;
-  DOMAIN_NAME = 2;
-
-  reserved 3 to 64;
-}
-
-message Address {
-  string host = 1;
-  int32 port = 2;
-
-  reserved 3 to 64;
-}
-
-message Endpoints {
-  AddressScheme scheme = 1;
-  repeated Address addresses = 2;
-
-  reserved 3 to 64;
-}
-
-message Broker {
-  // Name of the broker
-  string name = 1;
-
-  // Broker index. Canonically, index = 0 implies that the broker is playing
-  // leader role while brokers with index > 0 play follower role.
-  int32 id = 2;
-
-  // Address of the broker, complying with the following scheme
-  // 1. dns:[//authority/]host[:port]
-  // 2. ipv4:address[:port][,address[:port],...] – IPv4 addresses
-  // 3. ipv6:address[:port][,address[:port],...] – IPv6 addresses
-  Endpoints endpoints = 3;
-
-  reserved 4 to 64;
-}
-
-message Partition {
-  Resource topic = 1;
-  int32 id = 2;
-  Permission permission = 3;
-  Broker broker = 4;
-
-  reserved 5 to 64;
-}
-
-enum MessageType {
-  NORMAL = 0;
-
-  // Sequenced message
-  FIFO = 1;
-
-  // Messages that are delivered after the specified duration.
-  DELAY = 2;
-
-  // Messages that are transactional. Only committed messages are delivered to
-  // subscribers.
-  TRANSACTION = 3;
-
-  reserved 4 to 64;
-}
-
-enum DigestType {
-  // CRC algorithm achieves goal of detecting random data error with lowest
-  // computation overhead.
-  CRC32 = 0;
-
-  // MD5 algorithm achieves good balance between collision rate and computation
-  // overhead.
-  MD5 = 1;
-
-  // SHA-family has substantially fewer collision with fair amount of
-  // computation.
-  SHA1 = 2;
-
-  reserved 3 to 64;
-}
-
-// When publishing messages to or subscribing messages from brokers, clients
-// shall include or validate digests of message body to ensure data integrity.
-//
-// For message publishment, when an invalid digest were detected, brokers need
-// respond client with BAD_REQUEST.
-//
-// For messags subscription, when an invalid digest were detected, consumers
-// need to handle this case according to message type:
-// 1) Standard messages should be negatively acknowledged instantly, causing
-// immediate re-delivery; 2) FIFO messages require special RPC, to re-fetch
-// previously acquired messages batch;
-//
-// Message consumption model also affects how invalid digest are handled. When
-// messages are consumed in broadcasting way,
-// TODO: define semantics of invalid-digest-when-broadcasting.
-message Digest {
-  DigestType type = 1;
-  string checksum = 2;
-
-  reserved 3 to 64;
-}
-
-enum Encoding {
-  IDENTITY = 0;
-  GZIP = 1;
-
-  reserved 2 to 64;
-}
-
-message SystemAttribute {
-  // Tag
-  string tag = 1;
-
-  // Message keys
-  repeated string keys = 2;
-
-  // Message identifier, client-side generated, remains unique.
-  // if message_id is empty, the send message request will be aborted with
-  // status `INVALID_ARGUMENT`
-  string message_id = 3;
-
-  // Message body digest
-  Digest body_digest = 4;
-
-  // Message body encoding. Candidate options are identity, gzip, snappy etc.
-  Encoding body_encoding = 5;
-
-  // Message type, normal, FIFO or transactional.
-  MessageType message_type = 6;
-
-  // Message born time-point.
-  google.protobuf.Timestamp born_timestamp = 7;
-
-  // Message born host. Valid options are IPv4, IPv6 or client host domain name.
-  string born_host = 8;
-
-  // Time-point at which the message is stored in the broker.
-  google.protobuf.Timestamp store_timestamp = 9;
-
-  // The broker that stores this message. It may be name, IP or arbitrary
-  // identifier that uniquely identify the broker.
-  string store_host = 10;
-
-  oneof timed_delivery {
-    // Time-point at which broker delivers to clients.
-    google.protobuf.Timestamp delivery_timestamp = 11;
-
-    // Level-based delay strategy.
-    int32 delay_level = 12;
-  }
-
-  // If a message is acquired by way of POP, this field holds the receipt.
-  // Clients use the receipt to acknowledge or negatively acknowledge the
-  // message.
-  string receipt_handle = 13;
-
-  // Partition identifier in which a message is physically stored.
-  int32 partition_id = 14;
-
-  // Partition offset at which a message is stored.
-  int64 partition_offset = 15;
-
-  // Period of time servers would remain invisible once a message is acquired.
-  google.protobuf.Duration invisible_period = 16;
-
-  // Business code may failed to process messages for the moment. Hence, clients
-  // may request servers to deliver them again using certain back-off strategy,
-  // the attempt is 1 not 0 if message is delivered first time.
-  int32 delivery_attempt = 17;
-
-  // Message producer load-balance group if applicable.
-  Resource producer_group = 18;
-
-  string message_group = 19;
-
-  // Trace context.
-  string trace_context = 20;
-
-  // Delay time of first recover orphaned transaction request from server.
-  google.protobuf.Duration orphaned_transaction_recovery_period = 21;
-
-  reserved 22 to 64;
-}
-
-message Message {
-
-  Resource topic = 1;
-
-  // User defined key-value pairs.
-  // If user_attribute contains the reserved keys by RocketMQ,
-  // the send message request will be aborted with status `INVALID_ARGUMENT`.
-  // See below links for the reserved keys
-  // https://github.com/apache/rocketmq/blob/master/common/src/main/java/org/apache/rocketmq/common/message/MessageConst.java#L58
-  map<string, string> user_attribute = 2;
-
-  SystemAttribute system_attribute = 3;
-
-  bytes body = 4;
-
-  reserved 5 to 64;
-}
-
-message Assignment {
-  Partition Partition = 1;
-
-  reserved 2 to 64;
-}
-
-enum QueryOffsetPolicy {
-  // Use this option if client wishes to playback all existing messages.
-  BEGINNING = 0;
-
-  // Use this option if client wishes to skip all existing messages.
-  END = 1;
-
-  // Use this option if time-based seek is targeted.
-  TIME_POINT = 2;
-
-  reserved 3 to 64;
-}
\ No newline at end of file
diff --git a/proto/apache/rocketmq/v1/service.proto b/proto/apache/rocketmq/v1/service.proto
deleted file mode 100644
index 9d8e3b0..0000000
--- a/proto/apache/rocketmq/v1/service.proto
+++ /dev/null
@@ -1,531 +0,0 @@
-// 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 "google/rpc/error_details.proto";
-import "google/rpc/status.proto";
-
-import "apache/rocketmq/v1/definition.proto";
-
-package apache.rocketmq.v1;
-
-option java_multiple_files = true;
-option java_package = "apache.rocketmq.v1";
-option java_generate_equals_and_hash = true;
-option java_string_check_utf8 = true;
-option java_outer_classname = "MQService";
-
-message ResponseCommon {
-  google.rpc.Status status = 1;
-  google.rpc.RequestInfo request_info = 2;
-  google.rpc.Help help = 3;
-  google.rpc.RetryInfo retry_info = 4;
-  google.rpc.DebugInfo debug_info = 5;
-  google.rpc.ErrorInfo error_info = 6;
-
-  reserved 7 to 64;
-}
-
-// 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 auxillary 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 partitions, 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;
-
-  reserved 3 to 64;
-}
-
-message QueryRouteResponse {
-  ResponseCommon common = 1;
-
-  repeated Partition partitions = 2;
-
-  reserved 3 to 64;
-}
-
-message SendMessageRequest {
-  Message message = 1;
-  Partition partition = 2;
-
-  reserved 3 to 64;
-}
-
-message SendMessageResponse {
-  ResponseCommon common = 1;
-  string message_id = 2;
-  string transaction_id = 3;
-
-  reserved 4 to 64;
-}
-
-message QueryAssignmentRequest {
-  Resource topic = 1;
-  Resource group = 2;
-  string client_id = 3;
-
-  // Service access point
-  Endpoints endpoints = 4;
-
-  reserved 5 to 64;
-}
-
-message QueryAssignmentResponse {
-  ResponseCommon common = 1;
-  repeated Assignment assignments = 2;
-
-  reserved 3 to 64;
-}
-
-message ReceiveMessageRequest {
-  Resource group = 1;
-  string client_id = 2;
-  Partition partition = 3;
-  FilterExpression filter_expression = 4;
-  ConsumePolicy consume_policy = 5;
-  google.protobuf.Timestamp initialization_timestamp = 6;
-  int32 batch_size = 7;
-  google.protobuf.Duration invisible_duration = 8;
-  google.protobuf.Duration await_time = 9;
-  bool fifo_flag = 10;
-
-  reserved 11 to 64;
-}
-
-message ReceiveMessageResponse {
-  ResponseCommon common = 1;
-  repeated Message messages = 2;
-  google.protobuf.Timestamp delivery_timestamp = 3;
-  google.protobuf.Duration invisible_duration = 4;
-
-  reserved 5 to 64;
-}
-
-message AckMessageRequest {
-  Resource group = 1;
-  Resource topic = 2;
-  string client_id = 3;
-  oneof handle {
-    string receipt_handle = 4;
-    int64 offset = 5;
-  }
-  string message_id = 6;
-
-  reserved 7 to 64;
-}
-
-message AckMessageResponse {
-  ResponseCommon common = 1;
-
-  reserved 2 to 64;
-}
-
-message NackMessageRequest {
-  Resource group = 1;
-  Resource topic = 2;
-  string client_id = 3;
-  string receipt_handle = 4;
-  string message_id = 5;
-  int32 delivery_attempt = 6;
-  int32 max_delivery_attempts = 7;
-
-  reserved 8 to 64;
-}
-
-message NackMessageResponse {
-  ResponseCommon common = 1;
-
-  reserved 2 to 64;
-}
-
-message ForwardMessageToDeadLetterQueueRequest {
-  Resource group = 1;
-  Resource topic = 2;
-  string client_id = 3;
-  string receipt_handle = 4;
-  string message_id = 5;
-  int32 delivery_attempt = 6;
-  int32 max_delivery_attempts = 7;
-
-  reserved 8 to 64;
-}
-
-message ForwardMessageToDeadLetterQueueResponse {
-  ResponseCommon common = 1;
-
-  reserved 2 to 64;
-}
-
-message HeartbeatRequest {
-  string client_id = 1;
-  oneof client_data {
-    ProducerData producer_data = 2;
-    ConsumerData consumer_data = 3;
-  }
-  bool fifo_flag = 4;
-
-  reserved 5 to 64;
-}
-
-message HeartbeatResponse {
-  ResponseCommon common = 1;
-
-  reserved 2 to 64;
-}
-
-message HealthCheckRequest {
-  Resource group = 1;
-  string client_host = 2;
-
-  reserved 3 to 64;
-}
-
-message HealthCheckResponse {
-  ResponseCommon common = 1;
-
-  reserved 2 to 64;
-}
-
-message EndTransactionRequest {
-  Resource group = 1;
-  string message_id = 2;
-  string transaction_id = 3;
-  enum TransactionResolution {
-    COMMIT = 0;
-    ROLLBACK = 1;
-  }
-  TransactionResolution resolution = 4;
-  enum Source {
-    CLIENT = 0;
-    SERVER_CHECK = 1;
-  }
-  Source source = 5;
-  string trace_context = 6;
-
-  reserved 7 to 64;
-}
-
-message EndTransactionResponse {
-  ResponseCommon common = 1;
-
-  reserved 2 to 64;
-}
-
-message QueryOffsetRequest {
-  Partition partition = 1;
-  QueryOffsetPolicy policy = 2;
-  google.protobuf.Timestamp time_point = 3;
-
-  reserved 4 to 64;
-}
-
-message QueryOffsetResponse {
-  ResponseCommon common = 1;
-  int64 offset = 2;
-
-  reserved 3 to 64;
-}
-
-message PullMessageRequest {
-  Resource group = 1;
-  Partition partition = 2;
-  int64 offset = 3;
-  int32 batch_size = 4;
-  google.protobuf.Duration await_time = 5;
-  FilterExpression filter_expression = 6;
-  string client_id = 7;
-
-  reserved 8 to 64;
-}
-
-message PullMessageResponse {
-  ResponseCommon common = 1;
-  int64 min_offset = 2;
-  int64 next_offset = 3;
-  int64 max_offset = 4;
-  repeated Message messages = 5;
-
-  reserved 6 to 64;
-}
-
-message NoopCommand {
-  reserved 1 to 64;
-}
-
-message PrintThreadStackTraceCommand {
-  string command_id = 1;
-
-  reserved 2 to 64;
-}
-
-message ReportThreadStackTraceRequest {
-  string command_id = 1;
-  string thread_stack_trace = 2;
-
-  reserved 3 to 64;
-}
-
-message ReportThreadStackTraceResponse {
-  ResponseCommon common = 1;
-
-  reserved 2 to 64;
-}
-
-message VerifyMessageConsumptionCommand {
-  string command_id = 1;
-  Message message = 2;
-
-  reserved 3 to 64;
-}
-
-message ReportMessageConsumptionResultRequest {
-  string command_id = 1;
-  google.rpc.Status status = 2;
-
-  reserved 3 to 64;
-}
-
-message ReportMessageConsumptionResultResponse {
-  ResponseCommon common = 1;
-
-  reserved 2 to 64;
-}
-
-message RecoverOrphanedTransactionCommand {
-  Message orphaned_transactional_message = 1;
-  string transaction_id = 2;
-
-  reserved 3 to 64;
-}
-
-message PollCommandRequest {
-  string client_id = 1;
-  repeated Resource topics = 2;
-  oneof group {
-    Resource producer_group = 3;
-    Resource consumer_group = 4;
-  }
-
-  reserved 5 to 64;
-}
-
-message PollCommandResponse {
-  oneof type {
-    // Default command when no new command need to be delivered.
-    NoopCommand noop_command = 1;
-    // Request client to print thread stack trace.
-    PrintThreadStackTraceCommand print_thread_stack_trace_command = 2;
-    // Request client to verify the consumption of the appointed message.
-    VerifyMessageConsumptionCommand verify_message_consumption_command = 3;
-    // Request client to recover the orphaned transaction message.
-    RecoverOrphanedTransactionCommand recover_orphaned_transaction_command = 4;
-  }
-
-  reserved 5 to 64;
-}
-
-message NotifyClientTerminationRequest {
-  oneof group {
-    Resource producer_group = 1;
-    Resource consumer_group = 2;
-  }
-  string client_id = 3;
-
-  reserved 4 to 64;
-}
-
-message NotifyClientTerminationResponse {
-  ResponseCommon common = 1;
-
-  reserved 2 to 64;
-}
-
-// 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 {
-
-  // Querys the route entries of the requested topic in the perspective of the
-  // given endpoints. On success, servers should return a collection of
-  // addressable partitions. 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 emtpy, 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) {
-  }
-
-  // Checks the health status of message server, returns `OK` if services are
-  // online and serving. Clients may use this RPC to detect availability of
-  // messaging service, and take isolation actions when necessary.
-  rpc HealthCheck(HealthCheckRequest) returns (HealthCheckResponse) {
-  }
-
-  // Delivers messages to brokers.
-  // Clients may further:
-  // 1. Refine a message destination to topic partition 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) {
-  }
-
-  // Querys the assigned partition route info of a topic for current consumer,
-  // the returned assignment result is descided by server-side load balacner.
-  //
-  // If the corresponding topic doesn't exist, returns `NOT_FOUND`.
-  // If the specific endpoints is emtpy, 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 uacked 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.
-  rpc ReceiveMessage(ReceiveMessageRequest) returns (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) {
-  }
-
-  // Signals that the message has not been successfully processed. The message
-  // server should resend the message follow the retry policy defined at
-  // server-side.
-  //
-  // If the corresponding topic or consumer group doesn't exist, returns
-  // `NOT_FOUND`.
-  rpc NackMessage(NackMessageRequest) returns (NackMessageResponse) {
-  }
-
-  // Forwards one message to dead letter queue if the DeadLetterPolicy is
-  // triggered 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) {
-  }
-
-  // Querys the offset of the specific partition, returns the offset with `OK`
-  // if success. The message server should maintain a numerical offset for each
-  // message in a parition.
-  rpc QueryOffset(QueryOffsetRequest) returns (QueryOffsetResponse) {
-  }
-
-  // Pulls messages from the specific partition, returns a set of messages with
-  // next pull offset. The pulled messages can't be acked or nacked, while the
-  // client is responsible for manage offesets for consumer, typically update
-  // consume offset to local memory or a third-party storage service.
-  //
-  // 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.
-  rpc PullMessage(PullMessageRequest) returns (PullMessageResponse) {
-  }
-
-  // Multiplexing RPC(s) for various polling requests, which issue different
-  // commands to client.
-  //
-  // Sometimes client may need to receive and process the command from server.
-  // To prevent the complexity of streaming RPC(s), a unary RPC using
-  // long-polling is another solution.
-  //
-  // To mark the request-response of corresponding command, `command_id` in
-  // message is recorded in the subsequent RPC(s). For example, after receiving
-  // command of printing thread stack trace, client would send
-  // `ReportMessageConsumptionResultRequest` to server, which contain both of
-  // the stack trace and `command_id`.
-  //
-  // At same time, `NoopCommand` is delivered from server when no new command is
-  // needed, it is essential for client to maintain the ping-pong.
-  //
-  rpc PollCommand(PollCommandRequest) returns (PollCommandResponse) {
-  }
-
-  // After receiving the corresponding polling command, the thread stack trace
-  // is reported to the server.
-  rpc ReportThreadStackTrace(ReportThreadStackTraceRequest) returns (ReportThreadStackTraceResponse) {
-  }
-
-  // After receiving the corresponding polling command, the consumption result
-  // of appointed message is reported to the server.
-  rpc ReportMessageConsumptionResult(ReportMessageConsumptionResultRequest)
-      returns (ReportMessageConsumptionResultResponse) {
-  }
-
-  // Notify the server that the client is terminated.
-  rpc NotifyClientTermination(NotifyClientTerminationRequest) returns (NotifyClientTerminationResponse) {
-  }
-}
\ No newline at end of file
diff --git a/proto/apache/rocketmq/v1/admin.proto b/proto/apache/rocketmq/v2/admin.proto
similarity index 86%
rename from proto/apache/rocketmq/v1/admin.proto
rename to proto/apache/rocketmq/v2/admin.proto
index 554207b..7dbb702 100644
--- a/proto/apache/rocketmq/v1/admin.proto
+++ b/proto/apache/rocketmq/v2/admin.proto
@@ -15,11 +15,12 @@
 
 syntax = "proto3";
 
-package apache.rocketmq.v1;
+package apache.rocketmq.v2;
 
 option cc_enable_arenas = true;
+option csharp_namespace = "Apache.Rocketmq.V2";
 option java_multiple_files = true;
-option java_package = "apache.rocketmq.v1";
+option java_package = "apache.rocketmq.v2";
 option java_generate_equals_and_hash = true;
 option java_string_check_utf8 = true;
 option java_outer_classname = "MQAdmin";
@@ -35,11 +36,8 @@ message ChangeLogLevelRequest {
   Level level = 1;
 }
 
-message ChangeLogLevelResponse {
-  string remark = 1;
-}
+message ChangeLogLevelResponse { string remark = 1; }
 
 service Admin {
-  rpc ChangeLogLevel(ChangeLogLevelRequest) returns (ChangeLogLevelResponse) {
-  }
+  rpc ChangeLogLevel(ChangeLogLevelRequest) returns (ChangeLogLevelResponse) {}
 }
\ No newline at end of file
diff --git a/proto/apache/rocketmq/v2/definition.proto b/proto/apache/rocketmq/v2/definition.proto
new file mode 100644
index 0000000..6565a21
--- /dev/null
+++ b/proto/apache/rocketmq/v2/definition.proto
@@ -0,0 +1,447 @@
+// 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/timestamp.proto";
+import "google/protobuf/duration.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 = "MQDomain";
+
+enum TransactionResolution {
+  TRANSACTION_RESOLUTION_UNSPECIFIED = 0;
+  COMMIT = 1;
+  ROLLBACK = 2;
+}
+
+enum TransactionSource {
+  SOURCE_UNSPECIFIED = 0;
+  SOURCE_CLIENT = 1;
+  SOURCE_SERVER_CHECK = 2;
+}
+
+enum Permission {
+  PERMISSION_UNSPECIFIED = 0;
+  NONE = 1;
+  READ = 2;
+  WRITE = 3;
+  READ_WRITE = 4;
+}
+
+enum FilterType {
+  FILTER_TYPE_UNSPECIFIED = 0;
+  TAG = 1;
+  SQL = 2;
+}
+
+message FilterExpression {
+  FilterType type = 1;
+  string expression = 2;
+}
+
+message RetryPolicy {
+  int32 max_attempts = 1;
+  oneof strategy {
+    ExponentialBackoff exponential_backoff = 2;
+    CustomizedBackoff customized_backoff = 3;
+  }
+}
+
+// https://en.wikipedia.org/wiki/Exponential_backoff
+message ExponentialBackoff {
+  google.protobuf.Duration initial = 1;
+  google.protobuf.Duration max = 2;
+  float multiplier = 3;
+}
+
+message CustomizedBackoff {
+  // To support classic backoff strategy which is arbitary defined by end users.
+  // Typical values are: `1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h`
+  repeated google.protobuf.Duration next = 1;
+}
+
+message Resource {
+  string resource_namespace = 1;
+
+  // Resource name identifier, which remains unique within the abstract resource
+  // namespace.
+  string name = 2;
+}
+
+message SubscriptionEntry {
+  Resource topic = 1;
+  FilterExpression expression = 2;
+}
+
+enum AddressScheme {
+  ADDRESS_SCHEME_UNSPECIFIED = 0;
+  IPv4 = 1;
+  IPv6 = 2;
+  DOMAIN_NAME = 3;
+}
+
+message Address {
+  string host = 1;
+  int32 port = 2;
+}
+
+message Endpoints {
+  AddressScheme scheme = 1;
+  repeated Address addresses = 2;
+}
+
+message Broker {
+  // Name of the broker
+  string name = 1;
+
+  // Broker index. Canonically, index = 0 implies that the broker is playing
+  // leader role while brokers with index > 0 play follower role.
+  int32 id = 2;
+
+  // Address of the broker, complying with the following scheme
+  // 1. dns:[//authority/]host[:port]
+  // 2. ipv4:address[:port][,address[:port],...] – IPv4 addresses
+  // 3. ipv6:address[:port][,address[:port],...] – IPv6 addresses
+  Endpoints endpoints = 3;
+}
+
+message MessageQueue {
+  Resource topic = 1;
+  int32 id = 2;
+  Permission permission = 3;
+  Broker broker = 4;
+  repeated MessageType accept_message_types = 5;
+}
+
+enum MessageType {
+  MESSAGE_TYPE_UNSPECIFIED = 0;
+
+  NORMAL = 1;
+
+  // Sequenced message
+  FIFO = 2;
+
+  // Messages that are delivered after the specified duration.
+  DELAY = 3;
+
+  // Messages that are transactional. Only committed messages are delivered to
+  // subscribers.
+  TRANSACTION = 4;
+}
+
+enum DigestType {
+  DIGEST_TYPE_UNSPECIFIED = 0;
+
+  // CRC algorithm achieves goal of detecting random data error with lowest
+  // computation overhead.
+  CRC32 = 1;
+
+  // MD5 algorithm achieves good balance between collision rate and computation
+  // overhead.
+  MD5 = 2;
+
+  // SHA-family has substantially fewer collision with fair amount of
+  // computation.
+  SHA1 = 3;
+}
+
+// When publishing messages to or subscribing messages from brokers, clients
+// shall include or validate digests of message body to ensure data integrity.
+//
+// For message publishing, when an invalid digest were detected, brokers need
+// respond client with BAD_REQUEST.
+//
+// For messages subscription, when an invalid digest were detected, consumers
+// need to handle this case according to message type:
+// 1) Standard messages should be negatively acknowledged instantly, causing
+// immediate re-delivery; 2) FIFO messages require special RPC, to re-fetch
+// previously acquired messages batch;
+//
+// Message consumption model also affects how invalid digest are handled. When
+// messages are consumed in broadcasting way,
+// TODO: define semantics of invalid-digest-when-broadcasting.
+message Digest {
+  DigestType type = 1;
+  string checksum = 2;
+}
+
+enum ClientType {
+  CLIENT_TYPE_UNSPECIFIED = 0;
+  PRODUCER = 1;
+  PUSH_CONSUMER = 2;
+  SIMPLE_CONSUMER = 3;
+}
+
+enum Encoding {
+  ENCODING_UNSPECIFIED = 0;
+
+  IDENTITY = 1;
+
+  GZIP = 2;
+}
+
+message SystemProperties {
+  // Tag, which is optional.
+  optional string tag = 1;
+
+  // Message keys
+  repeated string keys = 2;
+
+  // Message identifier, client-side generated, remains unique.
+  // if message_id is empty, the send message request will be aborted with
+  // status `INVALID_ARGUMENT`
+  string message_id = 3;
+
+  // Message body digest
+  Digest body_digest = 4;
+
+  // Message body encoding. Candidate options are identity, gzip, snappy etc.
+  Encoding body_encoding = 5;
+
+  // Message type, normal, FIFO or transactional.
+  MessageType message_type = 6;
+
+  // Message born time-point.
+  google.protobuf.Timestamp born_timestamp = 7;
+
+  // Message born host. Valid options are IPv4, IPv6 or client host domain name.
+  string born_host = 8;
+
+  // Time-point at which the message is stored in the broker, which is absent
+  // for message publishing.
+  optional google.protobuf.Timestamp store_timestamp = 9;
+
+  // The broker that stores this message. It may be broker name, IP or arbitrary
+  // identifier that uniquely identify the server.
+  string store_host = 10;
+
+  // Time-point at which broker delivers to clients, which is optional.
+  optional google.protobuf.Timestamp delivery_timestamp = 11;
+
+  // If a message is acquired by way of POP, this field holds the receipt,
+  // which is absent for message publishing.
+  // Clients use the receipt to acknowledge or negatively acknowledge the
+  // message.
+  optional string receipt_handle = 12;
+
+  // Message queue identifier in which a message is physically stored.
+  int32 queue_id = 13;
+
+  // Message-queue offset at which a message is stored, which is absent for
+  // message publishing.
+  optional int64 queue_offset = 14;
+
+  // Period of time servers would remain invisible once a message is acquired.
+  optional google.protobuf.Duration invisible_duration = 15;
+
+  // Business code may failed to process messages for the moment. Hence, clients
+  // may request servers to deliver them again using certain back-off strategy,
+  // the attempt is 1 not 0 if message is delivered first time, and it is absent
+  // for message publishing.
+  optional int32 delivery_attempt = 16;
+
+  // Define the group name of message in the same topic, which is optional.
+  optional string message_group = 17;
+
+  // Trace context for each message, which is optional.
+  optional string trace_context = 18;
+
+  // If a transactional message stay unresolved for more than
+  // `transaction_orphan_threshold`, it would be regarded as an
+  // orphan. Servers that manages orphan messages would pick up
+  // a capable publisher to resolve
+  optional google.protobuf.Duration orphaned_transaction_recovery_duration = 19;
+}
+
+message Message {
+  Resource topic = 1;
+
+  // User defined key-value pairs.
+  // If user_properties contain the reserved keys by RocketMQ,
+  // the send message request will be aborted with status `INVALID_ARGUMENT`.
+  // See below links for the reserved keys
+  // https://github.com/apache/rocketmq/blob/master/common/src/main/java/org/apache/rocketmq/common/message/MessageConst.java#L58
+  map<string, string> user_properties = 2;
+
+  SystemProperties system_properties = 3;
+
+  bytes body = 4;
+}
+
+message Assignment {
+  MessageQueue message_queue = 1;
+}
+
+message SendReceipt {
+  string message_id = 1;
+  string transaction_id = 2;
+  int64 offset = 3;
+}
+
+enum Code {
+  // Success.
+  OK = 0;
+  // Format of access point is illegal.
+  ILLEGAL_ACCESS_POINT = 1;
+  // Format of topic is illegal.
+  ILLEGAL_TOPIC = 2;
+  // Format of consumer group is illegal.
+  ILLEGAL_CONSUMER_GROUP = 3;
+  // Format of message tag is illegal.
+  ILLEGAL_MESSAGE_TAG = 4;
+  // Format of message key is illegal.
+  ILLEGAL_MESSAGE_KEY = 5;
+  // Size of message keys exceeds the threshold.
+  MESSAGE_KEYS_TOO_LARGE = 6;
+  // Format of message group is illegal.
+  ILLEGAL_MESSAGE_GROUP = 7;
+  // Format of message property key is illegal.
+  ILLEGAL_MESSAGE_PROPERTY_KEY = 8;
+  // Message properties total size exceeds the threshold.
+  MESSAGE_PROPERTIES_TOO_LARGE = 9;
+  // Message body size exceeds the threshold.
+  MESSAGE_BODY_TOO_LARGE = 10;
+
+  // User does not have the permission to operate.
+  // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403
+  FORBIDDEN = 403;
+
+  // Code indicates that the client request has not been completed
+  // because it lacks valid authentication credentials for the
+  // requested resource.
+  // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401
+  UNAUTHORIZED = 401;
+
+  // Topic resource does not exist.
+  TOPIC_NOT_FOUND = 13;
+
+  // Consumer group resource does not exist.
+  CONSUMER_GROUP_NOT_FOUND = 14;
+
+  // Not allowed to verify message. Chances are that you are verifying
+  // a FIFO message, as is violating FIFO semantics.
+  VERIFY_MESSAGE_FORBIDDEN = 15;
+
+  // Failed to consume message.
+  FAILED_TO_CONSUME_MESSAGE = 16;
+
+  // Message is corrupted.
+  MESSAGE_CORRUPTED = 17;
+
+  // Too many requests are made in short period of duration.
+  // Requests are throttled.
+  TOO_MANY_REQUESTS = 18;
+
+  // Expired receipt-handle is used when trying to acknowledge or change
+  // invisible duration of a message
+  RECEIPT_HANDLE_EXPIRED = 19;
+
+  // Message property is not match the message type.
+  MESSAGE_PROPERTY_DOES_NOT_MATCH_MESSAGE_TYPE = 20;
+
+  // Format of message id is illegal.
+  ILLEGAL_MESSAGE_ID = 21;
+
+  // Transaction id is invalid.
+  INVALID_TRANSACTION_ID = 22;
+
+  // Format of filter expression is illegal.
+  ILLEGAL_FILTER_EXPRESSION = 23;
+
+  // Receipt handle of message is invalid.
+  INVALID_RECEIPT_HANDLE = 24;
+
+  // Message persistence timeout.
+  MASTER_PERSISTENCE_TIMEOUT = 25;
+
+  // Slave persistence timeout.
+  SLAVE_PERSISTENCE_TIMEOUT = 26;
+
+  // The HA-mechanism is not working now.
+  HA_NOT_AVAILABLE = 27;
+
+  // Operation is not allowed in current version.
+  VERSION_UNSUPPORTED = 28;
+
+  // Message not found from server.
+  MESSAGE_NOT_FOUND = 29;
+
+  // Message offset is illegal.
+  ILLEGAL_MESSAGE_OFFSET = 30;
+
+  // Illegal message is for the sake of backward compatibility. In most case,
+  // more definitive code is better, e.g. `ILLEGAL_MESSAGE_TAG`.
+  ILLEGAL_MESSAGE = 31;
+
+  // Client type could not be recognized.
+  UNRECOGNIZED_CLIENT_TYPE = 32;
+
+  // Code indicates that the server encountered an unexpected condition
+  // that prevented it from fulfilling the request.
+  // This error response is a generic "catch-all" response.
+  // Usually, this indicates the server cannot find a better alternative
+  // error code to response. Sometimes, server administrators log error
+  // responses like the 500 status code with more details about the request
+  // to prevent the error from happening again in the future.
+  //
+  // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500
+  INTERNAL_SERVER_ERROR = 500;
+
+  // Code means that the server or client does not support the functionality
+  // required to fulfill the request.
+  NOT_IMPLEMENTED = 501;
+
+  // Code indicates that the server, while acting as a gateway or proxy,
+  // did not get a response in time from the upstream server that
+  // it needed in order to complete the request.
+  // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/504
+  GATEWAY_TIMEOUT = 504;
+}
+
+message Status {
+  Code code = 1;
+  string message = 2;
+}
+
+enum Language {
+  LANGUAGE_UNSPECIFIED = 0;
+  JAVA = 1;
+  CPP = 2;
+  DOT_NET = 3;
+  GOLANG = 4;
+  RUST = 5;
+}
+
+// User Agent
+message UA {
+  // SDK language
+  Language language = 1;
+
+  // SDK version
+  string version = 2;
+
+  // Platform details, including OS name, version, arch etc.
+  string platform = 3;
+
+  // Hostname of the node
+  string hostname = 4;
+}
\ No newline at end of file
diff --git a/proto/apache/rocketmq/v2/service.proto b/proto/apache/rocketmq/v2/service.proto
new file mode 100644
index 0000000..aa688b4
--- /dev/null
+++ b/proto/apache/rocketmq/v2/service.proto
@@ -0,0 +1,436 @@
+// 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 "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 SendMessageResponse {
+  Status status = 1;
+  repeated SendReceipt receipts = 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;
+  }
+}
+
+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;
+  Message message = 2;
+}
+
+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;
+}
+
+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 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;
+}
+
+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) {
+  }
+}
\ No newline at end of file
diff --git a/src/main/cpp/admin/include/AdminClient.h b/src/main/cpp/admin/include/AdminClient.h
index 968d837..9e6e7c7 100644
--- a/src/main/cpp/admin/include/AdminClient.h
+++ b/src/main/cpp/admin/include/AdminClient.h
@@ -15,12 +15,12 @@
  * limitations under the License.
  */
 #pragma once
-#include "apache/rocketmq/v1/admin.grpc.pb.h"
+#include "apache/rocketmq/v2/admin.grpc.pb.h"
 #include "rocketmq/RocketMQ.h"
 #include <grpcpp/grpcpp.h>
 #include <memory>
 
-namespace rmq = apache::rocketmq::v1;
+namespace rmq = apache::rocketmq::v2;
 
 ROCKETMQ_NAMESPACE_BEGIN
 
diff --git a/src/main/cpp/admin/include/AdminServerImpl.h b/src/main/cpp/admin/include/AdminServerImpl.h
index b605635..5ef88ab 100644
--- a/src/main/cpp/admin/include/AdminServerImpl.h
+++ b/src/main/cpp/admin/include/AdminServerImpl.h
@@ -16,15 +16,17 @@
  */
 #pragma once
 
-#include "AdminServiceImpl.h"
-#include "rocketmq/AdminServer.h"
 #include <atomic>
 #include <condition_variable>
-#include <grpcpp/grpcpp.h>
 #include <memory>
 #include <mutex>
 #include <thread>
 
+#include "AdminServiceImpl.h"
+#include "rocketmq/AdminServer.h"
+
+#include "grpcpp/grpcpp.h"
+
 using grpc::Server;
 
 ROCKETMQ_NAMESPACE_BEGIN
diff --git a/src/main/cpp/admin/include/AdminServiceImpl.h b/src/main/cpp/admin/include/AdminServiceImpl.h
index 58933ab..e2d750c 100644
--- a/src/main/cpp/admin/include/AdminServiceImpl.h
+++ b/src/main/cpp/admin/include/AdminServiceImpl.h
@@ -15,13 +15,14 @@
  * limitations under the License.
  */
 #pragma once
-#include "apache/rocketmq/v1/admin.grpc.pb.h"
+#include "apache/rocketmq/v2/admin.grpc.pb.h"
+#include "grpcpp/grpcpp.h"
 #include "rocketmq/RocketMQ.h"
-#include <grpcpp/grpcpp.h>
 
 using grpc::ServerContext;
 using grpc::Status;
-namespace rmq = apache::rocketmq::v1;
+
+namespace rmq = apache::rocketmq::v2;
 
 ROCKETMQ_NAMESPACE_BEGIN
 
diff --git a/src/main/cpp/admin/include/ServerCall.h b/src/main/cpp/admin/include/ServerCall.h
index 138d433..66f3246 100644
--- a/src/main/cpp/admin/include/ServerCall.h
+++ b/src/main/cpp/admin/include/ServerCall.h
@@ -18,11 +18,11 @@
 
 #include <cassert>
 
-#include "apache/rocketmq/v1/admin.grpc.pb.h"
+#include "apache/rocketmq/v2/admin.grpc.pb.h"
 
 #include "rocketmq/RocketMQ.h"
 
-namespace rmq = apache::rocketmq::v1;
+namespace rmq = apache::rocketmq::v2;
 
 ROCKETMQ_NAMESPACE_BEGIN
 
diff --git a/src/main/cpp/base/BUILD.bazel b/src/main/cpp/base/BUILD.bazel
index 5c7ab81..959bba5 100644
--- a/src/main/cpp/base/BUILD.bazel
+++ b/src/main/cpp/base/BUILD.bazel
@@ -25,6 +25,7 @@ cc_library(
     strip_include_prefix = "//src/main/cpp/base/include",
     deps = [
         "//src/main/cpp/log:log_library",
+        "//proto:rocketmq_grpc_library",
         "@com_github_fmtlib_fmt//:fmtlib",
         "@com_google_absl//absl/base",
         "@com_google_absl//absl/container:flat_hash_map",
diff --git a/src/test/cpp/ut/rocketmq/FilterExpressionTest.cpp b/src/main/cpp/base/Configuration.cpp
similarity index 53%
rename from src/test/cpp/ut/rocketmq/FilterExpressionTest.cpp
rename to src/main/cpp/base/Configuration.cpp
index f7df8ce..cf0f4bd 100644
--- a/src/test/cpp/ut/rocketmq/FilterExpressionTest.cpp
+++ b/src/main/cpp/base/Configuration.cpp
@@ -14,34 +14,32 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include "FilterExpression.h"
-#include "gtest/gtest.h"
 
-ROCKETMQ_NAMESPACE_BEGIN
+#include "rocketmq/Configuration.h"
 
-class FilterExpressionTest : public testing::Test {
-public:
-  FilterExpressionTest() : filter_expression_("TagA") {
-  }
+ROCKETMQ_NAMESPACE_BEGIN
 
-  void SetUp() override {
-  }
+ConfigurationBuilder Configuration::newBuilder() {
+  return {};
+}
 
-  void TearDown() override {
-  }
+ConfigurationBuilder& ConfigurationBuilder::withEndpoints(std::string endpoints) {
+  configuration_.endpoints_ = std::move(endpoints);
+  return *this;
+}
 
-protected:
-  FilterExpression filter_expression_;
-};
+ConfigurationBuilder& ConfigurationBuilder::withCredentialsProvider(std::shared_ptr<CredentialsProvider> provider) {
+  configuration_.credentials_provider_ = std::move(provider);
+  return *this;
+}
 
-TEST_F(FilterExpressionTest, testAccept) {
-  MQMessageExt message;
-  message.setTags("TagA");
-  EXPECT_TRUE(filter_expression_.accept(message));
+ConfigurationBuilder& ConfigurationBuilder::withRequestTimeout(std::chrono::milliseconds request_timeout) {
+  configuration_.request_timeout_ = request_timeout;
+  return *this;
+}
 
-  MQMessageExt message2;
-  message2.setTags("TagB");
-  EXPECT_FALSE(filter_expression_.accept(message2));
+Configuration ConfigurationBuilder::build() {
+  return std::move(configuration_);
 }
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/base/include/DigestType.h b/src/main/cpp/base/ConfigurationDefaults.cpp
similarity index 82%
copy from src/main/cpp/base/include/DigestType.h
copy to src/main/cpp/base/ConfigurationDefaults.cpp
index e255d82..b11a6e6 100644
--- a/src/main/cpp/base/include/DigestType.h
+++ b/src/main/cpp/base/ConfigurationDefaults.cpp
@@ -14,19 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#pragma once
+#include <chrono>
 
-#include <cstdint>
-
-#include "rocketmq/RocketMQ.h"
+#include "rocketmq/ConfigurationDefaults.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-enum class DigestType : int8_t
-{
-  CRC32 = 0,
-  MD5 = 1,
-  SHA1 = 2,
-};
+const std::chrono::milliseconds ConfigurationDefaults::RequestTimeout = std::chrono::seconds(3);
 
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
+ROCKETMQ_NAMESPACE_END
diff --git a/src/main/cpp/rocketmq/CredentialsProvider.cpp b/src/main/cpp/base/CredentialsProvider.cpp
similarity index 100%
rename from src/main/cpp/rocketmq/CredentialsProvider.cpp
rename to src/main/cpp/base/CredentialsProvider.cpp
diff --git a/src/main/cpp/base/ErrorCategory.cpp b/src/main/cpp/base/ErrorCategory.cpp
index 166f632..4fe2ea0 100644
--- a/src/main/cpp/base/ErrorCategory.cpp
+++ b/src/main/cpp/base/ErrorCategory.cpp
@@ -24,6 +24,9 @@ std::string ErrorCategory::message(int code) const {
     case ErrorCode::Success:
       return "Success";
 
+    case ErrorCode::NoContent:
+      return "Broker has processed the request but is not going to return any content.";
+
     case ErrorCode::IllegalState:
       return "Client state illegal. Forgot to call start()?";
 
@@ -34,6 +37,9 @@ std::string ErrorCategory::message(int code) const {
       return "Message is ill-formed. Check validity of your topic, tag, "
              "etc";
 
+    case ErrorCode::BadRequestAsyncPubFifoMessage:
+      return "Publishing of FIFO messages is only allowed synchronously";
+
     case ErrorCode::Unauthorized:
       return "Authentication failed. Possibly caused by invalid credentials.";
 
@@ -42,8 +48,13 @@ std::string ErrorCategory::message(int code) const {
              "requested action";
 
     case ErrorCode::NotFound:
-      return "Topic not found, which should be created through console or "
+      return "Request resource not found, which should be created through console or "
              "administration API before hand.";
+    case ErrorCode::TopicNotFound:
+      return "Topic is not found. Verify the request topic has already been created through console or management API";
+
+    case ErrorCode::GroupNotFound:
+      return "Group is not found. Verify the request group has already been created through console or management API";
 
     case ErrorCode::RequestTimeout:
       return "Timeout when connecting, reading from or writing to brokers.";
diff --git a/src/main/cpp/rocketmq/FilterExpression.cpp b/src/main/cpp/base/FilterExpression.cpp
similarity index 87%
rename from src/main/cpp/rocketmq/FilterExpression.cpp
rename to src/main/cpp/base/FilterExpression.cpp
index a60290b..b187994 100644
--- a/src/main/cpp/rocketmq/FilterExpression.cpp
+++ b/src/main/cpp/base/FilterExpression.cpp
@@ -14,18 +14,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include "FilterExpression.h"
+#include "rocketmq/FilterExpression.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-bool FilterExpression::accept(const MQMessageExt& message) const {
-
+bool FilterExpression::accept(const Message& message) const {
   switch (type_) {
     case ExpressionType::TAG: {
       if (WILD_CARD_TAG == content_) {
         return true;
       } else {
-        return message.getTags() == content_;
+        return message.tag() == content_;
       }
     }
 
diff --git a/src/main/cpp/base/MQMessage.cpp b/src/main/cpp/base/MQMessage.cpp
deleted file mode 100644
index 2015a61..0000000
--- a/src/main/cpp/base/MQMessage.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * 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.
- */
-#include "rocketmq/MQMessage.h"
-#include "MessageAccessor.h"
-#include "MessageImpl.h"
-#include "MixAll.h"
-#include "Protocol.h"
-#include "UniqueIdGenerator.h"
-#include "UtilAll.h"
-#include "rocketmq/MQMessageExt.h"
-#include <chrono>
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-MQMessage::MQMessage() : MQMessage("", "", "", "") {
-}
-
-MQMessage::MQMessage(const std::string& topic, const std::string& body) : MQMessage(topic, "", "", body) {
-}
-
-MQMessage::MQMessage(const std::string& topic, const std::string& tags, const std::string& body)
-    : MQMessage(topic, tags, "", body) {
-}
-
-MQMessage::MQMessage(const std::string& topic, const std::string& tags, const std::string& keys,
-                     const std::string& body)
-    : impl_(new MessageImpl) {
-  impl_->topic_.name = topic;
-  impl_->system_attribute_.tag = tags;
-  if (!keys.empty()) {
-    impl_->system_attribute_.keys.emplace_back(keys);
-  }
-
-  impl_->system_attribute_.born_host = UtilAll::hostname();
-  impl_->system_attribute_.born_timestamp = absl::Now();
-  impl_->system_attribute_.message_id = UniqueIdGenerator::instance().next();
-
-  impl_->body_.clear();
-  impl_->body_.reserve(body.length());
-  impl_->body_.append(body.data(), body.length());
-}
-
-MQMessage::~MQMessage() {
-  delete impl_;
-}
-
-MQMessage::MQMessage(const MQMessage& other) {
-  impl_ = new MessageImpl(*other.impl_);
-}
-
-MQMessage& MQMessage::operator=(const MQMessage& other) {
-  if (this == &other) {
-    return *this;
-  }
-  *impl_ = *(other.impl_);
-  return *this;
-}
-
-const std::string& MQMessage::getMsgId() const {
-  return impl_->system_attribute_.message_id;
-}
-
-std::string MQMessage::getBornHost() const {
-  return impl_->system_attribute_.born_host;
-}
-
-std::chrono::system_clock::time_point MQMessage::deliveryTimestamp() const {
-  return absl::ToChronoTime(impl_->system_attribute_.delivery_timestamp);
-}
-
-void MQMessage::setProperty(const std::string& name, const std::string& value) {
-  impl_->user_attribute_map_[name] = value;
-}
-
-std::string MQMessage::getProperty(const std::string& name) const {
-  auto it = impl_->user_attribute_map_.find(name);
-  if (impl_->user_attribute_map_.end() == it) {
-    return "";
-  }
-  return it->second;
-}
-
-const std::string& MQMessage::getTopic() const {
-  return impl_->topic_.name;
-}
-
-void MQMessage::setTopic(const std::string& topic) {
-  impl_->topic_.name = topic;
-}
-
-void MQMessage::setTopic(const char* data, int len) {
-  impl_->topic_.name = std::string(data, len);
-}
-
-std::string MQMessage::getTags() const {
-  return impl_->system_attribute_.tag;
-}
-
-void MQMessage::setTags(const std::string& tags) {
-  impl_->system_attribute_.tag = tags;
-}
-
-const std::vector<std::string>& MQMessage::getKeys() const {
-  return impl_->system_attribute_.keys;
-}
-
-void MQMessage::setKey(const std::string& key) {
-  impl_->system_attribute_.keys.push_back(key);
-}
-
-void MQMessage::setKeys(const std::vector<std::string>& keys) {
-  impl_->system_attribute_.keys = keys;
-}
-
-int MQMessage::getDelayTimeLevel() const {
-  return impl_->system_attribute_.delay_level;
-}
-
-void MQMessage::setDelayTimeLevel(int level) {
-  impl_->system_attribute_.delay_level = level;
-}
-
-const std::string& MQMessage::traceContext() const {
-  return impl_->system_attribute_.trace_context;
-}
-
-void MQMessage::traceContext(const std::string& trace_context) {
-  impl_->system_attribute_.trace_context = trace_context;
-}
-
-const std::string& MQMessage::getBody() const {
-  return impl_->body_;
-}
-
-void MQMessage::setBody(const char* body, int len) {
-  impl_->body_.clear();
-  impl_->body_.reserve(len);
-  impl_->body_.append(body, len);
-}
-
-void MQMessage::setBody(const std::string& body) {
-  impl_->body_ = body;
-}
-
-uint32_t MQMessage::bodyLength() const {
-  return impl_->body_.length();
-}
-
-const std::map<std::string, std::string>& MQMessage::getProperties() const {
-  return impl_->user_attribute_map_;
-}
-
-void MQMessage::setProperties(const std::map<std::string, std::string>& properties) {
-  for (const auto& it : properties) {
-    impl_->user_attribute_map_.insert({it.first, it.second});
-  }
-}
-
-void MQMessage::messageType(MessageType message_type) {
-  impl_->system_attribute_.message_type = message_type;
-}
-
-MessageType MQMessage::messageType() const {
-  return impl_->system_attribute_.message_type;
-}
-
-void MQMessage::bindMessageGroup(absl::string_view message_group) {
-  impl_->system_attribute_.message_group.append(message_group.data(), message_group.length());
-  messageType(MessageType::FIFO);
-}
-
-const std::string& MQMessage::messageGroup() const {
-  return impl_->system_attribute_.message_group;
-}
-
-ROCKETMQ_NAMESPACE_END
diff --git a/src/main/cpp/base/MQMessageExt.cpp b/src/main/cpp/base/MQMessageExt.cpp
deleted file mode 100644
index 21a9476..0000000
--- a/src/main/cpp/base/MQMessageExt.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.
- */
-#include "rocketmq/MQMessageExt.h"
-#include "MessageImpl.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-MQMessageExt::MQMessageExt() : MQMessage() {
-}
-
-MQMessageExt::MQMessageExt(const MQMessageExt& other) : MQMessage(other) {
-}
-
-MQMessageExt& MQMessageExt::operator=(const MQMessageExt& other) {
-  if (this == &other) {
-    return *this;
-  }
-
-  *impl_ = *(other.impl_);
-  return *this;
-}
-
-int32_t MQMessageExt::getQueueId() const {
-  return impl_->system_attribute_.partition_id;
-}
-
-std::chrono::system_clock::time_point MQMessageExt::bornTimestamp() const {
-  return absl::ToChronoTime(impl_->system_attribute_.born_timestamp);
-}
-
-int64_t MQMessageExt::getBornTimestamp() const {
-  return absl::ToUnixMillis(impl_->system_attribute_.born_timestamp);
-}
-
-std::chrono::system_clock::time_point MQMessageExt::storeTimestamp() const {
-  return absl::ToChronoTime(impl_->system_attribute_.store_timestamp);
-}
-
-int64_t MQMessageExt::getStoreTimestamp() const {
-  return absl::ToUnixMillis(impl_->system_attribute_.store_timestamp);
-}
-
-std::string MQMessageExt::getStoreHost() const {
-  return impl_->system_attribute_.store_host;
-}
-
-int64_t MQMessageExt::getQueueOffset() const {
-  return impl_->system_attribute_.partition_offset;
-}
-
-int32_t MQMessageExt::getDeliveryAttempt() const {
-  return impl_->system_attribute_.attempt_times;
-}
-
-const std::string& MQMessageExt::receiptHandle() const {
-  return impl_->system_attribute_.receipt_handle;
-}
-
-bool MQMessageExt::operator==(const MQMessageExt& other) {
-  return impl_->system_attribute_.message_id == other.impl_->system_attribute_.message_id;
-}
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/base/Message.cpp b/src/main/cpp/base/Message.cpp
new file mode 100644
index 0000000..f20b4cd
--- /dev/null
+++ b/src/main/cpp/base/Message.cpp
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+#include "rocketmq/Message.h"
+
+#include "UniqueIdGenerator.h"
+#include "absl/memory/memory.h"
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+Message::Message() {
+  id_ = UniqueIdGenerator::instance().next();
+}
+
+MessageBuilder Message::newBuilder() {
+  return {};
+}
+
+MessageBuilder::MessageBuilder() : message_(absl::make_unique<Message>()) {
+}
+
+MessageBuilder& MessageBuilder::withTopic(std::string topic) {
+  message_->topic_.swap(topic);
+  return *this;
+}
+
+MessageBuilder& MessageBuilder::withTag(std::string tag) {
+  message_->tag_.swap(tag);
+  return *this;
+}
+
+MessageBuilder& MessageBuilder::withKeys(std::vector<std::string> keys) {
+  message_->keys_.swap(keys);
+  return *this;
+}
+
+MessageBuilder& MessageBuilder::withTraceContext(std::string trace_context) {
+  message_->trace_context_.swap(trace_context);
+  return *this;
+}
+
+MessageBuilder& MessageBuilder::withBody(std::string body) {
+  message_->body_.swap(body);
+  return *this;
+}
+
+MessageBuilder& MessageBuilder::withGroup(std::string group) {
+  message_->group_.swap(group);
+  return *this;
+}
+
+MessageBuilder& MessageBuilder::withProperties(std::unordered_map<std::string, std::string> properties) {
+  message_->properties_ = std::move(properties);
+  return *this;
+}
+
+MessageConstPtr MessageBuilder::build() {
+  return std::move(message_);
+}
+
+MessageBuilder& MessageBuilder::withId(std::string id) {
+  message_->id_ = std::move(id);
+  return *this;
+}
+
+MessageBuilder& MessageBuilder::withBornTime(std::chrono::system_clock::time_point born_time) {
+  message_->born_time_ = born_time;
+  return *this;
+}
+
+MessageBuilder& MessageBuilder::withBornHost(std::string born_host) {
+  message_->born_host_ = std::move(born_host);
+  return *this;
+}
+
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/base/MessageAccessor.cpp b/src/main/cpp/base/MessageAccessor.cpp
deleted file mode 100644
index 957f076..0000000
--- a/src/main/cpp/base/MessageAccessor.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-#include "MessageAccessor.h"
-#include "MessageImpl.h"
-#include "rocketmq/MQMessage.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-void MessageAccessor::setMessageId(MQMessageExt& message, std::string message_id) {
-  message.impl_->system_attribute_.message_id = std::move(message_id);
-}
-
-void MessageAccessor::setBornTimestamp(MQMessageExt& message, absl::Time born_timestamp) {
-  message.impl_->system_attribute_.born_timestamp = born_timestamp;
-}
-
-void MessageAccessor::setStoreTimestamp(MQMessageExt& message, absl::Time store_timestamp) {
-  message.impl_->system_attribute_.store_timestamp = store_timestamp;
-}
-
-void MessageAccessor::setQueueId(MQMessageExt& message, int32_t queue_id) {
-  message.impl_->system_attribute_.partition_id = queue_id;
-}
-
-void MessageAccessor::setQueueOffset(MQMessageExt& message, int64_t queue_offset) {
-  message.impl_->system_attribute_.partition_offset = queue_offset;
-}
-
-void MessageAccessor::setBornHost(MQMessageExt& message, std::string born_host) {
-  message.impl_->system_attribute_.born_host = std::move(born_host);
-}
-
-void MessageAccessor::setStoreHost(MQMessageExt& message, std::string store_host) {
-  message.impl_->system_attribute_.store_host = std::move(store_host);
-}
-
-void MessageAccessor::setDeliveryTimestamp(MQMessageExt& message, absl::Time delivery_timestamp) {
-  message.impl_->system_attribute_.delivery_timestamp = delivery_timestamp;
-}
-
-void MessageAccessor::setDeliveryAttempt(MQMessageExt& message, int32_t attempt_times) {
-  message.impl_->system_attribute_.attempt_times = attempt_times;
-}
-
-void MessageAccessor::setDecodedTimestamp(MQMessageExt& message, absl::Time decode_timestamp) {
-  message.impl_->system_attribute_.decode_timestamp = decode_timestamp;
-}
-
-absl::Time MessageAccessor::decodedTimestamp(const MQMessageExt& message) {
-  return message.impl_->system_attribute_.decode_timestamp;
-}
-
-void MessageAccessor::setInvisiblePeriod(MQMessageExt& message, absl::Duration invisible_period) {
-  message.impl_->system_attribute_.invisible_period = invisible_period;
-}
-
-void MessageAccessor::setReceiptHandle(MQMessageExt& message, std::string receipt_handle) {
-  message.impl_->system_attribute_.receipt_handle = std::move(receipt_handle);
-}
-
-void MessageAccessor::setTraceContext(MQMessageExt& message, std::string trace_context) {
-  message.impl_->system_attribute_.trace_context = std::move(trace_context);
-}
-
-void MessageAccessor::setMessageType(MQMessage& message, MessageType message_type) {
-  message.impl_->system_attribute_.message_type = message_type;
-}
-
-void MessageAccessor::setTargetEndpoint(MQMessage& message, const std::string& target_endpoint) {
-  message.impl_->system_attribute_.target_endpoint = target_endpoint;
-}
-
-const std::string& MessageAccessor::targetEndpoint(const MQMessage& message) {
-  return message.impl_->system_attribute_.target_endpoint;
-}
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/test/cpp/ut/api/ErrorCodeTest.cpp b/src/main/cpp/base/MessageExt.cpp
similarity index 73%
rename from src/test/cpp/ut/api/ErrorCodeTest.cpp
rename to src/main/cpp/base/MessageExt.cpp
index c63df2f..5477df7 100644
--- a/src/test/cpp/ut/api/ErrorCodeTest.cpp
+++ b/src/main/cpp/base/MessageExt.cpp
@@ -14,17 +14,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include "rocketmq/ErrorCode.h"
-#include "gtest/gtest.h"
-#include <system_error>
+#include "MessageExt.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-TEST(ErrorCodeTest, testErrorCode) {
-  std::error_code ec = ErrorCode::BadRequest;
-  if (ec) {
-    std::cout << ec.message() << std::endl;
+rmq::MessageType typeOf(const Message& message) {
+  if (message.group().has_value()) {
+    return rmq::MessageType::FIFO;
   }
+
+  if (message.deliveryTimestamp().has_value()) {
+    return rmq::MessageType::DELAY;
+  }
+
+  return rmq::MessageType::NORMAL;
 }
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/base/MetadataConstants.cpp b/src/main/cpp/base/MetadataConstants.cpp
index 0aa8d93..71e3da9 100644
--- a/src/main/cpp/base/MetadataConstants.cpp
+++ b/src/main/cpp/base/MetadataConstants.cpp
@@ -18,19 +18,35 @@
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-const char* MetadataConstants::TENANT_ID_KEY = "x-mq-tenant-id";
-const char* MetadataConstants::NAMESPACE_KEY = "x-mq-namespace";
-const char* MetadataConstants::AUTHORIZATION = "authorization";
-const char* MetadataConstants::STS_SESSION_TOKEN = "x-mq-session-token";
-const char* MetadataConstants::DATE_TIME_KEY = "x-mq-date-time";
-const char* MetadataConstants::ALGORITHM_KEY = "MQv2-HMAC-SHA1";
-const char* MetadataConstants::CREDENTIAL_KEY = "Credential";
-const char* MetadataConstants::SIGNED_HEADERS_KEY = "SignedHeaders";
-const char* MetadataConstants::SIGNATURE_KEY = "Signature";
-const char* MetadataConstants::DATE_TIME_FORMAT = "%Y%m%dT%H%M%SZ";
-const char* MetadataConstants::LANGUAGE_KEY = "x-mq-language";
-const char* MetadataConstants::CLIENT_VERSION_KEY = "x-mq-client-version";
+#ifndef CLIENT_VERSION_MAJOR
+#define CLIENT_VERSION_MAJOR "5"
+#endif
+
+#ifndef CLIENT_VERSION_MINOR
+#define CLIENT_VERSION_MINOR "0"
+#endif
+
+#ifndef CLIENT_VERSION_PATCH
+#define CLIENT_VERSION_PATCH "0"
+#endif
+
+const char* MetadataConstants::CLIENT_VERSION = CLIENT_VERSION_MAJOR "." CLIENT_VERSION_MINOR "." CLIENT_VERSION_PATCH;
+
+const char* MetadataConstants::TENANT_ID_KEY        = "x-mq-tenant-id";
+const char* MetadataConstants::CLIENT_ID_KEY        = "x-mq-client-id";
+const char* MetadataConstants::NAMESPACE_KEY        = "x-mq-namespace";
+const char* MetadataConstants::AUTHORIZATION        = "authorization";
+const char* MetadataConstants::STS_SESSION_TOKEN    = "x-mq-session-token";
+const char* MetadataConstants::DATE_TIME_KEY        = "x-mq-date-time";
+const char* MetadataConstants::ALGORITHM_KEY        = "MQv2-HMAC-SHA1";
+const char* MetadataConstants::CREDENTIAL_KEY       = "Credential";
+const char* MetadataConstants::SIGNED_HEADERS_KEY   = "SignedHeaders";
+const char* MetadataConstants::SIGNATURE_KEY        = "Signature";
+const char* MetadataConstants::DATE_TIME_FORMAT     = "%Y%m%dT%H%M%SZ";
+const char* MetadataConstants::LANGUAGE_KEY         = "x-mq-language";
+const char* MetadataConstants::CLIENT_VERSION_KEY   = "x-mq-client-version";
 const char* MetadataConstants::PROTOCOL_VERSION_KEY = "x-mq-protocol-version";
-const char* MetadataConstants::REQUEST_ID_KEY = "x-mq-request-id";
+const char* MetadataConstants::REQUEST_ID_KEY       = "x-mq-request-id";
+const char* MetadataConstants::SERVICE_NAME         = "RocketMQ";
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/base/MixAll.cpp b/src/main/cpp/base/MixAll.cpp
index 0bf273a..4d244ce 100644
--- a/src/main/cpp/base/MixAll.cpp
+++ b/src/main/cpp/base/MixAll.cpp
@@ -17,6 +17,7 @@
 #include "MixAll.h"
 
 #include <chrono>
+#include <cstdint>
 #include <cstdlib>
 
 #include "absl/random/random.h"
@@ -55,7 +56,7 @@ const std::chrono::duration<long long> MixAll::DEFAULT_INVISIBLE_TIME_ = std::ch
 
 const std::chrono::duration<long long> MixAll::PROCESS_QUEUE_EXPIRATION_THRESHOLD_ = std::chrono::seconds(120);
 
-const int32_t MixAll::MAX_SEND_MESSAGE_ATTEMPT_TIMES_ = 3;
+const std::size_t MixAll::MAX_SEND_MESSAGE_ATTEMPT_TIMES_ = 3;
 
 const std::string MixAll::PROPERTY_TRANSACTION_PREPARED_ = "TRAN_MSG";
 
@@ -63,6 +64,8 @@ const std::string MixAll::DEFAULT_LOAD_BALANCER_STRATEGY_NAME_ = "AVG";
 
 const uint32_t MixAll::DEFAULT_COMPRESS_BODY_THRESHOLD_ = 1024 * 1024 * 4;
 
+const std::chrono::milliseconds MixAll::DefaultReceiveMessageTimeout = std::chrono::seconds(30);
+
 const char* MixAll::HOME_PROFILE_ENV_ = "HOME";
 const char* MixAll::MESSAGE_KEY_SEPARATOR = " ";
 
@@ -135,11 +138,11 @@ const char* MixAll::SPAN_ANNOTATION_AWAIT_CONSUMPTION = "__await_consumption";
 const char* MixAll::SPAN_ANNOTATION_MESSAGE_KEYS = "__message_keys";
 const char* MixAll::SPAN_ANNOTATION_ATTR_START_TIME = "__start_time";
 
-bool MixAll::validate(const MQMessage& message) {
-  if (message.getTopic().empty()) {
+bool MixAll::validate(const Message& message) {
+  if (message.topic().empty()) {
     return false;
   }
-  const std::string& topic = message.getTopic();
+  const std::string& topic = message.topic();
   // Topic should not start with "CID" or "GID" which are reserved prefix
   if (absl::StartsWith(topic, "CID") || absl::StartsWith(topic, "GID")) {
     return false;
@@ -150,7 +153,7 @@ bool MixAll::validate(const MQMessage& message) {
     return false;
   }
 
-  uint32_t body_length = message.bodyLength();
+  uint32_t body_length = message.body().length();
   if (!body_length || body_length > MAX_MESSAGE_BODY_SIZE) {
     return false;
   }
@@ -295,4 +298,28 @@ bool MixAll::isIPv4(absl::string_view host) {
   return RE2::FullMatch(re2::StringPiece(host.data(), host.length()), IP_REGEX);
 }
 
+const char* MixAll::osName() {
+#if INTPTR_MAX == INT32_MAX
+#define BITS " 32-bit"
+#elif INTPTR_MAX == INT64_MAX
+#define BITS " 64-bit"
+#else
+#define BITS ""
+#endif
+
+#if defined(_WIN32) || defined(_WIN64)
+  return "Windows" BITS;
+#elif __APPLE__ || __MACH__
+  return "Mac OSX" BITS;
+#elif __linux__
+  return "Linux" BITS;
+#elif __FreeBSD__
+  return "FreeBSD" BITS;
+#elif __unix || __unix__
+  return "Unix" BITS;
+#else
+  return "Other" BITS;
+#endif
+}
+
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/base/Protocol.cpp b/src/main/cpp/base/Protocol.cpp
index be031e3..91a643b 100644
--- a/src/main/cpp/base/Protocol.cpp
+++ b/src/main/cpp/base/Protocol.cpp
@@ -14,14 +14,140 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #include "Protocol.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-#ifndef CLIENT_PROTOCOL_VERSION
-#define CLIENT_PROTOCOL_VERSION "v1"
-#endif
+const char* protocolVersion() {
+  static const char* protocol_version = "v2";
+  return protocol_version;
+}
+
+bool writable(rmq::Permission p) {
+  switch (p) {
+    case rmq::Permission::WRITE:
+    case rmq::Permission::READ_WRITE:
+      return true;
+    default: {
+      return false;
+    }
+  }
+}
+
+bool readable(rmq::Permission p) {
+  switch (p) {
+    case rmq::Permission::READ:
+    case rmq::Permission::READ_WRITE:
+      return true;
+    default:
+      return false;
+  }
+}
+
+bool operator<(const rmq::Resource& lhs, const rmq::Resource& rhs) {
+  return lhs.resource_namespace() < rhs.resource_namespace() || lhs.name() < rhs.name();
+}
+
+bool operator==(const rmq::Resource& lhs, const rmq::Resource& rhs) {
+  return lhs.resource_namespace() == rhs.resource_namespace() && lhs.name() == rhs.name();
+}
+
+bool operator<(const rmq::Broker& lhs, const rmq::Broker& rhs) {
+  return lhs.name() < rhs.name() || lhs.id() < rhs.id();
+}
+
+bool operator==(const rmq::Broker& lhs, const rmq::Broker& rhs) {
+  return lhs.name() == rhs.name() && lhs.id() == rhs.id();
+}
+
+bool operator<(const rmq::MessageQueue& lhs, const rmq::MessageQueue& rhs) {
+  return lhs.topic() < rhs.topic() || lhs.id() < rhs.id() || lhs.broker() < rhs.broker() ||
+         lhs.permission() < rhs.permission();
+}
+
+bool operator==(const rmq::MessageQueue& lhs, const rmq::MessageQueue& rhs) {
+  return lhs.topic() == rhs.topic() && lhs.id() == rhs.id() && lhs.broker() == rhs.broker() &&
+         lhs.permission() == rhs.permission();
+}
+
+std::string simpleNameOf(const rmq::MessageQueue& m) {
+  return fmt::format("{}{}-{}-{}", m.topic().resource_namespace(), m.topic().name(), m.id(), m.broker().name());
+}
+
+bool operator==(const std::vector<rmq::MessageQueue>& lhs, const std::vector<rmq::MessageQueue>& rhs) {
+  if (lhs.size() != rhs.size()) {
+    return false;
+  }
+
+  for (std::size_t i = 0; i < lhs.size(); i++) {
+    if (lhs[i] == rhs[i]) {
+      continue;
+    }
+    return false;
+  }
+
+  return true;
+}
+
+bool operator!=(const std::vector<rmq::MessageQueue>& lhs, const std::vector<rmq::MessageQueue>& rhs) {
+  return !(lhs == rhs);
+}
+
+std::string urlOf(const rmq::MessageQueue& message_queue) {
+  const auto& endpoints = message_queue.broker().endpoints();
+  const auto& addresses = endpoints.addresses();
+  switch (endpoints.scheme()) {
+    case rmq::AddressScheme::DOMAIN_NAME: {
+      assert(addresses.size() == 1);
+      auto first = addresses.begin();
+      return fmt::format("dns:{}:{}", first->host(), first->port());
+    }
+    case rmq::AddressScheme::IPv4: {
+      assert(!addresses.empty());
+      auto it = addresses.cbegin();
+      std::string result = fmt::format("ipv4:{}:{}", it->host(), it->port());
+      for (++it; it != addresses.cend(); ++it) {
+        result.append(fmt::format(",{}:{}", it->host(), it->port()));
+      }
+      return result;
+    }
+    case rmq::AddressScheme::IPv6: {
+      assert(!addresses.empty());
+      auto it = addresses.cbegin();
+      std::string result = fmt::format("ipv6:{}:{}", it->host(), it->port());
+      for (++it; it != addresses.cend(); ++it) {
+        result.append(fmt::format(",{}:{}", it->host(), it->port()));
+      }
+      return result;
+    }
+    default: {
+      break;
+    }
+  }
+  return {};
+}
+
+bool operator<(const rmq::Assignment& lhs, const rmq::Assignment& rhs) {
+  return lhs.message_queue() < rhs.message_queue();
+}
+
+bool operator==(const rmq::Assignment& lhs, const rmq::Assignment& rhs) {
+  return lhs.message_queue() == rhs.message_queue();
+}
+
+bool operator==(const std::vector<rmq::Assignment>& lhs, const std::vector<rmq::Assignment>& rhs) {
+  if (lhs.size() != rhs.size()) {
+    return false;
+  }
 
-const char* Protocol::PROTOCOL_VERSION = CLIENT_PROTOCOL_VERSION;
+  for (std::size_t i = 0; i < lhs.size(); i++) {
+    if (lhs[i] == rhs[i]) {
+      continue;
+    }
+    return false;
+  }
+  return true;
+}
 
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
+ROCKETMQ_NAMESPACE_END
diff --git a/src/main/cpp/base/include/DigestType.h b/src/main/cpp/base/Tracing.cpp
similarity index 83%
copy from src/main/cpp/base/include/DigestType.h
copy to src/main/cpp/base/Tracing.cpp
index e255d82..9eb7335 100644
--- a/src/main/cpp/base/include/DigestType.h
+++ b/src/main/cpp/base/Tracing.cpp
@@ -14,19 +14,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#pragma once
-
-#include <cstdint>
-
-#include "rocketmq/RocketMQ.h"
+#include "rocketmq/Tracing.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-enum class DigestType : int8_t
-{
-  CRC32 = 0,
-  MD5 = 1,
-  SHA1 = 2,
-};
+opencensus::trace::Sampler* traceSampler() {
+  static opencensus::trace::NeverSampler sampler;
+  return &sampler;
+}
 
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
+ROCKETMQ_NAMESPACE_END
diff --git a/src/main/cpp/base/include/InvocationContext.h b/src/main/cpp/base/include/InvocationContext.h
index cad3e06..910a65d 100644
--- a/src/main/cpp/base/include/InvocationContext.h
+++ b/src/main/cpp/base/include/InvocationContext.h
@@ -30,7 +30,6 @@
 #include "LoggerImpl.h"
 #include "MetadataConstants.h"
 #include "UniqueIdGenerator.h"
-#include "rocketmq/RocketMQ.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
@@ -86,6 +85,7 @@ struct InvocationContext : public BaseInvocationContext {
       SPDLOG_WARN("Asynchronous RPC[{}.{}] timed out, elapsing {}ms, deadline-over-due: {}ms",
                   absl::FormatTime(created_time, absl::UTCTimeZone()), elapsed, diff);
     }
+
     try {
       if (callback) {
         callback(this);
diff --git a/src/main/cpp/base/include/MessageAccessor.h b/src/main/cpp/base/include/MessageAccessor.h
deleted file mode 100644
index 371bd23..0000000
--- a/src/main/cpp/base/include/MessageAccessor.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.
- */
-#pragma once
-
-#include "rocketmq/MQMessageExt.h"
-
-#include "Protocol.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-class MessageAccessor {
-
-public:
-  static void setMessageId(MQMessageExt& message, std::string message_id);
-
-  static void setBornTimestamp(MQMessageExt& message, absl::Time born_timestamp);
-
-  static void setStoreTimestamp(MQMessageExt& message, absl::Time store_timestamp);
-
-  static void setQueueId(MQMessageExt& message, int32_t queue_id);
-
-  static void setQueueOffset(MQMessageExt& message, int64_t queue_offset);
-
-  static void setBornHost(MQMessageExt& message, std::string born_host);
-
-  static void setStoreHost(MQMessageExt& message, std::string store_host);
-
-  static void setDeliveryTimestamp(MQMessageExt& message, absl::Time delivery_timestamp);
-
-  static void setDeliveryAttempt(MQMessageExt& message, int32_t attempt_times);
-
-  static void setDecodedTimestamp(MQMessageExt& message, absl::Time decode_timestamp);
-  static absl::Time decodedTimestamp(const MQMessageExt& message);
-
-  static void setInvisiblePeriod(MQMessageExt& message, absl::Duration invisible_period);
-
-  static void setReceiptHandle(MQMessageExt& message, std::string receipt_handle);
-  static void setTraceContext(MQMessageExt& message, std::string trace_context);
-
-  static void setMessageType(MQMessage& message, MessageType message_type);
-
-  static void setTargetEndpoint(MQMessage& message, const std::string& target_endpoint);
-
-  static const std::string& targetEndpoint(const MQMessage& message);
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/api/rocketmq/MessageModel.h b/src/main/cpp/base/include/MessageExt.h
similarity index 82%
copy from api/rocketmq/MessageModel.h
copy to src/main/cpp/base/include/MessageExt.h
index 2422d32..31106bb 100644
--- a/api/rocketmq/MessageModel.h
+++ b/src/main/cpp/base/include/MessageExt.h
@@ -16,16 +16,16 @@
  */
 #pragma once
 
-#include "RocketMQ.h"
-
+#include <chrono>
+#include <cstddef>
 #include <cstdint>
+#include <string>
+
+#include "Protocol.h"
+#include "rocketmq/Message.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-enum class MessageModel : int8_t
-{
-  BROADCASTING,
-  CLUSTERING,
-};
+rmq::MessageType typeOf(const Message& message);
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/base/include/MessageImpl.h b/src/main/cpp/base/include/MessageImpl.h
deleted file mode 100644
index 079ba33..0000000
--- a/src/main/cpp/base/include/MessageImpl.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.
- */
-#pragma once
-
-#include <map>
-
-#include "Protocol.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-class MessageImpl {
-protected:
-  Resource topic_;
-  std::map<std::string, std::string> user_attribute_map_;
-  SystemAttribute system_attribute_;
-  std::string body_;
-  friend class MQMessage;
-  friend class MQMessageExt;
-  friend class MessageAccessor;
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/base/include/MetadataConstants.h b/src/main/cpp/base/include/MetadataConstants.h
index ac3af5b..a02fc19 100644
--- a/src/main/cpp/base/include/MetadataConstants.h
+++ b/src/main/cpp/base/include/MetadataConstants.h
@@ -24,6 +24,7 @@ class MetadataConstants {
 public:
   static const char* REQUEST_ID_KEY;
   static const char* TENANT_ID_KEY;
+  static const char* CLIENT_ID_KEY;
   static const char* NAMESPACE_KEY;
   static const char* AUTHORIZATION;
   static const char* STS_SESSION_TOKEN;
@@ -36,6 +37,8 @@ public:
   static const char* LANGUAGE_KEY;
   static const char* CLIENT_VERSION_KEY;
   static const char* PROTOCOL_VERSION_KEY;
+  static const char* CLIENT_VERSION;
+  static const char* SERVICE_NAME;
 };
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/base/include/MixAll.h b/src/main/cpp/base/include/MixAll.h
index ae272dc..1483737 100644
--- a/src/main/cpp/base/include/MixAll.h
+++ b/src/main/cpp/base/include/MixAll.h
@@ -23,7 +23,7 @@
 #include "absl/strings/string_view.h"
 #include "re2/re2.h"
 
-#include "rocketmq/MQMessage.h"
+#include "rocketmq/Message.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
@@ -49,7 +49,9 @@ public:
 
   static const std::chrono::duration<long long> PROCESS_QUEUE_EXPIRATION_THRESHOLD_;
 
-  static const int32_t MAX_SEND_MESSAGE_ATTEMPT_TIMES_;
+  static const std::chrono::milliseconds DefaultReceiveMessageTimeout;
+
+  static const std::size_t MAX_SEND_MESSAGE_ATTEMPT_TIMES_;
 
   static const std::string PROPERTY_TRANSACTION_PREPARED_;
 
@@ -142,7 +144,7 @@ public:
    * @param message
    * @return
    */
-  static bool validate(const MQMessage& message);
+  static bool validate(const Message& message);
 
   static uint32_t random(uint32_t left, uint32_t right);
 
@@ -162,6 +164,8 @@ public:
 
   static bool isIPv4(absl::string_view host);
 
+  static const char* osName();
+
 private:
   static bool hexCharValue(char c, uint8_t& value);
 };
diff --git a/src/main/cpp/base/include/Protocol.h b/src/main/cpp/base/include/Protocol.h
index 7d52fd6..5a8e671 100644
--- a/src/main/cpp/base/include/Protocol.h
+++ b/src/main/cpp/base/include/Protocol.h
@@ -16,65 +16,77 @@
  */
 #pragma once
 
-#include <chrono>
-#include <string>
-#include <vector>
+#include "absl/hash/hash.h"
+#include "fmt/format.h"
 
-#include "absl/time/clock.h"
-#include "absl/time/time.h"
+#include "apache/rocketmq/v2/definition.grpc.pb.h"
+#include "apache/rocketmq/v2/definition.pb.h"
+#include "apache/rocketmq/v2/service.grpc.pb.h"
+#include "apache/rocketmq/v2/service.pb.h"
 
-#include "DigestType.h"
-#include "Encoding.h"
-#include "rocketmq/MessageType.h"
+#include "rocketmq/RocketMQ.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-class Protocol {
-public:
-  static const char* PROTOCOL_VERSION;
-};
-
-struct Digest {
-  DigestType digest_type{DigestType::MD5};
-  std::string checksum;
-  Digest() = default;
-};
-
-struct Resource {
-  /**
-   * Abstract resource namespace
-   */
-  std::string resource_namespace;
-
-  /**
-   * Resource name, which remains unique within given abstract resource namespace.
-   */
-  std::string name;
-};
-
-struct SystemAttribute {
-  std::string tag;
-  std::vector<std::string> keys;
-  std::string message_id;
-  Digest digest;
-  Encoding body_encoding;
-  MessageType message_type;
-  absl::Time born_timestamp{absl::Now()};
-  std::string born_host;
-  absl::Time store_timestamp{absl::UnixEpoch()};
-  std::string store_host;
-  absl::Time delivery_timestamp{absl::UnixEpoch()};
-  absl::Time decode_timestamp{absl::Now()};
-  int32_t delay_level{0};
-  std::string receipt_handle;
-  int32_t partition_id{0};
-  int64_t partition_offset{0};
-  absl::Duration invisible_period;
-  int32_t attempt_times{0};
-  Resource publisher_group;
-  std::string trace_context;
-  std::string target_endpoint;
-  std::string message_group;
-};
-
-ROCKETMQ_NAMESPACE_END
+namespace rmq = apache::rocketmq::v2;
+
+using ChangeInvisibleDurationRequest = rmq::ChangeInvisibleDurationRequest;
+using ChangeInvisibleDurationResponse = rmq::ChangeInvisibleDurationResponse;
+using QueryRouteRequest = rmq::QueryRouteRequest;
+using QueryRouteResponse = rmq::QueryRouteResponse;
+using SendMessageRequest = rmq::SendMessageRequest;
+using SendMessageResponse = rmq::SendMessageResponse;
+using QueryAssignmentRequest = rmq::QueryAssignmentRequest;
+using QueryAssignmentResponse = rmq::QueryAssignmentResponse;
+using ReceiveMessageRequest = rmq::ReceiveMessageRequest;
+using ReceiveMessageResponse = rmq::ReceiveMessageResponse;
+using AckMessageRequest = rmq::AckMessageRequest;
+using AckMessageResponse = rmq::AckMessageResponse;
+using HeartbeatRequest = rmq::HeartbeatRequest;
+using HeartbeatResponse = rmq::HeartbeatResponse;
+using EndTransactionRequest = rmq::EndTransactionRequest;
+using EndTransactionResponse = rmq::EndTransactionResponse;
+using RecoverOrphanedTransactionCommand = rmq::RecoverOrphanedTransactionCommand;
+using PrintThreadStackTraceCommand = rmq::PrintThreadStackTraceCommand;
+using ThreadStackTrace = rmq::ThreadStackTrace;
+using VerifyMessageCommand = rmq::VerifyMessageCommand;
+using VerifyMessageResult = rmq::VerifyMessageResult;
+using TelemetryCommand = rmq::TelemetryCommand;
+using ForwardMessageToDeadLetterQueueRequest = rmq::ForwardMessageToDeadLetterQueueRequest;
+using ForwardMessageToDeadLetterQueueResponse = rmq::ForwardMessageToDeadLetterQueueResponse;
+using NotifyClientTerminationRequest = rmq::NotifyClientTerminationRequest;
+using NotifyClientTerminationResponse = rmq::NotifyClientTerminationResponse;
+
+const char* protocolVersion();
+
+bool writable(rmq::Permission p);
+
+bool readable(rmq::Permission p);
+
+bool operator<(const rmq::Resource& lhs, const rmq::Resource& rhs);
+
+bool operator==(const rmq::Resource& lhs, const rmq::Resource& rhs);
+
+bool operator<(const rmq::Broker& lhs, const rmq::Broker& rhs);
+
+bool operator==(const rmq::Broker& lhs, const rmq::Broker& rhs);
+
+bool operator<(const rmq::MessageQueue& lhs, const rmq::MessageQueue& rhs);
+
+bool operator==(const rmq::MessageQueue& lhs, const rmq::MessageQueue& rhs);
+
+std::string simpleNameOf(const rmq::MessageQueue& m);
+
+bool operator==(const std::vector<rmq::MessageQueue>& lhs, const std::vector<rmq::MessageQueue>& rhs);
+
+bool operator!=(const std::vector<rmq::MessageQueue>& lhs, const std::vector<rmq::MessageQueue>& rhs);
+
+std::string urlOf(const rmq::MessageQueue& message_queue);
+
+bool operator<(const rmq::Assignment& lhs, const rmq::Assignment& rhs);
+
+bool operator==(const rmq::Assignment& lhs, const rmq::Assignment& rhs);
+
+bool operator==(const std::vector<rmq::Assignment>& lhs, const std::vector<rmq::Assignment>& rhs);
+
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/base/include/RetryPolicy.h b/src/main/cpp/base/include/RetryPolicy.h
new file mode 100644
index 0000000..5cc4138
--- /dev/null
+++ b/src/main/cpp/base/include/RetryPolicy.h
@@ -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.
+ */
+#pragma once
+
+#include <cmath>
+#include <cstdint>
+#include <vector>
+
+#include "absl/time/time.h"
+#include "rocketmq/RocketMQ.h"
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+enum class BackoffStrategy : std::uint8_t
+{
+  Customized = 0,
+  Exponential = 1,
+};
+
+struct RetryPolicy {
+  std::uint32_t max_attempt;
+
+  BackoffStrategy strategy;
+
+  // Exponential back-off
+  absl::Duration initial;
+  absl::Duration max;
+  float multiplier;
+
+  // User defined back-off intervals.
+  std::vector<absl::Duration> next;
+
+  std::int64_t backoff(std::size_t attempt) {
+    static std::int64_t default_backoff = 1000;
+    if (!attempt) {
+      attempt = 1;
+    }
+
+    switch (strategy) {
+      case BackoffStrategy::Customized: {
+        if (next.empty()) {
+          return default_backoff;
+        }
+        if (attempt >= next.size()) {
+          return absl::ToInt64Milliseconds(next[next.size() - 1]);
+        }
+        return absl::ToInt64Milliseconds(next[attempt - 1]);
+      }
+
+      case BackoffStrategy::Exponential: {
+        if (!absl::ToInt64Milliseconds(max)) {
+          return default_backoff;
+        }
+
+        auto result = initial * pow(2, attempt);
+        if (result > max) {
+          return absl::ToInt64Milliseconds(max);
+        }
+        return absl::ToInt64Milliseconds(result);
+      }
+      default:
+        return default_backoff;
+    }
+  }
+};
+
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/rocketmq/include/StsCredentialsProviderImpl.h b/src/main/cpp/base/include/StsCredentialsProviderImpl.h
similarity index 100%
rename from src/main/cpp/rocketmq/include/StsCredentialsProviderImpl.h
rename to src/main/cpp/base/include/StsCredentialsProviderImpl.h
diff --git a/src/main/cpp/base/include/DigestType.h b/src/main/cpp/base/include/SubscriptionEntry.h
similarity index 84%
copy from src/main/cpp/base/include/DigestType.h
copy to src/main/cpp/base/include/SubscriptionEntry.h
index e255d82..9256242 100644
--- a/src/main/cpp/base/include/DigestType.h
+++ b/src/main/cpp/base/include/SubscriptionEntry.h
@@ -17,16 +17,17 @@
 #pragma once
 
 #include <cstdint>
+#include <string>
 
+#include "FilterExpression.h"
+#include "Resource.h"
 #include "rocketmq/RocketMQ.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-enum class DigestType : int8_t
-{
-  CRC32 = 0,
-  MD5 = 1,
-  SHA1 = 2,
+struct SubscriptionEntry {
+  Resource topic;
+  FilterExpression expression;
 };
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/base/tests/AssignmentTest.cpp b/src/main/cpp/base/tests/AssignmentTest.cpp
new file mode 100644
index 0000000..88c3c5a
--- /dev/null
+++ b/src/main/cpp/base/tests/AssignmentTest.cpp
@@ -0,0 +1,23 @@
+#include "gtest/gtest.h"
+#include <algorithm>
+
+#include "Protocol.h"
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+class AssignmentTest : public testing::Test {
+public:
+  void SetUp() override {
+  }
+
+  void TearDown() override {
+  }
+};
+
+TEST_F(AssignmentTest, testSort) {
+  std::vector<rmq::Assignment> assignments;
+  std::sort(assignments.begin(), assignments.end(),
+            [](const rmq::Assignment& lhs, const rmq::Assignment& rhs) { return lhs < rhs; });
+}
+
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/base/tests/BUILD.bazel b/src/main/cpp/base/tests/BUILD.bazel
new file mode 100644
index 0000000..054dfb5
--- /dev/null
+++ b/src/main/cpp/base/tests/BUILD.bazel
@@ -0,0 +1,54 @@
+load("@rules_cc//cc:defs.bzl", "cc_test")
+
+base_deps = [
+    "//src/main/cpp/base:base_library",
+    "@com_google_googletest//:gtest_main",
+]
+
+cc_test(
+    name = "message_builder_test",
+    srcs = [
+        "MessageBuilderTest.cpp",
+    ],
+    deps = base_deps,
+)
+
+cc_test(
+    name = "assignment_test",
+    srcs = [
+        "AssignmentTest.cpp",
+    ],
+    deps = base_deps,
+)
+
+cc_test(
+    name = "message_queue_test",
+    srcs = [
+        "MessageQueueTest.cpp",
+    ],
+    deps = base_deps,
+)
+
+cc_test(
+    name = "configuration_test",
+    srcs = [
+        "ConfigurationTest.cpp",
+    ],
+    deps = base_deps,
+)
+
+cc_test(
+    name = "mix_all_test",
+    srcs = [
+        "MixAllTest.cpp",
+    ],
+    deps = base_deps,
+)
+
+cc_test(
+    name = "retry_policy_test",
+    srcs = [
+        "RetryPolicyTest.cpp",
+    ],
+    deps = base_deps,
+)
\ No newline at end of file
diff --git a/src/main/cpp/base/tests/ConfigurationTest.cpp b/src/main/cpp/base/tests/ConfigurationTest.cpp
new file mode 100644
index 0000000..9174e39
--- /dev/null
+++ b/src/main/cpp/base/tests/ConfigurationTest.cpp
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#include <chrono>
+#include <memory>
+
+#include "gtest/gtest.h"
+#include "rocketmq/Configuration.h"
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+class ConfigurationTest : public testing::Test {
+public:
+protected:
+  std::string               endpoints_{"8.8.8.8:80;8.8.4.4:80"};
+  std::chrono::milliseconds request_timeout_{std::chrono::seconds(1)};
+};
+
+TEST_F(ConfigurationTest, testEndpoints) {
+  auto configuration = Configuration::newBuilder().withEndpoints(endpoints_).build();
+  ASSERT_EQ(endpoints_, configuration.endpoints());
+}
+
+TEST_F(ConfigurationTest, testCredentialsProvider) {
+  std::string access_key           = "ak";
+  std::string access_secret        = "as";
+  auto        credentials_provider = std::make_shared<StaticCredentialsProvider>(access_key, access_secret);
+  auto        configuration        = Configuration::newBuilder().withCredentialsProvider(credentials_provider).build();
+  auto        credentials          = configuration.credentialsProvider()->getCredentials();
+
+  ASSERT_EQ(access_key, credentials.accessKey());
+  ASSERT_EQ(access_secret, credentials.accessSecret());
+}
+
+TEST_F(ConfigurationTest, testRequestTimeout) {
+  auto configuration = Configuration::newBuilder().withRequestTimeout(request_timeout_).build();
+  ASSERT_EQ(request_timeout_, configuration.requestTimeout());
+}
+
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/base/tests/MessageBuilderTest.cpp b/src/main/cpp/base/tests/MessageBuilderTest.cpp
new file mode 100644
index 0000000..9ad4d58
--- /dev/null
+++ b/src/main/cpp/base/tests/MessageBuilderTest.cpp
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+#include <vector>
+
+#include "MessageExt.h"
+#include "gtest/gtest.h"
+#include "rocketmq/Message.h"
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+class MessageBuilderTest : public testing::Test {
+protected:
+  std::string topic_{"TestTopic"};
+  std::string tag_{"TagA"};
+  std::vector<std::string> keys_{"k1", "k2"};
+  std::string body_{"sample body content"};
+  std::string group_{"message-group"};
+};
+
+TEST_F(MessageBuilderTest, testBuilder) {
+  MessageConstPtr message =
+      Message::newBuilder().withTopic(topic_).withTag(tag_).withKeys(keys_).withBody(body_).build();
+  ASSERT_EQ(topic_, message->topic());
+  ASSERT_EQ(tag_, message->tag());
+  ASSERT_TRUE(keys_ == message->keys());
+  ASSERT_EQ(body_, message->body());
+  ASSERT_EQ(false, message->traceContext().has_value());
+}
+
+TEST_F(MessageBuilderTest, testBuilder2) {
+  for (std::size_t i = 0; i < 128; i++) {
+    MessageConstPtr message =
+        Message::newBuilder().withTopic(topic_).withTag(tag_).withKeys(keys_).withBody(body_).build();
+    ASSERT_EQ(topic_, message->topic());
+    ASSERT_EQ(tag_, message->tag());
+    ASSERT_TRUE(keys_ == message->keys());
+    ASSERT_EQ(body_, message->body());
+    ASSERT_EQ(false, message->traceContext().has_value());
+  }
+}
+
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/base/tests/MessageQueueTest.cpp b/src/main/cpp/base/tests/MessageQueueTest.cpp
new file mode 100644
index 0000000..2db2c83
--- /dev/null
+++ b/src/main/cpp/base/tests/MessageQueueTest.cpp
@@ -0,0 +1,21 @@
+#include <apache/rocketmq/v2/definition.pb.h>
+#include <cstdint>
+
+#include "absl/container/flat_hash_map.h"
+#include "google/protobuf/map.h"
+#include "gtest/gtest.h"
+
+#include "Protocol.h"
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+class MessageQueueTest : public testing::Test {
+public:
+  void SetUp() override {
+  }
+
+  void TearDown() override {
+  }
+};
+
+ROCKETMQ_NAMESPACE_END
diff --git a/src/test/cpp/ut/rocketmq/ConsumerTest.cpp b/src/main/cpp/base/tests/MixAllTest.cpp
similarity index 84%
rename from src/test/cpp/ut/rocketmq/ConsumerTest.cpp
rename to src/main/cpp/base/tests/MixAllTest.cpp
index 0c950c2..e66030e 100644
--- a/src/test/cpp/ut/rocketmq/ConsumerTest.cpp
+++ b/src/main/cpp/base/tests/MixAllTest.cpp
@@ -14,14 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include "ConsumerMock.h"
-#include "gmock/gmock.h"
+#include "MixAll.h"
 #include "gtest/gtest.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-TEST(ConsumerMockTest, testMock) {
-  testing::NiceMock<ConsumerMock> mock;
+TEST(MixAllTest, testOsName) {
+  const char* os_name = MixAll::osName();
+  std::cout << os_name << std::endl;
 }
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/test/cpp/ut/remoting/QueryRouteRequestHeaderTest.cpp b/src/main/cpp/base/tests/RetryPolicyTest.cpp
similarity index 64%
rename from src/test/cpp/ut/remoting/QueryRouteRequestHeaderTest.cpp
rename to src/main/cpp/base/tests/RetryPolicyTest.cpp
index d887ba6..4a49bcc 100644
--- a/src/test/cpp/ut/remoting/QueryRouteRequestHeaderTest.cpp
+++ b/src/main/cpp/base/tests/RetryPolicyTest.cpp
@@ -14,23 +14,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include "QueryRouteRequestHeader.h"
-
+#include "RetryPolicy.h"
 #include "gtest/gtest.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-TEST(QueryRouteRequestHeaderTest, testEncode) {
-  google::protobuf::Value root;
-  QueryRouteRequestHeader header;
-  header.topic("abc");
-  header.encode(root);
-
-  std::string json;
-  auto status = google::protobuf::util::MessageToJsonString(root, &json);
-  EXPECT_TRUE(status.ok());
-  EXPECT_FALSE(json.empty());
-  std::cout << json << std::endl;
+TEST(RetryPolicyTest, testBackoff) {
+  RetryPolicy policy{.max_attempt = 3,
+                     .strategy = BackoffStrategy::Customized,
+                     .next = {absl::Milliseconds(10), absl::Milliseconds(100), absl::Milliseconds(500)}};
+  ASSERT_EQ(policy.backoff(1), 10);
+  ASSERT_EQ(policy.backoff(2), 100);
+  ASSERT_EQ(policy.backoff(3), 500);
+  ASSERT_EQ(policy.backoff(4), 500);
+  ASSERT_EQ(policy.backoff(10000), 500);
 }
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/client/ClientConfigImpl.cpp b/src/main/cpp/client/ClientConfigImpl.cpp
deleted file mode 100644
index 29304e0..0000000
--- a/src/main/cpp/client/ClientConfigImpl.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.
- */
-#include "ClientConfigImpl.h"
-
-#include <chrono>
-#include <sstream>
-#include <string>
-
-#ifndef _WIN32
-#include <unistd.h>
-#endif
-
-#include "UtilAll.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-#ifndef CLIENT_VERSION_MAJOR
-#define CLIENT_VERSION_MAJOR "5"
-#endif
-
-#ifndef CLIENT_VERSION_MINOR
-#define CLIENT_VERSION_MINOR "0"
-#endif
-
-#ifndef CLIENT_VERSION_PATCH
-#define CLIENT_VERSION_PATCH "0"
-#endif
-
-const char* ClientConfigImpl::CLIENT_VERSION = CLIENT_VERSION_MAJOR "." CLIENT_VERSION_MINOR "." CLIENT_VERSION_PATCH;
-
-std::string ClientConfigImpl::steadyName() {
-  auto duration = std::chrono::steady_clock::now().time_since_epoch();
-  return std::to_string(std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count());
-}
-
-ClientConfigImpl::ClientConfigImpl(absl::string_view group_name)
-    : group_name_(group_name.data(), group_name.length()), io_timeout_(absl::Seconds(3)),
-      long_polling_timeout_(absl::Seconds(30)) {
-}
-
-std::string ClientConfigImpl::clientId() const {
-  std::stringstream ss;
-  ss << UtilAll::hostname();
-  ss << "@";
-  std::string processID = std::to_string(getpid());
-  ss << processID << "#";
-  ss << instance_name_;
-  return ss.str();
-}
-
-const std::string& ClientConfigImpl::getInstanceName() const {
-  return instance_name_;
-}
-
-void ClientConfigImpl::setInstanceName(std::string instance_name) {
-  instance_name_ = std::move(instance_name);
-}
-
-const std::string& ClientConfigImpl::getGroupName() const {
-  return group_name_;
-}
-
-void ClientConfigImpl::setGroupName(std::string group_name) {
-  group_name_ = std::move(group_name);
-}
-
-void ClientConfigImpl::setIoTimeout(absl::Duration timeout) {
-  io_timeout_ = timeout;
-}
-
-void ClientConfigImpl::setCredentialsProvider(CredentialsProviderPtr credentials_provider) {
-  credentials_provider_ = std::move(credentials_provider);
-}
-
-CredentialsProviderPtr ClientConfigImpl::credentialsProvider() {
-  return credentials_provider_;
-}
-
-absl::Duration ClientConfigImpl::getIoTimeout() const {
-  return io_timeout_;
-}
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/client/ClientManagerFactory.cpp b/src/main/cpp/client/ClientManagerFactory.cpp
index c72aedb..3cacaae 100644
--- a/src/main/cpp/client/ClientManagerFactory.cpp
+++ b/src/main/cpp/client/ClientManagerFactory.cpp
@@ -27,20 +27,20 @@ ClientManagerFactory& ClientManagerFactory::getInstance() {
 ClientManagerPtr ClientManagerFactory::getClientManager(const ClientConfig& client_config) {
   {
     absl::MutexLock lock(&client_manager_table_mtx_);
-    auto search = client_manager_table_.find(client_config.resourceNamespace());
+    auto search = client_manager_table_.find(client_config.resource_namespace);
     if (search != client_manager_table_.end()) {
       ClientManagerPtr client_manager = search->second.lock();
       if (client_manager) {
-        SPDLOG_DEBUG("Re-use existing client_manager[resource_namespace={}]", client_config.resourceNamespace());
+        SPDLOG_DEBUG("Re-use existing client_manager[resource_namespace={}]", client_config.resource_namespace);
         return client_manager;
       } else {
-        client_manager_table_.erase(client_config.resourceNamespace());
+        client_manager_table_.erase(client_config.resource_namespace);
       }
     }
-    ClientManagerPtr client_manager = std::make_shared<ClientManagerImpl>(client_config.resourceNamespace());
+    ClientManagerPtr client_manager = std::make_shared<ClientManagerImpl>(client_config.resource_namespace);
     std::weak_ptr<ClientManager> client_instance_weak_ptr(client_manager);
-    client_manager_table_.insert_or_assign(client_config.resourceNamespace(), client_instance_weak_ptr);
-    SPDLOG_INFO("Created a new client manager[resource_namespace={}]", client_config.resourceNamespace());
+    client_manager_table_.insert_or_assign(client_config.resource_namespace, client_instance_weak_ptr);
+    SPDLOG_INFO("Created a new client manager[resource_namespace={}]", client_config.resource_namespace);
     return client_manager;
   }
 }
diff --git a/src/main/cpp/client/ClientManagerImpl.cpp b/src/main/cpp/client/ClientManagerImpl.cpp
index d8a43e5..25fc559 100644
--- a/src/main/cpp/client/ClientManagerImpl.cpp
+++ b/src/main/cpp/client/ClientManagerImpl.cpp
@@ -17,59 +17,45 @@
 #include "ClientManagerImpl.h"
 
 #include <atomic>
+#include <cassert>
 #include <chrono>
 #include <memory>
 #include <system_error>
 #include <utility>
 #include <vector>
 
-#include "ReceiveMessageResult.h"
-#include "Scheduler.h"
-#include "google/rpc/code.pb.h"
-
 #include "InvocationContext.h"
 #include "LogInterceptor.h"
 #include "LogInterceptorFactory.h"
 #include "LoggerImpl.h"
-#include "MessageAccessor.h"
+#include "MessageExt.h"
 #include "MetadataConstants.h"
 #include "MixAll.h"
-#include "Partition.h"
 #include "Protocol.h"
+#include "ReceiveMessageContext.h"
 #include "RpcClient.h"
 #include "RpcClientImpl.h"
+#include "Scheduler.h"
 #include "TlsHelper.h"
 #include "UtilAll.h"
+#include "google/protobuf/util/time_util.h"
 #include "grpcpp/create_channel.h"
 #include "rocketmq/ErrorCode.h"
-#include "rocketmq/MQMessageExt.h"
+#include "rocketmq/SendReceipt.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
 ClientManagerImpl::ClientManagerImpl(std::string resource_namespace)
     : scheduler_(std::make_shared<SchedulerImpl>()), resource_namespace_(std::move(resource_namespace)),
-      state_(State::CREATED), completion_queue_(std::make_shared<CompletionQueue>()),
+      state_(State::CREATED),
       callback_thread_pool_(absl::make_unique<ThreadPoolImpl>(std::thread::hardware_concurrency())),
       latency_histogram_("Message-Latency", 11) {
   spdlog::set_level(spdlog::level::trace);
   assignLabels(latency_histogram_);
-  server_authorization_check_config_ = std::make_shared<grpc::experimental::TlsServerAuthorizationCheckConfig>(
-      std::make_shared<TlsServerAuthorizationChecker>());
-
-  // Make use of encryption only at the moment.
-  std::vector<grpc::experimental::IdentityKeyCertPair> identity_key_cert_list;
-  grpc::experimental::IdentityKeyCertPair pair{};
-  pair.private_key = TlsHelper::client_private_key;
-  pair.certificate_chain = TlsHelper::client_certificate_chain;
-
-  identity_key_cert_list.emplace_back(pair);
-  certificate_provider_ =
-      std::make_shared<grpc::experimental::StaticDataCertificateProvider>(TlsHelper::CA, identity_key_cert_list);
-  tls_channel_credential_options_.set_server_verification_option(GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION);
-  tls_channel_credential_options_.set_certificate_provider(certificate_provider_);
-  tls_channel_credential_options_.set_server_authorization_check_config(server_authorization_check_config_);
-  tls_channel_credential_options_.watch_root_certs();
-  tls_channel_credential_options_.watch_identity_key_cert_pairs();
+
+  certificate_verifier_ = grpc::experimental::ExternalCertificateVerifier::Create<InsecureCertificateVerifier>();
+  tls_channel_credential_options_.set_verify_server_certs(false);
+  tls_channel_credential_options_.set_check_call_host(false);
   channel_credential_ = grpc::experimental::TlsCredentials(tls_channel_credential_options_);
 
   // Use unlimited receive message size.
@@ -97,6 +83,8 @@ ClientManagerImpl::ClientManagerImpl(std::string resource_namespace)
    */
   channel_arguments_.SetInt(GRPC_ARG_ENABLE_RETRIES, 0);
 
+  channel_arguments_.SetSslTargetNameOverride("localhost");
+
   SPDLOG_INFO("ClientManager[ResourceNamespace={}] created", resource_namespace_);
 }
 
@@ -118,14 +106,6 @@ void ClientManagerImpl::start() {
 
   std::weak_ptr<ClientManagerImpl> client_instance_weak_ptr = shared_from_this();
 
-  auto health_check_functor = [client_instance_weak_ptr]() {
-    auto client_instance = client_instance_weak_ptr.lock();
-    if (client_instance) {
-      client_instance->doHealthCheck();
-    }
-  };
-  health_check_task_id_ = scheduler_->schedule(health_check_functor, HEALTH_CHECK_TASK_NAME, std::chrono::seconds(5),
-                                               std::chrono::seconds(5));
   auto heartbeat_functor = [client_instance_weak_ptr]() {
     auto client_instance = client_instance_weak_ptr.lock();
     if (client_instance) {
@@ -134,8 +114,7 @@ void ClientManagerImpl::start() {
   };
   heartbeat_task_id_ =
       scheduler_->schedule(heartbeat_functor, HEARTBEAT_TASK_NAME, std::chrono::seconds(1), std::chrono::seconds(10));
-
-  completion_queue_thread_ = std::thread(std::bind(&ClientManagerImpl::pollCompletionQueue, this));
+  SPDLOG_DEBUG("Heartbeat task-id={}", heartbeat_task_id_);
 
   auto stats_functor_ = [client_instance_weak_ptr]() {
     auto client_instance = client_instance_weak_ptr.lock();
@@ -158,10 +137,6 @@ void ClientManagerImpl::shutdown() {
 
   callback_thread_pool_->shutdown();
 
-  if (health_check_task_id_) {
-    scheduler_->cancel(health_check_task_id_);
-  }
-
   if (heartbeat_task_id_) {
     scheduler_->cancel(heartbeat_task_id_);
   }
@@ -175,17 +150,11 @@ void ClientManagerImpl::shutdown() {
   {
     absl::MutexLock lk(&rpc_clients_mtx_);
     rpc_clients_.clear();
-    SPDLOG_DEBUG("CompletionQueue of active clients stopped");
+    SPDLOG_DEBUG("rpc_clients_ is clear");
   }
 
-  completion_queue_->Shutdown();
-  if (completion_queue_thread_.joinable()) {
-    completion_queue_thread_.join();
-  }
-  SPDLOG_DEBUG("Completion queue thread completes OK");
-
   state_.store(State::STOPPED, std::memory_order_relaxed);
-  SPDLOG_DEBUG("Client instance stopped");
+  SPDLOG_DEBUG("ClientManager stopped");
 }
 
 void ClientManagerImpl::assignLabels(Histogram& histogram) {
@@ -202,102 +171,6 @@ void ClientManagerImpl::assignLabels(Histogram& histogram) {
   histogram.labels().emplace_back("[200ms~inf): ");
 }
 
-void ClientManagerImpl::healthCheck(
-    const std::string& target_host, const Metadata& metadata, const HealthCheckRequest& request,
-    std::chrono::milliseconds timeout,
-    const std::function<void(const std::error_code&, const InvocationContext<HealthCheckResponse>*)>& cb) {
-  std::error_code ec;
-  auto client = getRpcClient(target_host);
-  if (!client) {
-    ec = ErrorCode::RequestTimeout;
-    cb(ec, nullptr);
-    return;
-  }
-
-  SPDLOG_DEBUG("Prepare to send health-check to {}. Request: {}", target_host, request.DebugString());
-
-  auto invocation_context = new InvocationContext<HealthCheckResponse>();
-  invocation_context->task_name = fmt::format("HealthCheck to {}", target_host);
-  invocation_context->remote_address = target_host;
-  invocation_context->context.set_deadline(std::chrono::system_clock::now() + timeout);
-
-  for (const auto& entry : metadata) {
-    invocation_context->context.AddMetadata(entry.first, entry.second);
-  }
-
-  auto callback = [cb](const InvocationContext<HealthCheckResponse>* ctx) {
-    std::error_code ec;
-    if (!ctx->status.ok()) {
-      ec = ErrorCode::RequestTimeout;
-      cb(ec, ctx);
-      return;
-    }
-
-    const auto& common = ctx->response.common();
-    switch (common.status().code()) {
-      case google::rpc::Code::OK: {
-        cb(ec, ctx);
-      } break;
-      case google::rpc::Code::UNAUTHENTICATED: {
-        SPDLOG_WARN("Unauthenticated: {}", common.status().message());
-        ec = ErrorCode::Unauthorized;
-        cb(ec, ctx);
-      } break;
-      case google::rpc::Code::PERMISSION_DENIED: {
-        SPDLOG_WARN("PermissionDenied: {}", common.status().message());
-        ec = ErrorCode::Forbidden;
-        cb(ec, ctx);
-      } break;
-      case google::rpc::Code::INTERNAL: {
-        SPDLOG_WARN("InternalServerError: {}", common.status().message());
-        ec = ErrorCode::InternalServerError;
-        cb(ec, ctx);
-      } break;
-      default: {
-        SPDLOG_WARN("NotImplemented: please upgrade SDK to latest release");
-        ec = ErrorCode::NotImplemented;
-        cb(ec, ctx);
-      } break;
-    }
-  };
-
-  invocation_context->callback = callback;
-  client->asyncHealthCheck(request, invocation_context);
-}
-
-void ClientManagerImpl::doHealthCheck() {
-  SPDLOG_DEBUG("Start to perform health check for inactive clients");
-  if (State::STARTED != state_.load(std::memory_order_relaxed) &&
-      State::STARTING != state_.load(std::memory_order_relaxed)) {
-    SPDLOG_WARN("Unexpected client instance state={}.", state_.load(std::memory_order_relaxed));
-    return;
-  }
-
-  auto&& rpc_clients_removed = cleanOfflineRpcClients();
-
-  std::vector<std::shared_ptr<Client>> clients;
-  {
-    absl::MutexLock lk(&clients_mtx_);
-    for (auto& item : clients_) {
-      auto client = item.lock();
-      if (client && client->active()) {
-        clients.emplace_back(std::move(client));
-      }
-    }
-  }
-
-  if (!rpc_clients_removed.empty()) {
-    for (auto& client : clients) {
-      client->onRemoteEndpointRemoval(rpc_clients_removed);
-    }
-  }
-
-  for (auto& client : clients) {
-    client->healthCheck();
-  }
-  SPDLOG_DEBUG("Health check completed");
-}
-
 std::vector<std::string> ClientManagerImpl::cleanOfflineRpcClients() {
   absl::flat_hash_set<std::string> hosts;
   {
@@ -351,34 +224,30 @@ void ClientManagerImpl::heartbeat(const std::string& target_host, const Metadata
       return;
     }
 
-    const auto& common = invocation_context->response.common();
+    auto&& status = invocation_context->response.status();
     std::error_code ec;
-    switch (common.status().code()) {
-      case google::rpc::Code::OK: {
+    switch (status.code()) {
+      case rmq::Code::OK: {
         cb(ec, invocation_context->response);
       } break;
-      case google::rpc::Code::UNAUTHENTICATED: {
-        SPDLOG_WARN("Unauthenticated: {}", common.status().message());
+      case rmq::Code::UNAUTHORIZED: {
+        SPDLOG_WARN("Unauthorized: {}, host={}", status.message(), invocation_context->remote_address);
         ec = ErrorCode::Unauthorized;
         cb(ec, invocation_context->response);
       } break;
-      case google::rpc::Code::PERMISSION_DENIED: {
-        SPDLOG_WARN("PermissionDenied: {}", common.status().message());
+      case rmq::Code::FORBIDDEN: {
+        SPDLOG_WARN("Forbidden: {}, host={}", status.message(), invocation_context->remote_address);
         ec = ErrorCode::Forbidden;
         cb(ec, invocation_context->response);
       } break;
-      case google::rpc::Code::INVALID_ARGUMENT: {
-        SPDLOG_WARN("InvalidArgument: {}", common.status().message());
-        ec = ErrorCode::BadRequest;
-        cb(ec, invocation_context->response);
-      } break;
-      case google::rpc::Code::INTERNAL: {
-        SPDLOG_WARN("InternalServerError: {}", common.status().message());
+      case rmq::Code::INTERNAL_SERVER_ERROR: {
+        SPDLOG_WARN("InternalServerError: {}, host={}", status.message(), invocation_context->remote_address);
         ec = ErrorCode::InternalServerError;
         cb(ec, invocation_context->response);
       } break;
       default: {
-        SPDLOG_WARN("NotImplemented: Please upgrade SDK to latest release");
+        SPDLOG_WARN("NotImplemented: Please upgrade SDK to latest release. Message={}, host={}", status.message(),
+                    invocation_context->remote_address);
       } break;
     }
   };
@@ -391,60 +260,35 @@ void ClientManagerImpl::heartbeat(const std::string& target_host, const Metadata
 void ClientManagerImpl::doHeartbeat() {
   if (State::STARTED != state_.load(std::memory_order_relaxed) &&
       State::STARTING != state_.load(std::memory_order_relaxed)) {
-    SPDLOG_WARN("Unexpected client instance state={}.", state_.load(std::memory_order_relaxed));
+    SPDLOG_WARN("Unexpected client manager state={}.", state_.load(std::memory_order_relaxed));
     return;
   }
 
-  std::vector<std::shared_ptr<Client>> clients;
   {
     absl::MutexLock lk(&clients_mtx_);
     for (const auto& item : clients_) {
       auto client = item.lock();
       if (client && client->active()) {
-        clients.emplace_back(std::move(client));
-      }
-    }
-  }
-
-  for (auto& client : clients) {
-    client->heartbeat();
-  }
-}
-
-void ClientManagerImpl::pollCompletionQueue() {
-  while (State::STARTED == state_.load(std::memory_order_relaxed) ||
-         State::STARTING == state_.load(std::memory_order_relaxed)) {
-    bool ok = false;
-    void* opaque_invocation_context;
-    while (completion_queue_->Next(&opaque_invocation_context, &ok)) {
-      auto invocation_context = static_cast<BaseInvocationContext*>(opaque_invocation_context);
-      if (!ok) {
-        // the call is dead
-        SPDLOG_WARN("CompletionQueue#Next assigned ok false, indicating the call is dead");
+        client->heartbeat();
       }
-      auto callback = [invocation_context, ok]() { invocation_context->onCompletion(ok); };
-      callback_thread_pool_->submit(callback);
     }
-    SPDLOG_INFO("CompletionQueue is fully drained and shut down");
   }
-  SPDLOG_INFO("pollCompletionQueue completed and quit");
 }
 
 bool ClientManagerImpl::send(const std::string& target_host, const Metadata& metadata, SendMessageRequest& request,
-                             SendCallback* cb) {
+                             SendCallback cb) {
   assert(cb);
   SPDLOG_DEBUG("Prepare to send message to {} asynchronously", target_host);
   RpcClientSharedPtr client = getRpcClient(target_host);
   // Invocation context will be deleted in its onComplete() method.
   auto invocation_context = new InvocationContext<SendMessageResponse>();
-  invocation_context->task_name =
-      fmt::format("Send message[] to {}", request.message().system_attribute().message_id(), target_host);
+  invocation_context->task_name = fmt::format("Send message to {}", target_host);
   invocation_context->remote_address = target_host;
   for (const auto& entry : metadata) {
     invocation_context->context.AddMetadata(entry.first, entry.second);
   }
 
-  const std::string& topic = request.message().topic().name();
+  const std::string& topic = request.messages().begin()->topic().name();
   std::weak_ptr<ClientManager> client_manager(shared_from_this());
   auto completion_callback = [topic, cb,
                               client_manager](const InvocationContext<SendMessageResponse>* invocation_context) {
@@ -458,54 +302,51 @@ bool ClientManagerImpl::send(const std::string& target_host, const Metadata& met
       return;
     }
 
-    const auto& common = invocation_context->response.common();
-
+    SendReceipt send_receipt;
+    std::error_code ec;
     if (!invocation_context->status.ok()) {
       SPDLOG_WARN("Failed to send message to {} due to gRPC error. gRPC code: {}, gRPC error message: {}",
                   invocation_context->remote_address, invocation_context->status.error_code(),
                   invocation_context->status.error_message());
-      std::error_code ec = ErrorCode::RequestTimeout;
-      cb->onFailure(ec);
+      ec = ErrorCode::RequestTimeout;
+      cb(ec, send_receipt);
       return;
     }
 
-    if (invocation_context->status.ok()) {
-      switch (invocation_context->response.common().status().code()) {
-        case google::rpc::Code::OK: {
-          SendResult send_result;
-          send_result.setSendStatus(SendStatus::SEND_OK);
-          send_result.setMsgId(invocation_context->response.message_id());
-          send_result.setTransactionId(invocation_context->response.transaction_id());
-          cb->onSuccess(send_result);
-        } break;
-
-        case google::rpc::Code::INVALID_ARGUMENT: {
-          SPDLOG_WARN("InvalidArgument: {}", common.status().message());
-          std::error_code ec = ErrorCode::BadRequest;
-          cb->onFailure(ec);
-        } break;
-        case google::rpc::Code::UNAUTHENTICATED: {
-          SPDLOG_WARN("Unauthenticated: {}", common.status().message());
-          std::error_code ec = ErrorCode::Unauthorized;
-          cb->onFailure(ec);
-        } break;
-        case google::rpc::Code::PERMISSION_DENIED: {
-          SPDLOG_WARN("PermissionDenied: {}", common.status().message());
-          std::error_code ec = ErrorCode::Forbidden;
-          cb->onFailure(ec);
-        } break;
-        case google::rpc::Code::INTERNAL: {
-          SPDLOG_WARN("InternalServerError: {}", common.status().message());
-          std::error_code ec = ErrorCode::InternalServerError;
-          cb->onFailure(ec);
-        } break;
-        default: {
-          SPDLOG_WARN("Unsupported status code. Check and upgrade SDK to the latest");
-          std::error_code ec = ErrorCode::NotImplemented;
-          cb->onFailure(ec);
-        } break;
+    auto&& status = invocation_context->response.status();
+    switch (invocation_context->response.status().code()) {
+      case rmq::Code::OK: {
+        send_receipt.message_id = invocation_context->response.receipts().begin()->message_id();
+        break;
+      }
+      case rmq::Code::TOPIC_NOT_FOUND: {
+        SPDLOG_WARN("TopicNotFound: {}", status.message());
+        ec = ErrorCode::NotFound;
+        break;
+      }
+      case rmq::Code::UNAUTHORIZED: {
+        SPDLOG_WARN("Unauthenticated: {}", status.message());
+        ec = ErrorCode::Unauthorized;
+        break;
+      }
+      case rmq::Code::FORBIDDEN: {
+        SPDLOG_WARN("Forbidden: {}", status.message());
+        ec = ErrorCode::Forbidden;
+        cb(ec, send_receipt);
+        break;
+      }
+      case rmq::Code::INTERNAL_SERVER_ERROR: {
+        SPDLOG_WARN("InternalServerError: {}", status.message());
+        ec = ErrorCode::InternalServerError;
+        break;
+      }
+      default: {
+        SPDLOG_WARN("Unsupported status code. Check and upgrade SDK to the latest");
+        ec = ErrorCode::NotImplemented;
+        break;
       }
     }
+    cb(ec, send_receipt);
   };
 
   invocation_context->callback = completion_callback;
@@ -542,7 +383,8 @@ RpcClientSharedPtr ClientManagerImpl::getRpcClient(const std::string& target_hos
       interceptor_factories.emplace_back(absl::make_unique<LogInterceptorFactory>());
       auto channel = grpc::experimental::CreateCustomChannelWithInterceptors(
           target_host, channel_credential_, channel_arguments_, std::move(interceptor_factories));
-      client = std::make_shared<RpcClientImpl>(completion_queue_, channel, need_heartbeat);
+      std::weak_ptr<ClientManager> client_manager(shared_from_this());
+      client = std::make_shared<RpcClientImpl>(client_manager, channel, target_host, need_heartbeat);
       rpc_clients_.insert_or_assign(target_host, client);
     } else {
       client = search->second;
@@ -568,18 +410,27 @@ void ClientManagerImpl::cleanRpcClients() {
   rpc_clients_.clear();
 }
 
-SendResult ClientManagerImpl::processSendResponse(const MQMessageQueue& message_queue,
-                                                  const SendMessageResponse& response) {
-  if (google::rpc::Code::OK != response.common().status().code()) {
-    THROW_MQ_EXCEPTION(MQClientException, response.common().DebugString(), response.common().status().code());
+SendReceipt ClientManagerImpl::processSendResponse(const rmq::MessageQueue& message_queue,
+                                                   const SendMessageResponse& response, std::error_code& ec) {
+  SendReceipt send_receipt;
+
+  switch (response.status().code()) {
+    case rmq::Code::OK: {
+      assert(response.receipts_size() > 0);
+      send_receipt.message_id = response.receipts().begin()->message_id();
+      send_receipt.transaction_id = response.receipts().begin()->transaction_id();
+      return send_receipt;
+    }
+    case rmq::Code::ILLEGAL_TOPIC: {
+      ec = ErrorCode::BadRequest;
+      return send_receipt;
+    }
+    default: {
+      // TODO: handle other cases.
+      break;
+    }
   }
-  SendResult send_result;
-  send_result.setSendStatus(SendStatus::SEND_OK);
-  send_result.setMsgId(response.message_id());
-  send_result.setQueueOffset(-1);
-  send_result.setMessageQueue(message_queue);
-  send_result.setTransactionId(response.transaction_id());
-  return send_result;
+  return send_receipt;
 }
 
 void ClientManagerImpl::addClientObserver(std::weak_ptr<Client> client) {
@@ -618,81 +469,33 @@ void ClientManagerImpl::resolveRoute(const std::string& target_host, const Metad
     }
 
     std::error_code ec;
-    const auto& common = invocation_context->response.common();
-    switch (common.status().code()) {
-      case google::rpc::Code::OK: {
-        auto& partitions = invocation_context->response.partitions();
-        std::vector<Partition> topic_partitions;
-        for (const auto& partition : partitions) {
-          Topic t(partition.topic().resource_namespace(), partition.topic().name());
-
-          auto& broker = partition.broker();
-          AddressScheme scheme = AddressScheme::IPv4;
-          switch (broker.endpoints().scheme()) {
-            case rmq::AddressScheme::IPv4:
-              scheme = AddressScheme::IPv4;
-              break;
-            case rmq::AddressScheme::IPv6:
-              scheme = AddressScheme::IPv6;
-              break;
-            case rmq::AddressScheme::DOMAIN_NAME:
-              scheme = AddressScheme::DOMAIN_NAME;
-              break;
-            default:
-              break;
-          }
-
-          std::vector<Address> addresses;
-          for (const auto& address : broker.endpoints().addresses()) {
-            addresses.emplace_back(Address{address.host(), address.port()});
-          }
-          ServiceAddress service_address(scheme, addresses);
-          Broker b(partition.broker().name(), partition.broker().id(), service_address);
-
-          Permission permission = Permission::READ_WRITE;
-          switch (partition.permission()) {
-            case rmq::Permission::READ:
-              permission = Permission::READ;
-              break;
-
-            case rmq::Permission::WRITE:
-              permission = Permission::WRITE;
-              break;
-            case rmq::Permission::READ_WRITE:
-              permission = Permission::READ_WRITE;
-              break;
-            default:
-              break;
-          }
-          Partition topic_partition(t, partition.id(), permission, std::move(b));
-          topic_partitions.emplace_back(std::move(topic_partition));
+    auto&& status = invocation_context->response.status();
+    switch (status.code()) {
+      case rmq::Code::OK: {
+        std::vector<rmq::MessageQueue> message_queues;
+        for (const auto& item : invocation_context->response.message_queues()) {
+          message_queues.push_back(item);
         }
-        auto ptr =
-            std::make_shared<TopicRouteData>(std::move(topic_partitions), invocation_context->response.DebugString());
+        auto ptr = std::make_shared<TopicRouteData>(std::move(message_queues));
         cb(ec, ptr);
       } break;
-      case google::rpc::Code::UNAUTHENTICATED: {
-        SPDLOG_WARN("Unauthenticated: {}. Host={}", common.status().message(), invocation_context->remote_address);
+      case rmq::Code::UNAUTHORIZED: {
+        SPDLOG_WARN("Unauthorized: {}. Host={}", status.message(), invocation_context->remote_address);
         ec = ErrorCode::Unauthorized;
         cb(ec, nullptr);
       } break;
-      case google::rpc::Code::PERMISSION_DENIED: {
-        SPDLOG_WARN("PermissionDenied: {}. Host={}", common.status().message(), invocation_context->remote_address);
+      case rmq::Code::FORBIDDEN: {
+        SPDLOG_WARN("Forbidden: {}. Host={}", status.message(), invocation_context->remote_address);
         ec = ErrorCode::Forbidden;
         cb(ec, nullptr);
       } break;
-      case google::rpc::Code::INVALID_ARGUMENT: {
-        SPDLOG_WARN("InvalidArgument: {}. Host={}", common.status().message(), invocation_context->remote_address);
-        ec = ErrorCode::BadRequest;
-        cb(ec, nullptr);
-      } break;
-      case google::rpc::Code::NOT_FOUND: {
-        SPDLOG_WARN("NotFound: {}. Host={}", common.status().message(), invocation_context->remote_address);
+      case rmq::Code::TOPIC_NOT_FOUND: {
+        SPDLOG_WARN("TopicNotFound: {}. Host={}", status.message(), invocation_context->remote_address);
         ec = ErrorCode::NotFound;
         cb(ec, nullptr);
       } break;
-      case google::rpc::Code::INTERNAL: {
-        SPDLOG_WARN("InternalServerError: {}. Host={}", common.status().message(), invocation_context->remote_address);
+      case rmq::Code::INTERNAL_SERVER_ERROR: {
+        SPDLOG_WARN("InternalServerError: {}. Host={}", status.message(), invocation_context->remote_address);
         ec = ErrorCode::InternalServerError;
         cb(ec, nullptr);
       } break;
@@ -722,26 +525,22 @@ void ClientManagerImpl::queryAssignment(
       return;
     }
 
-    const auto& common = invocation_context->response.common();
+    auto&& status = invocation_context->response.status();
     std::error_code ec;
-    switch (common.status().code()) {
-      case google::rpc::Code::OK: {
+    switch (status.code()) {
+      case rmq::Code::OK: {
         SPDLOG_DEBUG("Query assignment OK");
       } break;
-      case google::rpc::Code::UNAUTHENTICATED: {
-        SPDLOG_WARN("Unauthenticated: {}, host={}", common.status().message(), invocation_context->remote_address);
+      case rmq::Code::UNAUTHORIZED: {
+        SPDLOG_WARN("Unauthorized: {}, host={}", status.message(), invocation_context->remote_address);
         ec = ErrorCode::Unauthorized;
       } break;
-      case google::rpc::Code::PERMISSION_DENIED: {
-        SPDLOG_WARN("PermissionDenied: {}, host={}", common.status().message(), invocation_context->remote_address);
+      case rmq::Code::FORBIDDEN: {
+        SPDLOG_WARN("Forbidden: {}, host={}", status.message(), invocation_context->remote_address);
         ec = ErrorCode::Forbidden;
       } break;
-      case google::rpc::Code::INVALID_ARGUMENT: {
-        SPDLOG_WARN("InvalidArgument: {}, host={}", common.status().message(), invocation_context->remote_address);
-        ec = ErrorCode::BadRequest;
-      } break;
-      case google::rpc::Code::INTERNAL: {
-        SPDLOG_WARN("InternalServerError: {}, host={}", common.status().message(), invocation_context->remote_address);
+      case rmq::Code::INTERNAL_SERVER_ERROR: {
+        SPDLOG_WARN("InternalServerError: {}, host={}", status.message(), invocation_context->remote_address);
         ec = ErrorCode::InternalServerError;
       } break;
       default: {
@@ -766,124 +565,53 @@ void ClientManagerImpl::queryAssignment(
 
 void ClientManagerImpl::receiveMessage(const std::string& target_host, const Metadata& metadata,
                                        const ReceiveMessageRequest& request, std::chrono::milliseconds timeout,
-                                       const std::shared_ptr<ReceiveMessageCallback>& cb) {
+                                       ReceiveMessageCallback cb) {
   SPDLOG_DEBUG("Prepare to receive message from {} asynchronously. Request: {}", target_host, request.DebugString());
   RpcClientSharedPtr client = getRpcClient(target_host);
-
-  auto invocation_context = new InvocationContext<ReceiveMessageResponse>();
-  invocation_context->task_name = fmt::format("ReceiveMessage from queue[{}-{}-{}-{}], host={}", request.group().name(),
-                                              request.partition().topic().name(), request.partition().broker().name(),
-                                              request.partition().id(), target_host);
-  invocation_context->remote_address = target_host;
-  if (!metadata.empty()) {
-    for (const auto& item : metadata) {
-      invocation_context->context.AddMetadata(item.first, item.second);
-    }
-  }
-  invocation_context->context.set_deadline(std::chrono::system_clock::now() + timeout);
-
-  auto callback = [this, cb](const InvocationContext<ReceiveMessageResponse>* invocation_context) {
-    std::error_code ec;
-    ReceiveMessageResult result;
-
-    // Handle network error.
-    if (!invocation_context->status.ok()) {
-      SPDLOG_WARN("Failed to pop messages through gRPC from {}, gRPC code: {}, gRPC error message: {}",
-                  invocation_context->remote_address, invocation_context->status.error_code(),
-                  invocation_context->status.error_message());
-      ec = ErrorCode::RequestTimeout;
-      cb->onCompletion(ec, result);
-      return;
-    }
-
-    // Handle application layer logic
-    result.source_host = invocation_context->remote_address;
-    const auto& common = invocation_context->response.common();
-    switch (common.status().code()) {
-      case google::rpc::Code::OK: {
-        SPDLOG_TRACE("ReceivedMessage Resonse: {}, host={}", invocation_context->response.DebugString(),
-                     invocation_context->remote_address);
-        for (auto& item : invocation_context->response.messages()) {
-          MQMessageExt message_ext;
-          MessageAccessor::setTargetEndpoint(message_ext, invocation_context->remote_address);
-          if (wrapMessage(item, message_ext)) {
-            result.messages.emplace_back(message_ext);
-          } else {
-            SPDLOG_WARN("A message fails to pass body checksum validation. Skip processing it.");
-          }
-        }
-        break;
-      }
-      case google::rpc::Code::UNAUTHENTICATED: {
-        SPDLOG_WARN("Unauthenticated: {}. Host={}", common.status().message(), invocation_context->remote_address);
-        ec = ErrorCode::Unauthorized;
-      } break;
-
-      case google::rpc::Code::PERMISSION_DENIED: {
-        SPDLOG_WARN("PermissionDenied: {}. Host={}", common.status().message(), invocation_context->remote_address);
-        ec = ErrorCode::Forbidden;
-      } break;
-
-      case google::rpc::Code::INVALID_ARGUMENT: {
-        SPDLOG_WARN("InvalidArgument: {}. Host={}", common.status().message(), invocation_context->remote_address);
-        ec = ErrorCode::BadRequest;
-      } break;
-
-      case google::rpc::Code::DEADLINE_EXCEEDED: {
-        SPDLOG_WARN("DeadlineExceeded: {}. Host={}", common.status().message(), invocation_context->remote_address);
-        ec = ErrorCode::GatewayTimeout;
-      } break;
-
-      case google::rpc::Code::INTERNAL: {
-        SPDLOG_WARN("IntervalServerError: {}. Host={}", common.status().message(), invocation_context->remote_address);
-        ec = ErrorCode::InternalServerError;
-      } break;
-      default: {
-        SPDLOG_WARN("Unsupported code. Please upgrade to use the latest release. Host={}",
-                    invocation_context->remote_address);
-        ec = ErrorCode::NotImplemented;
-      } break;
-    }
-    cb->onCompletion(ec, result);
-  };
-  invocation_context->callback = callback;
-  client->asyncReceive(request, invocation_context);
+  auto context = absl::make_unique<ReceiveMessageContext>();
+  context->callback = std::move(cb);
+  context->metadata = metadata;
+  context->timeout = timeout;
+  client->asyncReceive(request, std::move(context));
 }
 
 State ClientManagerImpl::state() const {
   return state_.load(std::memory_order_relaxed);
 }
 
-bool ClientManagerImpl::wrapMessage(const rmq::Message& item, MQMessageExt& message_ext) {
+MessageConstSharedPtr ClientManagerImpl::wrapMessage(const rmq::Message& item) {
   assert(item.topic().resource_namespace() == resource_namespace_);
+  auto builder = Message::newBuilder();
 
   // base
-  message_ext.setTopic(item.topic().name());
-
-  const auto& system_attributes = item.system_attribute();
+  builder.withTopic(item.topic().name());
 
-  // Receipt-handle
-  MessageAccessor::setReceiptHandle(message_ext, system_attributes.receipt_handle());
+  const auto& system_properties = item.system_properties();
 
   // Tag
-  message_ext.setTags(system_attributes.tag());
+  if (system_properties.has_tag()) {
+    builder.withTag(system_properties.tag());
+  }
 
   // Keys
   std::vector<std::string> keys;
-  for (const auto& key : system_attributes.keys()) {
+  for (const auto& key : system_properties.keys()) {
     keys.push_back(key);
   }
-  message_ext.setKeys(keys);
+  if (!keys.empty()) {
+    builder.withKeys(std::move(keys));
+  }
 
   // Message-Id
-  MessageAccessor::setMessageId(message_ext, system_attributes.message_id());
+  const auto& message_id = system_properties.message_id();
+  builder.withId(message_id);
 
   // Validate body digest
-  const rmq::Digest& digest = system_attributes.body_digest();
+  const rmq::Digest& digest = system_properties.body_digest();
   bool body_digest_match = false;
   if (item.body().empty()) {
     SPDLOG_WARN("Body of message[topic={}, msgId={}] is empty", item.topic().name(),
-                item.system_attribute().message_id());
+                item.system_properties().message_id());
     body_digest_match = true;
   } else {
     switch (digest.type()) {
@@ -908,10 +636,10 @@ bool ClientManagerImpl::wrapMessage(const rmq::Message& item, MQMessageExt& mess
         if (success) {
           body_digest_match = (digest.checksum() == checksum);
           if (body_digest_match) {
-            SPDLOG_DEBUG("Body of message[{}] MD5 checksum validation passed.", message_ext.getMsgId());
+            SPDLOG_DEBUG("Body of message[{}] MD5 checksum validation passed.", message_id);
           } else {
-            SPDLOG_WARN("Body of message[{}] MD5 checksum validation failed. Expect: {}, Actual: {}",
-                        message_ext.getMsgId(), digest.checksum(), checksum);
+            SPDLOG_WARN("Body of message[{}] MD5 checksum validation failed. Expect: {}, Actual: {}", message_id,
+                        digest.checksum(), checksum);
           }
         } else {
           SPDLOG_WARN("Failed to calculate MD5 digest. Skip.");
@@ -925,13 +653,13 @@ bool ClientManagerImpl::wrapMessage(const rmq::Message& item, MQMessageExt& mess
         if (success) {
           body_digest_match = (checksum == digest.checksum());
           if (body_digest_match) {
-            SPDLOG_DEBUG("Body of message[{}] SHA1 checksum validation passed", message_ext.getMsgId());
+            SPDLOG_DEBUG("Body of message[{}] SHA1 checksum validation passed", message_id);
           } else {
-            SPDLOG_WARN("Body of message[{}] SHA1 checksum validation failed. Expect: {}, Actual: {}",
-                        message_ext.getMsgId(), digest.checksum(), checksum);
+            SPDLOG_WARN("Body of message[{}] SHA1 checksum validation failed. Expect: {}, Actual: {}", message_id,
+                        digest.checksum(), checksum);
           }
         } else {
-          SPDLOG_WARN("Failed to calculate SHA1 digest for message[{}]. Skip.", message_ext.getMsgId());
+          SPDLOG_WARN("Failed to calculate SHA1 digest for message[{}]. Skip.", message_id);
         }
         break;
       }
@@ -944,21 +672,21 @@ bool ClientManagerImpl::wrapMessage(const rmq::Message& item, MQMessageExt& mess
   }
 
   if (!body_digest_match) {
-    SPDLOG_WARN("Message body checksum failed. MsgId={}", system_attributes.message_id());
+    SPDLOG_WARN("Message body checksum failed. MsgId={}", system_properties.message_id());
     // TODO: NACK it immediately
-    return false;
+    return nullptr;
   }
 
   // Body encoding
-  switch (system_attributes.body_encoding()) {
+  switch (system_properties.body_encoding()) {
     case rmq::Encoding::GZIP: {
       std::string uncompressed;
       UtilAll::uncompress(item.body(), uncompressed);
-      message_ext.setBody(uncompressed);
+      builder.withBody(uncompressed);
       break;
     }
     case rmq::Encoding::IDENTITY: {
-      message_ext.setBody(item.body());
+      builder.withBody(item.body());
       break;
     }
     default: {
@@ -967,106 +695,82 @@ bool ClientManagerImpl::wrapMessage(const rmq::Message& item, MQMessageExt& mess
     }
   }
 
-  timeval tv{};
-
-  // Message-type
-  MessageType message_type;
-  switch (system_attributes.message_type()) {
-    case rmq::MessageType::NORMAL:
-      message_type = MessageType::NORMAL;
-      break;
-    case rmq::MessageType::FIFO:
-      message_type = MessageType::FIFO;
-      break;
-    case rmq::MessageType::DELAY:
-      message_type = MessageType::DELAY;
-      break;
-    case rmq::MessageType::TRANSACTION:
-      message_type = MessageType::TRANSACTION;
-      break;
-    default:
-      SPDLOG_WARN("Unknown message type. Treat it as normal message");
-      message_type = MessageType::NORMAL;
-      break;
+  // User-properties
+  std::unordered_map<std::string, std::string> properties;
+  for (const auto& it : item.user_properties()) {
+    properties.insert(std::make_pair(it.first, it.second));
+  }
+  if (!properties.empty()) {
+    builder.withProperties(properties);
   }
-  MessageAccessor::setMessageType(message_ext, message_type);
 
   // Born-timestamp
-  if (system_attributes.has_born_timestamp()) {
-    tv.tv_sec = system_attributes.born_timestamp().seconds();
-    tv.tv_usec = system_attributes.born_timestamp().nanos() / 1000;
-    auto born_timestamp = absl::TimeFromTimeval(tv);
-    MessageAccessor::setBornTimestamp(message_ext, born_timestamp);
+  if (system_properties.has_born_timestamp()) {
+    auto born_timestamp = google::protobuf::util::TimeUtil::TimestampToMilliseconds(system_properties.born_timestamp());
+    builder.withBornTime(absl::ToChronoTime(absl::FromUnixMillis(born_timestamp)));
   }
 
   // Born-host
-  MessageAccessor::setBornHost(message_ext, system_attributes.born_host());
+  builder.withBornHost(system_properties.born_host());
+
+  // Trace-context
+  if (system_properties.has_trace_context()) {
+    builder.withTraceContext(system_properties.trace_context());
+  }
+
+  auto message = builder.build();
+
+  const Message* raw = message.release();
+  Message* msg = const_cast<Message*>(raw);
+  Extension& extension = msg->mutableExtension();
+
+  // Receipt-handle
+  extension.receipt_handle = system_properties.receipt_handle();
 
   // Store-timestamp
-  if (system_attributes.has_store_timestamp()) {
-    tv.tv_sec = system_attributes.store_timestamp().seconds();
-    tv.tv_usec = system_attributes.store_timestamp().nanos() / 1000;
-    MessageAccessor::setStoreTimestamp(message_ext, absl::TimeFromTimeval(tv));
+  if (system_properties.has_store_timestamp()) {
+    auto store_timestamp =
+        google::protobuf::util::TimeUtil::TimestampToMilliseconds(system_properties.store_timestamp());
+    extension.store_time = absl::ToChronoTime(absl::FromUnixMillis(store_timestamp));
   }
 
   // Store-host
-  MessageAccessor::setStoreHost(message_ext, system_attributes.store_host());
+  extension.store_host = system_properties.store_host();
 
   // Process one-of: delivery-timestamp and delay-level.
-  switch (system_attributes.timed_delivery_case()) {
-    case rmq::SystemAttribute::TimedDeliveryCase::kDelayLevel: {
-      message_ext.setDelayTimeLevel(system_attributes.delay_level());
-      break;
-    }
-
-    case rmq::SystemAttribute::TimedDeliveryCase::kDeliveryTimestamp: {
-      tv.tv_sec = system_attributes.delivery_timestamp().seconds();
-      tv.tv_usec = system_attributes.delivery_timestamp().nanos();
-      MessageAccessor::setDeliveryTimestamp(message_ext, absl::TimeFromTimeval(tv));
-      break;
-    }
-
-    default:
-      break;
+  if (system_properties.has_delivery_timestamp()) {
+    auto delivery_timestamp_ms =
+        google::protobuf::util::TimeUtil::TimestampToMilliseconds(system_properties.delivery_timestamp());
+    extension.delivery_timepoint = absl::ToChronoTime(absl::FromUnixMillis(delivery_timestamp_ms));
   }
 
-  // Partition-id
-  MessageAccessor::setQueueId(message_ext, system_attributes.partition_id());
+  // Queue-id
+  extension.queue_id = system_properties.queue_id();
 
-  // Partition-offset
-  MessageAccessor::setQueueOffset(message_ext, system_attributes.partition_offset());
+  // Queue-offset
+  extension.offset = system_properties.queue_offset();
 
   // Invisible-period
-  if (system_attributes.has_invisible_period()) {
-    absl::Duration invisible_period = absl::Seconds(system_attributes.invisible_period().seconds()) +
-                                      absl::Nanoseconds(system_attributes.invisible_period().nanos());
-    MessageAccessor::setInvisiblePeriod(message_ext, invisible_period);
+  if (system_properties.has_invisible_duration()) {
+    auto invisible_period = std::chrono::seconds(system_properties.invisible_duration().seconds()) +
+                            std::chrono::nanoseconds(system_properties.invisible_duration().nanos());
+    extension.invisible_period = invisible_period;
   }
 
   // Delivery attempt
-  MessageAccessor::setDeliveryAttempt(message_ext, system_attributes.delivery_attempt());
-
-  // Trace-context
-  MessageAccessor::setTraceContext(message_ext, system_attributes.trace_context());
+  extension.delivery_attempt = system_properties.delivery_attempt();
 
   // Decoded Time-Point
-  MessageAccessor::setDecodedTimestamp(message_ext, absl::Now());
-
-  // User-properties
-  std::map<std::string, std::string> properties;
-  for (const auto& it : item.user_attribute()) {
-    properties.insert(std::make_pair(it.first, it.second));
-  }
-  message_ext.setProperties(properties);
+  extension.decode_time = std::chrono::system_clock::now();
 
   // Extension
   {
-    auto elapsed = static_cast<int32_t>(absl::ToUnixMillis(absl::Now()) - message_ext.getStoreTimestamp());
+    auto elapsed = MixAll::millisecondsOf(std::chrono::system_clock::now() - extension.store_time);
     if (elapsed >= 0) {
       latency_histogram_.countIn(elapsed / 20);
     }
   }
-  return true;
+  return MessageConstSharedPtr(raw);
 }
 
 SchedulerSharedPtr ClientManagerImpl::getScheduler() {
@@ -1081,7 +785,7 @@ void ClientManagerImpl::ack(const std::string& target, const Metadata& metadata,
   RpcClientSharedPtr client = getRpcClient(target_host);
 
   auto invocation_context = new InvocationContext<AckMessageResponse>();
-  invocation_context->task_name = fmt::format("Ack message[{}] against {}", request.message_id(), target);
+  invocation_context->task_name = fmt::format("Ack messages against {}", target);
   invocation_context->remote_address = target_host;
   invocation_context->context.set_deadline(std::chrono::system_clock::now() + timeout);
 
@@ -1098,25 +802,21 @@ void ClientManagerImpl::ack(const std::string& target, const Metadata& metadata,
       return;
     }
 
-    const auto& common = invocation_context->response.common();
-    switch (common.status().code()) {
-      case google::rpc::Code::OK: {
+    auto&& status = invocation_context->response.status();
+    switch (status.code()) {
+      case rmq::Code::OK: {
         SPDLOG_DEBUG("Ack OK. host={}", invocation_context->remote_address);
       } break;
-      case google::rpc::Code::UNAUTHENTICATED: {
-        SPDLOG_WARN("Unauthenticated: {}, host={}", common.status().message(), invocation_context->remote_address);
+      case rmq::Code::UNAUTHORIZED: {
+        SPDLOG_WARN("Unauthorized: {}, host={}", status.message(), invocation_context->remote_address);
         ec = ErrorCode::Unauthorized;
       } break;
-      case google::rpc::Code::PERMISSION_DENIED: {
-        SPDLOG_WARN("PermissionDenied: {}, host={}", common.status().message(), invocation_context->remote_address);
+      case rmq::Code::FORBIDDEN: {
+        SPDLOG_WARN("PermissionDenied: {}, host={}", status.message(), invocation_context->remote_address);
         ec = ErrorCode::Forbidden;
       } break;
-      case google::rpc::Code::INVALID_ARGUMENT: {
-        SPDLOG_WARN("InvalidArgument: {}, host={}", common.status().message(), invocation_context->remote_address);
-        ec = ErrorCode::BadRequest;
-      } break;
-      case google::rpc::Code::INTERNAL: {
-        SPDLOG_WARN("InternalServerError: {}, host={}", common.status().message(), invocation_context->remote_address);
+      case rmq::Code::INTERNAL_SERVER_ERROR: {
+        SPDLOG_WARN("InternalServerError: {}, host={}", status.message(), invocation_context->remote_address);
         ec = ErrorCode::InternalServerError;
       } break;
       default: {
@@ -1130,13 +830,14 @@ void ClientManagerImpl::ack(const std::string& target, const Metadata& metadata,
   client->asyncAck(request, invocation_context);
 }
 
-void ClientManagerImpl::nack(const std::string& target_host, const Metadata& metadata,
-                             const NackMessageRequest& request, std::chrono::milliseconds timeout,
-                             const std::function<void(const std::error_code&)>& completion_callback) {
+void ClientManagerImpl::changeInvisibleDuration(
+    const std::string& target_host, const Metadata& metadata, const ChangeInvisibleDurationRequest& request,
+    std::chrono::milliseconds timeout, const std::function<void(const std::error_code&)>& completion_callback) {
   RpcClientSharedPtr client = getRpcClient(target_host);
   assert(client);
-  auto invocation_context = new InvocationContext<NackMessageResponse>();
-  invocation_context->task_name = fmt::format("Nack Message[{}] against {}", request.message_id(), target_host);
+  auto invocation_context = new InvocationContext<ChangeInvisibleDurationResponse>();
+  invocation_context->task_name = fmt::format("ChangeInvisibleDuration Message[receipt-handle={}] against {}",
+                                              request.receipt_handle(), target_host);
   invocation_context->remote_address = target_host;
   invocation_context->context.set_deadline(std::chrono::system_clock::now() + timeout);
 
@@ -1144,7 +845,7 @@ void ClientManagerImpl::nack(const std::string& target_host, const Metadata& met
     invocation_context->context.AddMetadata(item.first, item.second);
   }
 
-  auto callback = [completion_callback](const InvocationContext<NackMessageResponse>* invocation_context) {
+  auto callback = [completion_callback](const InvocationContext<ChangeInvisibleDurationResponse>* invocation_context) {
     if (!invocation_context->status.ok()) {
       SPDLOG_WARN("Failed to write Nack request to wire. gRPC-code: {}, gRPC-message: {}",
                   invocation_context->status.error_code(), invocation_context->status.error_message());
@@ -1154,24 +855,24 @@ void ClientManagerImpl::nack(const std::string& target_host, const Metadata& met
     }
 
     std::error_code ec;
-    const auto& common = invocation_context->response.common();
-    switch (common.status().code()) {
-      case google::rpc::Code::OK: {
+    auto&& status = invocation_context->response.status();
+    switch (status.code()) {
+      case rmq::Code::OK: {
         SPDLOG_DEBUG("Nack to {} OK", invocation_context->remote_address);
         break;
       };
-      case google::rpc::Code::UNAUTHENTICATED: {
-        SPDLOG_WARN("Unauthenticated: {}, host={}", common.status().message(), invocation_context->remote_address);
+      case rmq::Code::UNAUTHORIZED: {
+        SPDLOG_WARN("Unauthorized: {}, host={}", status.message(), invocation_context->remote_address);
         ec = ErrorCode::Unauthorized;
         break;
       }
-      case google::rpc::Code::PERMISSION_DENIED: {
-        SPDLOG_WARN("PermissionDenied: {}, host={}", common.status().message(), invocation_context->remote_address);
+      case rmq::Code::FORBIDDEN: {
+        SPDLOG_WARN("Forbidden: {}, host={}", status.message(), invocation_context->remote_address);
         ec = ErrorCode::Forbidden;
         break;
       }
-      case google::rpc::Code::INTERNAL: {
-        SPDLOG_WARN("InternalServerError: {}, host={}", common.status().message(), invocation_context->remote_address);
+      case rmq::Code::INTERNAL_SERVER_ERROR: {
+        SPDLOG_WARN("InternalServerError: {}, host={}", status.message(), invocation_context->remote_address);
         ec = ErrorCode::InternalServerError;
         break;
       }
@@ -1184,7 +885,7 @@ void ClientManagerImpl::nack(const std::string& target_host, const Metadata& met
     completion_callback(ec);
   };
   invocation_context->callback = callback;
-  client->asyncNack(request, invocation_context);
+  client->asyncChangeInvisibleDuration(request, invocation_context);
 }
 
 void ClientManagerImpl::endTransaction(
@@ -1225,26 +926,26 @@ void ClientManagerImpl::endTransaction(
       return;
     }
 
-    const auto& common = invocation_context->response.common();
-    switch (common.status().code()) {
-      case google::rpc::Code::OK: {
+    auto&& status = invocation_context->response.status();
+    switch (status.code()) {
+      case rmq::Code::OK: {
         SPDLOG_DEBUG("endTransaction completed OK. Response: {}, host={}", invocation_context->response.DebugString(),
                      invocation_context->remote_address);
       } break;
-      case google::rpc::Code::UNAUTHENTICATED: {
-        SPDLOG_WARN("Unauthenticated: {}, host={}", common.status().message(), invocation_context->remote_address);
+      case rmq::Code::UNAUTHORIZED: {
+        SPDLOG_WARN("Unauthorized: {}, host={}", status.message(), invocation_context->remote_address);
         ec = ErrorCode::Unauthorized;
       } break;
-      case google::rpc::Code::PERMISSION_DENIED: {
-        SPDLOG_WARN("PermissionDenied: {}, host={}", common.status().message(), invocation_context->remote_address);
+      case rmq::Code::FORBIDDEN: {
+        SPDLOG_WARN("Forbidden: {}, host={}", status.message(), invocation_context->remote_address);
         ec = ErrorCode::Forbidden;
       } break;
-      case google::rpc::INTERNAL: {
-        SPDLOG_WARN("InternalServerError: {}, host={}", common.status().message(), invocation_context->remote_address);
+      case rmq::Code::INTERNAL_SERVER_ERROR: {
+        SPDLOG_WARN("InternalServerError: {}, host={}", status.message(), invocation_context->remote_address);
         ec = ErrorCode::InternalServerError;
       } break;
       default: {
-        SPDLOG_WARN("NotImplemented: please upgrade SDK to latest release. {}, host={}", common.status().message(),
+        SPDLOG_WARN("NotImplemented: please upgrade SDK to latest release. {}, host={}", status.message(),
                     invocation_context->remote_address);
         ec = ErrorCode::NotImplemented;
       }
@@ -1256,177 +957,6 @@ void ClientManagerImpl::endTransaction(
   client->asyncEndTransaction(request, invocation_context);
 }
 
-void ClientManagerImpl::pollCommand(const std::string& target, const Metadata& metadata,
-                                    const PollCommandRequest& request, std::chrono::milliseconds timeout,
-                                    const std::function<void(const InvocationContext<PollCommandResponse>*)>& cb) {
-  auto client = getRpcClient(target);
-
-  auto invocation_context = new InvocationContext<PollCommandResponse>();
-  invocation_context->remote_address = target;
-  for (const auto& item : metadata) {
-    invocation_context->context.AddMetadata(item.first, item.second);
-  }
-  auto deadline = std::chrono::system_clock::now() + timeout;
-  invocation_context->context.set_deadline(deadline);
-
-  auto callback = [cb](const InvocationContext<PollCommandResponse>* invocation_context) { cb(invocation_context); };
-
-  invocation_context->callback = callback;
-  client->asyncPollCommand(request, invocation_context);
-}
-
-void ClientManagerImpl::queryOffset(const std::string& target_host, const Metadata& metadata,
-                                    const QueryOffsetRequest& request, std::chrono::milliseconds timeout,
-                                    const std::function<void(const std::error_code&, const QueryOffsetResponse&)>& cb) {
-  auto client = getRpcClient(target_host);
-  std::error_code ec;
-  if (!client) {
-    SPDLOG_WARN("Failed to get/create RPC client for {}", target_host);
-    ec = ErrorCode::RequestTimeout;
-    QueryOffsetResponse response;
-    cb(ec, response);
-    return;
-  }
-
-  auto invocation_context = new InvocationContext<QueryOffsetResponse>();
-  invocation_context->remote_address = target_host;
-  invocation_context->context.set_deadline(std::chrono::system_clock::now() + timeout);
-
-  for (const auto& entry : metadata) {
-    invocation_context->context.AddMetadata(entry.first, entry.second);
-  }
-
-  auto callback = [cb](const InvocationContext<QueryOffsetResponse>* invocation_context) {
-    std::error_code ec;
-
-    if (!invocation_context->status.ok()) {
-      SPDLOG_WARN("Failed to write QueryOffset request to wire. gRPC-code: {}, gRPC-message: {}, host={}",
-                  invocation_context->status.error_code(), invocation_context->status.error_message(),
-                  invocation_context->remote_address);
-      ec = ErrorCode::RequestTimeout;
-      cb(ec, invocation_context->response);
-      return;
-    }
-
-    const auto& common = invocation_context->response.common();
-    switch (common.status().code()) {
-      case google::rpc::Code::OK: {
-        SPDLOG_DEBUG("Query offset from server[host={}] OK", invocation_context->remote_address);
-        cb(ec, invocation_context->response);
-      } break;
-      case google::rpc::Code::UNAUTHENTICATED: {
-        SPDLOG_WARN("Unauthenticated: {}, host={}", common.status().message(), invocation_context->remote_address);
-        ec = ErrorCode::Unauthorized;
-        cb(ec, invocation_context->response);
-      } break;
-      case google::rpc::Code::PERMISSION_DENIED: {
-        SPDLOG_WARN("PermissionDenied: {}, host={}", common.status().message(), invocation_context->remote_address);
-        ec = ErrorCode::Forbidden;
-        cb(ec, invocation_context->response);
-      } break;
-      case google::rpc::Code::INTERNAL: {
-        SPDLOG_WARN("InternalServerError: {}, host={}", common.status().message(), invocation_context->remote_address);
-        ec = ErrorCode::InternalServerError;
-        cb(ec, invocation_context->response);
-      } break;
-      default: {
-        SPDLOG_WARN("NotImplemented: please upgrade SDK to the latest release. host={}",
-                    invocation_context->remote_address);
-        ec = ErrorCode::NotImplemented;
-        cb(ec, invocation_context->response);
-      }
-    }
-  };
-  invocation_context->callback = callback;
-  client->asyncQueryOffset(request, invocation_context);
-}
-
-void ClientManagerImpl::pullMessage(
-    const std::string& target_host, const Metadata& metadata, const PullMessageRequest& request,
-    std::chrono::milliseconds timeout,
-    const std::function<void(const std::error_code&, const ReceiveMessageResult&)>& cb) {
-  SPDLOG_DEBUG("PullMessage Request: {}, target_host={}", request.DebugString(), target_host);
-  auto client = getRpcClient(target_host);
-  auto invocation_context = new InvocationContext<PullMessageResponse>();
-  invocation_context->task_name = fmt::format("PullMessage for queue[{}-{}-{}-{}] from {}", request.group().name(),
-                                              request.partition().topic().name(), request.partition().broker().name(),
-                                              request.partition().id(), target_host);
-  invocation_context->remote_address = target_host;
-  invocation_context->context.set_deadline(std::chrono::system_clock::now() + timeout);
-  for (const auto& item : metadata) {
-    invocation_context->context.AddMetadata(item.first, item.second);
-  }
-
-  auto callback = [cb, this](const InvocationContext<PullMessageResponse>* invocation_context) {
-    std::error_code ec;
-    ReceiveMessageResult result;
-    result.source_host = invocation_context->remote_address;
-    // Handle network issue.
-    if (!invocation_context->status.ok()) {
-      ec = ErrorCode::RequestTimeout;
-      cb(ec, result);
-      return;
-    }
-
-    // Handle application layer logic: map status::code to corresponding error_code.
-    const auto& common = invocation_context->response.common();
-    result.min_offset = invocation_context->response.min_offset();
-    result.next_offset = invocation_context->response.next_offset();
-    result.max_offset = invocation_context->response.max_offset();
-    switch (common.status().code()) {
-      case google::rpc::Code::OK: {
-        SPDLOG_TRACE("Received PullMessage Response: {}, host={}", invocation_context->response.DebugString(),
-                     invocation_context->remote_address);
-        for (const auto& item : invocation_context->response.messages()) {
-          MQMessageExt message;
-          if (!wrapMessage(item, message)) {
-            return;
-          }
-          result.messages.emplace_back(message);
-        }
-      } break;
-      case google::rpc::Code::PERMISSION_DENIED: {
-        SPDLOG_WARN("PermissionDenied: {}, host={}", common.status().message(), invocation_context->remote_address);
-        ec = ErrorCode::Forbidden;
-      } break;
-      case google::rpc::Code::UNAUTHENTICATED: {
-        SPDLOG_WARN("Unauthenticated: {}, host={}", common.status().message(), invocation_context->remote_address);
-        ec = ErrorCode::Unauthorized;
-      } break;
-      case google::rpc::Code::NOT_FOUND: {
-        SPDLOG_WARN("NotFound: {}, host={}", common.status().message(), invocation_context->remote_address);
-        ec = ErrorCode::NotFound;
-        break;
-      }
-      case google::rpc::Code::DEADLINE_EXCEEDED: {
-        SPDLOG_WARN("DeadlineExceeded: {}, host={}", common.status().message(), invocation_context->remote_address);
-        ec = ErrorCode::GatewayTimeout;
-      } break;
-      case google::rpc::Code::INVALID_ARGUMENT: {
-        SPDLOG_WARN("InvalidArgument: {}, host={}", common.status().message(), invocation_context->remote_address);
-        ec = ErrorCode::BadRequest;
-      } break;
-      case google::rpc::Code::FAILED_PRECONDITION: {
-        SPDLOG_WARN("FailedPrecondition: {}, host={}", common.status().message(), invocation_context->remote_address);
-        ec = ErrorCode::PreconditionRequired;
-      } break;
-      case google::rpc::Code::INTERNAL: {
-        SPDLOG_WARN("InternalServerError: {}, host={}", common.status().message(), invocation_context->remote_address);
-        ec = ErrorCode::InternalServerError;
-      } break;
-      default: {
-        SPDLOG_WARN("Unimplemented: Please upgrade to use latest SDK release, host={}",
-                    invocation_context->remote_address);
-        ec = ErrorCode::NotImplemented;
-      } break;
-    }
-    cb(ec, result);
-  };
-
-  invocation_context->callback = callback;
-  client->asyncPull(request, invocation_context);
-}
-
 void ClientManagerImpl::forwardMessageToDeadLetterQueue(
     const std::string& target_host, const Metadata& metadata, const ForwardMessageToDeadLetterQueueRequest& request,
     std::chrono::milliseconds timeout,
@@ -1458,93 +988,6 @@ void ClientManagerImpl::forwardMessageToDeadLetterQueue(
   client->asyncForwardMessageToDeadLetterQueue(request, invocation_context);
 }
 
-std::error_code ClientManagerImpl::reportThreadStackTrace(const std::string& target_host, const Metadata& metadata,
-                                                          const ReportThreadStackTraceRequest& request,
-                                                          std::chrono::milliseconds timeout) {
-  std::error_code ec;
-  auto client = getRpcClient(target_host);
-  grpc::ClientContext context;
-  auto deadline = std::chrono::system_clock::now() + timeout;
-  context.set_deadline(deadline);
-
-  for (const auto& item : metadata) {
-    context.AddMetadata(item.first, item.second);
-  }
-
-  ReportThreadStackTraceResponse response;
-  auto status = client->reportThreadStackTrace(&context, request, &response);
-  if (!status.ok()) {
-    ec = ErrorCode::RequestTimeout;
-    SPDLOG_WARN("Failed to report thread-stack-trace to {}. Cause: {}", target_host, status.error_message());
-    return ec;
-  }
-
-  switch (response.common().status().code()) {
-    case google::rpc::Code::OK: {
-      return ec;
-    }
-    case google::rpc::Code::UNAUTHENTICATED: {
-      SPDLOG_WARN("Unauthorized. Host={}, Cause: {}", target_host, response.common().status().message());
-      ec = ErrorCode::Unauthorized;
-      break;
-    }
-    case google::rpc::Code::PERMISSION_DENIED: {
-      SPDLOG_WARN("Forbidden. Host={}, Cause: {}", target_host, response.common().status().message());
-      ec = ErrorCode::Forbidden;
-      break;
-    }
-    default: {
-      ec = ErrorCode::NotImplemented;
-      SPDLOG_WARN("Unsupported response code, please update client to latest release. Host={}", target_host);
-    }
-  }
-  return ec;
-}
-
-std::error_code ClientManagerImpl::reportMessageConsumptionResult(const std::string& target_host,
-                                                                  const Metadata& metadata,
-                                                                  const ReportMessageConsumptionResultRequest& request,
-                                                                  std::chrono::milliseconds timeout) {
-  std::error_code ec;
-  auto client = getRpcClient(target_host);
-  grpc::ClientContext context;
-  auto deadline = std::chrono::system_clock::now() + timeout;
-  context.set_deadline(deadline);
-
-  for (const auto& item : metadata) {
-    context.AddMetadata(item.first, item.second);
-  }
-
-  ReportMessageConsumptionResultResponse response;
-  auto status = client->reportMessageConsumptionResult(&context, request, &response);
-  if (!status.ok()) {
-    ec = ErrorCode::RequestTimeout;
-    SPDLOG_WARN("Failed to report thread-stack-trace to {}. Cause: {}", target_host, status.error_message());
-    return ec;
-  }
-
-  switch (response.common().status().code()) {
-    case google::rpc::Code::OK: {
-      return ec;
-    }
-    case google::rpc::Code::UNAUTHENTICATED: {
-      SPDLOG_WARN("Unauthorized. Host={}, Cause: {}", target_host, response.common().status().message());
-      ec = ErrorCode::Unauthorized;
-      break;
-    }
-    case google::rpc::Code::PERMISSION_DENIED: {
-      SPDLOG_WARN("Forbidden. Host={}, Cause: {}", target_host, response.common().status().message());
-      ec = ErrorCode::Forbidden;
-      break;
-    }
-    default: {
-      ec = ErrorCode::NotImplemented;
-      SPDLOG_WARN("Unsupported response code, please update client to latest release. Host={}", target_host);
-    }
-  }
-  return ec;
-}
-
 std::error_code ClientManagerImpl::notifyClientTermination(const std::string& target_host, const Metadata& metadata,
                                                            const NotifyClientTerminationRequest& request,
                                                            std::chrono::milliseconds timeout) {
@@ -1565,33 +1008,37 @@ std::error_code ClientManagerImpl::notifyClientTermination(const std::string& ta
   SPDLOG_DEBUG("NotifyClientTermination request: {}", request.DebugString());
 
   NotifyClientTerminationResponse response;
-  grpc::Status status = client->notifyClientTermination(&context, request, &response);
-  if (!status.ok()) {
-    SPDLOG_WARN("NotifyClientTermination failed. gRPC-code={}, gRPC-message={}, host={}", status.error_code(),
-                status.error_message(), target_host);
-    ec = ErrorCode::RequestTimeout;
-    return ec;
+  {
+    grpc::Status status = client->notifyClientTermination(&context, request, &response);
+    if (!status.ok()) {
+      SPDLOG_WARN("NotifyClientTermination failed. gRPC-code={}, gRPC-message={}, host={}", status.error_code(),
+                  status.error_message(), target_host);
+      ec = ErrorCode::RequestTimeout;
+      return ec;
+    }
   }
 
-  const auto& common = response.common();
+  auto&& status = response.status();
 
-  switch (common.status().code()) {
-    case google::rpc::Code::OK: {
+  switch (status.code()) {
+    case rmq::Code::OK: {
       SPDLOG_DEBUG("NotifyClientTermination OK. host={}", target_host);
       break;
     }
-    case google::rpc::Code::INTERNAL: {
-      SPDLOG_WARN("InternalServerError: Cause={}, host={}", common.status().message(), target_host);
+    case rmq::Code::INTERNAL_SERVER_ERROR: {
+      SPDLOG_WARN("InternalServerError: Cause={}, host={}", status.message(), target_host);
       ec = ErrorCode::InternalServerError;
       break;
     }
-    case google::rpc::Code::UNAUTHENTICATED: {
-      SPDLOG_WARN("Unauthenticated: Cause={}, host={}", common.status().message(), target_host);
+    case rmq::Code::UNAUTHORIZED: {
+      SPDLOG_WARN("Unauthorized due to lack of valid authentication credentials: Cause={}, host={}", status.message(),
+                  target_host);
       ec = ErrorCode::Unauthorized;
       break;
     }
-    case google::rpc::Code::PERMISSION_DENIED: {
-      SPDLOG_WARN("PermissionDenied: Cause={}, host={}", common.status().message(), target_host);
+    case rmq::Code::FORBIDDEN: {
+      SPDLOG_WARN("Forbidden due to insufficient permission to the resource: Cause={}, host={}", status.message(),
+                  target_host);
       ec = ErrorCode::Forbidden;
       break;
     }
@@ -1611,11 +1058,14 @@ void ClientManagerImpl::logStats() {
 }
 
 void ClientManagerImpl::submit(std::function<void()> task) {
+  State current_state = state();
+  if (current_state == State::STOPPING || current_state == State::STOPPED) {
+    return;
+  }
   callback_thread_pool_->submit(task);
 }
 
 const char* ClientManagerImpl::HEARTBEAT_TASK_NAME = "heartbeat-task";
 const char* ClientManagerImpl::STATS_TASK_NAME = "stats-task";
-const char* ClientManagerImpl::HEALTH_CHECK_TASK_NAME = "health-check-task";
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/client/ReceiveMessageStreamReader.cpp b/src/main/cpp/client/ReceiveMessageStreamReader.cpp
new file mode 100644
index 0000000..223c879
--- /dev/null
+++ b/src/main/cpp/client/ReceiveMessageStreamReader.cpp
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ */
+
+#include "ReceiveMessageStreamReader.h"
+
+#include "LoggerImpl.h"
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+ReceiveMessageStreamReader::ReceiveMessageStreamReader(std::weak_ptr<ClientManager> client_manager,
+                                                       rmq::MessagingService::Stub* stub,
+                                                       std::string peer_address,
+                                                       rmq::ReceiveMessageRequest request,
+                                                       std::unique_ptr<ReceiveMessageContext> context)
+    : client_manager_(client_manager),
+      stub_(stub),
+      peer_address_(std::move(peer_address)),
+      request_(std::move(request)),
+      context_(std::move(context)) {
+  for (const auto& entry : context_->metadata) {
+    client_context_.AddMetadata(entry.first, entry.second);
+  }
+  client_context_.set_deadline(std::chrono::system_clock::now() + context_->timeout);
+
+  stub_->async()->ReceiveMessage(&client_context_, &request_, this);
+  result_.source_host = peer_address_;
+  StartCall();
+  StartRead(&response_);
+}
+
+void ReceiveMessageStreamReader::OnReadDone(bool ok) {
+  if (ok) {
+    SPDLOG_DEBUG("ReceiveMessageStreamReader#OnReadDone: ok={}", ok);
+  } else {
+    if (result_.messages.empty() && !ec_) {
+      SPDLOG_WARN("ReceiveMessageStreamReader#OnReadDone: ok={}", ok);
+      ec_ = ErrorCode::BadGateway;
+    } else {
+      SPDLOG_DEBUG("ReceiveMessageStreamReader#OnReadDone reached end-of-stream");
+    }
+    return;
+  }
+
+  SPDLOG_DEBUG("ReceiveMessageStreamReader#OnReadDone: response={}", response_.DebugString());
+  switch (response_.content_case()) {
+    case rmq::ReceiveMessageResponse::ContentCase::kStatus: {
+      SPDLOG_DEBUG("ReceiveMessageResponse.status.message={}", response_.status().message());
+      switch (response_.status().code()) {
+        case rmq::Code::OK: {
+          break;
+        }
+        case rmq::Code::TOPIC_NOT_FOUND: {
+          ec_ = ErrorCode::TopicNotFound;
+          break;
+        }
+
+        case rmq::Code::CONSUMER_GROUP_NOT_FOUND: {
+          ec_ = ErrorCode::GroupNotFound;
+          break;
+        }
+        case rmq::Code::TOO_MANY_REQUESTS: {
+          ec_ = ErrorCode::TooManyRequest;
+          break;
+        }
+        case rmq::Code::MESSAGE_NOT_FOUND: {
+          ec_ = ErrorCode::NoContent;
+          break;
+        }
+        default:
+          SPDLOG_WARN("Unsupported code={}", response_.status().code());
+          break;
+      }
+      break;
+    }
+    case rmq::ReceiveMessageResponse::ContentCase::kMessage: {
+      auto client_manager = client_manager_.lock();
+      auto message = client_manager->wrapMessage(response_.message());
+      auto raw = const_cast<Message*>(message.get());
+      raw->mutableExtension().target_endpoint = peer_address_;
+      if (message) {
+        result_.messages.push_back(message);
+      }
+      break;
+    }
+    default:
+      break;
+  }
+
+  StartRead(&response_);
+}
+
+void ReceiveMessageStreamReader::OnDone(const grpc::Status& s) {
+  if (!s.ok()) {
+    SPDLOG_WARN("ReceiveMessageStreamReader#OnDone: status.ok={}, status.error_message={}", s.ok(), s.error_message());
+  } else {
+    SPDLOG_DEBUG("ReceiveMessageStreamReader#OnDone: status.ok={}", s.ok());
+  }
+
+  status_ = s;
+  context_->callback(ec_, result_);
+  delete this;
+}
+
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/client/RpcClientImpl.cpp b/src/main/cpp/client/RpcClientImpl.cpp
index 5d546b0..623547e 100644
--- a/src/main/cpp/client/RpcClientImpl.cpp
+++ b/src/main/cpp/client/RpcClientImpl.cpp
@@ -17,103 +17,115 @@
 #include "RpcClientImpl.h"
 
 #include <chrono>
+#include <functional>
+#include <sstream>
+#include <thread>
 
-#include "ClientConfigImpl.h"
-#include "TlsHelper.h"
 #include "absl/time/time.h"
 
-using ClientContext = grpc::ClientContext;
+#include "ClientManager.h"
+#include "ReceiveMessageStreamReader.h"
+#include "RpcClient.h"
+#include "TelemetryBidiReactor.h"
+#include "TlsHelper.h"
+#include "include/ReceiveMessageContext.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
+using ClientContext = grpc::ClientContext;
+
+void RpcClientImpl::asyncCallback(std::weak_ptr<RpcClient> client, BaseInvocationContext* invocation_context,
+                                  grpc::Status status) {
+
+  invocation_context->status = std::move(status);
+  std::shared_ptr<RpcClient> stub = client.lock();
+  if (!stub) {
+    SPDLOG_WARN("RpcClient has destructed. Response Ignored");
+    // TODO: execute orphan callback in event-loop thread?
+    // invocation_context->onCompletion(false);
+    // or
+    delete invocation_context;
+    return;
+  }
+
+  std::weak_ptr<ClientManager> client_manager = stub->clientManager();
+  std::shared_ptr<ClientManager> manager = client_manager.lock();
+  if (!manager) {
+    SPDLOG_WARN("ClientManager has destructed. Response ignored");
+    // TODO: execute orphan callback in event-loop thread?
+    // invocation_context->onCompletion(false);
+    // or
+    delete invocation_context;
+  }
+
+  auto task = [invocation_context, client] {
+    auto ptr = client.lock();
+    if (!ptr) {
+      // RPC client should have destructed.
+      return;
+    }
+    invocation_context->onCompletion(invocation_context->status.ok());
+  };
+
+  // Execute business post-processing in callback thread pool.
+  manager->submit(task);
+}
+
 void RpcClientImpl::asyncQueryRoute(const QueryRouteRequest& request,
                                     InvocationContext<QueryRouteResponse>* invocation_context) {
-  invocation_context->response_reader =
-      stub_->PrepareAsyncQueryRoute(&invocation_context->context, request, completion_queue_.get());
-  invocation_context->response_reader->StartCall();
-  invocation_context->response_reader->Finish(&invocation_context->response, &invocation_context->status,
-                                              invocation_context);
+  std::weak_ptr<RpcClient> rpc_client(shared_from_this());
+  auto callback = std::bind(&RpcClientImpl::asyncCallback, rpc_client, invocation_context, std::placeholders::_1);
+  stub_->async()->QueryRoute(&invocation_context->context, &request, &invocation_context->response, callback);
 }
 
 void RpcClientImpl::asyncSend(const SendMessageRequest& request,
                               InvocationContext<SendMessageResponse>* invocation_context) {
-  invocation_context->response_reader =
-      stub_->PrepareAsyncSendMessage(&invocation_context->context, request, completion_queue_.get());
-  invocation_context->response_reader->StartCall();
-  invocation_context->response_reader->Finish(&invocation_context->response, &invocation_context->status,
-                                              invocation_context);
+  std::weak_ptr<RpcClient> rpc_client(shared_from_this());
+  auto callback = std::bind(&RpcClientImpl::asyncCallback, rpc_client, invocation_context, std::placeholders::_1);
+  stub_->async()->SendMessage(&invocation_context->context, &request, &invocation_context->response, callback);
 }
 
 void RpcClientImpl::asyncQueryAssignment(const QueryAssignmentRequest& request,
                                          InvocationContext<QueryAssignmentResponse>* invocation_context) {
-  invocation_context->response_reader =
-      stub_->PrepareAsyncQueryAssignment(&invocation_context->context, request, completion_queue_.get());
-  invocation_context->response_reader->StartCall();
-  invocation_context->response_reader->Finish(&invocation_context->response, &invocation_context->status,
-                                              invocation_context);
-}
-
-std::shared_ptr<grpc::CompletionQueue>& rocketmq::RpcClientImpl::completionQueue() {
-  return completion_queue_;
+  std::weak_ptr<RpcClient> rpc_client(shared_from_this());
+  auto callback = std::bind(&RpcClientImpl::asyncCallback, rpc_client, invocation_context, std::placeholders::_1);
+  stub_->async()->QueryAssignment(&invocation_context->context, &request, &invocation_context->response, callback);
 }
 
-void RpcClientImpl::asyncReceive(const ReceiveMessageRequest& request,
-                                 InvocationContext<ReceiveMessageResponse>* invocation_context) {
-  invocation_context->response_reader =
-      stub_->PrepareAsyncReceiveMessage(&invocation_context->context, request, completion_queue_.get());
-  invocation_context->response_reader->StartCall();
-  invocation_context->response_reader->Finish(&invocation_context->response, &invocation_context->status,
-                                              invocation_context);
+void RpcClientImpl::asyncReceive(const ReceiveMessageRequest& request, std::unique_ptr<ReceiveMessageContext> context) {
+  new ReceiveMessageStreamReader(client_manager_, stub_.get(), peer_address_, request, std::move(context));
 }
 
 void RpcClientImpl::asyncAck(const AckMessageRequest& request,
                              InvocationContext<AckMessageResponse>* invocation_context) {
-  assert(invocation_context);
-  invocation_context->response_reader =
-      stub_->PrepareAsyncAckMessage(&invocation_context->context, request, completion_queue_.get());
-  invocation_context->response_reader->StartCall();
-  invocation_context->response_reader->Finish(&invocation_context->response, &invocation_context->status,
-                                              invocation_context);
+  std::weak_ptr<RpcClient> rpc_client(shared_from_this());
+  auto callback = std::bind(&RpcClientImpl::asyncCallback, rpc_client, invocation_context, std::placeholders::_1);
+  stub_->async()->AckMessage(&invocation_context->context, &request, &invocation_context->response, callback);
 }
 
-void RpcClientImpl::asyncNack(const NackMessageRequest& request,
-                              InvocationContext<NackMessageResponse>* invocation_context) {
-  assert(invocation_context);
-  invocation_context->response_reader =
-      stub_->PrepareAsyncNackMessage(&invocation_context->context, request, completion_queue_.get());
-  invocation_context->response_reader->StartCall();
-  invocation_context->response_reader->Finish(&invocation_context->response, &invocation_context->status,
-                                              invocation_context);
+void RpcClientImpl::asyncChangeInvisibleDuration(
+    const ChangeInvisibleDurationRequest& request,
+    InvocationContext<ChangeInvisibleDurationResponse>* invocation_context) {
+
+  std::weak_ptr<RpcClient> rpc_client(shared_from_this());
+  auto callback = std::bind(&RpcClientImpl::asyncCallback, rpc_client, invocation_context, std::placeholders::_1);
+
+  stub_->async()->ChangeInvisibleDuration(&invocation_context->context, &request, &invocation_context->response,
+                                          callback);
 }
 
 void RpcClientImpl::asyncHeartbeat(const HeartbeatRequest& request,
                                    InvocationContext<HeartbeatResponse>* invocation_context) {
-  assert(invocation_context);
-  invocation_context->response_reader =
-      stub_->PrepareAsyncHeartbeat(&invocation_context->context, request, completion_queue_.get());
-  invocation_context->response_reader->StartCall();
-  invocation_context->response_reader->Finish(&invocation_context->response, &invocation_context->status,
-                                              invocation_context);
-}
-
-void RpcClientImpl::asyncHealthCheck(const HealthCheckRequest& request,
-                                     InvocationContext<HealthCheckResponse>* invocation_context) {
-  assert(invocation_context);
-  invocation_context->response_reader =
-      stub_->PrepareAsyncHealthCheck(&invocation_context->context, request, completion_queue_.get());
-  invocation_context->response_reader->StartCall();
-  invocation_context->response_reader->Finish(&invocation_context->response, &invocation_context->status,
-                                              invocation_context);
+  std::weak_ptr<RpcClient> rpc_client(shared_from_this());
+  auto callback = std::bind(&RpcClientImpl::asyncCallback, rpc_client, invocation_context, std::placeholders::_1);
+  stub_->async()->Heartbeat(&invocation_context->context, &request, &invocation_context->response, callback);
 }
 
 void RpcClientImpl::asyncEndTransaction(const EndTransactionRequest& request,
                                         InvocationContext<EndTransactionResponse>* invocation_context) {
-  assert(invocation_context);
-  invocation_context->response_reader =
-      stub_->PrepareAsyncEndTransaction(&invocation_context->context, request, completion_queue_.get());
-  invocation_context->response_reader->StartCall();
-  invocation_context->response_reader->Finish(&invocation_context->response, &invocation_context->status,
-                                              invocation_context);
+  std::weak_ptr<RpcClient> rpc_client(shared_from_this());
+  auto callback = std::bind(&RpcClientImpl::asyncCallback, rpc_client, invocation_context, std::placeholders::_1);
+  stub_->async()->EndTransaction(&invocation_context->context, &request, &invocation_context->response, callback);
 }
 
 bool RpcClientImpl::ok() const {
@@ -135,25 +147,8 @@ void RpcClientImpl::needHeartbeat(bool need_heartbeat) {
   need_heartbeat_ = need_heartbeat;
 }
 
-void RpcClientImpl::asyncPollCommand(const PollCommandRequest& request,
-                                     InvocationContext<PollCommandResponse>* invocation_context) {
-  invocation_context->response_reader =
-      stub_->PrepareAsyncPollCommand(&invocation_context->context, request, completion_queue_.get());
-  invocation_context->response_reader->StartCall();
-  invocation_context->response_reader->Finish(&invocation_context->response, &invocation_context->status,
-                                              invocation_context);
-}
-
-grpc::Status RpcClientImpl::reportThreadStackTrace(grpc::ClientContext* context,
-                                                   const ReportThreadStackTraceRequest& request,
-                                                   ReportThreadStackTraceResponse* response) {
-  return stub_->ReportThreadStackTrace(context, request, response);
-}
-
-grpc::Status RpcClientImpl::reportMessageConsumptionResult(grpc::ClientContext* context,
-                                                           const ReportMessageConsumptionResultRequest& request,
-                                                           ReportMessageConsumptionResultResponse* response) {
-  return stub_->ReportMessageConsumptionResult(context, request, response);
+std::shared_ptr<TelemetryBidiReactor> RpcClientImpl::asyncTelemetry(std::weak_ptr<Client> client) {
+  return std::make_shared<TelemetryBidiReactor>(client, stub_.get(), peer_address_);
 }
 
 grpc::Status RpcClientImpl::notifyClientTermination(grpc::ClientContext* context,
@@ -162,33 +157,17 @@ grpc::Status RpcClientImpl::notifyClientTermination(grpc::ClientContext* context
   return stub_->NotifyClientTermination(context, request, response);
 }
 
-void RpcClientImpl::asyncQueryOffset(const QueryOffsetRequest& request,
-                                     InvocationContext<QueryOffsetResponse>* invocation_context) {
-  assert(invocation_context);
-  invocation_context->response_reader =
-      stub_->PrepareAsyncQueryOffset(&invocation_context->context, request, completion_queue_.get());
-  invocation_context->response_reader->StartCall();
-  invocation_context->response_reader->Finish(&invocation_context->response, &invocation_context->status,
-                                              invocation_context);
-}
-
-void RpcClientImpl::asyncPull(const PullMessageRequest& request,
-                              InvocationContext<PullMessageResponse>* invocation_context) {
-  invocation_context->response_reader =
-      stub_->PrepareAsyncPullMessage(&invocation_context->context, request, completion_queue_.get());
-  invocation_context->response_reader->StartCall();
-  invocation_context->response_reader->Finish(&invocation_context->response, &invocation_context->status,
-                                              invocation_context);
-}
-
 void RpcClientImpl::asyncForwardMessageToDeadLetterQueue(
     const ForwardMessageToDeadLetterQueueRequest& request,
     InvocationContext<ForwardMessageToDeadLetterQueueResponse>* invocation_context) {
-  invocation_context->response_reader = stub_->PrepareAsyncForwardMessageToDeadLetterQueue(
-      &invocation_context->context, request, completion_queue_.get());
-  invocation_context->response_reader->StartCall();
-  invocation_context->response_reader->Finish(&invocation_context->response, &invocation_context->status,
-                                              invocation_context);
+  std::weak_ptr<RpcClient> rpc_client(shared_from_this());
+  auto callback = std::bind(&RpcClientImpl::asyncCallback, rpc_client, invocation_context, std::placeholders::_1);
+  stub_->async()->ForwardMessageToDeadLetterQueue(&invocation_context->context, &request, &invocation_context->response,
+                                                  callback);
+}
+
+std::weak_ptr<ClientManager> RpcClientImpl::clientManager() {
+  return client_manager_;
 }
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/rocketmq/AwaitPullCallback.cpp b/src/main/cpp/client/SessionImpl.cpp
similarity index 55%
rename from src/main/cpp/rocketmq/AwaitPullCallback.cpp
rename to src/main/cpp/client/SessionImpl.cpp
index f4a5d99..5b7c085 100644
--- a/src/main/cpp/rocketmq/AwaitPullCallback.cpp
+++ b/src/main/cpp/client/SessionImpl.cpp
@@ -14,33 +14,32 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include "AwaitPullCallback.h"
+
+#include "SessionImpl.h"
+#include "LoggerImpl.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-void AwaitPullCallback::onSuccess(const PullResult& pull_result) noexcept {
-  absl::MutexLock lk(&mtx_);
-  completed_ = true;
-  // TODO: optimize out messages copy here.
-  pull_result_ = pull_result;
-  cv_.SignalAll();
+SessionImpl::SessionImpl(std::weak_ptr<Client> client, std::shared_ptr<RpcClient> rpc_client) : client_(client), rpc_client_(rpc_client) {
+  telemetry_ = rpc_client->asyncTelemetry(client_);
+  syncSettings();
+}
+
+bool SessionImpl::await() {
+  return telemetry_->await();
 }
 
-void AwaitPullCallback::onFailure(const std::error_code& ec) noexcept {
-  absl::MutexLock lk(&mtx_);
-  completed_ = true;
-  ec_ = ec;
-  cv_.SignalAll();
+void SessionImpl::syncSettings() {
+  auto ptr = client_.lock();
+
+  TelemetryCommand command;
+  command.mutable_settings()->CopyFrom(ptr->clientSettings());
+  telemetry_->write(command);
 }
 
-bool AwaitPullCallback::await() {
-  {
-    absl::MutexLock lk(&mtx_);
-    while (!completed_) {
-      cv_.Wait(&mtx_);
-    }
-    return !hasFailure();
-  }
+SessionImpl::~SessionImpl() {
+  SPDLOG_DEBUG("Session for {} destructed", rpc_client_->remoteAddress());
+  telemetry_->fireClose();
 }
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/client/Signature.cpp b/src/main/cpp/client/Signature.cpp
index 3364158..e25dbb5 100644
--- a/src/main/cpp/client/Signature.cpp
+++ b/src/main/cpp/client/Signature.cpp
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 #include "Signature.h"
-#include "ClientConfigImpl.h"
+#include "ClientConfig.h"
 #include "MetadataConstants.h"
 #include "Protocol.h"
 #include "TlsHelper.h"
@@ -23,29 +23,21 @@
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-void Signature::sign(ClientConfig* client, absl::flat_hash_map<std::string, std::string>& metadata) {
-  assert(client);
+void Signature::sign(const ClientConfig& client, absl::flat_hash_map<std::string, std::string>& metadata) {
 
   metadata.insert({MetadataConstants::LANGUAGE_KEY, "CPP"});
   // Add common headers
-  metadata.insert({MetadataConstants::CLIENT_VERSION_KEY, ClientConfigImpl::CLIENT_VERSION});
-  metadata.insert({MetadataConstants::PROTOCOL_VERSION_KEY, Protocol::PROTOCOL_VERSION});
-
-  if (!client->tenantId().empty()) {
-    metadata.insert({MetadataConstants::TENANT_ID_KEY, client->tenantId()});
-  }
-
-  if (!client->resourceNamespace().empty()) {
-    metadata.insert({MetadataConstants::NAMESPACE_KEY, client->resourceNamespace()});
-  }
+  metadata.insert({MetadataConstants::CLIENT_ID_KEY, client.client_id});
+  metadata.insert({MetadataConstants::CLIENT_VERSION_KEY, MetadataConstants::CLIENT_VERSION});
+  metadata.insert({MetadataConstants::PROTOCOL_VERSION_KEY, protocolVersion()});
 
   absl::Time now = absl::Now();
   absl::TimeZone utc_time_zone = absl::UTCTimeZone();
   const std::string request_date_time = absl::FormatTime(MetadataConstants::DATE_TIME_FORMAT, now, utc_time_zone);
   metadata.insert({MetadataConstants::DATE_TIME_KEY, request_date_time});
 
-  if (client->credentialsProvider()) {
-    Credentials&& credentials = client->credentialsProvider()->getCredentials();
+  if (client.credentials_provider) {
+    Credentials&& credentials = client.credentials_provider->getCredentials();
     if (credentials.accessKey().empty() || credentials.accessSecret().empty()) {
       SPDLOG_WARN("Access credential is incomplete. Check your access key/secret.");
       return;
@@ -58,9 +50,9 @@ void Signature::sign(ClientConfig* client, absl::flat_hash_map<std::string, std:
         .append("=")
         .append(credentials.accessKey())
         .append("/")
-        .append(client->region())
+        .append(client.region)
         .append("/")
-        .append(client->serviceName())
+        .append(MetadataConstants::SERVICE_NAME)
         .append(", ")
         .append(MetadataConstants::SIGNED_HEADERS_KEY)
         .append("=")
diff --git a/src/main/cpp/client/TelemetryBidiReactor.cpp b/src/main/cpp/client/TelemetryBidiReactor.cpp
new file mode 100644
index 0000000..f39cdec
--- /dev/null
+++ b/src/main/cpp/client/TelemetryBidiReactor.cpp
@@ -0,0 +1,339 @@
+/*
+ * 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.
+ */
+#include "TelemetryBidiReactor.h"
+
+#include <atomic>
+#include <memory>
+#include <utility>
+
+#include "ClientManager.h"
+#include "LoggerImpl.h"
+#include "MessageExt.h"
+#include "Metadata.h"
+#include "RpcClient.h"
+#include "Signature.h"
+#include "google/protobuf/util/time_util.h"
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+TelemetryBidiReactor::TelemetryBidiReactor(std::weak_ptr<Client> client,
+                                           rmq::MessagingService::Stub* stub,
+                                           std::string peer_address)
+    : client_(client), peer_address_(std::move(peer_address)), stream_state_(StreamState::Created) {
+  auto ptr = client.lock();
+  auto deadline = std::chrono::system_clock::now() + std::chrono::hours(1);
+  context_.set_deadline(deadline);
+  Metadata metadata;
+  Signature::sign(ptr->config(), metadata);
+  for (const auto& entry : metadata) {
+    context_.AddMetadata(entry.first, entry.second);
+  }
+  stub->async()->Telemetry(&context_, this);
+  StartCall();
+}
+
+TelemetryBidiReactor::~TelemetryBidiReactor() {
+  SPDLOG_INFO("Telemetry stream for {} destructed. StreamState={}", peer_address_, stream_state_);
+}
+
+bool TelemetryBidiReactor::await() {
+  absl::MutexLock lk(&server_setting_received_mtx_);
+  if (server_setting_received_) {
+    return true;
+  }
+
+  server_setting_received_cv_.Wait(&server_setting_received_mtx_);
+  return server_setting_received_;
+}
+
+void TelemetryBidiReactor::OnWriteDone(bool ok) {
+  SPDLOG_DEBUG("OnWriteDone: {}", ok);
+
+  {
+    bool expect = true;
+    if (!command_inflight_.compare_exchange_strong(expect, false, std::memory_order_relaxed)) {
+      SPDLOG_WARN("Illegal command-inflight state");
+    }
+  }
+
+  if (!ok) {
+    SPDLOG_WARN("Failed to write telemetry command {} to {}", write_.DebugString(), peer_address_);
+    {
+      absl::MutexLock lk(&stream_state_mtx_);
+      stream_state_ = StreamState::WriteDone;
+    }
+
+    fireClose();
+    return;
+  }
+
+  {
+    absl::MutexLock lk(&stream_state_mtx_);
+    if (StreamState::Created == stream_state_) {
+      stream_state_ = StreamState::Active;
+      fireRead();
+    }
+  }
+
+  fireWrite();
+}
+
+void TelemetryBidiReactor::OnReadDone(bool ok) {
+  SPDLOG_DEBUG("OnReadDone: ok={}", ok);
+  if (!ok) {
+    SPDLOG_WARN("Failed to read telemetry command from {}", peer_address_);
+    {
+      absl::MutexLock lk(&stream_state_mtx_);
+      stream_state_ = StreamState::ReadDone;
+    }
+    fireClose();
+    return;
+  }
+
+  SPDLOG_DEBUG("Read a telemetry command from {}: {}", peer_address_, read_.DebugString());
+  auto ptr = client_.lock();
+  if (!ptr) {
+    SPDLOG_INFO("Client for {} has destructed", peer_address_);
+    return;
+  }
+
+  switch (read_.command_case()) {
+    case rmq::TelemetryCommand::kSettings: {
+      auto settings = read_.settings();
+      SPDLOG_INFO("Received settings from {}: {}", peer_address_, settings.DebugString());
+      applySettings(settings);
+      {
+        absl::MutexLock lk(&server_setting_received_mtx_);
+        if (!server_setting_received_) {
+          server_setting_received_ = true;
+          server_setting_received_cv_.SignalAll();
+        }
+      }
+      break;
+    }
+    case rmq::TelemetryCommand::kRecoverOrphanedTransactionCommand: {
+      auto client = client_.lock();
+      if (!client) {
+        fireClose();
+        return;
+      }
+
+      auto message = client->manager()->wrapMessage(read_.release_verify_message_command()->message());
+      auto raw = const_cast<Message*>(message.get());
+      raw->mutableExtension().target_endpoint = peer_address_;
+      raw->mutableExtension().transaction_id = read_.recover_orphaned_transaction_command().transaction_id();
+      client->recoverOrphanedTransaction(message);
+
+      break;
+    }
+
+    case rmq::TelemetryCommand::kPrintThreadStackTraceCommand: {
+      TelemetryCommand response;
+      response.mutable_thread_stack_trace()->set_nonce(read_.print_thread_stack_trace_command().nonce());
+      response.mutable_thread_stack_trace()->set_thread_stack_trace("PrintStackTrace is not supported");
+      {
+        absl::MutexLock lk(&writes_mtx_);
+        writes_.push_back(response);
+      }
+      fireWrite();
+      StartRead(&read_);
+      break;
+    }
+
+    case rmq::TelemetryCommand::kVerifyMessageCommand: {
+      auto client = client_.lock();
+      if (!client) {
+        fireClose();
+        return;
+      }
+
+      std::weak_ptr<TelemetryBidiReactor> ptr(shared_from_this());
+      auto cb = [ptr](TelemetryCommand command) {
+        auto reactor = ptr.lock();
+        if (!reactor) {
+          return;
+        }
+        reactor->onVerifyMessageResult(std::move(command));
+      };
+      auto message = client->manager()->wrapMessage(read_.verify_message_command().message());
+      auto raw = const_cast<Message*>(message.get());
+      raw->mutableExtension().target_endpoint = peer_address_;
+      raw->mutableExtension().nonce = read_.verify_message_command().nonce();
+      client->verify(message, cb);
+      StartRead(&read_);
+      break;
+    }
+
+    default: {
+      SPDLOG_WARN("Unsupported command");
+      break;
+    }
+  }
+}
+
+void TelemetryBidiReactor::applySettings(const rmq::Settings& settings) {
+  auto ptr = client_.lock();
+  if (!ptr) {
+    SPDLOG_INFO("Client for {} has destructed", peer_address_);
+    return;
+  }
+
+  applyBackoffPolicy(settings, ptr);
+
+  switch (settings.pub_sub_case()) {
+    case rmq::Settings::PubSubCase::kPublishing: {
+      applyPublishingConfig(settings, ptr);
+      break;
+    }
+    case rmq::Settings::PubSubCase::kSubscription: {
+      applySubscriptionConfig(settings, ptr);
+      break;
+    }
+    default: {
+      break;
+    }
+  }
+}
+
+void TelemetryBidiReactor::applyBackoffPolicy(const rmq::Settings& settings, std::shared_ptr<Client>& ptr) {
+  // Apply backoff policy on throttling
+  if (settings.has_backoff_policy()) {
+    const auto& backoff_policy = settings.backoff_policy();
+    ptr->config().backoff_policy.max_attempt = backoff_policy.max_attempts();
+    if (backoff_policy.has_customized_backoff()) {
+      for (const auto& item : backoff_policy.customized_backoff().next()) {
+        auto backoff = std::chrono::seconds(item.seconds()) + std::chrono::nanoseconds(item.nanos());
+        ptr->config().backoff_policy.next.push_back(absl::FromChrono(backoff));
+      }
+    }
+
+    if (backoff_policy.has_exponential_backoff()) {
+      const auto& exp_backoff = backoff_policy.exponential_backoff();
+      ptr->config().backoff_policy.initial = absl::FromChrono(std::chrono::seconds(exp_backoff.initial().seconds()) +
+                                                              std::chrono::nanoseconds(exp_backoff.initial().nanos()));
+      ptr->config().backoff_policy.multiplier = exp_backoff.multiplier();
+      ptr->config().backoff_policy.max = absl::FromChrono(std::chrono::seconds(exp_backoff.max().seconds()) +
+                                                          std::chrono::nanoseconds(exp_backoff.max().nanos()));
+    }
+  }
+}
+
+void TelemetryBidiReactor::applyPublishingConfig(const rmq::Settings& settings, std::shared_ptr<Client> client) {
+  client->config().publisher.max_body_size = settings.publishing().max_body_size();
+  client->config().publisher.compress_body_threshold = settings.publishing().compress_body_threshold();
+}
+
+void TelemetryBidiReactor::applySubscriptionConfig(const rmq::Settings& settings, std::shared_ptr<Client> client) {
+  client->config().subscriber.fifo = settings.subscription().fifo();
+  auto polling_timeout =
+      google::protobuf::util::TimeUtil::DurationToMilliseconds(settings.subscription().long_polling_timeout());
+  client->config().subscriber.polling_timeout = absl::Milliseconds(polling_timeout);
+  client->config().subscriber.receive_batch_size = settings.subscription().receive_batch_size();
+}
+
+void TelemetryBidiReactor::fireRead() {
+  SPDLOG_DEBUG("{}#fireRead", peer_address_);
+  StartRead(&read_);
+}
+
+void TelemetryBidiReactor::write(TelemetryCommand command) {
+  {
+    absl::MutexLock lk(&writes_mtx_);
+    writes_.push_back(command);
+  }
+  fireWrite();
+}
+
+void TelemetryBidiReactor::fireWrite() {
+  SPDLOG_DEBUG("{}#fireWrite", peer_address_);
+  {
+    absl::MutexLock lk(&writes_mtx_);
+    if (writes_.empty()) {
+      SPDLOG_DEBUG("No TelemtryCommand to write. Peer={}", peer_address_);
+      return;
+    }
+
+    bool expect = false;
+    if (command_inflight_.compare_exchange_strong(expect, true, std::memory_order_relaxed)) {
+      write_ = std::move(*writes_.begin());
+      writes_.erase(writes_.begin());
+    } else {
+      SPDLOG_DEBUG("Another command is already on the wire. Peer={}", peer_address_);
+      return;
+    }
+  }
+  SPDLOG_DEBUG("Writing telemetry command to {}: {}", peer_address_, write_.DebugString());
+  StartWrite(&write_);
+}
+
+void TelemetryBidiReactor::fireClose() {
+  SPDLOG_INFO("{}#fireClose", peer_address_);
+  if (StreamState::Active == stream_state_) {
+    StartWritesDone();
+    {
+      absl::MutexLock lk(&stream_state_mtx_);
+      if (StreamState::Active == stream_state_) {
+        stream_state_cv_.Wait(&stream_state_mtx_);
+      }
+    }
+  }
+}
+
+void TelemetryBidiReactor::OnWritesDoneDone(bool ok) {
+  SPDLOG_DEBUG("{}#OnWritesDoneDone", peer_address_);
+}
+
+void TelemetryBidiReactor::onVerifyMessageResult(TelemetryCommand command) {
+  {
+    absl::MutexLock lk(&writes_mtx_);
+    writes_.emplace_back(command);
+  }
+  fireWrite();
+}
+
+/// Notifies the application that all operations associated with this RPC
+/// have completed and all Holds have been removed. OnDone provides the RPC
+/// status outcome for both successful and failed RPCs and will be called in
+/// all cases. If it is not called, it indicates an application-level problem
+/// (like failure to remove a hold).
+///
+/// \param[in] status The status outcome of this RPC
+void TelemetryBidiReactor::OnDone(const grpc::Status& status) {
+  SPDLOG_DEBUG("{}#OnDone, status.ok={}", peer_address_, status.ok());
+  if (!status.ok()) {
+    SPDLOG_WARN("{}#OnDone, status.error_code={}, status.error_message={}, status.error_details={}", peer_address_,
+                status.error_code(), status.error_message(), status.error_details());
+  }
+
+  {
+    SPDLOG_DEBUG("{} notifies awaiting close call", peer_address_);
+    absl::MutexLock lk(&stream_state_mtx_);
+    stream_state_ = StreamState::Closed;
+    stream_state_cv_.SignalAll();
+  }
+
+  auto client = client_.lock();
+  if (!client) {
+    return;
+  }
+
+  if (client->active()) {
+    client->createSession(peer_address_, true);
+  }
+}
+
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/client/TlsHelper.cpp b/src/main/cpp/client/TlsHelper.cpp
index 62d3ac1..aa4970a 100644
--- a/src/main/cpp/client/TlsHelper.cpp
+++ b/src/main/cpp/client/TlsHelper.cpp
@@ -16,10 +16,11 @@
  */
 #include "TlsHelper.h"
 
+#include <memory>
+
 #include "MixAll.h"
 #include "OpenSSLCompatible.h"
-#include <memory>
-#include <openssl/hmac.h>
+#include "openssl/hmac.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
@@ -37,213 +38,4 @@ std::string TlsHelper::sign(const std::string& access_secret, const std::string&
   return hex_str;
 }
 
-const char* TlsHelper::CA = R"(
------BEGIN CERTIFICATE-----
-MIIGCDCCA/CgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZwxCzAJBgNVBAYTAkNO
-MRIwEAYDVQQIDAlaaGUgSmlhbmcxEjAQBgNVBAcMCUhhbmcgWmhvdTEPMA0GA1UE
-CgwGQXBhY2hlMREwDwYDVQQLDAhSb2NrZXRNUTEcMBoGA1UEAwwTcm9ja2V0bXEu
-YXBhY2hlLm9yZzEjMCEGCSqGSIb3DQEJARYUbGl6aGFuaHVpQGFwYWNoZS5vcmcw
-HhcNMjEwNDI1MDkwMjE5WhcNMzEwNDIzMDkwMjE5WjCBiDELMAkGA1UEBhMCQ04x
-EjAQBgNVBAgMCVpoZSBKaWFuZzEPMA0GA1UECgwGQXBhY2hlMREwDwYDVQQLDAhS
-b2NrZXRNUTEcMBoGA1UEAwwTcm9ja2V0bXEuYXBhY2hlLm9yZzEjMCEGCSqGSIb3
-DQEJARYUbGl6aGFuaHVpQGFwYWNoZS5vcmcwggIiMA0GCSqGSIb3DQEBAQUAA4IC
-DwAwggIKAoICAQDLL1rQ3A6YnWwdAT3rcf7wXK2DN6AwkWfGexp5o8y+dPj49D5b
-PhEVIDEjidtWASFfCunJq9Ku48K/U8tha58JPL2CJ3773Mw7CU3LwD46Ft32+kGM
-3+rXuXi44Fs714U/jJkxA6AsJdl4VtgjfXGWhbTq7ZT//l3tECH7Q096cp4xXATx
-0RuvlaE33k8SpOPB+oHyjdFTwSW9HuZx71dLNCoZ0b52teJDVJFMACz6R5t3ZglF
-MUosUzEUKdCXqBDvjOzMI2GHr7NYKAWHnOPNcYbf8jKzQ5msW+1MOfacVX+YUmKr
-4Tf8NZHTSA4MuSNZ46gVFK7tYau2FDAkBWSb4hnuqqoGn58QtwrRBWtCmnLc4133
-6sgEGoJJR5M7WF0usl7KAgqgwy6xdU1joHO4SzvpysQ9kHWr1hcTqpeLD/svxLpZ
-3x0WrhIAQoyd4uIHv/501LgD2KE5YnBa4S10LYrZeQpoJO5YV56HJdyvqNgVh2fn
-tIRJAKq/1Wvw6izK/zOC6ZC+ug3n9vPqCgpBI0NFm3aR4AcSx70FsmlfrjUAsluL
-kIzQwuu3Ip7hUS9kBVUxmvaD2yy2HPc+UPiYm4Y2YxqTx2j11APbN32M8rj1mroE
... 17469 lines suppressed ...