fix(tpl): ensure backward compat in `emqx_rule_engine`

Missing bindings in string templates will be rendered as "undefined",
as before. Rendering still assumes that missing binding with implicit
default (`undefined`) is an error.

This will also restore complete backward compat in `emqx_prometheus`.
This commit is contained in:
Andrew Mayorov 2023-05-04 19:08:03 +03:00
parent 1fcdfe991c
commit f689d6c233
No known key found for this signature in database
GPG Key ID: 2837C62ACFBFED5D
4 changed files with 33 additions and 7 deletions

View File

@ -340,8 +340,6 @@ lookup(Prop, Bindings) when is_binary(Prop) ->
-spec to_string(binding()) ->
unicode:chardata().
to_string(undefined) ->
[];
to_string(Bin) when is_binary(Bin) -> Bin;
to_string(Num) when is_integer(Num) -> integer_to_binary(Num);
to_string(Num) when is_float(Num) -> float_to_binary(Num, [{decimals, 10}, compact]);

View File

@ -94,7 +94,7 @@ t_render_missing_bindings(_) ->
<<"a:${a},b:${b},c:${c},d:${d.d1},e:${no.such_atom_i_swear}">>
),
?assertEqual(
{<<"a:,b:,c:,d:,e:">>, [
{<<"a:undefined,b:undefined,c:undefined,d:undefined,e:undefined">>, [
{"no.such_atom_i_swear", undefined},
{"d.d1", undefined},
{"c", undefined},

View File

@ -118,10 +118,11 @@ republish(
}
}
) ->
Topic = unicode:characters_to_binary(
emqx_connector_template:render_strict(TopicTemplate, Selected)
),
Payload = emqx_connector_template:render_strict(PayloadTemplate, Selected),
% NOTE: rendering missing bindings as string "undefined"
{TopicString, _Errors1} = emqx_connector_template:render(TopicTemplate, Selected),
{PayloadString, _Errors2} = emqx_connector_template:render(PayloadTemplate, Selected),
Topic = iolist_to_binary(TopicString),
Payload = iolist_to_binary(PayloadString),
QoS = render_simple_var(QoSTemplate, Selected, 0),
Retain = render_simple_var(RetainTemplate, Selected, false),
%% 'flags' is set for message re-publishes or message related

View File

@ -81,6 +81,7 @@ groups() ->
t_sqlselect_3,
t_sqlselect_message_publish_event_keep_original_props_1,
t_sqlselect_message_publish_event_keep_original_props_2,
t_sqlselect_missing_template_vars_render_as_undefined,
t_sqlparse_event_1,
t_sqlparse_event_2,
t_sqlparse_event_3,
@ -1946,6 +1947,32 @@ t_sqlselect_as_put(_Config) ->
PayloadMap2
).
t_sqlselect_missing_template_vars_render_as_undefined(_Config) ->
SQL = <<"SELECT * FROM \"$events/client_connected\"">>,
Repub = republish_action(<<"t2">>, <<"${clientid}:${missing.var}">>),
{ok, TopicRule} = emqx_rule_engine:create_rule(
#{
sql => SQL,
id => ?TMP_RULEID,
actions => [Repub]
}
),
{ok, Client1} = emqtt:start_link([{clientid, <<"sub-01">>}]),
{ok, _} = emqtt:connect(Client1),
{ok, _, _} = emqtt:subscribe(Client1, <<"t2">>),
{ok, Client2} = emqtt:start_link([{clientid, <<"pub-02">>}]),
{ok, _} = emqtt:connect(Client2),
emqtt:publish(Client2, <<"foo/bar/1">>, <<>>),
receive
{publish, Msg} ->
?assertMatch(#{topic := <<"t2">>, payload := <<"pub-02:undefined">>}, Msg)
after 2000 ->
ct:fail(wait_for_t2)
end,
emqtt:stop(Client2),
emqtt:stop(Client1),
delete_rule(TopicRule).
t_sqlparse_event_1(_Config) ->
Sql =
"select topic as tp "