From e0603ba18a67c1ef33f60122fe6f00393c0c0203 Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Thu, 13 Jul 2017 01:28:06 +0200 Subject: Tweak map-valued decode Use the same [MsgName | Avps] representation as for the list decode, but with Avps a map instead of a AVP name/values list. As a result, don't set the message/AVP name on an additional key in the map, which felt a bit odd. Messages are [MsgName :: atom() | map()], Grouped AVPs are just map(). Fix at least one problem in the traffic suite along the way: with decode_format false, the own decode in to_map/2 didn't know whether or not to decode strings, resulting on some failures. --- lib/diameter/src/base/diameter_codec.erl | 7 ++-- lib/diameter/src/base/diameter_gen.erl | 13 ++++--- lib/diameter/src/base/diameter_traffic.erl | 58 +++++++++++------------------- 3 files changed, 30 insertions(+), 48 deletions(-) (limited to 'lib/diameter/src/base') diff --git a/lib/diameter/src/base/diameter_codec.erl b/lib/diameter/src/base/diameter_codec.erl index 275e80b9bb..9b21bf4141 100644 --- a/lib/diameter/src/base/diameter_codec.erl +++ b/lib/diameter/src/base/diameter_codec.erl @@ -275,9 +275,6 @@ rec2msg(_, [Name|_]) when is_atom(Name) -> Name; -rec2msg(_, #{':name' := Name}) -> - Name; - rec2msg(Mod, Rec) -> Mod:rec2msg(element(1, Rec)). @@ -383,7 +380,9 @@ decode_avps(MsgName, Mod, AppMod, Opts, Pkt, Avps) -> %% ... or not errors = Errors, avps = As}. -reformat(MsgName, Avps, #{decode_format := list}) -> +reformat(MsgName, Avps, #{decode_format := T}) + when T == map; + T == list -> [MsgName | Avps]; reformat(_, Msg, _) -> diff --git a/lib/diameter/src/base/diameter_gen.erl b/lib/diameter/src/base/diameter_gen.erl index 78d8bd2fa3..597ec143a8 100644 --- a/lib/diameter/src/base/diameter_gen.erl +++ b/lib/diameter/src/base/diameter_gen.erl @@ -186,7 +186,7 @@ decode_avps(Name, Recs, #{module := Mod, decode_format := Fmt} = Opts) -> %% AM counts the number of top-level AVPs, which missing/4 then %% uses when adding 5005 errors. Arities = Mod:avp_arity(Name), - {reformat(Rec, Arities, Mod, Fmt), + {reformat(Name, Rec, Arities, Mod, Fmt), Avps, Failed ++ missing(Arities, Opts, Mod, AM)}. @@ -752,8 +752,8 @@ newrec(_, _, false = No) -> newrec(Mod, Name, record) -> newrec(Mod, Name); -newrec(_, Name, _) -> - #{':name' => Name}. +newrec(_, _, _) -> + #{}. %% newrec/2 @@ -762,15 +762,14 @@ newrec(Mod, Name) -> %% reformat/4 -reformat(Map, Arities, _Mod, list) -> +reformat(_, Map, Arities, _Mod, list) -> [{F,V} || {F,_} <- Arities, #{F := V} <- [Map]]; -reformat(Map, Arities, Mod, record_from_map) -> - #{':name' := Name} = Map, +reformat(Name, Map, Arities, Mod, record_from_map) -> RecName = Mod:name2rec(Name), list_to_tuple([RecName | [maps:get(F, Map, def(A)) || {F,A} <- Arities]]); -reformat(Rec, _, _, _) -> +reformat(_, Rec, _, _, _) -> Rec. %% def/1 diff --git a/lib/diameter/src/base/diameter_traffic.erl b/lib/diameter/src/base/diameter_traffic.erl index f684f60cb7..e9c422d6ab 100644 --- a/lib/diameter/src/base/diameter_traffic.erl +++ b/lib/diameter/src/base/diameter_traffic.erl @@ -621,16 +621,10 @@ is_answer_message(#diameter_packet{msg = Msg}, Dict0) -> is_answer_message([#diameter_header{is_request = R, is_error = E} | _], _) -> E andalso not R; -%% Message sent as a tagged avp/value list. +%% Message sent as a map or tagged avp/value list. is_answer_message([Name | _], _) -> Name == 'answer-message'; -%% Message sent as a map. -is_answer_message(Map, _) - when is_map(Map) -> - #{':name' := Name} = Map, - Name == 'answer-message'; - %% Message sent as a record. is_answer_message(Rec, Dict) -> try @@ -875,15 +869,13 @@ reset(Msg, [RC | Avps], Dict) -> %% set/3 -%% Reply as name and tuple list ... +%% Reply as name/values list ... +set([Name|As], Avps, _) + when is_map(As) -> + [Name | maps:merge(As, maps:from_list(Avps))]; set([_|_] = Ans, Avps, _) -> Ans ++ Avps; %% Values nearer tail take precedence. -%% ... a map ... -set(Ans, Avps, _) - when is_map(Ans) -> - maps:merge(Ans, maps:from_list(Avps)); - %% ... or record. set(Rec, Avps, Dict) -> Dict:'#set-'(Avps, Rec). @@ -902,9 +894,6 @@ rc([MsgName | _], RC, Dict) -> _ -> [] end; -rc(#{':name' := Name}, RC, Dict) -> - rc([Name], RC, Dict); - rc(Rec, RC, Dict) -> rc([Dict:rec2msg(element(1, Rec))], RC, Dict). @@ -937,10 +926,6 @@ failed(Msg, FailedAvp, Dict) -> msg2rec([MsgName | _], Dict) -> Dict:msg2rec(MsgName); -%% ... map ... -msg2rec(#{':name' := MsgName}, Dict) -> - Dict:msg2rec(MsgName); - %% ... or record. msg2rec(Rec, _) -> element(1, Rec). @@ -949,12 +934,11 @@ msg2rec(Rec, _) -> %% Message as name/values list ... values([_ | Avps], F, _) -> - proplists:get_value(F, Avps, []); - -%% ... map ... -values(Msg, F, _) - when is_map(Msg) -> - maps:get(F, Msg, []); + if is_map(Avps) -> + maps:get(F, Avps, []); + is_list(Avps) -> + proplists:get_value(F, Avps, []) + end; %% ... or record. values(Rec, F, Dict) -> @@ -1906,23 +1890,13 @@ get_avp(Dict, Name, [#diameter_header{} | Avps]) -> %% Message as name/values list ... get_avp(_, Name, [_MsgName | Avps]) -> - case lists:keyfind(Name, 1, Avps) of + case find(Name, Avps) of {_, V} -> #diameter_avp{name = Name, value = V}; _ -> undefined end; -%% ... map ... -get_avp(_, Name, Map) - when is_map(Map) -> - case maps:find(Name, Map) of - {ok, V} -> - #diameter_avp{name = Name, value = V}; - error -> - undefined - end; - %% ... or record (but not necessarily). get_avp(Dict, Name, Rec) -> try @@ -1932,6 +1906,16 @@ get_avp(Dict, Name, Rec) -> undefined end. +%% find/2 + +find(Key, Map) + when is_map(Map) -> + maps:find(Key, Map); + +find(Key, List) + when is_list(List) -> + lists:keyfind(Key, 1, List). + %% get_avp_value/3 get_avp_value(Dict, Name, Msg) -> -- cgit v1.2.3