diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine.erl b/apps/emqx_rule_engine/src/emqx_rule_engine.erl index 8d4ccb2f6..052e5391a 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_engine.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_engine.erl @@ -40,6 +40,7 @@ , get_resource_params/1 , delete_resource/1 , ensure_resource_deleted/1 + , update_resource/1 ]). -export([ init_resource/4 @@ -309,6 +310,18 @@ delete_resource(ResId) -> {error, {resource_not_found, ResId}} end. +update_resource(#{id := Id, + config := Config, + type := Type, + description := Description, + created_at := CreatedAt} = NewResource) -> + ok = refresh_resource(#resource{id = Id, + config = Config, + type = Type, + description = Description, + created_at = CreatedAt}), + create_resource(NewResource). + %% @doc Ensure resource deleted. `resource_not_found` error is discarded. -spec(ensure_resource_deleted(resource_id()) -> ok). ensure_resource_deleted(ResId) -> diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl b/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl index 90db7217c..f073a54df 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl @@ -86,6 +86,13 @@ descr => "Create a resource" }). +-rest_api(#{name => update_resource, + method => 'PUT', + path => "/resources/:bin:id", + func => update_resource, + descr => "Update a resource" + }). + -rest_api(#{name => show_resource, method => 'GET', path => "/resources/:bin:id", @@ -159,6 +166,7 @@ , get_resource_status/2 , start_resource/2 , delete_resource/2 + , update_resource/2 ]). -export([ list_resource_types/2 @@ -264,6 +272,7 @@ do_create_resource(Create, Params) -> return({error, 400, ?ERR_BADARGS(Reason)}) end. + list_resources(#{}, _Params) -> Data0 = lists:foldr(fun maybe_record_to_map/2, [], emqx_rule_registry:get_resources()), Data = lists:map(fun(Res = #{id := Id}) -> @@ -312,6 +321,21 @@ start_resource(#{id := Id}, _Params) -> return({error, 400, ?ERR_BADARGS(Reason)}) end. +update_resource(#{id := Id}, Params) -> + case emqx_rule_registry:find_resource(Id) of + {ok, #resource{id = Id, type = Type} = _OldResource} -> + Config = maps:get(config, parse_resource_params(Params)), + Description = maps:get(description, parse_resource_params(Params)), + emqx_rule_engine:update_resource(#{id => Id, + config => Config, + type => Type, + description => Description, + created_at => erlang:system_time(millisecond)}), + return(ok); + _Other -> + return({error, 400, ?ERR_NO_RESOURCE(Id)}) + end. + delete_resource(#{id := Id}, _Params) -> ok = emqx_rule_engine:ensure_resource_deleted(Id), return(ok). diff --git a/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl b/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl index 4e21f36c7..e301603df 100644 --- a/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl +++ b/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl @@ -447,8 +447,17 @@ t_crud_resources_api(_Config) -> {ok, #{code := 0, data := Resources2}} = emqx_rule_engine_api:show_resource(#{id => ResId},[]), ?assertEqual(ResId, maps:get(id, Resources2)), - ?assertMatch({ok, #{code := 0}}, emqx_rule_engine_api:delete_resource(#{id => ResId},#{})), + {ok, #{code := 0}} = emqx_rule_engine_api:update_resource(#{id => ResId}, + [{<<"id">>, ResId}, + {<<"type">>, <<"built_in">>}, + {<<"config">>, [{<<"a">>, 2}]}, + {<<"description">>, <<"2">>}]), + {ok, #{code := 0, data := Resources3}} = emqx_rule_engine_api:show_resource(#{id => ResId},[]), + ?assertEqual(ResId, maps:get(id, Resources3)), + ?assertEqual(#{<<"a">> => 2}, maps:get(config, Resources3)), + ?assertEqual(<<"2">>, maps:get(description, Resources3)), + ?assertMatch({ok, #{code := 0}}, emqx_rule_engine_api:delete_resource(#{id => ResId},#{})), ?assertMatch({ok, #{code := 404}}, emqx_rule_engine_api:show_resource(#{id => ResId},[])), ok.