Merge pull request #7 from DLive/0.3.1

Add readonly event message feature
diff --git a/README.md b/README.md
index 4e9b3c5..5b6944d 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,8 @@
 =====
 Apache Dubbo Erlang Implementation.
 
-[![Build Status](https://travis-ci.org/dubboerl/dubboerl.svg?branch=master)](https://travis-ci.org/dubboerl/dubboerl)
-[![codecov](https://codecov.io/gh/dubboerl/dubboerl/branch/master/graph/badge.svg)](https://codecov.io/gh/dubboerl/dubboerl)
+[![Build Status](https://travis-ci.org/apache/incubator-dubbo-erlang.svg?branch=master)](https://travis-ci.org/apache/incubator-dubbo-erlang)
+[![codecov](https://codecov.io/gh/apache/incubator-dubbo-erlang/branch/master/graph/badge.svg)](https://codecov.io/gh/apache/incubator-dubbo-erlang)
 
 Feature list
 -----
diff --git a/config_example/sys.config b/config_example/sys.config
index f33d74a..b100088 100644
--- a/config_example/sys.config
+++ b/config_example/sys.config
@@ -23,10 +23,10 @@
         {protocol,hessian},
         {port,20881},
         {consumer,[
-            {<<"com.ifcoder.demo.facade.User">>,[]}
+            {<<"org.apache.dubbo.erlang.sample.service.facade.UserOperator">>,[]}
         ]},
         {provider,[
-            {dubbo_service_user_impl,user2,<<"com.ifcoder.demo.facade.User">>,[]}
+            {dubbo_service_user_impl,userOperator,<<"org.apache.dubbo.erlang.sample.service.facade.UserOperator">>,[]}
         ]}
         
     ]}
diff --git a/include/dubbo.hrl b/include/dubbo.hrl
index ffd494e..ad2277a 100644
--- a/include/dubbo.hrl
+++ b/include/dubbo.hrl
@@ -16,94 +16,94 @@
 %%------------------------------------------------------------------------------
 -include("hessian.hrl").
 
--define(DUBBO_VERSION,<<"2.6.0">>).
+-define(DUBBO_VERSION, <<"2.6.0">>).
 -define(DUBBO_MEGIC, -9541). %% new version 16#dabb
 -define(DUBBO_MEGIC_HIGH, 16#da). %% new version 16#da
 -define(DUBBO_MEGIC_LOW, 16#bb). %% new version 16#bb
 
--define(DUBBO_DEFAULT_PORT,20880).
+-define(DUBBO_DEFAULT_PORT, 20880).
 
 %% 序列化类型
--define(SERIALIZATION_HESSIAN,2).
--define(SERIALIZATION_FASTJSON,6).
--define(SERIALIZATION_KRYO,8).
+-define(SERIALIZATION_HESSIAN, 2).
+-define(SERIALIZATION_FASTJSON, 6).
+-define(SERIALIZATION_KRYO, 8).
 
--define(RESPONSE_WITH_EXCEPTION,0).
--define(RESPONSE_VALUE,1).
--define(RESPONSE_NULL_VALUE,2).
+-define(RESPONSE_WITH_EXCEPTION, 0).
+-define(RESPONSE_VALUE, 1).
+-define(RESPONSE_NULL_VALUE, 2).
 
 
--define(RESPONSE_STATE_OK,20).
+-define(RESPONSE_STATE_OK, 20).
 
--define(REQUEST_TIME_OUT,5000).
+-define(REQUEST_TIME_OUT, 5000).
 
--define(LINE_SEPERATOR,<<"\n"/utf8>>).
+-define(LINE_SEPERATOR, <<"\n"/utf8>>).
 
--record(dubbo_request,{
-    serialize_type = 2      ::integer(),
-    is_event = true         ::boolean(),
-    is_twoway = false       ::boolean(),
-    data                    ::null|dubbo_rpc_invocation,
-    mid                     ::integer(),
-    mversion                ::binary(),
-    error_msg               ::binary(),
-    state                   ::byte(),
+-record(dubbo_request, {
+    serialize_type = 2 :: integer(),
+    is_event = true :: boolean(),
+    is_twoway = false :: boolean(),
+    data :: null|dubbo_rpc_invocation,
+    mid :: integer(),
+    mversion :: binary(),
+    error_msg :: binary(),
+    state :: byte(),
     decode_state
 }).
 
--record(dubbo_response,{
-    serialize_type = 2      ::integer(),
-    is_event = true         ::boolean(),
-    is_twoway = false       ::boolean(),
-    data                    ::null|dubbo_rpc_invocation,
-    mid                     ::integer(),
-    mversion                ::string(),
-    error_msg               ::string(),
-    state                   ::byte(),
+-record(dubbo_response, {
+    serialize_type = 2 :: integer(),
+    is_event = true :: boolean(),
+    is_twoway = false :: boolean(),
+    data :: null|dubbo_rpc_invocation,
+    mid :: integer(),
+    mversion :: string(),
+    error_msg :: string(),
+    state :: byte(),
     decode_state
 }).
 
--record(dubbo_rpc_invocation,{
+-record(dubbo_rpc_invocation, {
     serialVersionUID = -4355285085441097045,
-    className               ::string(),
-    classVersion            ::string(),
-    methodName              ::string(),
-    parameterDesc           ::string(),
-    parameterTypes=[]       ::[#type_def{}],
-    parameters=[]           ::[term()],
-    attachments=[]          ::[term()]
+    className :: string(),
+    classVersion :: string(),
+    methodName :: string(),
+    parameterDesc :: string(),
+    parameterTypes = [] :: [#type_def{}],
+    parameters = [] :: [term()],
+    attachments = [] :: [term()]
 }).
 
--record(consumer_config,{
+-record(consumer_config, {
     interface,
-    application = <<"NoName">> ::binary(),
-    category = <<"consumers">> ::binary(),
-    check=false                ::boolean(),
-    default_timeout=500        ::integer(),
-    dubbo_version= <<"2.5.3">> ::binary(),
-    methods=[]                 ::list(),
-    revision= <<"">>           ::binary(),
-    side= <<"consumers">>      ::binary()
+    application = <<"NoName">> :: binary(),
+    category = <<"consumers">> :: binary(),
+    check = false :: boolean(),
+    default_timeout = 500 :: integer(),
+    dubbo_version = <<"2.5.3">> :: binary(),
+    methods = [] :: list(),
+    revision = <<"">> :: binary(),
+    side = <<"consumers">> :: binary()
 }).
 
--record(provider_config,{
+-record(provider_config, {
     protocol,
     host,
     port,
     interface,
-    anyhost=true,
-    executes=1,
+    anyhost = true,
+    executes = 1,
     application,
-    dubbo= <<"2.5.3">>,
-    methods=[],
-    side= <<"provider">>
+    dubbo = <<"2.5.3">>,
+    methods = [],
+    side = <<"provider">>
 }).
 
 
 
--record(interface_list,{interface,pid,connection_info}).
--record(provider_node_list,{host_flag,connection_info}).
--record(connection_info,{connection_id,pid,weight,host_flag}).
+-record(interface_list, {interface, pid, connection_info}).
+-record(provider_node_list, {host_flag, connection_info}).
+-record(connection_info, {connection_id, pid, weight, host_flag, readonly = false}).
 
--type dubbo_request() ::#dubbo_request{}.
--type dubbo_response()::#dubbo_response{}.
\ No newline at end of file
+-type dubbo_request() :: #dubbo_request{}.
+-type dubbo_response() :: #dubbo_response{}.
\ No newline at end of file
diff --git a/samples/dubbo-sample-service/pom.xml b/samples/dubbo-sample-service/pom.xml
index 2ad87e0..7c09fdb 100644
--- a/samples/dubbo-sample-service/pom.xml
+++ b/samples/dubbo-sample-service/pom.xml
@@ -30,14 +30,9 @@
             <version>1.1.1</version>
         </dependency>
         <dependency>
-            <groupId>com.alibaba</groupId>
+            <groupId>org.apache.dubbo</groupId>
             <artifactId>dubbo</artifactId>
-            <version>2.5.3</version>
-        </dependency>
-        <dependency>
-            <groupId>org.javassist</groupId>
-            <artifactId>javassist</artifactId>
-            <version>3.18.1-GA</version>
+            <version>2.7.1</version>
         </dependency>
         <dependency>
             <groupId>log4j</groupId>
@@ -63,30 +58,14 @@
             </exclusions>
         </dependency>
         <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring</artifactId>
-            <version>2.5.6.SEC03</version>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-api</artifactId>
-            <version>1.7.6</version>
-        </dependency>
-        <dependency>
-            <groupId>log4j</groupId>
-            <artifactId>log4j</artifactId>
-            <version>1.2.9</version>
-        </dependency>
-
-        <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-log4j12</artifactId>
             <version>1.6.1</version>
         </dependency>
         <dependency>
-            <groupId>com.101tec</groupId>
-            <artifactId>zkclient</artifactId>
-            <version>0.4</version>
+            <groupId>org.apache.curator</groupId>
+            <artifactId>curator-recipes</artifactId>
+            <version>2.12.0</version>
         </dependency>
     </dependencies>
 
diff --git a/src/cotton_hessian.erl b/src/cotton_hessian.erl
index 395389b..30ed6c6 100644
--- a/src/cotton_hessian.erl
+++ b/src/cotton_hessian.erl
@@ -216,7 +216,7 @@
 encode(class_object,Input,State)->
   [NativeType|Values] = tuple_to_list(Input),
   {ClassEncodingBin, EncodedRef, NewState} =
-    case type_encoding:visit(NativeType,State) of
+    case dubbo_type_encoding:visit(NativeType,State) of
       {ref, Ref} ->
 %%				encode_object(type_information, {ref, Ref}, State);
         %% todo need check
diff --git a/src/dubbo_consumer_pool.erl b/src/dubbo_consumer_pool.erl
index aba36b1..0a01d38 100644
--- a/src/dubbo_consumer_pool.erl
+++ b/src/dubbo_consumer_pool.erl
@@ -29,7 +29,7 @@
     terminate/2,
     code_change/3]).
 
--export([select_connection/1, select_connection/2]).
+-export([select_connection/1, select_connection/2, update_connection_readonly/2]).
 
 -include("dubbo.hrl").
 -define(SERVER, ?MODULE).
@@ -39,6 +39,10 @@
 
 -record(state, {}).
 
+-ifdef(TEST).
+-compile([export_all]).
+-endif.
+
 
 %%%===================================================================
 %%% API
@@ -229,12 +233,12 @@
 
 update_connection_info(Interface, HostFlag, ConnectionList, IsUpdateProvideNode) ->
     lists:map(fun(Item) ->
-        I1 = ets:insert(?INTERFCE_LIST_TABLE, #interface_list{interface = Interface, connection_info = Item}),
-        logger:debug("save INTERFCE_LIST_TABLE ~p info:~p", [Interface, I1]),
+        I1 = ets:insert(?INTERFCE_LIST_TABLE, #interface_list{interface = Interface, pid = Item#connection_info.pid, connection_info = Item}),
+        logger:debug("insert interface conection info ~p ~p ~p", [Interface, Item#connection_info.pid, I1]),
         case IsUpdateProvideNode of
             true ->
                 I2 = ets:insert(?PROVIDER_NODE_LIST_TABLE, #provider_node_list{host_flag = HostFlag, connection_info = Item}),
-                logger:debug("save PROVIDER_NODE_LIST_TABLE ~p info:~p", [HostFlag, I2]);
+                logger:debug("insert PROVIDER_NODE_LIST_TABLE ~p info:~p", [HostFlag, I2]);
             false ->
                 ok
         end,
@@ -248,7 +252,7 @@
             [];
         List ->
             ListRet = [Item#interface_list.connection_info#connection_info.host_flag || Item <- List],
-            lists_util:del_duplicate(ListRet)
+            dubbo_lists_util:del_duplicate(ListRet)
     end.
 
 select_connection(Interface) ->
@@ -265,6 +269,19 @@
             {ok, InterfaceListItem#interface_list.connection_info}
     end.
 
+-spec(update_connection_readonly(pid(), boolean()) -> ok).
+update_connection_readonly(ConnectionPid, Readonly) ->
+    Pattern = #interface_list{pid = ConnectionPid, _ = '_'},
+    Objects = ets:match_object(?INTERFCE_LIST_TABLE, Pattern),
+    lists:map(fun(#interface_list{interface = Interface, pid = Pid, connection_info = ConnectionInfo} = InterferConnection) ->
+        logger:debug("[dubbo] update interface ~p ~p readonly", [Interface, Pid]),
+        NewConnectionInfo = ConnectionInfo#connection_info{readonly = Readonly},
+        NewObject = InterferConnection#interface_list{connection_info = NewConnectionInfo},
+        ets:delete_object(?INTERFCE_LIST_TABLE, InterferConnection),
+        ets:insert(?INTERFCE_LIST_TABLE, NewObject)
+              end, Objects),
+    {ok, length(Objects)}.
+
 clean_invalid_provider([]) ->
     ok;
 clean_invalid_provider([HostFlag | DeleteProverList]) ->
@@ -272,7 +289,7 @@
         [] ->
             ok;
         ProviderNodeList ->
-            ProviderNodeList1 = lists_util:del_duplicate(ProviderNodeList),
+            ProviderNodeList1 = dubbo_lists_util:del_duplicate(ProviderNodeList),
             clean_connection_info(ProviderNodeList1)
     end,
     clean_invalid_provider(DeleteProverList).
diff --git a/src/java_type_defined.erl b/src/dubbo_java_type_defined.erl
similarity index 97%
rename from src/java_type_defined.erl
rename to src/dubbo_java_type_defined.erl
index b736a0e..2ecd6f8 100644
--- a/src/java_type_defined.erl
+++ b/src/dubbo_java_type_defined.erl
@@ -14,7 +14,7 @@
 %% See the License for the specific language governing permissions and
 %% limitations under the License.
 %%------------------------------------------------------------------------------
--module(java_type_defined).
+-module(dubbo_java_type_defined).
 -include("java_type.hrl").
 %% API
 -export([get_list/0]).
diff --git a/src/lists_util.erl b/src/dubbo_lists_util.erl
similarity index 98%
rename from src/lists_util.erl
rename to src/dubbo_lists_util.erl
index af84527..04068dd 100644
--- a/src/lists_util.erl
+++ b/src/dubbo_lists_util.erl
@@ -14,7 +14,7 @@
 %% See the License for the specific language governing permissions and
 %% limitations under the License.
 %%------------------------------------------------------------------------------
--module(lists_util).
+-module(dubbo_lists_util).
 %% API
 -export([join/2, del_duplicate/1]).
 
diff --git a/src/dubbo_netty_client.erl b/src/dubbo_netty_client.erl
index bd0bc67..0181d33 100644
--- a/src/dubbo_netty_client.erl
+++ b/src/dubbo_netty_client.erl
@@ -33,7 +33,7 @@
 
 -define(SERVER, ?MODULE).
 
--record(heartbeat, {last_write = 0, last_read = 0, timeout = 60000, max_timeout = 61000}).
+-record(heartbeat, {last_write = 0, last_read = 0, timeout = 60000, max_timeout = 180000}).
 -record(state, {provider_config, socket = undefined,
     heartbeat = #heartbeat{},
     recv_buffer = <<>>,         %%从服务端接收的数据
@@ -83,7 +83,7 @@
                 {error, _Reason} ->
                     #state{}
             end,
-    NowStamp = time_util:timestamp_ms(),
+    NowStamp = dubbo_time_util:timestamp_ms(),
     HeartBeatInfo = #heartbeat{last_read = NowStamp, last_write = NowStamp},
     logger:info("netty client start ~p", [HostFlag]),
     start_heartbeat_timer(HeartBeatInfo),
@@ -293,13 +293,13 @@
     erlang:start_timer(HeartbeatInfo#heartbeat.timeout, self(), {heartbeat_timer}),
     ok.
 update_heartbeat(write, Info) ->
-    Info#heartbeat{last_write = time_util:timestamp_ms()};
+    Info#heartbeat{last_write = dubbo_time_util:timestamp_ms()};
 update_heartbeat(read, Info) ->
-    Info#heartbeat{last_read = time_util:timestamp_ms()}.
+    Info#heartbeat{last_read = dubbo_time_util:timestamp_ms()}.
 
 
 check_heartbeat_state(#state{heartbeat = HeartBeatInfo} = _State) ->
-    Now = time_util:timestamp_ms(),
+    Now = dubbo_time_util:timestamp_ms(),
     #heartbeat{last_read = LastRead, last_write = LastWrite, timeout = Timeout, max_timeout = MaxTimeout} = HeartBeatInfo,
     if
         (Now - LastRead) > Timeout ->
@@ -317,7 +317,7 @@
     {ok, Bin} = dubbo_heartbeat:generate_request(Mid, NeedResponse),
     NewState = case send_msg(Bin, State) of
                    ok ->
-                       logger:info("send one heartbeat msg to server"),
+                       logger:info("send one heartbeat to server"),
                        State;
                    {error, Reason} ->
                        logger:warning("dubbo connection send heartbeat error ~p", [Reason]),
@@ -414,6 +414,9 @@
 process_response(true, _ResponseInfo, _RestData, State) ->
     {ok, State}.
 
+process_request(true, #dubbo_request{data = <<"R">>}, State) ->
+    {ok, _} = dubbo_consumer_pool:update_connection_readonly(self(), true),
+    {ok, State};
 process_request(true, Request, State) ->
     {ok, NewState} = send_heartbeat_msg(Request#dubbo_request.mid, false, State),
     {ok, NewState};
diff --git a/src/dubbo_node_config_util.erl b/src/dubbo_node_config_util.erl
index 9d96523..32207da 100644
--- a/src/dubbo_node_config_util.erl
+++ b/src/dubbo_node_config_util.erl
@@ -96,7 +96,7 @@
         {<<"executes">>, integer_to_binary(Providerconfig#provider_config.executes)},
         {<<"methods">>, Method2},
         {<<"side">>, Providerconfig#provider_config.side},
-        {<<"timestamp">>, integer_to_binary(time_util:timestamp_ms())}
+        {<<"timestamp">>, integer_to_binary(dubbo_time_util:timestamp_ms())}
     ],
     List2 = [io_lib:format("~ts=~ts", [Key, Value]) || {Key, Value} <- List],
     lists:flatten(string:join(List2, "&")).
\ No newline at end of file
diff --git a/src/dubbo_serializa_hessian.erl b/src/dubbo_serializa_hessian.erl
index d1d4f47..0b30e04 100644
--- a/src/dubbo_serializa_hessian.erl
+++ b/src/dubbo_serializa_hessian.erl
@@ -25,7 +25,7 @@
 
 
 encode_request_data(Request) ->
-    State = type_encoding:init(),
+    State = dubbo_type_encoding:init(),
     DataType = case Request#dubbo_request.is_event of
                    true ->
                        dubbo_event;
@@ -62,7 +62,7 @@
 
 
 encode_response_data(Response) ->
-    State = type_encoding:init(),
+    State = dubbo_type_encoding:init(),
     DataType = case Response#dubbo_response.is_event of
                    true ->
                        dubbo_event;
@@ -98,7 +98,7 @@
 
 encode_arguments(Data, State) ->
     {StateNew} = lists:foldl(fun(X, {StateTmp}) ->
-        StateTmpNew = type_encoding:enlist(X, StateTmp),
+        StateTmpNew = dubbo_type_encoding:enlist(X, StateTmp),
         {StateTmpNew} end,
         {State}, Data#dubbo_rpc_invocation.parameterTypes),
     {Bin, State2} = lists:foldl(fun(X, {BinTmp, StateTmp2}) ->
@@ -190,29 +190,14 @@
     end.
 
 decode_request(dubbo_rpc_invocation, Req, Data) ->
-    {ResultList, NewState, RestData} = decode_request_body(Data, cotton_hessian:init(), [dubbo, path, version, method_name, desc_and_args, attachments]),
-    [DubboVersion, Path, Version, MethodName, Desc, ArgsObj, Attachments] = ResultList,
+    {ResultList, _NewState, _RestData} = decode_request_body(Data, cotton_hessian:init(), [dubbo, path, version, method_name, desc_and_args, attachments]),
+    [_DubboVersion, Path, Version, MethodName, Desc, ArgsObj, Attachments] = ResultList,
     RpcData = #dubbo_rpc_invocation{className = Path, classVersion = Version, methodName = MethodName, parameterDesc = Data, parameters = ArgsObj, attachments = Attachments},
     Req2 = Req#dubbo_request{data = RpcData},
     {ok, Req2};
-%%    {Rest,Dubbo,State} = cotton_hessian:decode(Data,cotton_hessian:init()),
-%%    {Rest1,ClassName,State1} = cotton_hessian:decode(Data,State),
-%%    {Rest2,ClassName,State2} = cotton_hessian:decode(Rest1,State1),
-%%    case Type of
-%%        1 ->
-%%            {_,Object,DecodeState} = cotton_hessian:decode(Rest,State),
-%%            {ok,Req#dubbo_request{data = Object,decode_state = DecodeState}};
-%%        2 ->
-%%            {ok,Req#dubbo_request{data = null,decode_state = State}};
-%%        _->
-%%            logger:warning("decode unkonw type ~p ~p",[Type,Rest]),
-%%            {Rest2,Object2,DecodeState2} = cotton_hessian:decode(Rest,State),
-%%            logger:warning("decode unkonw type2 ~p ~p",[Object2,Rest2]),
-%%            {ok,Req#dubbo_request{data = Object2,decode_state = DecodeState2}}
-%%    end;
 decode_request(dubbo_event, Req, Data) ->
-    {_Rest, undefined, _NewState} = cotton_hessian:decode(Data, cotton_hessian:init()),
-    {ok, Req#dubbo_request{data = undefined}}.
+    {_Rest, EventData, _NewState} = cotton_hessian:decode(Data, cotton_hessian:init()),
+    {ok, Req#dubbo_request{data = EventData}}.
 
 decode_request_body(Data, State, List) ->
     {ResultList, NewState, RestData} = decode_request_body(List, Data, State, []),
diff --git a/src/dubbo_serializa_json.erl b/src/dubbo_serializa_json.erl
index 35a1079..b18197a 100644
--- a/src/dubbo_serializa_json.erl
+++ b/src/dubbo_serializa_json.erl
@@ -261,7 +261,7 @@
     [Name | _] = tuple_to_list(Data),
 %%    Size = record_info(size, Name),
 %%    Fields = record_info(fields, Name),
-    case type_register:lookup_native_type(Name) of
+    case dubbo_type_register:lookup_native_type(Name) of
         undefined ->
             <<"data encode error">>;
         #type_def{fieldnames = Fields, foreign_type = _ForeignType} ->
diff --git a/src/time_util.erl b/src/dubbo_time_util.erl
similarity index 98%
rename from src/time_util.erl
rename to src/dubbo_time_util.erl
index 3243487..ea013cb 100644
--- a/src/time_util.erl
+++ b/src/dubbo_time_util.erl
@@ -14,7 +14,7 @@
 %% See the License for the specific language governing permissions and
 %% limitations under the License.
 %%------------------------------------------------------------------------------
--module(time_util).
+-module(dubbo_time_util).
 
 -include_lib("kernel/include/file.hrl").
 
diff --git a/src/type_decoding.erl b/src/dubbo_type_decoding.erl
similarity index 99%
rename from src/type_decoding.erl
rename to src/dubbo_type_decoding.erl
index 4112b61..7dd95e0 100644
--- a/src/type_decoding.erl
+++ b/src/dubbo_type_decoding.erl
@@ -14,7 +14,7 @@
 %   limitations under the License.
 % ---------------------------------------------------------------------------
 
--module(type_decoding).
+-module(dubbo_type_decoding).
 -include("hessian.hrl").
 
 %% The encoding state contains all of the statically known tuple types.
diff --git a/src/type_encoding.erl b/src/dubbo_type_encoding.erl
similarity index 97%
rename from src/type_encoding.erl
rename to src/dubbo_type_encoding.erl
index b2f72d7..4140198 100644
--- a/src/type_encoding.erl
+++ b/src/dubbo_type_encoding.erl
@@ -14,7 +14,7 @@
 %   limitations under the License.
 % ---------------------------------------------------------------------------
 
--module(type_encoding).
+-module(dubbo_type_encoding).
 
 -include("hessian.hrl").
 
@@ -88,4 +88,4 @@
     {NewCount, NewTypeDef, #encoding_state{pool = NewPool, count = NewCount}}.
 
 get_deftype_public_pool(NativeType) ->
-    type_register:lookup_native_type(NativeType).
\ No newline at end of file
+    dubbo_type_register:lookup_native_type(NativeType).
\ No newline at end of file
diff --git a/src/type_register.erl b/src/dubbo_type_register.erl
similarity index 98%
rename from src/type_register.erl
rename to src/dubbo_type_register.erl
index 82d9202..4962c2c 100644
--- a/src/type_register.erl
+++ b/src/dubbo_type_register.erl
@@ -14,7 +14,7 @@
 %   limitations under the License.
 % ---------------------------------------------------------------------------
 
--module(type_register).
+-module(dubbo_type_register).
 %% API
 -export([init/0, regiest_foreign_native/1, lookup_foreign_type/1, lookup_native_type/1]).
 -include("hessian.hrl").
diff --git a/src/dubbo_type_transfer.erl b/src/dubbo_type_transfer.erl
index e67e493..827c3d2 100644
--- a/src/dubbo_type_transfer.erl
+++ b/src/dubbo_type_transfer.erl
@@ -47,7 +47,7 @@
 
 get_deftype(ForeignType) ->
 
-    case type_register:lookup_foreign_type(ForeignType) of
+    case dubbo_type_register:lookup_foreign_type(ForeignType) of
         undefined ->
             logger:debug("get deftype undefined ~p", [ForeignType]),
             false;
@@ -62,7 +62,7 @@
 pre_process_typedef(NativeType, ForeignType, FieldsNames) ->
     Type = #type_def{native_type = NativeType, foreign_type = ForeignType, fieldnames = FieldsNames},
 %%            Type2=type_decoding:hash_store(Type),
-    type_register:regiest_foreign_native(Type),
+    dubbo_type_register:regiest_foreign_native(Type),
     logger:debug("pre_process_typedef ~p,~p", [NativeType, ForeignType]),
     ok.
 
@@ -70,7 +70,7 @@
 jsonobj_to_native(Type, JsonObj, State) ->
     ClassName = java_desc_name_to_dot(Type),
     %% todo need recursion transfer
-    case type_register:lookup_foreign_type(ClassName) of
+    case dubbo_type_register:lookup_foreign_type(ClassName) of
         undefined ->
             JsonObj;
         #type_def{fieldnames = Fields, native_type = NativeType} ->
diff --git a/src/dubbo_zookeeper.erl b/src/dubbo_zookeeper.erl
index e6f500b..f62ace1 100644
--- a/src/dubbo_zookeeper.erl
+++ b/src/dubbo_zookeeper.erl
@@ -254,7 +254,7 @@
 
 gen_consumer_node_info(Consumer) ->
     %% revision参数字段的作用是什么? 暂时不添加
-    Methods = lists_util:join(Consumer#consumer_config.methods, <<",">>),
+    Methods = dubbo_lists_util:join(Consumer#consumer_config.methods, <<",">>),
     Value = io_lib:format(<<"consumer://~s/~s?application=~s&category=~s&check=~p&default.timeout=~p&dubbo=~s&interface=~s&methods=~s&side=~s&timestamp=~p">>,
         [dubbo_common_fun:local_ip_v4_str(),
             Consumer#consumer_config.interface,
@@ -266,7 +266,7 @@
             Consumer#consumer_config.interface,
             Methods,
             Consumer#consumer_config.side,
-            time_util:timestamp_ms()
+            dubbo_time_util:timestamp_ms()
         ]),
     list_to_binary(Value).
 
diff --git a/src/dubboerl_app.erl b/src/dubboerl_app.erl
index 2e92c59..223e842 100644
--- a/src/dubboerl_app.erl
+++ b/src/dubboerl_app.erl
@@ -41,13 +41,13 @@
 env_init() ->
     ets:new(?PROVIDER_IMPL_TABLE, [public, named_table]),
     dubbo_traffic_control:init(),
-    type_register:init(),
+    dubbo_type_register:init(),
     register_type_list().
 %%    type_decoding:init().
 
 
 register_type_list() ->
-    List = java_type_defined:get_list(),
+    List = dubbo_java_type_defined:get_list(),
     lists:map(
         fun({NativeType, ForeignType, Fields}) ->
             dubbo_type_transfer:pre_process_typedef(NativeType, ForeignType, Fields)
diff --git a/test/consumer_SUITE.erl b/test/consumer_SUITE.erl
index a820b5d..ade6032 100644
--- a/test/consumer_SUITE.erl
+++ b/test/consumer_SUITE.erl
@@ -21,7 +21,7 @@
 -compile(export_all).
 
 -include_lib("common_test/include/ct.hrl").
--include("dubbo_service.hrl").
+-include("dubbo_sample_service.hrl").
 %%--------------------------------------------------------------------
 %% Function: suite() -> Info
 %% Info = [tuple()]
@@ -44,7 +44,7 @@
     dubboerl:start_provider(),
     timer:sleep(2000),
     dubboerl:start_consumer(),
-    dubbo_service_app:register_type_list(),
+    dubbo_sample_service_app:register_type_list(),
     timer:sleep(5000),
     io:format(user, "test case start info ~p~n", [Start]),
     [{appid, 1}].
@@ -142,15 +142,15 @@
 
 json_sync_invoker(_Config) ->
     application:set_env(dubboerl, protocol, json),
-    R1 = user2:queryUserInfo(#userInfoRequest{username = "name", requestId = "111"}, #{sync=> true}),
+    R1 = userOperator:queryUserInfo(#userInfoRequest{username = "name", requestId = "111"}, #{sync=> true}),
     io:format(user, "json_sync_invoker result ~p ~n", [R1]),
-    R2 = user2:genUserId(),
+    R2 = userOperator:genUserId(),
     io:format(user, "json_sync_invoker result2 ~p ~n", [R2]),
     ok.
 hessian_sync_invoker(_Config) ->
     application:set_env(dubboerl, protocol, hessian),
-    R1 = user2:queryUserInfo(#userInfoRequest{username = "name", requestId = "111"}, #{sync=> true}),
+    R1 = userOperator:queryUserInfo(#userInfoRequest{username = "name", requestId = "111"}, #{sync=> true}),
     io:format(user, "json_sync_invoker result ~p ~n", [R1]),
-    R2 = user2:genUserId(),
+    R2 = userOperator:genUserId(),
     io:format(user, "json_sync_invoker result2 ~p ~n", [R2]),
     ok.
\ No newline at end of file
diff --git a/test/dubbo_common_fun_tests.erl b/test/dubbo_common_fun_tests.erl
index cc52132..9e74ab4 100644
--- a/test/dubbo_common_fun_tests.erl
+++ b/test/dubbo_common_fun_tests.erl
@@ -23,16 +23,16 @@
     ?assert(is_integer(Id)).
 
 string_join_test() ->
-    Result1 = lists_util:join([<<"a">>, <<"b">>], <<",">>),
+    Result1 = dubbo_lists_util:join([<<"a">>, <<"b">>], <<",">>),
     ?assertEqual(Result1, <<"a,b">>),
 
-    Result2 = lists_util:join([], <<",">>),
+    Result2 = dubbo_lists_util:join([], <<",">>),
     ?assertEqual(Result2, <<"">>),
 
-    Result3 = lists_util:join([<<"a">>, "b", ttt], <<",">>),
+    Result3 = dubbo_lists_util:join([<<"a">>, "b", ttt], <<",">>),
     ?assertEqual(Result3, <<"a,b">>),
     ok.
 
 list_dup_test() ->
-    R = lists_util:del_duplicate([a, b, a]),
+    R = dubbo_lists_util:del_duplicate([a, b, a]),
     ?assertEqual(length(R), 2).
\ No newline at end of file
diff --git a/test/dubbo_consumer_pool_tests.erl b/test/dubbo_consumer_pool_tests.erl
new file mode 100644
index 0000000..740ed84
--- /dev/null
+++ b/test/dubbo_consumer_pool_tests.erl
@@ -0,0 +1,33 @@
+%%------------------------------------------------------------------------------
+%% Licensed to the Apache Software Foundation (ASF) under one or more
+%% contributor license agreements.  See the NOTICE file distributed with
+%% this work for additional information regarding copyright ownership.
+%% The ASF licenses this file to You under the Apache License, Version 2.0
+%% (the "License"); you may not use this file except in compliance with
+%% the License.  You may obtain a copy of the License at
+%%
+%%     http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%------------------------------------------------------------------------------
+-module(dubbo_consumer_pool_tests).
+-author("dlive").
+
+-include_lib("eunit/include/eunit.hrl").
+-include("dubbo.hrl").
+
+update_readonly_test() ->
+    dubbo_consumer_pool:start_link(),
+    InterfaceName= <<"testinterfacename">>,
+    HostFalg= <<"127.0.0.1/20880">>,
+    ConnectionList = [
+        #connection_info{connection_id=1,pid= testpid,weight = 30,host_flag = HostFalg},
+        #connection_info{connection_id=2,pid= testpid2,weight = 30,host_flag = HostFalg}
+    ],
+    dubbo_consumer_pool:update_connection_info(InterfaceName,HostFalg,ConnectionList,true),
+    {ok,Size} = dubbo_consumer_pool:update_connection_readonly(testpid,false),
+    ?assertEqual(1,Size).
diff --git a/test/dubbo_sample_service.hrl b/test/dubbo_sample_service.hrl
new file mode 100644
index 0000000..52458ea
--- /dev/null
+++ b/test/dubbo_sample_service.hrl
@@ -0,0 +1,13 @@
+
+-record(userInfoRequest,{
+    requestId ::list(),
+    username ::list()}).
+
+-record(userRes,{
+    userlist ::[]}).
+
+-record(userInfo,{
+    userName ::list(),
+    userAge ::integer(),
+    userId ::list()}).
+
diff --git a/test/dubbo_sample_service_app.erl b/test/dubbo_sample_service_app.erl
new file mode 100644
index 0000000..12771dc
--- /dev/null
+++ b/test/dubbo_sample_service_app.erl
@@ -0,0 +1,39 @@
+%%%-------------------------------------------------------------------
+%% @doc dubbo_sample_service public API
+%% @end
+%%%-------------------------------------------------------------------
+
+-module(dubbo_sample_service_app).
+
+-behaviour(application).
+
+%% Application callbacks
+-export([start/2, stop/1]).
+
+-include("dubbo_sample_service.hrl").
+-export([register_type_list/0]).
+
+%%====================================================================
+%% API
+%%====================================================================
+
+start(_StartType, _StartArgs) ->
+    register_type_list(),
+    dubbo_sample_service_sup:start_link().
+
+%%--------------------------------------------------------------------
+stop(_State) ->
+    ok.
+
+%%====================================================================
+%% Internal functions
+%%====================================================================
+
+
+register_type_list()->
+    List = dubbo_sample_service_type_list:get_list(),
+    lists:map(
+        fun({NativeType,ForeignType,Fields}) ->
+        dubbo_type_transfer:pre_process_typedef(NativeType,ForeignType,Fields)
+    end,List),
+    ok.
\ No newline at end of file
diff --git a/test/dubbo_sample_service_sup.erl b/test/dubbo_sample_service_sup.erl
new file mode 100644
index 0000000..a7e7ead
--- /dev/null
+++ b/test/dubbo_sample_service_sup.erl
@@ -0,0 +1,35 @@
+%%%-------------------------------------------------------------------
+%% @doc dubbo_sample_service top level supervisor.
+%% @end
+%%%-------------------------------------------------------------------
+
+-module(dubbo_sample_service_sup).
+
+-behaviour(supervisor).
+
+%% API
+-export([start_link/0]).
+
+%% Supervisor callbacks
+-export([init/1]).
+
+-define(SERVER, ?MODULE).
+
+%%====================================================================
+%% API functions
+%%====================================================================
+
+start_link() ->
+    supervisor:start_link({local, ?SERVER}, ?MODULE, []).
+
+%%====================================================================
+%% Supervisor callbacks
+%%====================================================================
+
+%% Child :: {Id,StartFunc,Restart,Shutdown,Type,Modules}
+init([]) ->
+    {ok, { {one_for_all, 0, 1}, []} }.
+
+%%====================================================================
+%% Internal functions
+%%====================================================================
diff --git a/test/dubbo_sample_service_type_list.erl b/test/dubbo_sample_service_type_list.erl
new file mode 100644
index 0000000..ce46bef
--- /dev/null
+++ b/test/dubbo_sample_service_type_list.erl
@@ -0,0 +1,15 @@
+-module(dubbo_sample_service_type_list).
+
+%% API
+-export([register_type_list/0,get_list/0]).
+
+-include("dubbo_sample_service.hrl").
+
+get_list()->
+    [
+        {userInfoRequest,<<"org.apache.dubbo.erlang.sample.service.bean.UserInfoRequest">>,record_info(fields,userInfoRequest)},
+        {userRes,<<"org.apache.dubbo.erlang.sample.service.bean.UserRes">>,record_info(fields,userRes)},
+        {userInfo,<<"org.apache.dubbo.erlang.sample.service.bean.UserInfo">>,record_info(fields,userInfo)}    ].
+
+register_type_list()->
+    ok.
\ No newline at end of file
diff --git a/test/dubbo_service.hrl b/test/dubbo_service.hrl
deleted file mode 100644
index 1153844..0000000
--- a/test/dubbo_service.hrl
+++ /dev/null
@@ -1,30 +0,0 @@
-%%------------------------------------------------------------------------------
-%% Licensed to the Apache Software Foundation (ASF) under one or more
-%% contributor license agreements.  See the NOTICE file distributed with
-%% this work for additional information regarding copyright ownership.
-%% The ASF licenses this file to You under the Apache License, Version 2.0
-%% (the "License"); you may not use this file except in compliance with
-%% the License.  You may obtain a copy of the License at
-%%
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%------------------------------------------------------------------------------
-
--record(userInfoRequest, {
-    username :: list(),
-    requestId :: list()}).
-
-
--record(userInfo, {
-    userName :: list(),
-    userId :: list(),
-    userAge :: integer()}).
-
--record(userRes, {
-    userlist :: []}).
-
diff --git a/test/dubbo_service_app.erl b/test/dubbo_service_app.erl
deleted file mode 100644
index bde5980..0000000
--- a/test/dubbo_service_app.erl
+++ /dev/null
@@ -1,51 +0,0 @@
-%%------------------------------------------------------------------------------
-%% Licensed to the Apache Software Foundation (ASF) under one or more
-%% contributor license agreements.  See the NOTICE file distributed with
-%% this work for additional information regarding copyright ownership.
-%% The ASF licenses this file to You under the Apache License, Version 2.0
-%% (the "License"); you may not use this file except in compliance with
-%% the License.  You may obtain a copy of the License at
-%%
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%------------------------------------------------------------------------------
--module(dubbo_service_app).
-
--behaviour(application).
-
-%% Application callbacks
--export([start/2, stop/1]).
--export([register_type_list/0]).
-
--include("dubbo_service.hrl").
-
-
-%%====================================================================
-%% API
-%%====================================================================
-
-start(_StartType, _StartArgs) ->
-    register_type_list(),
-    dubbo_service_sup:start_link().
-
-%%--------------------------------------------------------------------
-stop(_State) ->
-    ok.
-
-%%====================================================================
-%% Internal functions
-%%====================================================================
-
-
-register_type_list() ->
-    List = dubbo_service_type_list:get_list(),
-    lists:map(
-        fun({NativeType, ForeignType, Fields}) ->
-            dubbo_type_transfer:pre_process_typedef(NativeType, ForeignType, Fields)
-        end, List),
-    ok.
\ No newline at end of file
diff --git a/test/dubbo_service_sup.erl b/test/dubbo_service_sup.erl
deleted file mode 100644
index eb95c4d..0000000
--- a/test/dubbo_service_sup.erl
+++ /dev/null
@@ -1,46 +0,0 @@
-%%------------------------------------------------------------------------------
-%% Licensed to the Apache Software Foundation (ASF) under one or more
-%% contributor license agreements.  See the NOTICE file distributed with
-%% this work for additional information regarding copyright ownership.
-%% The ASF licenses this file to You under the Apache License, Version 2.0
-%% (the "License"); you may not use this file except in compliance with
-%% the License.  You may obtain a copy of the License at
-%%
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%------------------------------------------------------------------------------
--module(dubbo_service_sup).
-
--behaviour(supervisor).
-
-%% API
--export([start_link/0]).
-
-%% Supervisor callbacks
--export([init/1]).
-
--define(SERVER, ?MODULE).
-
-%%====================================================================
-%% API functions
-%%====================================================================
-
-start_link() ->
-    supervisor:start_link({local, ?SERVER}, ?MODULE, []).
-
-%%====================================================================
-%% Supervisor callbacks
-%%====================================================================
-
-%% Child :: {Id,StartFunc,Restart,Shutdown,Type,Modules}
-init([]) ->
-    {ok, {{one_for_all, 0, 1}, []}}.
-
-%%====================================================================
-%% Internal functions
-%%====================================================================
diff --git a/test/dubbo_service_type_list.erl b/test/dubbo_service_type_list.erl
deleted file mode 100644
index 6c8f04d..0000000
--- a/test/dubbo_service_type_list.erl
+++ /dev/null
@@ -1,31 +0,0 @@
-%%------------------------------------------------------------------------------
-%% Licensed to the Apache Software Foundation (ASF) under one or more
-%% contributor license agreements.  See the NOTICE file distributed with
-%% this work for additional information regarding copyright ownership.
-%% The ASF licenses this file to You under the Apache License, Version 2.0
-%% (the "License"); you may not use this file except in compliance with
-%% the License.  You may obtain a copy of the License at
-%%
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%------------------------------------------------------------------------------
--module(dubbo_service_type_list).
-
-%% API
--export([register_type_list/0, get_list/0]).
-
--include("dubbo_service.hrl").
-
-get_list() ->
-    [
-        {userInfoRequest, <<"com.ifcoder.demo.bean.UserInfoRequest">>, record_info(fields, userInfoRequest)},
-        {userInfo, <<"com.ifcoder.demo.bean.UserInfo">>, record_info(fields, userInfo)},
-        {userRes, <<"com.ifcoder.demo.bean.UserRes">>, record_info(fields, userRes)}].
-
-register_type_list() ->
-    ok.
\ No newline at end of file
diff --git a/test/dubbo_service_user_impl.erl b/test/dubbo_service_user_impl.erl
index ce0d5c5..e908d8a 100644
--- a/test/dubbo_service_user_impl.erl
+++ b/test/dubbo_service_user_impl.erl
@@ -17,9 +17,9 @@
 -module(dubbo_service_user_impl).
 
 
--behaviour(user2).
+-behaviour(userOperator).
 
--include_lib("dubbo_service.hrl").
+-include_lib("dubbo_sample_service.hrl").
 -include_lib("dubboerl/include/hessian.hrl").
 -include_lib("dubboerl/include/dubbo.hrl").
 %% API
diff --git a/test/hessian_encode_tests.erl b/test/hessian_encode_tests.erl
index ddb3502..81d4193 100644
--- a/test/hessian_encode_tests.erl
+++ b/test/hessian_encode_tests.erl
@@ -28,12 +28,12 @@
     TypeDefA = #type_def{foreign_type = ForeignTypeA,
         native_type = de_TestReq,
         fieldnames = record_info(fields, de_TestReq)},
-    EncodingState0 = type_encoding:enlist(TypeDefA),
+    EncodingState0 = dubbo_type_encoding:enlist(TypeDefA),
     RequestArg0 = #de_TestReq{name = <<"nameinfo">>, nick = <<"nickname">>, age = 10},
 
     {Bin, State0} = cotton_hessian:encode(RequestArg0, EncodingState0),
 
-    type_register:init(),
+    dubbo_type_register:init(),
     dubbo_type_transfer:pre_process_typedef(de_TestReq, <<"com.ifcoder.demo.bean.UserInfoRequest">>, record_info(fields, de_TestReq)),
     {<<>>, Data, State2} = cotton_hessian:decode(Bin, cotton_hessian:init()),
     DecodeResult = dubbo_type_transfer:java_to_native(Data, State2),
diff --git a/test/user2.erl b/test/user2.erl
deleted file mode 100644
index 7a9daaf..0000000
--- a/test/user2.erl
+++ /dev/null
@@ -1,181 +0,0 @@
-%%------------------------------------------------------------------------------
-%% Licensed to the Apache Software Foundation (ASF) under one or more
-%% contributor license agreements.  See the NOTICE file distributed with
-%% this work for additional information regarding copyright ownership.
-%% The ASF licenses this file to You under the Apache License, Version 2.0
-%% (the "License"); you may not use this file except in compliance with
-%% the License.  You may obtain a copy of the License at
-%%
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%------------------------------------------------------------------------------
--module(user2).
-
--include_lib("dubboerl/include/dubbo.hrl").
--include_lib("dubboerl/include/hessian.hrl").
-
--define(CURRENT_CLASS_NAME, <<"com.ifcoder.demo.facade.User"/utf8>>).
--define(CURRENT_CLASS_VERSION, <<"0.0.0"/utf8>>).
-
--include("dubbo_service.hrl").
-
-
--export([test/0]).
-
-%% API
--export([
-    getUserInfo/1,
-    getUserInfo/2,
-    genUserId/0,
-    genUserId/1,
-    queryUserInfo/1,
-    queryUserInfo/2,
-    queryUserList/1,
-    queryUserList/2]).
-
--export([get_method_999_list/0]).
-
-%% behaviour
--callback getUserInfo(Arg0 :: list()) -> #userInfo{}.
--callback genUserId() -> list().
--callback queryUserInfo(Arg0 :: #userInfoRequest{}) -> #userInfo{}.
--callback queryUserList(Arg0 :: list()) -> #userRes{}.
-
-get_method_999_list() ->
-    [
-        getUserInfo,
-        genUserId,
-        queryUserInfo,
-        queryUserList].
-
-
-
--spec getUserInfo(Arg0 :: list()) ->
-    {ok, reference()}|
-    {ok, reference(), Data :: #userInfo{}, RpcContent :: list()}|
-    {error, Reason :: timeout|no_provider|any()}.
-getUserInfo(Arg0) ->
-    getUserInfo(Arg0, #{}).
-
-getUserInfo(Arg0, RequestOption) ->
-
-    Data = #dubbo_rpc_invocation{
-        className = ?CURRENT_CLASS_NAME,
-        classVersion = ?CURRENT_CLASS_VERSION,
-        methodName = <<"getUserInfo">>,
-        parameterDesc = <<"Ljava/lang/String;"/utf8>>,
-        parameterTypes = [
-            #type_def{foreign_type = <<"java.lang.String">>,
-                native_type = string,
-                fieldnames = []}
-        ],
-        parameters = [
-            Arg0
-        ],
-        attachments = [
-            {<<"path">>, ?CURRENT_CLASS_NAME},
-            {<<"interface">>, ?CURRENT_CLASS_NAME}
-        ]
-    },
-    Request = dubbo_adapter:reference(Data),
-    dubbo_invoker:invoke_request(?CURRENT_CLASS_NAME, Request, RequestOption).
-
-
--spec genUserId() ->
-    {ok, reference()}|
-    {ok, reference(), Data :: list(), RpcContent :: list()}|
-    {error, Reason :: timeout|no_provider|any()}.
-genUserId() ->
-    genUserId(#{}).
-
-genUserId(RequestOption) ->
-
-    Data = #dubbo_rpc_invocation{
-        className = ?CURRENT_CLASS_NAME,
-        classVersion = ?CURRENT_CLASS_VERSION,
-        methodName = <<"genUserId">>,
-        parameterDesc = <<""/utf8>>,
-        parameterTypes = [
-
-        ],
-        parameters = [
-
-        ],
-        attachments = [
-            {<<"path">>, ?CURRENT_CLASS_NAME},
-            {<<"interface">>, ?CURRENT_CLASS_NAME}
-        ]
-    },
-    Request = dubbo_adapter:reference(Data),
-    dubbo_invoker:invoke_request(?CURRENT_CLASS_NAME, Request, RequestOption).
-
-
--spec queryUserInfo(Arg0 :: #userInfoRequest{}) ->
-    {ok, reference()}|
-    {ok, reference(), Data :: #userInfo{}, RpcContent :: list()}|
-    {error, Reason :: timeout|no_provider|any()}.
-queryUserInfo(Arg0) ->
-    queryUserInfo(Arg0, #{}).
-
-queryUserInfo(Arg0, RequestOption) ->
-
-    Data = #dubbo_rpc_invocation{
-        className = ?CURRENT_CLASS_NAME,
-        classVersion = ?CURRENT_CLASS_VERSION,
-        methodName = <<"queryUserInfo">>,
-        parameterDesc = <<"Lcom/ifcoder/demo/bean/UserInfoRequest;"/utf8>>,
-        parameterTypes = [
-            #type_def{foreign_type = <<"com.ifcoder.demo.bean.UserInfoRequest">>,
-                native_type = userInfoRequest,
-                fieldnames = record_info(fields, userInfoRequest)}
-        ],
-        parameters = [
-            Arg0
-        ],
-        attachments = [
-            {<<"path">>, ?CURRENT_CLASS_NAME},
-            {<<"interface">>, ?CURRENT_CLASS_NAME}
-        ]
-    },
-    Request = dubbo_adapter:reference(Data),
-    dubbo_invoker:invoke_request(?CURRENT_CLASS_NAME, Request, RequestOption).
-
-
--spec queryUserList(Arg0 :: list()) ->
-    {ok, reference()}|
-    {ok, reference(), Data :: #userRes{}, RpcContent :: list()}|
-    {error, Reason :: timeout|no_provider|any()}.
-queryUserList(Arg0) ->
-    queryUserList(Arg0, #{}).
-
-queryUserList(Arg0, RequestOption) ->
-
-    Data = #dubbo_rpc_invocation{
-        className = ?CURRENT_CLASS_NAME,
-        classVersion = ?CURRENT_CLASS_VERSION,
-        methodName = <<"queryUserList">>,
-        parameterDesc = <<"Ljava/lang/String;"/utf8>>,
-        parameterTypes = [
-            #type_def{foreign_type = <<"java.lang.String">>,
-                native_type = string,
-                fieldnames = []}
-        ],
-        parameters = [
-            Arg0
-        ],
-        attachments = [
-            {<<"path">>, ?CURRENT_CLASS_NAME},
-            {<<"interface">>, ?CURRENT_CLASS_NAME}
-        ]
-    },
-    Request = dubbo_adapter:reference(Data),
-    dubbo_invoker:invoke_request(?CURRENT_CLASS_NAME, Request, RequestOption).
-
-
-test() ->
-    queryUserInfo(#userInfoRequest{username = "name", requestId = "111"}, #{sync=> true}).
\ No newline at end of file
diff --git a/test/userOperator.erl b/test/userOperator.erl
new file mode 100644
index 0000000..0d35917
--- /dev/null
+++ b/test/userOperator.erl
@@ -0,0 +1,164 @@
+-module(userOperator).
+
+-include_lib("dubboerl/include/dubbo.hrl").
+-include_lib("dubboerl/include/hessian.hrl").
+
+-define(CURRENT_CLASS_NAME,<<"org.apache.dubbo.erlang.sample.service.facade.UserOperator"/utf8>>).
+-define(CURRENT_CLASS_VERSION,<<"0.0.0"/utf8>>).
+
+-include("dubbo_sample_service.hrl").
+
+
+
+-export([test/0]).
+%% API
+-export([
+    getUserInfo/1,
+    getUserInfo/2,
+    genUserId/0,
+    genUserId/1,
+    queryUserInfo/1,
+    queryUserInfo/2,
+    queryUserList/1,
+    queryUserList/2]).
+
+-export([get_method_999_list/0]).
+
+%% behaviour
+-callback getUserInfo(Arg0::list())-> #userInfo{}.
+-callback genUserId()-> list().
+-callback queryUserInfo(Arg0::#userInfoRequest{})-> #userInfo{}.
+-callback queryUserList(Arg0::list())-> #userRes{}.
+
+get_method_999_list()->
+    [
+    getUserInfo,
+    genUserId,
+    queryUserInfo,
+    queryUserList].
+
+
+
+-spec getUserInfo(Arg0::list())->
+    {ok,reference()}|
+    {ok,reference(),Data::#userInfo{},RpcContent::list()}|
+    {error,Reason::timeout|no_provider|any()}.
+getUserInfo(Arg0)->
+    getUserInfo(Arg0 ,#{}).
+
+getUserInfo(Arg0, RequestOption)->
+    
+    Data = #dubbo_rpc_invocation{
+        className = ?CURRENT_CLASS_NAME,
+        classVersion = ?CURRENT_CLASS_VERSION,
+        methodName = <<"getUserInfo">>,
+        parameterDesc = <<"Ljava/lang/String;"/utf8>>,
+        parameterTypes = [
+            #type_def{foreign_type = <<"java.lang.String">>,
+            native_type = string,
+            fieldnames = []}
+        ],
+        parameters = [
+            Arg0
+        ],
+        attachments = [
+            {<<"path">>, ?CURRENT_CLASS_NAME},
+            {<<"interface">> , ?CURRENT_CLASS_NAME}
+        ]
+    },
+    Request = dubbo_adapter:reference(Data),
+    dubbo_invoker:invoke_request(?CURRENT_CLASS_NAME,Request,RequestOption).
+
+
+-spec genUserId()->
+    {ok,reference()}|
+    {ok,reference(),Data::list(),RpcContent::list()}|
+    {error,Reason::timeout|no_provider|any()}.
+genUserId()->
+    genUserId( #{}).
+
+genUserId( RequestOption)->
+    
+    Data = #dubbo_rpc_invocation{
+        className = ?CURRENT_CLASS_NAME,
+        classVersion = ?CURRENT_CLASS_VERSION,
+        methodName = <<"genUserId">>,
+        parameterDesc = <<""/utf8>>,
+        parameterTypes = [
+            
+        ],
+        parameters = [
+            
+        ],
+        attachments = [
+            {<<"path">>, ?CURRENT_CLASS_NAME},
+            {<<"interface">> , ?CURRENT_CLASS_NAME}
+        ]
+    },
+    Request = dubbo_adapter:reference(Data),
+    dubbo_invoker:invoke_request(?CURRENT_CLASS_NAME,Request,RequestOption).
+
+
+-spec queryUserInfo(Arg0::#userInfoRequest{})->
+    {ok,reference()}|
+    {ok,reference(),Data::#userInfo{},RpcContent::list()}|
+    {error,Reason::timeout|no_provider|any()}.
+queryUserInfo(Arg0)->
+    queryUserInfo(Arg0 ,#{}).
+
+queryUserInfo(Arg0, RequestOption)->
+    
+    Data = #dubbo_rpc_invocation{
+        className = ?CURRENT_CLASS_NAME,
+        classVersion = ?CURRENT_CLASS_VERSION,
+        methodName = <<"queryUserInfo">>,
+        parameterDesc = <<"Lorg/apache/dubbo/erlang/sample/service/bean/UserInfoRequest;"/utf8>>,
+        parameterTypes = [
+            #type_def{foreign_type = <<"org.apache.dubbo.erlang.sample.service.bean.UserInfoRequest">>,
+            native_type = userInfoRequest,
+            fieldnames = record_info(fields,userInfoRequest)}
+        ],
+        parameters = [
+            Arg0
+        ],
+        attachments = [
+            {<<"path">>, ?CURRENT_CLASS_NAME},
+            {<<"interface">> , ?CURRENT_CLASS_NAME}
+        ]
+    },
+    Request = dubbo_adapter:reference(Data),
+    dubbo_invoker:invoke_request(?CURRENT_CLASS_NAME,Request,RequestOption).
+
+
+-spec queryUserList(Arg0::list())->
+    {ok,reference()}|
+    {ok,reference(),Data::#userRes{},RpcContent::list()}|
+    {error,Reason::timeout|no_provider|any()}.
+queryUserList(Arg0)->
+    queryUserList(Arg0 ,#{}).
+
+queryUserList(Arg0, RequestOption)->
+    
+    Data = #dubbo_rpc_invocation{
+        className = ?CURRENT_CLASS_NAME,
+        classVersion = ?CURRENT_CLASS_VERSION,
+        methodName = <<"queryUserList">>,
+        parameterDesc = <<"Ljava/lang/String;"/utf8>>,
+        parameterTypes = [
+            #type_def{foreign_type = <<"java.lang.String">>,
+            native_type = string,
+            fieldnames = []}
+        ],
+        parameters = [
+            Arg0
+        ],
+        attachments = [
+            {<<"path">>, ?CURRENT_CLASS_NAME},
+            {<<"interface">> , ?CURRENT_CLASS_NAME}
+        ]
+    },
+    Request = dubbo_adapter:reference(Data),
+    dubbo_invoker:invoke_request(?CURRENT_CLASS_NAME,Request,RequestOption).
+
+test() ->
+    queryUserInfo(#userInfoRequest{username = "name", requestId = "111"}, #{sync=> true}).
\ No newline at end of file