You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rocketmq.apache.org by du...@apache.org on 2019/08/30 03:21:00 UTC

[rocketmq-ons] branch pullConsumer updated (6da9b49 -> 486e782)

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

duhengforever pushed a change to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git.


    from 6da9b49  [maven-release-plugin] prepare for next development iteration
     new f14be54  (1) Polish existed ons api (2) Add pull consumer Implementation
     new de9e452  Add meta data get API in pull consumer
     new f1ca1d7  Add comments for pull consumer
     new fe991ca  Remove subscribe method in Pullconsumer
     new ea41645  Polish pull consumer poll method
     new 4bb15ff  Remove deprecated of OrderProducer
     new 486e782  Merge pull request #8 from duhenglucky/sdk_polish

The 29 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../java/org/apache/rocketmq/ons/api/Admin.java    |  18 +--
 .../java/org/apache/rocketmq/ons/api/Consumer.java |   5 +-
 .../ons/api/{Admin.java => Credentials.java}       |  17 +--
 .../ons/api/{Admin.java => LifeCycle.java}         |  13 +-
 .../java/org/apache/rocketmq/ons/api/Producer.java |  14 +-
 .../org/apache/rocketmq/ons/api/PullConsumer.java  | 143 +++++++++++++++++++++
 .../Subscription.java => TopicPartition.java}      |  63 ++++-----
 .../rocketmq/ons/api/batch/BatchConsumer.java      |   5 +-
 .../apache/rocketmq/ons/api/bean/ProducerBean.java |   9 ++
 .../ons/api/bean/TransactionProducerBean.java      |   4 +-
 .../rocketmq/ons/api/order/OrderConsumer.java      |   6 +-
 .../rocketmq/ons/api/order/OrderProducer.java      |  10 +-
 .../api/transaction/LocalTransactionChecker.java   |   2 +
 ...Executer.java => LocalTransactionExecutor.java} |   4 +-
 .../ons/api/transaction/TransactionProducer.java   |  16 +--
 .../ons/api/impl/rocketmq/ProducerImpl.java        |   9 ++
 .../api/impl/rocketmq/TransactionProducerImpl.java |   4 +-
 ons-core/pom.xml                                   |   6 +-
 ons-sample/pom.xml                                 |   4 +-
 .../sample/producer/SimpleTransactionProducer.java |   5 +-
 20 files changed, 227 insertions(+), 130 deletions(-)
 copy ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/{Admin.java => Credentials.java} (88%)
 copy ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/{Admin.java => LifeCycle.java} (88%)
 create mode 100644 ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PullConsumer.java
 copy ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/{bean/Subscription.java => TopicPartition.java} (61%)
 rename ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/{LocalTransactionExecuter.java => LocalTransactionExecutor.java} (88%)


[rocketmq-ons] 24/29: Add meta data get API in pull consumer

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit de9e4522665e0b59ff6c58ad7dc77fccf474799b
Author: duhenglucky <du...@gmail.com>
AuthorDate: Wed Jul 17 17:37:13 2019 +0800

    Add meta data get API in pull consumer
---
 .../org/apache/rocketmq/ons/api/MessageQueue.java  | 25 ++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageQueue.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageQueue.java
index 00f8b2d..abe77b4 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageQueue.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageQueue.java
@@ -15,5 +15,30 @@
  * limitations under the License.
  */
 package org.apache.rocketmq.ons.api;
+
 public class MessageQueue {
+    private String topic;
+
+    private String queue;
+
+    public MessageQueue(String topic, String queue) {
+        this.topic = topic;
+        this.queue = queue;
+    }
+
+    public String getTopic() {
+        return topic;
+    }
+
+    public void setTopic(String topic) {
+        this.topic = topic;
+    }
+
+    public String getQueue() {
+        return queue;
+    }
+
+    public void setQueue(String queue) {
+        this.queue = queue;
+    }
 }


[rocketmq-ons] 14/29: Modify apache 2.0 license

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit b1be94d3095408a4a3204c83815c184a144ec738
Author: duhenglucky <du...@gmail.com>
AuthorDate: Mon Jul 1 16:55:00 2019 +0800

    Modify apache 2.0 license
---
 ons-sample/pom.xml                                     | 18 +++++++++++++++++-
 .../java/org/apache/rocketmq/ons/sample/MQConfig.java  | 13 ++++++++-----
 .../ons/sample/consumer/MessageListenerImpl.java       | 13 ++++++++-----
 .../sample/producer/LocalTransactionCheckerImpl.java   | 15 +++++++++++++++
 .../rocketmq/ons/sample/producer/MQTimerProducer.java  | 13 ++++++++-----
 .../ons/sample/producer/SimpleOrderProducer.java       | 13 ++++++++-----
 .../ons/sample/producer/SimpleTransactionProducer.java | 15 +++++++++++++++
 7 files changed, 79 insertions(+), 21 deletions(-)

diff --git a/ons-sample/pom.xml b/ons-sample/pom.xml
index 2cebaaf..8f52602 100644
--- a/ons-sample/pom.xml
+++ b/ons-sample/pom.xml
@@ -1,4 +1,20 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
 <project xmlns="http://maven.apache.org/POM/4.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/MQConfig.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/MQConfig.java
index 17937d4..a7d8094 100644
--- a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/MQConfig.java
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/MQConfig.java
@@ -1,14 +1,17 @@
 /**
  * Copyright (C) 2010-2016 Alibaba Group Holding Limited
  * <p>
- * Licensed 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
+ * Licensed 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
  * <p>
  * http://www.apache.org/licenses/LICENSE-2.0
  * <p>
- * 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.
+ * 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.
  */
 package org.apache.rocketmq.ons.sample;
 
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/MessageListenerImpl.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/MessageListenerImpl.java
index f51d16f..f8e8ec1 100644
--- a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/MessageListenerImpl.java
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/MessageListenerImpl.java
@@ -1,14 +1,17 @@
 /**
  * Copyright (C) 2010-2016 Alibaba Group Holding Limited
  * <p>
- * Licensed 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
+ * Licensed 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
  * <p>
  * http://www.apache.org/licenses/LICENSE-2.0
  * <p>
- * 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.
+ * 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.
  */
 package org.apache.rocketmq.ons.sample.consumer;
 
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/LocalTransactionCheckerImpl.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/LocalTransactionCheckerImpl.java
index 32a756f..f5dbd1a 100644
--- a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/LocalTransactionCheckerImpl.java
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/LocalTransactionCheckerImpl.java
@@ -1,3 +1,18 @@
+/**
+ * Copyright (C) 2010-2016 Alibaba Group Holding Limited
+ * <p>
+ * Licensed 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.
+ */
 package org.apache.rocketmq.ons.sample.producer;
 
 import org.apache.rocketmq.ons.api.Message;
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/MQTimerProducer.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/MQTimerProducer.java
index 1f70ad3..471b8bd 100644
--- a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/MQTimerProducer.java
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/MQTimerProducer.java
@@ -1,14 +1,17 @@
 /**
  * Copyright (C) 2010-2016 Alibaba Group Holding Limited
  * <p>
- * Licensed 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
+ * Licensed 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
  * <p>
  * http://www.apache.org/licenses/LICENSE-2.0
  * <p>
- * 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.
+ * 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.
  */
 package org.apache.rocketmq.ons.sample.producer;
 
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleOrderProducer.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleOrderProducer.java
index 550005c..dd0b3ae 100644
--- a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleOrderProducer.java
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleOrderProducer.java
@@ -1,14 +1,17 @@
 /**
  * Copyright (C) 2010-2016 Alibaba Group Holding Limited
  * <p>
- * Licensed 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
+ * Licensed 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
  * <p>
  * http://www.apache.org/licenses/LICENSE-2.0
  * <p>
- * 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.
+ * 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.
  */
 package org.apache.rocketmq.ons.sample.producer;
 
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleTransactionProducer.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleTransactionProducer.java
index bbb97e3..4ab6805 100644
--- a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleTransactionProducer.java
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleTransactionProducer.java
@@ -1,3 +1,18 @@
+/**
+ * Copyright (C) 2010-2016 Alibaba Group Holding Limited
+ * <p>
+ * Licensed 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.
+ */
 package org.apache.rocketmq.ons.sample.producer;
 
 import java.util.Date;


[rocketmq-ons] 01/29: Init commit.

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit 3dbc38a9e4e742c604540b5887453bc0219e2817
Author: duheng.dh <du...@alibaba-inc.com>
AuthorDate: Wed Jun 5 11:16:34 2019 +0800

    Init commit.
---
 .gitignore                                         |  22 ++
 .gitmodules                                        |   0
 README.md                                          |   2 +
 ons-core/.idea/codeStyleSettings.xml               |  38 ++
 ons-core/.idea/copyright/profiles_settings.xml     |   7 +
 ons-core/.idea/encodings.xml                       |  11 +
 ons-core/README.md                                 |   0
 ons-core/ons-api/pom.xml                           |  28 ++
 .../java/org/apache/rocketmq/ons/api/Action.java   |  26 ++
 .../java/org/apache/rocketmq/ons/api/Admin.java    |  37 ++
 .../org/apache/rocketmq/ons/api/Constants.java     |  21 ++
 .../apache/rocketmq/ons/api/ConsumeContext.java    |  21 ++
 .../java/org/apache/rocketmq/ons/api/Consumer.java |  29 ++
 .../apache/rocketmq/ons/api/ExpressionType.java    |  24 ++
 .../java/org/apache/rocketmq/ons/api/MQType.java   |  38 ++
 .../java/org/apache/rocketmq/ons/api/Message.java  | 245 +++++++++++++
 .../apache/rocketmq/ons/api/MessageAccessor.java   |  41 +++
 .../apache/rocketmq/ons/api/MessageListener.java   |  23 ++
 .../apache/rocketmq/ons/api/MessageSelector.java   |  49 +++
 .../org/apache/rocketmq/ons/api/ONSFactory.java    |  88 +++++
 .../org/apache/rocketmq/ons/api/ONSFactoryAPI.java |  40 +++
 .../rocketmq/ons/api/OnExceptionContext.java       |  56 +++
 .../java/org/apache/rocketmq/ons/api/Producer.java |  37 ++
 .../apache/rocketmq/ons/api/PropertyKeyConst.java  | 102 ++++++
 .../rocketmq/ons/api/PropertyValueConst.java       |  27 ++
 .../org/apache/rocketmq/ons/api/SendCallback.java  |  24 ++
 .../org/apache/rocketmq/ons/api/SendResult.java    |  47 +++
 .../rocketmq/ons/api/batch/BatchConsumer.java      |  27 ++
 .../ons/api/batch/BatchMessageListener.java        |  29 ++
 .../rocketmq/ons/api/bean/BatchConsumerBean.java   | 114 ++++++
 .../apache/rocketmq/ons/api/bean/ConsumerBean.java | 157 +++++++++
 .../rocketmq/ons/api/bean/OrderConsumerBean.java   | 111 ++++++
 .../rocketmq/ons/api/bean/OrderProducerBean.java   |  82 +++++
 .../apache/rocketmq/ons/api/bean/ProducerBean.java |  98 ++++++
 .../apache/rocketmq/ons/api/bean/Subscription.java |  93 +++++
 .../rocketmq/ons/api/bean/SubscriptionExt.java     |  47 +++
 .../ons/api/bean/TransactionProducerBean.java      |  95 +++++
 .../ons/api/exception/ONSClientException.java      |  42 +++
 .../ons/api/order/ConsumeOrderContext.java         |  21 ++
 .../ons/api/order/MessageOrderListener.java        |  25 ++
 .../ons/api/order/MessageQueueSelector.java        |  25 ++
 .../apache/rocketmq/ons/api/order/OrderAction.java |  26 ++
 .../rocketmq/ons/api/order/OrderConsumer.java      |  35 ++
 .../rocketmq/ons/api/order/OrderProducer.java      |  28 ++
 .../api/transaction/LocalTransactionChecker.java   |  24 ++
 .../api/transaction/LocalTransactionExecuter.java  |  26 ++
 .../ons/api/transaction/TransactionProducer.java   |  38 ++
 .../ons/api/transaction/TransactionStatus.java     |  28 ++
 ons-core/ons-auth4client/pom.xml                   |  37 ++
 .../rocketmq/ons/api/impl/authority/AuthUtil.java  |  58 ++++
 .../ons/api/impl/authority/OnsAuthSigner.java      |  90 +++++
 .../ons/api/impl/authority/SessionCredentials.java | 214 ++++++++++++
 .../ons/api/impl/authority/SigningAlgorithm.java   |  24 ++
 .../exception/AuthenticationException.java         |  69 ++++
 .../authority/exception/FlowControlException.java  |  44 +++
 .../authority/exception/SignatureException.java    |  48 +++
 .../ons/api/impl/rocketmq/AbstractRPCHook.java     |  75 ++++
 .../ons/api/impl/rocketmq/ClientRPCHook.java       |  57 +++
 .../rocketmq/ons/api/impl/rocketmq/ONSChannel.java |  24 ++
 ons-core/ons-client/pom.xml                        |  74 ++++
 .../apache/rocketmq/ons/api/impl/MQClientInfo.java |  39 +++
 .../rocketmq/ons/api/impl/ONSFactoryImpl.java      |  90 +++++
 .../ons/api/impl/rocketmq/BatchConsumerImpl.java   | 131 +++++++
 .../ons/api/impl/rocketmq/ConsumerImpl.java        | 133 +++++++
 .../apache/rocketmq/ons/api/impl/rocketmq/FAQ.java |  46 +++
 .../ons/api/impl/rocketmq/ONSClientAbstract.java   | 268 +++++++++++++++
 .../ons/api/impl/rocketmq/ONSConsumerAbstract.java | 198 +++++++++++
 .../rocketmq/ons/api/impl/rocketmq/ONSUtil.java    | 185 ++++++++++
 .../ons/api/impl/rocketmq/OnsClientRPCHook.java    |  42 +++
 .../ons/api/impl/rocketmq/OrderConsumerImpl.java   | 114 ++++++
 .../ons/api/impl/rocketmq/OrderProducerImpl.java   | 149 ++++++++
 .../ons/api/impl/rocketmq/ProducerImpl.java        | 246 +++++++++++++
 .../api/impl/rocketmq/TransactionProducerImpl.java | 155 +++++++++
 .../tracehook/OnsClientSendMessageHookImpl.java    |  98 ++++++
 .../impl/tracehook/OnsConsumeMessageHookImpl.java  | 123 +++++++
 .../ons/api/impl/util/ClientLoggerUtil.java        |  55 +++
 .../rocketmq/ons/api/impl/util/MsgConvertUtil.java |  89 +++++
 .../rocketmq/ons/api/impl/util/NameAddrUtils.java  |  47 +++
 .../src/main/resources/ons_client_info.properties  |  16 +
 .../impl/rocketmq/NameServerAutoUpdateTest.java    |  95 +++++
 .../impl/rocketmq/ONSClientTokenUpdateTest.java    | 189 ++++++++++
 .../ons/api/impl/rocketmq/ONSUtilTest.java         |  59 ++++
 ons-core/ons-trace-core/pom.xml                    |  41 +++
 .../ons/open/trace/core/common/OnsTraceBean.java   | 145 ++++++++
 .../open/trace/core/common/OnsTraceConstants.java  |  57 +++
 .../open/trace/core/common/OnsTraceContext.java    | 168 +++++++++
 .../trace/core/common/OnsTraceDataEncoder.java     | 162 +++++++++
 .../trace/core/common/OnsTraceDispatcherType.java  |  25 ++
 .../trace/core/common/OnsTraceTransferBean.java    |  46 +++
 .../ons/open/trace/core/common/OnsTraceType.java   |  27 ++
 .../open/trace/core/dispatch/AsyncDispatcher.java  |  33 ++
 .../core/dispatch/impl/AsyncArrayDispatcher.java   | 382 +++++++++++++++++++++
 .../core/dispatch/impl/TraceProducerFactory.java   |  97 ++++++
 .../ons/open/trace/core/hook/AbstractRPCHook.java  |  72 ++++
 .../ons/open/trace/core/utils/MixUtils.java        | 111 ++++++
 ons-core/pom.xml                                   | 271 +++++++++++++++
 pom.xml                                            | 277 +++++++++++++++
 style/copyright/Apache.xml                         |  23 ++
 style/copyright/profiles_settings.xml              |  64 ++++
 style/ons_checkstyle.xml                           | 137 ++++++++
 style/ons_codeStyle.xml                            | 143 ++++++++
 101 files changed, 7916 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7a1b3a8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,22 @@
+*.iml
+.idea/
+target/
+logs/
+.classpath
+.project
+.settings/
+.amateras
+src/main/resources/hibernate.cfg.xml
+src/main/resources/hibernate.reveng.xml
+/target*
+*/bin/*
+*.log*
+*.versionsBackup
+test-output*
+runtest.sh
+/ons-top/frontend
+*dependency-reduced-pom.xml
+local
+frontend
+/ons-top/ons-frontend
+.DS_Store/
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..e69de29
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..868fecc
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+## Overview
+### Apache RocketMQ lightweight client.
diff --git a/ons-core/.idea/codeStyleSettings.xml b/ons-core/.idea/codeStyleSettings.xml
new file mode 100644
index 0000000..3319e57
--- /dev/null
+++ b/ons-core/.idea/codeStyleSettings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectCodeStyleSettingsManager">
+    <option name="PER_PROJECT_SETTINGS">
+      <value>
+        <option name="LINE_SEPARATOR" value="&#10;" />
+        <option name="GENERATE_FINAL_LOCALS" value="true" />
+        <option name="GENERATE_FINAL_PARAMETERS" value="true" />
+        <option name="JD_ADD_BLANK_AFTER_PARM_COMMENTS" value="true" />
+        <option name="JD_ADD_BLANK_AFTER_RETURN" value="true" />
+        <option name="JD_P_AT_EMPTY_LINES" value="false" />
+        <option name="JD_PARAM_DESCRIPTION_ON_NEW_LINE" value="true" />
+        <XML>
+          <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
+        </XML>
+        <codeStyleSettings language="JAVA">
+          <arrangement>
+            <groups>
+              <group>
+                <type>GETTERS_AND_SETTERS</type>
+                <order>KEEP</order>
+              </group>
+              <group>
+                <type>OVERRIDDEN_METHODS</type>
+                <order>KEEP</order>
+              </group>
+              <group>
+                <type>DEPENDENT_METHODS</type>
+                <order>BREADTH_FIRST</order>
+              </group>
+            </groups>
+          </arrangement>
+        </codeStyleSettings>
+      </value>
+    </option>
+    <option name="USE_PER_PROJECT_SETTINGS" value="true" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/ons-core/.idea/copyright/profiles_settings.xml b/ons-core/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..74200de
--- /dev/null
+++ b/ons-core/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,7 @@
+<component name="CopyrightManager">
+  <settings default="">
+    <LanguageOptions name="JAVA">
+      <option name="fileTypeOverride" value="1" />
+    </LanguageOptions>
+  </settings>
+</component>
\ No newline at end of file
diff --git a/ons-core/.idea/encodings.xml b/ons-core/.idea/encodings.xml
new file mode 100644
index 0000000..3446947
--- /dev/null
+++ b/ons-core/.idea/encodings.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8">
+    <file url="file://$PROJECT_DIR$" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/ons-api" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/ons-auth4client" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/ons-client" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/ons-trace-core" charset="UTF-8" />
+    <file url="PROJECT" charset="UTF-8" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/ons-core/README.md b/ons-core/README.md
new file mode 100644
index 0000000..e69de29
diff --git a/ons-core/ons-api/pom.xml b/ons-core/ons-api/pom.xml
new file mode 100644
index 0000000..374e460
--- /dev/null
+++ b/ons-core/ons-api/pom.xml
@@ -0,0 +1,28 @@
+<!--
+  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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.apache.rocketmq</groupId>
+        <artifactId>ons-all</artifactId>
+        <version>1.8.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <packaging>jar</packaging>
+    <artifactId>ons-api</artifactId>
+    <name>ons-api ${project.version}</name>
+</project>
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Action.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Action.java
new file mode 100644
index 0000000..2c0a2c9
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Action.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api;
+
+
+public enum Action {
+
+    CommitMessage,
+
+    ReconsumeLater,
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Admin.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Admin.java
new file mode 100644
index 0000000..702d9a5
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Admin.java
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api;
+
+import java.util.Properties;
+
+
+public interface Admin {
+
+    boolean isStarted();
+
+
+    boolean isClosed();
+
+
+    void start();
+
+
+    void updateCredential(Properties credentialProperties);
+
+
+    void shutdown();
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Constants.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Constants.java
new file mode 100644
index 0000000..a51ba20
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Constants.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api;
+
+public class Constants {
+    public static final String TRANSACTION_ID = "__transactionId__";
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/ConsumeContext.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/ConsumeContext.java
new file mode 100644
index 0000000..5973428
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/ConsumeContext.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api;
+
+public class ConsumeContext {
+
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Consumer.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Consumer.java
new file mode 100644
index 0000000..a592559
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Consumer.java
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api;
+
+
+public interface Consumer extends Admin {
+
+    void subscribe(final String topic, final String subExpression, final MessageListener listener);
+
+
+    void subscribe(final String topic, final MessageSelector selector, final MessageListener listener);
+
+
+    void unsubscribe(final String topic);
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/ExpressionType.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/ExpressionType.java
new file mode 100644
index 0000000..1980ac6
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/ExpressionType.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api;
+
+public enum ExpressionType {
+
+    SQL92,
+
+    TAG
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MQType.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MQType.java
new file mode 100644
index 0000000..17d4afa
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MQType.java
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api;
+
+public enum MQType {
+
+    NOTIFY("NOTIFY"),
+
+    METAQ("METAQ");
+
+    private String name;
+
+    MQType(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Message.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Message.java
new file mode 100644
index 0000000..5d1f999
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Message.java
@@ -0,0 +1,245 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api;
+
+import java.io.Serializable;
+import java.util.Properties;
+
+
+public class Message implements Serializable {
+
+    private static final long serialVersionUID = -1385924226856188094L;
+
+
+    Properties systemProperties;
+
+
+    private String topic;
+
+
+    private Properties userProperties;
+
+
+    private byte[] body;
+
+
+    public Message() {
+        this(null, null, "", null);
+    }
+
+
+    public Message(String topic, String tag, String key, byte[] body) {
+        this.topic = topic;
+        this.body = body;
+
+        this.putSystemProperties(SystemPropKey.TAG, tag);
+        this.putSystemProperties(SystemPropKey.KEY, key);
+    }
+
+
+    void putSystemProperties(final String key, final String value) {
+        if (null == this.systemProperties) {
+            this.systemProperties = new Properties();
+        }
+
+        if (key != null && value != null) {
+            this.systemProperties.put(key, value);
+        }
+    }
+
+
+    public Message(String topic, String tags, byte[] body) {
+        this(topic, tags, "", body);
+    }
+
+
+    public void putUserProperties(final String key, final String value) {
+        if (null == this.userProperties) {
+            this.userProperties = new Properties();
+        }
+
+        if (key != null && value != null) {
+            this.userProperties.put(key, value);
+        }
+    }
+
+
+    public String getUserProperties(final String key) {
+        if (null != this.userProperties) {
+            return (String) this.userProperties.get(key);
+        }
+
+        return null;
+    }
+
+
+    public String getTopic() {
+        return topic;
+    }
+
+
+    public void setTopic(String topic) {
+        this.topic = topic;
+    }
+
+
+    public String getTag() {
+        return this.getSystemProperties(SystemPropKey.TAG);
+    }
+
+
+    String getSystemProperties(final String key) {
+        if (null != this.systemProperties) {
+            return this.systemProperties.getProperty(key);
+        }
+
+        return null;
+    }
+
+
+    public void setTag(String tag) {
+        this.putSystemProperties(SystemPropKey.TAG, tag);
+    }
+
+
+    public String getKey() {
+        return this.getSystemProperties(SystemPropKey.KEY);
+    }
+
+
+    public void setKey(String key) {
+        this.putSystemProperties(SystemPropKey.KEY, key);
+    }
+
+
+    public String getMsgID() {
+        return this.getSystemProperties(SystemPropKey.MSGID);
+    }
+
+
+    public void setMsgID(String msgid) {
+        this.putSystemProperties(SystemPropKey.MSGID, msgid);
+    }
+
+    Properties getSystemProperties() {
+        return systemProperties;
+    }
+
+    void setSystemProperties(Properties systemProperties) {
+        this.systemProperties = systemProperties;
+    }
+
+    public Properties getUserProperties() {
+        return userProperties;
+    }
+
+    public void setUserProperties(Properties userProperties) {
+        this.userProperties = userProperties;
+    }
+
+    public byte[] getBody() {
+        return body;
+    }
+
+    public void setBody(byte[] body) {
+        this.body = body;
+    }
+
+
+    public int getReconsumeTimes() {
+        String pro = this.getSystemProperties(SystemPropKey.RECONSUMETIMES);
+        if (pro != null) {
+            return Integer.parseInt(pro);
+        }
+
+        return 0;
+    }
+
+
+    public void setReconsumeTimes(final int value) {
+        putSystemProperties(SystemPropKey.RECONSUMETIMES, String.valueOf(value));
+    }
+
+
+    public long getBornTimestamp() {
+        String pro = this.getSystemProperties(SystemPropKey.BORNTIMESTAMP);
+        if (pro != null) {
+            return Long.parseLong(pro);
+        }
+
+        return 0L;
+    }
+
+
+    public void setBornTimestamp(final long value) {
+        putSystemProperties(SystemPropKey.BORNTIMESTAMP, String.valueOf(value));
+    }
+
+
+    public String getBornHost() {
+        String pro = this.getSystemProperties(SystemPropKey.BORNHOST);
+        return pro == null ? "" : pro;
+    }
+
+
+    public void setBornHost(final String value) {
+        putSystemProperties(SystemPropKey.BORNHOST, value);
+    }
+
+
+    public long getStartDeliverTime() {
+        String pro = this.getSystemProperties(SystemPropKey.STARTDELIVERTIME);
+        if (pro != null) {
+            return Long.parseLong(pro);
+        }
+
+        return 0L;
+    }
+
+    public String getShardingKey() {
+        String pro = this.getSystemProperties(SystemPropKey.SHARDINGKEY);
+        return pro == null ? "" : pro;
+    }
+
+    public void setShardingKey(final String value) {
+        putSystemProperties(SystemPropKey.SHARDINGKEY, value);
+    }
+
+
+    public void setStartDeliverTime(final long value) {
+        putSystemProperties(SystemPropKey.STARTDELIVERTIME, String.valueOf(value));
+    }
+
+    @Override
+    public String toString() {
+        return "Message [topic=" + topic + ", systemProperties=" + systemProperties + ", userProperties=" + userProperties + ", body="
+            + (body != null ? body.length : 0) + "]";
+    }
+
+
+    static public class SystemPropKey {
+        public static final String TAG = "__TAG";
+        public static final String KEY = "__KEY";
+        public static final String MSGID = "__MSGID";
+        public static final String SHARDINGKEY = "__SHARDINGKEY";
+        public static final String RECONSUMETIMES = "__RECONSUMETIMES";
+        public static final String BORNTIMESTAMP = "__BORNTIMESTAMP";
+        public static final String BORNHOST = "__BORNHOST";
+
+        public static final String STARTDELIVERTIME = "__STARTDELIVERTIME";
+    }
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageAccessor.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageAccessor.java
new file mode 100644
index 0000000..61f23b1
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageAccessor.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api;
+
+import java.util.Properties;
+
+
+public class MessageAccessor {
+    public static Properties getSystemProperties(final Message msg) {
+        return msg.systemProperties;
+    }
+
+
+    public static void setSystemProperties(final Message msg, Properties systemProperties) {
+        msg.systemProperties = systemProperties;
+    }
+
+
+    public static void putSystemProperties(final Message msg, final String key, final String value) {
+        msg.putSystemProperties(key, value);
+    }
+
+
+    public static String getSystemProperties(final Message msg, final String key) {
+        return msg.getSystemProperties(key);
+    }
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageListener.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageListener.java
new file mode 100644
index 0000000..22b56c7
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageListener.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api;
+
+
+public interface MessageListener {
+
+    Action consume(final Message message, final ConsumeContext context);
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageSelector.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageSelector.java
new file mode 100644
index 0000000..f28bdae
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageSelector.java
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api;
+
+public class MessageSelector {
+
+    private ExpressionType type;
+
+    private String subExpression;
+
+    public static MessageSelector bySql(String subExpression) {
+        return new MessageSelector(ExpressionType.SQL92, subExpression);
+    }
+
+    public static MessageSelector byTag(String subExpression) {
+        return new MessageSelector(ExpressionType.TAG, subExpression);
+    }
+
+    private MessageSelector() {
+    }
+
+    private MessageSelector(ExpressionType type, String subExpression) {
+        this.type = type;
+        this.subExpression = subExpression;
+    }
+
+    public ExpressionType getType() {
+        return type;
+    }
+
+    public String getSubExpression() {
+        return subExpression;
+    }
+}
\ No newline at end of file
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/ONSFactory.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/ONSFactory.java
new file mode 100644
index 0000000..eaff503
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/ONSFactory.java
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api;
+
+import org.apache.rocketmq.ons.api.batch.BatchConsumer;
+import org.apache.rocketmq.ons.api.order.OrderConsumer;
+import org.apache.rocketmq.ons.api.order.OrderProducer;
+import org.apache.rocketmq.ons.api.transaction.LocalTransactionChecker;
+import org.apache.rocketmq.ons.api.transaction.TransactionProducer;
+import java.util.Properties;
+
+
+public class ONSFactory {
+
+
+    private static ONSFactoryAPI onsFactory = null;
+
+    static {
+        try {
+
+            Class<?> factoryClass =
+                    ONSFactory.class.getClassLoader().loadClass(
+                            "org.apache.rocketmq.ons.api.impl.ONSFactoryNotifyAndMetaQImpl");
+            onsFactory = (ONSFactoryAPI) factoryClass.newInstance();
+        } catch (Throwable e) {
+            try {
+                Class<?> factoryClass =
+                        ONSFactory.class.getClassLoader().loadClass(
+                                "org.apache.rocketmq.ons.api.impl.ONSFactoryImpl");
+                onsFactory = (ONSFactoryAPI) factoryClass.newInstance();
+            } catch (Throwable e1) {
+                e.printStackTrace();
+                e1.printStackTrace();
+            }
+        }
+    }
+
+
+
+    public static Producer createProducer(final Properties properties) {
+        return onsFactory.createProducer(properties);
+    }
+
+
+
+    public static OrderProducer createOrderProducer(final Properties properties) {
+        return onsFactory.createOrderProducer(properties);
+    }
+
+
+
+    public static TransactionProducer createTransactionProducer(final Properties properties,
+                                                                final LocalTransactionChecker checker) {
+        return onsFactory.createTransactionProducer(properties, checker);
+    }
+
+
+
+    public static Consumer createConsumer(final Properties properties) {
+        return onsFactory.createConsumer(properties);
+    }
+
+
+    public static BatchConsumer createBatchConsumer(final Properties properties) {
+        return onsFactory.createBatchConsumer(properties);
+    }
+
+
+
+    public static OrderConsumer createOrderedConsumer(final Properties properties) {
+        return onsFactory.createOrderedConsumer(properties);
+    }
+
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/ONSFactoryAPI.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/ONSFactoryAPI.java
new file mode 100644
index 0000000..b4bdd8a
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/ONSFactoryAPI.java
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api;
+
+import org.apache.rocketmq.ons.api.batch.BatchConsumer;
+import org.apache.rocketmq.ons.api.order.OrderConsumer;
+import org.apache.rocketmq.ons.api.order.OrderProducer;
+import org.apache.rocketmq.ons.api.transaction.LocalTransactionChecker;
+import org.apache.rocketmq.ons.api.transaction.TransactionProducer;
+import java.util.Properties;
+
+public interface ONSFactoryAPI {
+
+    Producer createProducer(final Properties properties);
+
+    Consumer createConsumer(final Properties properties);
+
+    BatchConsumer createBatchConsumer(final Properties properties);
+
+    OrderProducer createOrderProducer(final Properties properties);
+
+    OrderConsumer createOrderedConsumer(final Properties properties);
+
+    TransactionProducer createTransactionProducer(final Properties properties,
+        final LocalTransactionChecker checker);
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/OnExceptionContext.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/OnExceptionContext.java
new file mode 100644
index 0000000..3eb7620
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/OnExceptionContext.java
@@ -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.
+ */
+package org.apache.rocketmq.ons.api;
+
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+
+
+public class OnExceptionContext {
+
+
+    private String messageId;
+
+
+    private String topic;
+
+
+    private ONSClientException exception;
+
+    public String getMessageId() {
+        return messageId;
+    }
+
+    public void setMessageId(String messageId) {
+        this.messageId = messageId;
+    }
+
+    public String getTopic() {
+        return topic;
+    }
+
+    public void setTopic(String topic) {
+        this.topic = topic;
+    }
+
+    public ONSClientException getException() {
+        return exception;
+    }
+
+    public void setException(ONSClientException exception) {
+        this.exception = exception;
+    }
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Producer.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Producer.java
new file mode 100644
index 0000000..e45e613
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Producer.java
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api;
+
+import java.util.concurrent.ExecutorService;
+
+public interface Producer extends Admin {
+
+
+    @Override
+    void start();
+
+    @Override
+    void shutdown();
+
+    SendResult send(final Message message);
+
+    void sendOneway(final Message message);
+
+    void sendAsync(final Message message, final SendCallback sendCallback);
+
+    void setCallbackExecutor(final ExecutorService callbackExecutor);
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PropertyKeyConst.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PropertyKeyConst.java
new file mode 100644
index 0000000..d98d49c
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PropertyKeyConst.java
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api;
+
+import javax.annotation.Generated;
+
+@Generated("ons-api")
+public class PropertyKeyConst {
+
+    public static final String MessageModel = "MessageModel";
+
+    /**
+     * Deprecated, replaced with GROUP_ID
+     */
+    @Deprecated
+    public static final String ProducerId = "ProducerId";
+
+    /**
+     * Deprecated, replaced with GROUP_ID
+     */
+    @Deprecated
+    public static final String ConsumerId = "ConsumerId";
+
+    public static final String GROUP_ID = "GROUP_ID";
+
+    public static final String AccessKey = "AccessKey";
+
+    public static final String SecretKey = "SecretKey";
+
+    public static final String SecurityToken = "SecurityToken";
+
+    public static final String SendMsgTimeoutMillis = "SendMsgTimeoutMillis";
+
+    public static final String ONSAddr = "ONSAddr";
+
+    public static final String NAMESRV_ADDR = "NAMESRV_ADDR";
+
+    public static final String ConsumeThreadNums = "ConsumeThreadNums";
+
+    public static final String OnsChannel = "OnsChannel";
+
+    public static final String MQType = "MQType";
+
+    public static final String isVipChannelEnabled = "isVipChannelEnabled";
+
+    public static final String SuspendTimeMillis = "suspendTimeMillis";
+
+    public static final String MaxReconsumeTimes = "maxReconsumeTimes";
+
+    public static final String ConsumeTimeout = "consumeTimeout";
+
+    public static final String CheckImmunityTimeInSeconds = "CheckImmunityTimeInSeconds";
+
+    public static final String PostSubscriptionWhenPull = "PostSubscriptionWhenPull";
+
+    public static final String ConsumeMessageBatchMaxSize = "ConsumeMessageBatchMaxSize";
+
+    public static final String MaxCachedMessageAmount = "maxCachedMessageAmount";
+
+    public static final String MaxCachedMessageSizeInMiB = "maxCachedMessageSizeInMiB";
+
+    public static final String InstanceName = "InstanceName";
+
+    public static final String MsgTraceSwitch = "MsgTraceSwitch";
+
+    public static final String MqttMessageId = "mqttMessageId";
+
+    public static final String MqttMessage = "mqttMessage";
+
+    public static final String MqttPublishRetain = "mqttRetain";
+
+    public static final String MqttPublishDubFlag = "mqttPublishDubFlag";
+
+    public static final String MqttSecondTopic = "mqttSecondTopic";
+
+    public static final String MqttClientId = "clientId";
+
+    public static final String MqttQOS = "qoslevel";
+
+    public static final String INSTANCE_ID = "INSTANCE_ID";
+
+    public static final String EXACTLYONCE_DELIVERY = "exactlyOnceDelivery";
+
+    public static final String EXACTLYONCE_RM_REFRESHINTERVAL = "exactlyOnceRmRefreshInterval";
+
+    public static final String MAX_BATCH_MESSAGE_COUNT = "maxBatchMessageCount";
+
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PropertyValueConst.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PropertyValueConst.java
new file mode 100644
index 0000000..c748447
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PropertyValueConst.java
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api;
+
+
+public class PropertyValueConst {
+
+
+    public static final String BROADCASTING = "BROADCASTING";
+
+
+    public static final String CLUSTERING = "CLUSTERING";
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/SendCallback.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/SendCallback.java
new file mode 100644
index 0000000..ade3f70
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/SendCallback.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api;
+
+public interface SendCallback {
+
+    void onSuccess(final SendResult sendResult);
+
+    void onException(final OnExceptionContext context);
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/SendResult.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/SendResult.java
new file mode 100644
index 0000000..2dd0bb5
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/SendResult.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.rocketmq.ons.api;
+
+public class SendResult {
+
+    private String messageId;
+
+    private String topic;
+
+
+    public String getMessageId() {
+        return messageId;
+    }
+
+
+    public void setMessageId(String messageId) {
+        this.messageId = messageId;
+    }
+
+    public String getTopic() {
+        return topic;
+    }
+
+    public void setTopic(String topic) {
+        this.topic = topic;
+    }
+
+    @Override
+    public String toString() {
+        return "SendResult[topic=" + topic + ", messageId=" + messageId + ']';
+    }
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/batch/BatchConsumer.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/batch/BatchConsumer.java
new file mode 100644
index 0000000..848a139
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/batch/BatchConsumer.java
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.batch;
+
+import org.apache.rocketmq.ons.api.Admin;
+
+public interface BatchConsumer extends Admin {
+
+    void subscribe(final String topic, final String subExpression, final BatchMessageListener listener);
+
+    void unsubscribe(final String topic);
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/batch/BatchMessageListener.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/batch/BatchMessageListener.java
new file mode 100644
index 0000000..3716a90
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/batch/BatchMessageListener.java
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.batch;
+
+import org.apache.rocketmq.ons.api.Action;
+import org.apache.rocketmq.ons.api.ConsumeContext;
+import org.apache.rocketmq.ons.api.Message;
+import java.util.List;
+
+
+public interface BatchMessageListener {
+
+    Action consume(final List<Message> messages, final ConsumeContext context);
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/BatchConsumerBean.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/BatchConsumerBean.java
new file mode 100644
index 0000000..1cfedde
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/BatchConsumerBean.java
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.bean;
+
+import java.util.Map;
+import java.util.Properties;
+import org.apache.rocketmq.ons.api.ONSFactory;
+import org.apache.rocketmq.ons.api.batch.BatchConsumer;
+import org.apache.rocketmq.ons.api.batch.BatchMessageListener;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+
+
+public class BatchConsumerBean implements BatchConsumer {
+
+    private Properties properties;
+
+
+    private Map<Subscription, BatchMessageListener> subscriptionTable;
+
+    private BatchConsumer batchConsumer;
+
+    @Override
+    public boolean isStarted() {
+        return this.batchConsumer.isStarted();
+    }
+
+    @Override
+    public boolean isClosed() {
+        return this.batchConsumer.isClosed();
+    }
+
+
+    @Override
+    public void start() {
+        if (null == this.properties) {
+            throw new ONSClientException("properties not set");
+        }
+
+        if (null == this.subscriptionTable) {
+            throw new ONSClientException("subscriptionTable not set");
+        }
+
+        this.batchConsumer = ONSFactory.createBatchConsumer(this.properties);
+
+        for (final Map.Entry<Subscription, BatchMessageListener> next : this.subscriptionTable.entrySet()) {
+            this.subscribe(next.getKey().getTopic(), next.getKey().getExpression(), next.getValue());
+        }
+
+        this.batchConsumer.start();
+    }
+
+    @Override
+    public void updateCredential(Properties credentialProperties) {
+        if (this.batchConsumer != null) {
+            this.batchConsumer.updateCredential(credentialProperties);
+        }
+    }
+
+
+    @Override
+    public void shutdown() {
+        if (this.batchConsumer != null) {
+            this.batchConsumer.shutdown();
+        }
+    }
+
+    @Override
+    public void subscribe(final String topic, final String subExpression, final BatchMessageListener listener) {
+        if (null == this.batchConsumer) {
+            throw new ONSClientException("subscribe must be called after BatchConsumerBean started");
+        }
+        this.batchConsumer.subscribe(topic, subExpression, listener);
+    }
+
+    @Override
+    public void unsubscribe(final String topic) {
+        if (null == this.batchConsumer) {
+            throw new ONSClientException("unsubscribe must be called after BatchConsumerBean started");
+        }
+        this.batchConsumer.unsubscribe(topic);
+    }
+
+    public Properties getProperties() {
+        return properties;
+    }
+
+    public void setProperties(final Properties properties) {
+        this.properties = properties;
+    }
+
+    public Map<Subscription, BatchMessageListener> getSubscriptionTable() {
+        return subscriptionTable;
+    }
+
+    public void setSubscriptionTable(
+        final Map<Subscription, BatchMessageListener> subscriptionTable) {
+        this.subscriptionTable = subscriptionTable;
+    }
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/ConsumerBean.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/ConsumerBean.java
new file mode 100644
index 0000000..839ad62
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/ConsumerBean.java
@@ -0,0 +1,157 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.bean;
+
+import java.lang.reflect.Method;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import org.apache.rocketmq.ons.api.Consumer;
+import org.apache.rocketmq.ons.api.ExpressionType;
+import org.apache.rocketmq.ons.api.MessageListener;
+import org.apache.rocketmq.ons.api.MessageSelector;
+import org.apache.rocketmq.ons.api.ONSFactory;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+
+
+public class ConsumerBean implements Consumer {
+
+    private Properties properties;
+
+
+    private Map<Subscription, MessageListener> subscriptionTable;
+
+    private Consumer consumer;
+
+
+    @Override
+    public void start() {
+        if (null == this.properties) {
+            throw new ONSClientException("properties not set");
+        }
+
+        if (null == this.subscriptionTable) {
+            throw new ONSClientException("subscriptionTable not set");
+        }
+
+        this.consumer = ONSFactory.createConsumer(this.properties);
+
+        Iterator<Entry<Subscription, MessageListener>> it = this.subscriptionTable.entrySet().iterator();
+        while (it.hasNext()) {
+            Entry<Subscription, MessageListener> next = it.next();
+            if ("com.aliyun.openservices.ons.api.impl.notify.ConsumerImpl".equals(this.consumer.getClass().getCanonicalName())
+                && (next.getKey() instanceof SubscriptionExt)) {
+                SubscriptionExt subscription = (SubscriptionExt) next.getKey();
+                for (Method method : this.consumer.getClass().getMethods()) {
+                    if ("subscribeNotify".equals(method.getName())) {
+                        try {
+                            method.invoke(consumer, subscription.getTopic(), subscription.getExpression(),
+                                    subscription.isPersistence(), next.getValue());
+                        } catch (Exception e) {
+                            throw new ONSClientException("subscribeNotify invoke exception", e);
+                        }
+                        break;
+                    }
+                }
+
+            } else {
+                Subscription subscription = next.getKey();
+                if (subscription.getType() == null || ExpressionType.TAG.name().equals(subscription.getType())) {
+
+                    this.subscribe(subscription.getTopic(), subscription.getExpression(), next.getValue());
+
+                } else if (ExpressionType.SQL92.name().equals(subscription.getType())) {
+
+                    this.subscribe(subscription.getTopic(), MessageSelector.bySql(subscription.getExpression()), next.getValue());
+                } else {
+
+                    throw new ONSClientException(String.format("Expression type %s is unknown!", subscription.getType()));
+                }
+            }
+
+        }
+
+        this.consumer.start();
+    }
+
+    @Override
+    public void updateCredential(Properties credentialProperties) {
+        if (this.consumer != null) {
+            this.consumer.updateCredential(credentialProperties);
+        }
+    }
+
+
+    @Override
+    public void shutdown() {
+        if (this.consumer != null) {
+            this.consumer.shutdown();
+        }
+    }
+
+    @Override
+    public void subscribe(String topic, String subExpression, MessageListener listener) {
+        if (null == this.consumer) {
+            throw new ONSClientException("subscribe must be called after consumerBean started");
+        }
+        this.consumer.subscribe(topic, subExpression, listener);
+    }
+
+    @Override
+    public void subscribe(final String topic, final MessageSelector selector, final MessageListener listener) {
+        if (null == this.consumer) {
+            throw new ONSClientException("subscribe must be called after consumerBean started");
+        }
+        this.consumer.subscribe(topic, selector, listener);
+    }
+
+    @Override
+    public void unsubscribe(String topic) {
+        if (null == this.consumer) {
+            throw new ONSClientException("unsubscribe must be called after consumerBean started");
+        }
+        this.consumer.unsubscribe(topic);
+    }
+
+    public Properties getProperties() {
+        return properties;
+    }
+
+    public void setProperties(Properties properties) {
+        this.properties = properties;
+    }
+
+    public Map<Subscription, MessageListener> getSubscriptionTable() {
+        return subscriptionTable;
+    }
+
+    public void setSubscriptionTable(Map<Subscription, MessageListener> subscriptionTable) {
+        this.subscriptionTable = subscriptionTable;
+    }
+
+    @Override
+    public boolean isStarted() {
+        return this.consumer.isStarted();
+    }
+
+    @Override
+    public boolean isClosed() {
+        return this.consumer.isClosed();
+    }
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/OrderConsumerBean.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/OrderConsumerBean.java
new file mode 100644
index 0000000..e5b6402
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/OrderConsumerBean.java
@@ -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.
+ */
+
+package org.apache.rocketmq.ons.api.bean;
+
+import java.util.Map;
+import java.util.Properties;
+import org.apache.rocketmq.ons.api.MessageSelector;
+import org.apache.rocketmq.ons.api.ONSFactory;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+import org.apache.rocketmq.ons.api.order.MessageOrderListener;
+import org.apache.rocketmq.ons.api.order.OrderConsumer;
+
+public class OrderConsumerBean implements OrderConsumer {
+
+    private Properties properties;
+
+    private Map<Subscription, MessageOrderListener> subscriptionTable;
+
+    private OrderConsumer orderConsumer;
+
+    @Override
+    public boolean isStarted() {
+        return this.orderConsumer.isStarted();
+    }
+
+    @Override
+    public boolean isClosed() {
+        return this.orderConsumer.isClosed();
+    }
+
+    @Override
+    public void start() {
+        if (null == this.properties) {
+            throw new ONSClientException("properties not set");
+        }
+
+        if (null == this.subscriptionTable) {
+            throw new ONSClientException("subscriptionTable not set");
+        }
+
+        this.orderConsumer = ONSFactory.createOrderedConsumer(this.properties);
+
+        for (final Map.Entry<Subscription, MessageOrderListener> next : this.subscriptionTable.entrySet()) {
+            this.subscribe(next.getKey().getTopic(), next.getKey().getExpression(), next.getValue());
+        }
+
+        this.orderConsumer.start();
+    }
+
+    @Override
+    public void updateCredential(Properties credentialProperties) {
+        if (this.orderConsumer != null) {
+            this.orderConsumer.updateCredential(credentialProperties);
+        }
+    }
+
+    @Override
+    public void shutdown() {
+        if (this.orderConsumer != null) {
+            this.orderConsumer.shutdown();
+        }
+    }
+
+    @Override
+    public void subscribe(final String topic, final String subExpression, final MessageOrderListener listener) {
+        if (null == this.orderConsumer) {
+            throw new ONSClientException("subscribe must be called after OrderConsumerBean started");
+        }
+        this.orderConsumer.subscribe(topic, subExpression, listener);
+    }
+
+    @Override
+    public void subscribe(String topic, MessageSelector selector, MessageOrderListener listener) {
+        if (null == this.orderConsumer) {
+            throw new ONSClientException("subscribe must be called after OrderConsumerBean started");
+        }
+        this.orderConsumer.subscribe(topic, selector, listener);
+    }
+
+    public Properties getProperties() {
+        return properties;
+    }
+
+    public void setProperties(final Properties properties) {
+        this.properties = properties;
+    }
+
+    public Map<Subscription, MessageOrderListener> getSubscriptionTable() {
+        return subscriptionTable;
+    }
+
+    public void setSubscriptionTable(
+        final Map<Subscription, MessageOrderListener> subscriptionTable) {
+        this.subscriptionTable = subscriptionTable;
+    }
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/OrderProducerBean.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/OrderProducerBean.java
new file mode 100644
index 0000000..64cf25b
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/OrderProducerBean.java
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.bean;
+
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.ONSFactory;
+import org.apache.rocketmq.ons.api.SendResult;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+import org.apache.rocketmq.ons.api.order.OrderProducer;
+import java.util.Properties;
+
+
+public class OrderProducerBean implements OrderProducer {
+
+    private Properties properties;
+
+    private OrderProducer orderProducer;
+
+
+    @Override
+    public void start() {
+        if (null == this.properties) {
+            throw new ONSClientException("properties not set");
+        }
+
+        this.orderProducer = ONSFactory.createOrderProducer(this.properties);
+        this.orderProducer.start();
+    }
+
+    @Override
+    public void updateCredential(Properties credentialProperties) {
+        if (this.orderProducer != null) {
+            this.orderProducer.updateCredential(credentialProperties);
+        }
+    }
+
+
+    @Override
+    public void shutdown() {
+        if (this.orderProducer != null) {
+            this.orderProducer.shutdown();
+        }
+    }
+
+    @Override
+    public boolean isStarted() {
+        return this.orderProducer.isStarted();
+    }
+
+    @Override
+    public boolean isClosed() {
+        return this.orderProducer.isClosed();
+    }
+
+    @Override
+    public SendResult send(final Message message, final String shardingKey) {
+        return this.orderProducer.send(message, shardingKey);
+    }
+
+    public Properties getProperties() {
+        return properties;
+    }
+
+    public void setProperties(final Properties properties) {
+        this.properties = properties;
+    }
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/ProducerBean.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/ProducerBean.java
new file mode 100644
index 0000000..2094158
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/ProducerBean.java
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.bean;
+
+import java.util.Properties;
+import java.util.concurrent.ExecutorService;
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.ONSFactory;
+import org.apache.rocketmq.ons.api.Producer;
+import org.apache.rocketmq.ons.api.SendCallback;
+import org.apache.rocketmq.ons.api.SendResult;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+
+
+public class ProducerBean implements Producer {
+
+    private Properties properties;
+    private Producer producer;
+
+    @Override
+    public void start() {
+        if (null == this.properties) {
+            throw new ONSClientException("properties not set");
+        }
+
+        this.producer = ONSFactory.createProducer(this.properties);
+        this.producer.start();
+    }
+
+    @Override
+    public void updateCredential(Properties credentialProperties) {
+        if (this.producer != null) {
+            this.producer.updateCredential(credentialProperties);
+        }
+    }
+
+    @Override
+    public void shutdown() {
+        if (this.producer != null) {
+            this.producer.shutdown();
+        }
+    }
+
+
+    @Override
+    public SendResult send(Message message) {
+        return this.producer.send(message);
+    }
+
+
+    @Override
+    public void sendOneway(Message message) {
+        this.producer.sendOneway(message);
+    }
+
+    @Override
+    public void sendAsync(Message message, SendCallback sendCallback) {
+        this.producer.sendAsync(message, sendCallback);
+    }
+
+    @Override
+    public void setCallbackExecutor(final ExecutorService callbackExecutor) {
+        this.producer.setCallbackExecutor(callbackExecutor);
+    }
+
+    public Properties getProperties() {
+        return properties;
+    }
+
+    public void setProperties(Properties properties) {
+        this.properties = properties;
+    }
+
+    @Override
+    public boolean isStarted() {
+        return this.producer.isStarted();
+    }
+
+    @Override
+    public boolean isClosed() {
+        return this.producer.isClosed();
+    }
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/Subscription.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/Subscription.java
new file mode 100644
index 0000000..1840d4d
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/Subscription.java
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.bean;
+
+import org.apache.rocketmq.ons.api.ExpressionType;
+
+public class Subscription {
+    private String topic;
+    private String expression;
+
+    /**
+     * TAG or SQL92
+     * <br>if null, equals to TAG
+     *
+     * @see ExpressionType#TAG
+     * @see ExpressionType#SQL92
+     */
+    private String type;
+
+    public String getTopic() {
+        return topic;
+    }
+
+    public void setTopic(String topic) {
+        this.topic = topic;
+    }
+
+    public String getExpression() {
+        return expression;
+    }
+
+    public void setExpression(String expression) {
+        this.expression = expression;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(final String type) {
+        this.type = type;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((topic == null) ? 0 : topic.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        Subscription other = (Subscription) obj;
+        if (topic == null) {
+            if (other.topic != null) {
+                return false;
+            }
+        } else if (!topic.equals(other.topic)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "Subscription [topic=" + topic + ", expression=" + expression + ", type=" + type + "]";
+    }
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/SubscriptionExt.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/SubscriptionExt.java
new file mode 100644
index 0000000..7413f90
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/SubscriptionExt.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.rocketmq.ons.api.bean;
+
+
+public class SubscriptionExt extends Subscription {
+    private boolean persistence = true;
+
+    public boolean isPersistence() {
+        return persistence;
+    }
+
+    public void setPersistence(boolean persistence) {
+        this.persistence = persistence;
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return super.equals(obj);
+    }
+
+    @Override
+    public String toString() {
+        return "Subscription [topic=" + super.getTopic() + ", expression=" + super.getExpression()
+            + ", persistence=" + persistence + "]";
+    }
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/TransactionProducerBean.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/TransactionProducerBean.java
new file mode 100644
index 0000000..cb55e14
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/TransactionProducerBean.java
@@ -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.
+ */
+
+package org.apache.rocketmq.ons.api.bean;
+
+import java.util.Properties;
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.ONSFactory;
+import org.apache.rocketmq.ons.api.SendResult;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+import org.apache.rocketmq.ons.api.transaction.LocalTransactionChecker;
+import org.apache.rocketmq.ons.api.transaction.LocalTransactionExecuter;
+import org.apache.rocketmq.ons.api.transaction.TransactionProducer;
+
+
+public class TransactionProducerBean implements TransactionProducer {
+
+    private Properties properties;
+
+
+    private LocalTransactionChecker localTransactionChecker;
+
+    private TransactionProducer transactionProducer;
+
+
+    @Override
+    public void start() {
+        if (null == this.properties) {
+            throw new ONSClientException("properties not set");
+        }
+
+        this.transactionProducer = ONSFactory.createTransactionProducer(properties, localTransactionChecker);
+        this.transactionProducer.start();
+    }
+
+    @Override
+    public void updateCredential(Properties credentialProperties) {
+        if (this.transactionProducer != null) {
+            this.transactionProducer.updateCredential(credentialProperties);
+        }
+    }
+
+
+    @Override
+    public void shutdown() {
+        if (this.transactionProducer != null) {
+            this.transactionProducer.shutdown();
+        }
+    }
+
+    @Override
+    public SendResult send(Message message, LocalTransactionExecuter executer, Object arg) {
+        return this.transactionProducer.send(message, executer, arg);
+    }
+
+    public Properties getProperties() {
+        return properties;
+    }
+
+    public void setProperties(Properties properties) {
+        this.properties = properties;
+    }
+
+    public LocalTransactionChecker getLocalTransactionChecker() {
+        return localTransactionChecker;
+    }
+
+    public void setLocalTransactionChecker(LocalTransactionChecker localTransactionChecker) {
+        this.localTransactionChecker = localTransactionChecker;
+    }
+
+    @Override
+    public boolean isStarted() {
+        return this.transactionProducer.isStarted();
+    }
+
+    @Override
+    public boolean isClosed() {
+        return this.transactionProducer.isClosed();
+    }
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/exception/ONSClientException.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/exception/ONSClientException.java
new file mode 100644
index 0000000..a761e3b
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/exception/ONSClientException.java
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.exception;
+
+
+public class ONSClientException extends RuntimeException {
+    private static final long serialVersionUID = 5755356574640041094L;
+
+
+    public ONSClientException() {
+    }
+
+
+    public ONSClientException(String message) {
+        super(message);
+    }
+
+
+    public ONSClientException(Throwable cause) {
+        super(cause);
+    }
+
+
+    public ONSClientException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/ConsumeOrderContext.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/ConsumeOrderContext.java
new file mode 100644
index 0000000..f7102c3
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/ConsumeOrderContext.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api.order;
+
+public class ConsumeOrderContext {
+
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/MessageOrderListener.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/MessageOrderListener.java
new file mode 100644
index 0000000..20a4003
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/MessageOrderListener.java
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.order;
+
+import org.apache.rocketmq.ons.api.Message;
+
+public interface MessageOrderListener {
+
+    OrderAction consume(final Message message, final ConsumeOrderContext context);
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/MessageQueueSelector.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/MessageQueueSelector.java
new file mode 100644
index 0000000..bee8d64
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/MessageQueueSelector.java
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.order;
+
+import org.apache.rocketmq.ons.api.Message;
+
+public interface MessageQueueSelector {
+
+    int select(final int queueTotal, final Message msg, final Object arg);
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderAction.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderAction.java
new file mode 100644
index 0000000..e2dc190
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderAction.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.order;
+
+
+public enum OrderAction {
+
+    Success,
+
+    Suspend,
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderConsumer.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderConsumer.java
new file mode 100644
index 0000000..4e73c1b
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderConsumer.java
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.order;
+
+import org.apache.rocketmq.ons.api.Admin;
+import org.apache.rocketmq.ons.api.MessageSelector;
+
+
+public interface OrderConsumer extends Admin {
+
+    @Override
+    void start();
+
+    @Override
+    void shutdown();
+
+    void subscribe(final String topic, final String subExpression, final MessageOrderListener listener);
+
+    void subscribe(final String topic, final MessageSelector selector, final MessageOrderListener listener);
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderProducer.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderProducer.java
new file mode 100644
index 0000000..4e9a0bb
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderProducer.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.order;
+
+import org.apache.rocketmq.ons.api.Admin;
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.SendResult;
+
+
+public interface OrderProducer extends Admin {
+
+    SendResult send(final Message message, final String shardingKey);
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/LocalTransactionChecker.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/LocalTransactionChecker.java
new file mode 100644
index 0000000..eb46593
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/LocalTransactionChecker.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api.transaction;
+
+import org.apache.rocketmq.ons.api.Message;
+
+public interface LocalTransactionChecker {
+
+    TransactionStatus check(final Message msg);
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/LocalTransactionExecuter.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/LocalTransactionExecuter.java
new file mode 100644
index 0000000..f3fe785
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/LocalTransactionExecuter.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.transaction;
+
+import org.apache.rocketmq.ons.api.Message;
+
+
+public interface LocalTransactionExecuter {
+
+    TransactionStatus execute(final Message msg, final Object arg);
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/TransactionProducer.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/TransactionProducer.java
new file mode 100644
index 0000000..c139db1
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/TransactionProducer.java
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.transaction;
+
+import org.apache.rocketmq.ons.api.Admin;
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.SendResult;
+
+
+public interface TransactionProducer extends Admin {
+
+    @Override
+    void start();
+
+
+    @Override
+    void shutdown();
+
+
+    SendResult send(final Message message,
+        final LocalTransactionExecuter executer,
+        final Object arg);
+}
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/TransactionStatus.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/TransactionStatus.java
new file mode 100644
index 0000000..c98c9ef
--- /dev/null
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/TransactionStatus.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.transaction;
+
+
+public enum TransactionStatus {
+
+    CommitTransaction,
+
+    RollbackTransaction,
+
+    Unknow
+}
diff --git a/ons-core/ons-auth4client/pom.xml b/ons-core/ons-auth4client/pom.xml
new file mode 100644
index 0000000..643f7c7
--- /dev/null
+++ b/ons-core/ons-auth4client/pom.xml
@@ -0,0 +1,37 @@
+<!--
+  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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>ons-all</artifactId>
+        <groupId>org.apache.rocketmq</groupId>
+        <version>1.8.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>ons-auth4client</artifactId>
+    <name>ons-auth4client ${project.version}</name>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.rocketmq</groupId>
+            <artifactId>rocketmq-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/AuthUtil.java b/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/AuthUtil.java
new file mode 100644
index 0000000..c8dd4f9
--- /dev/null
+++ b/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/AuthUtil.java
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api.impl.authority;
+
+import java.util.Map;
+import java.util.SortedMap;
+
+import org.apache.rocketmq.remoting.protocol.RemotingCommand;
+
+
+public class AuthUtil {
+    public static byte[] combineRequestContent(RemotingCommand request, SortedMap<String, String> fieldsMap) {
+        try {
+            StringBuilder sb = new StringBuilder("");
+            for (Map.Entry<String, String> entry : fieldsMap.entrySet()) {
+                if (!SessionCredentials.Signature.equals(entry.getKey())) {
+                    sb.append(entry.getValue());
+                }
+            }
+
+            return AuthUtil.combineBytes(sb.toString().getBytes(SessionCredentials.CHARSET), request.getBody());
+        } catch (Exception e) {
+            throw new RuntimeException("incompatible exception.", e);
+        }
+    }
+
+    public static byte[] combineBytes(byte[] b1, byte[] b2) {
+        int size = (null != b1 ? b1.length : 0) + (null != b2 ? b2.length : 0);
+        byte[] total = new byte[size];
+        if (null != b1) {
+            System.arraycopy(b1, 0, total, 0, b1.length);
+        }
+        if (null != b2) {
+            System.arraycopy(b2, 0, total, b1.length, b2.length);
+        }
+        return total;
+    }
+
+
+    public static String calSignature(byte[] data, String secretKey) {
+        String signature = OnsAuthSigner.calSignature(data, secretKey);
+        return signature;
+    }
+}
diff --git a/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/OnsAuthSigner.java b/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/OnsAuthSigner.java
new file mode 100644
index 0000000..b948779
--- /dev/null
+++ b/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/OnsAuthSigner.java
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.authority;
+
+import java.nio.charset.Charset;
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.rocketmq.common.constant.LoggerName;
+import org.apache.rocketmq.logging.InternalLogger;
+import org.apache.rocketmq.logging.InternalLoggerFactory;
+import org.apache.rocketmq.ons.api.impl.authority.exception.AuthenticationException;
+
+public class OnsAuthSigner {
+    private static final InternalLogger LOGGER = InternalLoggerFactory.getLogger(LoggerName.ROCKETMQ_AUTHORIZE_LOGGER_NAME);
+    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
+    public static final SigningAlgorithm DEFAULT_ALGORITHM = SigningAlgorithm.HmacSHA1;
+    private static final int CAL_SIGNATURE_FAILED = 10015;
+    private static final String CAL_SIGNATURE_FAILED_MSG = "[%s:signature-failed] unable to calculate a request signature. error=%s";
+
+    public static String calSignature(String data, String key) throws AuthenticationException {
+        return calSignature(data, key, DEFAULT_ALGORITHM, DEFAULT_CHARSET);
+    }
+
+    public static String calSignature(String data, String key, SigningAlgorithm algorithm,
+        Charset charset) throws AuthenticationException {
+        return signAndBase64Encode(data, key, algorithm, charset);
+    }
+
+    private static String signAndBase64Encode(String data, String key, SigningAlgorithm algorithm, Charset charset)
+        throws AuthenticationException {
+        try {
+            byte[] signature = sign(data.getBytes(charset), key.getBytes(charset), algorithm);
+            return new String(Base64.encodeBase64(signature), DEFAULT_CHARSET);
+        } catch (Exception e) {
+            String message = String.format(CAL_SIGNATURE_FAILED_MSG, CAL_SIGNATURE_FAILED, e.getMessage());
+            LOGGER.error(message, e);
+            throw new AuthenticationException("CAL_SIGNATURE_FAILED", CAL_SIGNATURE_FAILED, message, e);
+        }
+    }
+
+    private static byte[] sign(byte[] data, byte[] key, SigningAlgorithm algorithm) throws AuthenticationException {
+        try {
+            Mac mac = Mac.getInstance(algorithm.toString());
+            mac.init(new SecretKeySpec(key, algorithm.toString()));
+            return mac.doFinal(data);
+        } catch (Exception e) {
+            String message = String.format(CAL_SIGNATURE_FAILED_MSG, CAL_SIGNATURE_FAILED, e.getMessage());
+            LOGGER.error(message, e);
+            throw new AuthenticationException("CAL_SIGNATURE_FAILED", CAL_SIGNATURE_FAILED, message, e);
+        }
+    }
+
+    public static String calSignature(byte[] data, String key) throws AuthenticationException {
+        return calSignature(data, key, DEFAULT_ALGORITHM, DEFAULT_CHARSET);
+    }
+
+    public static String calSignature(byte[] data, String key, SigningAlgorithm algorithm,
+        Charset charset) throws AuthenticationException {
+        return signAndBase64Encode(data, key, algorithm, charset);
+    }
+
+    private static String signAndBase64Encode(byte[] data, String key, SigningAlgorithm algorithm, Charset charset)
+        throws AuthenticationException {
+        try {
+            byte[] signature = sign(data, key.getBytes(charset), algorithm);
+            return new String(Base64.encodeBase64(signature), DEFAULT_CHARSET);
+        } catch (Exception e) {
+            String message = String.format(CAL_SIGNATURE_FAILED_MSG, CAL_SIGNATURE_FAILED, e.getMessage());
+            LOGGER.error(message, e);
+            throw new AuthenticationException("CAL_SIGNATURE_FAILED", CAL_SIGNATURE_FAILED, message, e);
+        }
+    }
+
+}
diff --git a/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/SessionCredentials.java b/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/SessionCredentials.java
new file mode 100644
index 0000000..fdbac11
--- /dev/null
+++ b/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/SessionCredentials.java
@@ -0,0 +1,214 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.authority;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.Properties;
+
+import javax.annotation.Generated;
+
+import org.apache.rocketmq.common.MixAll;
+
+import org.apache.rocketmq.ons.api.impl.rocketmq.ONSChannel;
+
+@Generated("ons-auth4client")
+public class SessionCredentials {
+    public static final Charset CHARSET = Charset.forName("UTF-8");
+    public static final String AccessKey = "AccessKey";
+    public static final String SecretKey = "SecretKey";
+    public static final String Signature = "Signature";
+    public static final String SecurityToken = "SecurityToken";
+    public static final String SignatureMethod = "SignatureMethod";
+    public static final String ONSChannelKey = "OnsChannel";
+
+    public static final String KeyFile = System.getProperty("rocketmq.client.keyFile",
+        System.getProperty("user.home") + File.separator + "onskey");
+
+    private String accessKey;
+    private String secretKey;
+    private String securityToken;
+    private String signature;
+    private String signatureMethod;
+    private ONSChannel onsChannel = ONSChannel.ALIYUN;
+
+    public SessionCredentials() {
+        String keyContent = null;
+        try {
+            keyContent = MixAll.file2String(KeyFile);
+        } catch (IOException ignore) {
+        }
+        if (keyContent != null) {
+            Properties prop = MixAll.string2Properties(keyContent);
+            if (prop != null) {
+                this.updateContent(prop);
+            }
+        }
+    }
+
+    public void updateContent(Properties prop) {
+        {
+            String value = prop.getProperty(AccessKey);
+            if (value != null) {
+                this.accessKey = value.trim();
+            }
+        }
+        {
+            String value = prop.getProperty(SecretKey);
+            if (value != null) {
+                this.secretKey = value.trim();
+            }
+        }
+        {
+            Object value = prop.get(ONSChannelKey);
+            if (value != null) {
+                this.onsChannel = ONSChannel.valueOf(value.toString());
+            }
+        }
+
+        {
+            String value = prop.getProperty(SecurityToken);
+            if (value != null) {
+                this.securityToken = value.trim();
+            }
+        }
+    }
+
+    public String getAccessKey() {
+        return accessKey;
+    }
+
+    public void setAccessKey(String accessKey) {
+        this.accessKey = accessKey;
+    }
+
+    public String getSecretKey() {
+        return secretKey;
+    }
+
+    public void setSecretKey(String secretKey) {
+        this.secretKey = secretKey;
+    }
+
+    public String getSignature() {
+        return signature;
+    }
+
+    public void setSignature(String signature) {
+        this.signature = signature;
+    }
+
+    public String getSecurityToken() {
+        return securityToken;
+    }
+
+    public void setSecurityToken(final String securityToken) {
+        this.securityToken = securityToken;
+    }
+
+    public String getSignatureMethod() {
+        return signatureMethod;
+    }
+
+    public void setSignatureMethod(String signatureMethod) {
+        this.signatureMethod = signatureMethod;
+    }
+
+    public ONSChannel getOnsChannel() {
+        return onsChannel;
+    }
+
+    public void setOnsChannel(ONSChannel onsChannel) {
+        this.onsChannel = onsChannel;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((accessKey == null) ? 0 : accessKey.hashCode());
+        result = prime * result + ((secretKey == null) ? 0 : secretKey.hashCode());
+        result = prime * result + ((signature == null) ? 0 : signature.hashCode());
+        result = prime * result + ((signatureMethod == null) ? 0 : signatureMethod.hashCode());
+        result = prime * result + ((onsChannel == null) ? 0 : onsChannel.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+
+        SessionCredentials other = (SessionCredentials) obj;
+        if (accessKey == null) {
+            if (other.accessKey != null) {
+                return false;
+            }
+        } else if (!accessKey.equals(other.accessKey)) {
+            return false;
+        }
+
+        if (secretKey == null) {
+            if (other.secretKey != null) {
+                return false;
+            }
+        } else if (!secretKey.equals(other.secretKey)) {
+            return false;
+        }
+
+        if (signature == null) {
+            if (other.signature != null) {
+                return false;
+            }
+        } else if (!signature.equals(other.signature)) {
+            return false;
+        }
+
+        if (signatureMethod == null) {
+            if (other.signatureMethod != null) {
+                return false;
+            }
+        } else if (!signatureMethod.equals(other.signatureMethod)) {
+            return false;
+        }
+
+        if (onsChannel == null) {
+            if (other.onsChannel != null) {
+                return false;
+            }
+        } else if (!onsChannel.equals(other.onsChannel)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "SessionCredentials [accessKey=" + accessKey + ", secretKey=" + secretKey + ", signature="
+            + signature + ", signatureMethod=" + signatureMethod + ", onsChannel=" + onsChannel + "]";
+    }
+}
\ No newline at end of file
diff --git a/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/SigningAlgorithm.java b/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/SigningAlgorithm.java
new file mode 100644
index 0000000..663b887
--- /dev/null
+++ b/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/SigningAlgorithm.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.authority;
+
+public enum SigningAlgorithm {
+    HmacSHA1,
+    HmacSHA256,
+    HmacMD5;
+}
diff --git a/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/exception/AuthenticationException.java b/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/exception/AuthenticationException.java
new file mode 100644
index 0000000..4188a98
--- /dev/null
+++ b/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/exception/AuthenticationException.java
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.authority.exception;
+
+public class AuthenticationException extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+
+    private String status;
+    private int code;
+
+
+    public AuthenticationException(String status, int code) {
+        super();
+        this.status = status;
+        this.code = code;
+    }
+
+
+    public AuthenticationException(String status, int code, String message) {
+        super(message);
+        this.status = status;
+        this.code = code;
+    }
+
+
+    public AuthenticationException(String status, int code, Throwable throwable) {
+        super(throwable);
+        this.status = status;
+        this.code = code;
+    }
+
+
+    public AuthenticationException(String status, int code, String message, Throwable throwable) {
+        super(message, throwable);
+        this.status = status;
+        this.code = code;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+}
diff --git a/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/exception/FlowControlException.java b/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/exception/FlowControlException.java
new file mode 100644
index 0000000..17d872c
--- /dev/null
+++ b/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/exception/FlowControlException.java
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api.impl.authority.exception;
+
+public class FlowControlException extends RuntimeException {
+
+    private static final long serialVersionUID = -3662598055526208602L;
+    private final int code;
+
+    public FlowControlException(int code) {
+        super();
+        this.code = code;
+    }
+
+    public FlowControlException(int code, String message, Throwable cause) {
+        super(message, cause);
+        this.code = code;
+    }
+
+    public FlowControlException(int code, String message) {
+        super(message);
+        this.code = code;
+    }
+
+    public FlowControlException(int code, Throwable cause) {
+        super(cause);
+        this.code = code;
+    }
+
+}
diff --git a/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/exception/SignatureException.java b/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/exception/SignatureException.java
new file mode 100644
index 0000000..4269391
--- /dev/null
+++ b/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/authority/exception/SignatureException.java
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.authority.exception;
+
+public class SignatureException extends RuntimeException {
+
+    private static final long serialVersionUID = -3662598055526208602L;
+    private final int code;
+
+
+    public SignatureException(int code) {
+        super();
+        this.code = code;
+    }
+
+
+    public SignatureException(int code, String message, Throwable cause) {
+        super(message, cause);
+        this.code = code;
+    }
+
+
+    public SignatureException(int code, String message) {
+        super(message);
+        this.code = code;
+    }
+
+
+    public SignatureException(int code, Throwable cause) {
+        super(cause);
+        this.code = code;
+    }
+}
diff --git a/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/AbstractRPCHook.java b/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/AbstractRPCHook.java
new file mode 100644
index 0000000..102b24b
--- /dev/null
+++ b/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/AbstractRPCHook.java
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.rocketmq;
+
+import java.lang.reflect.Field;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.rocketmq.remoting.CommandCustomHeader;
+import org.apache.rocketmq.remoting.RPCHook;
+import org.apache.rocketmq.remoting.protocol.RemotingCommand;
+
+import static org.apache.rocketmq.ons.api.impl.authority.SessionCredentials.AccessKey;
+import static org.apache.rocketmq.ons.api.impl.authority.SessionCredentials.ONSChannelKey;
+import static org.apache.rocketmq.ons.api.impl.authority.SessionCredentials.SecurityToken;
+
+public abstract class AbstractRPCHook implements RPCHook {
+    protected ConcurrentHashMap<Class<? extends CommandCustomHeader>, Field[]> fieldCache =
+            new ConcurrentHashMap<Class<? extends CommandCustomHeader>, Field[]>();
+
+
+    protected SortedMap<String, String> parseRequestContent(RemotingCommand request, String ak, String securityToken, String onsChannel) {
+        CommandCustomHeader header = request.readCustomHeader();
+        // sort property
+        SortedMap<String, String> map = new TreeMap<String, String>();
+        map.put(AccessKey, ak);
+        map.put(ONSChannelKey, onsChannel);
+        if (securityToken != null) {
+            map.put(SecurityToken, securityToken);
+        }
+        try {
+            // add header properties
+            if (null != header) {
+                Field[] fields = fieldCache.get(header.getClass());
+                if (null == fields) {
+                    fields = header.getClass().getDeclaredFields();
+                    for (Field field : fields) {
+                        field.setAccessible(true);
+                    }
+                    Field[] tmp = fieldCache.putIfAbsent(header.getClass(), fields);
+                    if (null != tmp) {
+                        fields = tmp;
+                    }
+                }
+
+                for (Field field : fields) {
+                    Object value = field.get(header);
+                    if (null != value && !field.isSynthetic()) {
+                        map.put(field.getName(), value.toString());
+                    }
+                }
+            }
+            return map;
+        } catch (Exception e) {
+            throw new RuntimeException("incompatible exception.", e);
+        }
+    }
+
+}
diff --git a/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ClientRPCHook.java b/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ClientRPCHook.java
new file mode 100644
index 0000000..72e36b9
--- /dev/null
+++ b/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ClientRPCHook.java
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.rocketmq;
+
+import org.apache.rocketmq.remoting.protocol.RemotingCommand;
+import org.apache.rocketmq.ons.api.impl.authority.AuthUtil;
+import org.apache.rocketmq.ons.api.impl.authority.SessionCredentials;
+
+import static org.apache.rocketmq.ons.api.impl.authority.SessionCredentials.AccessKey;
+import static org.apache.rocketmq.ons.api.impl.authority.SessionCredentials.ONSChannelKey;
+import static org.apache.rocketmq.ons.api.impl.authority.SessionCredentials.SecurityToken;
+import static org.apache.rocketmq.ons.api.impl.authority.SessionCredentials.Signature;
+
+public class ClientRPCHook extends AbstractRPCHook {
+    private SessionCredentials sessionCredentials;
+
+    public ClientRPCHook(SessionCredentials sessionCredentials) {
+        this.sessionCredentials = sessionCredentials;
+    }
+
+    @Override
+    public void doBeforeRequest(String remoteAddr, RemotingCommand request) {
+        byte[] total = AuthUtil.combineRequestContent(request,
+            parseRequestContent(request, sessionCredentials.getAccessKey(),
+                sessionCredentials.getSecurityToken(), sessionCredentials.getOnsChannel().name()));
+        String signature = AuthUtil.calSignature(total, sessionCredentials.getSecretKey());
+        request.addExtField(Signature, signature);
+        request.addExtField(AccessKey, sessionCredentials.getAccessKey());
+        request.addExtField(ONSChannelKey, sessionCredentials.getOnsChannel().name());
+
+        if (sessionCredentials.getSecurityToken() != null) {
+            request.addExtField(SecurityToken, sessionCredentials.getSecurityToken());
+        }
+    }
+
+
+    @Override
+    public void doAfterResponse(String remoteAddr, RemotingCommand request, RemotingCommand response) {
+
+    }
+
+}
diff --git a/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSChannel.java b/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSChannel.java
new file mode 100644
index 0000000..93fdaf1
--- /dev/null
+++ b/ons-core/ons-auth4client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSChannel.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.rocketmq;
+
+public enum ONSChannel {
+    CLOUD,
+    ALIYUN,
+    ALL
+}
diff --git a/ons-core/ons-client/pom.xml b/ons-core/ons-client/pom.xml
new file mode 100644
index 0000000..7cc5df2
--- /dev/null
+++ b/ons-core/ons-client/pom.xml
@@ -0,0 +1,74 @@
+<!--
+  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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.apache.rocketmq</groupId>
+        <artifactId>ons-all</artifactId>
+        <version>1.8.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <packaging>jar</packaging>
+    <artifactId>ons-client</artifactId>
+    <name>ons-client ${project.version}</name>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.rocketmq</groupId>
+            <artifactId>rocketmq-client</artifactId>
+            <version>${rocketmq.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>ons-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>ons-trace-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>ons-auth4client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.11</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/MQClientInfo.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/MQClientInfo.java
new file mode 100644
index 0000000..96ce1ca
--- /dev/null
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/MQClientInfo.java
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl;
+
+import java.io.InputStream;
+import java.util.Properties;
+import org.apache.rocketmq.common.MQVersion;
+
+public class MQClientInfo {
+
+    public static int versionCode = MQVersion.CURRENT_VERSION;
+
+    static {
+        try {
+            InputStream stream = MQClientInfo.class.getClassLoader().getResourceAsStream("ons_client_info.properties");
+            Properties properties = new Properties();
+            properties.load(stream);
+            String pkgVersion = String.valueOf(properties.get("version"));
+            versionCode = Integer.MAX_VALUE - Integer.valueOf(pkgVersion.replaceAll("[^0-9]", ""));
+        } catch (Exception ignore) {
+        }
+    }
+
+}
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/ONSFactoryImpl.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/ONSFactoryImpl.java
new file mode 100644
index 0000000..4fca00e
--- /dev/null
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/ONSFactoryImpl.java
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl;
+
+import org.apache.rocketmq.client.producer.LocalTransactionState;
+import org.apache.rocketmq.client.producer.TransactionCheckListener;
+import org.apache.rocketmq.common.message.MessageExt;
+import java.util.Properties;
+import org.apache.rocketmq.ons.api.Constants;
+import org.apache.rocketmq.ons.api.Consumer;
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.ONSFactoryAPI;
+import org.apache.rocketmq.ons.api.Producer;
+import org.apache.rocketmq.ons.api.batch.BatchConsumer;
+import org.apache.rocketmq.ons.api.impl.rocketmq.BatchConsumerImpl;
+import org.apache.rocketmq.ons.api.impl.rocketmq.ConsumerImpl;
+import org.apache.rocketmq.ons.api.impl.rocketmq.ONSUtil;
+import org.apache.rocketmq.ons.api.impl.rocketmq.OrderConsumerImpl;
+import org.apache.rocketmq.ons.api.impl.rocketmq.OrderProducerImpl;
+import org.apache.rocketmq.ons.api.impl.rocketmq.ProducerImpl;
+import org.apache.rocketmq.ons.api.impl.rocketmq.TransactionProducerImpl;
+import org.apache.rocketmq.ons.api.order.OrderConsumer;
+import org.apache.rocketmq.ons.api.order.OrderProducer;
+import org.apache.rocketmq.ons.api.transaction.LocalTransactionChecker;
+import org.apache.rocketmq.ons.api.transaction.TransactionProducer;
+import org.apache.rocketmq.ons.api.transaction.TransactionStatus;
+
+public class ONSFactoryImpl implements ONSFactoryAPI {
+    @Override
+    public Producer createProducer(final Properties properties) {
+        return new ProducerImpl(ONSUtil.extractProperties(properties));
+    }
+
+
+    @Override
+    public Consumer createConsumer(final Properties properties) {
+        return new ConsumerImpl(ONSUtil.extractProperties(properties));
+    }
+
+    @Override
+    public BatchConsumer createBatchConsumer(final Properties properties) {
+        return new BatchConsumerImpl(ONSUtil.extractProperties(properties));
+    }
+
+    @Override
+    public OrderProducer createOrderProducer(final Properties properties) {
+        return new OrderProducerImpl(ONSUtil.extractProperties(properties));
+    }
+
+
+    @Override
+    public OrderConsumer createOrderedConsumer(final Properties properties) {
+        return new OrderConsumerImpl(ONSUtil.extractProperties(properties));
+    }
+
+    @Override
+    public TransactionProducer createTransactionProducer(Properties properties,
+                                                         final LocalTransactionChecker checker) {
+        return new TransactionProducerImpl(ONSUtil.extractProperties(properties), new TransactionCheckListener() {
+            @Override
+            public LocalTransactionState checkLocalTransactionState(MessageExt msg) {
+                String msgId = msg.getProperty(Constants.TRANSACTION_ID);
+                Message message = ONSUtil.msgConvert(msg);
+                message.setMsgID(msgId);
+                TransactionStatus check = checker.check(message);
+                if (TransactionStatus.CommitTransaction == check) {
+                    return LocalTransactionState.COMMIT_MESSAGE;
+                } else if (TransactionStatus.RollbackTransaction == check) {
+                    return LocalTransactionState.ROLLBACK_MESSAGE;
+                }
+                return LocalTransactionState.UNKNOW;
+            }
+        });
+    }
+}
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/BatchConsumerImpl.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/BatchConsumerImpl.java
new file mode 100644
index 0000000..592a40c
--- /dev/null
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/BatchConsumerImpl.java
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.rocketmq;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.annotation.Generated;
+
+import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
+import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
+import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
+import org.apache.rocketmq.common.UtilAll;
+import org.apache.rocketmq.common.message.MessageExt;
+import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
+
+import org.apache.rocketmq.ons.api.Action;
+import org.apache.rocketmq.ons.api.Constants;
+import org.apache.rocketmq.ons.api.ConsumeContext;
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.PropertyKeyConst;
+import org.apache.rocketmq.ons.api.PropertyValueConst;
+import org.apache.rocketmq.ons.api.batch.BatchConsumer;
+import org.apache.rocketmq.ons.api.batch.BatchMessageListener;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+
+@Generated("ons-client")
+public class BatchConsumerImpl extends ONSConsumerAbstract implements BatchConsumer {
+    private final static int MAX_BATCH_SIZE = 32;
+    private final static int MIN_BATCH_SIZE = 1;
+    private final ConcurrentHashMap<String, BatchMessageListener> subscribeTable = new ConcurrentHashMap<String, BatchMessageListener>();
+
+    public BatchConsumerImpl(final Properties properties) {
+        super(properties);
+
+        boolean postSubscriptionWhenPull = Boolean.parseBoolean(properties.getProperty(PropertyKeyConst.PostSubscriptionWhenPull, "false"));
+        this.defaultMQPushConsumer.setPostSubscriptionWhenPull(postSubscriptionWhenPull);
+
+        String messageModel = properties.getProperty(PropertyKeyConst.MessageModel, PropertyValueConst.CLUSTERING);
+        this.defaultMQPushConsumer.setMessageModel(MessageModel.valueOf(messageModel));
+
+        String consumeBatchSize = properties.getProperty(PropertyKeyConst.ConsumeMessageBatchMaxSize);
+        if (!UtilAll.isBlank(consumeBatchSize)) {
+            int batchSize = Math.min(MAX_BATCH_SIZE, Integer.valueOf(consumeBatchSize));
+            batchSize = Math.max(MIN_BATCH_SIZE, batchSize);
+            this.defaultMQPushConsumer.setConsumeMessageBatchMaxSize(batchSize);
+        }
+    }
+
+    @Override
+    public void start() {
+        this.defaultMQPushConsumer.registerMessageListener(new BatchMessageListenerImpl());
+        super.start();
+    }
+
+    @Override
+    public void subscribe(String topic, String subExpression, BatchMessageListener listener) {
+        if (null == topic) {
+            throw new ONSClientException("topic is null");
+        }
+
+        if (null == listener) {
+            throw new ONSClientException("listener is null");
+        }
+        this.subscribeTable.put(topic, listener);
+        super.subscribe(topic, subExpression);
+    }
+
+    @Override
+    public void unsubscribe(String topic) {
+        if (null != topic) {
+            this.subscribeTable.remove(topic);
+            super.unsubscribe(topic);
+        }
+    }
+
+    class BatchMessageListenerImpl implements MessageListenerConcurrently {
+
+        @Override
+        public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> rmqMsgList,
+            ConsumeConcurrentlyContext contextRMQ) {
+            List<Message> msgList = new ArrayList<Message>();
+            for (MessageExt rmqMsg : rmqMsgList) {
+                Message msg = ONSUtil.msgConvert(rmqMsg);
+                Map<String, String> propertiesMap = rmqMsg.getProperties();
+                msg.setMsgID(rmqMsg.getMsgId());
+                if (propertiesMap != null && propertiesMap.get(Constants.TRANSACTION_ID) != null) {
+                    msg.setMsgID(propertiesMap.get(Constants.TRANSACTION_ID));
+                }
+                msgList.add(msg);
+            }
+
+            BatchMessageListener listener = BatchConsumerImpl.this.subscribeTable.get(msgList.get(0).getTopic());
+            if (null == listener) {
+                throw new ONSClientException("BatchMessageListener is null");
+            }
+
+            final ConsumeContext context = new ConsumeContext();
+            Action action = listener.consume(msgList, context);
+            if (action != null) {
+                switch (action) {
+                    case CommitMessage:
+                        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
+                    case ReconsumeLater:
+                        return ConsumeConcurrentlyStatus.RECONSUME_LATER;
+                    default:
+                        break;
+                }
+            }
+            return null;
+        }
+    }
+}
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ConsumerImpl.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ConsumerImpl.java
new file mode 100644
index 0000000..415482f
--- /dev/null
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ConsumerImpl.java
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.rocketmq;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.annotation.Generated;
+
+import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
+import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
+import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
+import org.apache.rocketmq.common.message.MessageExt;
+import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
+
+import org.apache.rocketmq.ons.api.Action;
+import org.apache.rocketmq.ons.api.Constants;
+import org.apache.rocketmq.ons.api.ConsumeContext;
+import org.apache.rocketmq.ons.api.Consumer;
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.MessageListener;
+import org.apache.rocketmq.ons.api.MessageSelector;
+import org.apache.rocketmq.ons.api.PropertyKeyConst;
+import org.apache.rocketmq.ons.api.PropertyValueConst;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+
+@Generated("ons-client")
+public class ConsumerImpl extends ONSConsumerAbstract implements Consumer {
+    private final ConcurrentHashMap<String, MessageListener> subscribeTable = new ConcurrentHashMap<String, MessageListener>();
+
+    public ConsumerImpl(final Properties properties) {
+        super(properties);
+        boolean postSubscriptionWhenPull = Boolean.parseBoolean(properties.getProperty(PropertyKeyConst.PostSubscriptionWhenPull, "false"));
+        this.defaultMQPushConsumer.setPostSubscriptionWhenPull(postSubscriptionWhenPull);
+
+        String messageModel = properties.getProperty(PropertyKeyConst.MessageModel, PropertyValueConst.CLUSTERING);
+        this.defaultMQPushConsumer.setMessageModel(MessageModel.valueOf(messageModel));
+    }
+
+    @Override
+    public void start() {
+        this.defaultMQPushConsumer.registerMessageListener(new MessageListenerImpl());
+        super.start();
+    }
+
+
+    @Override
+    public void subscribe(String topic, String subExpression, MessageListener listener) {
+        if (null == topic) {
+            throw new ONSClientException("topic is null");
+        }
+
+        if (null == listener) {
+            throw new ONSClientException("listener is null");
+        }
+        this.subscribeTable.put(topic, listener);
+        super.subscribe(topic, subExpression);
+    }
+
+    @Override
+    public void subscribe(final String topic, final MessageSelector selector, final MessageListener listener) {
+        if (null == topic) {
+            throw new ONSClientException("topic is null");
+        }
+
+        if (null == listener) {
+            throw new ONSClientException("listener is null");
+        }
+        this.subscribeTable.put(topic, listener);
+        super.subscribe(topic, selector);
+    }
+
+
+    @Override
+    public void unsubscribe(String topic) {
+        if (null != topic) {
+            this.subscribeTable.remove(topic);
+            super.unsubscribe(topic);
+        }
+    }
+
+
+    class MessageListenerImpl implements MessageListenerConcurrently {
+
+        @Override
+        public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgsRMQList,
+            ConsumeConcurrentlyContext contextRMQ) {
+            MessageExt msgRMQ = msgsRMQList.get(0);
+            Message msg = ONSUtil.msgConvert(msgRMQ);
+            Map<String, String> stringStringMap = msgRMQ.getProperties();
+            msg.setMsgID(msgRMQ.getMsgId());
+            if (stringStringMap != null && stringStringMap.get(Constants.TRANSACTION_ID) != null) {
+                msg.setMsgID(stringStringMap.get(Constants.TRANSACTION_ID));
+            }
+            MessageListener listener = ConsumerImpl.this.subscribeTable.get(msg.getTopic());
+            if (null == listener) {
+                throw new ONSClientException("MessageListener is null");
+            }
+
+            final ConsumeContext context = new ConsumeContext();
+            Action action = listener.consume(msg, context);
+            if (action != null) {
+                switch (action) {
+                    case CommitMessage:
+                        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
+                    case ReconsumeLater:
+                        return ConsumeConcurrentlyStatus.RECONSUME_LATER;
+                    default:
+                        break;
+                }
+            }
+
+            return null;
+        }
+    }
+}
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/FAQ.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/FAQ.java
new file mode 100644
index 0000000..523184d
--- /dev/null
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/FAQ.java
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.rocketmq;
+
+public class FAQ {
+    public static final String FIND_NS_FAILED =
+            "http://rocketmq.apache.org/docs/faq/exceptions&namesrv_not_exist";
+
+    public static final String CONNECT_BROKER_FAILED =
+            "http://rocketmq.apache.org/docs/faq/exceptions&connect_broker_failed";
+
+    public static final String SEND_MSG_TO_BROKER_TIMEOUT =
+            "http://rocketmq.apache.org/docs/faq/exceptions&send_msg_failed";
+
+    public static final String SERVICE_STATE_WRONG =
+            "http://rocketmq.apache.org/docs/faq/exceptions&service_not_ok";
+
+    public static final String BROKER_RESPONSE_EXCEPTION =
+            "http://rocketmq.apache.org/docs/faq/exceptions&broker_response_exception";
+
+    public static final String CLIENT_CHECK_MSG_EXCEPTION =
+            "http://rocketmq.apache.org/docs/faq/exceptions&msg_check_failed";
+
+    public static final String TOPIC_ROUTE_NOT_EXIST =
+            "http://rocketmq.apache.org/docs/faq/exceptions&topic_not_exist";
+
+
+    public static String errorMessage(final String msg, final String url) {
+        return String.format("%s\nSee %s for further details.", msg, url);
+    }
+}
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSClientAbstract.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSClientAbstract.java
new file mode 100644
index 0000000..2cc4d9c
--- /dev/null
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSClientAbstract.java
@@ -0,0 +1,268 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.rocketmq;
+
+import java.util.Properties;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.annotation.Generated;
+
+import org.apache.rocketmq.ons.open.trace.core.dispatch.AsyncDispatcher;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl;
+import org.apache.rocketmq.common.UtilAll;
+import org.apache.rocketmq.common.namesrv.TopAddressing;
+import org.apache.rocketmq.logging.InternalLogger;
+
+import org.apache.rocketmq.ons.api.Admin;
+import org.apache.rocketmq.ons.api.PropertyKeyConst;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+import org.apache.rocketmq.ons.api.impl.authority.SessionCredentials;
+import org.apache.rocketmq.ons.api.impl.util.ClientLoggerUtil;
+import org.apache.rocketmq.ons.api.impl.util.NameAddrUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import static org.apache.rocketmq.common.UtilAll.getPid;
+
+@Generated("ons-client")
+public abstract class ONSClientAbstract implements Admin {
+
+    protected static final String WSADDR_INTERNAL = System.getProperty("com.aliyun.openservices.ons.addr.internal",
+        "http://onsaddr-internal.aliyun.com:8080/rocketmq/nsaddr4client-internal");
+
+    protected static final String WSADDR_INTERNET = System.getProperty("com.aliyun.openservices.ons.addr.internet",
+        "http://onsaddr-internet.aliyun.com/rocketmq/nsaddr4client-internet");
+    protected static final long WSADDR_INTERNAL_TIMEOUTMILLS =
+        Long.parseLong(System.getProperty("com.aliyun.openservices.ons.addr.internal.timeoutmills", "3000"));
+    protected static final long WSADDR_INTERNET_TIMEOUTMILLS =
+            Long.parseLong(System.getProperty("com.aliyun.openservices.ons.addr.internet.timeoutmills", "5000"));
+    private final static InternalLogger LOGGER = ClientLoggerUtil.getClientLogger();
+    protected final Properties properties;
+    protected final SessionCredentials sessionCredentials = new SessionCredentials();
+    protected String nameServerAddr = NameAddrUtils.getNameAdd();
+
+    protected AsyncDispatcher traceDispatcher = null;
+
+    protected final AtomicBoolean started = new AtomicBoolean(false);
+
+    private final ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1,
+        new ThreadFactory() {
+            @Override
+            public Thread newThread(Runnable r) {
+                return new Thread(r, "ONSClient-UpdateNameServerThread");
+            }
+        });
+
+    public ONSClientAbstract(Properties properties) {
+        this.properties = properties;
+        this.sessionCredentials.updateContent(properties);
+        if (null == this.sessionCredentials.getAccessKey() || "".equals(this.sessionCredentials.getAccessKey())) {
+            throw new ONSClientException("please set access key");
+        }
+
+        if (null == this.sessionCredentials.getSecretKey() || "".equals(this.sessionCredentials.getSecretKey())) {
+            throw new ONSClientException("please set secret key");
+        }
+
+        if (null == this.sessionCredentials.getOnsChannel()) {
+            throw new ONSClientException("please set ons channel");
+        }
+
+
+
+        this.nameServerAddr = getNameSrvAddrFromProperties();
+        if (nameServerAddr != null) {
+            return;
+        }
+        this.nameServerAddr = fetchNameServerAddr();
+        if (null == nameServerAddr) {
+            throw new ONSClientException(FAQ.errorMessage("Can not find name server, May be your network problem.", FAQ.FIND_NS_FAILED));
+        }
+
+        this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    String nsAddrs = fetchNameServerAddr();
+                    if (nsAddrs != null && !ONSClientAbstract.this.nameServerAddr.equals(nsAddrs)) {
+                        ONSClientAbstract.this.nameServerAddr = nsAddrs;
+                        if (isStarted()) {
+                            updateNameServerAddr(nsAddrs);
+                        }
+                    }
+                } catch (Exception e) {
+                    LOGGER.error("update name server periodically failed.", e);
+                }
+            }
+        }, 10 * 1000L, 90 * 1000L, TimeUnit.MILLISECONDS);
+
+    }
+
+    protected abstract void updateNameServerAddr(String newAddrs);
+
+    private String getNameSrvAddrFromProperties() {
+        String nameserverAddrs = this.properties.getProperty(PropertyKeyConst.NAMESRV_ADDR);
+        if (StringUtils.isNotEmpty(nameserverAddrs) && NameAddrUtils.NAMESRV_ENDPOINT_PATTERN.matcher(nameserverAddrs.trim()).matches()) {
+            return nameserverAddrs.substring(NameAddrUtils.ENDPOINT_PREFIX.length());
+        }
+
+        return nameserverAddrs;
+    }
+
+    private String fetchNameServerAddr() {
+        String nsAddrs;
+
+
+        {
+            String property = this.properties.getProperty(PropertyKeyConst.ONSAddr);
+            if (property != null) {
+                nsAddrs = new TopAddressing(property).fetchNSAddr();
+                if (nsAddrs != null) {
+                    LOGGER.info("connected to user-defined ons addr server, {} success, {}", property, nsAddrs);
+                    return nsAddrs;
+                } else {
+                    throw new ONSClientException(FAQ.errorMessage("Can not find name server with onsAddr " + property, FAQ.FIND_NS_FAILED));
+                }
+            }
+        }
+
+
+        {
+            TopAddressing top = new TopAddressing(WSADDR_INTERNAL);
+            nsAddrs = top.fetchNSAddr(false, WSADDR_INTERNAL_TIMEOUTMILLS);
+            if (nsAddrs != null) {
+                LOGGER.info("connected to internal server, {} success, {}", WSADDR_INTERNAL, nsAddrs);
+                return nsAddrs;
+            }
+        }
+
+
+        {
+            TopAddressing top = new TopAddressing(WSADDR_INTERNET);
+            nsAddrs = top.fetchNSAddr(false, WSADDR_INTERNET_TIMEOUTMILLS);
+            if (nsAddrs != null) {
+                LOGGER.info("connected to internet server, {} success, {}", WSADDR_INTERNET, nsAddrs);
+            }
+        }
+
+        return nsAddrs;
+    }
+
+    public String getNameServerAddr() {
+        return this.nameServerAddr;
+    }
+
+    protected String buildIntanceName() {
+        return Integer.toString(UtilAll.getPid())
+            + "#" + this.nameServerAddr.hashCode()
+            + "#" + this.sessionCredentials.getAccessKey().hashCode()
+            + "#" + System.nanoTime();
+    }
+
+    protected String getNamespace() {
+        String namespace = null;
+
+
+        {
+            String nameserverAddr = this.properties.getProperty(PropertyKeyConst.NAMESRV_ADDR);
+            if (StringUtils.isNotEmpty(nameserverAddr)) {
+                if (NameAddrUtils.validateInstanceEndpoint(nameserverAddr)) {
+                    namespace = NameAddrUtils.parseInstanceIdFromEndpoint(nameserverAddr);
+                    LOGGER.info("User specify namespace by endpoint: {}.", namespace);
+                }
+            }
+        }
+
+
+        {
+            String namespaceFromProperty = this.properties.getProperty(PropertyKeyConst.INSTANCE_ID, null);
+            if (StringUtils.isNotEmpty(namespaceFromProperty)) {
+                namespace = namespaceFromProperty;
+                LOGGER.info("User specify namespace by property: {}.", namespace);
+            }
+        }
+
+        return namespace;
+    }
+
+    protected void checkONSProducerServiceState(DefaultMQProducerImpl producer) {
+        switch (producer.getServiceState()) {
+            case CREATE_JUST:
+                throw new ONSClientException(
+                    FAQ.errorMessage(String.format("You do not have start the producer[" + getPid() + "], %s", producer.getServiceState()),
+                        FAQ.SERVICE_STATE_WRONG));
+            case SHUTDOWN_ALREADY:
+                throw new ONSClientException(FAQ.errorMessage(String.format("Your producer has been shut down, %s", producer.getServiceState()),
+                    FAQ.SERVICE_STATE_WRONG));
+            case START_FAILED:
+                throw new ONSClientException(FAQ.errorMessage(
+                    String.format("When you start your service throws an exception, %s", producer.getServiceState()), FAQ.SERVICE_STATE_WRONG));
+            case RUNNING:
+                break;
+            default:
+                break;
+        }
+    }
+
+    @Override
+    public void start() {
+        if (null != traceDispatcher) {
+            try {
+                traceDispatcher.start();
+            } catch (MQClientException e) {
+                LOGGER.warn("trace dispatcher start failed ", e);
+            }
+        }
+    }
+
+    @Override
+    public void updateCredential(Properties credentialProperties) {
+        if (null == credentialProperties.getProperty(SessionCredentials.AccessKey)
+                || "".equals(credentialProperties.getProperty(SessionCredentials.AccessKey))) {
+            throw new ONSClientException("update credential failed. please set access key.");
+        }
+
+        if (null == credentialProperties.getProperty(SessionCredentials.SecretKey)
+                || "".equals(credentialProperties.getProperty(SessionCredentials.SecretKey))) {
+            throw new ONSClientException("update credential failed. please set secret key");
+        }
+        this.sessionCredentials.updateContent(credentialProperties);
+    }
+
+    @Override
+    public void shutdown() {
+        if (null != traceDispatcher) {
+            traceDispatcher.shutdown();
+        }
+        scheduledExecutorService.shutdown();
+    }
+
+    @Override
+    public boolean isStarted() {
+        return started.get();
+    }
+
+    @Override
+    public boolean isClosed() {
+        return !isStarted();
+    }
+}
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSConsumerAbstract.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSConsumerAbstract.java
new file mode 100644
index 0000000..d2bb38b
--- /dev/null
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSConsumerAbstract.java
@@ -0,0 +1,198 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.rocketmq;
+
+import java.util.Properties;
+
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceConstants;
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceDispatcherType;
+import org.apache.rocketmq.ons.open.trace.core.dispatch.impl.AsyncArrayDispatcher;
+import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.common.UtilAll;
+import org.apache.rocketmq.logging.InternalLogger;
+
+import org.apache.rocketmq.ons.api.MessageSelector;
+import org.apache.rocketmq.ons.api.PropertyKeyConst;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+import org.apache.rocketmq.ons.api.impl.tracehook.OnsConsumeMessageHookImpl;
+import org.apache.rocketmq.ons.api.impl.util.ClientLoggerUtil;
+import org.apache.commons.lang3.StringUtils;
+
+public class ONSConsumerAbstract extends ONSClientAbstract {
+    final static InternalLogger LOGGER = ClientLoggerUtil.getClientLogger();
+    protected final DefaultMQPushConsumer defaultMQPushConsumer;
+    private final static int MAX_CACHED_MESSAGE_SIZE_IN_MIB = 2048;
+    private final static int MIN_CACHED_MESSAGE_SIZE_IN_MIB = 16;
+    private final static int MAX_CACHED_MESSAGE_AMOUNT = 50000;
+    private final static int MIN_CACHED_MESSAGE_AMOUNT = 100;
+
+    private int maxCachedMessageSizeInMiB = 512;
+
+    private int maxCachedMessageAmount = 5000;
+
+    public ONSConsumerAbstract(final Properties properties) {
+        super(properties);
+
+        String consumerGroup = properties.getProperty(PropertyKeyConst.GROUP_ID, properties.getProperty(PropertyKeyConst.ConsumerId));
+        if (StringUtils.isEmpty(consumerGroup)) {
+            throw new ONSClientException("ConsumerId property is null");
+        }
+
+        this.defaultMQPushConsumer =
+            new DefaultMQPushConsumer(this.getNamespace(), consumerGroup, new OnsClientRPCHook(sessionCredentials));
+
+
+        String maxReconsumeTimes = properties.getProperty(PropertyKeyConst.MaxReconsumeTimes);
+        if (!UtilAll.isBlank(maxReconsumeTimes)) {
+            try {
+                this.defaultMQPushConsumer.setMaxReconsumeTimes(Integer.parseInt(maxReconsumeTimes));
+            } catch (NumberFormatException ignored) {
+            }
+        }
+
+        String maxBatchMessageCount = properties.getProperty(PropertyKeyConst.MAX_BATCH_MESSAGE_COUNT);
+        if (!UtilAll.isBlank(maxBatchMessageCount)) {
+            this.defaultMQPushConsumer.setPullBatchSize(Integer.valueOf(maxBatchMessageCount));
+        }
+
+        String consumeTimeout = properties.getProperty(PropertyKeyConst.ConsumeTimeout);
+        if (!UtilAll.isBlank(consumeTimeout)) {
+            try {
+                this.defaultMQPushConsumer.setConsumeTimeout(Integer.parseInt(consumeTimeout));
+            } catch (NumberFormatException ignored) {
+            }
+        }
+
+        boolean isVipChannelEnabled = Boolean.parseBoolean(properties.getProperty(PropertyKeyConst.isVipChannelEnabled, "false"));
+        this.defaultMQPushConsumer.setVipChannelEnabled(isVipChannelEnabled);
+
+        String instanceName = properties.getProperty(PropertyKeyConst.InstanceName, this.buildIntanceName());
+        this.defaultMQPushConsumer.setInstanceName(instanceName);
+        this.defaultMQPushConsumer.setNamesrvAddr(this.getNameServerAddr());
+
+        String consumeThreadNums = properties.getProperty(PropertyKeyConst.ConsumeThreadNums);
+        if (!UtilAll.isBlank(consumeThreadNums)) {
+            this.defaultMQPushConsumer.setConsumeThreadMin(Integer.valueOf(consumeThreadNums));
+            this.defaultMQPushConsumer.setConsumeThreadMax(Integer.valueOf(consumeThreadNums));
+        }
+
+        String configuredCachedMessageAmount = properties.getProperty(PropertyKeyConst.MaxCachedMessageAmount);
+        if (!UtilAll.isBlank(configuredCachedMessageAmount)) {
+            maxCachedMessageAmount = Math.min(MAX_CACHED_MESSAGE_AMOUNT, Integer.valueOf(configuredCachedMessageAmount));
+            maxCachedMessageAmount = Math.max(MIN_CACHED_MESSAGE_AMOUNT, maxCachedMessageAmount);
+            this.defaultMQPushConsumer.setPullThresholdForTopic(maxCachedMessageAmount);
+
+        }
+
+        String configuredCachedMessageSizeInMiB = properties.getProperty(PropertyKeyConst.MaxCachedMessageSizeInMiB);
+        if (!UtilAll.isBlank(configuredCachedMessageSizeInMiB)) {
+            maxCachedMessageSizeInMiB = Math.min(MAX_CACHED_MESSAGE_SIZE_IN_MIB, Integer.valueOf(configuredCachedMessageSizeInMiB));
+            maxCachedMessageSizeInMiB = Math.max(MIN_CACHED_MESSAGE_SIZE_IN_MIB, maxCachedMessageSizeInMiB);
+            this.defaultMQPushConsumer.setPullThresholdSizeForTopic(maxCachedMessageSizeInMiB);
+        }
+
+        String msgTraceSwitch = properties.getProperty(PropertyKeyConst.MsgTraceSwitch);
+        if (!UtilAll.isBlank(msgTraceSwitch) && (!Boolean.parseBoolean(msgTraceSwitch))) {
+            LOGGER.info("MQ Client Disable the Trace Hook!");
+        } else {
+            try {
+                Properties tempProperties = new Properties();
+                tempProperties.put(OnsTraceConstants.AccessKey, sessionCredentials.getAccessKey());
+                tempProperties.put(OnsTraceConstants.SecretKey, sessionCredentials.getSecretKey());
+                tempProperties.put(OnsTraceConstants.MaxMsgSize, "128000");
+                tempProperties.put(OnsTraceConstants.AsyncBufferSize, "2048");
+                tempProperties.put(OnsTraceConstants.MaxBatchNum, "100");
+                tempProperties.put(OnsTraceConstants.NAMESRV_ADDR, this.getNameServerAddr());
+                tempProperties.put(OnsTraceConstants.InstanceName, "PID_CLIENT_INNER_TRACE_PRODUCER");
+                tempProperties.put(OnsTraceConstants.TraceDispatcherType, OnsTraceDispatcherType.CONSUMER.name());
+                AsyncArrayDispatcher dispatcher = new AsyncArrayDispatcher(tempProperties, sessionCredentials);
+                dispatcher.setHostConsumer(defaultMQPushConsumer.getDefaultMQPushConsumerImpl());
+                traceDispatcher = dispatcher;
+                this.defaultMQPushConsumer.getDefaultMQPushConsumerImpl().registerConsumeMessageHook(
+                    new OnsConsumeMessageHookImpl(traceDispatcher));
+            } catch (Throwable e) {
+                LOGGER.error("system mqtrace hook init failed ,maybe can't send msg trace data", e);
+            }
+        }
+    }
+
+    @Override
+    protected void updateNameServerAddr(String newAddrs) {
+        this.defaultMQPushConsumer.getDefaultMQPushConsumerImpl().getmQClientFactory().getMQClientAPIImpl().updateNameServerAddressList(newAddrs);
+    }
+
+    protected void subscribe(String topic, String subExpression) {
+        try {
+            this.defaultMQPushConsumer.subscribe(topic, subExpression);
+        } catch (MQClientException e) {
+            throw new ONSClientException("defaultMQPushConsumer subscribe exception", e);
+        }
+    }
+
+    protected void subscribe(final String topic, final MessageSelector selector) {
+        String subExpression = "*";
+        String type = org.apache.rocketmq.common.filter.ExpressionType.TAG;
+        if (selector != null) {
+            if (selector.getType() == null) {
+                throw new ONSClientException("Expression type is null!");
+            }
+            subExpression = selector.getSubExpression();
+            type = selector.getType().name();
+        }
+
+        org.apache.rocketmq.client.consumer.MessageSelector messageSelector;
+        if (org.apache.rocketmq.common.filter.ExpressionType.SQL92.equals(type)) {
+            messageSelector = org.apache.rocketmq.client.consumer.MessageSelector.bySql(subExpression);
+        } else if (org.apache.rocketmq.common.filter.ExpressionType.TAG.equals(type)) {
+            messageSelector = org.apache.rocketmq.client.consumer.MessageSelector.byTag(subExpression);
+        } else {
+            throw new ONSClientException(String.format("Expression type %s is unknown!", type));
+        }
+
+        try {
+            this.defaultMQPushConsumer.subscribe(topic, messageSelector);
+        } catch (MQClientException e) {
+            throw new ONSClientException("Consumer subscribe exception", e);
+        }
+    }
+
+    protected void unsubscribe(String topic) {
+        this.defaultMQPushConsumer.unsubscribe(topic);
+    }
+
+    @Override
+    public void start() {
+        try {
+            if (this.started.compareAndSet(false, true)) {
+                this.defaultMQPushConsumer.start();
+                super.start();
+            }
+        } catch (Exception e) {
+            throw new ONSClientException(e.getMessage());
+        }
+    }
+
+    @Override
+    public void shutdown() {
+        if (this.started.compareAndSet(true, false)) {
+            this.defaultMQPushConsumer.shutdown();
+        }
+        super.shutdown();
+    }
+}
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSUtil.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSUtil.java
new file mode 100644
index 0000000..e6fac51
--- /dev/null
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSUtil.java
@@ -0,0 +1,185 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.rocketmq;
+
+import java.lang.reflect.Field;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.rocketmq.common.message.MessageConst;
+import org.apache.rocketmq.common.message.MessageExt;
+
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.MessageAccessor;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+
+public class ONSUtil {
+    private static final Set<String> RESERVED_KEY_SET_RMQ = new HashSet<String>();
+
+    private static final Set<String> RESERVED_KEY_SET_ONS = new HashSet<String>();
+
+
+    static {
+
+        /**
+         * RMQ
+         */
+        RESERVED_KEY_SET_RMQ.add(MessageConst.PROPERTY_KEYS);
+        RESERVED_KEY_SET_RMQ.add(MessageConst.PROPERTY_TAGS);
+        RESERVED_KEY_SET_RMQ.add(MessageConst.PROPERTY_WAIT_STORE_MSG_OK);
+        RESERVED_KEY_SET_RMQ.add(MessageConst.PROPERTY_DELAY_TIME_LEVEL);
+        RESERVED_KEY_SET_RMQ.add(MessageConst.PROPERTY_RETRY_TOPIC);
+        RESERVED_KEY_SET_RMQ.add(MessageConst.PROPERTY_REAL_TOPIC);
+        RESERVED_KEY_SET_RMQ.add(MessageConst.PROPERTY_REAL_QUEUE_ID);
+        RESERVED_KEY_SET_RMQ.add(MessageConst.PROPERTY_TRANSACTION_PREPARED);
+        RESERVED_KEY_SET_RMQ.add(MessageConst.PROPERTY_PRODUCER_GROUP);
+        RESERVED_KEY_SET_RMQ.add(MessageConst.PROPERTY_MIN_OFFSET);
+        RESERVED_KEY_SET_RMQ.add(MessageConst.PROPERTY_MAX_OFFSET);
+
+        /**
+         * ONS
+         */
+        RESERVED_KEY_SET_ONS.add(Message.SystemPropKey.TAG);
+        RESERVED_KEY_SET_ONS.add(Message.SystemPropKey.KEY);
+        RESERVED_KEY_SET_ONS.add(Message.SystemPropKey.MSGID);
+        RESERVED_KEY_SET_ONS.add(Message.SystemPropKey.RECONSUMETIMES);
+        RESERVED_KEY_SET_ONS.add(Message.SystemPropKey.STARTDELIVERTIME);
+        RESERVED_KEY_SET_ONS.add(Message.SystemPropKey.BORNHOST);
+        RESERVED_KEY_SET_ONS.add(Message.SystemPropKey.BORNTIMESTAMP);
+        RESERVED_KEY_SET_ONS.add(Message.SystemPropKey.SHARDINGKEY);
+    }
+
+
+    public static org.apache.rocketmq.common.message.Message msgConvert(Message message) {
+        org.apache.rocketmq.common.message.Message msgRMQ = new org.apache.rocketmq.common.message.Message();
+        if (message == null) {
+            throw new ONSClientException("\'message\' is null");
+        }
+
+        if (message.getTopic() != null) {
+            msgRMQ.setTopic(message.getTopic());
+        }
+        if (message.getKey() != null) {
+            msgRMQ.setKeys(message.getKey());
+        }
+        if (message.getTag() != null) {
+            msgRMQ.setTags(message.getTag());
+        }
+        if (message.getStartDeliverTime() > 0) {
+            msgRMQ.putUserProperty(Message.SystemPropKey.STARTDELIVERTIME, String.valueOf(message.getStartDeliverTime()));
+        }
+        if (message.getBody() != null) {
+            msgRMQ.setBody(message.getBody());
+        }
+
+        if (message.getShardingKey() != null && !message.getShardingKey().isEmpty()) {
+            msgRMQ.putUserProperty(Message.SystemPropKey.SHARDINGKEY, message.getShardingKey());
+        }
+
+        Properties systemProperties = MessageAccessor.getSystemProperties(message);
+        if (systemProperties != null) {
+            Iterator<Entry<Object, Object>> it = systemProperties.entrySet().iterator();
+            while (it.hasNext()) {
+                Entry<Object, Object> next = it.next();
+                if (!RESERVED_KEY_SET_ONS.contains(next.getKey().toString())) {
+                    org.apache.rocketmq.common.message.MessageAccessor.putProperty(msgRMQ, next.getKey().toString(),
+                            next.getValue().toString());
+                }
+            }
+        }
+
+        Properties userProperties = message.getUserProperties();
+        if (userProperties != null) {
+            Iterator<Entry<Object, Object>> it = userProperties.entrySet().iterator();
+            while (it.hasNext()) {
+                Entry<Object, Object> next = it.next();
+                if (!RESERVED_KEY_SET_RMQ.contains(next.getKey().toString())) {
+                    org.apache.rocketmq.common.message.MessageAccessor.putProperty(msgRMQ, next.getKey().toString(),
+                            next.getValue().toString());
+                }
+            }
+        }
+
+        return msgRMQ;
+    }
+
+    public static Message msgConvert(org.apache.rocketmq.common.message.Message msgRMQ) {
+        Message message = new Message();
+        if (msgRMQ.getTopic() != null) {
+            message.setTopic(msgRMQ.getTopic());
+        }
+        if (msgRMQ.getKeys() != null) {
+            message.setKey(msgRMQ.getKeys());
+        }
+        if (msgRMQ.getTags() != null) {
+            message.setTag(msgRMQ.getTags());
+        }
+        if (msgRMQ.getBody() != null) {
+            message.setBody(msgRMQ.getBody());
+        }
+
+        message.setReconsumeTimes(((MessageExt) msgRMQ).getReconsumeTimes());
+        message.setBornTimestamp(((MessageExt) msgRMQ).getBornTimestamp());
+        message.setBornHost(String.valueOf(((MessageExt) msgRMQ).getBornHost()));
+
+        Map<String, String> properties = msgRMQ.getProperties();
+        if (properties != null) {
+            Iterator<Entry<String, String>> it = properties.entrySet().iterator();
+            while (it.hasNext()) {
+                Entry<String, String> next = it.next();
+                // System
+                if (RESERVED_KEY_SET_RMQ.contains(next.getKey()) || RESERVED_KEY_SET_ONS.contains(next.getKey())) {
+                    MessageAccessor.putSystemProperties(message, next.getKey(), next.getValue());
+                }
+                // User
+                else {
+                    message.putUserProperties(next.getKey(), next.getValue());
+                }
+            }
+        }
+
+        return message;
+    }
+
+    public static Properties extractProperties(final Properties properties) {
+        Properties newPro = new Properties();
+        Properties inner = null;
+        try {
+            Field field = Properties.class.getDeclaredField("defaults");
+            field.setAccessible(true);
+            inner = (Properties) field.get(properties);
+        } catch (Exception ignore) {
+        }
+
+        if (inner != null) {
+            for (final Entry<Object, Object> entry : inner.entrySet()) {
+                newPro.setProperty(String.valueOf(entry.getKey()), String.valueOf(entry.getValue()));
+            }
+        }
+
+        for (final Entry<Object, Object> entry : properties.entrySet()) {
+            newPro.setProperty(String.valueOf(entry.getKey()), String.valueOf(entry.getValue()));
+        }
+
+        return newPro;
+    }
+}
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/OnsClientRPCHook.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/OnsClientRPCHook.java
new file mode 100644
index 0000000..a145c25
--- /dev/null
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/OnsClientRPCHook.java
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.rocketmq;
+
+import org.apache.rocketmq.remoting.protocol.RemotingCommand;
+import org.apache.rocketmq.ons.api.impl.MQClientInfo;
+import org.apache.rocketmq.ons.api.impl.authority.SessionCredentials;
+
+public class OnsClientRPCHook extends ClientRPCHook {
+
+    public OnsClientRPCHook(SessionCredentials sessionCredentials) {
+        super(sessionCredentials);
+    }
+
+    @Override
+    public void doBeforeRequest(String remoteAddr, RemotingCommand request) {
+        super.doBeforeRequest(remoteAddr, request);
+        request.setVersion(MQClientInfo.versionCode);
+    }
+
+
+    @Override
+    public void doAfterResponse(String remoteAddr, RemotingCommand request, RemotingCommand response) {
+        super.doAfterResponse(remoteAddr, request, response);
+    }
+
+}
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/OrderConsumerImpl.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/OrderConsumerImpl.java
new file mode 100644
index 0000000..4004f3e
--- /dev/null
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/OrderConsumerImpl.java
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.rocketmq;
+
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext;
+import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
+import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
+import org.apache.rocketmq.common.UtilAll;
+import org.apache.rocketmq.common.message.MessageExt;
+
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.MessageSelector;
+import org.apache.rocketmq.ons.api.PropertyKeyConst;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+import org.apache.rocketmq.ons.api.order.ConsumeOrderContext;
+import org.apache.rocketmq.ons.api.order.MessageOrderListener;
+import org.apache.rocketmq.ons.api.order.OrderAction;
+import org.apache.rocketmq.ons.api.order.OrderConsumer;
+
+public class OrderConsumerImpl extends ONSConsumerAbstract implements OrderConsumer {
+    private final ConcurrentHashMap<String, MessageOrderListener> subscribeTable = new ConcurrentHashMap<String, MessageOrderListener>();
+
+    public OrderConsumerImpl(final Properties properties) {
+        super(properties);
+        String suspendTimeMillis = properties.getProperty(PropertyKeyConst.SuspendTimeMillis);
+        if (!UtilAll.isBlank(suspendTimeMillis)) {
+            try {
+                this.defaultMQPushConsumer.setSuspendCurrentQueueTimeMillis(Long.parseLong(suspendTimeMillis));
+            } catch (NumberFormatException ignored) {
+            }
+        }
+    }
+
+    @Override
+    public void start() {
+        this.defaultMQPushConsumer.registerMessageListener(new MessageListenerOrderlyImpl());
+        super.start();
+    }
+
+    @Override
+    public void subscribe(String topic, String subExpression, MessageOrderListener listener) {
+        if (null == topic) {
+            throw new ONSClientException("topic is null");
+        }
+
+        if (null == listener) {
+            throw new ONSClientException("listener is null");
+        }
+        this.subscribeTable.put(topic, listener);
+        super.subscribe(topic, subExpression);
+    }
+
+    @Override
+    public void subscribe(final String topic, final MessageSelector selector, final MessageOrderListener listener) {
+        if (null == topic) {
+            throw new ONSClientException("topic is null");
+        }
+
+        if (null == listener) {
+            throw new ONSClientException("listener is null");
+        }
+        this.subscribeTable.put(topic, listener);
+        super.subscribe(topic, selector);
+    }
+
+    class MessageListenerOrderlyImpl implements MessageListenerOrderly {
+
+        @Override
+        public ConsumeOrderlyStatus consumeMessage(List<MessageExt> arg0, ConsumeOrderlyContext arg1) {
+            MessageExt msgRMQ = arg0.get(0);
+            Message msg = ONSUtil.msgConvert(msgRMQ);
+            msg.setMsgID(msgRMQ.getMsgId());
+
+            MessageOrderListener listener = OrderConsumerImpl.this.subscribeTable.get(msg.getTopic());
+            if (null == listener) {
+                throw new ONSClientException("MessageOrderListener is null");
+            }
+
+            final ConsumeOrderContext context = new ConsumeOrderContext();
+            OrderAction action = listener.consume(msg, context);
+            if (action != null) {
+                switch (action) {
+                    case Success:
+                        return ConsumeOrderlyStatus.SUCCESS;
+                    case Suspend:
+                        return ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT;
+                    default:
+                        break;
+                }
+            }
+
+            return ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT;
+        }
+    }
+}
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/OrderProducerImpl.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/OrderProducerImpl.java
new file mode 100644
index 0000000..218a8c2
--- /dev/null
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/OrderProducerImpl.java
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.rocketmq;
+
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceConstants;
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceDispatcherType;
+import org.apache.rocketmq.ons.open.trace.core.dispatch.impl.AsyncArrayDispatcher;
+import org.apache.rocketmq.client.producer.DefaultMQProducer;
+import org.apache.rocketmq.common.UtilAll;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.logging.InternalLogger;
+
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.PropertyKeyConst;
+import org.apache.rocketmq.ons.api.SendResult;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+import org.apache.rocketmq.ons.api.impl.tracehook.OnsClientSendMessageHookImpl;
+import org.apache.rocketmq.ons.api.impl.util.ClientLoggerUtil;
+import org.apache.rocketmq.ons.api.order.OrderProducer;
+import org.apache.commons.lang3.StringUtils;
+
+public class OrderProducerImpl extends ONSClientAbstract implements OrderProducer {
+    private final static InternalLogger LOGGER = ClientLoggerUtil.getClientLogger();
+    private final DefaultMQProducer defaultMQProducer;
+
+    public OrderProducerImpl(final Properties properties) {
+        super(properties);
+        String producerGroup = properties.getProperty(PropertyKeyConst.GROUP_ID, properties.getProperty(PropertyKeyConst.ProducerId));
+        if (StringUtils.isEmpty(producerGroup)) {
+            producerGroup = "__ONS_PRODUCER_DEFAULT_GROUP";
+        }
+
+        this.defaultMQProducer =
+            new DefaultMQProducer(this.getNamespace(), producerGroup, new OnsClientRPCHook(sessionCredentials));
+
+
+        this.defaultMQProducer.setProducerGroup(producerGroup);
+
+        boolean isVipChannelEnabled = Boolean.parseBoolean(properties.getProperty(PropertyKeyConst.isVipChannelEnabled, "false"));
+        this.defaultMQProducer.setVipChannelEnabled(isVipChannelEnabled);
+
+        String sendMsgTimeoutMillis = properties.getProperty(PropertyKeyConst.SendMsgTimeoutMillis, "3000");
+        this.defaultMQProducer.setSendMsgTimeout(Integer.parseInt(sendMsgTimeoutMillis));
+
+//        boolean addExtendUniqInfo = Boolean.parseBoolean(properties.getProperty(PropertyKeyConst.EXACTLYONCE_DELIVERY, "false"));
+//        this.defaultMQProducer.setAddExtendUniqInfo(addExtendUniqInfo);
+
+        String instanceName = properties.getProperty(PropertyKeyConst.InstanceName, this.buildIntanceName());
+        this.defaultMQProducer.setInstanceName(instanceName);
+        this.defaultMQProducer.setNamesrvAddr(this.getNameServerAddr());
+        String msgTraceSwitch = properties.getProperty(PropertyKeyConst.MsgTraceSwitch);
+        if (!UtilAll.isBlank(msgTraceSwitch) && (!Boolean.parseBoolean(msgTraceSwitch))) {
+            LOGGER.info("MQ Client Disable the Trace Hook!");
+        } else {
+            try {
+                Properties tempProperties = new Properties();
+                tempProperties.put(OnsTraceConstants.AccessKey, sessionCredentials.getAccessKey());
+                tempProperties.put(OnsTraceConstants.SecretKey, sessionCredentials.getSecretKey());
+                tempProperties.put(OnsTraceConstants.MaxMsgSize, "128000");
+                tempProperties.put(OnsTraceConstants.AsyncBufferSize, "2048");
+                tempProperties.put(OnsTraceConstants.MaxBatchNum, "100");
+                tempProperties.put(OnsTraceConstants.NAMESRV_ADDR, this.getNameServerAddr());
+                tempProperties.put(OnsTraceConstants.InstanceName, "PID_CLIENT_INNER_TRACE_PRODUCER");
+                tempProperties.put(OnsTraceConstants.TraceDispatcherType, OnsTraceDispatcherType.PRODUCER.name());
+                AsyncArrayDispatcher dispatcher = new AsyncArrayDispatcher(tempProperties, sessionCredentials);
+                dispatcher.setHostProducer(defaultMQProducer.getDefaultMQProducerImpl());
+                traceDispatcher = dispatcher;
+                this.defaultMQProducer.getDefaultMQProducerImpl().registerSendMessageHook(
+                    new OnsClientSendMessageHookImpl(traceDispatcher));
+            } catch (Throwable e) {
+                LOGGER.error("system mqtrace hook init failed ,maybe can't send msg trace data", e);
+            }
+        }
+    }
+
+    @Override
+    protected void updateNameServerAddr(String newAddrs) {
+        this.defaultMQProducer.getDefaultMQProducerImpl().getmQClientFactory().getMQClientAPIImpl().updateNameServerAddressList(newAddrs);
+    }
+
+    @Override
+    public void start() {
+        try {
+            if (started.compareAndSet(false, true)) {
+                this.defaultMQProducer.start();
+                super.start();
+            }
+        } catch (Exception e) {
+            throw new ONSClientException(e.getMessage());
+        }
+    }
+
+    @Override
+    public void shutdown() {
+        if (started.compareAndSet(true, false)) {
+            this.defaultMQProducer.shutdown();
+        }
+        super.shutdown();
+    }
+
+    @Override
+    public SendResult send(final Message message, final String shardingKey) {
+        if (UtilAll.isBlank(shardingKey)) {
+            throw new ONSClientException("\'shardingKey\' is blank.");
+        }
+        message.setShardingKey(shardingKey);
+        this.checkONSProducerServiceState(this.defaultMQProducer.getDefaultMQProducerImpl());
+        final org.apache.rocketmq.common.message.Message msgRMQ = ONSUtil.msgConvert(message);
+        try {
+            org.apache.rocketmq.client.producer.SendResult sendResultRMQ =
+                this.defaultMQProducer.send(msgRMQ, new org.apache.rocketmq.client.producer.MessageQueueSelector() {
+                    @Override
+                    public MessageQueue select(List<MessageQueue> mqs, org.apache.rocketmq.common.message.Message msg,
+                        Object shardingKey) {
+                        int select = Math.abs(shardingKey.hashCode());
+                        if (select < 0) {
+                            select = 0;
+                        }
+                        return mqs.get(select % mqs.size());
+                    }
+                }, shardingKey);
+            message.setMsgID(sendResultRMQ.getMsgId());
+            SendResult sendResult = new SendResult();
+            sendResult.setTopic(message.getTopic());
+            sendResult.setMessageId(sendResultRMQ.getMsgId());
+            return sendResult;
+        } catch (Exception e) {
+            throw new ONSClientException("defaultMQProducer send order exception", e);
+        }
+    }
+}
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java
new file mode 100644
index 0000000..bd1dede
--- /dev/null
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java
@@ -0,0 +1,246 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.rocketmq;
+
+import java.util.Properties;
+import java.util.concurrent.ExecutorService;
+
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceConstants;
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceDispatcherType;
+import org.apache.rocketmq.ons.open.trace.core.dispatch.impl.AsyncArrayDispatcher;
+import org.apache.rocketmq.client.exception.MQBrokerException;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.client.producer.DefaultMQProducer;
+import org.apache.rocketmq.common.UtilAll;
+import org.apache.rocketmq.common.message.MessageClientIDSetter;
+import org.apache.rocketmq.common.protocol.ResponseCode;
+import org.apache.rocketmq.logging.InternalLogger;
+import org.apache.rocketmq.remoting.exception.RemotingConnectException;
+import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
+
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.OnExceptionContext;
+import org.apache.rocketmq.ons.api.Producer;
+import org.apache.rocketmq.ons.api.PropertyKeyConst;
+import org.apache.rocketmq.ons.api.SendCallback;
+import org.apache.rocketmq.ons.api.SendResult;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+import org.apache.rocketmq.ons.api.impl.tracehook.OnsClientSendMessageHookImpl;
+import org.apache.rocketmq.ons.api.impl.util.ClientLoggerUtil;
+import org.apache.commons.lang3.StringUtils;
+
+public class ProducerImpl extends ONSClientAbstract implements Producer {
+    private final static InternalLogger LOGGER = ClientLoggerUtil.getClientLogger();
+    private final DefaultMQProducer defaultMQProducer;
+
+    public ProducerImpl(final Properties properties) {
+        super(properties);
+
+        String producerGroup = properties.getProperty(PropertyKeyConst.GROUP_ID, properties.getProperty(PropertyKeyConst.ProducerId));
+        if (StringUtils.isEmpty(producerGroup)) {
+            producerGroup = "__ONS_PRODUCER_DEFAULT_GROUP";
+        }
+
+        this.defaultMQProducer =
+            new DefaultMQProducer(this.getNamespace(), producerGroup, new OnsClientRPCHook(sessionCredentials));
+
+        this.defaultMQProducer.setProducerGroup(producerGroup);
+
+        boolean isVipChannelEnabled = Boolean.parseBoolean(properties.getProperty(PropertyKeyConst.isVipChannelEnabled, "false"));
+        this.defaultMQProducer.setVipChannelEnabled(isVipChannelEnabled);
+
+        if (properties.containsKey(PropertyKeyConst.SendMsgTimeoutMillis)) {
+            this.defaultMQProducer.setSendMsgTimeout(Integer.valueOf(properties.get(PropertyKeyConst.SendMsgTimeoutMillis).toString()));
+        } else {
+            this.defaultMQProducer.setSendMsgTimeout(5000);
+        }
+
+//        if (properties.containsKey(PropertyKeyConst.EXACTLYONCE_DELIVERY)) {
+//            this.defaultMQProducer.setAddExtendUniqInfo(Boolean.valueOf(properties.get(PropertyKeyConst.EXACTLYONCE_DELIVERY).toString()));
+//        }
+
+        String instanceName = properties.getProperty(PropertyKeyConst.InstanceName, this.buildIntanceName());
+        this.defaultMQProducer.setInstanceName(instanceName);
+        this.defaultMQProducer.setNamesrvAddr(this.getNameServerAddr());
+        this.defaultMQProducer.setMaxMessageSize(1024 * 1024 * 4);
+        String msgTraceSwitch = properties.getProperty(PropertyKeyConst.MsgTraceSwitch);
+        if (!UtilAll.isBlank(msgTraceSwitch) && (!Boolean.parseBoolean(msgTraceSwitch))) {
+            LOGGER.info("MQ Client Disable the Trace Hook!");
+        } else {
+            try {
+                Properties tempProperties = new Properties();
+                tempProperties.put(OnsTraceConstants.AccessKey, sessionCredentials.getAccessKey());
+                tempProperties.put(OnsTraceConstants.SecretKey, sessionCredentials.getSecretKey());
+                tempProperties.put(OnsTraceConstants.MaxMsgSize, "128000");
+                tempProperties.put(OnsTraceConstants.AsyncBufferSize, "2048");
+                tempProperties.put(OnsTraceConstants.MaxBatchNum, "100");
+                tempProperties.put(OnsTraceConstants.NAMESRV_ADDR, this.getNameServerAddr());
+                tempProperties.put(OnsTraceConstants.InstanceName, "PID_CLIENT_INNER_TRACE_PRODUCER");
+                tempProperties.put(OnsTraceConstants.TraceDispatcherType, OnsTraceDispatcherType.PRODUCER.name());
+                AsyncArrayDispatcher dispatcher = new AsyncArrayDispatcher(tempProperties, sessionCredentials);
+                dispatcher.setHostProducer(defaultMQProducer.getDefaultMQProducerImpl());
+                traceDispatcher = dispatcher;
+                this.defaultMQProducer.getDefaultMQProducerImpl().registerSendMessageHook(
+                    new OnsClientSendMessageHookImpl(traceDispatcher));
+            } catch (Throwable e) {
+                LOGGER.error("system mqtrace hook init failed ,maybe can't send msg trace data.", e);
+            }
+        }
+    }
+
+    @Override
+    protected void updateNameServerAddr(String newAddrs) {
+        this.defaultMQProducer.getDefaultMQProducerImpl().getmQClientFactory().getMQClientAPIImpl().updateNameServerAddressList(newAddrs);
+    }
+
+    @Override
+    public void start() {
+        try {
+            if (this.started.compareAndSet(false, true)) {
+                this.defaultMQProducer.start();
+                super.start();
+            }
+        } catch (Exception e) {
+            throw new ONSClientException(e.getMessage());
+        }
+    }
+
+    @Override
+    public void shutdown() {
+        if (this.started.compareAndSet(true, false)) {
+            this.defaultMQProducer.shutdown();
+        }
+        super.shutdown();
+    }
+
+    @Override
+    public SendResult send(Message message) {
+        this.checkONSProducerServiceState(this.defaultMQProducer.getDefaultMQProducerImpl());
+        org.apache.rocketmq.common.message.Message msgRMQ = ONSUtil.msgConvert(message);
+
+        try {
+            org.apache.rocketmq.client.producer.SendResult sendResultRMQ = this.defaultMQProducer.send(msgRMQ);
+
+            message.setMsgID(sendResultRMQ.getMsgId());
+            SendResult sendResult = new SendResult();
+            sendResult.setTopic(sendResultRMQ.getMessageQueue().getTopic());
+            sendResult.setMessageId(sendResultRMQ.getMsgId());
+            return sendResult;
+        } catch (Exception e) {
+            LOGGER.error(String.format("Send message Exception, %s", message), e);
+            throw checkProducerException(message.getTopic(), message.getMsgID(), e);
+        }
+    }
+
+    @Override
+    public void sendOneway(Message message) {
+        this.checkONSProducerServiceState(this.defaultMQProducer.getDefaultMQProducerImpl());
+        org.apache.rocketmq.common.message.Message msgRMQ = ONSUtil.msgConvert(message);
+        try {
+            this.defaultMQProducer.sendOneway(msgRMQ);
+            message.setMsgID(MessageClientIDSetter.getUniqID(msgRMQ));
+        } catch (Exception e) {
+            LOGGER.error(String.format("Send message oneway Exception, %s", message), e);
+            throw checkProducerException(message.getTopic(), message.getMsgID(), e);
+        }
+    }
+
+    @Override
+    public void sendAsync(Message message, SendCallback sendCallback) {
+        this.checkONSProducerServiceState(this.defaultMQProducer.getDefaultMQProducerImpl());
+        org.apache.rocketmq.common.message.Message msgRMQ = ONSUtil.msgConvert(message);
+        try {
+            this.defaultMQProducer.send(msgRMQ, sendCallbackConvert(message, sendCallback));
+            message.setMsgID(MessageClientIDSetter.getUniqID(msgRMQ));
+        } catch (Exception e) {
+            LOGGER.error(String.format("Send message async Exception, %s", message), e);
+            throw checkProducerException(message.getTopic(), message.getMsgID(), e);
+        }
+    }
+
+    @Override
+    public void setCallbackExecutor(final ExecutorService callbackExecutor) {
+        this.defaultMQProducer.setCallbackExecutor(callbackExecutor);
+    }
+
+    public DefaultMQProducer getDefaultMQProducer() {
+        return defaultMQProducer;
+    }
+
+    private org.apache.rocketmq.client.producer.SendCallback sendCallbackConvert(final Message message,
+        final SendCallback sendCallback) {
+        org.apache.rocketmq.client.producer.SendCallback rmqSendCallback = new org.apache.rocketmq.client.producer.SendCallback() {
+            @Override
+            public void onSuccess(org.apache.rocketmq.client.producer.SendResult sendResult) {
+                sendCallback.onSuccess(sendResultConvert(sendResult));
+            }
+
+            @Override
+            public void onException(Throwable e) {
+                String topic = new String(message.getTopic());
+                String msgId = new String(message.getMsgID());
+                ONSClientException onsEx = checkProducerException(topic, msgId, e);
+                OnExceptionContext context = new OnExceptionContext();
+                context.setTopic(topic);
+                context.setMessageId(msgId);
+                context.setException(onsEx);
+                sendCallback.onException(context);
+            }
+        };
+        return rmqSendCallback;
+    }
+
+    private SendResult sendResultConvert(
+        final org.apache.rocketmq.client.producer.SendResult rmqSendResult) {
+        SendResult sendResult = new SendResult();
+        sendResult.setTopic(rmqSendResult.getMessageQueue().getTopic());
+        sendResult.setMessageId(rmqSendResult.getMsgId());
+        return sendResult;
+    }
+
+    private ONSClientException checkProducerException(String topic, String msgId, Throwable e) {
+        if (e instanceof MQClientException) {
+            if (e.getCause() != null) {
+                if (e.getCause() instanceof RemotingConnectException) {
+                    return new ONSClientException(
+                        FAQ.errorMessage(String.format("Connect broker failed, Topic=%s, msgId=%s", topic, msgId), FAQ.CONNECT_BROKER_FAILED));
+                } else if (e.getCause() instanceof RemotingTimeoutException) {
+                    return new ONSClientException(FAQ.errorMessage(String.format("Send message to broker timeout, %dms, Topic=%s, msgId=%s",
+                        this.defaultMQProducer.getSendMsgTimeout(), topic, msgId), FAQ.SEND_MSG_TO_BROKER_TIMEOUT));
+                } else if (e.getCause() instanceof MQBrokerException) {
+                    MQBrokerException excep = (MQBrokerException) e.getCause();
+                    return new ONSClientException(FAQ.errorMessage(
+                        String.format("Receive a broker exception, Topi=%s, msgId=%s, %s", topic, msgId, excep.getErrorMessage()),
+                        FAQ.BROKER_RESPONSE_EXCEPTION));
+                }
+            } else {
+                MQClientException excep = (MQClientException) e;
+                if (-1 == excep.getResponseCode()) {
+                    return new ONSClientException(
+                        FAQ.errorMessage(String.format("Topic does not exist, Topic=%s, msgId=%s", topic, msgId), FAQ.TOPIC_ROUTE_NOT_EXIST));
+                } else if (ResponseCode.MESSAGE_ILLEGAL == excep.getResponseCode()) {
+                    return new ONSClientException(
+                        FAQ.errorMessage(String.format("ONS Client check message exception, Topic=%s, msgId=%s", topic, msgId),
+                            FAQ.CLIENT_CHECK_MSG_EXCEPTION));
+                }
+            }
+        }
+
+        return new ONSClientException("defaultMQProducer send exception", e);
+    }
+}
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/TransactionProducerImpl.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/TransactionProducerImpl.java
new file mode 100644
index 0000000..bc03867
--- /dev/null
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/TransactionProducerImpl.java
@@ -0,0 +1,155 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.rocketmq;
+
+import java.util.Properties;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.client.producer.LocalTransactionState;
+import org.apache.rocketmq.client.producer.TransactionCheckListener;
+import org.apache.rocketmq.client.producer.TransactionMQProducer;
+import org.apache.rocketmq.common.UtilAll;
+import org.apache.rocketmq.logging.InternalLogger;
+import org.apache.rocketmq.ons.api.Constants;
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.PropertyKeyConst;
+import org.apache.rocketmq.ons.api.SendResult;
+import org.apache.rocketmq.ons.api.impl.tracehook.OnsClientSendMessageHookImpl;
+import org.apache.rocketmq.ons.api.impl.util.ClientLoggerUtil;
+import org.apache.rocketmq.ons.api.transaction.LocalTransactionExecuter;
+import org.apache.rocketmq.ons.api.transaction.TransactionProducer;
+import org.apache.rocketmq.ons.api.transaction.TransactionStatus;
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceConstants;
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceDispatcherType;
+import org.apache.rocketmq.ons.open.trace.core.dispatch.impl.AsyncArrayDispatcher;
+
+public class TransactionProducerImpl extends ONSClientAbstract implements TransactionProducer {
+    private final static InternalLogger LOGGER = ClientLoggerUtil.getClientLogger();
+    TransactionMQProducer transactionMQProducer = null;
+    private Properties properties;
+
+    public TransactionProducerImpl(Properties properties, TransactionCheckListener transactionCheckListener) {
+        super(properties);
+        this.properties = properties;
+        String producerGroup = properties.getProperty(PropertyKeyConst.GROUP_ID, properties.getProperty(PropertyKeyConst.ProducerId));
+        if (StringUtils.isEmpty(producerGroup)) {
+            producerGroup = "__ONS_PRODUCER_DEFAULT_GROUP";
+        }
+        transactionMQProducer =
+            new TransactionMQProducer(this.getNamespace(), producerGroup, new OnsClientRPCHook(sessionCredentials));
+
+        boolean isVipChannelEnabled = Boolean.parseBoolean(properties.getProperty(PropertyKeyConst.isVipChannelEnabled, "false"));
+        transactionMQProducer.setVipChannelEnabled(isVipChannelEnabled);
+
+        String instanceName = properties.getProperty(PropertyKeyConst.InstanceName, this.buildIntanceName());
+        this.transactionMQProducer.setInstanceName(instanceName);
+
+//        boolean addExtendUniqInfo = Boolean.parseBoolean(properties.getProperty(PropertyKeyConst.EXACTLYONCE_DELIVERY, "false"));
+//        transactionMQProducer.setAddExtendUniqInfo(addExtendUniqInfo);
+
+        transactionMQProducer.setTransactionCheckListener(transactionCheckListener);
+        String msgTraceSwitch = properties.getProperty(PropertyKeyConst.MsgTraceSwitch);
+        if (!UtilAll.isBlank(msgTraceSwitch) && (!Boolean.parseBoolean(msgTraceSwitch))) {
+            LOGGER.info("MQ Client Disable the Trace Hook!");
+        } else {
+            try {
+                Properties tempProperties = new Properties();
+                tempProperties.put(OnsTraceConstants.AccessKey, sessionCredentials.getAccessKey());
+                tempProperties.put(OnsTraceConstants.SecretKey, sessionCredentials.getSecretKey());
+                tempProperties.put(OnsTraceConstants.MaxMsgSize, "128000");
+                tempProperties.put(OnsTraceConstants.AsyncBufferSize, "2048");
+                tempProperties.put(OnsTraceConstants.MaxBatchNum, "100");
+                tempProperties.put(OnsTraceConstants.NAMESRV_ADDR, this.getNameServerAddr());
+                tempProperties.put(OnsTraceConstants.InstanceName, "PID_CLIENT_INNER_TRACE_PRODUCER");
+                tempProperties.put(OnsTraceConstants.TraceDispatcherType, OnsTraceDispatcherType.PRODUCER.name());
+                AsyncArrayDispatcher dispatcher = new AsyncArrayDispatcher(tempProperties, sessionCredentials);
+                dispatcher.setHostProducer(transactionMQProducer.getDefaultMQProducerImpl());
+                traceDispatcher = dispatcher;
+                this.transactionMQProducer.getDefaultMQProducerImpl().registerSendMessageHook(
+                    new OnsClientSendMessageHookImpl(traceDispatcher));
+            } catch (Throwable e) {
+                LOGGER.error("system mqtrace hook init failed ,maybe can't send msg trace data", e);
+            }
+        }
+    }
+
+    @Override
+    public void start() {
+        if (started.compareAndSet(false, true)) {
+            if (transactionMQProducer.getTransactionCheckListener() == null) {
+                throw new IllegalArgumentException("TransactionCheckListener is null");
+            }
+            transactionMQProducer.setNamesrvAddr(this.nameServerAddr);
+            try {
+                transactionMQProducer.start();
+                super.start();
+            } catch (MQClientException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    @Override
+    protected void updateNameServerAddr(String newAddrs) {
+        this.transactionMQProducer.getDefaultMQProducerImpl().getmQClientFactory().getMQClientAPIImpl().updateNameServerAddressList(newAddrs);
+    }
+
+    @Override
+    public void shutdown() {
+        if (started.compareAndSet(true, false)) {
+            transactionMQProducer.shutdown();
+        }
+        super.shutdown();
+    }
+
+    @Override
+    public SendResult send(final Message message, final LocalTransactionExecuter executer, Object arg) {
+        this.checkONSProducerServiceState(this.transactionMQProducer.getDefaultMQProducerImpl());
+        org.apache.rocketmq.common.message.Message msgRMQ = ONSUtil.msgConvert(message);
+        org.apache.rocketmq.client.producer.TransactionSendResult sendResultRMQ = null;
+        try {
+            sendResultRMQ = transactionMQProducer.sendMessageInTransaction(msgRMQ,
+                new org.apache.rocketmq.client.producer.LocalTransactionExecuter() {
+                    @Override
+                    public LocalTransactionState executeLocalTransactionBranch(
+                        org.apache.rocketmq.common.message.Message msg,
+                        Object arg) {
+                        String msgId = msg.getProperty(Constants.TRANSACTION_ID);
+                        message.setMsgID(msgId);
+                        TransactionStatus transactionStatus = executer.execute(message, arg);
+                        if (TransactionStatus.CommitTransaction == transactionStatus) {
+                            return LocalTransactionState.COMMIT_MESSAGE;
+                        } else if (TransactionStatus.RollbackTransaction == transactionStatus) {
+                            return LocalTransactionState.ROLLBACK_MESSAGE;
+                        }
+                        return LocalTransactionState.UNKNOW;
+                    }
+                }, arg);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        if (sendResultRMQ.getLocalTransactionState() == LocalTransactionState.ROLLBACK_MESSAGE) {
+            throw new RuntimeException("local transaction branch failed ,so transaction rollback");
+        }
+        SendResult sendResult = new SendResult();
+        sendResult.setMessageId(sendResultRMQ.getMsgId());
+        sendResult.setTopic(sendResultRMQ.getMessageQueue().getTopic());
+        return sendResult;
+    }
+
+}
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/tracehook/OnsClientSendMessageHookImpl.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/tracehook/OnsClientSendMessageHookImpl.java
new file mode 100644
index 0000000..c6fbe10
--- /dev/null
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/tracehook/OnsClientSendMessageHookImpl.java
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api.impl.tracehook;
+
+import java.util.ArrayList;
+
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceBean;
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceConstants;
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceContext;
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceType;
+import org.apache.rocketmq.ons.open.trace.core.dispatch.AsyncDispatcher;
+import org.apache.rocketmq.client.hook.SendMessageContext;
+import org.apache.rocketmq.client.hook.SendMessageHook;
+import org.apache.rocketmq.client.producer.SendStatus;
+import org.apache.rocketmq.common.MixAll;
+import org.apache.rocketmq.common.protocol.NamespaceUtil;
+
+public class OnsClientSendMessageHookImpl implements SendMessageHook {
+
+    private AsyncDispatcher localDispatcher;
+
+    public OnsClientSendMessageHookImpl(AsyncDispatcher localDispatcher) {
+        this.localDispatcher = localDispatcher;
+    }
+
+    @Override
+    public String hookName() {
+        return "OnsClientSendMessageHook";
+    }
+
+    @Override
+    public void sendMessageBefore(SendMessageContext context) {
+
+        if (context == null || context.getMessage().getTopic().startsWith(MixAll.SYSTEM_TOPIC_PREFIX)) {
+            return;
+        }
+        OnsTraceContext onsContext = new OnsTraceContext();
+        onsContext.setTraceBeans(new ArrayList<OnsTraceBean>(1));
+        context.setMqTraceContext(onsContext);
+        onsContext.setTraceType(OnsTraceType.Pub);
+        String userGroup = NamespaceUtil.withoutNamespace(context.getProducerGroup(), context.getNamespace());
+        onsContext.setGroupName(userGroup);
+        OnsTraceBean traceBean = new OnsTraceBean();
+        String userTopic = NamespaceUtil.withoutNamespace(context.getMessage().getTopic(), context.getNamespace());
+        traceBean.setTopic(userTopic);
+        traceBean.setTags(context.getMessage().getTags());
+        traceBean.setKeys(context.getMessage().getKeys());
+        traceBean.setStoreHost(context.getBrokerAddr());
+        traceBean.setBodyLength(context.getMessage().getBody().length);
+        traceBean.setMsgType(context.getMsgType());
+        onsContext.getTraceBeans().add(traceBean);
+    }
+
+    @Override
+    public void sendMessageAfter(SendMessageContext context) {
+
+        if (context == null || context.getMessage().getTopic().startsWith(OnsTraceConstants.traceTopic) || context.getMqTraceContext() == null) {
+            return;
+        }
+        if (context.getSendResult() == null) {
+            return;
+        }
+        if (context.getSendResult().getRegionId() == null
+            || context.getSendResult().getRegionId().equals(OnsTraceConstants.default_region)
+            || !context.getSendResult().isTraceOn()) {
+            // if regionId is default or switch is false,skip it
+            return;
+        }
+        OnsTraceContext onsContext = (OnsTraceContext) context.getMqTraceContext();
+        OnsTraceBean traceBean = onsContext.getTraceBeans().get(0);
+        int costTime = (int) ((System.currentTimeMillis() - onsContext.getTimeStamp()) / onsContext.getTraceBeans().size());
+        onsContext.setCostTime(costTime);
+        if (context.getSendResult().getSendStatus().equals(SendStatus.SEND_OK)) {
+            onsContext.setSuccess(true);
+        } else {
+            onsContext.setSuccess(false);
+        }
+        onsContext.setRegionId(context.getSendResult().getRegionId());
+        traceBean.setMsgId(context.getSendResult().getMsgId());
+        traceBean.setOffsetMsgId(context.getSendResult().getOffsetMsgId());
+        traceBean.setStoreTime(onsContext.getTimeStamp() + costTime / 2);
+        localDispatcher.append(onsContext);
+    }
+}
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/tracehook/OnsConsumeMessageHookImpl.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/tracehook/OnsConsumeMessageHookImpl.java
new file mode 100644
index 0000000..d5a0782
--- /dev/null
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/tracehook/OnsConsumeMessageHookImpl.java
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.tracehook;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.rocketmq.client.consumer.listener.ConsumeReturnType;
+import org.apache.rocketmq.client.hook.ConsumeMessageContext;
+import org.apache.rocketmq.client.hook.ConsumeMessageHook;
+import org.apache.rocketmq.common.MixAll;
+import org.apache.rocketmq.common.message.MessageConst;
+import org.apache.rocketmq.common.message.MessageExt;
+import org.apache.rocketmq.common.protocol.NamespaceUtil;
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceBean;
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceConstants;
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceContext;
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceType;
+import org.apache.rocketmq.ons.open.trace.core.dispatch.AsyncDispatcher;
+
+public class OnsConsumeMessageHookImpl implements ConsumeMessageHook {
+
+    private AsyncDispatcher localDispatcher;
+
+    public OnsConsumeMessageHookImpl(AsyncDispatcher localDispatcher) {
+        this.localDispatcher = localDispatcher;
+    }
+
+    @Override
+    public String hookName() {
+        return "OnsConsumeMessageHook";
+    }
+
+    @Override
+    public void consumeMessageBefore(ConsumeMessageContext context) {
+        if (context == null || context.getMsgList() == null || context.getMsgList().isEmpty()) {
+            return;
+        }
+        OnsTraceContext onsTraceContext = new OnsTraceContext();
+        context.setMqTraceContext(onsTraceContext);
+        onsTraceContext.setTraceType(OnsTraceType.SubBefore);
+        String userGroup = NamespaceUtil.withoutNamespace(context.getConsumerGroup(), context.getNamespace());
+        onsTraceContext.setGroupName(userGroup);
+        List<OnsTraceBean> beans = new ArrayList<OnsTraceBean>();
+        for (MessageExt msg : context.getMsgList()) {
+            if (msg == null) {
+                continue;
+            }
+            String regionId = msg.getProperty(MessageConst.PROPERTY_MSG_REGION);
+            String traceOn = msg.getProperty(MessageConst.PROPERTY_TRACE_SWITCH);
+            if (regionId == null || regionId.equals(OnsTraceConstants.default_region)) {
+                // if regionId is default ,skip it
+                continue;
+            }
+            if (traceOn != null && "false".equals(traceOn)) {
+                // if trace switch is false ,skip it
+                continue;
+            }
+            OnsTraceBean traceBean = new OnsTraceBean();
+
+            String userTopic = NamespaceUtil.withoutNamespace(msg.getTopic(), context.getNamespace());
+            traceBean.setTopic(userTopic);
+            traceBean.setMsgId(msg.getMsgId());
+            traceBean.setTags(msg.getTags());
+            traceBean.setKeys(msg.getKeys());
+            traceBean.setStoreTime(msg.getStoreTimestamp());
+            traceBean.setBodyLength(msg.getStoreSize());
+            traceBean.setRetryTimes(msg.getReconsumeTimes());
+            onsTraceContext.setRegionId(regionId);
+            beans.add(traceBean);
+        }
+        if (beans.size() > 0) {
+            onsTraceContext.setTraceBeans(beans);
+            onsTraceContext.setTimeStamp(System.currentTimeMillis());
+            localDispatcher.append(onsTraceContext);
+        }
+    }
+
+    @Override
+    public void consumeMessageAfter(ConsumeMessageContext context) {
+        if (context == null || context.getMsgList() == null || context.getMsgList().isEmpty()) {
+            return;
+        }
+        OnsTraceContext subBeforeContext = (OnsTraceContext) context.getMqTraceContext();
+        if (subBeforeContext.getRegionId().equals(OnsTraceConstants.default_region)) {
+            // if regionId is default ,skip it
+            return;
+        }
+        if (subBeforeContext.getTraceBeans() == null || subBeforeContext.getTraceBeans().size() < 1) {
+            // if subbefore bean is null ,skip it
+            return;
+        }
+        OnsTraceContext subAfterContext = new OnsTraceContext();
+        subAfterContext.setTraceType(OnsTraceType.SubAfter);
+        subAfterContext.setRegionId(subBeforeContext.getRegionId());
+        subAfterContext.setGroupName(subBeforeContext.getGroupName());
+        subAfterContext.setRequestId(subBeforeContext.getRequestId());
+        subAfterContext.setSuccess(context.isSuccess());
+
+        int costTime = (int) ((System.currentTimeMillis() - subBeforeContext.getTimeStamp()) / context.getMsgList().size());
+        subAfterContext.setCostTime(costTime);//
+        subAfterContext.setTraceBeans(subBeforeContext.getTraceBeans());
+        String contextType = context.getProps().get(MixAll.CONSUME_CONTEXT_TYPE);
+        if (contextType != null) {
+            subAfterContext.setContextCode(ConsumeReturnType.valueOf(contextType).ordinal());
+        }
+        localDispatcher.append(subAfterContext);
+    }
+}
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/util/ClientLoggerUtil.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/util/ClientLoggerUtil.java
new file mode 100644
index 0000000..a7e8391
--- /dev/null
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/util/ClientLoggerUtil.java
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+package org.apache.rocketmq.ons.api.impl.util;
+
+import java.util.Arrays;
+
+import org.apache.rocketmq.client.log.ClientLogger;
+import org.apache.rocketmq.logging.InternalLogger;
+
+public class ClientLoggerUtil {
+    private static final String CLIENT_LOG_ROOT = "ons.client.logRoot";
+    private static final String CLIENT_LOG_FILEMAXINDEX = "ons.client.logFileMaxIndex";
+    private static final int CLIENT_LOG_FILE_MAX_INDEX = 100;
+    private static final String CLIENT_LOG_LEVEL = "ons.client.logLevel";
+    private static final String[] LEVEL_ARRAY = {"ERROR", "WARN", "INFO", "DEBUG"};
+    private static final long CLIENT_LOG_FILESIZE = 64 * 1024 * 1024L;
+
+    public static InternalLogger getClientLogger() {
+        //Make sure
+        String onsClientLogRoot = System.getProperty(CLIENT_LOG_ROOT, System.getProperty("user.home") + "/logs");
+        System.setProperty(ClientLogger.CLIENT_LOG_ROOT, onsClientLogRoot);
+        String onsClientLogLevel = System.getProperty(CLIENT_LOG_LEVEL, "INFO").trim().toUpperCase();
+        if (!Arrays.asList(LEVEL_ARRAY).contains(onsClientLogLevel)) {
+            onsClientLogLevel = "INFO";
+        }
+        System.setProperty(ClientLogger.CLIENT_LOG_LEVEL, onsClientLogLevel);
+        String onsClientLogMaxIndex = System.getProperty(CLIENT_LOG_FILEMAXINDEX, "10").trim();
+        try {
+            int maxIndex = Integer.parseInt(onsClientLogMaxIndex);
+            if (maxIndex <= 0 || maxIndex > CLIENT_LOG_FILE_MAX_INDEX) {
+                throw new NumberFormatException();
+            }
+        } catch (NumberFormatException e) {
+            onsClientLogMaxIndex = "10";
+        }
+        System.setProperty(ClientLogger.CLIENT_LOG_MAXINDEX, onsClientLogMaxIndex);
+        System.setProperty(ClientLogger.CLIENT_LOG_FILENAME, "ons.log");
+        System.setProperty(ClientLogger.CLIENT_LOG_FILESIZE, String.valueOf(CLIENT_LOG_FILESIZE));
+        return ClientLogger.getLog();
+    }
+}
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/util/MsgConvertUtil.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/util/MsgConvertUtil.java
new file mode 100644
index 0000000..19d7792
--- /dev/null
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/util/MsgConvertUtil.java
@@ -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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+public class MsgConvertUtil {
+
+    public static final byte[] EMPTY_BYTES = new byte[0];
+    public static final String EMPTY_STRING = "";
+
+    public static final String JMS_MSGMODEL = "jmsMsgModel";
+    /**
+     * To adapt this scene: "Notify client try to receive ObjectMessage sent by JMS client"
+     * Set notify out message model, value can be textMessage OR objectMessage
+     */
+    public static final String COMPATIBLE_FIELD_MSGMODEL = "notifyOutMsgModel";
+
+    public static final String MSGMODEL_TEXT = "textMessage";
+    public static final String MSGMODEL_BYTES = "bytesMessage";
+    public static final String MSGMODEL_OBJ = "objectMessage";
+
+    public static final String MSG_TOPIC = "msgTopic";
+    public static final String MSG_TYPE = "msgType";
+
+
+    public static byte[] objectSerialize(Object object) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+        oos.writeObject(object);
+        oos.close();
+        baos.close();
+        return baos.toByteArray();
+    }
+
+    public static Serializable objectDeserialize(byte[] bytes) throws IOException, ClassNotFoundException {
+        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        ObjectInputStream ois = new ObjectInputStream(bais);
+        ois.close();
+        bais.close();
+        return (Serializable) ois.readObject();
+    }
+
+    public static final byte[] string2Bytes(String s, String charset) {
+        if (null == s) {
+            return EMPTY_BYTES;
+        }
+        byte[] bs = null;
+        try {
+            bs = s.getBytes(charset);
+        } catch (Exception e) {
+            // ignore
+        }
+        return bs;
+    }
+
+    public static final String bytes2String(byte[] bs, String charset) {
+        if (null == bs) {
+            return EMPTY_STRING;
+        }
+        String s = null;
+        try {
+            s = new String(bs, charset);
+        } catch (Exception e) {
+            // ignore
+        }
+        return s;
+    }
+}
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/util/NameAddrUtils.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/util/NameAddrUtils.java
new file mode 100644
index 0000000..a652d85
--- /dev/null
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/util/NameAddrUtils.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.rocketmq.ons.api.impl.util;
+
+import java.util.regex.Pattern;
+
+import org.apache.rocketmq.common.MixAll;
+
+import org.apache.commons.lang3.StringUtils;
+
+public class NameAddrUtils {
+    public static final String INSTANCE_PREFIX = "MQ_INST_";
+    public static final String INSTANCE_REGEX = INSTANCE_PREFIX + "\\w+_\\w+";
+    public static final String ENDPOINT_PREFIX = "http://";
+    public static final Pattern NAMESRV_ENDPOINT_PATTERN = Pattern.compile("^" + ENDPOINT_PREFIX + ".*");
+    public static final Pattern INST_ENDPOINT_PATTERN = Pattern.compile("^" + ENDPOINT_PREFIX + INSTANCE_REGEX + "\\..*");
+
+    public static String getNameAdd() {
+        return System.getProperty(MixAll.NAMESRV_ADDR_PROPERTY, System.getenv(MixAll.NAMESRV_ADDR_ENV));
+    }
+
+    public static boolean validateInstanceEndpoint(String endpoint) {
+        return INST_ENDPOINT_PATTERN.matcher(endpoint).matches();
+    }
+
+    public static String parseInstanceIdFromEndpoint(String endpoint) {
+        if (StringUtils.isEmpty(endpoint)) {
+            return null;
+        }
+        return endpoint.substring(ENDPOINT_PREFIX.length(), endpoint.indexOf('.'));
+    }
+}
diff --git a/ons-core/ons-client/src/main/resources/ons_client_info.properties b/ons-core/ons-client/src/main/resources/ons_client_info.properties
new file mode 100644
index 0000000..0ba07b4
--- /dev/null
+++ b/ons-core/ons-client/src/main/resources/ons_client_info.properties
@@ -0,0 +1,16 @@
+# 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.
+
+version=${project.version}
diff --git a/ons-core/ons-client/src/test/java/org/apache/rocketmq/ons/api/impl/rocketmq/NameServerAutoUpdateTest.java b/ons-core/ons-client/src/test/java/org/apache/rocketmq/ons/api/impl/rocketmq/NameServerAutoUpdateTest.java
new file mode 100644
index 0000000..e04d890
--- /dev/null
+++ b/ons-core/ons-client/src/test/java/org/apache/rocketmq/ons/api/impl/rocketmq/NameServerAutoUpdateTest.java
@@ -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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.rocketmq;
+
+import org.apache.rocketmq.ons.api.Consumer;
+import org.apache.rocketmq.ons.api.ONSFactory;
+import org.apache.rocketmq.ons.api.Producer;
+import org.apache.rocketmq.ons.api.PropertyKeyConst;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+import org.apache.rocketmq.ons.api.order.OrderProducer;
+import org.junit.Rule;
+import org.junit.rules.ExpectedException;
+
+import java.util.Properties;
+
+public class NameServerAutoUpdateTest {
+
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    @org.junit.Test
+    public void testNamesrv_setNsAddr() {
+        Properties prop = buildProps();
+        prop.setProperty(PropertyKeyConst.NAMESRV_ADDR, "xxx-whatever");
+        Consumer consumer = ONSFactory.createConsumer(prop);
+        consumer.start();
+    }
+
+    @org.junit.Test
+    public void testNamesrv_setOnsAddr_invalid() {
+        expectedException.expect(ONSClientException.class);
+        expectedException.expectMessage("onsAddr " + "xxx");
+
+        Properties prop = buildProps();
+        prop.setProperty(PropertyKeyConst.ONSAddr, "xxx");
+        Consumer consumer = ONSFactory.createConsumer(prop);
+        consumer.start();
+    }
+
+    @org.junit.Test
+    public void testNamesrv_setOnsAddr_valid() throws InterruptedException {
+        Properties prop = buildProps();
+        prop.setProperty(PropertyKeyConst.ONSAddr, "http://onsaddr-internet.aliyun.com/rocketmq/nsaddr4client-internet");
+        Consumer consumer = ONSFactory.createConsumer(prop);
+        consumer.start();
+    }
+
+    @org.junit.Test
+    public void testNamesrv_notSetOnsAddr_useInternet_default() throws InterruptedException {
+        Properties prop = buildProps();
+        Consumer consumer = ONSFactory.createConsumer(prop);
+        consumer.start();
+    }
+
+    @org.junit.Test
+    public void testNamesrv_notSetOnsAddr_useInternet_default_Producer() throws InterruptedException {
+        Properties prop = buildProps();
+        Producer producer = ONSFactory.createProducer(prop);
+        producer.start();
+    }
+
+    @org.junit.Test
+    public void testNamesrv_notSetOnsAddr_useInternet_default_OrderProcucer() throws InterruptedException {
+        Properties prop = buildProps();
+        OrderProducer producer = ONSFactory.createOrderProducer(prop);
+        producer.start();
+    }
+
+    private static Properties buildProps() {
+        Properties properties = new Properties();
+
+        properties.put(PropertyKeyConst.ConsumerId, "metaq-consumer-01_SELF");
+        // 鉴权用 AccessKey,在阿里云服务器管理控制台创建
+        properties.put(PropertyKeyConst.AccessKey, "XXX");
+        // 鉴权用 SecretKey,在阿里云服务器管理控制台创建
+        properties.put(PropertyKeyConst.SecretKey, "XXX");
+        return properties;
+    }
+
+}
diff --git a/ons-core/ons-client/src/test/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSClientTokenUpdateTest.java b/ons-core/ons-client/src/test/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSClientTokenUpdateTest.java
new file mode 100644
index 0000000..245fddd
--- /dev/null
+++ b/ons-core/ons-client/src/test/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSClientTokenUpdateTest.java
@@ -0,0 +1,189 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.rocketmq;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import org.apache.rocketmq.ons.api.Consumer;
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.ONSFactory;
+import org.apache.rocketmq.ons.api.Producer;
+import org.apache.rocketmq.ons.api.PropertyKeyConst;
+import org.apache.rocketmq.ons.api.SendResult;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+import org.apache.rocketmq.ons.api.impl.authority.SessionCredentials;
+import org.apache.rocketmq.remoting.netty.NettyRemotingClient;
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class ONSClientTokenUpdateTest {
+
+    private static final String TOPIC = "STS_TOPIC_TEST_MOLING";
+
+    @Ignore
+    public void testSend() throws InterruptedException {
+
+        List<List<String>> credentials = new ArrayList<List<String>>() {
+            {
+                add(new ArrayList<String>() {
+                    {
+                        add("ak");
+                        add("sk");
+                        add("token");
+                    }
+                });
+
+                add(new ArrayList<String>() {
+                    {
+                        add("ak");
+                        add("sk");
+                        add("token");
+                    }
+                });
+
+            }
+        };
+
+        Producer producer = ONSFactory.createProducer(buildProps(
+            "ak",
+            "sk",
+            "token",
+            ONSChannel.ALIYUN.name()
+        ));
+        producer.start();
+
+        for (int i = 0; i < 100; i++) {
+            List<String> credential = credentials.get(i % credentials.size());
+            producer.updateCredential(buildProps(credential.get(0), credential.get(1), credential.get(2), ONSChannel.ALIYUN.name()));
+            try {
+                Message msg = new Message(TOPIC, "tag", "key" + i, ("content." + i).getBytes());
+                SendResult result = producer.send(msg);
+                System.out.println(i + " use ak " + credential.get(0) + " send " + result.getMessageId());
+            } catch (Exception e) {
+                System.out.println(i + " use ak " + credential.get(0) + " send failed.");
+            }
+        }
+
+        Thread.sleep(10 * 1000L);
+        producer.shutdown();
+    }
+
+    @Test
+    public void test_ConsumerImpl() throws NoSuchFieldException, IllegalAccessException {
+        Consumer consumer = ONSFactory.createConsumer(buildProps("ak", "sk", "token", ONSChannel.ALIYUN.name()));
+        ONSConsumerAbstract subImpl = (ONSConsumerAbstract) consumer;
+        consumer.start();
+
+        Assert.assertTrue(subImpl.defaultMQPushConsumer.getDefaultMQPushConsumerImpl().getmQClientFactory().getMQClientAPIImpl().getRemotingClient() instanceof NettyRemotingClient);
+        NettyRemotingClient remotingClient =
+            (NettyRemotingClient) subImpl.defaultMQPushConsumer.getDefaultMQPushConsumerImpl().getmQClientFactory().getMQClientAPIImpl().getRemotingClient();
+        Assert.assertTrue(remotingClient.getRPCHooks() instanceof ClientRPCHook);
+        ClientRPCHook clientRPCHook = (ClientRPCHook) remotingClient.getRPCHooks();
+        Field field = ClientRPCHook.class.getDeclaredField("sessionCredentials");
+        field.setAccessible(true);
+        SessionCredentials credentials = (SessionCredentials) field.get(clientRPCHook);
+
+        Assert.assertEquals("ak", credentials.getAccessKey());
+        Assert.assertEquals("sk", credentials.getSecretKey());
+        Assert.assertEquals("token", credentials.getSecurityToken());
+        Assert.assertEquals(ONSChannel.ALIYUN, credentials.getOnsChannel());
+
+        consumer.updateCredential(buildProps("nak", "nsk", "ntoken", ONSChannel.CLOUD.name()));
+
+        Assert.assertEquals("nak", credentials.getAccessKey());
+        Assert.assertEquals("nsk", credentials.getSecretKey());
+        Assert.assertEquals("ntoken", credentials.getSecurityToken());
+        Assert.assertEquals(ONSChannel.CLOUD, credentials.getOnsChannel());
+    }
+
+    @Test
+    public void test_ProducerImpl() throws NoSuchFieldException, IllegalAccessException {
+        Producer producer = ONSFactory.createProducer(buildProps("ak", "sk", "token", ONSChannel.ALIYUN.name()));
+        ProducerImpl subImpl = (ProducerImpl) producer;
+        producer.start();
+
+        Assert.assertTrue(subImpl.getDefaultMQProducer().getDefaultMQProducerImpl().getmQClientFactory().getMQClientAPIImpl().getRemotingClient() instanceof NettyRemotingClient);
+        NettyRemotingClient remotingClient =
+            (NettyRemotingClient) subImpl.getDefaultMQProducer().getDefaultMQProducerImpl().getmQClientFactory().getMQClientAPIImpl().getRemotingClient();
+        Assert.assertTrue(remotingClient.getRPCHooks() instanceof ClientRPCHook);
+        ClientRPCHook clientRPCHook = (ClientRPCHook) remotingClient.getRPCHooks();
+        Field field = ClientRPCHook.class.getDeclaredField("sessionCredentials");
+        field.setAccessible(true);
+        SessionCredentials credentials = (SessionCredentials) field.get(clientRPCHook);
+
+        Assert.assertEquals("ak", credentials.getAccessKey());
+        Assert.assertEquals("sk", credentials.getSecretKey());
+        Assert.assertEquals("token", credentials.getSecurityToken());
+        Assert.assertEquals(ONSChannel.ALIYUN, credentials.getOnsChannel());
+
+        producer.updateCredential(buildProps("nak", "nsk", "ntoken", ONSChannel.CLOUD.name()));
+
+        Assert.assertEquals("nak", credentials.getAccessKey());
+        Assert.assertEquals("nsk", credentials.getSecretKey());
+        Assert.assertEquals("ntoken", credentials.getSecurityToken());
+        Assert.assertEquals(ONSChannel.CLOUD, credentials.getOnsChannel());
+    }
+
+    @Test
+    public void test_ConsumerImpl_updateNull() throws NoSuchFieldException, IllegalAccessException {
+        Consumer consumer = ONSFactory.createConsumer(buildProps("ak", "sk", "token", ONSChannel.ALIYUN.name()));
+        ONSConsumerAbstract subImpl = (ONSConsumerAbstract) consumer;
+        consumer.start();
+
+        Assert.assertTrue(subImpl.defaultMQPushConsumer.getDefaultMQPushConsumerImpl().getmQClientFactory().getMQClientAPIImpl().getRemotingClient() instanceof NettyRemotingClient);
+        NettyRemotingClient remotingClient =
+            (NettyRemotingClient) subImpl.defaultMQPushConsumer.getDefaultMQPushConsumerImpl().getmQClientFactory().getMQClientAPIImpl().getRemotingClient();
+        Assert.assertTrue(remotingClient.getRPCHooks() instanceof ClientRPCHook);
+        ClientRPCHook clientRPCHook = (ClientRPCHook) remotingClient.getRPCHooks();
+        Field field = ClientRPCHook.class.getDeclaredField("sessionCredentials");
+        field.setAccessible(true);
+        SessionCredentials credentials = (SessionCredentials) field.get(clientRPCHook);
+
+        Assert.assertEquals("ak", credentials.getAccessKey());
+        Assert.assertEquals("sk", credentials.getSecretKey());
+        Assert.assertEquals("token", credentials.getSecurityToken());
+        Assert.assertEquals(ONSChannel.ALIYUN, credentials.getOnsChannel());
+
+        try {
+            consumer.updateCredential(buildProps("nak", "", "ntoken", ONSChannel.CLOUD.name()));
+        } catch (Exception e) {
+            Assert.assertTrue(e instanceof ONSClientException);
+        }
+
+        Assert.assertEquals("ak", credentials.getAccessKey());
+        Assert.assertEquals("sk", credentials.getSecretKey());
+        Assert.assertEquals("token", credentials.getSecurityToken());
+        Assert.assertEquals(ONSChannel.ALIYUN, credentials.getOnsChannel());
+    }
+
+    private static Properties buildProps(String ak, String sk, String token, String channel) {
+        Properties properties = new Properties();
+        properties.put(PropertyKeyConst.ConsumerId, "CID_STS_TEST_MOLING");
+        properties.put(PropertyKeyConst.ProducerId, "PID_STS_TEST_MOLING");
+        properties.put(PropertyKeyConst.AccessKey, ak);
+        properties.put(PropertyKeyConst.SecretKey, sk);
+        properties.put(PropertyKeyConst.SecurityToken, token);
+        properties.put(PropertyKeyConst.OnsChannel, channel);
+
+        return properties;
+    }
+
+}
diff --git a/ons-core/ons-client/src/test/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSUtilTest.java b/ons-core/ons-client/src/test/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSUtilTest.java
new file mode 100644
index 0000000..b0b0a1f
--- /dev/null
+++ b/ons-core/ons-client/src/test/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSUtilTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.api.impl.rocketmq;
+
+import java.util.Properties;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ONSUtilTest {
+    @org.junit.Test
+    public void extractProperties() throws Exception {
+        Properties properties = new Properties();
+        properties.put("Integer", 123);
+
+        assertThat(properties.get("Integer")).isEqualTo(123);
+        assertThat(properties.getProperty("Integer")).isNull();
+
+        Properties newPro = ONSUtil.extractProperties(properties);
+        assertThat(newPro.getProperty("Integer")).isEqualTo("123");
+        assertThat(newPro.get("Integer")).isEqualTo("123");
+    }
+
+    @org.junit.Test
+    public void extractProperties_WithInner() throws Exception {
+        Properties inner = new Properties();
+        inner.put("Integer", 123);
+
+        Properties properties = new Properties(inner);
+
+        assertThat(properties.get("Integer")).isNull();
+        assertThat(properties.getProperty("Integer")).isNull();
+
+        inner.put("String", "String");
+        assertThat(properties.get("String")).isNull();
+        assertThat(properties.getProperty("String")).isEqualTo("String");
+
+
+        Properties newPro = ONSUtil.extractProperties(properties);
+        assertThat(newPro.getProperty("Integer")).isEqualTo("123");
+        assertThat(newPro.get("Integer")).isEqualTo("123");
+        assertThat(newPro.getProperty("String")).isEqualTo("String");
+        assertThat(newPro.get("String")).isEqualTo("String");
+    }
+}
\ No newline at end of file
diff --git a/ons-core/ons-trace-core/pom.xml b/ons-core/ons-trace-core/pom.xml
new file mode 100644
index 0000000..4ba3f7d
--- /dev/null
+++ b/ons-core/ons-trace-core/pom.xml
@@ -0,0 +1,41 @@
+<!--
+  ~ /*
+  ~  * 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.
+  ~  */
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>ons-all</artifactId>
+        <groupId>org.apache.rocketmq</groupId>
+        <version>1.8.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>ons-trace-core</artifactId>
+    <packaging>jar</packaging>
+    <name>ons-trace-core ${project.version}</name>
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>ons-auth4client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.rocketmq</groupId>
+            <artifactId>rocketmq-client</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceBean.java b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceBean.java
new file mode 100644
index 0000000..211958e
--- /dev/null
+++ b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceBean.java
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.open.trace.core.common;
+
+import org.apache.rocketmq.ons.open.trace.core.utils.MixUtils;
+import org.apache.rocketmq.common.message.MessageType;
+
+public class OnsTraceBean {
+    private static final String LOCAL_ADDRESS = MixUtils.getLocalAddress();
+    private String topic = "";
+    private String msgId = "";
+    private String offsetMsgId = "";
+    private String tags = "";
+    private String keys = "";
+    private String storeHost = LOCAL_ADDRESS;
+    private String clientHost = LOCAL_ADDRESS;
+    private long storeTime;
+    private int retryTimes;
+    private int bodyLength;
+    private MessageType msgType;
+
+
+    public MessageType getMsgType() {
+        return msgType;
+    }
+
+
+    public void setMsgType(final MessageType msgType) {
+        this.msgType = msgType;
+    }
+
+
+    public String getOffsetMsgId() {
+        return offsetMsgId;
+    }
+
+
+    public void setOffsetMsgId(final String offsetMsgId) {
+        this.offsetMsgId = offsetMsgId;
+    }
+
+    public String getTopic() {
+        return topic;
+    }
+
+
+    public void setTopic(String topic) {
+        this.topic = topic;
+    }
+
+
+    public String getMsgId() {
+        return msgId;
+    }
+
+
+    public void setMsgId(String msgId) {
+        this.msgId = msgId;
+    }
+
+
+    public String getTags() {
+        return tags;
+    }
+
+
+    public void setTags(String tags) {
+        this.tags = tags;
+    }
+
+
+    public String getKeys() {
+        return keys;
+    }
+
+
+    public void setKeys(String keys) {
+        this.keys = keys;
+    }
+
+
+    public String getStoreHost() {
+        return storeHost;
+    }
+
+
+    public void setStoreHost(String storeHost) {
+        this.storeHost = storeHost;
+    }
+
+
+    public String getClientHost() {
+        return clientHost;
+    }
+
+
+    public void setClientHost(String clientHost) {
+        this.clientHost = clientHost;
+    }
+
+
+    public long getStoreTime() {
+        return storeTime;
+    }
+
+
+    public void setStoreTime(long storeTime) {
+        this.storeTime = storeTime;
+    }
+
+
+    public int getRetryTimes() {
+        return retryTimes;
+    }
+
+
+    public void setRetryTimes(int retryTimes) {
+        this.retryTimes = retryTimes;
+    }
+
+
+    public int getBodyLength() {
+        return bodyLength;
+    }
+
+
+    public void setBodyLength(int bodyLength) {
+        this.bodyLength = bodyLength;
+    }
+}
diff --git a/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceConstants.java b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceConstants.java
new file mode 100644
index 0000000..0877f84
--- /dev/null
+++ b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceConstants.java
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.open.trace.core.common;
+
+import javax.annotation.Generated;
+
+import org.apache.rocketmq.common.MixAll;
+
+@Generated("ons-client")
+public class OnsTraceConstants {
+
+    public static final String NAMESRV_ADDR = "NAMESRV_ADDR";
+
+    public static final String ADDRSRV_URL = "ADDRSRV_URL";
+
+    public static final String AccessKey = "AccessKey";
+
+    public static final String SecretKey = "SecretKey";
+
+    public static final String InstanceName = "InstanceName";
+
+    public static final String AsyncBufferSize = "AsyncBufferSize";
+
+    public static final String MaxBatchNum = "MaxBatchNum";
+
+    public static final String WakeUpNum = "WakeUpNum";
+
+    public static final String MaxMsgSize = "MaxMsgSize";
+
+
+    public static final String groupName = "_INNER_TRACE_PRODUCER";
+
+    public static final String traceTopic = MixAll.SYSTEM_TOPIC_PREFIX + "TRACE_DATA_";
+
+
+    public static final String default_region = MixAll.DEFAULT_TRACE_REGION_ID;
+
+    public static final char CONTENT_SPLITOR = (char)1;
+    public static final char FIELD_SPLITOR = (char)2;
+
+    public static final String TraceDispatcherType = "DispatcherType";
+}
diff --git a/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceContext.java b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceContext.java
new file mode 100644
index 0000000..f6aa191
--- /dev/null
+++ b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceContext.java
@@ -0,0 +1,168 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.open.trace.core.common;
+
+import java.util.List;
+
+import org.apache.rocketmq.common.message.MessageClientIDSetter;
+
+public class OnsTraceContext implements Comparable<OnsTraceContext> {
+
+    private OnsTraceType traceType;
+
+    private long timeStamp = System.currentTimeMillis();
+
+    private String regionId = "";
+    private String regionName = "";
+
+    private String groupName = "";
+
+    private int costTime = 0;
+
+    private boolean isSuccess = true;
+
+    private String requestId = MessageClientIDSetter.createUniqID();
+
+    private int contextCode = 0;
+
+    private int exactlyOnceStatus = 0;
+
+    private List<OnsTraceBean> traceBeans;
+
+    public int getContextCode() {
+        return contextCode;
+    }
+
+    public void setContextCode(final int contextCode) {
+        this.contextCode = contextCode;
+    }
+
+    public int getExactlyOnceStatus() {
+        return exactlyOnceStatus;
+    }
+
+    public void setExactlyOnceStatus(int exactlyOnceStatus) {
+        this.exactlyOnceStatus = exactlyOnceStatus;
+    }
+
+    public List<OnsTraceBean> getTraceBeans() {
+        return traceBeans;
+    }
+
+
+    public void setTraceBeans(List<OnsTraceBean> traceBeans) {
+        this.traceBeans = traceBeans;
+    }
+
+
+    public String getRegionId() {
+        return regionId;
+    }
+
+
+    public void setRegionId(String regionId) {
+        this.regionId = regionId;
+    }
+
+
+    public OnsTraceType getTraceType() {
+        return traceType;
+    }
+
+
+    public void setTraceType(OnsTraceType traceType) {
+        this.traceType = traceType;
+    }
+
+
+    public long getTimeStamp() {
+        return timeStamp;
+    }
+
+
+    public void setTimeStamp(long timeStamp) {
+        this.timeStamp = timeStamp;
+    }
+
+
+    public String getGroupName() {
+        return groupName;
+    }
+
+
+    public void setGroupName(String groupName) {
+        this.groupName = groupName;
+    }
+
+
+    public int getCostTime() {
+        return costTime;
+    }
+
+
+    public void setCostTime(int costTime) {
+        this.costTime = costTime;
+    }
+
+
+    public boolean isSuccess() {
+        return isSuccess;
+    }
+
+
+    public void setSuccess(boolean success) {
+        isSuccess = success;
+    }
+
+
+    public String getRequestId() {
+        return requestId;
+    }
+
+
+    public void setRequestId(String requestId) {
+        this.requestId = requestId;
+    }
+
+    public String getRegionName() {
+        return regionName;
+    }
+
+    public void setRegionName(String regionName) {
+        this.regionName = regionName;
+    }
+
+    @Override
+    public int compareTo(OnsTraceContext o) {
+        return (int) (this.timeStamp - o.getTimeStamp());
+    }
+
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(1024);
+        sb.append(traceType).append("_").append(groupName)
+            .append("_").append(regionId).append("_").append(isSuccess).append("_");
+        if (traceBeans != null && traceBeans.size() > 0) {
+            for (OnsTraceBean bean : traceBeans) {
+                sb.append(bean.getMsgId() + "_" + bean.getTopic() + "_");
+            }
+        }
+        return "OnsTraceContext{" + sb.toString() + '}';
+    }
+}
diff --git a/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceDataEncoder.java b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceDataEncoder.java
new file mode 100644
index 0000000..7b6ad6e
--- /dev/null
+++ b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceDataEncoder.java
@@ -0,0 +1,162 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.open.trace.core.common;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.rocketmq.common.message.MessageType;
+
+public class OnsTraceDataEncoder {
+
+
+    public static List<OnsTraceContext> decoderFromTraceDataString(String traceData) {
+        List<OnsTraceContext> resList = new ArrayList<OnsTraceContext>();
+        if (traceData == null || traceData.length() <= 0) {
+            return resList;
+        }
+        String[] contextList = traceData.split(String.valueOf(OnsTraceConstants.FIELD_SPLITOR));
+        for (String context : contextList) {
+            String[] line = context.split(String.valueOf(OnsTraceConstants.CONTENT_SPLITOR));
+            if (line[0].equals(OnsTraceType.Pub.name())) {
+                OnsTraceContext pubContext = new OnsTraceContext();
+                pubContext.setTraceType(OnsTraceType.Pub);
+                pubContext.setTimeStamp(Long.parseLong(line[1]));
+                pubContext.setRegionId(line[2]);
+                pubContext.setGroupName(line[3]);
+                OnsTraceBean bean = new OnsTraceBean();
+                bean.setTopic(line[4]);
+                bean.setMsgId(line[5]);
+                bean.setTags(line[6]);
+                bean.setKeys(line[7]);
+                bean.setStoreHost(line[8]);
+                bean.setBodyLength(Integer.parseInt(line[9]));
+                pubContext.setCostTime(Integer.parseInt(line[10]));
+                bean.setMsgType(MessageType.values()[Integer.parseInt(line[11])]);
+                if (line.length == 13) {
+                    pubContext.setSuccess(Boolean.parseBoolean(line[12]));
+                } else if (line.length == 14) {
+                    bean.setOffsetMsgId(line[12]);
+                    pubContext.setSuccess(Boolean.parseBoolean(line[13]));
+                }
+                pubContext.setTraceBeans(new ArrayList<OnsTraceBean>(1));
+                pubContext.getTraceBeans().add(bean);
+                resList.add(pubContext);
+            } else if (line[0].equals(OnsTraceType.SubBefore.name())) {
+                OnsTraceContext subBeforeContext = new OnsTraceContext();
+                subBeforeContext.setTraceType(OnsTraceType.SubBefore);
+                subBeforeContext.setTimeStamp(Long.parseLong(line[1]));
+                subBeforeContext.setRegionId(line[2]);
+                subBeforeContext.setGroupName(line[3]);
+                subBeforeContext.setRequestId(line[4]);
+                OnsTraceBean bean = new OnsTraceBean();
+                bean.setMsgId(line[5]);
+                bean.setRetryTimes(Integer.parseInt(line[6]));
+                bean.setKeys(line[7]);
+                subBeforeContext.setTraceBeans(new ArrayList<OnsTraceBean>(1));
+                subBeforeContext.getTraceBeans().add(bean);
+                resList.add(subBeforeContext);
+            } else if (line[0].equals(OnsTraceType.SubAfter.name())) {
+                OnsTraceContext subAfterContext = new OnsTraceContext();
+                subAfterContext.setTraceType(OnsTraceType.SubAfter);
+                subAfterContext.setRequestId(line[1]);
+                OnsTraceBean bean = new OnsTraceBean();
+                bean.setMsgId(line[2]);
+                bean.setKeys(line[5]);
+                subAfterContext.setTraceBeans(new ArrayList<OnsTraceBean>(1));
+                subAfterContext.getTraceBeans().add(bean);
+                subAfterContext.setCostTime(Integer.parseInt(line[3]));
+                subAfterContext.setSuccess(Boolean.parseBoolean(line[4]));
+                if (line.length >= 7) {
+                    // add the context type
+                    subAfterContext.setContextCode(Integer.parseInt(line[6]));
+                }
+                if (line.length >= 8) {
+                    subAfterContext.setExactlyOnceStatus(Integer.parseInt(line[7]));
+                }
+                resList.add(subAfterContext);
+            }
+        }
+        return resList;
+    }
+
+
+    public static OnsTraceTransferBean encoderFromContextBean(OnsTraceContext ctx) {
+        if (ctx == null) {
+            return null;
+        }
+        OnsTraceTransferBean transferBean = new OnsTraceTransferBean();
+        StringBuilder sb = new StringBuilder(256);
+        switch (ctx.getTraceType()) {
+            case Pub: {
+                OnsTraceBean bean = ctx.getTraceBeans().get(0);
+                sb.append(ctx.getTraceType()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                    .append(ctx.getTimeStamp()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                    .append(ctx.getRegionId()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                    .append(ctx.getGroupName()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                    .append(bean.getTopic()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                    .append(bean.getMsgId()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                    .append(bean.getTags()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                    .append(bean.getKeys()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                    .append(bean.getStoreHost()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                    .append(bean.getBodyLength()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                    .append(ctx.getCostTime()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                    .append(bean.getMsgType().ordinal()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                    .append(bean.getOffsetMsgId()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                    .append(ctx.isSuccess()).append(OnsTraceConstants.FIELD_SPLITOR);
+            }
+            break;
+            case SubBefore: {
+                for (OnsTraceBean bean : ctx.getTraceBeans()) {
+                    sb.append(ctx.getTraceType()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                        .append(ctx.getTimeStamp()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                        .append(ctx.getRegionId()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                        .append(ctx.getGroupName()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                        .append(ctx.getRequestId()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                        .append(bean.getMsgId()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                        .append(bean.getRetryTimes()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                        .append(bean.getKeys()).append(OnsTraceConstants.FIELD_SPLITOR);//
+                }
+            }
+            break;
+            case SubAfter: {
+                for (OnsTraceBean bean : ctx.getTraceBeans()) {
+                    sb.append(ctx.getTraceType()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                        // .append(ctx.getTimeStamp()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                        .append(ctx.getRequestId()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                        .append(bean.getMsgId()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                        .append(ctx.getCostTime()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                        .append(ctx.isSuccess()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                        .append(bean.getKeys()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                        .append(ctx.getContextCode()).append(OnsTraceConstants.CONTENT_SPLITOR)//
+                        .append(ctx.getExactlyOnceStatus()).append(OnsTraceConstants.FIELD_SPLITOR);
+                }
+            }
+            break;
+            default:
+        }
+        transferBean.setTransData(sb.toString());
+        for (OnsTraceBean bean : ctx.getTraceBeans()) {
+            transferBean.getTransKey().add(bean.getMsgId());
+            if (bean.getKeys() != null && bean.getKeys().length() > 0) {
+                transferBean.getTransKey().add(bean.getKeys());
+            }
+        }
+        return transferBean;
+    }
+}
diff --git a/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceDispatcherType.java b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceDispatcherType.java
new file mode 100644
index 0000000..88dc595
--- /dev/null
+++ b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceDispatcherType.java
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.open.trace.core.common;
+
+public enum OnsTraceDispatcherType {
+
+    PRODUCER,
+
+    CONSUMER
+}
diff --git a/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceTransferBean.java b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceTransferBean.java
new file mode 100644
index 0000000..71d79e4
--- /dev/null
+++ b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceTransferBean.java
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.open.trace.core.common;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class OnsTraceTransferBean {
+    private String transData;
+    private Set<String> transKey = new HashSet<String>();
+
+
+    public String getTransData() {
+        return transData;
+    }
+
+
+    public void setTransData(String transData) {
+        this.transData = transData;
+    }
+
+
+    public Set<String> getTransKey() {
+        return transKey;
+    }
+
+
+    public void setTransKey(Set<String> transKey) {
+        this.transKey = transKey;
+    }
+}
diff --git a/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceType.java b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceType.java
new file mode 100644
index 0000000..5684584
--- /dev/null
+++ b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/common/OnsTraceType.java
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.open.trace.core.common;
+
+public enum OnsTraceType {
+
+    Pub,
+
+    SubBefore,
+
+    SubAfter,
+}
diff --git a/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/dispatch/AsyncDispatcher.java b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/dispatch/AsyncDispatcher.java
new file mode 100644
index 0000000..87ead88
--- /dev/null
+++ b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/dispatch/AsyncDispatcher.java
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.open.trace.core.dispatch;
+
+import java.io.IOException;
+
+import org.apache.rocketmq.client.exception.MQClientException;
+
+public interface AsyncDispatcher {
+
+    void start() throws MQClientException;
+
+    boolean append(Object ctx);
+
+    void flush() throws IOException;
+
+    void shutdown();
+}
diff --git a/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/dispatch/impl/AsyncArrayDispatcher.java b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/dispatch/impl/AsyncArrayDispatcher.java
new file mode 100644
index 0000000..4f02bbd
--- /dev/null
+++ b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/dispatch/impl/AsyncArrayDispatcher.java
@@ -0,0 +1,382 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.open.trace.core.dispatch.impl;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+import org.apache.rocketmq.client.common.ThreadLocalIndex;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.client.impl.consumer.DefaultMQPushConsumerImpl;
+import org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl;
+import org.apache.rocketmq.client.impl.producer.TopicPublishInfo;
+import org.apache.rocketmq.client.log.ClientLogger;
+import org.apache.rocketmq.client.producer.DefaultMQProducer;
+import org.apache.rocketmq.client.producer.MessageQueueSelector;
+import org.apache.rocketmq.client.producer.SendCallback;
+import org.apache.rocketmq.client.producer.SendResult;
+import org.apache.rocketmq.common.ThreadFactoryImpl;
+import org.apache.rocketmq.common.message.Message;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.common.protocol.NamespaceUtil;
+import org.apache.rocketmq.logging.InternalLogger;
+import org.apache.rocketmq.ons.api.impl.authority.SessionCredentials;
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceConstants;
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceContext;
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceDataEncoder;
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceDispatcherType;
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceTransferBean;
+import org.apache.rocketmq.ons.open.trace.core.dispatch.AsyncDispatcher;
+
+public class AsyncArrayDispatcher implements AsyncDispatcher {
+    private final static InternalLogger CLIENT_LOG = ClientLogger.getLog();
+    private final int queueSize;
+    private final int batchSize;
+    private final DefaultMQProducer traceProducer;
+    private final ThreadPoolExecutor traceExecuter;
+
+    private AtomicLong discardCount;
+    private Thread worker;
+    private ArrayBlockingQueue<OnsTraceContext> traceContextQueue;
+    private ArrayBlockingQueue<Runnable> appenderQueue;
+    private volatile Thread shutDownHook;
+    private volatile boolean stopped = false;
+    private String dispatcherType;
+    private DefaultMQProducerImpl hostProducer;
+    private DefaultMQPushConsumerImpl hostConsumer;
+    private volatile ThreadLocalIndex sendWhichQueue = new ThreadLocalIndex();
+    private String dispatcherId = UUID.randomUUID().toString();
+
+    public AsyncArrayDispatcher(Properties properties) throws MQClientException {
+        dispatcherType = properties.getProperty(OnsTraceConstants.TraceDispatcherType);
+        int queueSize = Integer.parseInt(properties.getProperty(OnsTraceConstants.AsyncBufferSize, "2048"));
+        queueSize = 1 << (32 - Integer.numberOfLeadingZeros(queueSize - 1));
+        this.queueSize = queueSize;
+        batchSize = Integer.parseInt(properties.getProperty(OnsTraceConstants.MaxBatchNum, "1"));
+        this.discardCount = new AtomicLong(0L);
+        traceContextQueue = new ArrayBlockingQueue<OnsTraceContext>(1024);
+        appenderQueue = new ArrayBlockingQueue<Runnable>(queueSize);
+
+        this.traceExecuter = new ThreadPoolExecutor(//
+            10, //
+            20, //
+            1000 * 60, //
+            TimeUnit.MILLISECONDS, //
+            this.appenderQueue, //
+            new ThreadFactoryImpl("MQTraceSendThread_"));
+        traceProducer = TraceProducerFactory.getTraceDispatcherProducer(properties);
+    }
+
+    public AsyncArrayDispatcher(Properties properties, SessionCredentials sessionCredentials) throws MQClientException {
+        dispatcherType = properties.getProperty(OnsTraceConstants.TraceDispatcherType);
+        int queueSize = Integer.parseInt(properties.getProperty(OnsTraceConstants.AsyncBufferSize, "2048"));
+        queueSize = 1 << (32 - Integer.numberOfLeadingZeros(queueSize - 1));
+        this.queueSize = queueSize;
+        batchSize = Integer.parseInt(properties.getProperty(OnsTraceConstants.MaxBatchNum, "1"));
+        this.discardCount = new AtomicLong(0L);
+        traceContextQueue = new ArrayBlockingQueue<OnsTraceContext>(1024);
+        appenderQueue = new ArrayBlockingQueue<Runnable>(queueSize);
+
+        this.traceExecuter = new ThreadPoolExecutor(
+            10,
+            20,
+            1000 * 60,
+            TimeUnit.MILLISECONDS,
+            this.appenderQueue,
+            new ThreadFactoryImpl("MQTraceSendThread_"));
+        traceProducer = TraceProducerFactory.getTraceDispatcherProducer(properties, sessionCredentials);
+    }
+
+    public DefaultMQProducerImpl getHostProducer() {
+        return hostProducer;
+    }
+
+    public void setHostProducer(DefaultMQProducerImpl hostProducer) {
+        this.hostProducer = hostProducer;
+    }
+
+    public DefaultMQPushConsumerImpl getHostConsumer() {
+        return hostConsumer;
+    }
+
+    public void setHostConsumer(DefaultMQPushConsumerImpl hostConsumer) {
+        this.hostConsumer = hostConsumer;
+    }
+
+    @Override
+    public void start() throws MQClientException {
+        TraceProducerFactory.registerTraceDispatcher(dispatcherId);
+        this.worker = new ThreadFactoryImpl("MQ-AsyncArrayDispatcher-Thread-" + dispatcherId, true)
+            .newThread(new AsyncRunnable());
+        this.worker.start();
+        this.registerShutDownHook();
+    }
+
+    @Override
+    public boolean append(final Object ctx) {
+        boolean result = traceContextQueue.offer((OnsTraceContext) ctx);
+        if (!result) {
+            CLIENT_LOG.info("buffer full" + discardCount.incrementAndGet() + " ,context is " + ctx);
+        }
+        return result;
+    }
+
+    @Override
+    public void flush() throws IOException {
+        long end = System.currentTimeMillis() + 500;
+        while (traceContextQueue.size() > 0 || appenderQueue.size() > 0 && System.currentTimeMillis() <= end) {
+            try {
+                Thread.sleep(1);
+            } catch (InterruptedException e) {
+                break;
+            }
+        }
+        CLIENT_LOG.info("------end trace send " + traceContextQueue.size() + "   " + appenderQueue.size());
+    }
+
+    @Override
+    public void shutdown() {
+        this.stopped = true;
+        this.traceExecuter.shutdown();
+        TraceProducerFactory.unregisterTraceDispatcher(dispatcherId);
+        this.removeShutdownHook();
+    }
+
+    public void registerShutDownHook() {
+        if (shutDownHook == null) {
+            shutDownHook = new ThreadFactoryImpl("ShutdownHookMQTrace").newThread(new Runnable() {
+                private volatile boolean hasShutdown = false;
+                @Override
+                public void run() {
+                    synchronized (this) {
+                        if (!this.hasShutdown) {
+                            try {
+                                flush();
+                            } catch (IOException e) {
+                                CLIENT_LOG.error("system mqtrace hook shutdown failed ,maybe loss some trace data");
+                            }
+                        }
+                    }
+                }
+            });
+            Runtime.getRuntime().addShutdownHook(shutDownHook);
+        }
+    }
+
+    public void removeShutdownHook() {
+        if (shutDownHook != null) {
+            Runtime.getRuntime().removeShutdownHook(shutDownHook);
+        }
+    }
+
+    class AsyncRunnable implements Runnable {
+        private boolean stopped;
+
+        @Override
+        public void run() {
+            while (!stopped) {
+                List<OnsTraceContext> contexts = new ArrayList<OnsTraceContext>(batchSize);
+                for (int i = 0; i < batchSize; i++) {
+                    OnsTraceContext context = null;
+                    try {
+                        context = traceContextQueue.poll(5, TimeUnit.MILLISECONDS);
+                    } catch (InterruptedException e) {
+                    }
+                    if (context != null) {
+                        contexts.add(context);
+                    } else {
+                        break;
+                    }
+                }
+                if (contexts.size() > 0) {
+                    AsyncAppenderRequest request = new AsyncAppenderRequest(contexts);
+                    traceExecuter.submit(request);
+                } else if (AsyncArrayDispatcher.this.stopped) {
+                    this.stopped = true;
+                }
+            }
+
+        }
+    }
+
+    class AsyncAppenderRequest implements Runnable {
+        List<OnsTraceContext> contextList;
+
+        public AsyncAppenderRequest(final List<OnsTraceContext> contextList) {
+            if (contextList != null) {
+                this.contextList = contextList;
+            } else {
+                this.contextList = new ArrayList<OnsTraceContext>(1);
+            }
+        }
+
+        @Override
+        public void run() {
+            sendTraceData(contextList);
+        }
+
+        public void sendTraceData(List<OnsTraceContext> contextList) {
+            Map<String, List<OnsTraceTransferBean>> transBeanMap = new HashMap<String, List<OnsTraceTransferBean>>(16);
+            String currentRegionId = null;
+            for (OnsTraceContext context : contextList) {
+                currentRegionId = context.getRegionId();
+                if (currentRegionId == null || context.getTraceBeans().isEmpty()) {
+                    continue;
+                }
+                String topic = context.getTraceBeans().get(0).getTopic();
+                String key = topic + OnsTraceConstants.CONTENT_SPLITOR + currentRegionId;
+                List<OnsTraceTransferBean> transBeanList = transBeanMap.get(key);
+                if (transBeanList == null) {
+                    transBeanList = new ArrayList<OnsTraceTransferBean>();
+                    transBeanMap.put(key, transBeanList);
+                }
+                OnsTraceTransferBean traceData = OnsTraceDataEncoder.encoderFromContextBean(context);
+                transBeanList.add(traceData);
+            }
+            for (Map.Entry<String, List<OnsTraceTransferBean>> entry : transBeanMap.entrySet()) {
+                String[] key = entry.getKey().split(String.valueOf(OnsTraceConstants.CONTENT_SPLITOR));
+                flushData(entry.getValue(), key[0], key[1]);
+            }
+        }
+
+        private void flushData(List<OnsTraceTransferBean> transBeanList, String topic, String currentRegionId) {
+            if (transBeanList.size() == 0) {
+                return;
+            }
+            StringBuilder buffer = new StringBuilder(1024);
+            int count = 0;
+            Set<String> keySet = new HashSet<String>();
+
+            for (OnsTraceTransferBean bean : transBeanList) {
+                keySet.addAll(bean.getTransKey());
+                buffer.append(bean.getTransData());
+                count++;
+                if (buffer.length() >= traceProducer.getMaxMessageSize()) {
+                    sendTraceDataByMQ(keySet, buffer.toString(), topic, currentRegionId);
+                    buffer.delete(0, buffer.length());
+                    keySet.clear();
+                    count = 0;
+                }
+            }
+            if (count > 0) {
+                sendTraceDataByMQ(keySet, buffer.toString(), topic, currentRegionId);
+            }
+            transBeanList.clear();
+        }
+
+        private void sendTraceDataByMQ(Set<String> keySet, final String data, String dataTopic,
+            String currentRegionId) {
+            String topic = OnsTraceConstants.traceTopic + currentRegionId;
+            final Message message = new Message(topic, data.getBytes());
+            message.setKeys(keySet);
+            try {
+                Set<String> dataBrokerSet = getBrokerSetByTopic(dataTopic);
+                Set<String> traceBrokerSet = tryGetMessageQueueBrokerSet(traceProducer.getDefaultMQProducerImpl(), topic);
+                dataBrokerSet.retainAll(traceBrokerSet);
+                SendCallback callback = new SendCallback() {
+                    @Override
+                    public void onSuccess(SendResult sendResult) {
+                    }
+
+                    @Override
+                    public void onException(Throwable e) {
+                        CLIENT_LOG.info("send trace data ,the traceData is " + data);
+                    }
+                };
+                if (dataBrokerSet.isEmpty()) {
+                    //no cross set
+                    traceProducer.send(message, callback, 5000);
+                } else {
+                    traceProducer.send(message, new MessageQueueSelector() {
+                        @Override
+                        public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
+                            Set<String> brokerSet = (Set<String>) arg;
+                            List<MessageQueue> filterMqs = new ArrayList<MessageQueue>();
+                            for (MessageQueue queue : mqs) {
+                                if (brokerSet.contains(queue.getBrokerName())) {
+                                    filterMqs.add(queue);
+                                }
+                            }
+                            int index = sendWhichQueue.getAndIncrement();
+                            int pos = Math.abs(index) % filterMqs.size();
+                            if (pos < 0) {
+                                pos = 0;
+                            }
+                            return filterMqs.get(pos);
+                        }
+                    }, dataBrokerSet, callback);
+                }
+
+            } catch (Exception e) {
+                CLIENT_LOG.info("send trace data,the traceData is" + data);
+            }
+        }
+
+        private Set<String> getBrokerSetByTopic(String topic) {
+            Set<String> brokerSet = new HashSet<String>();
+            if (dispatcherType != null && dispatcherType.equals(OnsTraceDispatcherType.PRODUCER.name()) && hostProducer != null) {
+                brokerSet = tryGetMessageQueueBrokerSet(hostProducer, topic);
+            }
+            if (dispatcherType != null && dispatcherType.equals(OnsTraceDispatcherType.CONSUMER.name()) && hostConsumer != null) {
+                brokerSet = tryGetMessageQueueBrokerSet(hostConsumer, topic);
+            }
+            return brokerSet;
+        }
+
+        private Set<String> tryGetMessageQueueBrokerSet(DefaultMQProducerImpl producer, String topic) {
+            Set<String> brokerSet = new HashSet<String>();
+            String realTopic = NamespaceUtil.wrapNamespace(producer.getDefaultMQProducer().getNamespace(), topic);
+            TopicPublishInfo topicPublishInfo = producer.getTopicPublishInfoTable().get(realTopic);
+            if (null == topicPublishInfo || !topicPublishInfo.ok()) {
+                producer.getTopicPublishInfoTable().putIfAbsent(realTopic, new TopicPublishInfo());
+                producer.getmQClientFactory().updateTopicRouteInfoFromNameServer(realTopic);
+                topicPublishInfo = producer.getTopicPublishInfoTable().get(realTopic);
+            }
+            if (topicPublishInfo.isHaveTopicRouterInfo() || topicPublishInfo.ok()) {
+                for (MessageQueue queue : topicPublishInfo.getMessageQueueList()) {
+                    brokerSet.add(queue.getBrokerName());
+                }
+            }
+            return brokerSet;
+        }
+
+        private Set<String> tryGetMessageQueueBrokerSet(DefaultMQPushConsumerImpl consumer, String topic) {
+            Set<String> brokerSet = new HashSet<String>();
+            try {
+                String realTopic = NamespaceUtil.wrapNamespace(consumer.getDefaultMQPushConsumer().getNamespace(), topic);
+                Set<MessageQueue> messageQueues = consumer.fetchSubscribeMessageQueues(realTopic);
+                for (MessageQueue queue : messageQueues) {
+                    brokerSet.add(queue.getBrokerName());
+                }
+            } catch (MQClientException e) {
+                CLIENT_LOG.info("fetch message queue failed, the topic is {}", topic);
+            }
+            return brokerSet;
+        }
+    }
+}
diff --git a/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/dispatch/impl/TraceProducerFactory.java b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/dispatch/impl/TraceProducerFactory.java
new file mode 100644
index 0000000..60e65cb
--- /dev/null
+++ b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/dispatch/impl/TraceProducerFactory.java
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.open.trace.core.dispatch.impl;
+
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceConstants;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.client.producer.DefaultMQProducer;
+import org.apache.rocketmq.common.namesrv.TopAddressing;
+
+import org.apache.rocketmq.ons.api.impl.authority.SessionCredentials;
+import org.apache.rocketmq.ons.api.impl.rocketmq.ClientRPCHook;
+
+public class TraceProducerFactory {
+    private static Map<String, Object> dispatcherTable = new ConcurrentHashMap<String, Object>();
+    private static AtomicBoolean isStarted = new AtomicBoolean(false);
+    private static DefaultMQProducer traceProducer;
+
+    public static DefaultMQProducer getTraceDispatcherProducer(Properties properties) {
+        if (traceProducer == null) {
+            SessionCredentials sessionCredentials = new SessionCredentials();
+            Properties sessionProperties = new Properties();
+            String accessKey = properties.getProperty(OnsTraceConstants.AccessKey);
+            String secretKey = properties.getProperty(OnsTraceConstants.SecretKey);
+            sessionProperties.put(OnsTraceConstants.AccessKey, accessKey);
+            sessionProperties.put(OnsTraceConstants.SecretKey, secretKey);
+            sessionCredentials.updateContent(sessionProperties);
+            traceProducer = new DefaultMQProducer(new ClientRPCHook(sessionCredentials));
+            traceProducer.setProducerGroup(accessKey + OnsTraceConstants.groupName);
+            traceProducer.setSendMsgTimeout(5000);
+            traceProducer.setInstanceName(properties.getProperty(OnsTraceConstants.InstanceName, String.valueOf(System.currentTimeMillis())));
+            String nameSrv = properties.getProperty(OnsTraceConstants.NAMESRV_ADDR);
+            if (nameSrv == null) {
+                TopAddressing topAddressing = new TopAddressing(properties.getProperty(OnsTraceConstants.ADDRSRV_URL));
+                nameSrv = topAddressing.fetchNSAddr();
+            }
+            traceProducer.setNamesrvAddr(nameSrv);
+            traceProducer.setVipChannelEnabled(false);
+            int maxSize = Integer.parseInt(properties.getProperty(OnsTraceConstants.MaxMsgSize, "128000"));
+            traceProducer.setMaxMessageSize(maxSize - 10 * 1000);
+        }
+        return traceProducer;
+    }
+
+    public static DefaultMQProducer getTraceDispatcherProducer(Properties properties, SessionCredentials sessionCredentials) {
+        if (traceProducer == null) {
+            String accessKey = properties.getProperty(OnsTraceConstants.AccessKey);
+            traceProducer = new DefaultMQProducer(new ClientRPCHook(sessionCredentials));
+            traceProducer.setProducerGroup(accessKey.replace('.', '-') + OnsTraceConstants.groupName);
+            traceProducer.setSendMsgTimeout(5000);
+            traceProducer.setInstanceName(properties.getProperty(OnsTraceConstants.InstanceName, String.valueOf(System.currentTimeMillis())));
+            String nameSrv = properties.getProperty(OnsTraceConstants.NAMESRV_ADDR);
+            if (nameSrv == null) {
+                TopAddressing topAddressing = new TopAddressing(properties.getProperty(OnsTraceConstants.ADDRSRV_URL));
+                nameSrv = topAddressing.fetchNSAddr();
+            }
+            traceProducer.setNamesrvAddr(nameSrv);
+            traceProducer.setVipChannelEnabled(false);
+            int maxSize = Integer.parseInt(properties.getProperty(OnsTraceConstants.MaxMsgSize, "128000"));
+            traceProducer.setMaxMessageSize(maxSize - 10 * 1000);
+        }
+        return traceProducer;
+    }
+
+    public static void registerTraceDispatcher(String dispatcherId) throws MQClientException {
+        dispatcherTable.put(dispatcherId, new Object());
+        if (traceProducer != null && isStarted.compareAndSet(false, true)) {
+            traceProducer.start();
+        }
+    }
+
+    public static void unregisterTraceDispatcher(String dispatcherId) {
+        dispatcherTable.remove(dispatcherId);
+        if (dispatcherTable.isEmpty() && traceProducer != null && isStarted.get()) {
+            traceProducer.shutdown();
+        }
+    }
+}
diff --git a/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/hook/AbstractRPCHook.java b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/hook/AbstractRPCHook.java
new file mode 100644
index 0000000..9e78880
--- /dev/null
+++ b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/hook/AbstractRPCHook.java
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+package org.apache.rocketmq.ons.open.trace.core.hook;
+
+import java.lang.reflect.Field;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.rocketmq.remoting.CommandCustomHeader;
+import org.apache.rocketmq.remoting.RPCHook;
+import org.apache.rocketmq.remoting.protocol.RemotingCommand;
+
+import static org.apache.rocketmq.ons.api.impl.authority.SessionCredentials.AccessKey;
+import static org.apache.rocketmq.ons.api.impl.authority.SessionCredentials.ONSChannelKey;
+
+public abstract class AbstractRPCHook implements RPCHook {
+    protected ConcurrentHashMap<Class<? extends CommandCustomHeader>, Field[]> fieldCache =
+            new ConcurrentHashMap<Class<? extends CommandCustomHeader>, Field[]>();
+
+
+    protected SortedMap<String, String> parseRequestContent(RemotingCommand request, String ak, String onsChannel) {
+        CommandCustomHeader header = request.readCustomHeader();
+        // sort property
+        SortedMap<String, String> map = new TreeMap<String, String>();
+        map.put(AccessKey, ak);
+        map.put(ONSChannelKey, onsChannel);
+        try {
+            // add header properties
+            if (null != header) {
+                Field[] fields = fieldCache.get(header.getClass());
+                if (null == fields) {
+                    fields = header.getClass().getDeclaredFields();
+                    for (Field field : fields) {
+                        field.setAccessible(true);
+                    }
+                    Field[] tmp = fieldCache.putIfAbsent(header.getClass(), fields);
+                    if (null != tmp) {
+                        fields = tmp;
+                    }
+                }
+
+                for (Field field : fields) {
+                    Object value = field.get(header);
+                    if (null != value && !field.isSynthetic()) {
+                        map.put(field.getName(), value.toString());
+                    }
+                }
+            }
+            return map;
+        }
+        catch (Exception e) {
+            throw new RuntimeException("incompatible exception.", e);
+        }
+    }
+
+}
diff --git a/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/utils/MixUtils.java b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/utils/MixUtils.java
new file mode 100644
index 0000000..9eb5be1
--- /dev/null
+++ b/ons-core/ons-trace-core/src/main/java/org/apache/rocketmq/ons/open/trace/core/utils/MixUtils.java
@@ -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.
+ */
+
+
+package org.apache.rocketmq.ons.open.trace.core.utils;
+
+import org.apache.rocketmq.remoting.protocol.RemotingSerializable;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+
+public class MixUtils {
+    public static String getLocalAddress() {
+        try {
+
+            Enumeration<NetworkInterface> enumeration = NetworkInterface.getNetworkInterfaces();
+            ArrayList<String> ipv4Result = new ArrayList<String>();
+            ArrayList<String> ipv6Result = new ArrayList<String>();
+            while (enumeration.hasMoreElements()) {
+                final NetworkInterface networkInterface = enumeration.nextElement();
+                final Enumeration<InetAddress> en = networkInterface.getInetAddresses();
+                while (en.hasMoreElements()) {
+                    final InetAddress address = en.nextElement();
+                    if (!address.isLoopbackAddress()) {
+                        if (address instanceof Inet6Address) {
+                            ipv6Result.add(normalizeHostAddress(address));
+                        }
+                        else {
+                            ipv4Result.add(normalizeHostAddress(address));
+                        }
+                    }
+                }
+            }
+
+
+            if (!ipv4Result.isEmpty()) {
+                for (String ip : ipv4Result) {
+                    if (ip.startsWith("127.0") || ip.startsWith("192.168")) {
+                        continue;
+                    }
+
+                    return ip;
+                }
+
+
+                return ipv4Result.get(ipv4Result.size() - 1);
+            }
+
+            else if (!ipv6Result.isEmpty()) {
+                return ipv6Result.get(0);
+            }
+
+            final InetAddress localHost = InetAddress.getLocalHost();
+            return normalizeHostAddress(localHost);
+        }
+        catch (SocketException e) {
+            e.printStackTrace();
+        }
+        catch (UnknownHostException e) {
+            e.printStackTrace();
+        }
+        finally {
+
+        }
+
+        return null;
+    }
+
+
+    public static String normalizeHostAddress(final InetAddress localHost) {
+        if (localHost instanceof Inet6Address) {
+            return "[" + localHost.getHostAddress() + "]";
+        }
+        else {
+            return localHost.getHostAddress();
+        }
+    }
+
+
+    public static String toJson(final Object obj, boolean prettyFormat) {
+        return RemotingSerializable.toJson(obj, prettyFormat);
+    }
+
+
+    public static <T> T fromJson(String json, Class<T> classOfT) {
+        return RemotingSerializable.fromJson(json, classOfT);
+    }
+
+
+    public static String replaceNull(String ori) {
+        return ori == null ? "" : ori;
+    }
+}
diff --git a/ons-core/pom.xml b/ons-core/pom.xml
new file mode 100644
index 0000000..edadb69
--- /dev/null
+++ b/ons-core/pom.xml
@@ -0,0 +1,271 @@
+<!--
+  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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <parent>
+        <groupId>org.apache.rocketmq</groupId>
+        <artifactId>ons-parent</artifactId>
+        <version>1.8.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <inceptionYear>2012</inceptionYear>
+    <artifactId>ons-all</artifactId>
+    <packaging>pom</packaging>
+    <name>ons-all ${project.version}</name>
+    <url>https://github.org.apache.rocketmq</url>
+    <description>https://github.com/alibaba/RocketMQ/blob/develop/README.md</description>
+    <modules>
+        <module>ons-client</module>
+        <module>ons-api</module>
+        <module>ons-trace-core</module>
+        <module>ons-auth4client</module>
+    </modules>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <!--maven properties -->
+        <maven.test.skip>true</maven.test.skip>
+        <maven.jdoc.skip>true</maven.jdoc.skip>
+        <downloadSources>true</downloadSources>
+        <!-- compiler settings properties -->
+        <java_source_version>1.6</java_source_version>
+        <java_target_version>1.6</java_target_version>
+        <file_encoding>UTF-8</file_encoding>
+        <!-- Always use stable version of RocketMQ -->
+        <rocketmq.version>4.5.1</rocketmq.version>
+        <auth.version>${project.version}</auth.version>
+        <spring.version>4.1.2.RELEASE</spring.version>
+        <diamond.version>3.7.4</diamond.version>
+    </properties>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>2.3.2</version>
+                <configuration>
+                    <source>${java_source_version}</source>
+                    <target>${java_target_version}</target>
+                    <encoding>${file_encoding}</encoding>
+                    <showDeprecation>true</showDeprecation>
+                    <showWarnings>true</showWarnings>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>2.3</version>
+                <configuration>
+                    <skip>${maven.test.skip}</skip>
+                    <argLine>-Xms512m -Xmx1024m</argLine>
+                    <forkMode>once</forkMode>
+                    <includes>
+                        <include>**/*Test.java</include>
+                    </includes>
+                    <excludes>
+                        <exclude>org.apache.rocketmq/remoting/ExceptionTest.java</exclude>
+                        <exclude>org.apache.rocketmq/remoting/SyncInvokeTest.java</exclude>
+                        <exclude>org.apache.rocketmq/remoting/NettyIdleTest.java</exclude>
+                        <exclude>org.apache.rocketmq/remoting/NettyConnectionTest.java</exclude>
+                        <exclude>org.apache.rocketmq/common/filter/PolishExprTest.java</exclude>
+                        <exclude>org.apache.rocketmq/common/protocol/MQProtosHelperTest.java</exclude>
+                        <exclude>
+                            org.apache.rocketmq/client/consumer/loadbalance/AllocateMessageQueueAveragelyTest.java
+                        </exclude>
+                        <exclude>org.apache.rocketmq/store/RecoverTest.java</exclude>
+                        <exclude>org.apache.rocketmq/broker/api/SendMessageTest.java</exclude>
+                        <exclude>org.apache.rocketmq/test/integration/*/*.java</exclude>
+                        <exclude>org.apache.rocketmq/test/integration/BaseTest.java</exclude>
+                        <exclude>org.apache.rocketmq/test/*/*.java</exclude>
+                        <exclude>org.apache.rocketmq/test/BaseTest.java</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <version>2.10.4</version>
+                <executions>
+                    <execution>
+                        <id>attach-javadocs</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <skip>${maven.jdoc.skip}</skip>
+                    <encoding>${file_encoding}</encoding>
+                    <charset>${file_encoding}</charset>
+                    <doclet>org.jboss.apiviz.APIviz</doclet>
+                    <docletArtifact>
+                        <groupId>org.jboss.apiviz</groupId>
+                        <artifactId>apiviz</artifactId>
+                        <version>1.3.2.GA</version>
+                    </docletArtifact>
+                    <useStandardDocletOptions>true</useStandardDocletOptions>
+                    <breakiterator>true</breakiterator>
+                    <version>true</version>
+                    <author>true</author>
+                    <keywords>true</keywords>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+                <version>2.1.2</version>
+                <executions>
+                    <execution>
+                        <id>attach-sources</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>false</filtering>
+            </resource>
+        </resources>
+    </build>
+    <profiles>
+        <profile>
+            <id>release-sign-artifacts</id>
+            <activation>
+                <property>
+                    <name>performRelease</name>
+                    <value>true</value>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-gpg-plugin</artifactId>
+                        <version>1.1</version>
+                        <executions>
+                            <execution>
+                                <id>sign-artifacts</id>
+                                <phase>verify</phase>
+                                <goals>
+                                    <goal>sign</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>rmq</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-assembly-plugin</artifactId>
+                        <configuration>
+                            <finalName>rmq</finalName>
+                            <descriptors>
+                                <descriptor>release.xml</descriptor>
+                            </descriptors>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+
+        <profile>
+            <id>ons-client</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-assembly-plugin</artifactId>
+                        <configuration>
+                            <finalName>rocketmq-ons-client</finalName>
+                            <descriptors>
+                                <descriptor>release-client.xml</descriptor>
+                            </descriptors>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.slf4j</groupId>
+                <artifactId>slf4j-api</artifactId>
+                <version>1.7.7</version>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>ons-api</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>ons-client</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>ons-trace-core</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.rocketmq</groupId>
+                <artifactId>rocketmq-client</artifactId>
+                <version>${rocketmq.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.rocketmq</groupId>
+                <artifactId>rocketmq-remoting</artifactId>
+                <version>${rocketmq.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.rocketmq</groupId>
+                <artifactId>rocketmq-common</artifactId>
+                <version>${rocketmq.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.rocketmq</groupId>
+                <artifactId>rocketmq-tools</artifactId>
+                <version>${rocketmq.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>ons-auth4client</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>ch.qos.logback</groupId>
+                <artifactId>logback-classic</artifactId>
+                <version>1.1.11</version>
+            </dependency>
+            <dependency>
+                <groupId>ch.qos.logback</groupId>
+                <artifactId>logback-core</artifactId>
+                <version>1.1.11</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+</project>
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..9718937
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,277 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <parent>
+      <groupId>org.apache</groupId>
+      <artifactId>apache</artifactId>
+      <version>18</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.rocketmq</groupId>
+    <artifactId>ons-parent</artifactId>
+    <version>1.8.1-SNAPSHOT</version>
+    <packaging>pom</packaging>
+    <name>ons-parent ${project.version}</name>
+    <description>
+        Apache RocketMQ lightweight client
+    </description>
+    <inceptionYear>2019</inceptionYear>
+    <licenses>
+        <license>
+            <name>The Apache Software License, Version 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+            <distribution>repo</distribution>
+        </license>
+    </licenses>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <file_encoding>UTF-8</file_encoding>
+        <!-- Compiler settings properties -->
+        <maven.compiler.source>1.7</maven.compiler.source>
+        <maven.compiler.target>1.7</maven.compiler.target>
+        <eagleeye.core.version>1.4.8</eagleeye.core.version>
+    </properties>
+    <modules>
+        <module>ons-core</module>
+    </modules>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>versions-maven-plugin</artifactId>
+                <version>2.3</version>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>clirr-maven-plugin</artifactId>
+                <version>2.7</version>
+            </plugin>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.6.1</version>
+                <configuration>
+                    <source>${maven.compiler.source}</source>
+                    <target>${maven.compiler.target}</target>
+                    <compilerVersion>${maven.compiler.source}</compilerVersion>
+                    <showDeprecation>true</showDeprecation>
+                    <showWarnings>true</showWarnings>
+                    <encoding>${file_encoding}</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>2.19.1</version>
+                <configuration>
+                    <argLine>-Xms512m -Xmx1024m</argLine>
+                    <forkMode>always</forkMode>
+                    <includes>
+                        <include>**/*Test.java</include>
+                    </includes>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-site-plugin</artifactId>
+                <version>3.6</version>
+                <configuration>
+                    <locales>en_US</locales>
+                    <outputEncoding>UTF-8</outputEncoding>
+                    <inputEncoding>UTF-8</inputEncoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-source-plugin</artifactId>
+                <version>3.0.1</version>
+                <executions>
+                    <execution>
+                        <id>attach-sources</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <version>2.10.4</version>
+                <configuration>
+                    <charset>UTF-8</charset>
+                    <locale>en_US</locale>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>aggregate</id>
+                        <goals>
+                            <goal>aggregate</goal>
+                        </goals>
+                        <phase>site</phase>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-resources-plugin</artifactId>
+                <version>3.0.2</version>
+                <configuration>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>findbugs-maven-plugin</artifactId>
+                <version>3.0.4</version>
+            </plugin>
+            <plugin>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <version>2.17</version>
+                <executions>
+                    <execution>
+                        <id>verify</id>
+                        <phase>verify</phase>
+                        <configuration>
+                            <configLocation>style/ons_checkstyle.xml</configLocation>
+                            <encoding>UTF-8</encoding>
+                            <consoleOutput>true</consoleOutput>
+                            <failsOnError>true</failsOnError>
+                            <includeTestSourceDirectory>false</includeTestSourceDirectory>
+                        </configuration>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>pl.project13.maven</groupId>
+                <artifactId>git-commit-id-plugin</artifactId>
+                <version>2.2.3</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>revision</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <prefix>git</prefix>
+                    <dateFormat>yyyy-MM-dd HH:mm:ss z</dateFormat>
+                    <failOnNoGitDirectory>false</failOnNoGitDirectory>
+                    <dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
+                    <skipPoms>false</skipPoms>
+                    <verbose>false</verbose>
+                    <generateGitPropertiesFile>false</generateGitPropertiesFile>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>3.0.2</version>
+                <configuration>
+                    <archive>
+                        <manifest>
+                            <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+                            <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+                            <addClasspath>false</addClasspath>
+                        </manifest>
+                        <manifestEntries>
+                            <Project-Version>${project.version}</Project-Version>
+                        </manifestEntries>
+                    </archive>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.slf4j</groupId>
+                <artifactId>slf4j-api</artifactId>
+                <version>1.7.7</version>
+            </dependency>
+            <dependency>
+                <groupId>ch.qos.logback</groupId>
+                <artifactId>logback-classic</artifactId>
+                <version>1.1.11</version>
+            </dependency>
+            <dependency>
+                <groupId>ch.qos.logback</groupId>
+                <artifactId>logback-core</artifactId>
+                <version>1.1.11</version>
+            </dependency>
+            <dependency>
+                <groupId>commons-codec</groupId>
+                <artifactId>commons-codec</artifactId>
+                <version>1.9</version>
+            </dependency>
+            <dependency>
+                <groupId>com.google.guava</groupId>
+                <artifactId>guava</artifactId>
+                <version>18.0</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.commons</groupId>
+                <artifactId>commons-lang3</artifactId>
+                <version>3.6</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.commons</groupId>
+                <artifactId>commons-csv</artifactId>
+                <version>1.5</version>
+            </dependency>
+            <dependency>
+                <groupId>commons-beanutils</groupId>
+                <artifactId>commons-beanutils</artifactId>
+                <version>1.9.3</version>
+            </dependency>
+            <dependency>
+                <groupId>com.alibaba</groupId>
+                <artifactId>fastjson</artifactId>
+                <version>1.2.50</version>
+            </dependency>
+            <dependency>
+                <groupId>junit</groupId>
+                <artifactId>junit</artifactId>
+                <version>4.11</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.assertj</groupId>
+                <artifactId>assertj-core</artifactId>
+                <version>2.6.0</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.mockito</groupId>
+                <artifactId>mockito-core</artifactId>
+                <version>2.6.3</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.mockito</groupId>
+                <artifactId>mockito-core</artifactId>
+                <version>2.6.3</version>
+                <scope>test</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+    <scm>
+        <url>git@gitlab.alibaba-inc.com:middleware/ons.git</url>
+        <connection>scm:git:git@gitlab.alibaba-inc.com:middleware/ons.git</connection>
+        <developerConnection>scm:git:git@gitlab.alibaba-inc.com:middleware/ons.git</developerConnection>
+    </scm>
+</project>
diff --git a/style/copyright/Apache.xml b/style/copyright/Apache.xml
new file mode 100644
index 0000000..e3e3dec
--- /dev/null
+++ b/style/copyright/Apache.xml
@@ -0,0 +1,23 @@
+<!--
+  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.
+  -->
+
+<component name="CopyrightManager">
+    <copyright>
+        <option name="myName" value="Apache" />
+        <option name="notice" value="Licensed to the Apache Software Foundation (ASF) under one or more&#10;contributor license agreements.  See the NOTICE file distributed with&#10;this work for additional information regarding copyright ownership.&#10;The ASF licenses this file to You under the Apache License, Version 2.0&#10;(the &quot;License&quot;); you may not use this file except in compliance with&#10;the License.  You may obtain a copy of the License at&#10;&#10;    http://www.a [...]
+    </copyright>
+</component>
\ No newline at end of file
diff --git a/style/copyright/profiles_settings.xml b/style/copyright/profiles_settings.xml
new file mode 100644
index 0000000..747c7e2
--- /dev/null
+++ b/style/copyright/profiles_settings.xml
@@ -0,0 +1,64 @@
+<!--
+  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.
+  -->
+
+<component name="CopyrightManager">
+    <settings default="Apache">
+        <module2copyright>
+            <element module="All" copyright="Apache"/>
+        </module2copyright>
+        <LanguageOptions name="GSP">
+            <option name="fileTypeOverride" value="3"/>
+            <option name="prefixLines" value="false"/>
+        </LanguageOptions>
+        <LanguageOptions name="HTML">
+            <option name="fileTypeOverride" value="3"/>
+            <option name="prefixLines" value="false"/>
+        </LanguageOptions>
+        <LanguageOptions name="JAVA">
+            <option name="fileTypeOverride" value="3" />
+            <option name="addBlankAfter" value="false" />
+        </LanguageOptions>
+        <LanguageOptions name="JSP">
+            <option name="fileTypeOverride" value="3"/>
+            <option name="prefixLines" value="false"/>
+        </LanguageOptions>
+        <LanguageOptions name="JSPX">
+            <option name="fileTypeOverride" value="3"/>
+            <option name="prefixLines" value="false"/>
+        </LanguageOptions>
+        <LanguageOptions name="MXML">
+            <option name="fileTypeOverride" value="3"/>
+            <option name="prefixLines" value="false"/>
+        </LanguageOptions>
+        <LanguageOptions name="Properties">
+            <option name="fileTypeOverride" value="3"/>
+            <option name="block" value="false"/>
+        </LanguageOptions>
+        <LanguageOptions name="SPI">
+            <option name="fileTypeOverride" value="3"/>
+            <option name="block" value="false"/>
+        </LanguageOptions>
+        <LanguageOptions name="XML">
+            <option name="fileTypeOverride" value="3"/>
+            <option name="prefixLines" value="false"/>
+        </LanguageOptions>
+        <LanguageOptions name="__TEMPLATE__">
+            <option name="separateBefore" value="true"/>
+            <option name="lenBefore" value="1"/>
+        </LanguageOptions>
+    </settings>
+</component>
\ No newline at end of file
diff --git a/style/ons_checkstyle.xml b/style/ons_checkstyle.xml
new file mode 100644
index 0000000..3b682af
--- /dev/null
+++ b/style/ons_checkstyle.xml
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<!DOCTYPE module PUBLIC
+    "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
+    "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
+<!--Refer http://checkstyle.sourceforge.net/reports/google-java-style.html#s2.2-file-encoding -->
+<module name="Checker">
+
+    <property name="localeLanguage" value="en"/>
+
+    <!--To configure the check to report on the first instance in each file-->
+    <module name="FileTabCharacter"/>
+
+    <!-- header -->
+    <module name="RegexpHeader">
+        <property name="header" value="/\*\nLicensed to the Apache Software Foundation*"/>
+        <property name="fileExtensions" value="java"/>
+    </module>
+
+    <module name="RegexpHeader">
+        <property name="header" value="#[\s]*Licensed to the Apache Software Foundation*"/>
+        <property name="fileExtensions" value="properties"/>
+    </module>
+
+    <module name="RegexpSingleline">
+        <property name="format" value="System\.out\.println"/>
+        <property name="message" value="Prohibit invoking System.out.println in source code !"/>
+    </module>
+
+    <module name="RegexpSingleline">
+        <property name="format" value="//FIXME"/>
+        <property name="message" value="Recommended fix FIXME task !"/>
+    </module>
+
+    <module name="RegexpSingleline">
+        <property name="format" value="//TODO"/>
+        <property name="message" value="Recommended fix TODO task !"/>
+    </module>
+
+    <module name="RegexpSingleline">
+        <property name="format" value="@alibaba"/>
+        <property name="message" value="Recommended remove @alibaba keyword!"/>
+    </module>
+    <module name="RegexpSingleline">
+        <property name="format" value="@taobao"/>
+        <property name="message" value="Recommended remove @taobao keyword!"/>
+    </module>
+    <module name="RegexpSingleline">
+        <property name="format" value="@author"/>
+        <property name="message" value="Recommended remove @author tag in javadoc!"/>
+    </module>
+
+    <module name="RegexpSingleline">
+        <property name="format"
+                  value=".*[\u3400-\u4DB5\u4E00-\u9FA5\u9FA6-\u9FBB\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9\uFF00-\uFFEF\u2E80-\u2EFF\u3000-\u303F\u31C0-\u31EF]+.*"/>
+        <property name="message" value="Not allow chinese character !"/>
+    </module>
+
+    <module name="FileLength">
+        <property name="max" value="3000"/>
+    </module>
+
+    <module name="TreeWalker">
+
+        <module name="UnusedImports">
+            <property name="processJavadoc" value="true"/>
+        </module>
+        <module name="RedundantImport"/>
+
+        <!--<module name="IllegalImport" />-->
+
+        <!--Checks that classes that override equals() also override hashCode()-->
+        <module name="EqualsHashCode"/>
+        <!--Checks for over-complicated boolean expressions. Currently finds code like if (topic == true), topic || true, !false, etc.-->
+        <module name="SimplifyBooleanExpression"/>
+        <module name="OneStatementPerLine"/>
+        <module name="UnnecessaryParentheses"/>
+        <!--Checks for over-complicated boolean return statements. For example the following code-->
+        <module name="SimplifyBooleanReturn"/>
+
+        <!--Check that the default is after all the cases in producerGroup switch statement-->
+        <module name="DefaultComesLast"/>
+        <!--Detects empty statements (standalone ";" semicolon)-->
+        <module name="EmptyStatement"/>
+        <!--Checks that long constants are defined with an upper ell-->
+        <module name="UpperEll"/>
+        <!--Checks that local, non-final variable names conform to producerGroup format specified by the format property-->
+        <module name="LocalVariableName"/>
+        <!--Validates identifiers for local, final variables, including catch parameters-->
+        <module name="LocalFinalVariableName"/>
+        <!--Validates identifiers for non-static fields-->
+        <module name="MemberName"/>
+        <!--Validates identifiers for class type parameters-->
+        <module name="ClassTypeParameterName">
+            <property name="format" value="^[A-Z0-9]*$"/>
+        </module>
+        <!--Validates identifiers for method type parameters-->
+        <module name="MethodTypeParameterName">
+            <property name="format" value="^[A-Z0-9]*$"/>
+        </module>
+        <module name="PackageName"/>
+        <module name="ParameterName"/>
+        <module name="StaticVariableName"/>
+        <module name="TypeName"/>
+        <!--Checks that there are no import statements that use the * notation-->
+        <module name="AvoidStarImport"/>
+
+        <!--whitespace-->
+        <module name="GenericWhitespace"/>
+        <!--<module name="NoWhitespaceBefore"/>-->
+        <!--<module name="NoWhitespaceAfter"/>-->
+        <module name="WhitespaceAround">
+            <property name="allowEmptyConstructors" value="true"/>
+            <property name="allowEmptyMethods" value="true"/>
+        </module>
+        <module name="Indentation"/>
+        <module name="MethodParamPad"/>
+        <module name="ParenPad"/>
+        <module name="TypecastParenPad"/>
+    </module>
+</module>
diff --git a/style/ons_codeStyle.xml b/style/ons_codeStyle.xml
new file mode 100644
index 0000000..7c7ce54
--- /dev/null
+++ b/style/ons_codeStyle.xml
@@ -0,0 +1,143 @@
+<!--
+  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.
+  -->
+
+<code_scheme name="rocketmq">
+    <option name="USE_SAME_INDENTS" value="true"/>
+    <option name="IGNORE_SAME_INDENTS_FOR_LANGUAGES" value="true"/>
+    <option name="OTHER_INDENT_OPTIONS">
+        <value>
+            <option name="INDENT_SIZE" value="4"/>
+            <option name="CONTINUATION_INDENT_SIZE" value="4"/>
+            <option name="TAB_SIZE" value="4"/>
+            <option name="USE_TAB_CHARACTER" value="false"/>
+            <option name="SMART_TABS" value="false"/>
+            <option name="LABEL_INDENT_SIZE" value="0"/>
+            <option name="LABEL_INDENT_ABSOLUTE" value="false"/>
+            <option name="USE_RELATIVE_INDENTS" value="false"/>
+        </value>
+    </option>
+    <option name="PREFER_LONGER_NAMES" value="false"/>
+    <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="1000"/>
+    <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="1000"/>
+    <option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
+        <value/>
+    </option>
+    <option name="IMPORT_LAYOUT_TABLE">
+        <value>
+            <package name="" withSubpackages="true" static="false"/>
+            <emptyLine/>
+            <package name="" withSubpackages="true" static="true"/>
+        </value>
+    </option>
+    <option name="JD_ALIGN_PARAM_COMMENTS" value="false"/>
+    <option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false"/>
+    <option name="JD_P_AT_EMPTY_LINES" value="false"/>
+    <option name="JD_KEEP_INVALID_TAGS" value="false"/>
+    <option name="JD_DO_NOT_WRAP_ONE_LINE_COMMENTS" value="true"/>
+    <option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
+    <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1"/>
+    <option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
+    <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
+    <option name="WHILE_ON_NEW_LINE" value="true"/>
+    <option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
+    <option name="ALIGN_MULTILINE_FOR" value="false"/>
+    <option name="SPACE_AFTER_TYPE_CAST" value="true"/>
+    <option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true"/>
+    <option name="METHOD_PARAMETERS_WRAP" value="1"/>
+    <option name="ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE" value="true"/>
+    <option name="LABELED_STATEMENT_WRAP" value="1"/>
+    <option name="WRAP_COMMENTS" value="true"/>
+    <option name="METHOD_ANNOTATION_WRAP" value="1"/>
+    <option name="CLASS_ANNOTATION_WRAP" value="1"/>
+    <option name="FIELD_ANNOTATION_WRAP" value="1"/>
+    <JavaCodeStyleSettings>
+        <option name="CLASS_NAMES_IN_JAVADOC" value="3"/>
+    </JavaCodeStyleSettings>
+    <XML>
+        <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true"/>
+    </XML>
+    <ADDITIONAL_INDENT_OPTIONS fileType="haml">
+        <option name="INDENT_SIZE" value="2"/>
+    </ADDITIONAL_INDENT_OPTIONS>
+    <codeStyleSettings language="Groovy">
+        <option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
+        <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1"/>
+        <option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
+        <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
+        <option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
+        <option name="ALIGN_MULTILINE_FOR" value="false"/>
+        <option name="METHOD_PARAMETERS_WRAP" value="1"/>
+        <option name="METHOD_ANNOTATION_WRAP" value="1"/>
+        <option name="CLASS_ANNOTATION_WRAP" value="1"/>
+        <option name="FIELD_ANNOTATION_WRAP" value="1"/>
+        <option name="PARENT_SETTINGS_INSTALLED" value="true"/>
+        <indentOptions>
+            <option name="CONTINUATION_INDENT_SIZE" value="4"/>
+        </indentOptions>
+    </codeStyleSettings>
+    <codeStyleSettings language="HOCON">
+        <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
+        <option name="PARENT_SETTINGS_INSTALLED" value="true"/>
+    </codeStyleSettings>
+    <codeStyleSettings language="JAVA">
+        <option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
+        <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1"/>
+        <option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
+        <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
+        <option name="WHILE_ON_NEW_LINE" value="true"/>
+        <option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
+        <option name="ALIGN_MULTILINE_FOR" value="false"/>
+        <option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true"/>
+        <option name="METHOD_PARAMETERS_WRAP" value="1"/>
+        <option name="ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE" value="true"/>
+        <option name="LABELED_STATEMENT_WRAP" value="1"/>
+        <option name="METHOD_ANNOTATION_WRAP" value="1"/>
+        <option name="CLASS_ANNOTATION_WRAP" value="1"/>
+        <option name="FIELD_ANNOTATION_WRAP" value="1"/>
+        <option name="PARENT_SETTINGS_INSTALLED" value="true"/>
+        <indentOptions>
+            <option name="CONTINUATION_INDENT_SIZE" value="4"/>
+        </indentOptions>
+    </codeStyleSettings>
+    <codeStyleSettings language="JSON">
+        <option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
+        <option name="PARENT_SETTINGS_INSTALLED" value="true"/>
+    </codeStyleSettings>
+    <codeStyleSettings language="Scala">
+        <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1"/>
+        <option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
+        <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
+        <option name="WHILE_ON_NEW_LINE" value="true"/>
+        <option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
+        <option name="ALIGN_MULTILINE_FOR" value="false"/>
+        <option name="METHOD_PARAMETERS_WRAP" value="1"/>
+        <option name="METHOD_ANNOTATION_WRAP" value="1"/>
+        <option name="CLASS_ANNOTATION_WRAP" value="1"/>
+        <option name="FIELD_ANNOTATION_WRAP" value="1"/>
+        <option name="PARENT_SETTINGS_INSTALLED" value="true"/>
+        <indentOptions>
+            <option name="INDENT_SIZE" value="4"/>
+            <option name="CONTINUATION_INDENT_SIZE" value="4"/>
+            <option name="TAB_SIZE" value="4"/>
+        </indentOptions>
+    </codeStyleSettings>
+    <codeStyleSettings language="XML">
+        <indentOptions>
+            <option name="CONTINUATION_INDENT_SIZE" value="4"/>
+        </indentOptions>
+    </codeStyleSettings>
+</code_scheme>
\ No newline at end of file


[rocketmq-ons] 08/29: Merge pull request #2 from ShannonDing/fix_async_send

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit 4a72b449741769f9e59f61e3a3a652c10630ffba
Merge: e28b1a9 2a87d33
Author: Heng Du <du...@gmail.com>
AuthorDate: Mon Jun 17 17:37:21 2019 +0800

    Merge pull request #2 from ShannonDing/fix_async_send
    
    Call onException instead when async sending with NULL topic

 .../apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java    | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)


[rocketmq-ons] 23/29: (1) Polish existed ons api (2) Add pull consumer Implementation

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit f14be542b1f9f02c225cdb179c97b1b517450d44
Author: duhenglucky <du...@gmail.com>
AuthorDate: Wed Jul 17 13:55:00 2019 +0800

    (1) Polish existed ons api (2) Add pull consumer Implementation
---
 .../java/org/apache/rocketmq/ons/api/Admin.java    | 18 +---------------
 .../java/org/apache/rocketmq/ons/api/Consumer.java |  5 +----
 .../ons/api/{Admin.java => Credentials.java}       | 17 +--------------
 .../ons/api/{Admin.java => LifeCycle.java}         | 15 ++------------
 ...alTransactionChecker.java => MessageQueue.java} |  9 ++------
 .../java/org/apache/rocketmq/ons/api/Producer.java | 14 ++++++-------
 .../ons/api/{Admin.java => PullConsumer.java}      | 24 +++++++++++++++-------
 .../rocketmq/ons/api/batch/BatchConsumer.java      |  5 +++--
 .../apache/rocketmq/ons/api/bean/ProducerBean.java | 11 ++++++++++
 .../ons/api/bean/TransactionProducerBean.java      |  4 ++--
 .../rocketmq/ons/api/order/OrderConsumer.java      |  6 +++---
 .../rocketmq/ons/api/order/OrderProducer.java      | 11 +++++++---
 .../api/transaction/LocalTransactionChecker.java   |  2 ++
 ...Executer.java => LocalTransactionExecutor.java} |  4 ++--
 .../ons/api/transaction/TransactionProducer.java   | 16 ++++-----------
 .../ons/api/impl/rocketmq/ProducerImpl.java        |  9 ++++++++
 .../api/impl/rocketmq/TransactionProducerImpl.java |  4 ++--
 .../sample/producer/SimpleTransactionProducer.java |  5 +++--
 18 files changed, 79 insertions(+), 100 deletions(-)

diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Admin.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Admin.java
index 702d9a5..46f1e79 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Admin.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Admin.java
@@ -16,22 +16,6 @@
  */
 package org.apache.rocketmq.ons.api;
 
-import java.util.Properties;
+public interface Admin extends LifeCycle, Credentials {
 
-
-public interface Admin {
-
-    boolean isStarted();
-
-
-    boolean isClosed();
-
-
-    void start();
-
-
-    void updateCredential(Properties credentialProperties);
-
-
-    void shutdown();
 }
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Consumer.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Consumer.java
index a592559..03d8f7c 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Consumer.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Consumer.java
@@ -16,14 +16,11 @@
  */
 package org.apache.rocketmq.ons.api;
 
-
-public interface Consumer extends Admin {
+public interface Consumer extends LifeCycle, Credentials {
 
     void subscribe(final String topic, final String subExpression, final MessageListener listener);
 
-
     void subscribe(final String topic, final MessageSelector selector, final MessageListener listener);
 
-
     void unsubscribe(final String topic);
 }
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Admin.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Credentials.java
similarity index 88%
copy from ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Admin.java
copy to ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Credentials.java
index 702d9a5..08a90c8 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Admin.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Credentials.java
@@ -15,23 +15,8 @@
  * limitations under the License.
  */
 package org.apache.rocketmq.ons.api;
-
 import java.util.Properties;
 
-
-public interface Admin {
-
-    boolean isStarted();
-
-
-    boolean isClosed();
-
-
-    void start();
-
-
+public interface Credentials {
     void updateCredential(Properties credentialProperties);
-
-
-    void shutdown();
 }
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Admin.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/LifeCycle.java
similarity index 84%
copy from ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Admin.java
copy to ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/LifeCycle.java
index 702d9a5..51d96c4 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Admin.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/LifeCycle.java
@@ -1,4 +1,4 @@
-/*
+package org.apache.rocketmq.ons.api;/*
  * 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.
@@ -14,24 +14,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.rocketmq.ons.api;
-
-import java.util.Properties;
-
-
-public interface Admin {
 
+public interface LifeCycle {
     boolean isStarted();
 
-
     boolean isClosed();
 
-
     void start();
 
-
-    void updateCredential(Properties credentialProperties);
-
-
     void shutdown();
 }
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/LocalTransactionChecker.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageQueue.java
similarity index 81%
copy from ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/LocalTransactionChecker.java
copy to ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageQueue.java
index eb46593..00f8b2d 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/LocalTransactionChecker.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageQueue.java
@@ -14,11 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.rocketmq.ons.api.transaction;
-
-import org.apache.rocketmq.ons.api.Message;
-
-public interface LocalTransactionChecker {
-
-    TransactionStatus check(final Message msg);
+package org.apache.rocketmq.ons.api;
+public class MessageQueue {
 }
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Producer.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Producer.java
index e45e613..3bd1a0d 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Producer.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Producer.java
@@ -16,16 +16,10 @@
  */
 package org.apache.rocketmq.ons.api;
 
+import java.util.Collection;
 import java.util.concurrent.ExecutorService;
 
-public interface Producer extends Admin {
-
-
-    @Override
-    void start();
-
-    @Override
-    void shutdown();
+public interface Producer extends LifeCycle, Credentials {
 
     SendResult send(final Message message);
 
@@ -34,4 +28,8 @@ public interface Producer extends Admin {
     void sendAsync(final Message message, final SendCallback sendCallback);
 
     void setCallbackExecutor(final ExecutorService callbackExecutor);
+
+    SendResult send(final Message message, final String shardingKey);
+
+    SendResult send(final Collection<Message> messages);
 }
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Admin.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PullConsumer.java
similarity index 54%
copy from ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Admin.java
copy to ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PullConsumer.java
index 702d9a5..abdd966 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Admin.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PullConsumer.java
@@ -16,22 +16,32 @@
  */
 package org.apache.rocketmq.ons.api;
 
-import java.util.Properties;
+import java.util.Collection;
+import java.util.List;
 
+public interface PullConsumer {
 
-public interface Admin {
+    void subscribe(final Collection<String> topics);
 
-    boolean isStarted();
+    void subscribe(final Collection<String> topics, final String subExpression);
 
+    void unsubscribe(final Collection<String> topics);
 
-    boolean isClosed();
+    List<Message> poll(long timeout);
 
+    void seek(MessageQueue messageQueue, long offset);
 
-    void start();
+    void seekToBeginning(MessageQueue messageQueue);
 
+    void seekToEnd(MessageQueue messageQueuea);
 
-    void updateCredential(Properties credentialProperties);
+    void pause(Collection<MessageQueue> messageQueues);
 
+    void resume(Collection<MessageQueue> partitions);
 
-    void shutdown();
+    Long offsetForTimestamp(MessageQueue messageQueue, Long timestamp);
+
+    Long committed(MessageQueue messageQueue);
+
+    void commitSync();
 }
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/batch/BatchConsumer.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/batch/BatchConsumer.java
index 848a139..d5887bc 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/batch/BatchConsumer.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/batch/BatchConsumer.java
@@ -17,9 +17,10 @@
 
 package org.apache.rocketmq.ons.api.batch;
 
-import org.apache.rocketmq.ons.api.Admin;
+import org.apache.rocketmq.ons.api.Credentials;
+import org.apache.rocketmq.ons.api.LifeCycle;
 
-public interface BatchConsumer extends Admin {
+public interface BatchConsumer extends LifeCycle, Credentials {
 
     void subscribe(final String topic, final String subExpression, final BatchMessageListener listener);
 
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/ProducerBean.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/ProducerBean.java
index 2094158..548cc82 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/ProducerBean.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/ProducerBean.java
@@ -17,6 +17,7 @@
 
 package org.apache.rocketmq.ons.api.bean;
 
+import java.util.Collection;
 import java.util.Properties;
 import java.util.concurrent.ExecutorService;
 import org.apache.rocketmq.ons.api.Message;
@@ -95,4 +96,14 @@ public class ProducerBean implements Producer {
     public boolean isClosed() {
         return this.producer.isClosed();
     }
+
+    @Override public SendResult send(Message message, String shardingKey) {
+        //TODO
+        return null;
+    }
+
+    @Override public SendResult send(Collection<Message> messages) {
+        //TODO
+        return null;
+    }
 }
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/TransactionProducerBean.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/TransactionProducerBean.java
index cb55e14..ddf513c 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/TransactionProducerBean.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/TransactionProducerBean.java
@@ -23,7 +23,7 @@ import org.apache.rocketmq.ons.api.ONSFactory;
 import org.apache.rocketmq.ons.api.SendResult;
 import org.apache.rocketmq.ons.api.exception.ONSClientException;
 import org.apache.rocketmq.ons.api.transaction.LocalTransactionChecker;
-import org.apache.rocketmq.ons.api.transaction.LocalTransactionExecuter;
+import org.apache.rocketmq.ons.api.transaction.LocalTransactionExecutor;
 import org.apache.rocketmq.ons.api.transaction.TransactionProducer;
 
 
@@ -63,7 +63,7 @@ public class TransactionProducerBean implements TransactionProducer {
     }
 
     @Override
-    public SendResult send(Message message, LocalTransactionExecuter executer, Object arg) {
+    public SendResult send(Message message, LocalTransactionExecutor executer, Object arg) {
         return this.transactionProducer.send(message, executer, arg);
     }
 
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderConsumer.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderConsumer.java
index 4e73c1b..09b9127 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderConsumer.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderConsumer.java
@@ -17,11 +17,11 @@
 
 package org.apache.rocketmq.ons.api.order;
 
-import org.apache.rocketmq.ons.api.Admin;
+import org.apache.rocketmq.ons.api.Credentials;
+import org.apache.rocketmq.ons.api.LifeCycle;
 import org.apache.rocketmq.ons.api.MessageSelector;
 
-
-public interface OrderConsumer extends Admin {
+public interface OrderConsumer extends LifeCycle, Credentials {
 
     @Override
     void start();
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderProducer.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderProducer.java
index 4e9a0bb..25df1d0 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderProducer.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderProducer.java
@@ -17,12 +17,17 @@
 
 package org.apache.rocketmq.ons.api.order;
 
-import org.apache.rocketmq.ons.api.Admin;
+import org.apache.rocketmq.ons.api.Credentials;
+import org.apache.rocketmq.ons.api.LifeCycle;
 import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.Producer;
 import org.apache.rocketmq.ons.api.SendResult;
 
-
-public interface OrderProducer extends Admin {
+/**
+ * This interface will be removed in the year 2021, {@link Producer#send(Message, String)} is recommended
+ */
+@Deprecated
+public interface OrderProducer extends LifeCycle, Credentials {
 
     SendResult send(final Message message, final String shardingKey);
 }
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/LocalTransactionChecker.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/LocalTransactionChecker.java
index eb46593..cb3aa0a 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/LocalTransactionChecker.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/LocalTransactionChecker.java
@@ -21,4 +21,6 @@ import org.apache.rocketmq.ons.api.Message;
 public interface LocalTransactionChecker {
 
     TransactionStatus check(final Message msg);
+
+
 }
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/LocalTransactionExecuter.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/LocalTransactionExecutor.java
similarity index 88%
rename from ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/LocalTransactionExecuter.java
rename to ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/LocalTransactionExecutor.java
index f3fe785..fad6493 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/LocalTransactionExecuter.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/LocalTransactionExecutor.java
@@ -20,7 +20,7 @@ package org.apache.rocketmq.ons.api.transaction;
 import org.apache.rocketmq.ons.api.Message;
 
 
-public interface LocalTransactionExecuter {
+public interface LocalTransactionExecutor {
 
-    TransactionStatus execute(final Message msg, final Object arg);
+    TransactionStatus execute(final Message message, final Object arg);
 }
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/TransactionProducer.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/TransactionProducer.java
index c139db1..f9878a4 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/TransactionProducer.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/transaction/TransactionProducer.java
@@ -17,22 +17,14 @@
 
 package org.apache.rocketmq.ons.api.transaction;
 
-import org.apache.rocketmq.ons.api.Admin;
+import org.apache.rocketmq.ons.api.Credentials;
+import org.apache.rocketmq.ons.api.LifeCycle;
 import org.apache.rocketmq.ons.api.Message;
 import org.apache.rocketmq.ons.api.SendResult;
 
-
-public interface TransactionProducer extends Admin {
-
-    @Override
-    void start();
-
-
-    @Override
-    void shutdown();
-
+public interface TransactionProducer extends LifeCycle, Credentials {
 
     SendResult send(final Message message,
-        final LocalTransactionExecuter executer,
+        final LocalTransactionExecutor executer,
         final Object arg);
 }
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java
index cfbe212..2b6280a 100644
--- a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java
@@ -17,6 +17,7 @@
 
 package org.apache.rocketmq.ons.api.impl.rocketmq;
 
+import java.util.Collection;
 import java.util.Properties;
 import java.util.concurrent.ExecutorService;
 
@@ -219,6 +220,14 @@ public class ProducerImpl extends ONSClientAbstract implements Producer {
         return sendResult;
     }
 
+    @Override public SendResult send(Message message, String shardingKey) {
+        return null;
+    }
+
+    @Override public SendResult send(Collection<Message> messages) {
+        return null;
+    }
+
     private ONSClientException checkProducerException(String topic, String msgId, Throwable e) {
         if (e instanceof MQClientException) {
             if (e.getCause() != null) {
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/TransactionProducerImpl.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/TransactionProducerImpl.java
index 13ed7e4..abcf954 100644
--- a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/TransactionProducerImpl.java
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/TransactionProducerImpl.java
@@ -31,7 +31,7 @@ import org.apache.rocketmq.ons.api.PropertyKeyConst;
 import org.apache.rocketmq.ons.api.SendResult;
 import org.apache.rocketmq.ons.api.impl.tracehook.OnsClientSendMessageHookImpl;
 import org.apache.rocketmq.ons.api.impl.util.ClientLoggerUtil;
-import org.apache.rocketmq.ons.api.transaction.LocalTransactionExecuter;
+import org.apache.rocketmq.ons.api.transaction.LocalTransactionExecutor;
 import org.apache.rocketmq.ons.api.transaction.TransactionProducer;
 import org.apache.rocketmq.ons.api.transaction.TransactionStatus;
 import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceConstants;
@@ -123,7 +123,7 @@ public class TransactionProducerImpl extends ONSClientAbstract implements Transa
     }
 
     @Override
-    public SendResult send(final Message message, final LocalTransactionExecuter executer, Object arg) {
+    public SendResult send(final Message message, final LocalTransactionExecutor executer, Object arg) {
         this.checkONSProducerServiceState(this.transactionMQProducer.getDefaultMQProducerImpl());
         org.apache.rocketmq.common.message.Message msgRMQ = ONSUtil.msgConvert(message);
         org.apache.rocketmq.client.producer.TransactionSendResult sendResultRMQ = null;
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleTransactionProducer.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleTransactionProducer.java
index 4d16d51..992bd3b 100644
--- a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleTransactionProducer.java
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleTransactionProducer.java
@@ -23,7 +23,7 @@ import org.apache.rocketmq.ons.api.ONSFactory;
 import org.apache.rocketmq.ons.api.PropertyKeyConst;
 import org.apache.rocketmq.ons.api.SendResult;
 import org.apache.rocketmq.ons.api.exception.ONSClientException;
-import org.apache.rocketmq.ons.api.transaction.LocalTransactionExecuter;
+import org.apache.rocketmq.ons.api.transaction.LocalTransactionExecutor;
 import org.apache.rocketmq.ons.api.transaction.TransactionProducer;
 import org.apache.rocketmq.ons.api.transaction.TransactionStatus;
 import org.apache.rocketmq.ons.sample.MQConfig;
@@ -44,12 +44,13 @@ public class SimpleTransactionProducer {
 
         for (int i = 0; i < 10; i++) {
             try {
-                SendResult sendResult = transactionProducer.send(message, new LocalTransactionExecuter() {
+                SendResult sendResult = transactionProducer.send(message, new LocalTransactionExecutor() {
                     @Override
                     public TransactionStatus execute(Message msg, Object arg) {
                         System.out.printf("Execute local transaction and return TransactionStatus. %n");
                         return TransactionStatus.CommitTransaction;
                     }
+
                 }, null);
                 assert sendResult != null;
             } catch (ONSClientException e) {


[rocketmq-ons] 18/29: Remove System.out.println in sample and changed to standarded apache license

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit 9cb0ab2ef356a773d4ec238c2df8104a7bb29af5
Author: duhenglucky <du...@gmail.com>
AuthorDate: Fri Jul 12 10:02:48 2019 +0800

    Remove System.out.println in sample and changed to standarded apache license
---
 .../org/apache/rocketmq/ons/sample/MQConfig.java   | 19 +++++++--------
 .../ons/sample/consumer/MessageListenerImpl.java   | 22 +++++++++---------
 .../ons/sample/consumer/SimpleMQConsumer.java      | 22 +++++++++---------
 .../ons/sample/consumer/SimpleOrderConsumer.java   | 25 ++++++++++----------
 .../producer/LocalTransactionCheckerImpl.java      | 22 +++++++++---------
 .../ons/sample/producer/MQTimerProducer.java       | 26 ++++++++++-----------
 .../ons/sample/producer/SimpleMQProducer.java      | 27 +++++++++++-----------
 .../ons/sample/producer/SimpleOrderProducer.java   | 26 ++++++++++-----------
 .../sample/producer/SimpleTransactionProducer.java | 25 ++++++++++----------
 9 files changed, 108 insertions(+), 106 deletions(-)

diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/MQConfig.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/MQConfig.java
index a7d8094..2ef0e44 100644
--- a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/MQConfig.java
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/MQConfig.java
@@ -1,12 +1,13 @@
-/**
- * Copyright (C) 2010-2016 Alibaba Group Holding Limited
- * <p>
- * Licensed 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
+/*
+ * 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.
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/MessageListenerImpl.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/MessageListenerImpl.java
index f8e8ec1..1205ce9 100644
--- a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/MessageListenerImpl.java
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/MessageListenerImpl.java
@@ -1,12 +1,13 @@
-/**
- * Copyright (C) 2010-2016 Alibaba Group Holding Limited
- * <p>
- * Licensed 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
+/*
+ * 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.
@@ -15,7 +16,6 @@
  */
 package org.apache.rocketmq.ons.sample.consumer;
 
-import java.util.Date;
 import org.apache.rocketmq.ons.api.Action;
 import org.apache.rocketmq.ons.api.ConsumeContext;
 import org.apache.rocketmq.ons.api.Message;
@@ -24,7 +24,7 @@ import org.apache.rocketmq.ons.api.MessageListener;
 public class MessageListenerImpl implements MessageListener {
     @Override
     public Action consume(Message message, ConsumeContext consumeContext) {
-        System.out.println(new Date() + " Receive message, Topic is:" + message.getTopic() + ", MsgId is:" + message.getMsgID());
+        System.out.printf("Receive message, Topic is: %s,  MsgId is: %s%n", message.getTopic(), message.getMsgID());
         return Action.CommitMessage;
     }
 }
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/SimpleMQConsumer.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/SimpleMQConsumer.java
index 4c4f58b..df95829 100644
--- a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/SimpleMQConsumer.java
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/SimpleMQConsumer.java
@@ -1,12 +1,13 @@
-/**
- * Copyright (C) 2010-2016 Alibaba Group Holding Limited
- * <p>
- * Licensed 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
+/*
+ * 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.
@@ -33,9 +34,8 @@ public class SimpleMQConsumer {
         Consumer consumer = ONSFactory.createConsumer(consumerProperties);
         consumer.subscribe(MQConfig.TOPIC, MQConfig.TAG, new MessageListenerImpl());
         consumer.start();
-        System.out.println("Consumer start success.");
+        System.out.printf("Consumer start success. %n");
 
-        //等待固定时间防止进程退出
         try {
             Thread.sleep(200000);
         } catch (InterruptedException e) {
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/SimpleOrderConsumer.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/SimpleOrderConsumer.java
index ea5159f..b51a6a0 100644
--- a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/SimpleOrderConsumer.java
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/SimpleOrderConsumer.java
@@ -1,12 +1,13 @@
-/**
- * Copyright (C) 2010-2016 Alibaba Group Holding Limited
- * <p>
- * Licensed 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
+/*
+ * 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.
@@ -34,16 +35,16 @@ public class SimpleOrderConsumer {
         consumerProperties.setProperty(PropertyKeyConst.SecretKey, MQConfig.SECRET_KEY);
         consumerProperties.setProperty(PropertyKeyConst.NAMESRV_ADDR, MQConfig.NAMESRV_ADDR);
         OrderConsumer consumer = ONSFactory.createOrderedConsumer(consumerProperties);
-        consumer.subscribe(MQConfig.ORDER_TOPIC, MQConfig.TAG,  new MessageOrderListener() {
+        consumer.subscribe(MQConfig.ORDER_TOPIC, MQConfig.TAG, new MessageOrderListener() {
 
             @Override
             public OrderAction consume(final Message message, final ConsumeOrderContext context) {
-                System.out.println(message);
+                System.out.printf("Received message: %s%n", message);
                 return OrderAction.Success;
             }
         });
         consumer.start();
-        System.out.println("Consumer start success.");
+        System.out.printf("Consumer start success. %n");
 
         try {
             Thread.sleep(200000);
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/LocalTransactionCheckerImpl.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/LocalTransactionCheckerImpl.java
index f5dbd1a..f21db81 100644
--- a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/LocalTransactionCheckerImpl.java
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/LocalTransactionCheckerImpl.java
@@ -1,12 +1,13 @@
-/**
- * Copyright (C) 2010-2016 Alibaba Group Holding Limited
- * <p>
- * Licensed 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
+/*
+ * 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.
@@ -19,12 +20,11 @@ import org.apache.rocketmq.ons.api.Message;
 import org.apache.rocketmq.ons.api.transaction.LocalTransactionChecker;
 import org.apache.rocketmq.ons.api.transaction.TransactionStatus;
 
-
 public class LocalTransactionCheckerImpl implements LocalTransactionChecker {
 
     @Override
     public TransactionStatus check(Message msg) {
-        System.out.println("Receive transaction check back request, MsgId: " + msg.getMsgID());
+        System.out.printf("Receive transaction check back request, MsgId: %s%n", msg.getMsgID());
         return TransactionStatus.CommitTransaction;
     }
 }
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/MQTimerProducer.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/MQTimerProducer.java
index 471b8bd..26a6bf2 100644
--- a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/MQTimerProducer.java
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/MQTimerProducer.java
@@ -1,12 +1,13 @@
-/**
- * Copyright (C) 2010-2016 Alibaba Group Holding Limited
- * <p>
- * Licensed 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
+/*
+ * 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.
@@ -15,7 +16,6 @@
  */
 package org.apache.rocketmq.ons.sample.producer;
 
-import java.util.Date;
 import java.util.Properties;
 import org.apache.rocketmq.ons.api.Message;
 import org.apache.rocketmq.ons.api.ONSFactory;
@@ -34,7 +34,7 @@ public class MQTimerProducer {
         producerProperties.setProperty(PropertyKeyConst.NAMESRV_ADDR, MQConfig.NAMESRV_ADDR);
         Producer producer = ONSFactory.createProducer(producerProperties);
         producer.start();
-        System.out.println("Producer Started");
+        System.out.printf("Producer Started. %n");
 
         for (int i = 0; i < 10; i++) {
             Message message = new Message(MQConfig.TOPIC, MQConfig.TAG, "MQ send timer message test".getBytes());
@@ -43,9 +43,9 @@ public class MQTimerProducer {
             try {
                 SendResult sendResult = producer.send(message);
                 assert sendResult != null;
-                System.out.println(new Date() + " Send mq timer message success! Topic is: " + MQConfig.TOPIC + " msgId is: " + sendResult.getMessageId());
+                System.out.printf("Send mq timer message success! Topic is: %s msgId is: %s%n", MQConfig.TOPIC, sendResult.getMessageId());
             } catch (ONSClientException e) {
-                System.out.println(new Date() + " Send mq message failed. Topic is:" + MQConfig.TOPIC);
+                System.out.printf("Send mq message failed. Topic is: %s%n", MQConfig.TOPIC);
                 e.printStackTrace();
             }
         }
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleMQProducer.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleMQProducer.java
index e397a00..e3cb192 100644
--- a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleMQProducer.java
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleMQProducer.java
@@ -1,12 +1,13 @@
-/**
- * Copyright (C) 2010-2016 Alibaba Group Holding Limited
- * <p>
- * Licensed 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
+/*
+ * 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.
@@ -15,8 +16,6 @@
  */
 package org.apache.rocketmq.ons.sample.producer;
 
-
-import java.util.Date;
 import java.util.Properties;
 import org.apache.rocketmq.ons.api.Message;
 import org.apache.rocketmq.ons.api.ONSFactory;
@@ -37,16 +36,16 @@ public class SimpleMQProducer {
         producerProperties.setProperty(PropertyKeyConst.NAMESRV_ADDR, MQConfig.NAMESRV_ADDR);
         Producer producer = ONSFactory.createProducer(producerProperties);
         producer.start();
-        System.out.println("Producer Started");
+        System.out.printf("Producer Started %n");
 
         for (int i = 0; i < 10; i++) {
             Message message = new Message(MQConfig.TOPIC, MQConfig.TAG, "mq send transaction message test".getBytes());
             try {
                 SendResult sendResult = producer.send(message);
                 assert sendResult != null;
-                System.out.println(new Date() + " Send mq message success! Topic is: " + MQConfig.TOPIC + " msgId is: " + sendResult.getMessageId());
+                System.out.printf("Send mq timer message success! Topic is: %s msgId is: %s%n", MQConfig.TOPIC, sendResult.getMessageId());
             } catch (ONSClientException e) {
-                System.out.println(new Date() + " Send mq message failed! Topic is: " + MQConfig.TOPIC);
+                System.out.printf("Send mq message failed. Topic is: %s%n", MQConfig.TOPIC);
                 e.printStackTrace();
             }
         }
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleOrderProducer.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleOrderProducer.java
index dd0b3ae..43ab7f0 100644
--- a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleOrderProducer.java
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleOrderProducer.java
@@ -1,12 +1,13 @@
-/**
- * Copyright (C) 2010-2016 Alibaba Group Holding Limited
- * <p>
- * Licensed 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
+/*
+ * 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.
@@ -15,7 +16,6 @@
  */
 package org.apache.rocketmq.ons.sample.producer;
 
-import java.util.Date;
 import java.util.Properties;
 import org.apache.rocketmq.ons.api.Message;
 import org.apache.rocketmq.ons.api.ONSFactory;
@@ -35,7 +35,7 @@ public class SimpleOrderProducer {
         producerProperties.setProperty(PropertyKeyConst.NAMESRV_ADDR, MQConfig.NAMESRV_ADDR);
         OrderProducer producer = ONSFactory.createOrderProducer(producerProperties);
         producer.start();
-        System.out.println("Producer Started");
+        System.out.printf("Producer Started. %n");
 
         for (int i = 0; i < 10; i++) {
             Message msg = new Message(MQConfig.ORDER_TOPIC, MQConfig.TAG, "MQ send order message test".getBytes());
@@ -45,9 +45,9 @@ public class SimpleOrderProducer {
             try {
                 SendResult sendResult = producer.send(msg, shardingKey);
                 assert sendResult != null;
-                System.out.println(new Date() + " Send mq message success! Topic is: " + MQConfig.ORDER_TOPIC + " msgId is: " + sendResult.getMessageId());
+                System.out.printf("Send mq timer message success! Topic is: %s msgId is: %s%n", MQConfig.TOPIC, sendResult.getMessageId());
             } catch (ONSClientException e) {
-                System.out.println(new Date() + " Send mq message failed! Topic is: " + MQConfig.TOPIC);
+                System.out.printf("Send mq message failed. Topic is: %s%n", MQConfig.TOPIC);
                 e.printStackTrace();
             }
         }
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleTransactionProducer.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleTransactionProducer.java
index 4ab6805..4d16d51 100644
--- a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleTransactionProducer.java
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleTransactionProducer.java
@@ -1,12 +1,13 @@
-/**
- * Copyright (C) 2010-2016 Alibaba Group Holding Limited
- * <p>
- * Licensed 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
+/*
+ * 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.
@@ -46,17 +47,17 @@ public class SimpleTransactionProducer {
                 SendResult sendResult = transactionProducer.send(message, new LocalTransactionExecuter() {
                     @Override
                     public TransactionStatus execute(Message msg, Object arg) {
-                        System.out.println("Execute local transaction and return TransactionStatus.");
+                        System.out.printf("Execute local transaction and return TransactionStatus. %n");
                         return TransactionStatus.CommitTransaction;
                     }
                 }, null);
                 assert sendResult != null;
             } catch (ONSClientException e) {
-                System.out.println(new Date() + " Send mq message failed! Topic is:" + MQConfig.TOPIC);
+                System.out.printf(new Date() + " Send mq message failed! Topic is: %s%n", MQConfig.TOPIC);
                 e.printStackTrace();
             }
         }
 
-        System.out.println("Send transaction message success.");
+        System.out.printf("Send transaction message success. %n");
     }
 }
\ No newline at end of file


[rocketmq-ons] 25/29: Add comments for pull consumer

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit f1ca1d72e4f7f5ccde7cff1b78fbc4c45ecd9a7e
Author: duhenglucky <du...@gmail.com>
AuthorDate: Wed Jul 17 17:37:31 2019 +0800

    Add comments for pull consumer
---
 .../org/apache/rocketmq/ons/api/LifeCycle.java     |   4 +-
 .../org/apache/rocketmq/ons/api/MessageQueue.java  |  34 +++++++
 .../org/apache/rocketmq/ons/api/PullConsumer.java  | 102 ++++++++++++++++++++-
 3 files changed, 133 insertions(+), 7 deletions(-)

diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/LifeCycle.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/LifeCycle.java
index 51d96c4..811411e 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/LifeCycle.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/LifeCycle.java
@@ -1,4 +1,4 @@
-package org.apache.rocketmq.ons.api;/*
+/*
  * 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.
@@ -14,7 +14,7 @@ package org.apache.rocketmq.ons.api;/*
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
+package org.apache.rocketmq.ons.api;
 public interface LifeCycle {
     boolean isStarted();
 
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageQueue.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageQueue.java
index abe77b4..55f9c75 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageQueue.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageQueue.java
@@ -41,4 +41,38 @@ public class MessageQueue {
     public void setQueue(String queue) {
         this.queue = queue;
     }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((topic == null) ? 0 : topic.hashCode());
+        result = prime * result + ((queue == null) ? 0 : queue.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        MessageQueue other = (MessageQueue) obj;
+        if (queue == null) {
+            if (other.queue != null) {
+                return false;
+            }
+        } else if (!queue.equals(other.queue)) {
+            return false;
+        }
+        if (topic == null) {
+            if (other.topic != null)
+                return false;
+        } else if (!topic.equals(other.topic)) {
+            return false;
+        }
+        return true;
+    }
 }
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PullConsumer.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PullConsumer.java
index abdd966..e4910f2 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PullConsumer.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PullConsumer.java
@@ -18,30 +18,122 @@ package org.apache.rocketmq.ons.api;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 
-public interface PullConsumer {
-
+public interface PullConsumer extends LifeCycle, Credentials {
+    /**
+     * Subscribe to the given list of topics to get dynamically assigned message queues.
+     *
+     * @param topics
+     */
     void subscribe(final Collection<String> topics);
 
+    /**
+     * Subscribe to the given list of topics to get dynamically assigned message queues with filters.
+     *
+     * @param topics
+     */
     void subscribe(final Collection<String> topics, final String subExpression);
 
+    /**
+     * Unsubscribe the given list of topics.
+     *
+     * @param topics
+     */
     void unsubscribe(final Collection<String> topics);
 
+    /**
+     * Fetch data for the topics or partitions specified using subscribe API. It is an error to not have subscribed to
+     * any topics or partitions before polling for data.
+     *
+     * @param timeout
+     * @return
+     */
     List<Message> poll(long timeout);
 
+    /**
+     * Overrides the fetch offsets that the consumer will use on the next {@link #poll(long)}. If this API is invoked
+     * for the same message queue more than once, the latest offset will be used on the next poll(). Note that you may
+     * lose data if this API is arbitrarily used in the middle of consumption.
+     *
+     * @param messageQueue
+     * @param offset
+     */
     void seek(MessageQueue messageQueue, long offset);
 
+    /**
+     * Overrides the fetch offsets with the beginning offset in server that the consumer will use on the next {@link
+     * #poll(long)}.
+     *
+     * @param messageQueue
+     */
     void seekToBeginning(MessageQueue messageQueue);
 
-    void seekToEnd(MessageQueue messageQueuea);
+    /**
+     * Overrides the fetch offsets with the end offset in server that the consumer will use on the next {@link
+     * #poll(long)}.
+     *
+     * @param messageQueue
+     */
+    void seekToEnd(MessageQueue messageQueue);
 
+    /**
+     * Suspend fetching from the requested message queues. Future calls to {@link #poll(long)} will not return any
+     * records from these message queues until they have been resumed using {@link #resume(Collection)}.
+     *
+     * Note that this method does not affect message queue subscription. In particular, it does not cause a group
+     * rebalance.
+     *
+     * @param messageQueues
+     */
     void pause(Collection<MessageQueue> messageQueues);
 
-    void resume(Collection<MessageQueue> partitions);
+    /**
+     * Resume specified message queues which have been paused with {@link #pause(Collection)}. New calls to {@link
+     * #poll(long)} will return records from these partitions if there are any to be fetched. If the message queues were
+     * not previously paused, this method is a no-op.
+     *
+     * @param messageQueues
+     */
+    void resume(Collection<MessageQueue> messageQueues);
+
+    /**
+     * Get metadata about the partitions for a given topic. This method will issue a remote call to the server if it
+     * does not already have any metadata about the given topic.
+     *
+     * @param topic
+     * @return
+     */
+    Set<MessageQueue> messageQueues(String topic);
 
+    /**
+     * Look up the offsets for the given message queue by timestamp. The returned offset for each message queue is the
+     * earliest offset whose timestamp is greater than or equal to the given timestamp in the corresponding message
+     * queue.
+     *
+     * @param messageQueue
+     * @param timestamp
+     * @return
+     */
     Long offsetForTimestamp(MessageQueue messageQueue, Long timestamp);
 
+    /**
+     * Get the last committed offset for the given message queue (whether the commit happened by this process or
+     * another). This offset will be used as the position for the consumer in the event of a failure.
+     *
+     * @param messageQueue
+     * @return
+     */
     Long committed(MessageQueue messageQueue);
 
-    void commitSync();
+    /**
+     * Commit the last offset that has been stored securely. Should the process fail and restart, this is the offset
+     * that the consumer will recover to. The consumer can either automatically commit offsets periodically;
+     */
+    void commit();
+
+    /**
+     * Wakeup the consumer. This method is thread-safe and is useful in particular to abort a long poll.
+     */
+    void wakeup();
 }


[rocketmq-ons] 15/29: Add ONS samples.

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit 03e429c5e3f3d4b110741271fef96a430d6b4226
Merge: 2e94e3e b1be94d
Author: dinglei <li...@163.com>
AuthorDate: Mon Jul 1 17:47:06 2019 +0800

    Add ONS samples.
    
    Ons sample

 ons-sample/pom.xml                                 | 46 ++++++++++++++++
 .../org/apache/rocketmq/ons/sample/MQConfig.java   | 35 ++++++++++++
 .../ons/sample/consumer/MessageListenerImpl.java   | 30 +++++++++++
 .../ons/sample/consumer/SimpleMQConsumer.java      | 45 ++++++++++++++++
 .../ons/sample/consumer/SimpleOrderConsumer.java   | 54 +++++++++++++++++++
 .../producer/LocalTransactionCheckerImpl.java      | 30 +++++++++++
 .../ons/sample/producer/MQTimerProducer.java       | 53 ++++++++++++++++++
 .../ons/sample/producer/SimpleMQProducer.java      | 54 +++++++++++++++++++
 .../ons/sample/producer/SimpleOrderProducer.java   | 55 +++++++++++++++++++
 .../sample/producer/SimpleTransactionProducer.java | 62 ++++++++++++++++++++++
 pom.xml                                            |  1 +
 11 files changed, 465 insertions(+)


[rocketmq-ons] 06/29: Add language identifier to support native image for cpp

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit 47687022311b0167e5dfb817030090c21658244c
Author: ShannonDing <li...@163.com>
AuthorDate: Mon Jun 17 16:44:24 2019 +0800

    Add language identifier to support native image for cpp
---
 .../src/main/java/org/apache/rocketmq/ons/api/Message.java | 14 ++++++++++----
 .../java/org/apache/rocketmq/ons/api/PropertyKeyConst.java |  2 ++
 .../ons/api/impl/rocketmq/ONSConsumerAbstract.java         |  7 ++++++-
 .../rocketmq/ons/api/impl/rocketmq/OrderProducerImpl.java  |  7 ++++++-
 .../rocketmq/ons/api/impl/rocketmq/ProducerImpl.java       |  7 ++++++-
 .../ons/api/impl/rocketmq/TransactionProducerImpl.java     |  7 ++++++-
 6 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Message.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Message.java
index 5d1f999..db56b15 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Message.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/Message.java
@@ -51,7 +51,7 @@ public class Message implements Serializable {
     }
 
 
-    void putSystemProperties(final String key, final String value) {
+    public void putSystemProperties(final String key, final String value) {
         if (null == this.systemProperties) {
             this.systemProperties = new Properties();
         }
@@ -102,7 +102,7 @@ public class Message implements Serializable {
     }
 
 
-    String getSystemProperties(final String key) {
+    public String getSystemProperties(final String key) {
         if (null != this.systemProperties) {
             return this.systemProperties.getProperty(key);
         }
@@ -135,15 +135,21 @@ public class Message implements Serializable {
         this.putSystemProperties(SystemPropKey.MSGID, msgid);
     }
 
-    Properties getSystemProperties() {
+    public Properties getSystemProperties() {
+        if (null == systemProperties) {
+            return new Properties();
+        }
         return systemProperties;
     }
 
-    void setSystemProperties(Properties systemProperties) {
+    public void setSystemProperties(Properties systemProperties) {
         this.systemProperties = systemProperties;
     }
 
     public Properties getUserProperties() {
+        if (null == userProperties) {
+            return new Properties();
+        }
         return userProperties;
     }
 
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PropertyKeyConst.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PropertyKeyConst.java
index d98d49c..6862189 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PropertyKeyConst.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PropertyKeyConst.java
@@ -99,4 +99,6 @@ public class PropertyKeyConst {
 
     public static final String MAX_BATCH_MESSAGE_COUNT = "maxBatchMessageCount";
 
+    public static final String LANGUAGE_IDENTIFIER = "languageIdentifier";
+
 }
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSConsumerAbstract.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSConsumerAbstract.java
index d2bb38b..5844ebc 100644
--- a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSConsumerAbstract.java
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ONSConsumerAbstract.java
@@ -33,6 +33,7 @@ import org.apache.rocketmq.ons.api.exception.ONSClientException;
 import org.apache.rocketmq.ons.api.impl.tracehook.OnsConsumeMessageHookImpl;
 import org.apache.rocketmq.ons.api.impl.util.ClientLoggerUtil;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.rocketmq.remoting.protocol.LanguageCode;
 
 public class ONSConsumerAbstract extends ONSClientAbstract {
     final static InternalLogger LOGGER = ClientLoggerUtil.getClientLogger();
@@ -81,7 +82,11 @@ public class ONSConsumerAbstract extends ONSClientAbstract {
 
         boolean isVipChannelEnabled = Boolean.parseBoolean(properties.getProperty(PropertyKeyConst.isVipChannelEnabled, "false"));
         this.defaultMQPushConsumer.setVipChannelEnabled(isVipChannelEnabled);
-
+        if (properties.containsKey(PropertyKeyConst.LANGUAGE_IDENTIFIER)) {
+            int language = Integer.valueOf(properties.get(PropertyKeyConst.LANGUAGE_IDENTIFIER).toString());
+            byte languageByte = (byte) language;
+            this.defaultMQPushConsumer.setLanguage(LanguageCode.valueOf(languageByte));
+        }
         String instanceName = properties.getProperty(PropertyKeyConst.InstanceName, this.buildIntanceName());
         this.defaultMQPushConsumer.setInstanceName(instanceName);
         this.defaultMQPushConsumer.setNamesrvAddr(this.getNameServerAddr());
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/OrderProducerImpl.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/OrderProducerImpl.java
index 218a8c2..651c65b 100644
--- a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/OrderProducerImpl.java
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/OrderProducerImpl.java
@@ -36,6 +36,7 @@ import org.apache.rocketmq.ons.api.impl.tracehook.OnsClientSendMessageHookImpl;
 import org.apache.rocketmq.ons.api.impl.util.ClientLoggerUtil;
 import org.apache.rocketmq.ons.api.order.OrderProducer;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.rocketmq.remoting.protocol.LanguageCode;
 
 public class OrderProducerImpl extends ONSClientAbstract implements OrderProducer {
     private final static InternalLogger LOGGER = ClientLoggerUtil.getClientLogger();
@@ -62,7 +63,11 @@ public class OrderProducerImpl extends ONSClientAbstract implements OrderProduce
 
 //        boolean addExtendUniqInfo = Boolean.parseBoolean(properties.getProperty(PropertyKeyConst.EXACTLYONCE_DELIVERY, "false"));
 //        this.defaultMQProducer.setAddExtendUniqInfo(addExtendUniqInfo);
-
+        if (properties.containsKey(PropertyKeyConst.LANGUAGE_IDENTIFIER)) {
+            int language = Integer.valueOf(properties.get(PropertyKeyConst.LANGUAGE_IDENTIFIER).toString());
+            byte languageByte = (byte) language;
+            this.defaultMQProducer.setLanguage(LanguageCode.valueOf(languageByte));
+        }
         String instanceName = properties.getProperty(PropertyKeyConst.InstanceName, this.buildIntanceName());
         this.defaultMQProducer.setInstanceName(instanceName);
         this.defaultMQProducer.setNamesrvAddr(this.getNameServerAddr());
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java
index bd1dede..2658c7a 100644
--- a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java
@@ -43,6 +43,7 @@ import org.apache.rocketmq.ons.api.exception.ONSClientException;
 import org.apache.rocketmq.ons.api.impl.tracehook.OnsClientSendMessageHookImpl;
 import org.apache.rocketmq.ons.api.impl.util.ClientLoggerUtil;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.rocketmq.remoting.protocol.LanguageCode;
 
 public class ProducerImpl extends ONSClientAbstract implements Producer {
     private final static InternalLogger LOGGER = ClientLoggerUtil.getClientLogger();
@@ -73,7 +74,11 @@ public class ProducerImpl extends ONSClientAbstract implements Producer {
 //        if (properties.containsKey(PropertyKeyConst.EXACTLYONCE_DELIVERY)) {
 //            this.defaultMQProducer.setAddExtendUniqInfo(Boolean.valueOf(properties.get(PropertyKeyConst.EXACTLYONCE_DELIVERY).toString()));
 //        }
-
+        if (properties.containsKey(PropertyKeyConst.LANGUAGE_IDENTIFIER)) {
+            int language = Integer.valueOf(properties.get(PropertyKeyConst.LANGUAGE_IDENTIFIER).toString());
+            byte languageByte = (byte) language;
+            this.defaultMQProducer.setLanguage(LanguageCode.valueOf(languageByte));
+        }
         String instanceName = properties.getProperty(PropertyKeyConst.InstanceName, this.buildIntanceName());
         this.defaultMQProducer.setInstanceName(instanceName);
         this.defaultMQProducer.setNamesrvAddr(this.getNameServerAddr());
diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/TransactionProducerImpl.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/TransactionProducerImpl.java
index bc03867..13ed7e4 100644
--- a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/TransactionProducerImpl.java
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/TransactionProducerImpl.java
@@ -37,6 +37,7 @@ import org.apache.rocketmq.ons.api.transaction.TransactionStatus;
 import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceConstants;
 import org.apache.rocketmq.ons.open.trace.core.common.OnsTraceDispatcherType;
 import org.apache.rocketmq.ons.open.trace.core.dispatch.impl.AsyncArrayDispatcher;
+import org.apache.rocketmq.remoting.protocol.LanguageCode;
 
 public class TransactionProducerImpl extends ONSClientAbstract implements TransactionProducer {
     private final static InternalLogger LOGGER = ClientLoggerUtil.getClientLogger();
@@ -55,7 +56,11 @@ public class TransactionProducerImpl extends ONSClientAbstract implements Transa
 
         boolean isVipChannelEnabled = Boolean.parseBoolean(properties.getProperty(PropertyKeyConst.isVipChannelEnabled, "false"));
         transactionMQProducer.setVipChannelEnabled(isVipChannelEnabled);
-
+        if (properties.containsKey(PropertyKeyConst.LANGUAGE_IDENTIFIER)) {
+            int language = Integer.valueOf(properties.get(PropertyKeyConst.LANGUAGE_IDENTIFIER).toString());
+            byte languageByte = (byte) language;
+            this.transactionMQProducer.setLanguage(LanguageCode.valueOf(languageByte));
+        }
         String instanceName = properties.getProperty(PropertyKeyConst.InstanceName, this.buildIntanceName());
         this.transactionMQProducer.setInstanceName(instanceName);
 


[rocketmq-ons] 03/29: Remove unnecessary file

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit e28b1a94ee962570eb03f6e9552012ee32b37782
Author: duhenglucky <du...@gmail.com>
AuthorDate: Fri Jun 14 22:53:43 2019 +0800

    Remove unnecessary file
---
 NOTICE             | 2 +-
 ons-core/README.md | 0
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/NOTICE b/NOTICE
index 703c28b..309831a 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,5 +1,5 @@
 Apache RocketMQ
-Copyright 2016-2018 The Apache Software Foundation
+Copyright 2016-2019 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
\ No newline at end of file
diff --git a/ons-core/README.md b/ons-core/README.md
deleted file mode 100644
index e69de29..0000000


[rocketmq-ons] 21/29: [maven-release-plugin] prepare release ons-parent-1.0.0

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit 7c24199ff24252334f1bdffbf3e7f83ffa11070b
Author: duhenglucky <du...@gmail.com>
AuthorDate: Fri Jul 12 11:08:24 2019 +0800

    [maven-release-plugin] prepare release ons-parent-1.0.0
---
 ons-core/ons-api/pom.xml         |  2 +-
 ons-core/ons-auth4client/pom.xml |  2 +-
 ons-core/ons-client/pom.xml      |  2 +-
 ons-core/ons-trace-core/pom.xml  |  2 +-
 ons-core/pom.xml                 |  2 +-
 ons-sample/pom.xml               | 10 ++++------
 pom.xml                          |  4 ++--
 7 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/ons-core/ons-api/pom.xml b/ons-core/ons-api/pom.xml
index 374e460..95ba4c4 100644
--- a/ons-core/ons-api/pom.xml
+++ b/ons-core/ons-api/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.rocketmq</groupId>
         <artifactId>ons-all</artifactId>
-        <version>1.8.1-SNAPSHOT</version>
+        <version>1.0.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <packaging>jar</packaging>
diff --git a/ons-core/ons-auth4client/pom.xml b/ons-core/ons-auth4client/pom.xml
index 643f7c7..2c6db2a 100644
--- a/ons-core/ons-auth4client/pom.xml
+++ b/ons-core/ons-auth4client/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>ons-all</artifactId>
         <groupId>org.apache.rocketmq</groupId>
-        <version>1.8.1-SNAPSHOT</version>
+        <version>1.0.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>ons-auth4client</artifactId>
diff --git a/ons-core/ons-client/pom.xml b/ons-core/ons-client/pom.xml
index 7cc5df2..0840795 100644
--- a/ons-core/ons-client/pom.xml
+++ b/ons-core/ons-client/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.rocketmq</groupId>
         <artifactId>ons-all</artifactId>
-        <version>1.8.1-SNAPSHOT</version>
+        <version>1.0.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <packaging>jar</packaging>
diff --git a/ons-core/ons-trace-core/pom.xml b/ons-core/ons-trace-core/pom.xml
index 4ba3f7d..48f872d 100644
--- a/ons-core/ons-trace-core/pom.xml
+++ b/ons-core/ons-trace-core/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>ons-all</artifactId>
         <groupId>org.apache.rocketmq</groupId>
-        <version>1.8.1-SNAPSHOT</version>
+        <version>1.0.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>ons-trace-core</artifactId>
diff --git a/ons-core/pom.xml b/ons-core/pom.xml
index edadb69..bfb2dc4 100644
--- a/ons-core/pom.xml
+++ b/ons-core/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.rocketmq</groupId>
         <artifactId>ons-parent</artifactId>
-        <version>1.8.1-SNAPSHOT</version>
+        <version>1.0.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <inceptionYear>2012</inceptionYear>
diff --git a/ons-sample/pom.xml b/ons-sample/pom.xml
index 8f52602..bedea83 100644
--- a/ons-sample/pom.xml
+++ b/ons-sample/pom.xml
@@ -15,13 +15,11 @@
   limitations under the License.
   -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
         <artifactId>ons-parent</artifactId>
         <groupId>org.apache.rocketmq</groupId>
-        <version>1.8.1-SNAPSHOT</version>
+        <version>1.0.0</version>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
@@ -33,12 +31,12 @@
         <dependency>
             <groupId>org.apache.rocketmq</groupId>
             <artifactId>ons-api</artifactId>
-            <version>1.8.1-SNAPSHOT</version>
+            <version>1.0.0</version>
         </dependency>
         <dependency>
             <groupId>org.apache.rocketmq</groupId>
             <artifactId>ons-client</artifactId>
-            <version>1.8.1-SNAPSHOT</version>
+            <version>1.0.0</version>
         </dependency>
     </dependencies>
 
diff --git a/pom.xml b/pom.xml
index 9317ccd..803a101 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>org.apache.rocketmq</groupId>
     <artifactId>ons-parent</artifactId>
-    <version>1.8.1-SNAPSHOT</version>
+    <version>1.0.0</version>
     <packaging>pom</packaging>
     <name>ons-parent ${project.version}</name>
     <description>
@@ -274,6 +274,6 @@
         <url>git@github.com:apache/rocketmq-ons.git</url>
         <connection>scm:git:git@github.com:apache/rocketmq-ons.git</connection>
         <developerConnection>scm:git:git@github.com:apache/rocketmq-ons.git</developerConnection>
-        <tag>HEAD</tag>
+        <tag>ons-parent-1.0.0</tag>
     </scm>
 </project>


[rocketmq-ons] 28/29: Remove deprecated of OrderProducer

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit 4bb15ff7870c8633aad4e20bcdfc62938a89bfbc
Author: duhenglucky <du...@gmail.com>
AuthorDate: Fri Aug 30 11:19:21 2019 +0800

    Remove deprecated of OrderProducer
---
 .../src/main/java/org/apache/rocketmq/ons/api/order/OrderProducer.java   | 1 -
 1 file changed, 1 deletion(-)

diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderProducer.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderProducer.java
index 25df1d0..5a401fc 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderProducer.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/order/OrderProducer.java
@@ -26,7 +26,6 @@ import org.apache.rocketmq.ons.api.SendResult;
 /**
  * This interface will be removed in the year 2021, {@link Producer#send(Message, String)} is recommended
  */
-@Deprecated
 public interface OrderProducer extends LifeCycle, Credentials {
 
     SendResult send(final Message message, final String shardingKey);


[rocketmq-ons] 22/29: [maven-release-plugin] prepare for next development iteration

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit 6da9b49cc63035f6900148ca3b491707f398d836
Author: duhenglucky <du...@gmail.com>
AuthorDate: Fri Jul 12 11:09:03 2019 +0800

    [maven-release-plugin] prepare for next development iteration
---
 ons-core/ons-api/pom.xml         | 2 +-
 ons-core/ons-auth4client/pom.xml | 2 +-
 ons-core/ons-client/pom.xml      | 2 +-
 ons-core/ons-trace-core/pom.xml  | 2 +-
 ons-core/pom.xml                 | 2 +-
 ons-sample/pom.xml               | 6 +++---
 pom.xml                          | 4 ++--
 7 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/ons-core/ons-api/pom.xml b/ons-core/ons-api/pom.xml
index 95ba4c4..adbec96 100644
--- a/ons-core/ons-api/pom.xml
+++ b/ons-core/ons-api/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.rocketmq</groupId>
         <artifactId>ons-all</artifactId>
-        <version>1.0.0</version>
+        <version>1.0.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <packaging>jar</packaging>
diff --git a/ons-core/ons-auth4client/pom.xml b/ons-core/ons-auth4client/pom.xml
index 2c6db2a..fe24766 100644
--- a/ons-core/ons-auth4client/pom.xml
+++ b/ons-core/ons-auth4client/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>ons-all</artifactId>
         <groupId>org.apache.rocketmq</groupId>
-        <version>1.0.0</version>
+        <version>1.0.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>ons-auth4client</artifactId>
diff --git a/ons-core/ons-client/pom.xml b/ons-core/ons-client/pom.xml
index 0840795..0bcab99 100644
--- a/ons-core/ons-client/pom.xml
+++ b/ons-core/ons-client/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.rocketmq</groupId>
         <artifactId>ons-all</artifactId>
-        <version>1.0.0</version>
+        <version>1.0.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <packaging>jar</packaging>
diff --git a/ons-core/ons-trace-core/pom.xml b/ons-core/ons-trace-core/pom.xml
index 48f872d..579e842 100644
--- a/ons-core/ons-trace-core/pom.xml
+++ b/ons-core/ons-trace-core/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>ons-all</artifactId>
         <groupId>org.apache.rocketmq</groupId>
-        <version>1.0.0</version>
+        <version>1.0.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>ons-trace-core</artifactId>
diff --git a/ons-core/pom.xml b/ons-core/pom.xml
index bfb2dc4..27e4142 100644
--- a/ons-core/pom.xml
+++ b/ons-core/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.rocketmq</groupId>
         <artifactId>ons-parent</artifactId>
-        <version>1.0.0</version>
+        <version>1.0.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <inceptionYear>2012</inceptionYear>
diff --git a/ons-sample/pom.xml b/ons-sample/pom.xml
index bedea83..710b0af 100644
--- a/ons-sample/pom.xml
+++ b/ons-sample/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>ons-parent</artifactId>
         <groupId>org.apache.rocketmq</groupId>
-        <version>1.0.0</version>
+        <version>1.0.1-SNAPSHOT</version>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
@@ -31,12 +31,12 @@
         <dependency>
             <groupId>org.apache.rocketmq</groupId>
             <artifactId>ons-api</artifactId>
-            <version>1.0.0</version>
+            <version>1.0.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.apache.rocketmq</groupId>
             <artifactId>ons-client</artifactId>
-            <version>1.0.0</version>
+            <version>1.0.1-SNAPSHOT</version>
         </dependency>
     </dependencies>
 
diff --git a/pom.xml b/pom.xml
index 803a101..ec1c4fa 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>org.apache.rocketmq</groupId>
     <artifactId>ons-parent</artifactId>
-    <version>1.0.0</version>
+    <version>1.0.1-SNAPSHOT</version>
     <packaging>pom</packaging>
     <name>ons-parent ${project.version}</name>
     <description>
@@ -274,6 +274,6 @@
         <url>git@github.com:apache/rocketmq-ons.git</url>
         <connection>scm:git:git@github.com:apache/rocketmq-ons.git</connection>
         <developerConnection>scm:git:git@github.com:apache/rocketmq-ons.git</developerConnection>
-        <tag>ons-parent-1.0.0</tag>
+        <tag>HEAD</tag>
     </scm>
 </project>


[rocketmq-ons] 19/29: Merge pull request #5 from duhenglucky/master

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit cedf1b8555aeb27816beef7aff7e754682458fd5
Merge: bc9934a 9cb0ab2
Author: wlliqipeng <wl...@163.com>
AuthorDate: Fri Jul 12 10:37:32 2019 +0800

    Merge pull request #5 from duhenglucky/master
    
    Optimize the sample code to make it can pass the code style check

 .../org/apache/rocketmq/ons/sample/MQConfig.java   | 19 +++++++--------
 .../ons/sample/consumer/MessageListenerImpl.java   | 22 +++++++++---------
 .../ons/sample/consumer/SimpleMQConsumer.java      | 22 +++++++++---------
 .../ons/sample/consumer/SimpleOrderConsumer.java   | 25 ++++++++++----------
 .../producer/LocalTransactionCheckerImpl.java      | 22 +++++++++---------
 .../ons/sample/producer/MQTimerProducer.java       | 26 ++++++++++-----------
 .../ons/sample/producer/SimpleMQProducer.java      | 27 +++++++++++-----------
 .../ons/sample/producer/SimpleOrderProducer.java   | 26 ++++++++++-----------
 .../sample/producer/SimpleTransactionProducer.java | 25 ++++++++++----------
 9 files changed, 108 insertions(+), 106 deletions(-)


[rocketmq-ons] 12/29: Add rocketmq-ons demo

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit 316399b4cadf630b7e6634c380c529de613bbd6f
Author: duhenglucky <du...@gmail.com>
AuthorDate: Mon Jul 1 16:45:52 2019 +0800

    Add rocketmq-ons demo
---
 ons-sample/pom.xml                                 | 27 +++++++++++
 .../org/apache/rocketmq/ons/sample/MQConfig.java   | 32 +++++++++++++
 .../ons/sample/consumer/MessageListenerImpl.java   | 27 +++++++++++
 .../ons/sample/consumer/SimpleMQConsumer.java      | 45 ++++++++++++++++++
 .../ons/sample/consumer/SimpleOrderConsumer.java   | 54 ++++++++++++++++++++++
 .../producer/LocalTransactionCheckerImpl.java      | 15 ++++++
 .../ons/sample/producer/MQTimerProducer.java       | 50 ++++++++++++++++++++
 .../ons/sample/producer/SimpleMQProducer.java      | 54 ++++++++++++++++++++++
 .../ons/sample/producer/SimpleOrderProducer.java   | 52 +++++++++++++++++++++
 .../sample/producer/SimpleTransactionProducer.java | 47 +++++++++++++++++++
 pom.xml                                            |  1 +
 11 files changed, 404 insertions(+)

diff --git a/ons-sample/pom.xml b/ons-sample/pom.xml
new file mode 100644
index 0000000..71a7972
--- /dev/null
+++ b/ons-sample/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>ons-parent</artifactId>
+        <groupId>org.apache.rocketmq</groupId>
+        <version>1.8.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>ons-sample</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.rocketmq</groupId>
+            <artifactId>ons-api</artifactId>
+            <version>1.8.1-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.rocketmq</groupId>
+            <artifactId>ons-client</artifactId>
+            <version>1.8.1-SNAPSHOT</version>
+        </dependency>
+    </dependencies>
+
+
+</project>
\ No newline at end of file
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/MQConfig.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/MQConfig.java
new file mode 100644
index 0000000..17937d4
--- /dev/null
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/MQConfig.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (C) 2010-2016 Alibaba Group Holding Limited
+ * <p>
+ * Licensed 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.
+ */
+package org.apache.rocketmq.ons.sample;
+
+public class MQConfig {
+    /**
+     * RocketMQ config
+     */
+    public static final String TOPIC = "xxxx";
+    public static final String GROUP_ID = "GID-xxxx";
+    public static final String ORDER_TOPIC = "xxxx";
+    public static final String ORDER_GROUP_ID = "GID-xxxx";
+    public static final String ACCESS_KEY = "xxxx";
+    public static final String SECRET_KEY = "xxxxxxxxxxx";
+    public static final String TAG = "*";
+
+    /**
+     * NAMESRV_ADDR
+     */
+    public static final String NAMESRV_ADDR = "xxxxxx";
+
+}
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/MessageListenerImpl.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/MessageListenerImpl.java
new file mode 100644
index 0000000..f51d16f
--- /dev/null
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/MessageListenerImpl.java
@@ -0,0 +1,27 @@
+/**
+ * Copyright (C) 2010-2016 Alibaba Group Holding Limited
+ * <p>
+ * Licensed 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.
+ */
+package org.apache.rocketmq.ons.sample.consumer;
+
+import java.util.Date;
+import org.apache.rocketmq.ons.api.Action;
+import org.apache.rocketmq.ons.api.ConsumeContext;
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.MessageListener;
+
+public class MessageListenerImpl implements MessageListener {
+    @Override
+    public Action consume(Message message, ConsumeContext consumeContext) {
+        System.out.println(new Date() + " Receive message, Topic is:" + message.getTopic() + ", MsgId is:" + message.getMsgID());
+        return Action.CommitMessage;
+    }
+}
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/SimpleMQConsumer.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/SimpleMQConsumer.java
new file mode 100644
index 0000000..4c4f58b
--- /dev/null
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/SimpleMQConsumer.java
@@ -0,0 +1,45 @@
+/**
+ * Copyright (C) 2010-2016 Alibaba Group Holding Limited
+ * <p>
+ * Licensed 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.
+ */
+package org.apache.rocketmq.ons.sample.consumer;
+
+
+import java.util.Properties;
+import org.apache.rocketmq.ons.api.Consumer;
+import org.apache.rocketmq.ons.api.ONSFactory;
+import org.apache.rocketmq.ons.api.PropertyKeyConst;
+import org.apache.rocketmq.ons.sample.MQConfig;
+
+public class SimpleMQConsumer {
+
+    public static void main(String[] args) {
+        Properties consumerProperties = new Properties();
+        consumerProperties.setProperty(PropertyKeyConst.GROUP_ID, MQConfig.GROUP_ID);
+        consumerProperties.setProperty(PropertyKeyConst.AccessKey, MQConfig.ACCESS_KEY);
+        consumerProperties.setProperty(PropertyKeyConst.SecretKey, MQConfig.SECRET_KEY);
+        consumerProperties.setProperty(PropertyKeyConst.NAMESRV_ADDR, MQConfig.NAMESRV_ADDR);
+        Consumer consumer = ONSFactory.createConsumer(consumerProperties);
+        consumer.subscribe(MQConfig.TOPIC, MQConfig.TAG, new MessageListenerImpl());
+        consumer.start();
+        System.out.println("Consumer start success.");
+
+        //等待固定时间防止进程退出
+        try {
+            Thread.sleep(200000);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/SimpleOrderConsumer.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/SimpleOrderConsumer.java
new file mode 100644
index 0000000..ea5159f
--- /dev/null
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/consumer/SimpleOrderConsumer.java
@@ -0,0 +1,54 @@
+/**
+ * Copyright (C) 2010-2016 Alibaba Group Holding Limited
+ * <p>
+ * Licensed 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.
+ */
+package org.apache.rocketmq.ons.sample.consumer;
+
+import java.util.Properties;
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.ONSFactory;
+import org.apache.rocketmq.ons.api.PropertyKeyConst;
+import org.apache.rocketmq.ons.api.order.ConsumeOrderContext;
+import org.apache.rocketmq.ons.api.order.MessageOrderListener;
+import org.apache.rocketmq.ons.api.order.OrderAction;
+import org.apache.rocketmq.ons.api.order.OrderConsumer;
+import org.apache.rocketmq.ons.sample.MQConfig;
+
+public class SimpleOrderConsumer {
+
+    public static void main(String[] args) {
+        Properties consumerProperties = new Properties();
+        consumerProperties.setProperty(PropertyKeyConst.GROUP_ID, MQConfig.ORDER_GROUP_ID);
+        consumerProperties.setProperty(PropertyKeyConst.AccessKey, MQConfig.ACCESS_KEY);
+        consumerProperties.setProperty(PropertyKeyConst.SecretKey, MQConfig.SECRET_KEY);
+        consumerProperties.setProperty(PropertyKeyConst.NAMESRV_ADDR, MQConfig.NAMESRV_ADDR);
+        OrderConsumer consumer = ONSFactory.createOrderedConsumer(consumerProperties);
+        consumer.subscribe(MQConfig.ORDER_TOPIC, MQConfig.TAG,  new MessageOrderListener() {
+
+            @Override
+            public OrderAction consume(final Message message, final ConsumeOrderContext context) {
+                System.out.println(message);
+                return OrderAction.Success;
+            }
+        });
+        consumer.start();
+        System.out.println("Consumer start success.");
+
+        try {
+            Thread.sleep(200000);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/LocalTransactionCheckerImpl.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/LocalTransactionCheckerImpl.java
new file mode 100644
index 0000000..32a756f
--- /dev/null
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/LocalTransactionCheckerImpl.java
@@ -0,0 +1,15 @@
+package org.apache.rocketmq.ons.sample.producer;
+
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.transaction.LocalTransactionChecker;
+import org.apache.rocketmq.ons.api.transaction.TransactionStatus;
+
+
+public class LocalTransactionCheckerImpl implements LocalTransactionChecker {
+
+    @Override
+    public TransactionStatus check(Message msg) {
+        System.out.println("Receive transaction check back request, MsgId: " + msg.getMsgID());
+        return TransactionStatus.CommitTransaction;
+    }
+}
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/MQTimerProducer.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/MQTimerProducer.java
new file mode 100644
index 0000000..1f70ad3
--- /dev/null
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/MQTimerProducer.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (C) 2010-2016 Alibaba Group Holding Limited
+ * <p>
+ * Licensed 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.
+ */
+package org.apache.rocketmq.ons.sample.producer;
+
+import java.util.Date;
+import java.util.Properties;
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.ONSFactory;
+import org.apache.rocketmq.ons.api.Producer;
+import org.apache.rocketmq.ons.api.PropertyKeyConst;
+import org.apache.rocketmq.ons.api.SendResult;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+import org.apache.rocketmq.ons.sample.MQConfig;
+
+public class MQTimerProducer {
+    public static void main(String[] args) {
+        Properties producerProperties = new Properties();
+        producerProperties.setProperty(PropertyKeyConst.GROUP_ID, MQConfig.GROUP_ID);
+        producerProperties.setProperty(PropertyKeyConst.AccessKey, MQConfig.ACCESS_KEY);
+        producerProperties.setProperty(PropertyKeyConst.SecretKey, MQConfig.SECRET_KEY);
+        producerProperties.setProperty(PropertyKeyConst.NAMESRV_ADDR, MQConfig.NAMESRV_ADDR);
+        Producer producer = ONSFactory.createProducer(producerProperties);
+        producer.start();
+        System.out.println("Producer Started");
+
+        for (int i = 0; i < 10; i++) {
+            Message message = new Message(MQConfig.TOPIC, MQConfig.TAG, "MQ send timer message test".getBytes());
+            long delayTime = 3000;
+            message.setStartDeliverTime(System.currentTimeMillis() + delayTime);
+            try {
+                SendResult sendResult = producer.send(message);
+                assert sendResult != null;
+                System.out.println(new Date() + " Send mq timer message success! Topic is: " + MQConfig.TOPIC + " msgId is: " + sendResult.getMessageId());
+            } catch (ONSClientException e) {
+                System.out.println(new Date() + " Send mq message failed. Topic is:" + MQConfig.TOPIC);
+                e.printStackTrace();
+            }
+        }
+    }
+}
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleMQProducer.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleMQProducer.java
new file mode 100644
index 0000000..e397a00
--- /dev/null
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleMQProducer.java
@@ -0,0 +1,54 @@
+/**
+ * Copyright (C) 2010-2016 Alibaba Group Holding Limited
+ * <p>
+ * Licensed 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.
+ */
+package org.apache.rocketmq.ons.sample.producer;
+
+
+import java.util.Date;
+import java.util.Properties;
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.ONSFactory;
+import org.apache.rocketmq.ons.api.Producer;
+import org.apache.rocketmq.ons.api.PropertyKeyConst;
+import org.apache.rocketmq.ons.api.SendResult;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+import org.apache.rocketmq.ons.sample.MQConfig;
+
+public class SimpleMQProducer {
+
+
+    public static void main(String[] args) {
+        Properties producerProperties = new Properties();
+        producerProperties.setProperty(PropertyKeyConst.GROUP_ID, MQConfig.GROUP_ID);
+        producerProperties.setProperty(PropertyKeyConst.AccessKey, MQConfig.ACCESS_KEY);
+        producerProperties.setProperty(PropertyKeyConst.SecretKey, MQConfig.SECRET_KEY);
+        producerProperties.setProperty(PropertyKeyConst.NAMESRV_ADDR, MQConfig.NAMESRV_ADDR);
+        Producer producer = ONSFactory.createProducer(producerProperties);
+        producer.start();
+        System.out.println("Producer Started");
+
+        for (int i = 0; i < 10; i++) {
+            Message message = new Message(MQConfig.TOPIC, MQConfig.TAG, "mq send transaction message test".getBytes());
+            try {
+                SendResult sendResult = producer.send(message);
+                assert sendResult != null;
+                System.out.println(new Date() + " Send mq message success! Topic is: " + MQConfig.TOPIC + " msgId is: " + sendResult.getMessageId());
+            } catch (ONSClientException e) {
+                System.out.println(new Date() + " Send mq message failed! Topic is: " + MQConfig.TOPIC);
+                e.printStackTrace();
+            }
+        }
+    }
+}
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleOrderProducer.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleOrderProducer.java
new file mode 100644
index 0000000..550005c
--- /dev/null
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleOrderProducer.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (C) 2010-2016 Alibaba Group Holding Limited
+ * <p>
+ * Licensed 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.
+ */
+package org.apache.rocketmq.ons.sample.producer;
+
+import java.util.Date;
+import java.util.Properties;
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.ONSFactory;
+import org.apache.rocketmq.ons.api.PropertyKeyConst;
+import org.apache.rocketmq.ons.api.SendResult;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+import org.apache.rocketmq.ons.api.order.OrderProducer;
+import org.apache.rocketmq.ons.sample.MQConfig;
+
+public class SimpleOrderProducer {
+
+    public static void main(String[] args) {
+        Properties producerProperties = new Properties();
+        producerProperties.setProperty(PropertyKeyConst.GROUP_ID, MQConfig.ORDER_GROUP_ID);
+        producerProperties.setProperty(PropertyKeyConst.AccessKey, MQConfig.ACCESS_KEY);
+        producerProperties.setProperty(PropertyKeyConst.SecretKey, MQConfig.SECRET_KEY);
+        producerProperties.setProperty(PropertyKeyConst.NAMESRV_ADDR, MQConfig.NAMESRV_ADDR);
+        OrderProducer producer = ONSFactory.createOrderProducer(producerProperties);
+        producer.start();
+        System.out.println("Producer Started");
+
+        for (int i = 0; i < 10; i++) {
+            Message msg = new Message(MQConfig.ORDER_TOPIC, MQConfig.TAG, "MQ send order message test".getBytes());
+            String orderId = "biz_" + i % 10;
+            msg.setKey(orderId);
+            String shardingKey = String.valueOf(orderId);
+            try {
+                SendResult sendResult = producer.send(msg, shardingKey);
+                assert sendResult != null;
+                System.out.println(new Date() + " Send mq message success! Topic is: " + MQConfig.ORDER_TOPIC + " msgId is: " + sendResult.getMessageId());
+            } catch (ONSClientException e) {
+                System.out.println(new Date() + " Send mq message failed! Topic is: " + MQConfig.TOPIC);
+                e.printStackTrace();
+            }
+        }
+    }
+}
diff --git a/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleTransactionProducer.java b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleTransactionProducer.java
new file mode 100644
index 0000000..bbb97e3
--- /dev/null
+++ b/ons-sample/src/main/java/org/apache/rocketmq/ons/sample/producer/SimpleTransactionProducer.java
@@ -0,0 +1,47 @@
+package org.apache.rocketmq.ons.sample.producer;
+
+import java.util.Date;
+import java.util.Properties;
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.ONSFactory;
+import org.apache.rocketmq.ons.api.PropertyKeyConst;
+import org.apache.rocketmq.ons.api.SendResult;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+import org.apache.rocketmq.ons.api.transaction.LocalTransactionExecuter;
+import org.apache.rocketmq.ons.api.transaction.TransactionProducer;
+import org.apache.rocketmq.ons.api.transaction.TransactionStatus;
+import org.apache.rocketmq.ons.sample.MQConfig;
+
+public class SimpleTransactionProducer {
+
+    public static void main(String[] args) {
+        Properties tranProducerProperties = new Properties();
+        tranProducerProperties.setProperty(PropertyKeyConst.GROUP_ID, MQConfig.GROUP_ID);
+        tranProducerProperties.setProperty(PropertyKeyConst.AccessKey, MQConfig.ACCESS_KEY);
+        tranProducerProperties.setProperty(PropertyKeyConst.SecretKey, MQConfig.SECRET_KEY);
+        tranProducerProperties.setProperty(PropertyKeyConst.NAMESRV_ADDR, MQConfig.NAMESRV_ADDR);
+        LocalTransactionCheckerImpl localTransactionChecker = new LocalTransactionCheckerImpl();
+        TransactionProducer transactionProducer = ONSFactory.createTransactionProducer(tranProducerProperties, localTransactionChecker);
+        transactionProducer.start();
+
+        Message message = new Message(MQConfig.TOPIC, MQConfig.TAG, "MQ send transaction message test".getBytes());
+
+        for (int i = 0; i < 10; i++) {
+            try {
+                SendResult sendResult = transactionProducer.send(message, new LocalTransactionExecuter() {
+                    @Override
+                    public TransactionStatus execute(Message msg, Object arg) {
+                        System.out.println("Execute local transaction and return TransactionStatus.");
+                        return TransactionStatus.CommitTransaction;
+                    }
+                }, null);
+                assert sendResult != null;
+            } catch (ONSClientException e) {
+                System.out.println(new Date() + " Send mq message failed! Topic is:" + MQConfig.TOPIC);
+                e.printStackTrace();
+            }
+        }
+
+        System.out.println("Send transaction message success.");
+    }
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 9718937..59fdb13 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,6 +51,7 @@
     </properties>
     <modules>
         <module>ons-core</module>
+        <module>ons-sample</module>
     </modules>
     <build>
         <plugins>


[rocketmq-ons] 05/29: Call onException instead of throw exception when async sending

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit 3f9457e265a6fdece1a3ac8147adab3396c7fd12
Author: ShannonDing <li...@163.com>
AuthorDate: Mon Jun 17 16:30:20 2019 +0800

    Call onException instead of throw exception when async sending
---
 .../org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java   | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java
index 6118435..921861a 100644
--- a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java
@@ -169,7 +169,13 @@ public class ProducerImpl extends ONSClientAbstract implements Producer {
             message.setMsgID(MessageClientIDSetter.getUniqID(msgRMQ));
         } catch (Exception e) {
             LOGGER.error(String.format("Send message async Exception, %s", message), e);
-            throw checkProducerException(message.getTopic(), message.getMsgID(), e);
+            //throw checkProducerException(message.getTopic(), message.getMsgID(), e);
+            ONSClientException clientException = checkProducerException(message.getTopic(), message.getMsgID(), e);
+            OnExceptionContext context = new OnExceptionContext();
+            context.setException(clientException);
+            context.setTopic(message.getTopic());
+            context.setMessageId(message.getMsgID());
+            sendCallback.onException(context);
         }
     }
 


[rocketmq-ons] 29/29: Merge pull request #8 from duhenglucky/sdk_polish

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit 486e78272dd1a8c334ef5213fff89e799865104f
Merge: 6da9b49 4bb15ff
Author: Heng Du <du...@apache.org>
AuthorDate: Fri Aug 30 11:20:56 2019 +0800

    Merge pull request #8 from duhenglucky/sdk_polish
    
     Add pull consumer interface and polished Admin interface

 .../java/org/apache/rocketmq/ons/api/Admin.java    |  18 +--
 .../java/org/apache/rocketmq/ons/api/Consumer.java |   5 +-
 .../ons/api/{Admin.java => Credentials.java}       |  17 +--
 .../ons/api/{Admin.java => LifeCycle.java}         |  13 +-
 .../java/org/apache/rocketmq/ons/api/Producer.java |  14 +-
 .../org/apache/rocketmq/ons/api/PullConsumer.java  | 143 +++++++++++++++++++++
 .../apache/rocketmq/ons/api/TopicPartition.java    |  78 +++++++++++
 .../rocketmq/ons/api/batch/BatchConsumer.java      |   5 +-
 .../apache/rocketmq/ons/api/bean/ProducerBean.java |   9 ++
 .../ons/api/bean/TransactionProducerBean.java      |   4 +-
 .../rocketmq/ons/api/order/OrderConsumer.java      |   6 +-
 .../rocketmq/ons/api/order/OrderProducer.java      |  10 +-
 .../api/transaction/LocalTransactionChecker.java   |   2 +
 ...Executer.java => LocalTransactionExecutor.java} |   4 +-
 .../ons/api/transaction/TransactionProducer.java   |  16 +--
 .../ons/api/impl/rocketmq/ProducerImpl.java        |   9 ++
 .../api/impl/rocketmq/TransactionProducerImpl.java |   4 +-
 ons-core/pom.xml                                   |   6 +-
 ons-sample/pom.xml                                 |   4 +-
 .../sample/producer/SimpleTransactionProducer.java |   5 +-
 20 files changed, 281 insertions(+), 91 deletions(-)


[rocketmq-ons] 20/29: Change scm configuration in pom file

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit a63d36b9e89000fc9e35f88ed2a82dbf8fe947d2
Author: duhenglucky <du...@gmail.com>
AuthorDate: Fri Jul 12 11:06:15 2019 +0800

    Change scm configuration in pom file
---
 pom.xml | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/pom.xml b/pom.xml
index 59fdb13..9317ccd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -271,8 +271,9 @@
         </dependencies>
     </dependencyManagement>
     <scm>
-        <url>git@gitlab.alibaba-inc.com:middleware/ons.git</url>
-        <connection>scm:git:git@gitlab.alibaba-inc.com:middleware/ons.git</connection>
-        <developerConnection>scm:git:git@gitlab.alibaba-inc.com:middleware/ons.git</developerConnection>
+        <url>git@github.com:apache/rocketmq-ons.git</url>
+        <connection>scm:git:git@github.com:apache/rocketmq-ons.git</connection>
+        <developerConnection>scm:git:git@github.com:apache/rocketmq-ons.git</developerConnection>
+        <tag>HEAD</tag>
     </scm>
 </project>


[rocketmq-ons] 13/29: Modify ons-sample pom file

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit a9c9227350055988908653e564affaa68df21738
Author: duhenglucky <du...@gmail.com>
AuthorDate: Mon Jul 1 16:48:52 2019 +0800

    Modify ons-sample pom file
---
 ons-sample/pom.xml | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/ons-sample/pom.xml b/ons-sample/pom.xml
index 71a7972..2cebaaf 100644
--- a/ons-sample/pom.xml
+++ b/ons-sample/pom.xml
@@ -7,9 +7,12 @@
         <groupId>org.apache.rocketmq</groupId>
         <version>1.8.1-SNAPSHOT</version>
     </parent>
-    <modelVersion>4.0.0</modelVersion>
 
+    <modelVersion>4.0.0</modelVersion>
+    <packaging>jar</packaging>
     <artifactId>ons-sample</artifactId>
+    <name>rocketmq-ons ${project.version}</name>
+
     <dependencies>
         <dependency>
             <groupId>org.apache.rocketmq</groupId>


[rocketmq-ons] 17/29: Update README.md

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit bc9934af0db4fcaf3269ed67aae66c39286b6778
Author: Heng Du <du...@gmail.com>
AuthorDate: Wed Jul 3 15:00:26 2019 +0800

    Update README.md
---
 README.md | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 6ad473d..d556ce5 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,17 @@
 ## Overview
- Apache RocketMQ ONS is a RocketMQ lightweight client.
+Apache RocketMQ ONS is a RocketMQ lightweight client.      
+As a high-level client, ONS is more simple and easy to use than native clients. It shields the underlying implementation details and provides a better abstraction. It also removes admin interfaces used for resource management. Therefore, for most RocketMQ users, ONS can be used to access the RocketMQ service faster, and the code is more concise and secure.         
 
 ----------
+
+## Feature
+ - Produce messages, including normal, transactional, delayed messages, in synchronously, asynchronously and oneway model.
+ - Consume messages, in cluster or broadcast model, concurrently and orderly with push consumer
+ - Automatically rebalanced, both in producing and consuming process.
+ - Reliability, any downtime broker or name server has no impact on the client.
+
+ 
+----------
 ## Contributing
 We always welcome new contributions, whether for trivial cleanups, big new features or other material rewards, more details see [here](http://rocketmq.apache.org/docs/how-to-contribute/).
  


[rocketmq-ons] 10/29: Add error log for async send failed

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit 64fd96ef65885dc13246f0f702ed49dfe1fa4a1b
Author: ShannonDing <li...@163.com>
AuthorDate: Tue Jun 18 11:10:00 2019 +0800

    Add error log for async send failed
---
 .../java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java     | 1 +
 1 file changed, 1 insertion(+)

diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java
index ecb5221..cfbe212 100644
--- a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java
@@ -199,6 +199,7 @@ public class ProducerImpl extends ONSClientAbstract implements Producer {
             public void onException(Throwable e) {
                 //String topic = new String(message.getTopic());
                 //String msgId = new String(message.getMsgID());
+                LOGGER.error(String.format("Send message async Exception, %s", message), e);
                 ONSClientException onsEx = checkProducerException(message.getTopic(), message.getMsgID(), e);
                 OnExceptionContext context = new OnExceptionContext();
                 context.setTopic(message.getTopic());


[rocketmq-ons] 02/29: Add License and Notice file

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit c9eb2296cbe0ee676c968e4f1ef409a39efc398e
Author: duhenglucky <du...@gmail.com>
AuthorDate: Fri Jun 14 22:47:04 2019 +0800

    Add License and Notice file
---
 LICENSE   | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 NOTICE    |   5 ++
 README.md |  11 +++-
 3 files changed, 216 insertions(+), 1 deletion(-)

diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..7f77f44
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (properties) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
\ No newline at end of file
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..703c28b
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,5 @@
+Apache RocketMQ
+Copyright 2016-2018 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
\ No newline at end of file
diff --git a/README.md b/README.md
index 868fecc..cae1bae 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,11 @@
 ## Overview
-### Apache RocketMQ lightweight client.
+ Apache RocketMQ ons is a RocketMQ lightweight client.
+
+----------
+## Contributing
+We always welcome new contributions, whether for trivial cleanups, big new features or other material rewards, more details see [here](http://rocketmq.apache.org/docs/how-to-contribute/).
+ 
+----------
+## License
+[Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html) Copyright (C) Apache Software Foundation
+


[rocketmq-ons] 16/29: Update README.md

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit 17916c20cc615b67413919fa2488e1c327bccff5
Author: Heng Du <du...@gmail.com>
AuthorDate: Wed Jul 3 14:38:31 2019 +0800

    Update README.md
---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index cae1bae..6ad473d 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
 ## Overview
- Apache RocketMQ ons is a RocketMQ lightweight client.
+ Apache RocketMQ ONS is a RocketMQ lightweight client.
 
 ----------
 ## Contributing


[rocketmq-ons] 04/29: Fix the issue that exception callback can not be called when doing async sending message with null topic

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit 7af9b5793010069d49ff720c397c924a5a598fc1
Author: ShannonDing <li...@163.com>
AuthorDate: Mon Jun 17 15:25:04 2019 +0800

    Fix the issue that exception callback can not be called when doing async sending message with null topic
---
 .../org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java     | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java
index bd1dede..6118435 100644
--- a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java
@@ -192,11 +192,11 @@ public class ProducerImpl extends ONSClientAbstract implements Producer {
 
             @Override
             public void onException(Throwable e) {
-                String topic = new String(message.getTopic());
+                //String topic = new String(message.getTopic());
                 String msgId = new String(message.getMsgID());
-                ONSClientException onsEx = checkProducerException(topic, msgId, e);
+                ONSClientException onsEx = checkProducerException(message.getTopic(), msgId, e);
                 OnExceptionContext context = new OnExceptionContext();
-                context.setTopic(topic);
+                context.setTopic(message.getTopic());
                 context.setMessageId(msgId);
                 context.setException(onsEx);
                 sendCallback.onException(context);


[rocketmq-ons] 09/29: Merge remote-tracking branch 'origin' into graalvm-sdk

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit ee4b1bf6e0f4a95386e8d7680fa440760368a9dc
Merge: 4768702 4a72b44
Author: ShannonDing <li...@163.com>
AuthorDate: Mon Jun 17 17:43:58 2019 +0800

    Merge remote-tracking branch 'origin' into graalvm-sdk

 .../apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java    | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)



[rocketmq-ons] 07/29: Keep runtime exception throw

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit 2a87d338e3fa56f54fa70fd1d335bd02150f0961
Author: ShannonDing <li...@163.com>
AuthorDate: Mon Jun 17 17:17:37 2019 +0800

    Keep runtime exception throw
---
 .../rocketmq/ons/api/impl/rocketmq/ProducerImpl.java       | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java
index 921861a..9710b33 100644
--- a/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java
+++ b/ons-core/ons-client/src/main/java/org/apache/rocketmq/ons/api/impl/rocketmq/ProducerImpl.java
@@ -169,13 +169,7 @@ public class ProducerImpl extends ONSClientAbstract implements Producer {
             message.setMsgID(MessageClientIDSetter.getUniqID(msgRMQ));
         } catch (Exception e) {
             LOGGER.error(String.format("Send message async Exception, %s", message), e);
-            //throw checkProducerException(message.getTopic(), message.getMsgID(), e);
-            ONSClientException clientException = checkProducerException(message.getTopic(), message.getMsgID(), e);
-            OnExceptionContext context = new OnExceptionContext();
-            context.setException(clientException);
-            context.setTopic(message.getTopic());
-            context.setMessageId(message.getMsgID());
-            sendCallback.onException(context);
+            throw checkProducerException(message.getTopic(), message.getMsgID(), e);
         }
     }
 
@@ -199,11 +193,11 @@ public class ProducerImpl extends ONSClientAbstract implements Producer {
             @Override
             public void onException(Throwable e) {
                 //String topic = new String(message.getTopic());
-                String msgId = new String(message.getMsgID());
-                ONSClientException onsEx = checkProducerException(message.getTopic(), msgId, e);
+                //String msgId = new String(message.getMsgID());
+                ONSClientException onsEx = checkProducerException(message.getTopic(), message.getMsgID(), e);
                 OnExceptionContext context = new OnExceptionContext();
                 context.setTopic(message.getTopic());
-                context.setMessageId(msgId);
+                context.setMessageId(message.getMsgID());
                 context.setException(onsEx);
                 sendCallback.onException(context);
             }


[rocketmq-ons] 26/29: Remove subscribe method in Pullconsumer

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit fe991caffbd36a7d30deaa746886ad93b30348f1
Author: duhenglucky <du...@gmail.com>
AuthorDate: Fri Jul 26 11:52:55 2019 +0800

    Remove subscribe method in Pullconsumer
---
 .../org/apache/rocketmq/ons/api/PullConsumer.java  | 95 +++++++++++-----------
 .../api/{MessageQueue.java => TopicPartition.java} | 26 +++---
 ons-sample/pom.xml                                 |  4 +-
 3 files changed, 62 insertions(+), 63 deletions(-)

diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PullConsumer.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PullConsumer.java
index e4910f2..6043183 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PullConsumer.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PullConsumer.java
@@ -20,31 +20,49 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Set;
 
-public interface PullConsumer extends LifeCycle, Credentials {
+public interface PullConsumer {
+
+    interface TopicPartitionChangeListener {
+        /**
+         * This method will be invoked in the condition of partition numbers changed, These scenarios occur when the
+         * topic is expanded or shrunk.
+         *
+         * @param topicPartitions
+         */
+        void onChanged(Set<TopicPartition> topicPartitions);
+    }
+
     /**
-     * Subscribe to the given list of topics to get dynamically assigned message queues.
+     * Get metadata about the partitions for a given topic. This method will issue a remote call to the server if it
+     * does not already have any metadata about the given topic.
      *
-     * @param topics
+     * @param topic
+     * @return
      */
-    void subscribe(final Collection<String> topics);
+    Set<TopicPartition> topicPartitions(String topic);
 
     /**
-     * Subscribe to the given list of topics to get dynamically assigned message queues with filters.
+     * Manually assign a list of partitions to this consumer. This interface does not allow for incremental assignment
+     * and will replace the previous assignment (if there is one).
      *
-     * @param topics
+     * If auto-commit is enabled, an async commit (based on the old assignment) will be triggered before the new
+     * assignment replaces the old one.
+     *
+     * @param topicPartitions
      */
-    void subscribe(final Collection<String> topics, final String subExpression);
+    void assign(Collection<TopicPartition> topicPartitions);
 
     /**
-     * Unsubscribe the given list of topics.
+     * Register a callback for sensing topic metadata changes.
      *
-     * @param topics
+     * @param topic
+     * @param callback
      */
-    void unsubscribe(final Collection<String> topics);
+    void registerTopicPartitionChangedListener(String topic, TopicPartitionChangeListener callback);
 
     /**
-     * Fetch data for the topics or partitions specified using subscribe API. It is an error to not have subscribed to
-     * any topics or partitions before polling for data.
+     * Fetch data for the topics or partitions specified using assign API. It is an error to not have subscribed to any
+     * topics or partitions before polling for data.
      *
      * @param timeout
      * @return
@@ -52,30 +70,30 @@ public interface PullConsumer extends LifeCycle, Credentials {
     List<Message> poll(long timeout);
 
     /**
-     * Overrides the fetch offsets that the consumer will use on the next {@link #poll(long)}. If this API is invoked
+     * Overrides the fetch offsets that the consumer will use on the next {@link #poll(long)} }. If this API is invoked
      * for the same message queue more than once, the latest offset will be used on the next poll(). Note that you may
      * lose data if this API is arbitrarily used in the middle of consumption.
      *
-     * @param messageQueue
+     * @param topicPartition
      * @param offset
      */
-    void seek(MessageQueue messageQueue, long offset);
+    void seek(TopicPartition topicPartition, long offset);
 
     /**
      * Overrides the fetch offsets with the beginning offset in server that the consumer will use on the next {@link
-     * #poll(long)}.
+     * #poll(long)} }.
      *
-     * @param messageQueue
+     * @param topicPartition
      */
-    void seekToBeginning(MessageQueue messageQueue);
+    void seekToBeginning(TopicPartition topicPartition);
 
     /**
      * Overrides the fetch offsets with the end offset in server that the consumer will use on the next {@link
-     * #poll(long)}.
+     * #poll(long)} }.
      *
-     * @param messageQueue
+     * @param topicPartition
      */
-    void seekToEnd(MessageQueue messageQueue);
+    void seekToEnd(TopicPartition topicPartition);
 
     /**
      * Suspend fetching from the requested message queues. Future calls to {@link #poll(long)} will not return any
@@ -84,56 +102,37 @@ public interface PullConsumer extends LifeCycle, Credentials {
      * Note that this method does not affect message queue subscription. In particular, it does not cause a group
      * rebalance.
      *
-     * @param messageQueues
+     * @param topicPartitions
      */
-    void pause(Collection<MessageQueue> messageQueues);
+    void pause(Collection<TopicPartition> topicPartitions);
 
     /**
      * Resume specified message queues which have been paused with {@link #pause(Collection)}. New calls to {@link
      * #poll(long)} will return records from these partitions if there are any to be fetched. If the message queues were
      * not previously paused, this method is a no-op.
      *
-     * @param messageQueues
+     * @param topicPartitions
      */
-    void resume(Collection<MessageQueue> messageQueues);
-
-    /**
-     * Get metadata about the partitions for a given topic. This method will issue a remote call to the server if it
-     * does not already have any metadata about the given topic.
-     *
-     * @param topic
-     * @return
-     */
-    Set<MessageQueue> messageQueues(String topic);
+    void resume(Collection<TopicPartition> topicPartitions);
 
     /**
      * Look up the offsets for the given message queue by timestamp. The returned offset for each message queue is the
      * earliest offset whose timestamp is greater than or equal to the given timestamp in the corresponding message
      * queue.
      *
-     * @param messageQueue
+     * @param topicPartition
      * @param timestamp
      * @return
      */
-    Long offsetForTimestamp(MessageQueue messageQueue, Long timestamp);
+    Long offsetForTimestamp(TopicPartition topicPartition, Long timestamp);
 
     /**
      * Get the last committed offset for the given message queue (whether the commit happened by this process or
      * another). This offset will be used as the position for the consumer in the event of a failure.
      *
-     * @param messageQueue
+     * @param topicPartition
      * @return
      */
-    Long committed(MessageQueue messageQueue);
+    Long committed(TopicPartition topicPartition);
 
-    /**
-     * Commit the last offset that has been stored securely. Should the process fail and restart, this is the offset
-     * that the consumer will recover to. The consumer can either automatically commit offsets periodically;
-     */
-    void commit();
-
-    /**
-     * Wakeup the consumer. This method is thread-safe and is useful in particular to abort a long poll.
-     */
-    void wakeup();
 }
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageQueue.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/TopicPartition.java
similarity index 75%
rename from ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageQueue.java
rename to ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/TopicPartition.java
index 55f9c75..82ff1b1 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/MessageQueue.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/TopicPartition.java
@@ -16,14 +16,14 @@
  */
 package org.apache.rocketmq.ons.api;
 
-public class MessageQueue {
+public class TopicPartition {
     private String topic;
 
-    private String queue;
+    private String partition;
 
-    public MessageQueue(String topic, String queue) {
+    public TopicPartition(String topic, String partition) {
         this.topic = topic;
-        this.queue = queue;
+        this.partition = partition;
     }
 
     public String getTopic() {
@@ -34,12 +34,12 @@ public class MessageQueue {
         this.topic = topic;
     }
 
-    public String getQueue() {
-        return queue;
+    public String getPartition() {
+        return partition;
     }
 
-    public void setQueue(String queue) {
-        this.queue = queue;
+    public void setPartition(String partition) {
+        this.partition = partition;
     }
 
     @Override
@@ -47,7 +47,7 @@ public class MessageQueue {
         final int prime = 31;
         int result = 1;
         result = prime * result + ((topic == null) ? 0 : topic.hashCode());
-        result = prime * result + ((queue == null) ? 0 : queue.hashCode());
+        result = prime * result + ((partition == null) ? 0 : partition.hashCode());
         return result;
     }
 
@@ -59,12 +59,12 @@ public class MessageQueue {
             return false;
         if (getClass() != obj.getClass())
             return false;
-        MessageQueue other = (MessageQueue) obj;
-        if (queue == null) {
-            if (other.queue != null) {
+        TopicPartition other = (TopicPartition) obj;
+        if (partition == null) {
+            if (other.partition != null) {
                 return false;
             }
-        } else if (!queue.equals(other.queue)) {
+        } else if (!partition.equals(other.partition)) {
             return false;
         }
         if (topic == null) {
diff --git a/ons-sample/pom.xml b/ons-sample/pom.xml
index 710b0af..667d6fe 100644
--- a/ons-sample/pom.xml
+++ b/ons-sample/pom.xml
@@ -31,12 +31,12 @@
         <dependency>
             <groupId>org.apache.rocketmq</groupId>
             <artifactId>ons-api</artifactId>
-            <version>1.0.1-SNAPSHOT</version>
+            <version>${project.version}</version>
         </dependency>
         <dependency>
             <groupId>org.apache.rocketmq</groupId>
             <artifactId>ons-client</artifactId>
-            <version>1.0.1-SNAPSHOT</version>
+            <version>${project.version}</version>
         </dependency>
     </dependencies>
 


[rocketmq-ons] 27/29: Polish pull consumer poll method

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit ea416451b92ad81e0d537bd001afd5512dbd1d1d
Author: duhenglucky <du...@gmail.com>
AuthorDate: Fri Aug 30 11:15:39 2019 +0800

    Polish pull consumer poll method
---
 .../java/org/apache/rocketmq/ons/api/PullConsumer.java  | 17 +++++++++++------
 .../org/apache/rocketmq/ons/api/bean/ProducerBean.java  |  2 --
 ons-core/pom.xml                                        |  6 ++----
 3 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PullConsumer.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PullConsumer.java
index 6043183..d7f60a8 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PullConsumer.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/PullConsumer.java
@@ -19,6 +19,7 @@ package org.apache.rocketmq.ons.api;
 import java.util.Collection;
 import java.util.List;
 import java.util.Set;
+import java.time.Duration;
 
 public interface PullConsumer {
 
@@ -67,10 +68,10 @@ public interface PullConsumer {
      * @param timeout
      * @return
      */
-    List<Message> poll(long timeout);
+    List<Message> poll(Duration timeout);
 
     /**
-     * Overrides the fetch offsets that the consumer will use on the next {@link #poll(long)} }. If this API is invoked
+     * Overrides the fetch offsets that the consumer will use on the next {@link #poll(Duration)} }. If this API is invoked
      * for the same message queue more than once, the latest offset will be used on the next poll(). Note that you may
      * lose data if this API is arbitrarily used in the middle of consumption.
      *
@@ -81,7 +82,7 @@ public interface PullConsumer {
 
     /**
      * Overrides the fetch offsets with the beginning offset in server that the consumer will use on the next {@link
-     * #poll(long)} }.
+     * #poll(Duration)} }.
      *
      * @param topicPartition
      */
@@ -89,14 +90,14 @@ public interface PullConsumer {
 
     /**
      * Overrides the fetch offsets with the end offset in server that the consumer will use on the next {@link
-     * #poll(long)} }.
+     * #poll(Duration)} }.
      *
      * @param topicPartition
      */
     void seekToEnd(TopicPartition topicPartition);
 
     /**
-     * Suspend fetching from the requested message queues. Future calls to {@link #poll(long)} will not return any
+     * Suspend fetching from the requested message queues. Future calls to {@link #poll(Duration)} will not return any
      * records from these message queues until they have been resumed using {@link #resume(Collection)}.
      *
      * Note that this method does not affect message queue subscription. In particular, it does not cause a group
@@ -108,7 +109,7 @@ public interface PullConsumer {
 
     /**
      * Resume specified message queues which have been paused with {@link #pause(Collection)}. New calls to {@link
-     * #poll(long)} will return records from these partitions if there are any to be fetched. If the message queues were
+     * #poll(Duration)} will return records from these partitions if there are any to be fetched. If the message queues were
      * not previously paused, this method is a no-op.
      *
      * @param topicPartitions
@@ -135,4 +136,8 @@ public interface PullConsumer {
      */
     Long committed(TopicPartition topicPartition);
 
+    /**
+     * Sync commit current consumed offset to server.
+     */
+    void commitSync();
 }
diff --git a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/ProducerBean.java b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/ProducerBean.java
index 548cc82..1036253 100644
--- a/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/ProducerBean.java
+++ b/ons-core/ons-api/src/main/java/org/apache/rocketmq/ons/api/bean/ProducerBean.java
@@ -98,12 +98,10 @@ public class ProducerBean implements Producer {
     }
 
     @Override public SendResult send(Message message, String shardingKey) {
-        //TODO
         return null;
     }
 
     @Override public SendResult send(Collection<Message> messages) {
-        //TODO
         return null;
     }
 }
diff --git a/ons-core/pom.xml b/ons-core/pom.xml
index 27e4142..862c623 100644
--- a/ons-core/pom.xml
+++ b/ons-core/pom.xml
@@ -41,14 +41,12 @@
         <maven.jdoc.skip>true</maven.jdoc.skip>
         <downloadSources>true</downloadSources>
         <!-- compiler settings properties -->
-        <java_source_version>1.6</java_source_version>
-        <java_target_version>1.6</java_target_version>
+        <java_source_version>1.8</java_source_version>
+        <java_target_version>1.8</java_target_version>
         <file_encoding>UTF-8</file_encoding>
         <!-- Always use stable version of RocketMQ -->
         <rocketmq.version>4.5.1</rocketmq.version>
         <auth.version>${project.version}</auth.version>
-        <spring.version>4.1.2.RELEASE</spring.version>
-        <diamond.version>3.7.4</diamond.version>
     </properties>
     <build>
         <plugins>


[rocketmq-ons] 11/29: Merge pull request #3 from ShannonDing/graalvm-sdk

Posted by du...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

duhengforever pushed a commit to branch pullConsumer
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons.git

commit 2e94e3e68e0aa88b34cc5c03b8a753f5f58eaa81
Merge: 4a72b44 64fd96e
Author: Heng Du <du...@gmail.com>
AuthorDate: Fri Jun 28 11:36:19 2019 +0800

    Merge pull request #3 from ShannonDing/graalvm-sdk
    
    Add language identifier to support cpp native image

 .../src/main/java/org/apache/rocketmq/ons/api/Message.java | 14 ++++++++++----
 .../java/org/apache/rocketmq/ons/api/PropertyKeyConst.java |  2 ++
 .../ons/api/impl/rocketmq/ONSConsumerAbstract.java         |  7 ++++++-
 .../rocketmq/ons/api/impl/rocketmq/OrderProducerImpl.java  |  7 ++++++-
 .../rocketmq/ons/api/impl/rocketmq/ProducerImpl.java       |  8 +++++++-
 .../ons/api/impl/rocketmq/TransactionProducerImpl.java     |  7 ++++++-
 6 files changed, 37 insertions(+), 8 deletions(-)