Merge pull request #84 (merge rpc module into commons)

refact(rpc): merge rpc module into commons
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 780d51e..8445d0a 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -11,7 +11,7 @@
         ### Note (特别注意) : 
 
         > 1. 请先**搜索**现有的[Server-Issues](https://github.com/hugegraph/hugegraph/issues) 与
-        [Common-Issues](https://github.com/hugegraph/hugegraph-common/issues) 中没有与您相同
+        [Commons-Issues](https://github.com/hugegraph/hugegraph-commons/issues) 中没有与您相同
         / 相关的问题 (请勿重复提交)
 
         > 2. 我们需要尽可能**详细**的信息来**复现**问题, 越详细的信息 (包括**日志 / 截图 / 配置**等)
@@ -35,7 +35,7 @@
     attributes:
       label: Before submit
       options:
-        - label: 我已经确认现有的 [Server-Issues](https://github.com/hugegraph/hugegraph/issues) 与 [Common-Issues](https://github.com/hugegraph/hugegraph-common/issues) 中没有相同 / 重复问题
+        - label: 我已经确认现有的 [Server-Issues](https://github.com/hugegraph/hugegraph/issues) 与 [Commons-Issues](https://github.com/hugegraph/hugegraph-commons/issues) 中没有相同 / 重复问题
           required: true
 
   - type: textarea
diff --git a/.github/ISSUE_TEMPLATE/question_ask.yml b/.github/ISSUE_TEMPLATE/question_ask.yml
index 6a57883..9724e66 100644
--- a/.github/ISSUE_TEMPLATE/question_ask.yml
+++ b/.github/ISSUE_TEMPLATE/question_ask.yml
@@ -9,7 +9,7 @@
         ### Note (特别注意) : 
 
         > 1. 请先**搜索**现有的[Server-Issues](https://github.com/hugegraph/hugegraph/issues) 与
-        [Common-Issues](https://github.com/hugegraph/hugegraph-common/issues) 中没有与您相同
+        [Commons-Issues](https://github.com/hugegraph/hugegraph-commons/issues) 中没有与您相同
         / 相关的问题 (请勿重复提交)
 
         > 2. 我们需要尽可能**详细**的信息来**复现**问题, 越详细的信息 (包括**日志 / 截图 / 配置**等)
@@ -33,7 +33,7 @@
     attributes:
       label: Before submit
       options:
-        - label: 我已经确认现有的 [Server-Issues](https://github.com/hugegraph/hugegraph/issues) 与 [Common-Issues](https://github.com/hugegraph/hugegraph-common/issues) 中没有相同 / 重复问题
+        - label: 我已经确认现有的 [Server-Issues](https://github.com/hugegraph/hugegraph/issues) 与 [Commons-Issues](https://github.com/hugegraph/hugegraph-commons/issues) 中没有相同 / 重复问题
           required: true
 
   - type: textarea
diff --git a/.travis.yml b/.github/outdated/.travis.yml
similarity index 100%
rename from .travis.yml
rename to .github/outdated/.travis.yml
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5dda168..a09093a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,4 +1,4 @@
-name: hugegraph-common ci
+name: hugegraph-commons ci
 
 on:
   push:
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
index 1813bd3..93e1bd1 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -20,14 +20,16 @@
         stale-pr-message: 'Due to the lack of activity, the current pr is marked as stale and will be closed after 180 days, any update will remove the stale label'
         stale-issue-label: 'inactive'
         stale-pr-label: 'inactive'
-        exempt-issue-labels: 'feature,bug,enhancement,improvement,wontfix,todo'
+        exempt-issue-labels: 'feature,bug,enhancement,improvement,wontfix,todo,help wanted'
+        exempt-pr-labels: 'feature,bug,enhancement,improvement,wontfix,todo,help wanted'
+        exempt-all-milestones: true
 
         days-before-issue-stale: 15
         days-before-issue-close: 20
         days-before-pr-stale: 30
         days-before-pr-close: 180
         operations-per-run: 10
-        start-date: '2018-12-01T00:00:00Z'
+        start-date: '2018-10-01T00:00:00Z'
 
         exempt-all-assignees: true
         remove-stale-when-updated: true
diff --git a/.gitignore b/.gitignore
index d851342..fa22f58 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,4 @@
 target
 gen-java
 build
+node*
diff --git a/BCLOUD b/BCLOUD
deleted file mode 100644
index df3f342..0000000
--- a/BCLOUD
+++ /dev/null
@@ -1 +0,0 @@
-BUILD_SUBMITTER -x -u ./ -e CENTOS6U3 -m baidu/xbu-data/hugegraph-common -c "export MAVEN_HOME=/home/scmtools/buildkit/maven/apache-maven-3.3.9/ && export JAVA_HOME=/home/scmtools/buildkit/java/jdk1.8.0_25/ && export PATH=$JAVA_HOME/bin:$MAVEN_HOME/bin:$PATH && cd baidu/xbu-data/hugegraph-common && mkdir output && sh build.sh" -o output
\ No newline at end of file
diff --git a/README.md b/README.md
index d311524..3d669eb 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,11 @@
-# hugegraph-common
+# hugegraph-commons
 
 [![License](https://img.shields.io/badge/license-Apache%202-0E78BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
-[![Build Status](https://travis-ci.org/hugegraph/hugegraph-common.svg?branch=master)](https://travis-ci.org/hugegraph/hugegraph-common)
 [![codecov](https://codecov.io/gh/hugegraph/hugegraph-common/branch/master/graph/badge.svg)](https://codecov.io/gh/hugegraph/hugegraph-common)
 [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.baidu.hugegraph/hugegraph-common/badge.svg)](https://mvnrepository.com/artifact/com.baidu.hugegraph/hugegraph-common)
 
-hugegraph-common is a common module for [HugeGraph](https://github.com/hugegraph/hugegraph) and its peripheral components.
-hugegraph-common encapsulates locks, configurations, events, iterators, rest and some 
+hugegraph-commons is a common module for [HugeGraph](https://github.com/hugegraph/hugegraph) and its peripheral components.
+hugegraph-commons encapsulates locks, configurations, events, iterators, rest and some 
 numeric or collection util classes to simplify the development of HugeGraph and 
 its components.
 
@@ -17,7 +16,8 @@
 - Event: listening and notification, do something asynchronously
 - Iterator: some iterators with extra functions, map, filter, extend etc.
 - Rest: RESTful client implemented on Jersey, POST, PUT, GET and DELETE
-- Util: Performance analyzer, version checker, numeric and Collection utils, log and exception utils etc.
+- Util: performance analyzer, version checker, numeric and Collection utils, log and exception utils etc.
+- Rpc: rpc component for inner module communication, currently it's based on [Sofa-RPC](https://github.com/sofastack/sofa-rpc)
 
 ## Licence
-The same as HugeGraph, hugegraph-common is also licensed under Apache 2.0 License.
+The same as HugeGraph, hugegraph-commons is also licensed under Apache 2.0 License.
diff --git a/hugegraph-common/LICENSE b/hugegraph-common/LICENSE
new file mode 100644
index 0000000..e06d208
--- /dev/null
+++ b/hugegraph-common/LICENSE
@@ -0,0 +1,202 @@
+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 (i) 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.
+
diff --git a/hugegraph-common/README.md b/hugegraph-common/README.md
new file mode 100644
index 0000000..d311524
--- /dev/null
+++ b/hugegraph-common/README.md
@@ -0,0 +1,23 @@
+# hugegraph-common
+
+[![License](https://img.shields.io/badge/license-Apache%202-0E78BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
+[![Build Status](https://travis-ci.org/hugegraph/hugegraph-common.svg?branch=master)](https://travis-ci.org/hugegraph/hugegraph-common)
+[![codecov](https://codecov.io/gh/hugegraph/hugegraph-common/branch/master/graph/badge.svg)](https://codecov.io/gh/hugegraph/hugegraph-common)
+[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.baidu.hugegraph/hugegraph-common/badge.svg)](https://mvnrepository.com/artifact/com.baidu.hugegraph/hugegraph-common)
+
+hugegraph-common is a common module for [HugeGraph](https://github.com/hugegraph/hugegraph) and its peripheral components.
+hugegraph-common encapsulates locks, configurations, events, iterators, rest and some 
+numeric or collection util classes to simplify the development of HugeGraph and 
+its components.
+
+## Components
+
+- Lock: atomic lock, key lock, lock group and lock manger
+- Config: register and load config option with security check
+- Event: listening and notification, do something asynchronously
+- Iterator: some iterators with extra functions, map, filter, extend etc.
+- Rest: RESTful client implemented on Jersey, POST, PUT, GET and DELETE
+- Util: Performance analyzer, version checker, numeric and Collection utils, log and exception utils etc.
+
+## Licence
+The same as HugeGraph, hugegraph-common is also licensed under Apache 2.0 License.
diff --git a/build.sh b/hugegraph-common/build.sh
similarity index 100%
rename from build.sh
rename to hugegraph-common/build.sh
diff --git a/hugegraph-common/checkstyle.xml b/hugegraph-common/checkstyle.xml
new file mode 100644
index 0000000..9373a70
--- /dev/null
+++ b/hugegraph-common/checkstyle.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC
+        "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
+        "https://checkstyle.org/dtds/configuration_1_3.dtd">
+<!-- 参考:https://checkstyle.sourceforge.io/checks.html -->
+<module name="Checker">
+    <!--检查不通过时被判定的违规级别,必须修复后才能使build通过-->
+    <property name="severity" value="error"/>
+    <!--对java文件做检查-->
+    <property name="fileExtensions" value="java"/>
+    <!--对UTF-8编码的文件做检查-->
+    <property name="charset" value="UTF-8"/>
+    <!--文件中不允许包含制表符-->
+    <module name="FileTabCharacter">
+        <property name="eachLine" value="true"/>
+    </module>
+
+    <!--检查java源文件并定义一些适用于检查此类文件的一些属性-->
+    <module name="TreeWalker">
+        <!--检查行长度-->
+        <module name="LineLength">
+            <property name="max" value="80"/>
+            <!--可以忽略的行-->
+            <property name="ignorePattern"
+                      value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
+        </module>
+        <!--检查没有import语句使用*号-->
+        <module name="AvoidStarImport"/>
+        <!--检查是否存在多余的import语句,比如重复的,java自带的包,相同包下的其他类-->
+        <module name="RedundantImport"/>
+        <!--检查是否存在没有使用的import语句-->
+        <module name="UnusedImports"/>
+        <!--检查包名称是否遵守命名规约-->
+        <module name="PackageName">
+            <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
+        </module>
+        <!--检查局部变量的名称是否遵守命名规约-->
+        <module name="LocalVariableName">
+            <property name="format" value="^[a-z][a-zA-Z0-9_]*$"/>
+        </module>
+        <!--检查成员变量(非静态字段)的名称是否遵守命名规约-->
+        <module name="MemberName">
+            <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
+        </module>
+        <!--检查方法名称是否遵守命名规约-->
+        <module name="MethodName">
+            <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
+        </module>
+        <!--检查参数名称是否遵守命名规约-->
+        <module name="ParameterName">
+            <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
+        </module>
+        <!--检查常量(用static final修饰的字段)的名称是否遵守命名规约-->
+        <module name="ConstantName">
+            <property name="format" value="^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$"/>
+        </module>
+        <!--检查数组是否属于java风格,方括号放在类型后面,而不是变量后面,比如:int[] nums(合法),int nums[](不合法)-->
+        <module name="ArrayTypeStyle">
+            <property name="javaStyle" value="true"/>
+        </module>
+        <!--long类型的字面量如果要以"L"结尾,必须是大写的"L",而非小写的"l"-->
+        <module name="UpperEll"/>
+        <!--代码换行时,运算符必须在当前行的末尾,比如:+、&&、?、: 等-->
+        <module name="OperatorWrap">
+            <property name="option" value="eol"/>
+        </module>
+        <!--检查指定标记的周围是否有空格,比如:if、for、while、synchoronized 等-->
+        <module name="WhitespaceAround"/>
+        <!--左圆括号之后和右圆括号之前是否需要有一个空格,不需要-->
+        <module name="ParenPad"/>
+        <!--检查修饰符是否符合Java建议,顺序是:public、protected、private、abstract、default、static、final、transient、volatile、synchronized、native、strictfp-->
+        <module name="ModifierOrder"/>
+        <!--检查代码块的左花括号的放置位置,必须在当前行的末尾-->
+        <module name="LeftCurly">
+            <property name="option" value="eol"/>
+            <property name="ignoreEnums" value="false"/>
+        </module>
+        <!--代码中不允许有空语句,也就是单独的;符号-->
+        <module name="EmptyStatement"/>
+        <!--覆盖equals()方法的类必须也覆盖了hashCode()方法-->
+        <module name="EqualsHashCode"/>
+        <!--switch语句必须含有default子句-->
+        <module name="MissingSwitchDefault"/>
+        <!--switch语句的default必须放在所有的case分支之后-->
+        <module name="DefaultComesLast"/>
+        <!--覆盖clone()方法时调用了super.clone()方法-->
+        <module name="SuperClone"/>
+    </module>
+</module>
diff --git a/hugegraph-common/pom.xml b/hugegraph-common/pom.xml
new file mode 100644
index 0000000..4b35592
--- /dev/null
+++ b/hugegraph-common/pom.xml
@@ -0,0 +1,321 @@
+<?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">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.baidu.hugegraph</groupId>
+        <artifactId>hugegraph-commons</artifactId>
+        <version>1.8.10</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>hugegraph-common</artifactId>
+    <name>hugegraph-common</name>
+    <url>https://github.com/hugegraph/hugegraph-common</url>
+    <description>
+        hugegraph-common is a common module for HugeGraph and its peripheral components.
+        hugegraph-common encapsulates locks, configurations, events, iterators, rest and some
+        numeric or collection util classes to simplify the development of HugeGraph and its components.
+    </description>
+
+    <properties>
+        <!-- Use parent params -->
+    </properties>
+
+    <dependencies>
+        <!-- Test -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>${junit.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>${mockito.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <!-- Logging -->
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-api</artifactId>
+            <version>${log4j2.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-core</artifactId>
+            <version>${log4j2.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j-impl</artifactId>
+            <version>${log4j2.version}</version>
+        </dependency>
+
+        <!-- Utility -->
+        <dependency>
+            <groupId>org.glassfish</groupId>
+            <artifactId>javax.json</artifactId>
+            <version>${javax.json.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-configuration</groupId>
+            <artifactId>commons-configuration</artifactId>
+            <version>${commons.configuration.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-configuration2</artifactId>
+            <version>${commons.configuration2.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>${commons.io.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-collections</groupId>
+            <artifactId>commons-collections</artifactId>
+            <version>${commons.collections.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+            <version>${commons.codec.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>${guava.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.code.findbugs</groupId>
+            <artifactId>jsr305</artifactId>
+            <version>${jsr305.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+            <version>2.10.8</version>
+        </dependency>
+
+        <!-- javassist -->
+        <dependency>
+            <groupId>org.javassist</groupId>
+            <artifactId>javassist</artifactId>
+            <version>${javassist.version}</version>
+        </dependency>
+
+        <!-- jackson -->
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.module</groupId>
+            <artifactId>jackson-module-jaxb-annotations</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.jaxrs</groupId>
+            <artifactId>jackson-jaxrs-base</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.jaxrs</groupId>
+            <artifactId>jackson-jaxrs-json-provider</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
+
+        <!-- jersey -->
+        <dependency>
+            <groupId>org.glassfish.jersey.core</groupId>
+            <artifactId>jersey-client</artifactId>
+            <version>${jersey.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.media</groupId>
+            <artifactId>jersey-media-json-jackson</artifactId>
+            <version>${jersey.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.fasterxml.jackson.jaxrs</groupId>
+                    <artifactId>jackson-jaxrs-base</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>com.fasterxml.jackson.jaxrs</groupId>
+                    <artifactId>jackson-jaxrs-json-provider</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.connectors</groupId>
+            <artifactId>jersey-apache-connector</artifactId>
+            <version>${jersey.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.inject</groupId>
+            <artifactId>jersey-hk2</artifactId>
+            <version>${jersey.hk2.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>de.schlichtherle.truelicense</groupId>
+            <artifactId>truelicense-core</artifactId>
+            <version>1.33</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.1</version>
+                <configuration>
+                    <source>${compiler.source}</source>
+                    <target>${compiler.target}</target>
+                    <compilerArguments>
+                        <Xmaxerrs>500</Xmaxerrs>
+                    </compilerArguments>
+                    <compilerArgs>
+                        <arg>-Xlint:unchecked</arg>
+                    </compilerArgs>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <version>3.1.0</version>
+                <configuration>
+                    <configLocation>checkstyle.xml</configLocation>
+                    <encoding>UTF-8</encoding>
+                    <consoleOutput>true</consoleOutput>
+                    <failsOnError>true</failsOnError>
+                    <linkXRef>false</linkXRef>
+                    <includeTestSourceDirectory>false</includeTestSourceDirectory>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>validate</id>
+                        <phase>validate</phase>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>2.6</version>
+                <configuration>
+                    <archive>
+                        <index>true</index>
+                        <manifest>
+                            <addDefaultImplementationEntries>
+                                false
+                            </addDefaultImplementationEntries>
+                            <addDefaultSpecificationEntries>
+                                true
+                            </addDefaultSpecificationEntries>
+                        </manifest>
+                        <manifestEntries>
+                            <!-- Must be on one line, otherwise the automatic
+                                 upgrade script cannot replace the version number -->
+                            <Implementation-Version>1.8.9.0</Implementation-Version>
+                        </manifestEntries>
+                    </archive>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.jacoco</groupId>
+                <artifactId>jacoco-maven-plugin</artifactId>
+                <version>0.8.2</version>
+                <executions>
+                    <execution>
+                        <id>pre-unit-test</id>
+                        <goals>
+                            <goal>prepare-agent</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>post-unit-test</id>
+                        <phase>test</phase>
+                        <goals>
+                            <goal>report</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.parent.build.directory}</outputDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>release</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-source-plugin</artifactId>
+                        <version>2.2.1</version>
+                        <executions>
+                            <execution>
+                                <id>attach-sources</id>
+                                <goals>
+                                    <goal>jar-no-fork</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-javadoc-plugin</artifactId>
+                        <version>2.9.1</version>
+                        <executions>
+                            <execution>
+                                <id>attach-javadocs</id>
+                                <goals>
+                                    <goal>jar</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-gpg-plugin</artifactId>
+                        <version>1.5</version>
+                        <executions>
+                            <execution>
+                                <id>sign-artifacts</id>
+                                <phase>verify</phase>
+                                <goals>
+                                    <goal>sign</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/src/main/java/com/baidu/hugegraph/concurrent/AtomicLock.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/concurrent/AtomicLock.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/concurrent/AtomicLock.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/concurrent/AtomicLock.java
diff --git a/src/main/java/com/baidu/hugegraph/concurrent/BarrierEvent.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/concurrent/BarrierEvent.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/concurrent/BarrierEvent.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/concurrent/BarrierEvent.java
diff --git a/src/main/java/com/baidu/hugegraph/concurrent/KeyLock.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/concurrent/KeyLock.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/concurrent/KeyLock.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/concurrent/KeyLock.java
diff --git a/src/main/java/com/baidu/hugegraph/concurrent/LockGroup.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/concurrent/LockGroup.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/concurrent/LockGroup.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/concurrent/LockGroup.java
diff --git a/src/main/java/com/baidu/hugegraph/concurrent/LockManager.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/concurrent/LockManager.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/concurrent/LockManager.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/concurrent/LockManager.java
diff --git a/src/main/java/com/baidu/hugegraph/concurrent/PausableScheduledThreadPool.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/concurrent/PausableScheduledThreadPool.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/concurrent/PausableScheduledThreadPool.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/concurrent/PausableScheduledThreadPool.java
diff --git a/src/main/java/com/baidu/hugegraph/concurrent/RowLock.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/concurrent/RowLock.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/concurrent/RowLock.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/concurrent/RowLock.java
diff --git a/src/main/java/com/baidu/hugegraph/config/ConfigConvOption.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/config/ConfigConvOption.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/config/ConfigConvOption.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/config/ConfigConvOption.java
diff --git a/src/main/java/com/baidu/hugegraph/config/ConfigException.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/config/ConfigException.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/config/ConfigException.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/config/ConfigException.java
diff --git a/src/main/java/com/baidu/hugegraph/config/ConfigListConvOption.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/config/ConfigListConvOption.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/config/ConfigListConvOption.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/config/ConfigListConvOption.java
diff --git a/src/main/java/com/baidu/hugegraph/config/ConfigListOption.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/config/ConfigListOption.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/config/ConfigListOption.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/config/ConfigListOption.java
diff --git a/src/main/java/com/baidu/hugegraph/config/ConfigOption.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/config/ConfigOption.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/config/ConfigOption.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/config/ConfigOption.java
diff --git a/src/main/java/com/baidu/hugegraph/config/HugeConfig.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/config/HugeConfig.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/config/HugeConfig.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/config/HugeConfig.java
diff --git a/src/main/java/com/baidu/hugegraph/config/OptionChecker.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/config/OptionChecker.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/config/OptionChecker.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/config/OptionChecker.java
diff --git a/src/main/java/com/baidu/hugegraph/config/OptionHolder.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/config/OptionHolder.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/config/OptionHolder.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/config/OptionHolder.java
diff --git a/src/main/java/com/baidu/hugegraph/config/OptionSpace.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/config/OptionSpace.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/config/OptionSpace.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/config/OptionSpace.java
diff --git a/src/main/java/com/baidu/hugegraph/config/TypedOption.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/config/TypedOption.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/config/TypedOption.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/config/TypedOption.java
diff --git a/src/main/java/com/baidu/hugegraph/date/SafeDateFormat.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/date/SafeDateFormat.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/date/SafeDateFormat.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/date/SafeDateFormat.java
diff --git a/src/main/java/com/baidu/hugegraph/event/Event.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/event/Event.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/event/Event.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/event/Event.java
diff --git a/src/main/java/com/baidu/hugegraph/event/EventHub.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/event/EventHub.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/event/EventHub.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/event/EventHub.java
diff --git a/src/main/java/com/baidu/hugegraph/event/EventListener.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/event/EventListener.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/event/EventListener.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/event/EventListener.java
diff --git a/src/main/java/com/baidu/hugegraph/func/TriFunction.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/func/TriFunction.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/func/TriFunction.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/func/TriFunction.java
diff --git a/src/main/java/com/baidu/hugegraph/iterator/BatchMapperIterator.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/BatchMapperIterator.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/iterator/BatchMapperIterator.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/BatchMapperIterator.java
diff --git a/src/main/java/com/baidu/hugegraph/iterator/CIter.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/CIter.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/iterator/CIter.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/CIter.java
diff --git a/src/main/java/com/baidu/hugegraph/iterator/ExtendableIterator.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/ExtendableIterator.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/iterator/ExtendableIterator.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/ExtendableIterator.java
diff --git a/src/main/java/com/baidu/hugegraph/iterator/FilterIterator.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/FilterIterator.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/iterator/FilterIterator.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/FilterIterator.java
diff --git a/src/main/java/com/baidu/hugegraph/iterator/FlatMapperFilterIterator.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/FlatMapperFilterIterator.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/iterator/FlatMapperFilterIterator.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/FlatMapperFilterIterator.java
diff --git a/src/main/java/com/baidu/hugegraph/iterator/FlatMapperIterator.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/FlatMapperIterator.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/iterator/FlatMapperIterator.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/FlatMapperIterator.java
diff --git a/src/main/java/com/baidu/hugegraph/iterator/LimitIterator.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/LimitIterator.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/iterator/LimitIterator.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/LimitIterator.java
diff --git a/src/main/java/com/baidu/hugegraph/iterator/ListIterator.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/ListIterator.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/iterator/ListIterator.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/ListIterator.java
diff --git a/src/main/java/com/baidu/hugegraph/iterator/MapperIterator.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/MapperIterator.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/iterator/MapperIterator.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/MapperIterator.java
diff --git a/src/main/java/com/baidu/hugegraph/iterator/Metadatable.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/Metadatable.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/iterator/Metadatable.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/Metadatable.java
diff --git a/src/main/java/com/baidu/hugegraph/iterator/WrappedIterator.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/WrappedIterator.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/iterator/WrappedIterator.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/iterator/WrappedIterator.java
diff --git a/src/main/java/com/baidu/hugegraph/license/CommonLicenseManager.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/license/CommonLicenseManager.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/license/CommonLicenseManager.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/license/CommonLicenseManager.java
diff --git a/src/main/java/com/baidu/hugegraph/license/ExtraParam.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/license/ExtraParam.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/license/ExtraParam.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/license/ExtraParam.java
diff --git a/src/main/java/com/baidu/hugegraph/license/FileKeyStoreParam.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/license/FileKeyStoreParam.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/license/FileKeyStoreParam.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/license/FileKeyStoreParam.java
diff --git a/src/main/java/com/baidu/hugegraph/license/LicenseCreateParam.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/license/LicenseCreateParam.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/license/LicenseCreateParam.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/license/LicenseCreateParam.java
diff --git a/src/main/java/com/baidu/hugegraph/license/LicenseVerifyParam.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/license/LicenseVerifyParam.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/license/LicenseVerifyParam.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/license/LicenseVerifyParam.java
diff --git a/src/main/java/com/baidu/hugegraph/license/MachineInfo.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/license/MachineInfo.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/license/MachineInfo.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/license/MachineInfo.java
diff --git a/src/main/java/com/baidu/hugegraph/perf/LightStopwatch.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/perf/LightStopwatch.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/perf/LightStopwatch.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/perf/LightStopwatch.java
diff --git a/src/main/java/com/baidu/hugegraph/perf/NormalStopwatch.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/perf/NormalStopwatch.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/perf/NormalStopwatch.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/perf/NormalStopwatch.java
diff --git a/src/main/java/com/baidu/hugegraph/perf/PerfUtil.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/perf/PerfUtil.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/perf/PerfUtil.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/perf/PerfUtil.java
diff --git a/src/main/java/com/baidu/hugegraph/perf/Stopwatch.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/perf/Stopwatch.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/perf/Stopwatch.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/perf/Stopwatch.java
diff --git a/src/main/java/com/baidu/hugegraph/rest/AbstractRestClient.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/rest/AbstractRestClient.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/rest/AbstractRestClient.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/rest/AbstractRestClient.java
diff --git a/src/main/java/com/baidu/hugegraph/rest/ClientException.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/rest/ClientException.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/rest/ClientException.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/rest/ClientException.java
diff --git a/src/main/java/com/baidu/hugegraph/rest/RestClient.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/rest/RestClient.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/rest/RestClient.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/rest/RestClient.java
diff --git a/src/main/java/com/baidu/hugegraph/rest/RestResult.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/rest/RestResult.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/rest/RestResult.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/rest/RestResult.java
diff --git a/src/main/java/com/baidu/hugegraph/rest/SerializeException.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/rest/SerializeException.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/rest/SerializeException.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/rest/SerializeException.java
diff --git a/src/main/java/com/baidu/hugegraph/testutil/Assert.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/testutil/Assert.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/testutil/Assert.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/testutil/Assert.java
diff --git a/src/main/java/com/baidu/hugegraph/testutil/Whitebox.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/testutil/Whitebox.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/testutil/Whitebox.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/testutil/Whitebox.java
diff --git a/src/main/java/com/baidu/hugegraph/util/Bytes.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/util/Bytes.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/util/Bytes.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/util/Bytes.java
diff --git a/src/main/java/com/baidu/hugegraph/util/CheckSocket.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/util/CheckSocket.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/util/CheckSocket.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/util/CheckSocket.java
diff --git a/src/main/java/com/baidu/hugegraph/util/CollectionUtil.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/util/CollectionUtil.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/util/CollectionUtil.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/util/CollectionUtil.java
diff --git a/src/main/java/com/baidu/hugegraph/util/DateUtil.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/util/DateUtil.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/util/DateUtil.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/util/DateUtil.java
diff --git a/src/main/java/com/baidu/hugegraph/util/E.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/util/E.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/util/E.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/util/E.java
diff --git a/src/main/java/com/baidu/hugegraph/util/ExecutorUtil.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/util/ExecutorUtil.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/util/ExecutorUtil.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/util/ExecutorUtil.java
diff --git a/src/main/java/com/baidu/hugegraph/util/HashUtil.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/util/HashUtil.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/util/HashUtil.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/util/HashUtil.java
diff --git a/src/main/java/com/baidu/hugegraph/util/InsertionOrderUtil.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/util/InsertionOrderUtil.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/util/InsertionOrderUtil.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/util/InsertionOrderUtil.java
diff --git a/src/main/java/com/baidu/hugegraph/util/Log.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/util/Log.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/util/Log.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/util/Log.java
diff --git a/src/main/java/com/baidu/hugegraph/util/LongEncoding.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/util/LongEncoding.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/util/LongEncoding.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/util/LongEncoding.java
diff --git a/src/main/java/com/baidu/hugegraph/util/NumericUtil.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/util/NumericUtil.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/util/NumericUtil.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/util/NumericUtil.java
diff --git a/src/main/java/com/baidu/hugegraph/util/OrderLimitMap.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/util/OrderLimitMap.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/util/OrderLimitMap.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/util/OrderLimitMap.java
diff --git a/src/main/java/com/baidu/hugegraph/util/ReflectionUtil.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/util/ReflectionUtil.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/util/ReflectionUtil.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/util/ReflectionUtil.java
diff --git a/src/main/java/com/baidu/hugegraph/util/StringUtil.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/util/StringUtil.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/util/StringUtil.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/util/StringUtil.java
diff --git a/src/main/java/com/baidu/hugegraph/util/TimeUtil.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/util/TimeUtil.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/util/TimeUtil.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/util/TimeUtil.java
diff --git a/src/main/java/com/baidu/hugegraph/util/UnitUtil.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/util/UnitUtil.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/util/UnitUtil.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/util/UnitUtil.java
diff --git a/src/main/java/com/baidu/hugegraph/util/VersionUtil.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/util/VersionUtil.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/util/VersionUtil.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/util/VersionUtil.java
diff --git a/src/main/java/com/baidu/hugegraph/version/CommonVersion.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/version/CommonVersion.java
similarity index 100%
rename from src/main/java/com/baidu/hugegraph/version/CommonVersion.java
rename to hugegraph-common/src/main/java/com/baidu/hugegraph/version/CommonVersion.java
diff --git a/src/test/java/com/baidu/hugegraph/testutil/AssertTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/testutil/AssertTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/testutil/AssertTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/testutil/AssertTest.java
diff --git a/src/test/java/com/baidu/hugegraph/testutil/WhiteboxTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/testutil/WhiteboxTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/testutil/WhiteboxTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/testutil/WhiteboxTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/BaseUnitTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/BaseUnitTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/BaseUnitTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/BaseUnitTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/UnitTestSuite.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/UnitTestSuite.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/UnitTestSuite.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/UnitTestSuite.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/concurrent/AtomicLockTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/concurrent/AtomicLockTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/concurrent/AtomicLockTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/concurrent/AtomicLockTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/concurrent/BarrierEventTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/concurrent/BarrierEventTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/concurrent/BarrierEventTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/concurrent/BarrierEventTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/concurrent/KeyLockTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/concurrent/KeyLockTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/concurrent/KeyLockTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/concurrent/KeyLockTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/concurrent/LockGroupTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/concurrent/LockGroupTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/concurrent/LockGroupTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/concurrent/LockGroupTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/concurrent/LockManagerTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/concurrent/LockManagerTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/concurrent/LockManagerTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/concurrent/LockManagerTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/concurrent/PausableScheduledThreadPoolTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/concurrent/PausableScheduledThreadPoolTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/concurrent/PausableScheduledThreadPoolTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/concurrent/PausableScheduledThreadPoolTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/concurrent/RowLockTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/concurrent/RowLockTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/concurrent/RowLockTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/concurrent/RowLockTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/config/HugeConfigTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/config/HugeConfigTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/config/HugeConfigTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/config/HugeConfigTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/config/OptionSpaceTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/config/OptionSpaceTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/config/OptionSpaceTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/config/OptionSpaceTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/config/test-check-error.conf b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/config/test-check-error.conf
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/config/test-check-error.conf
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/config/test-check-error.conf
diff --git a/src/test/java/com/baidu/hugegraph/unit/config/test-list-error.conf b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/config/test-list-error.conf
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/config/test-list-error.conf
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/config/test-list-error.conf
diff --git a/src/test/java/com/baidu/hugegraph/unit/config/test-type-error.conf b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/config/test-type-error.conf
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/config/test-type-error.conf
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/config/test-type-error.conf
diff --git a/src/test/java/com/baidu/hugegraph/unit/config/test.conf b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/config/test.conf
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/config/test.conf
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/config/test.conf
diff --git a/src/test/java/com/baidu/hugegraph/unit/date/SafeDateFormatTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/date/SafeDateFormatTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/date/SafeDateFormatTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/date/SafeDateFormatTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/event/EventHubTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/event/EventHubTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/event/EventHubTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/event/EventHubTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/iterator/BatchMapperIteratorTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/iterator/BatchMapperIteratorTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/iterator/BatchMapperIteratorTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/iterator/BatchMapperIteratorTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/iterator/ExtendableIteratorTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/iterator/ExtendableIteratorTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/iterator/ExtendableIteratorTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/iterator/ExtendableIteratorTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/iterator/FilterIteratorTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/iterator/FilterIteratorTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/iterator/FilterIteratorTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/iterator/FilterIteratorTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/iterator/FlatMapperFilterIteratorTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/iterator/FlatMapperFilterIteratorTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/iterator/FlatMapperFilterIteratorTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/iterator/FlatMapperFilterIteratorTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/iterator/FlatMapperIteratorTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/iterator/FlatMapperIteratorTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/iterator/FlatMapperIteratorTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/iterator/FlatMapperIteratorTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/iterator/LimitIteratorTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/iterator/LimitIteratorTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/iterator/LimitIteratorTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/iterator/LimitIteratorTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/iterator/ListIteratorTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/iterator/ListIteratorTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/iterator/ListIteratorTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/iterator/ListIteratorTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/iterator/MapperIteratorTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/iterator/MapperIteratorTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/iterator/MapperIteratorTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/iterator/MapperIteratorTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/license/ExtraParamTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/license/ExtraParamTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/license/ExtraParamTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/license/ExtraParamTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/license/LicenseCreateParamTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/license/LicenseCreateParamTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/license/LicenseCreateParamTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/license/LicenseCreateParamTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/license/LicenseManagerTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/license/LicenseManagerTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/license/LicenseManagerTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/license/LicenseManagerTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/license/LicenseVerifyParamTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/license/LicenseVerifyParamTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/license/LicenseVerifyParamTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/license/LicenseVerifyParamTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/license/MachineInfoTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/license/MachineInfoTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/license/MachineInfoTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/license/MachineInfoTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/perf/PerfUtilTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/perf/PerfUtilTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/perf/PerfUtilTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/perf/PerfUtilTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/perf/StopwatchTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/perf/StopwatchTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/perf/StopwatchTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/perf/StopwatchTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/perf/testclass/TestClass.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/perf/testclass/TestClass.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/perf/testclass/TestClass.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/perf/testclass/TestClass.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/perf/testclass/TestLightClass.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/perf/testclass/TestLightClass.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/perf/testclass/TestLightClass.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/perf/testclass/TestLightClass.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/perf/testclass/TestPerfClass.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/perf/testclass/TestPerfClass.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/perf/testclass/TestPerfClass.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/perf/testclass/TestPerfClass.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/perf/testclass/TestPerfLightClass.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/perf/testclass/TestPerfLightClass.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/perf/testclass/TestPerfLightClass.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/perf/testclass/TestPerfLightClass.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/perf/testclass2/TestClass4Package.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/perf/testclass2/TestClass4Package.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/perf/testclass2/TestClass4Package.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/perf/testclass2/TestClass4Package.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/rest/RestClientTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/rest/RestClientTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/rest/RestClientTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/rest/RestClientTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/rest/RestResultTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/rest/RestResultTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/rest/RestResultTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/rest/RestResultTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/util/BytesTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/BytesTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/util/BytesTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/BytesTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/util/CollectionUtilTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/CollectionUtilTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/util/CollectionUtilTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/CollectionUtilTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/util/DateUtilTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/DateUtilTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/util/DateUtilTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/DateUtilTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/util/EcheckTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/EcheckTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/util/EcheckTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/EcheckTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/util/HashUtilTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/HashUtilTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/util/HashUtilTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/HashUtilTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/util/InsertionOrderUtilTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/InsertionOrderUtilTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/util/InsertionOrderUtilTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/InsertionOrderUtilTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/util/LogTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/LogTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/util/LogTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/LogTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/util/LongEncodingTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/LongEncodingTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/util/LongEncodingTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/LongEncodingTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/util/NumericUtilTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/NumericUtilTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/util/NumericUtilTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/NumericUtilTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/util/OrderLimitMapTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/OrderLimitMapTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/util/OrderLimitMapTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/OrderLimitMapTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/util/ReflectionUtilTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/ReflectionUtilTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/util/ReflectionUtilTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/ReflectionUtilTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/util/StringUtilTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/StringUtilTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/util/StringUtilTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/StringUtilTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/util/TimeUtilTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/TimeUtilTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/util/TimeUtilTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/TimeUtilTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/util/UnitUtilTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/UnitUtilTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/util/UnitUtilTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/UnitUtilTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/util/VersionUtilTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/VersionUtilTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/util/VersionUtilTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/util/VersionUtilTest.java
diff --git a/src/test/java/com/baidu/hugegraph/unit/version/VersionTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/unit/version/VersionTest.java
similarity index 100%
rename from src/test/java/com/baidu/hugegraph/unit/version/VersionTest.java
rename to hugegraph-common/src/test/java/com/baidu/hugegraph/unit/version/VersionTest.java
diff --git a/src/test/resources/META-INF/MANIFEST.MF b/hugegraph-common/src/test/resources/META-INF/MANIFEST.MF
similarity index 100%
rename from src/test/resources/META-INF/MANIFEST.MF
rename to hugegraph-common/src/test/resources/META-INF/MANIFEST.MF
diff --git a/src/test/resources/cacerts.jks b/hugegraph-common/src/test/resources/cacerts.jks
similarity index 100%
rename from src/test/resources/cacerts.jks
rename to hugegraph-common/src/test/resources/cacerts.jks
Binary files differ
diff --git a/src/test/resources/create-license.json b/hugegraph-common/src/test/resources/create-license.json
similarity index 100%
rename from src/test/resources/create-license.json
rename to hugegraph-common/src/test/resources/create-license.json
diff --git a/src/test/resources/log4j2.xml b/hugegraph-common/src/test/resources/log4j2.xml
similarity index 100%
rename from src/test/resources/log4j2.xml
rename to hugegraph-common/src/test/resources/log4j2.xml
diff --git a/src/test/resources/privateKeys.store b/hugegraph-common/src/test/resources/privateKeys.store
similarity index 100%
rename from src/test/resources/privateKeys.store
rename to hugegraph-common/src/test/resources/privateKeys.store
Binary files differ
diff --git a/src/test/resources/publicCerts.store b/hugegraph-common/src/test/resources/publicCerts.store
similarity index 100%
rename from src/test/resources/publicCerts.store
rename to hugegraph-common/src/test/resources/publicCerts.store
Binary files differ
diff --git a/src/test/resources/verify-license.json b/hugegraph-common/src/test/resources/verify-license.json
similarity index 100%
rename from src/test/resources/verify-license.json
rename to hugegraph-common/src/test/resources/verify-license.json
diff --git a/hugegraph-rpc/LICENSE b/hugegraph-rpc/LICENSE
new file mode 100644
index 0000000..e06d208
--- /dev/null
+++ b/hugegraph-rpc/LICENSE
@@ -0,0 +1,202 @@
+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 (i) 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.
+
diff --git a/hugegraph-rpc/README.md b/hugegraph-rpc/README.md
new file mode 100644
index 0000000..17a17b6
--- /dev/null
+++ b/hugegraph-rpc/README.md
@@ -0,0 +1,17 @@
+# HugeGraph-RPC
+
+HugeGraph Database RPC component, currently it's based on [Sofa-RPC](https://github.com/sofastack/sofa-rpc)
+
+## Features
+
+## Learn More
+
+The [project homepage](https://hugegraph.github.io/hugegraph-doc/) contains more information on HugeGraph and provides links to documentation, getting-started guides and release downloads.
+
+## Contributing
+
+Welcome to contribute to HugeGraph, please see [`How to Contribute`](CONTRIBUTING.md) for more information.
+
+## License
+
+HugeGraph is licensed under Apache 2.0 License.
diff --git a/hugegraph-rpc/checkstyle.xml b/hugegraph-rpc/checkstyle.xml
new file mode 100644
index 0000000..9373a70
--- /dev/null
+++ b/hugegraph-rpc/checkstyle.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC
+        "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
+        "https://checkstyle.org/dtds/configuration_1_3.dtd">
+<!-- 参考:https://checkstyle.sourceforge.io/checks.html -->
+<module name="Checker">
+    <!--检查不通过时被判定的违规级别,必须修复后才能使build通过-->
+    <property name="severity" value="error"/>
+    <!--对java文件做检查-->
+    <property name="fileExtensions" value="java"/>
+    <!--对UTF-8编码的文件做检查-->
+    <property name="charset" value="UTF-8"/>
+    <!--文件中不允许包含制表符-->
+    <module name="FileTabCharacter">
+        <property name="eachLine" value="true"/>
+    </module>
+
+    <!--检查java源文件并定义一些适用于检查此类文件的一些属性-->
+    <module name="TreeWalker">
+        <!--检查行长度-->
+        <module name="LineLength">
+            <property name="max" value="80"/>
+            <!--可以忽略的行-->
+            <property name="ignorePattern"
+                      value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
+        </module>
+        <!--检查没有import语句使用*号-->
+        <module name="AvoidStarImport"/>
+        <!--检查是否存在多余的import语句,比如重复的,java自带的包,相同包下的其他类-->
+        <module name="RedundantImport"/>
+        <!--检查是否存在没有使用的import语句-->
+        <module name="UnusedImports"/>
+        <!--检查包名称是否遵守命名规约-->
+        <module name="PackageName">
+            <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
+        </module>
+        <!--检查局部变量的名称是否遵守命名规约-->
+        <module name="LocalVariableName">
+            <property name="format" value="^[a-z][a-zA-Z0-9_]*$"/>
+        </module>
+        <!--检查成员变量(非静态字段)的名称是否遵守命名规约-->
+        <module name="MemberName">
+            <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
+        </module>
+        <!--检查方法名称是否遵守命名规约-->
+        <module name="MethodName">
+            <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
+        </module>
+        <!--检查参数名称是否遵守命名规约-->
+        <module name="ParameterName">
+            <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
+        </module>
+        <!--检查常量(用static final修饰的字段)的名称是否遵守命名规约-->
+        <module name="ConstantName">
+            <property name="format" value="^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$"/>
+        </module>
+        <!--检查数组是否属于java风格,方括号放在类型后面,而不是变量后面,比如:int[] nums(合法),int nums[](不合法)-->
+        <module name="ArrayTypeStyle">
+            <property name="javaStyle" value="true"/>
+        </module>
+        <!--long类型的字面量如果要以"L"结尾,必须是大写的"L",而非小写的"l"-->
+        <module name="UpperEll"/>
+        <!--代码换行时,运算符必须在当前行的末尾,比如:+、&&、?、: 等-->
+        <module name="OperatorWrap">
+            <property name="option" value="eol"/>
+        </module>
+        <!--检查指定标记的周围是否有空格,比如:if、for、while、synchoronized 等-->
+        <module name="WhitespaceAround"/>
+        <!--左圆括号之后和右圆括号之前是否需要有一个空格,不需要-->
+        <module name="ParenPad"/>
+        <!--检查修饰符是否符合Java建议,顺序是:public、protected、private、abstract、default、static、final、transient、volatile、synchronized、native、strictfp-->
+        <module name="ModifierOrder"/>
+        <!--检查代码块的左花括号的放置位置,必须在当前行的末尾-->
+        <module name="LeftCurly">
+            <property name="option" value="eol"/>
+            <property name="ignoreEnums" value="false"/>
+        </module>
+        <!--代码中不允许有空语句,也就是单独的;符号-->
+        <module name="EmptyStatement"/>
+        <!--覆盖equals()方法的类必须也覆盖了hashCode()方法-->
+        <module name="EqualsHashCode"/>
+        <!--switch语句必须含有default子句-->
+        <module name="MissingSwitchDefault"/>
+        <!--switch语句的default必须放在所有的case分支之后-->
+        <module name="DefaultComesLast"/>
+        <!--覆盖clone()方法时调用了super.clone()方法-->
+        <module name="SuperClone"/>
+    </module>
+</module>
diff --git a/hugegraph-rpc/pom.xml b/hugegraph-rpc/pom.xml
new file mode 100644
index 0000000..b06fc89
--- /dev/null
+++ b/hugegraph-rpc/pom.xml
@@ -0,0 +1,229 @@
+<?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">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.baidu.hugegraph</groupId>
+        <artifactId>hugegraph-commons</artifactId>
+        <version>1.8.10</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>hugegraph-rpc</artifactId>
+    <version>1.0.1</version>
+
+    <name>hugegraph-rpc</name>
+    <description>HugeGraph Database RPC component</description>
+
+    <properties>
+        <!-- Use parent params -->
+    </properties>
+
+    <dependencies>
+        <!-- hugegraph-common -->
+        <dependency>
+            <groupId>com.baidu.hugegraph</groupId>
+            <artifactId>hugegraph-common</artifactId>
+            <!-- TODO: use commons latest version ${project.version}?-->
+            <version>1.8.5</version>
+        </dependency>
+
+        <!-- sofa rpc -->
+        <dependency>
+            <groupId>com.lmax</groupId>
+            <artifactId>disruptor</artifactId>
+            <version>3.3.7</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alipay.sofa</groupId>
+            <artifactId>bolt</artifactId>
+            <version>1.6.2</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.alipay.sofa</groupId>
+            <artifactId>sofa-rpc-all</artifactId>
+            <version>5.7.6</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.jboss.resteasy</groupId>
+                    <artifactId>resteasy-client</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.jboss.resteasy</groupId>
+                    <artifactId>resteasy-netty4</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.jboss.resteasy</groupId>
+                    <artifactId>resteasy-jackson2-provider</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.httpcomponents</groupId>
+                    <artifactId>httpclient</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.httpcomponents</groupId>
+                    <artifactId>httpcore</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.httpcomponents</groupId>
+                    <artifactId>httpmime</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.jboss.logging</groupId>
+                    <artifactId>jboss-logging</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.1</version>
+                <configuration>
+                    <source>${compiler.source}</source>
+                    <target>${compiler.target}</target>
+                    <compilerArguments>
+                        <Xmaxerrs>500</Xmaxerrs>
+                    </compilerArguments>
+                    <compilerArgs>
+                        <arg>-Xlint:unchecked</arg>
+                    </compilerArgs>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <version>3.1.0</version>
+                <configuration>
+                    <configLocation>checkstyle.xml</configLocation>
+                    <encoding>UTF-8</encoding>
+                    <consoleOutput>true</consoleOutput>
+                    <failsOnError>true</failsOnError>
+                    <linkXRef>false</linkXRef>
+                    <includeTestSourceDirectory>false</includeTestSourceDirectory>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>validate</id>
+                        <phase>validate</phase>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>2.6</version>
+                <configuration>
+                    <archive>
+                        <index>true</index>
+                        <manifest>
+                            <addDefaultImplementationEntries>
+                                false
+                            </addDefaultImplementationEntries>
+                            <addDefaultSpecificationEntries>
+                                true
+                            </addDefaultSpecificationEntries>
+                        </manifest>
+                        <manifestEntries>
+                            <!-- Must be on one line, otherwise the automatic
+                                 upgrade script cannot replace the version number -->
+                            <Implementation-Version>1.0.0.0</Implementation-Version>
+                        </manifestEntries>
+                    </archive>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.jacoco</groupId>
+                <artifactId>jacoco-maven-plugin</artifactId>
+                <version>0.8.2</version>
+                <executions>
+                    <execution>
+                        <id>pre-unit-test</id>
+                        <goals>
+                            <goal>prepare-agent</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>post-unit-test</id>
+                        <phase>test</phase>
+                        <goals>
+                            <goal>report</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.parent.build.directory}</outputDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>release</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-source-plugin</artifactId>
+                        <version>2.2.1</version>
+                        <executions>
+                            <execution>
+                                <id>attach-sources</id>
+                                <goals>
+                                    <goal>jar-no-fork</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-javadoc-plugin</artifactId>
+                        <version>2.9.1</version>
+                        <executions>
+                            <execution>
+                                <id>attach-javadocs</id>
+                                <goals>
+                                    <goal>jar</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-gpg-plugin</artifactId>
+                        <version>1.5</version>
+                        <executions>
+                            <execution>
+                                <id>sign-artifacts</id>
+                                <phase>verify</phase>
+                                <goals>
+                                    <goal>sign</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/hugegraph-rpc/src/main/java/com/baidu/hugegraph/config/RpcOptions.java b/hugegraph-rpc/src/main/java/com/baidu/hugegraph/config/RpcOptions.java
new file mode 100644
index 0000000..d58673c
--- /dev/null
+++ b/hugegraph-rpc/src/main/java/com/baidu/hugegraph/config/RpcOptions.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2017 HugeGraph Authors
+ *
+ * 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 com.baidu.hugegraph.config;
+
+import static com.baidu.hugegraph.config.OptionChecker.allowValues;
+import static com.baidu.hugegraph.config.OptionChecker.disallowEmpty;
+import static com.baidu.hugegraph.config.OptionChecker.rangeInt;
+
+public class RpcOptions extends OptionHolder {
+
+    private RpcOptions() {
+        super();
+    }
+
+    private static volatile RpcOptions instance;
+
+    public static synchronized RpcOptions instance() {
+        if (instance == null) {
+            instance = new RpcOptions();
+            instance.registerOptions();
+        }
+        return instance;
+    }
+
+    public static final ConfigOption<String> RPC_SERVER_HOST =
+            new ConfigOption<>(
+                    "rpc.server_host",
+                    "The hosts/ips bound by rpc server to provide services, " +
+                    "empty value means not enabled.",
+                    null,
+                    ""
+            );
+
+    public static final ConfigOption<Integer> RPC_SERVER_PORT =
+            new ConfigOption<>(
+                    "rpc.server_port",
+                    "The port bound by rpc server to provide services.",
+                    rangeInt(0, Integer.MAX_VALUE),
+                    8090
+            );
+
+    public static final ConfigOption<Boolean> RPC_ADAPTIVE_PORT =
+            new ConfigOption<>(
+                    "rpc.server_adaptive_port",
+                    "Whether the bound port is adaptive, if it's enabled, " +
+                    "when the port is in use, automatically +1 to detect " +
+                    "the next available port. Note that this process is " +
+                    "not atomic, so there may still be port conflicts.",
+                    disallowEmpty(),
+                    false
+            );
+
+    public static final ConfigOption<Integer> RPC_SERVER_TIMEOUT =
+            new ConfigOption<>(
+                    "rpc.server_timeout",
+                    "The timeout(in seconds) of rpc server execution.",
+                    rangeInt(1, Integer.MAX_VALUE),
+                    30
+            );
+
+    public static final ConfigOption<String> RPC_REMOTE_URL =
+            new ConfigOption<>(
+                    "rpc.remote_url",
+                    "The remote urls of rpc peers, it can be set to " +
+                    "multiple addresses, which are concat by ',', " +
+                    "empty value means not enabled.",
+                    null,
+                    ""
+            );
+
+    public static final ConfigOption<Integer> RPC_CLIENT_CONNECT_TIMEOUT =
+            new ConfigOption<>(
+                    "rpc.client_connect_timeout",
+                    "The timeout(in seconds) of rpc client connect to rpc " +
+                    "server.",
+                    rangeInt(1, Integer.MAX_VALUE),
+                    20
+            );
+
+    public static final ConfigOption<Integer> RPC_CLIENT_RECONNECT_PERIOD =
+            new ConfigOption<>(
+                    "rpc.client_reconnect_period",
+                    "The period(in seconds) of rpc client reconnect to rpc " +
+                    "server.",
+                    rangeInt(1, Integer.MAX_VALUE),
+                    10
+            );
+
+    public static final ConfigOption<Integer> RPC_CLIENT_READ_TIMEOUT =
+            new ConfigOption<>(
+                    "rpc.client_read_timeout",
+                    "The timeout(in seconds) of rpc client read from rpc " +
+                    "server.",
+                    rangeInt(1, Integer.MAX_VALUE),
+                    40
+            );
+
+    public static final ConfigOption<Integer> RPC_CLIENT_RETRIES =
+            new ConfigOption<>(
+                    "rpc.client_retries",
+                    "Failed retry number of rpc client calls to rpc server.",
+                    rangeInt(0, Integer.MAX_VALUE),
+                    3
+            );
+
+    public static final ConfigOption<String> RPC_CLIENT_LOAD_BALANCER =
+            new ConfigOption<>(
+                    "rpc.client_load_balancer",
+                    "The rpc client uses a load-balancing algorithm to " +
+                    "access multiple rpc servers in one cluster. Default " +
+                    "value is 'consistentHash', means forwording by request " +
+                    "parameters.",
+                    allowValues("random", "localPref", "roundRobin",
+                                "consistentHash", "weightRoundRobin"),
+                    "consistentHash"
+            );
+
+    public static final ConfigOption<String> RPC_PROTOCOL =
+            new ConfigOption<>(
+                    "rpc.protocol",
+                    "Rpc communication protocol, client and server need to " +
+                    "be specified the same value.",
+                    allowValues("bolt", "rest", "dubbo", "h2c", "http"),
+                    "bolt"
+            );
+
+    public static final ConfigOption<Integer> RPC_CONFIG_ORDER =
+            new ConfigOption<>(
+                    "rpc.config_order",
+                    "Sofa rpc configuration file loading order, the larger " +
+                    "the more later loading.",
+                    rangeInt(1, Integer.MAX_VALUE),
+                    999
+            );
+
+    public static final ConfigOption<String> RPC_LOGGER_IMPL =
+            new ConfigOption<>(
+                    "rpc.logger_impl",
+                    "Sofa rpc log implementation class.",
+                    disallowEmpty(),
+                    "com.alipay.sofa.rpc.log.SLF4JLoggerImpl"
+            );
+}
diff --git a/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcClientProvider.java b/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcClientProvider.java
new file mode 100644
index 0000000..6f0eba5
--- /dev/null
+++ b/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcClientProvider.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2017 HugeGraph Authors
+ *
+ * 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 com.baidu.hugegraph.rpc;
+
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import com.alipay.sofa.rpc.common.utils.StringUtils;
+import com.baidu.hugegraph.config.HugeConfig;
+import com.baidu.hugegraph.config.RpcOptions;
+import com.baidu.hugegraph.util.E;
+
+public class RpcClientProvider {
+
+    private final RpcConsumerConfig consumerConfig;
+
+    public RpcClientProvider(HugeConfig config) {
+        // TODO: fetch from registry server
+        String rpcUrl = config.get(RpcOptions.RPC_REMOTE_URL);
+        String selfUrl = config.get(RpcOptions.RPC_SERVER_HOST) + ":" +
+                         config.get(RpcOptions.RPC_SERVER_PORT);
+        rpcUrl = excludeSelfUrl(rpcUrl, selfUrl);
+        this.consumerConfig = StringUtils.isNotBlank(rpcUrl) ?
+                              new RpcConsumerConfig(config, rpcUrl) : null;
+    }
+    public boolean enabled() {
+        return this.consumerConfig != null;
+    }
+
+    public RpcConsumerConfig config() {
+        E.checkArgument(this.consumerConfig != null,
+                        "RpcClient is not enabled, please config option '%s' " +
+                        "and ensure to add an address other than self service",
+                        RpcOptions.RPC_REMOTE_URL.name());
+        return this.consumerConfig;
+    }
+
+    public void unreferAll() {
+        if (this.consumerConfig != null) {
+            this.consumerConfig.removeAllServiceProxy();
+        }
+    }
+
+    public void destroy() {
+        if (this.consumerConfig != null) {
+            this.consumerConfig.destroy();
+        }
+    }
+
+    protected static String excludeSelfUrl(String rpcUrl, String selfUrl) {
+        String[] urls = StringUtils.splitWithCommaOrSemicolon(rpcUrl);
+        // Keep urls order via LinkedHashSet
+        Set<String> urlSet = new LinkedHashSet<>(Arrays.asList(urls));
+        urlSet.remove(selfUrl);
+        return String.join(",", urlSet);
+    }
+}
diff --git a/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcCommonConfig.java b/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcCommonConfig.java
new file mode 100644
index 0000000..4ee50b6
--- /dev/null
+++ b/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcCommonConfig.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2017 HugeGraph Authors
+ *
+ * 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 com.baidu.hugegraph.rpc;
+
+import java.util.Map;
+
+import com.alipay.sofa.rpc.common.RpcConfigs;
+import com.baidu.hugegraph.config.HugeConfig;
+import com.baidu.hugegraph.config.RpcOptions;
+
+public class RpcCommonConfig {
+
+    public static void initRpcConfigs(HugeConfig config) {
+        RpcConfigs.putValue("rpc.config.order",
+                            config.get(RpcOptions.RPC_CONFIG_ORDER));
+        RpcConfigs.putValue("logger.impl",
+                            config.get(RpcOptions.RPC_LOGGER_IMPL));
+    }
+
+    public static void initRpcConfigs(String key, Object value) {
+        RpcConfigs.putValue(key, value);
+    }
+
+    public static void initRpcConfigs(Map<String, Object> conf) {
+        for (Map.Entry<String, Object> entry : conf.entrySet()) {
+            RpcConfigs.putValue(entry.getKey(), entry.getValue());
+        }
+    }
+}
diff --git a/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcConsumerConfig.java b/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcConsumerConfig.java
new file mode 100644
index 0000000..c9b28f9
--- /dev/null
+++ b/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcConsumerConfig.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2017 HugeGraph Authors
+ *
+ * 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 com.baidu.hugegraph.rpc;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.slf4j.Logger;
+
+import com.alipay.sofa.rpc.bootstrap.Bootstraps;
+import com.alipay.sofa.rpc.bootstrap.ConsumerBootstrap;
+import com.alipay.sofa.rpc.client.AbstractCluster;
+import com.alipay.sofa.rpc.client.Cluster;
+import com.alipay.sofa.rpc.client.ProviderInfo;
+import com.alipay.sofa.rpc.config.ConsumerConfig;
+import com.alipay.sofa.rpc.core.exception.RpcErrorType;
+import com.alipay.sofa.rpc.core.exception.SofaRpcException;
+import com.alipay.sofa.rpc.core.request.SofaRequest;
+import com.alipay.sofa.rpc.core.response.SofaResponse;
+import com.alipay.sofa.rpc.ext.Extension;
+import com.alipay.sofa.rpc.ext.ExtensionLoaderFactory;
+import com.baidu.hugegraph.config.HugeConfig;
+import com.baidu.hugegraph.config.RpcOptions;
+import com.baidu.hugegraph.util.Log;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+public class RpcConsumerConfig implements RpcServiceConfig4Client {
+
+    private final HugeConfig conf;
+    private final String remoteUrls;
+    private final Map<String, ConsumerConfig<?>> configs;
+    private final List<ConsumerBootstrap<?>> bootstraps;
+
+    static {
+         ExtensionLoaderFactory.getExtensionLoader(Cluster.class)
+                               .loadExtension(FanoutCluster.class);
+    }
+
+    public RpcConsumerConfig(HugeConfig config, String remoteUrls) {
+        RpcCommonConfig.initRpcConfigs(config);
+        this.conf = config;
+        this.remoteUrls = remoteUrls;
+        this.configs = Maps.newHashMap();
+        this.bootstraps = Lists.newArrayList();
+    }
+
+    @Override
+    public <T> T serviceProxy(String interfaceId) {
+        return this.serviceProxy(null, interfaceId);
+    }
+
+    @Override
+    public <T> T serviceProxy(String graph, String interfaceId) {
+        ConsumerConfig<T> config = this.consumerConfig(graph, interfaceId);
+        ConsumerBootstrap<T> bootstrap = Bootstraps.from(config);
+        this.bootstraps.add(bootstrap);
+        return bootstrap.refer();
+    }
+
+    @Override
+    public void removeAllServiceProxy() {
+        for (ConsumerBootstrap<?> bootstrap : this.bootstraps) {
+            bootstrap.unRefer();
+        }
+    }
+
+    public void destroy() {
+        Set<Cluster> clusters = Sets.newHashSet();
+        for (ConsumerBootstrap<?> bootstrap : this.bootstraps) {
+            bootstrap.unRefer();
+            clusters.add(bootstrap.getCluster());
+        }
+        for (Cluster cluster : clusters) {
+            cluster.destroy();
+        }
+    }
+
+    private <T> ConsumerConfig<T> consumerConfig(String graph,
+                                                 String interfaceId) {
+        String serviceId;
+        if (graph != null) {
+            serviceId = interfaceId + ":" + graph;
+        } else {
+            serviceId = interfaceId;
+        }
+
+        @SuppressWarnings("unchecked")
+        ConsumerConfig<T> consumerConfig = (ConsumerConfig<T>)
+                                           this.configs.get(serviceId);
+        if (consumerConfig != null) {
+            return consumerConfig;
+        }
+
+        assert consumerConfig == null;
+        consumerConfig = new ConsumerConfig<>();
+
+        HugeConfig conf = this.conf;
+        String protocol = conf.get(RpcOptions.RPC_PROTOCOL);
+        int timeout = conf.get(RpcOptions.RPC_CLIENT_READ_TIMEOUT) * 1000;
+        int connectTimeout = conf.get(RpcOptions
+                                      .RPC_CLIENT_CONNECT_TIMEOUT) * 1000;
+        int reconnectPeriod = conf.get(RpcOptions
+                                       .RPC_CLIENT_RECONNECT_PERIOD) * 1000;
+        int retries = conf.get(RpcOptions.RPC_CLIENT_RETRIES);
+        String loadBalancer = conf.get(RpcOptions.RPC_CLIENT_LOAD_BALANCER);
+
+        if (graph != null) {
+            consumerConfig.setId(serviceId).setUniqueId(graph);
+            // Default is FailoverCluster, set to FanoutCluster to broadcast
+            consumerConfig.setCluster("fanout");
+        }
+        consumerConfig.setInterfaceId(interfaceId)
+                      .setProtocol(protocol)
+                      .setDirectUrl(this.remoteUrls)
+                      .setTimeout(timeout)
+                      .setConnectTimeout(connectTimeout)
+                      .setReconnectPeriod(reconnectPeriod)
+                      .setRetries(retries)
+                      .setLoadBalancer(loadBalancer);
+
+        this.configs.put(serviceId, consumerConfig);
+        return consumerConfig;
+    }
+
+    @Extension("fanout")
+    private static class FanoutCluster extends AbstractCluster {
+
+        private static final Logger LOG = Log.logger(FanoutCluster.class);
+
+        public FanoutCluster(ConsumerBootstrap<?> consumerBootstrap) {
+            super(consumerBootstrap);
+        }
+
+        @Override
+        protected SofaResponse doInvoke(SofaRequest request)
+                                        throws SofaRpcException {
+            List<ProviderInfo> providers = this.getRouterChain()
+                                               .route(request, null);
+            List<SofaResponse> responses = new ArrayList<>(providers.size());
+            List<SofaRpcException> excepts = new ArrayList<>(providers.size());
+
+            for (ProviderInfo provider : providers) {
+                try {
+                    SofaResponse response = this.doInvoke(request, provider);
+                    responses.add(response);
+                } catch (SofaRpcException e) {
+                    excepts.add(e);
+                    LOG.warn("{}.(error {})", e.getMessage(), e.getErrorType());
+                }
+            }
+
+            if (responses.size() > 0) {
+                /*
+                 * Just choose the first one as result to return, ignore others
+                 * TODO: maybe more strategies should be provided
+                 */
+                return responses.get(0);
+            } else if (excepts.size() > 0) {
+                throw excepts.get(0);
+            } else {
+                assert providers.isEmpty();
+                String method = methodName(request);
+                throw new SofaRpcException(RpcErrorType.CLIENT_ROUTER,
+                                           "No service provider for " + method);
+            }
+        }
+
+        private SofaResponse doInvoke(SofaRequest request,
+                                      ProviderInfo providerInfo) {
+            try {
+                SofaResponse response = this.filterChain(providerInfo, request);
+                if (response != null) {
+                    return response;
+                }
+                String method = methodName(request);
+                throw new SofaRpcException(RpcErrorType.CLIENT_UNDECLARED_ERROR,
+                          "Failed to call " + method + " on remote server " +
+                          providerInfo + ", return null response");
+            } catch (Exception e) {
+                int error = RpcErrorType.CLIENT_UNDECLARED_ERROR;
+                if (e instanceof SofaRpcException) {
+                    error = ((SofaRpcException) e).getErrorType();
+                }
+                String method = methodName(request);
+                throw new SofaRpcException(error,
+                          "Failed to call " + method + " on remote server " +
+                          providerInfo + ", caused by exception: " + e);
+            }
+        }
+
+        private static String methodName(SofaRequest request) {
+            return request.getInterfaceName() + "." +
+                   request.getMethodName() + "()";
+        }
+    }
+}
diff --git a/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcException.java b/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcException.java
new file mode 100644
index 0000000..2a2675c
--- /dev/null
+++ b/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcException.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2017 HugeGraph Authors
+ *
+ * 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 com.baidu.hugegraph.rpc;
+
+public class RpcException extends RuntimeException {
+
+    private static final long serialVersionUID = -6067652498161184537L;
+
+    public RpcException(String message) {
+        super(message);
+    }
+
+    public RpcException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public RpcException(String message, Object... args) {
+        super(String.format(message, args));
+    }
+
+    public RpcException(String message, Throwable cause, Object... args) {
+        super(String.format(message, args), cause);
+    }
+}
diff --git a/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcProviderConfig.java b/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcProviderConfig.java
new file mode 100644
index 0000000..8bf0aea
--- /dev/null
+++ b/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcProviderConfig.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2017 HugeGraph Authors
+ *
+ * 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 com.baidu.hugegraph.rpc;
+
+import java.util.Map;
+
+import com.alipay.sofa.rpc.config.ProviderConfig;
+import com.baidu.hugegraph.util.E;
+import com.google.common.collect.Maps;
+
+public class RpcProviderConfig implements RpcServiceConfig4Server {
+
+    private final Map<String, ProviderConfig<?>> configs = Maps.newHashMap();
+
+    @Override
+    public <T, S extends T> String addService(Class<T> clazz, S serviceImpl) {
+        return this.addService(null, clazz.getName(), serviceImpl);
+    }
+
+    @Override
+    public <T, S extends T> String addService(String graph,
+                                              Class<T> clazz,
+                                              S serviceImpl) {
+        return this.addService(graph, clazz.getName(), serviceImpl);
+    }
+
+    private <T, S extends T> String addService(String graph,
+                                               String interfaceId,
+                                               S serviceImpl) {
+        ProviderConfig<T> providerConfig = new ProviderConfig<>();
+        String serviceId;
+        if (graph != null) {
+            serviceId = interfaceId + ":" + graph;
+            providerConfig.setId(serviceId).setUniqueId(graph);
+        } else {
+            serviceId = interfaceId;
+        }
+
+        providerConfig.setInterfaceId(interfaceId)
+                      .setRef(serviceImpl);
+
+        E.checkArgument(!this.configs.containsKey(serviceId),
+                        "Not allowed to add service already exist: '%s'",
+                        serviceId);
+        this.configs.put(serviceId, providerConfig);
+        return serviceId;
+    }
+
+    @Override
+    public void removeService(String serviceId) {
+        ProviderConfig<?> config = this.configs.remove(serviceId);
+        E.checkArgument(config != null,
+                        "The service '%s' doesn't exist", serviceId);
+        config.unExport();
+    }
+
+    @Override
+    public void removeAllService() {
+        for (ProviderConfig<?> config : this.configs.values()) {
+            config.unExport();
+        }
+        this.configs.clear();
+    }
+
+    public Map<String, ProviderConfig<?>> configs() {
+        return this.configs;
+    }
+}
diff --git a/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcServer.java b/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcServer.java
new file mode 100644
index 0000000..a7e0ba9
--- /dev/null
+++ b/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcServer.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2017 HugeGraph Authors
+ *
+ * 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 com.baidu.hugegraph.rpc;
+
+import java.util.Map;
+
+import org.apache.commons.collections.MapUtils;
+import org.slf4j.Logger;
+
+import com.alipay.remoting.RemotingServer;
+import com.alipay.sofa.rpc.common.utils.StringUtils;
+import com.alipay.sofa.rpc.config.ProviderConfig;
+import com.alipay.sofa.rpc.config.ServerConfig;
+import com.alipay.sofa.rpc.server.Server;
+import com.alipay.sofa.rpc.server.bolt.BoltServer;
+import com.baidu.hugegraph.config.HugeConfig;
+import com.baidu.hugegraph.config.RpcOptions;
+import com.baidu.hugegraph.testutil.Whitebox;
+import com.baidu.hugegraph.util.E;
+import com.baidu.hugegraph.util.Log;
+
+public class RpcServer {
+
+    private static final Logger LOG = Log.logger(RpcServer.class);
+
+    private final HugeConfig conf;
+    private final RpcProviderConfig configs;
+    private final ServerConfig serverConfig;
+
+    public RpcServer(HugeConfig config) {
+        RpcCommonConfig.initRpcConfigs(config);
+        this.conf = config;
+        this.configs = new RpcProviderConfig();
+
+        String host = config.get(RpcOptions.RPC_SERVER_HOST);
+        if (StringUtils.isNotBlank(host)) {
+            int port = config.get(RpcOptions.RPC_SERVER_PORT);
+            boolean adaptivePort = config.get(RpcOptions.RPC_ADAPTIVE_PORT);
+            this.serverConfig = new ServerConfig();
+            this.serverConfig.setProtocol(config.get(RpcOptions.RPC_PROTOCOL))
+                             .setHost(host).setPort(port)
+                             .setAdaptivePort(adaptivePort)
+                             .setDaemon(false);
+        } else {
+            this.serverConfig = null;
+        }
+    }
+
+    public boolean enabled() {
+        return this.serverConfig != null;
+    }
+
+    public RpcProviderConfig config() {
+        this.checkEnabled();
+        return this.configs;
+    }
+
+    public String host() {
+        this.checkEnabled();
+        return this.serverConfig.getBoundHost();
+    }
+
+    public int port() {
+        this.checkEnabled();
+        Server server = this.serverConfig.getServer();
+        if (server instanceof BoltServer && server.isStarted()) {
+            /*
+             * When using random port 0, try to fetch the actual port
+             * NOTE: RemotingServer.port() would return the actual port only
+             *       if sofa-bolt version >= 1.6.1, please see:
+             *       https://github.com/sofastack/sofa-bolt/issues/196
+             * TODO: remove this code after adding Server.port() interface:
+             *       https://github.com/sofastack/sofa-rpc/issues/1022
+             */
+            RemotingServer rs = Whitebox.getInternalState(server,
+                                                          "remotingServer");
+            return rs.port();
+        }
+        // When using random port 0, the returned port is not the actual port
+        return this.serverConfig.getPort();
+    }
+
+    public void exportAll() {
+        this.checkEnabled();
+        LOG.debug("RpcServer starting on port {}", this.port());
+        Map<String, ProviderConfig<?>> configs = this.configs.configs();
+        if (MapUtils.isEmpty(configs)) {
+            LOG.info("RpcServer config is empty, skip starting RpcServer");
+            return;
+        }
+        int timeout = this.conf.get(RpcOptions.RPC_SERVER_TIMEOUT) * 1000;
+        for (ProviderConfig<?> providerConfig : configs.values()) {
+            providerConfig.setServer(this.serverConfig)
+                          .setTimeout(timeout)
+                          .export();
+        }
+        LOG.info("RpcServer started success on port {}", this.port());
+    }
+
+    public void unexportAll() {
+        this.configs.removeAllService();
+    }
+
+    public void unexport(String serviceId) {
+        this.configs.removeService(serviceId);
+    }
+
+    public void destroy() {
+        if (!this.enabled()) {
+            return;
+        }
+        LOG.info("RpcServer stop on port {}", this.port());
+        for (ProviderConfig<?> config : this.configs.configs().values()) {
+            Object service = config.getRef();
+            if (service instanceof AutoCloseable) {
+                try {
+                    ((AutoCloseable) service).close();
+                } catch (Exception e) {
+                    LOG.warn("Failed to close service {}", service, e);
+                }
+            }
+        }
+        this.serverConfig.destroy();
+        this.configs.removeAllService();
+    }
+
+    private void checkEnabled() {
+        E.checkArgument(this.enabled(),
+                        "RpcServer is not enabled, please config option '%s'",
+                        RpcOptions.RPC_SERVER_HOST.name());
+    }
+}
diff --git a/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcServiceConfig4Client.java b/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcServiceConfig4Client.java
new file mode 100644
index 0000000..13cfca9
--- /dev/null
+++ b/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcServiceConfig4Client.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2017 HugeGraph Authors
+ *
+ * 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 com.baidu.hugegraph.rpc;
+
+public interface RpcServiceConfig4Client {
+
+    public <T> T serviceProxy(String interfaceId);
+
+    public <T> T serviceProxy(String graph, String interfaceId);
+
+    public default <T> T serviceProxy(Class<T> clazz) {
+        return this.serviceProxy(clazz.getName());
+    }
+
+    public default <T> T serviceProxy(String graph, Class<T> clazz) {
+        return this.serviceProxy(graph, clazz.getName());
+    }
+
+    public void removeAllServiceProxy();
+}
diff --git a/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcServiceConfig4Server.java b/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcServiceConfig4Server.java
new file mode 100644
index 0000000..7139073
--- /dev/null
+++ b/hugegraph-rpc/src/main/java/com/baidu/hugegraph/rpc/RpcServiceConfig4Server.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2017 HugeGraph Authors
+ *
+ * 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 com.baidu.hugegraph.rpc;
+
+public interface RpcServiceConfig4Server {
+
+    public <T, S extends T> String addService(Class<T> clazz, S serviceImpl);
+
+    public <T, S extends T> String addService(String graph,
+                                              Class<T> clazz, S serviceImpl);
+
+    public void removeService(String serviceId);
+
+    public void removeAllService();
+}
diff --git a/hugegraph-rpc/src/main/java/com/baidu/hugegraph/version/RpcVersion.java b/hugegraph-rpc/src/main/java/com/baidu/hugegraph/version/RpcVersion.java
new file mode 100644
index 0000000..cd41fe5
--- /dev/null
+++ b/hugegraph-rpc/src/main/java/com/baidu/hugegraph/version/RpcVersion.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2017 HugeGraph Authors
+ *
+ * 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 com.baidu.hugegraph.version;
+
+import com.baidu.hugegraph.util.VersionUtil.Version;
+
+public class RpcVersion {
+
+    public static final String NAME = "hugegraph-rpc";
+
+    // The second parameter of Version.of() is for all-in-one JAR
+    public static final Version VERSION = Version.of(RpcVersion.class,
+                                                     "1.0.1");
+}
diff --git a/hugegraph-rpc/src/test/java/com/baidu/hugegraph/unit/BaseUnitTest.java b/hugegraph-rpc/src/test/java/com/baidu/hugegraph/unit/BaseUnitTest.java
new file mode 100644
index 0000000..cdbdb03
--- /dev/null
+++ b/hugegraph-rpc/src/test/java/com/baidu/hugegraph/unit/BaseUnitTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2017 HugeGraph Authors
+ *
+ * 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 com.baidu.hugegraph.unit;
+
+import java.net.URL;
+
+import org.junit.BeforeClass;
+
+import com.baidu.hugegraph.config.HugeConfig;
+import com.baidu.hugegraph.config.OptionSpace;
+import com.baidu.hugegraph.rpc.RpcServer;
+
+public class BaseUnitTest {
+
+    @BeforeClass
+    public static void initEnv() {
+        OptionSpace.register("rpc", "com.baidu.hugegraph.config.RpcOptions");
+    }
+
+    protected static HugeConfig config(boolean server) {
+        return config(server ? "server" : "client");
+    }
+
+    protected static HugeConfig config(String type) {
+        String name = String.format("rpc-%s.properties", type);
+        URL conf = BaseUnitTest.class.getClassLoader().getResource(name);
+        return new HugeConfig(conf.getPath());
+    }
+
+    protected static void startServer(RpcServer rpcServer) {
+        rpcServer.config().configs().values().forEach(c -> {
+            c.setRepeatedExportLimit(100);
+        });
+
+        rpcServer.exportAll();
+    }
+
+    protected static void stopServer(RpcServer rpcServer) {
+        rpcServer.destroy();
+    }
+}
diff --git a/hugegraph-rpc/src/test/java/com/baidu/hugegraph/unit/ExceptionTest.java b/hugegraph-rpc/src/test/java/com/baidu/hugegraph/unit/ExceptionTest.java
new file mode 100644
index 0000000..ade2198
--- /dev/null
+++ b/hugegraph-rpc/src/test/java/com/baidu/hugegraph/unit/ExceptionTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2017 HugeGraph Authors
+ *
+ * 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 com.baidu.hugegraph.unit;
+
+import org.junit.Test;
+
+import com.baidu.hugegraph.rpc.RpcException;
+import com.baidu.hugegraph.testutil.Assert;
+
+public class ExceptionTest {
+
+    @Test
+    public void testExceptionWithMessage() {
+        RpcException e = new RpcException("test");
+        Assert.assertEquals("test", e.getMessage());
+        Assert.assertEquals(null, e.getCause());
+    }
+
+    @Test
+    public void testExceptionWithMessageAndCause() {
+        Exception cause = new Exception();
+        RpcException e = new RpcException("test", cause);
+        Assert.assertEquals("test", e.getMessage());
+        Assert.assertEquals(cause, e.getCause());
+    }
+
+    @Test
+    public void testExceptionWithMessageAndArgs() {
+        RpcException e = new RpcException("test %s", 168);
+        Assert.assertEquals("test 168", e.getMessage());
+        Assert.assertEquals(null, e.getCause());
+    }
+
+    @Test
+    public void testExceptionWithMessageAndArgsAndCause() {
+        Exception cause = new Exception();
+        RpcException e = new RpcException("test %s", cause, 168);
+        Assert.assertEquals("test 168", e.getMessage());
+        Assert.assertEquals(cause, e.getCause());
+    }
+}
diff --git a/hugegraph-rpc/src/test/java/com/baidu/hugegraph/unit/ServerClientTest.java b/hugegraph-rpc/src/test/java/com/baidu/hugegraph/unit/ServerClientTest.java
new file mode 100644
index 0000000..28fe564
--- /dev/null
+++ b/hugegraph-rpc/src/test/java/com/baidu/hugegraph/unit/ServerClientTest.java
@@ -0,0 +1,787 @@
+/*
+ * Copyright 2017 HugeGraph Authors
+ *
+ * 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 com.baidu.hugegraph.unit;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.alipay.sofa.rpc.common.RpcOptions;
+import com.alipay.sofa.rpc.core.exception.SofaRpcException;
+import com.alipay.sofa.rpc.core.exception.SofaRpcRuntimeException;
+import com.baidu.hugegraph.config.HugeConfig;
+import com.baidu.hugegraph.rpc.RpcClientProvider;
+import com.baidu.hugegraph.rpc.RpcCommonConfig;
+import com.baidu.hugegraph.rpc.RpcConsumerConfig;
+import com.baidu.hugegraph.rpc.RpcProviderConfig;
+import com.baidu.hugegraph.rpc.RpcServer;
+import com.baidu.hugegraph.testutil.Assert;
+import com.baidu.hugegraph.testutil.Whitebox;
+import com.baidu.hugegraph.util.E;
+import com.google.common.collect.ImmutableMap;
+
+public class ServerClientTest extends BaseUnitTest {
+
+    private static RpcServer rpcServer;
+    private static RpcClientProvider rpcClient;
+
+    @BeforeClass
+    public static void init() {
+        rpcServer = new RpcServer(config(true));
+        rpcClient = new RpcClientProvider(config(false));
+    }
+
+    @AfterClass
+    public static void clear() throws Exception {
+        if (rpcClient != null) {
+            rpcClient.destroy();
+        }
+        if (rpcServer != null) {
+            rpcServer.destroy();
+        }
+    }
+
+    @After
+    public void teardown() {
+        if (rpcClient != null) {
+            rpcClient.unreferAll();
+        }
+        if (rpcServer != null) {
+            rpcServer.unexportAll();
+        }
+    }
+
+    @Test
+    public void testSimpleService() {
+        // Init server
+        RpcProviderConfig serverConfig = rpcServer.config();
+        serverConfig.addService(HelloService.class, new HelloServiceImpl());
+        startServer(rpcServer);
+
+        // Init client
+        RpcConsumerConfig clientConfig = rpcClient.config();
+        HelloService client = clientConfig.serviceProxy(HelloService.class);
+
+        // Test call
+        Assert.assertEquals("hello tom!", client.hello("tom"));
+        Assert.assertEquals("tom", client.echo("tom"));
+        Assert.assertEquals(5.14, client.sum(2, 3.14), 0.00000001d);
+
+        Assert.assertThrows(IllegalArgumentException.class, () -> {
+            client.hello("");
+        }, e -> {
+            Assert.assertContains("empty hello parameter", e.getMessage());
+        });
+    }
+
+    @Test
+    public void testMultiService() {
+        // Init server
+        GraphHelloServiceImpl g1 = new GraphHelloServiceImpl("g1");
+        GraphHelloServiceImpl g2 = new GraphHelloServiceImpl("g2");
+        GraphHelloServiceImpl g3 = new GraphHelloServiceImpl("g3");
+
+        RpcProviderConfig serverConfig = rpcServer.config();
+        serverConfig.addService(g1.graph(), HelloService.class, g1);
+        serverConfig.addService(g2.graph(), HelloService.class, g2);
+        serverConfig.addService(g3.graph(), HelloService.class, g3);
+        startServer(rpcServer);
+
+        // Init client
+        RpcConsumerConfig clientConfig = rpcClient.config();
+        HelloService c1 = clientConfig.serviceProxy("g1", HelloService.class);
+        HelloService c2 = clientConfig.serviceProxy("g2", HelloService.class);
+        HelloService c3 = clientConfig.serviceProxy("g3", HelloService.class);
+
+        // Test call
+        Assert.assertEquals("g1: hello tom!", c1.hello("tom"));
+        Assert.assertEquals("g1: tom", c1.echo("tom"));
+        Assert.assertEquals(5.14, c1.sum(2, 3.14), 0.00000001d);
+
+        Assert.assertEquals("g2: hello tom!", c2.hello("tom"));
+        Assert.assertEquals("g2: tom", c2.echo("tom"));
+        Assert.assertEquals(6.14, c2.sum(3, 3.14), 0.00000001d);
+
+        Assert.assertEquals("g3: hello tom!", c3.hello("tom"));
+        Assert.assertEquals("g3: tom", c3.echo("tom"));
+        Assert.assertEquals(103.14, c3.sum(100, 3.14), 0.00000001d);
+
+        Assert.assertEquals(5.14, g1.result(), 0.00000001d);
+        Assert.assertEquals(6.14, g2.result(), 0.00000001d);
+        Assert.assertEquals(103.14, g3.result(), 0.00000001d);
+    }
+
+    @Test
+    public void testStartServerWithRandomPort() {
+        // Init server
+        RpcServer rpcServerRandom = new RpcServer(config("server-random"));
+        RpcProviderConfig serverConfig = rpcServerRandom.config();
+        serverConfig.addService(HelloService.class, new HelloServiceImpl());
+        startServer(rpcServerRandom);
+
+        Assert.assertNotEquals(0, rpcServerRandom.port());
+        Assert.assertNotEquals(8090, rpcServerRandom.port());
+
+        // Init client
+        HugeConfig config = config(false);
+        String url = rpcServerRandom.host() + ":" + rpcServerRandom.port();
+        String remoteUrlKey = com.baidu.hugegraph.config
+                                 .RpcOptions.RPC_REMOTE_URL.name();
+        config.setProperty(remoteUrlKey, url);
+        RpcClientProvider rpcClientRandom = new RpcClientProvider(config);
+
+        RpcConsumerConfig clientConfig = rpcClientRandom.config();
+        HelloService client = clientConfig.serviceProxy(HelloService.class);
+
+        // Test call
+        Assert.assertEquals("hello tom!", client.hello("tom"));
+        Assert.assertEquals("tom", client.echo("tom"));
+        Assert.assertEquals(5.14, client.sum(2, 3.14), 0.00000001d);
+
+        // Destroy all
+        rpcClientRandom.destroy();
+        stopServer(rpcServerRandom);
+    }
+
+    @Test
+    public void testStartServerWithAdaptivePort() throws IOException {
+        // Init server
+        RpcServer rpcServerAdaptive = new RpcServer(config("server-adaptive"));
+        RpcProviderConfig serverConfig = rpcServerAdaptive.config();
+        serverConfig.addService(HelloService.class, new HelloServiceImpl());
+
+        // Start other server bound the port
+        int usedPort = rpcServerAdaptive.port();
+        InetAddress ip = InetAddress.getByName(rpcServerAdaptive.host());
+        ServerSocket inUse = new ServerSocket(usedPort,50, ip);
+
+        // Start server after the port in use
+        startServer(rpcServerAdaptive);
+
+        Assert.assertNotEquals(0, rpcServerAdaptive.port());
+        Assert.assertNotEquals(usedPort, rpcServerAdaptive.port());
+
+        // Init client
+        HugeConfig config = config(false);
+        String url = rpcServerAdaptive.host() + ":" + rpcServerAdaptive.port();
+        String remoteUrlKey = com.baidu.hugegraph.config
+                                 .RpcOptions.RPC_REMOTE_URL.name();
+        config.setProperty(remoteUrlKey, url);
+        RpcClientProvider rpcClientAdaptive = new RpcClientProvider(config);
+
+        RpcConsumerConfig clientConfig = rpcClientAdaptive.config();
+        HelloService client = clientConfig.serviceProxy(HelloService.class);
+
+        // Test call
+        Assert.assertEquals("hello tom!", client.hello("tom"));
+        Assert.assertEquals("tom", client.echo("tom"));
+        Assert.assertEquals(5.14, client.sum(2, 3.14), 0.00000001d);
+
+        // Destroy all
+        rpcClientAdaptive.destroy();
+        stopServer(rpcServerAdaptive);
+
+        inUse.close();
+    }
+
+    @Test
+    public void testStartBothServerAndClientThroughSameConfig() {
+        // Init server1
+        HugeConfig server1 = config("server1-client");
+        RpcServer rpcServer1 = new RpcServer(server1);
+        RpcClientProvider rpcClient1 = new RpcClientProvider(server1);
+
+        GraphHelloServiceImpl s1g1 = new GraphHelloServiceImpl("g1");
+        GraphHelloServiceImpl s1g2 = new GraphHelloServiceImpl("g2");
+
+        rpcServer1.config().addService(s1g1.graph(), HelloService.class, s1g1);
+        rpcServer1.config().addService(s1g2.graph(), HelloService.class, s1g2);
+
+        startServer(rpcServer1);
+
+        // Init server2
+        HugeConfig server2 = config("server2-client");
+        RpcServer rpcServer2 = new RpcServer(server2);
+        RpcClientProvider rpcClient2 = new RpcClientProvider(server2);
+
+        GraphHelloServiceImpl s2g1 = new GraphHelloServiceImpl("g1");
+        GraphHelloServiceImpl s2g2 = new GraphHelloServiceImpl("g2");
+
+        rpcServer2.config().addService(s2g1.graph(), HelloService.class, s2g1);
+        rpcServer2.config().addService(s2g2.graph(), HelloService.class, s2g2);
+
+        startServer(rpcServer2);
+
+        // Init client1
+        HelloService s2g1Client = rpcClient1.config().serviceProxy(
+                                  "g1", HelloService.class);
+        HelloService s2g2Client = rpcClient1.config().serviceProxy(
+                                  "g2", HelloService.class);
+
+        // Init client2
+        HelloService s1g1Client = rpcClient2.config().serviceProxy(
+                                  "g1", HelloService.class);
+        HelloService s1g2Client = rpcClient2.config().serviceProxy(
+                                  "g2", HelloService.class);
+
+        // Test call
+        Assert.assertEquals(2.1, s2g1Client.sum(1, 1.1), 0.00000001d);
+        Assert.assertEquals(2.2, s2g2Client.sum(1, 1.2), 0.00000001d);
+
+        Assert.assertEquals(1.1, s1g1Client.sum(1, 0.1), 0.00000001d);
+        Assert.assertEquals(1.2, s1g2Client.sum(0, 1.2), 0.00000001d);
+
+        Assert.assertEquals(1.1, s1g1.result(), 0.00000001d);
+        Assert.assertEquals(1.2, s1g2.result(), 0.00000001d);
+        Assert.assertEquals(2.1, s2g1.result(), 0.00000001d);
+        Assert.assertEquals(2.2, s2g2.result(), 0.00000001d);
+
+        // Destroy all
+        rpcClient1.destroy();
+        rpcClient2.destroy();
+        stopServer(rpcServer1);
+        stopServer(rpcServer2);
+    }
+
+    @Test
+    public void testFanoutCallService() {
+        // Init 3 servers
+        HugeConfig server3 = config("server3");
+        RpcServer rpcServer3 = new RpcServer(server3);
+
+        HugeConfig server4 = config("server4");
+        RpcServer rpcServer4 = new RpcServer(server4);
+
+        HugeConfig server5 = config("server5");
+        RpcServer rpcServer5 = new RpcServer(server5);
+
+        GraphHelloServiceImpl s3g1 = new GraphHelloServiceImpl("g1");
+        GraphHelloServiceImpl s4g1 = new GraphHelloServiceImpl("g1");
+        GraphHelloServiceImpl s5g1 = new GraphHelloServiceImpl("g1");
+
+        rpcServer3.config().addService(s3g1.graph(), HelloService.class, s3g1);
+        rpcServer4.config().addService(s4g1.graph(), HelloService.class, s4g1);
+        rpcServer5.config().addService(s5g1.graph(), HelloService.class, s5g1);
+
+        startServer(rpcServer3);
+        startServer(rpcServer4);
+        startServer(rpcServer5);
+
+        // Init client
+        HugeConfig client345 = config("client345");
+        RpcClientProvider rpcClient345 = new RpcClientProvider(client345);
+
+        HelloService g1 = rpcClient345.config()
+                                      .serviceProxy("g1", HelloService.class);
+
+        // Test fanout
+        Assert.assertEquals("g1: fanout", g1.echo("fanout"));
+        Assert.assertEquals(16.8, g1.sum(10, 6.8), 0.00000001d);
+
+        Assert.assertThrows(IllegalArgumentException.class, () -> {
+            g1.hello("");
+        }, e -> {
+            Assert.assertContains("empty hello parameter", e.getMessage());
+        });
+
+        Assert.assertEquals(16.8, s3g1.result(), 0.00000001d);
+        Assert.assertEquals(16.8, s4g1.result(), 0.00000001d);
+        Assert.assertEquals(16.8, s5g1.result(), 0.00000001d);
+
+        // Destroy all
+        rpcClient345.destroy();
+
+        stopServer(rpcServer3);
+        stopServer(rpcServer4);
+        stopServer(rpcServer5);
+    }
+
+    @Test
+    public void testFanoutCallServiceWithError() {
+        // Init 3 servers
+        HugeConfig server3 = config("server3");
+        RpcServer rpcServer3 = new RpcServer(server3);
+
+        HugeConfig server4 = config("server4");
+        RpcServer rpcServer4 = new RpcServer(server4);
+
+        HugeConfig server5 = config("server5");
+        RpcServer rpcServer5 = new RpcServer(server5);
+
+        GraphHelloServiceImpl s3g1 = new GraphHelloServiceImpl("g1");
+        GraphHelloServiceImpl s4g1 = new GraphHelloServiceImpl("g1");
+        GraphHelloServiceImpl s5g1 = new GraphHelloServiceImpl("g1");
+
+        rpcServer3.config().addService(s3g1.graph(), HelloService.class, s3g1);
+        rpcServer4.config().addService(s4g1.graph(), HelloService.class, s4g1);
+        rpcServer5.config().addService(s5g1.graph(), HelloService.class, s5g1);
+
+        startServer(rpcServer3);
+        startServer(rpcServer4);
+        startServer(rpcServer5);
+
+        // Init client with one server unavailable
+        HugeConfig client346 = config("client346");
+        RpcClientProvider rpcClient346 = new RpcClientProvider(client346);
+
+        HelloService g1 = rpcClient346.config()
+                                      .serviceProxy("g1", HelloService.class);
+
+        // Test fanout with one failed
+        Assert.assertEquals("g1: fanout", g1.echo("fanout"));
+        Assert.assertEquals(16.8, g1.sum(10, 6.8), 0.00000001d);
+
+        Assert.assertThrows(IllegalArgumentException.class, () -> {
+            g1.hello("");
+        }, e -> {
+            Assert.assertContains("empty hello parameter", e.getMessage());
+        });
+
+        Assert.assertEquals(16.8, s3g1.result(), 0.00000001d);
+        Assert.assertEquals(16.8, s4g1.result(), 0.00000001d);
+        Assert.assertEquals(0.0, s5g1.result(), 0.00000001d);
+
+        s3g1.resetResult();
+        s4g1.resetResult();
+        s5g1.resetResult();
+
+        // Init client with all servers unavailable
+        HugeConfig client67 = config("client67");
+        RpcClientProvider rpcClient67 = new RpcClientProvider(client67);
+
+        HelloService g67 = rpcClient67.config()
+                                      .serviceProxy("g1", HelloService.class);
+
+        // Test fanout with all failed
+        Assert.assertThrows(SofaRpcException.class, () -> {
+            g67.echo("fanout");
+        }, e -> {
+            Assert.assertContains("Failed to call", e.getMessage());
+            Assert.assertContains("echo() on remote server", e.getMessage());
+        });
+
+        Assert.assertEquals(0.0, s3g1.result(), 0.00000001d);
+        Assert.assertEquals(0.0, s4g1.result(), 0.00000001d);
+        Assert.assertEquals(0.0, s5g1.result(), 0.00000001d);
+
+        // Init client with none service provider
+        RpcClientProvider rpcClient0 = new RpcClientProvider(client67);
+        Whitebox.setInternalState(rpcClient0, "consumerConfig.remoteUrls",
+                                  "");
+        HelloService g0 = rpcClient0.config()
+                                    .serviceProxy("g1", HelloService.class);
+
+        Assert.assertThrows(SofaRpcException.class, () -> {
+            g0.echo("fanout");
+        }, e -> {
+            Assert.assertContains("No service provider for", e.getMessage());
+        });
+
+        // Destroy all
+        rpcClient346.destroy();
+        rpcClient67.destroy();
+
+        stopServer(rpcServer3);
+        stopServer(rpcServer4);
+        stopServer(rpcServer5);
+    }
+
+    @Test
+    public void testLoadBalancer() {
+        // Init 3 servers
+        HugeConfig server3 = config("server3");
+        RpcServer rpcServer3 = new RpcServer(server3);
+
+        HugeConfig server4 = config("server4");
+        RpcServer rpcServer4 = new RpcServer(server4);
+
+        HugeConfig server5 = config("server5");
+        RpcServer rpcServer5 = new RpcServer(server5);
+
+        GraphHelloServiceImpl s3g1 = new GraphHelloServiceImpl("g1");
+        GraphHelloServiceImpl s4g1 = new GraphHelloServiceImpl("g1");
+        GraphHelloServiceImpl s5g1 = new GraphHelloServiceImpl("g1");
+
+        rpcServer3.config().addService(HelloService.class, s3g1);
+        rpcServer4.config().addService(HelloService.class, s4g1);
+        rpcServer5.config().addService(HelloService.class, s5g1);
+
+        startServer(rpcServer3);
+        startServer(rpcServer4);
+        startServer(rpcServer5);
+
+        // Test LB "consistentHash"
+        HugeConfig clientLB = config("client-lb");
+        RpcClientProvider rpcClientCHash = new RpcClientProvider(clientLB);
+        HelloService cHash = rpcClientCHash.config()
+                                           .serviceProxy(HelloService.class);
+
+        Assert.assertEquals("g1: load", cHash.echo("load"));
+        Assert.assertEquals(16.8, cHash.sum(10, 6.8), 0.00000001d);
+        Assert.assertEquals(16.8, s3g1.result() + s4g1.result() + s5g1.result(),
+                            0.00000001d);
+
+        Assert.assertEquals("g1: load", cHash.echo("load"));
+        Assert.assertEquals(16.8, cHash.sum(10, 6.8), 0.00000001d);
+        Assert.assertEquals(16.8, s3g1.result() + s4g1.result() + s5g1.result(),
+                            0.00000001d);
+
+        Assert.assertEquals("g1: load", cHash.echo("load"));
+        Assert.assertEquals(16.8, cHash.sum(10, 6.8), 0.00000001d);
+        Assert.assertEquals(16.8, s3g1.result() + s4g1.result() + s5g1.result(),
+                            0.00000001d);
+
+        s3g1.resetResult();
+        s4g1.resetResult();
+        s5g1.resetResult();
+
+        // Test LB "roundRobin"
+        String lbKey = com.baidu.hugegraph.config
+                          .RpcOptions.RPC_CLIENT_LOAD_BALANCER.name();
+        clientLB.setProperty(lbKey, "roundRobin");
+        RpcClientProvider rpcClientRound = new RpcClientProvider(clientLB);
+        HelloService round = rpcClientRound.config()
+                                           .serviceProxy(HelloService.class);
+
+        Assert.assertEquals("g1: load", round.echo("load"));
+        Assert.assertEquals(1.1, round.sum(1, 0.1), 0.00000001d);
+        Assert.assertEquals(1.1, s3g1.result() + s4g1.result() + s5g1.result(),
+                            0.00000001d);
+
+        Assert.assertEquals("g1: load", round.echo("load"));
+        Assert.assertEquals(1.1, round.sum(1, 0.1), 0.00000001d);
+        Assert.assertEquals(2.2, s3g1.result() + s4g1.result() + s5g1.result(),
+                            0.00000001d);
+
+        Assert.assertEquals("g1: load", round.echo("load"));
+        Assert.assertEquals(1.1, round.sum(1, 0.1), 0.00000001d);
+        Assert.assertEquals(3.3, s3g1.result() + s4g1.result() + s5g1.result(),
+                            0.00000001d);
+
+        s3g1.resetResult();
+        s4g1.resetResult();
+        s5g1.resetResult();
+
+        // Test LB "random"
+        clientLB.setProperty(lbKey, "random");
+        RpcClientProvider rpcClientRandom = new RpcClientProvider(clientLB);
+        HelloService random = rpcClientRandom.config()
+                                             .serviceProxy(HelloService.class);
+
+        Assert.assertEquals("g1: load", random.echo("load"));
+        Assert.assertEquals(1.1, random.sum(1, 0.1), 0.00000001d);
+        Assert.assertEquals(1.1, s3g1.result() + s4g1.result() + s5g1.result(),
+                            0.00000001d);
+
+        Assert.assertEquals("g1: load", random.echo("load"));
+        Assert.assertEquals(1.1, random.sum(1, 0.1), 0.00000001d);
+        double sum = s3g1.result() + s4g1.result() + s5g1.result();
+        Assert.assertTrue(2.2 == sum || 1.1 == sum);
+
+        Assert.assertEquals("g1: load", random.echo("load"));
+        Assert.assertEquals(1.1, random.sum(1, 0.1), 0.00000001d);
+        double sum2 = s3g1.result() + s4g1.result() + s5g1.result();
+        Assert.assertTrue(sum == sum2 || sum + 1.1 == sum2);
+
+        for (int i = 0; i < 9; i++) {
+            Assert.assertEquals(1.1, random.sum(1, 0.1), 0.00000001d);
+        }
+        Assert.assertEquals(3.3, s3g1.result() + s4g1.result() + s5g1.result(),
+                            0.00000001d);
+
+        s3g1.resetResult();
+        s4g1.resetResult();
+        s5g1.resetResult();
+
+        // Destroy all
+        rpcClientCHash.destroy();
+        rpcClientRound.destroy();
+        rpcClientRandom.destroy();
+
+        stopServer(rpcServer3);
+        stopServer(rpcServer4);
+        stopServer(rpcServer5);
+    }
+
+    @Test
+    public void testServiceProxy() {
+        // Init server
+        RpcProviderConfig serverConfig = rpcServer.config();
+        serverConfig.addService(HelloService.class, new HelloServiceImpl());
+        serverConfig.addService("graph", HelloService.class,
+                                new GraphHelloServiceImpl("graph"));
+        startServer(rpcServer);
+
+        // Init client
+        RpcConsumerConfig clientConfig = rpcClient.config();
+        HelloService client = clientConfig.serviceProxy(HelloService.class);
+        HelloService client2 = clientConfig.serviceProxy(HelloService.class);
+        HelloService clientG = clientConfig.serviceProxy("graph",
+                                                         HelloService.class);
+
+        // Test call
+        Assert.assertNotEquals(client, client2);
+        Assert.assertEquals("hello tom!", client.hello("tom"));
+        Assert.assertEquals("hello tom!", client2.hello("tom"));
+        Assert.assertEquals("graph: hello tom!", clientG.hello("tom"));
+
+        // Test call after unrefer
+        rpcClient.unreferAll();
+
+        Assert.assertThrows(SofaRpcRuntimeException.class, () -> {
+            client.hello("tom");
+        });
+        Assert.assertThrows(SofaRpcRuntimeException.class, () -> {
+            client2.hello("tom");
+        });
+        Assert.assertThrows(SofaRpcRuntimeException.class, () -> {
+            clientG.hello("tom");
+        });
+    }
+
+    @Test
+    public void testAddServiceMultiTimesOfSameService() {
+        RpcServer rpcServerExport = new RpcServer(config(true));
+
+        rpcServerExport.config().addService(HelloService.class,
+                                            new HelloServiceImpl());
+
+        Assert.assertThrows(IllegalArgumentException.class, () -> {
+            rpcServerExport.config().addService(HelloService.class,
+                                                new HelloServiceImpl());
+        }, e -> {
+            Assert.assertContains("Not allowed to add service already exist",
+                                  e.getMessage());
+        });
+
+        rpcServerExport.exportAll();
+
+        stopServer(rpcServerExport);
+    }
+
+    @Test
+    public void testExportMultiTimesOfSameServer() {
+        RpcServer rpcServerExport = new RpcServer(config(true));
+        rpcServerExport.config().addService(HelloService.class,
+                                            new HelloServiceImpl());
+        rpcServerExport.exportAll();
+        rpcServerExport.exportAll();
+
+        stopServer(rpcServerExport);
+    }
+
+    @Test
+    public void testExportMultiTimesOfSameService() {
+        RpcServer rpcServerExport = new RpcServer(config(true));
+        rpcServerExport.config().addService(HelloService.class,
+                                            new HelloServiceImpl());
+        rpcServerExport.exportAll();
+
+        rpcServerExport.config().addService("graph", HelloService.class,
+                                            new HelloServiceImpl());
+        rpcServerExport.exportAll();
+
+        stopServer(rpcServerExport);
+    }
+
+    @Test
+    public void testExportNoneService() {
+        RpcServer rpcServerNoneService = new RpcServer(config(true));
+
+        // Will be ignored if none service added
+        rpcServerNoneService.exportAll();
+
+        stopServer(rpcServerNoneService);
+    }
+
+    @Test
+    public void testUnexportService() {
+        RpcServer rpcServerUnexport = new RpcServer(config(true));
+
+        RpcProviderConfig serverConfig = rpcServerUnexport.config();
+        String service = serverConfig.addService(HelloService.class,
+                                                 new HelloServiceImpl());
+        rpcServerUnexport.exportAll();
+
+        RpcConsumerConfig clientConfig = rpcClient.config();
+        HelloService client = clientConfig.serviceProxy(HelloService.class);
+
+        Assert.assertEquals("hello tom!", client.hello("tom"));
+
+        rpcServerUnexport.unexport(service);
+
+        Assert.assertThrows(SofaRpcException.class, () -> {
+            client.hello("tom");
+        });
+
+        stopServer(rpcServerUnexport);
+    }
+
+    @Test
+    public void testUnexportAllService() {
+        RpcServer rpcServerUnexport = new RpcServer(config(true));
+
+        RpcProviderConfig serverConfig = rpcServerUnexport.config();
+        serverConfig.addService(HelloService.class, new HelloServiceImpl());
+        serverConfig.addService("graph", HelloService.class,
+                                new GraphHelloServiceImpl("graph"));
+        rpcServerUnexport.exportAll();
+
+        RpcConsumerConfig clientConfig = rpcClient.config();
+        HelloService client = clientConfig.serviceProxy(HelloService.class);
+        HelloService clientG = clientConfig.serviceProxy("graph",
+                                                         HelloService.class);
+
+        Assert.assertEquals("hello tom!", client.hello("tom"));
+        Assert.assertEquals("graph: hello tom!", clientG.hello("tom"));
+
+        rpcServerUnexport.unexportAll();
+
+        Assert.assertThrows(SofaRpcException.class, () -> {
+            client.hello("tom");
+        });
+        Assert.assertThrows(SofaRpcException.class, () -> {
+            clientG.hello("tom");
+        });
+
+        stopServer(rpcServerUnexport);
+    }
+
+    @Test
+    public void testUnexportNotExistService() {
+        Assert.assertThrows(IllegalArgumentException.class, () -> {
+            rpcServer.unexport("fake");
+        }, e -> {
+            Assert.assertContains("The service 'fake' doesn't exist",
+                                  e.getMessage());
+        });
+    }
+
+    @Test
+    public void testServerDisabled() {
+        HugeConfig clientConf = config(false);
+        RpcServer rpcServerDisabled = new RpcServer(clientConf);
+
+        Assert.assertFalse(rpcServerDisabled.enabled());
+        Assert.assertThrows(IllegalArgumentException.class, () -> {
+            rpcServerDisabled.config();
+        }, e -> {
+            Assert.assertContains("RpcServer is not enabled", e.getMessage());
+        });
+
+        stopServer(rpcServerDisabled);
+    }
+
+    @Test
+    public void testClientDisabled() {
+        HugeConfig serverConf = config(true);
+        RpcClientProvider rpcClientDisabled = new RpcClientProvider(serverConf);
+
+        Assert.assertFalse(rpcClientDisabled.enabled());
+        Assert.assertThrows(IllegalArgumentException.class, () -> {
+            rpcClientDisabled.config();
+        }, e -> {
+            Assert.assertContains("RpcClient is not enabled", e.getMessage());
+        });
+
+        rpcClientDisabled.destroy();
+    }
+
+    @Test
+    public void testInitRpcConfigs() {
+        ImmutableMap<String, Object> fixedOptions = ImmutableMap.of(
+                RpcOptions.PROVIDER_REPEATED_EXPORT_LIMIT, 1);
+        RpcCommonConfig.initRpcConfigs(fixedOptions);
+
+        RpcCommonConfig.initRpcConfigs(RpcOptions.CONSUMER_RETRIES, 2);
+    }
+
+    public static interface HelloService {
+
+        public String hello(String string);
+
+        public String echo(String string);
+
+        public double sum(long a, double b);
+    }
+
+    public static class HelloServiceImpl implements HelloService {
+
+        @Override
+        public String hello(String string) {
+            E.checkArgument(!string.isEmpty(), "empty hello parameter");
+            return "hello " + string + "!";
+        }
+
+        @Override
+        public String echo(String string) {
+            return string;
+        }
+
+        @Override
+        public double sum(long a, double b) {
+            return a + b;
+        }
+    }
+
+    public static class GraphHelloServiceImpl implements HelloService {
+
+        private final String graph;
+        private double result;
+
+        public GraphHelloServiceImpl(String graph) {
+            this.graph = graph;
+        }
+
+        public String graph() {
+            return this.graph;
+        }
+
+        public void resetResult() {
+            this.result = 0.0;
+        }
+
+        public double result() {
+            return this.result;
+        }
+
+        @Override
+        public String hello(String string) {
+            E.checkArgument(!string.isEmpty(), "empty hello parameter");
+            return this.graph + ": hello " + string + "!";
+        }
+
+        @Override
+        public String echo(String string) {
+            return this.graph + ": " + string;
+        }
+
+        @Override
+        public double sum(long a, double b) {
+            this.result = a + b;
+            return this.result;
+        }
+    }
+}
diff --git a/hugegraph-rpc/src/test/java/com/baidu/hugegraph/unit/UnitTestSuite.java b/hugegraph-rpc/src/test/java/com/baidu/hugegraph/unit/UnitTestSuite.java
new file mode 100644
index 0000000..7944660
--- /dev/null
+++ b/hugegraph-rpc/src/test/java/com/baidu/hugegraph/unit/UnitTestSuite.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2017 HugeGraph Authors
+ *
+ * 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 com.baidu.hugegraph.unit;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+    VersionTest.class,
+    ExceptionTest.class,
+    ServerClientTest.class
+})
+public class UnitTestSuite {
+}
diff --git a/hugegraph-rpc/src/test/java/com/baidu/hugegraph/unit/VersionTest.java b/hugegraph-rpc/src/test/java/com/baidu/hugegraph/unit/VersionTest.java
new file mode 100644
index 0000000..e603f22
--- /dev/null
+++ b/hugegraph-rpc/src/test/java/com/baidu/hugegraph/unit/VersionTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2017 HugeGraph Authors
+ *
+ * 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 com.baidu.hugegraph.unit;
+
+import org.junit.Test;
+
+import com.baidu.hugegraph.testutil.Assert;
+import com.baidu.hugegraph.util.VersionUtil;
+import com.baidu.hugegraph.version.RpcVersion;
+
+public class VersionTest {
+
+    @Test
+    public void testGetCommonVersion() {
+        String pomVersion = VersionUtil.getPomVersion();
+        Assert.assertNotNull(pomVersion);
+        String version = RpcVersion.VERSION.get();
+        Assert.assertNotNull(version);
+        Assert.assertEquals(pomVersion, version);
+    }
+}
diff --git a/hugegraph-rpc/src/test/resources/log4j2.xml b/hugegraph-rpc/src/test/resources/log4j2.xml
new file mode 100644
index 0000000..f69acfd
--- /dev/null
+++ b/hugegraph-rpc/src/test/resources/log4j2.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration status="error">
+    <appenders>
+        <Console name="console" target="SYSTEM_OUT">
+            <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
+            <PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} %-5r [%t] [%-5p] %c %x - %m%n"/>
+        </Console>
+
+        <RollingFile name="file" fileName="logs/hugegraph-rpc.log"
+                     filePattern="logs/$${date:yyyy-MM}/hugegraph-rpc-%d{yyyy-MM-dd}-%i.log">
+            <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
+            <PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} %-5r [%t] [%-5p] %c %x - %m%n"/>
+            <SizeBasedTriggeringPolicy size="100MB"/>
+        </RollingFile>
+    </appenders>
+    <loggers>
+        <root level="INFO">
+            <appender-ref ref="console"/>
+            <appender-ref ref="file"/>
+        </root>
+        <logger name="com.baidu.hugegraph" level="INFO" additivity="false">
+            <appender-ref ref="console"/>
+            <appender-ref ref="file"/>
+        </logger>
+    </loggers>
+</configuration>
diff --git a/hugegraph-rpc/src/test/resources/rpc-client-lb.properties b/hugegraph-rpc/src/test/resources/rpc-client-lb.properties
new file mode 100644
index 0000000..fb8cad8
--- /dev/null
+++ b/hugegraph-rpc/src/test/resources/rpc-client-lb.properties
@@ -0,0 +1,9 @@
+#rpc.server_host=127.0.0.1
+#rpc.server_port=8090
+#rpc.server_timeout=30
+rpc.remote_url=127.0.0.1:8093,127.0.0.1:8094,127.0.0.1:8095
+#rpc.client_connect_timeout=20
+#rpc.client_reconnect_period=10
+#rpc.client_read_timeout=40
+#rpc.client_retries=3
+rpc.client_load_balancer=consistentHash
diff --git a/hugegraph-rpc/src/test/resources/rpc-client.properties b/hugegraph-rpc/src/test/resources/rpc-client.properties
new file mode 100644
index 0000000..16b23f3
--- /dev/null
+++ b/hugegraph-rpc/src/test/resources/rpc-client.properties
@@ -0,0 +1,9 @@
+#rpc.server_host=127.0.0.1
+#rpc.server_port=8090
+#rpc.server_timeout=30
+rpc.remote_url=127.0.0.1:8090
+#rpc.client_connect_timeout=20
+#rpc.client_reconnect_period=10
+#rpc.client_read_timeout=40
+#rpc.client_retries=3
+#rpc.client_load_balancer=consistentHash
diff --git a/hugegraph-rpc/src/test/resources/rpc-client345.properties b/hugegraph-rpc/src/test/resources/rpc-client345.properties
new file mode 100644
index 0000000..1a4fa00
--- /dev/null
+++ b/hugegraph-rpc/src/test/resources/rpc-client345.properties
@@ -0,0 +1,9 @@
+#rpc.server_host=127.0.0.1
+#rpc.server_port=8090
+#rpc.server_timeout=30
+rpc.remote_url=127.0.0.1:8093,127.0.0.1:8094,127.0.0.1:8095
+#rpc.client_connect_timeout=20
+#rpc.client_reconnect_period=10
+#rpc.client_read_timeout=40
+#rpc.client_retries=3
+#rpc.client_load_balancer=consistentHash
diff --git a/hugegraph-rpc/src/test/resources/rpc-client346.properties b/hugegraph-rpc/src/test/resources/rpc-client346.properties
new file mode 100644
index 0000000..dbcede5
--- /dev/null
+++ b/hugegraph-rpc/src/test/resources/rpc-client346.properties
@@ -0,0 +1,9 @@
+#rpc.server_host=127.0.0.1
+#rpc.server_port=8090
+#rpc.server_timeout=30
+rpc.remote_url=127.0.0.1:8093,127.0.0.1:8094,127.0.0.1:8096
+#rpc.client_connect_timeout=20
+#rpc.client_reconnect_period=10
+#rpc.client_read_timeout=40
+#rpc.client_retries=3
+#rpc.client_load_balancer=consistentHash
diff --git a/hugegraph-rpc/src/test/resources/rpc-client67.properties b/hugegraph-rpc/src/test/resources/rpc-client67.properties
new file mode 100644
index 0000000..692d7ce
--- /dev/null
+++ b/hugegraph-rpc/src/test/resources/rpc-client67.properties
@@ -0,0 +1,9 @@
+#rpc.server_host=127.0.0.1
+#rpc.server_port=8090
+#rpc.server_timeout=30
+rpc.remote_url=127.0.0.1:8096,127.0.0.1:8097
+#rpc.client_connect_timeout=20
+#rpc.client_reconnect_period=10
+#rpc.client_read_timeout=40
+#rpc.client_retries=3
+#rpc.client_load_balancer=consistentHash
diff --git a/hugegraph-rpc/src/test/resources/rpc-server-adaptive.properties b/hugegraph-rpc/src/test/resources/rpc-server-adaptive.properties
new file mode 100644
index 0000000..ae92732
--- /dev/null
+++ b/hugegraph-rpc/src/test/resources/rpc-server-adaptive.properties
@@ -0,0 +1,10 @@
+rpc.server_host=127.0.0.1
+rpc.server_port=8098
+rpc.server_adaptive_port=true
+#rpc.server_timeout=30
+#rpc.remote_url=127.0.0.1:8090
+#rpc.client_connect_timeout=20
+#rpc.client_reconnect_period=10
+#rpc.client_read_timeout=40
+#rpc.client_retries=3
+#rpc.client_load_balancer=consistentHash
diff --git a/hugegraph-rpc/src/test/resources/rpc-server-random.properties b/hugegraph-rpc/src/test/resources/rpc-server-random.properties
new file mode 100644
index 0000000..5be8331
--- /dev/null
+++ b/hugegraph-rpc/src/test/resources/rpc-server-random.properties
@@ -0,0 +1,9 @@
+rpc.server_host=127.0.0.1
+rpc.server_port=0
+#rpc.server_timeout=30
+#rpc.remote_url=127.0.0.1:8090
+#rpc.client_connect_timeout=20
+#rpc.client_reconnect_period=10
+#rpc.client_read_timeout=40
+#rpc.client_retries=3
+#rpc.client_load_balancer=consistentHash
diff --git a/hugegraph-rpc/src/test/resources/rpc-server.properties b/hugegraph-rpc/src/test/resources/rpc-server.properties
new file mode 100644
index 0000000..a22bf7e
--- /dev/null
+++ b/hugegraph-rpc/src/test/resources/rpc-server.properties
@@ -0,0 +1,9 @@
+rpc.server_host=127.0.0.1
+rpc.server_port=8090
+#rpc.server_timeout=30
+#rpc.remote_url=127.0.0.1:8090
+#rpc.client_connect_timeout=20
+#rpc.client_reconnect_period=10
+#rpc.client_read_timeout=40
+#rpc.client_retries=3
+#rpc.client_load_balancer=consistentHash
diff --git a/hugegraph-rpc/src/test/resources/rpc-server1-client.properties b/hugegraph-rpc/src/test/resources/rpc-server1-client.properties
new file mode 100644
index 0000000..a390758
--- /dev/null
+++ b/hugegraph-rpc/src/test/resources/rpc-server1-client.properties
@@ -0,0 +1,9 @@
+rpc.server_host=127.0.0.1
+rpc.server_port=8091
+#rpc.server_timeout=30
+rpc.remote_url=127.0.0.1:8092
+#rpc.client_connect_timeout=20
+#rpc.client_reconnect_period=10
+#rpc.client_read_timeout=40
+#rpc.client_retries=3
+#rpc.client_load_balancer=consistentHash
diff --git a/hugegraph-rpc/src/test/resources/rpc-server2-client.properties b/hugegraph-rpc/src/test/resources/rpc-server2-client.properties
new file mode 100644
index 0000000..e0298ed
--- /dev/null
+++ b/hugegraph-rpc/src/test/resources/rpc-server2-client.properties
@@ -0,0 +1,9 @@
+rpc.server_host=127.0.0.1
+rpc.server_port=8092
+#rpc.server_timeout=30
+rpc.remote_url=127.0.0.1:8091
+#rpc.client_connect_timeout=20
+#rpc.client_reconnect_period=10
+#rpc.client_read_timeout=40
+#rpc.client_retries=3
+#rpc.client_load_balancer=consistentHash
diff --git a/hugegraph-rpc/src/test/resources/rpc-server3.properties b/hugegraph-rpc/src/test/resources/rpc-server3.properties
new file mode 100644
index 0000000..004757c
--- /dev/null
+++ b/hugegraph-rpc/src/test/resources/rpc-server3.properties
@@ -0,0 +1,9 @@
+rpc.server_host=127.0.0.1
+rpc.server_port=8093
+#rpc.server_timeout=30
+#rpc.remote_url=127.0.0.1:8090
+#rpc.client_connect_timeout=20
+#rpc.client_reconnect_period=10
+#rpc.client_read_timeout=40
+#rpc.client_retries=3
+#rpc.client_load_balancer=consistentHash
diff --git a/hugegraph-rpc/src/test/resources/rpc-server4.properties b/hugegraph-rpc/src/test/resources/rpc-server4.properties
new file mode 100644
index 0000000..607b751
--- /dev/null
+++ b/hugegraph-rpc/src/test/resources/rpc-server4.properties
@@ -0,0 +1,9 @@
+rpc.server_host=127.0.0.1
+rpc.server_port=8094
+#rpc.server_timeout=30
+#rpc.remote_url=127.0.0.1:8090
+#rpc.client_connect_timeout=20
+#rpc.client_reconnect_period=10
+#rpc.client_read_timeout=40
+#rpc.client_retries=3
+#rpc.client_load_balancer=consistentHash
diff --git a/hugegraph-rpc/src/test/resources/rpc-server5.properties b/hugegraph-rpc/src/test/resources/rpc-server5.properties
new file mode 100644
index 0000000..dbeb1e9
--- /dev/null
+++ b/hugegraph-rpc/src/test/resources/rpc-server5.properties
@@ -0,0 +1,9 @@
+rpc.server_host=127.0.0.1
+rpc.server_port=8095
+#rpc.server_timeout=30
+#rpc.remote_url=127.0.0.1:8090
+#rpc.client_connect_timeout=20
+#rpc.client_reconnect_period=10
+#rpc.client_read_timeout=40
+#rpc.client_retries=3
+#rpc.client_load_balancer=consistentHash
diff --git a/pom.xml b/pom.xml
index 7b9e61c..771e807 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,14 +5,15 @@
     <modelVersion>4.0.0</modelVersion>
 
     <groupId>com.baidu.hugegraph</groupId>
-    <artifactId>hugegraph-common</artifactId>
+    <artifactId>hugegraph-commons</artifactId>
     <version>1.8.10</version>
+    <packaging>pom</packaging>
 
-    <name>hugegraph-common</name>
-    <url>https://github.com/hugegraph/hugegraph-common</url>
+    <name>hugegraph-commons</name>
+    <url>https://github.com/hugegraph/hugegraph-commons</url>
     <description>
-        hugegraph-common is a common module for HugeGraph and its peripheral components.
-        hugegraph-common encapsulates locks, configurations, events, iterators, rest and some
+        hugegraph-commons is a common module for HugeGraph-Common and HugeGraph-Rpc with their peripheral components.
+        It includes rpc frame, locks, configurations, events, iterators, rest and some
         numeric or collection util classes to simplify the development of HugeGraph and its components.
     </description>
 
@@ -31,9 +32,9 @@
     </licenses>
 
     <scm>
-        <url>https://github.com/hugegraph/hugegraph-common</url>
-        <connection>https://github.com/hugegraph/hugegraph-common</connection>
-        <developerConnection>https://github.com/hugegraph/hugegraph-common</developerConnection>
+        <url>https://github.com/hugegraph/hugegraph-commons</url>
+        <connection>https://github.com/hugegraph/hugegraph-commons</connection>
+        <developerConnection>https://github.com/hugegraph/hugegraph-commons</developerConnection>
     </scm>
 
     <developers>
@@ -73,163 +74,10 @@
         <mockito.version>2.25.1</mockito.version>
     </properties>
 
-    <dependencies>
-        <!-- Test -->
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <version>${junit.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.mockito</groupId>
-            <artifactId>mockito-core</artifactId>
-            <version>${mockito.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <!-- Logging -->
-        <dependency>
-            <groupId>org.apache.logging.log4j</groupId>
-            <artifactId>log4j-api</artifactId>
-            <version>${log4j2.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.logging.log4j</groupId>
-            <artifactId>log4j-core</artifactId>
-            <version>${log4j2.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.logging.log4j</groupId>
-            <artifactId>log4j-slf4j-impl</artifactId>
-            <version>${log4j2.version}</version>
-        </dependency>
-
-        <!-- Utility -->
-        <dependency>
-            <groupId>org.glassfish</groupId>
-            <artifactId>javax.json</artifactId>
-            <version>${javax.json.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>commons-configuration</groupId>
-            <artifactId>commons-configuration</artifactId>
-            <version>${commons.configuration.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-configuration2</artifactId>
-            <version>${commons.configuration2.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-            <version>${commons.io.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>commons-collections</groupId>
-            <artifactId>commons-collections</artifactId>
-            <version>${commons.collections.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>commons-codec</groupId>
-            <artifactId>commons-codec</artifactId>
-            <version>${commons.codec.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-            <version>${guava.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>com.google.code.findbugs</groupId>
-            <artifactId>jsr305</artifactId>
-            <version>${jsr305.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>joda-time</groupId>
-            <artifactId>joda-time</artifactId>
-            <version>2.10.8</version>
-        </dependency>
-
-        <!-- javassist -->
-        <dependency>
-            <groupId>org.javassist</groupId>
-            <artifactId>javassist</artifactId>
-            <version>${javassist.version}</version>
-        </dependency>
-
-        <!-- jackson -->
-        <dependency>
-            <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-annotations</artifactId>
-            <version>${jackson.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-core</artifactId>
-            <version>${jackson.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-databind</artifactId>
-            <version>${jackson.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.fasterxml.jackson.module</groupId>
-            <artifactId>jackson-module-jaxb-annotations</artifactId>
-            <version>${jackson.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.fasterxml.jackson.jaxrs</groupId>
-            <artifactId>jackson-jaxrs-base</artifactId>
-            <version>${jackson.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.fasterxml.jackson.jaxrs</groupId>
-            <artifactId>jackson-jaxrs-json-provider</artifactId>
-            <version>${jackson.version}</version>
-        </dependency>
-
-        <!-- jersey -->
-        <dependency>
-            <groupId>org.glassfish.jersey.core</groupId>
-            <artifactId>jersey-client</artifactId>
-            <version>${jersey.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.glassfish.jersey.media</groupId>
-            <artifactId>jersey-media-json-jackson</artifactId>
-            <version>${jersey.version}</version>
-            <exclusions>
-                <exclusion>
-                    <groupId>com.fasterxml.jackson.jaxrs</groupId>
-                    <artifactId>jackson-jaxrs-base</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>com.fasterxml.jackson.jaxrs</groupId>
-                    <artifactId>jackson-jaxrs-json-provider</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-        <dependency>
-            <groupId>org.glassfish.jersey.connectors</groupId>
-            <artifactId>jersey-apache-connector</artifactId>
-            <version>${jersey.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.glassfish.jersey.inject</groupId>
-            <artifactId>jersey-hk2</artifactId>
-            <version>${jersey.hk2.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>de.schlichtherle.truelicense</groupId>
-            <artifactId>truelicense-core</artifactId>
-            <version>1.33</version>
-        </dependency>
-    </dependencies>
+    <modules>
+        <module>hugegraph-common</module>
+        <module>hugegraph-rpc</module>
+    </modules>
 
     <build>
         <plugins>