feature: json serialize parse to native object
diff --git a/src/dubbo_codec.erl b/src/dubbo_codec.erl
index f2a9301..49c0c38 100644
--- a/src/dubbo_codec.erl
+++ b/src/dubbo_codec.erl
@@ -47,85 +47,27 @@
Header = << ?DUBBO_MEGIC:16,Header22:8,RequestState:8,RequestId:64,DataLen:32>>,
Header.
encode_request_data(?SERIALIZATION_FASTJSON,Request)->
- dubbo_serializa_fastjson:encode_request_data(Request);
+ dubbo_serializa_json:encode_request_data(Request);
encode_request_data(?SERIALIZATION_HESSIAN,Request)->
- State=type_encoding:init(),
- DataType =case Request#dubbo_request.is_event of
- true->
- dubbo_event;
- false->
- case Request#dubbo_request.data of
- #dubbo_rpc_invocation{} ->
- dubbo_rpc_invocation;
- _ ->
- unknow
- end
- end,
- {ok,Bin} = encode_request_data(DataType,Request,Request#dubbo_request.data,State),
- {ok,Bin}.
+ dubbo_serializa_hessian:encode_request_data(Request).
-encode_request_data(dubbo_event,Request,Data,State) ->
- Bin = cotton_hessian:encode(Data,State),
- {ok,Bin};
-encode_request_data(dubbo_rpc_invocation,Request,Data,State) ->
- METHOD_NAME = Data#dubbo_rpc_invocation.methodName,
- METHOD_ARGS_TYPES = Data#dubbo_rpc_invocation.parameterDesc,
- RequestList = [
- cotton_hessian:encode(?DUBBO_VERSION, State), %% dubbo version
- cotton_hessian:encode(Data#dubbo_rpc_invocation.className, State),
- cotton_hessian:encode(Data#dubbo_rpc_invocation.classVersion, State),
- cotton_hessian:encode(METHOD_NAME, State),
- cotton_hessian:encode(METHOD_ARGS_TYPES, State)
- ],
- {ArgsBin,State2} = encode_arguments(Data,State),
- AttachDict = dict:from_list(Data#dubbo_rpc_invocation.attachments),
- AttachMaps = #map{dict = AttachDict },
- {AttachBinay,_} = cotton_hessian:encode(AttachMaps, State2),
- RequestData = erlang:iolist_to_binary(RequestList ++ [ArgsBin,AttachBinay]),
- {ok,RequestData}.
-spec encode_response(#dubbo_response{})-> {ok,term()}.
encode_response(Response)->
- {ok,ResponseData} = encode_response_data(Response),
+ {ok,ResponseData} = encode_response_data(Response#dubbo_response.serialize_type,Response),
Size = byte_size(ResponseData),
Header = encode_response_header(Response,Size,?RESPONSE_STATE_OK),
ResponseContent = <<Header/binary,ResponseData/binary>>,
{ok, ResponseContent}.
-encode_response_data(Response)->
- State=type_encoding:init(),
- DataType =case Response#dubbo_response.is_event of
- true->
- dubbo_event;
- false->
- case Response#dubbo_response.data of
- #dubbo_rpc_invocation{} ->
- dubbo_rpc_invocation;
- _ ->
- unknow
- end
- end,
- {ok,Bin} = encode_response_data(DataType,Response,Response#dubbo_response.data,State),
- {ok,Bin}.
-encode_response_data(dubbo_event,Response,Data,State) ->
- Bin = cotton_hessian:encode(Data,State),
+encode_response_data(?SERIALIZATION_FASTJSON,Response)->
+ {ok,Bin} = dubbo_serializa_json:encode_response_data(Response),
{ok,Bin};
-encode_response_data(dubbo_rpc_invocation,Response,Data,State) ->
- Result = case Data of
- null ->
- [
- cotton_hessian:encode(?RESPONSE_NULL_VALUE, State)
- ];
- _ ->
- {ArgsBin,_State2} = encode_arguments(Data,State),
- [
- cotton_hessian:encode(?RESPONSE_VALUE, State),
- ArgsBin
- ]
- end,
- ResponseData = erlang:iolist_to_binary(Result),
- {ok,ResponseData}.
+encode_response_data(?SERIALIZATION_HESSIAN,Response)->
+
+ {ok,Bin} = dubbo_serializa_hessian:encode_response_data(Response),
+ {ok,Bin}.
encode_response_header(Response,DataLen, ResponseState)->
Header2= Response#dubbo_response.serialize_type,
@@ -140,20 +82,7 @@
RequestId = Response#dubbo_response.mid,
Header = << ?DUBBO_MEGIC:16,Header22:8, ResponseState:8,RequestId:64,DataLen:32>>,
Header.
-encode_arguments(Data,State)->
- {StateNew} = lists:foldl(fun(X,{StateTmp})->
- StateTmpNew = type_encoding:enlist(X,StateTmp),
- {StateTmpNew} end,
- {State},Data#dubbo_rpc_invocation.parameterTypes),
- {Bin,State2} = lists:foldl(fun(X,{BinTmp,StateTmp2})->
- case cotton_hessian:encode(X, StateTmp2) of
- {ArgsBin,StateTmpNew} ->
- {<<BinTmp/binary,ArgsBin/binary>>, StateTmpNew};
- ArgsBin2 ->
- {<<BinTmp/binary,ArgsBin2/binary>>, StateTmp2}
- end end,
- {<<>>,StateNew},Data#dubbo_rpc_invocation.parameters),
- {Bin,State2}.
+
-spec decode_header(binary())-> {State::ok|error,Type::request|response,Data::#dubbo_response{}|#dubbo_request{}}.
decode_header(Header)->
@@ -201,13 +130,13 @@
decode_response(Res,Data)->
case Res#dubbo_response.serialize_type of
?SERIALIZATION_FASTJSON ->
- dubbo_serializa_fastjson:decode_response(Res,Data);
+ dubbo_serializa_json:decode_response(Res,Data);
?SERIALIZATION_HESSIAN ->
dubbo_serializa_hessian:decode_response(Res,Data)
end.
%%decode_response(?SERIALIZATION_FASTJSON,dubbo_rpc_invocation,Res,Data)->
-%% dubbo_serializa_fastjson:decode_response(dubbo_rpc_invocation,Res,Data);
+%% dubbo_serializa_json:decode_response(dubbo_rpc_invocation,Res,Data);
%%
%%decode_response(?SERIALIZATION_HESSIAN,dubbo_rpc_invocation,Res,Data)->
%% {Rest,Type,State} = cotton_hessian:decode(Data,cotton_hessian:init()),
@@ -231,7 +160,7 @@
decode_request(Req,Data)->
case Req#dubbo_request.serialize_type of
?SERIALIZATION_FASTJSON ->
- dubbo_serializa_fastjson:decode_request(Req,Data);
+ dubbo_serializa_json:decode_request(Req,Data);
?SERIALIZATION_HESSIAN ->
dubbo_serializa_hessian:decode_request(Req,Data)
end.
diff --git a/src/dubbo_provider_worker.erl b/src/dubbo_provider_worker.erl
index bf1d8a2..f857a91 100644
--- a/src/dubbo_provider_worker.erl
+++ b/src/dubbo_provider_worker.erl
@@ -184,13 +184,18 @@
ok;
#dubbo_rpc_invocation{}=ResultInvoca ->
#dubbo_request{mid = Mid} = Request,
- {ok,Content }= dubbo_codec:encode_response(#dubbo_response{mid=Mid,is_event = false,data= ResultInvoca}),
+ {ok,Content }=
+ dubbo_codec:encode_response(#dubbo_response{
+ serialize_type = Request#dubbo_request.serialize_type,
+ mid=Mid,
+ is_event = false,
+ data= ResultInvoca}),
{ok,Content};
ResultObj->
%% Data = #databaseOperateResponse{databaseOperateRsp = "ha-ha"},
#dubbo_request{mid = Mid} = Request,
Data2 =#dubbo_rpc_invocation{parameters = [ResultObj]},
- {ok,Content }= dubbo_codec:encode_response(#dubbo_response{mid=Mid,is_event = false,data= Data2}),
+ {ok,Content }= dubbo_codec:encode_response(#dubbo_response{serialize_type = Request#dubbo_request.serialize_type,mid=Mid,is_event = false,data= Data2}),
{ok,Content}
end;
{error,Reason} ->
diff --git a/src/dubbo_serializa_hessian.erl b/src/dubbo_serializa_hessian.erl
index 13fc3fd..927bc82 100644
--- a/src/dubbo_serializa_hessian.erl
+++ b/src/dubbo_serializa_hessian.erl
@@ -14,12 +14,29 @@
-export([decode_header/1]).
-export([decode_response/2]).
-export([decode_request/2]).
+-export([encode_request_data/1,encode_response_data/1]).
-encode_request_data(dubbo_event,Request,Data,State) ->
+encode_request_data(Request)->
+ State=type_encoding:init(),
+ DataType =case Request#dubbo_request.is_event of
+ true->
+ dubbo_event;
+ false->
+ case Request#dubbo_request.data of
+ #dubbo_rpc_invocation{} ->
+ dubbo_rpc_invocation;
+ _ ->
+ unknow
+ end
+ end,
+ {ok,Bin} = encode_request_data(DataType,Request,Request#dubbo_request.data,State),
+ {ok,Bin}.
+
+encode_request_data(dubbo_event,_Request,Data,State) ->
Bin = cotton_hessian:encode(Data,State),
{ok,Bin};
-encode_request_data(dubbo_rpc_invocation,Request,Data,State) ->
+encode_request_data(dubbo_rpc_invocation,_Request,Data,State) ->
METHOD_NAME = Data#dubbo_rpc_invocation.methodName,
METHOD_ARGS_TYPES = Data#dubbo_rpc_invocation.parameterDesc,
RequestList = [
@@ -36,13 +53,6 @@
RequestData = erlang:iolist_to_binary(RequestList ++ [ArgsBin,AttachBinay]),
{ok,RequestData}.
--spec encode_response(#dubbo_response{})-> {ok,term()}.
-encode_response(Response)->
- {ok,ResponseData} = encode_response_data(Response),
- Size = byte_size(ResponseData),
- Header = encode_response_header(Response,Size,?RESPONSE_STATE_OK),
- ResponseContent = <<Header/binary,ResponseData/binary>>,
- {ok, ResponseContent}.
encode_response_data(Response)->
State=type_encoding:init(),
@@ -59,10 +69,11 @@
end,
{ok,Bin} = encode_response_data(DataType,Response,Response#dubbo_response.data,State),
{ok,Bin}.
-encode_response_data(dubbo_event,Response,Data,State) ->
+
+encode_response_data(dubbo_event,_Response,Data,State) ->
Bin = cotton_hessian:encode(Data,State),
{ok,Bin};
-encode_response_data(dubbo_rpc_invocation,Response,Data,State) ->
+encode_response_data(dubbo_rpc_invocation,_Response,Data,State) ->
Result = case Data of
null ->
[
@@ -78,19 +89,6 @@
ResponseData = erlang:iolist_to_binary(Result),
{ok,ResponseData}.
-encode_response_header(Response,DataLen, ResponseState)->
- Header2= Response#dubbo_response.serialize_type,
- Header21=case Response#dubbo_response.is_twoway of
- true -> Header2 bor 64;
- false-> Header2
- end,
- Header22=case Response#dubbo_response.is_event of
- true -> Header21 bor 32;
- false-> Header21
- end,
- RequestId = Response#dubbo_response.mid,
- Header = << ?DUBBO_MEGIC:16,Header22:8, ResponseState:8,RequestId:64,DataLen:32>>,
- Header.
encode_arguments(Data,State)->
{StateNew} = lists:foldl(fun(X,{StateTmp})->
StateTmpNew = type_encoding:enlist(X,StateTmp),
diff --git a/src/dubbo_serializa_fastjson.erl b/src/dubbo_serializa_json.erl
similarity index 77%
rename from src/dubbo_serializa_fastjson.erl
rename to src/dubbo_serializa_json.erl
index 0c1ed57..fd8a211 100644
--- a/src/dubbo_serializa_fastjson.erl
+++ b/src/dubbo_serializa_json.erl
@@ -6,15 +6,14 @@
%%% @end
%%% Created : 11. May 2018 10:07 AM
%%%-------------------------------------------------------------------
--module(dubbo_serializa_fastjson).
+-module(dubbo_serializa_json).
-author("dlive").
-include("dubbo.hrl").
%% API
--export([encode_request_data/1,decode_response/2,decode_request/2]).
+-export([decode_response/2,decode_request/2,decode_header/1,decode_request/2]).
--export([decode_header/1]).
--export([decode_request/2]).
+-export([encode_request_data/1,encode_response_data/1]).
encode_request_data(Request)->
DataType =case Request#dubbo_request.is_event of
@@ -61,16 +60,8 @@
{ok,Bin}.
--spec encode_response(#dubbo_response{})-> {ok,term()}.
-encode_response(Response)->
- {ok,ResponseData} = encode_response_data(Response),
- Size = byte_size(ResponseData),
- Header = encode_response_header(Response,Size,?RESPONSE_STATE_OK),
- ResponseContent = <<Header/binary,ResponseData/binary>>,
- {ok, ResponseContent}.
-
encode_response_data(Response)->
- State=type_encoding:init(),
+ State=#{},
DataType =case Response#dubbo_response.is_event of
true->
dubbo_event;
@@ -84,38 +75,27 @@
end,
{ok,Bin} = encode_response_data(DataType,Response,Response#dubbo_response.data,State),
{ok,Bin}.
-encode_response_data(dubbo_event,Response,Data,State) ->
- Bin = cotton_hessian:encode(Data,State),
+
+encode_response_data(dubbo_event,_Response,Data,State) ->
+ Bin = jiffy:encode(Data,[]),
{ok,Bin};
-encode_response_data(dubbo_rpc_invocation,Response,Data,State) ->
+encode_response_data(dubbo_rpc_invocation,_Response,Data,State) ->
Result = case Data of
null ->
[
- cotton_hessian:encode(?RESPONSE_NULL_VALUE, State)
+ string_encode(?RESPONSE_NULL_VALUE)
];
_ ->
{ArgsBin,_State2} = encode_arguments(Data,State),
[
- cotton_hessian:encode(?RESPONSE_VALUE, State),
+ string_encode(?RESPONSE_VALUE),
+ ?LINE_SEPERATOR,
ArgsBin
]
end,
ResponseData = erlang:iolist_to_binary(Result),
{ok,ResponseData}.
-encode_response_header(Response,DataLen, ResponseState)->
- Header2= Response#dubbo_response.serialize_type,
- Header21=case Response#dubbo_response.is_twoway of
- true -> Header2 bor 64;
- false-> Header2
- end,
- Header22=case Response#dubbo_response.is_event of
- true -> Header21 bor 32;
- false-> Header21
- end,
- RequestId = Response#dubbo_response.mid,
- Header = << ?DUBBO_MEGIC:16,Header22:8, ResponseState:8,RequestId:64,DataLen:32>>,
- Header.
encode_arguments(Data,State)->
{Bin} = lists:foldl(
fun(X,{BinTmp})->
@@ -176,7 +156,7 @@
decode_response(dubbo_rpc_invocation,Res,Data)
end.
decode_response(dubbo_rpc_invocation,Res,Data)->
- DataList = binary:split(Data,<<"\n">>),
+ DataList = binary:split(Data,<<"\n">>,[global]),
[TypeBin | DataList1] = DataList,
%% {Rest,Type,State} = cotton_hessian:decode(Data,cotton_hessian:init()),
Type = jiffy:decode(TypeBin),
@@ -185,7 +165,7 @@
?RESPONSE_VALUE ->
%% {_,Object,DecodeState} = cotton_hessian:decode(Rest,State),
[Value | _] = DataList1,
- Object = jiffy:decode(Value),
+ Object = jiffy:decode(Value,[return_maps]),
{ok,Res#dubbo_response{data = Object}};
?RESPONSE_NULL_VALUE ->
{ok,Res#dubbo_response{data = null}};
@@ -212,9 +192,9 @@
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]),
+ {ResultList,NewState,RestData} = decode_request_body(Data,#{},[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},
+ RpcData = #dubbo_rpc_invocation{className = Path,classVersion = Version,methodName = MethodName,parameterDesc = Desc,parameters = ArgsObj,attachments = Attachments},
Req2 = Req#dubbo_request{data = RpcData},
{ok,Req2};
@@ -226,7 +206,8 @@
{ok,Req#dubbo_request{data = Result}}.
decode_request_body(Data,State,List)->
- DataList = binary:split(Data,<<"\n">>),
+ logger:debug("decode_request_body origin data ~p",[Data]),
+ DataList = binary:split(Data,<<"\n">>,[global]),
if
length(DataList) <6 ->
{error,request_data_error};
@@ -237,10 +218,10 @@
-decode_request_body([ParseType|List],[DataItem | Data],_,ResultList)
+decode_request_body([ParseType|List],[DataItem | Data],State,ResultList)
when ParseType==dubbo;ParseType==path;ParseType==version;ParseType==method_name ->
- DecodeData = jiffy:decode(DataItem,[]),
- decode_request_body(List,Data,_, [DecodeData] ++ ResultList);
+ DecodeData = jiffy:decode(DataItem,[return_maps]),
+ decode_request_body(List,Data,State, [DecodeData] ++ ResultList);
decode_request_body([desc_and_args| List],[DescBin|Data],State,ResultList)->
ParameterDesc = jiffy:decode(DescBin,[]),
@@ -254,10 +235,10 @@
{ArgsObjList,NewState,RestData} = decode_request_body_args(ParameterDescArray,Data,State,[]),
decode_request_body(List,RestData,NewState, [ArgsObjList,ParameterDesc]++ ResultList)
end;
-decode_request_body([attachments|List],Data,State,ResultList)->
- {Rest,Attachments,State1 } = cotton_hessian:decode(Data,State),
- AttachmentsList = dict:to_list(Attachments#map.dict),
- decode_request_body(List,Rest,State1,[AttachmentsList] ++ ResultList);
+decode_request_body([attachments|List],[DataItem|Data],State,ResultList)->
+ Attachments = jiffy:decode(DataItem,[return_maps]),
+%% AttachmentsList = dict:to_list(Attachments#map.dict),
+ decode_request_body(List,Data,State,[Attachments] ++ ResultList);
decode_request_body([_Type1|List],Data,State,ResultList)->
logger:warning("decode_request_body unknow type"),
decode_request_body(List,Data,State, ResultList);
@@ -271,12 +252,29 @@
decode_request_body_args([ArgsType|RestList],Data,State,ArgsObjList) when ArgsType== <<>> ->
decode_request_body_args(RestList,Data,State,ArgsObjList);
-decode_request_body_args([_ArgsType|RestList],Data,State,ArgsObjList) ->
- {Rest,ArgObj,NewState } = cotton_hessian:decode(Data,State),
- ArgObj2 = dubbo_type_transfer:classobj_to_native(ArgObj,NewState),
- decode_request_body_args(RestList,Rest,NewState,ArgsObjList++[ArgObj2]).
+decode_request_body_args([ArgsType|RestList],[DataItem |Data],State,ArgsObjList) ->
+ ArgObj = jiffy:decode(DataItem,[return_maps]),
+%% {Rest,ArgObj,NewState } = cotton_hessian:decode(Data,State),
+ ArgObj2 = dubbo_type_transfer:jsonobj_to_native(ArgsType,ArgObj,State),
+ decode_request_body_args(RestList,Data,State,ArgsObjList++[ArgObj2]).
-string_encode(Data) when is_binary(Data)->
+string_encode(Data) when is_binary(Data) ->
<< <<"\"">>/binary,Data/binary,<<"\"">>/binary >>;
+string_encode(Data) when is_tuple(Data) ->
+ [Name |_] = tuple_to_list(Data),
+%% Size = record_info(size, Name),
+%% Fields = record_info(fields, Name),
+ case type_register:lookup_native_type(Name) of
+ undefined ->
+ <<"data encode error">>;
+ #type_def{fieldnames = Fields,foreign_type = _ForeignType} ->
+ logger:debug("string_encode lookup ~p ret ~p",[Name,Fields]),
+ MapValue = lists:foldl(
+ fun({I, E}, Acc) ->
+ Acc#{E => element(I, Data)}
+ end, #{}, lists:zip(lists:seq(2, length(Fields)+1 ),Fields)),
+ jiffy:encode(MapValue)
+ end;
+
string_encode(Data)->
jiffy:encode(Data).