فهرست منبع

feat: add `/rule_engine` API endpoint

Stefan Strigler 2 سال پیش
والد
کامیت
aea870f319

+ 3 - 0
apps/emqx_rule_engine/src/emqx_rule_api_schema.erl

@@ -48,12 +48,15 @@ check_params(Params, Tag) ->
 
 roots() ->
     [
+        {"rule_engine", sc(ref("rule_engine"), #{desc => ?DESC("root_rule_engine")})},
         {"rule_creation", sc(ref("rule_creation"), #{desc => ?DESC("root_rule_creation")})},
         {"rule_info", sc(ref("rule_info"), #{desc => ?DESC("root_rule_info")})},
         {"rule_events", sc(ref("rule_events"), #{desc => ?DESC("root_rule_events")})},
         {"rule_test", sc(ref("rule_test"), #{desc => ?DESC("root_rule_test")})}
     ].
 
+fields("rule_engine") ->
+    emqx_rule_engine_schema:fields("rule_engine");
 fields("rule_creation") ->
     emqx_rule_engine_schema:fields("rules");
 fields("rule_info") ->

+ 70 - 11
apps/emqx_rule_engine/src/emqx_rule_engine_api.erl

@@ -32,6 +32,7 @@
 
 %% API callbacks
 -export([
+    '/rule_engine'/2,
     '/rule_events'/2,
     '/rule_test'/2,
     '/rules'/2,
@@ -41,7 +42,7 @@
 ]).
 
 %% query callback
--export([qs2ms/2, run_fuzzy_match/2, format_rule_resp/1]).
+-export([qs2ms/2, run_fuzzy_match/2, format_rule_info_resp/1]).
 
 -define(ERR_BADARGS(REASON), begin
     R0 = err_msg(REASON),
@@ -134,6 +135,7 @@ api_spec() ->
 
 paths() ->
     [
+        "/rule_engine",
         "/rule_events",
         "/rule_test",
         "/rules",
@@ -145,6 +147,9 @@ paths() ->
 error_schema(Code, Message) when is_atom(Code) ->
     emqx_dashboard_swagger:error_codes([Code], list_to_binary(Message)).
 
+rule_engine_schema() ->
+    ref(emqx_rule_api_schema, "rule_engine").
+
 rule_creation_schema() ->
     ref(emqx_rule_api_schema, "rule_creation").
 
@@ -184,7 +189,7 @@ schema("/rules") ->
             responses => #{
                 200 =>
                     [
-                        {data, mk(array(rule_info_schema()), #{desc => ?DESC("desc9")})},
+                        {data, mk(array(rule_info_schema()), #{desc => ?DESC("api1_resp")})},
                         {meta, mk(ref(emqx_dashboard_swagger, meta), #{})}
                     ],
                 400 => error_schema('BAD_REQUEST', "Invalid Parameters")
@@ -289,6 +294,26 @@ schema("/rule_test") ->
                 200 => <<"Rule Test Pass">>
             }
         }
+    };
+schema("/rule_engine") ->
+    #{
+        'operationId' => '/rule_engine',
+        get => #{
+            tags => [<<"rules">>],
+            description => ?DESC("api9"),
+            responses => #{
+                200 => rule_engine_schema()
+            }
+        },
+        put => #{
+            tags => [<<"rules">>],
+            description => ?DESC("api10"),
+            'requestBody' => rule_engine_schema(),
+            responses => #{
+                200 => rule_engine_schema(),
+                400 => error_schema('BAD_REQUEST', "Invalid request")
+            }
+        }
     }.
 
 param_path_id() ->
@@ -309,7 +334,7 @@ param_path_id() ->
             QueryString,
             ?RULE_QS_SCHEMA,
             fun ?MODULE:qs2ms/2,
-            fun ?MODULE:format_rule_resp/1
+            fun ?MODULE:format_rule_info_resp/1
         )
     of
         {error, page_limit_invalid} ->
@@ -331,7 +356,7 @@ param_path_id() ->
                     case emqx_conf:update(ConfPath, Params, #{override_to => cluster}) of
                         {ok, #{post_config_update := #{emqx_rule_engine := AllRules}}} ->
                             [Rule] = get_one_rule(AllRules, Id),
-                            {201, format_rule_resp(Rule)};
+                            {201, format_rule_info_resp(Rule)};
                         {error, Reason} ->
                             ?SLOG(error, #{
                                 msg => "create_rule_failed",
@@ -362,7 +387,7 @@ param_path_id() ->
 '/rules/:id'(get, #{bindings := #{id := Id}}) ->
     case emqx_rule_engine:get_rule(Id) of
         {ok, Rule} ->
-            {200, format_rule_resp(Rule)};
+            {200, format_rule_info_resp(Rule)};
         not_found ->
             {404, #{code => 'NOT_FOUND', message => <<"Rule Id Not Found">>}}
     end;
@@ -372,7 +397,7 @@ param_path_id() ->
     case emqx_conf:update(ConfPath, Params, #{override_to => cluster}) of
         {ok, #{post_config_update := #{emqx_rule_engine := AllRules}}} ->
             [Rule] = get_one_rule(AllRules, Id),
-            {200, format_rule_resp(Rule)};
+            {200, format_rule_info_resp(Rule)};
         {error, Reason} ->
             ?SLOG(error, #{
                 msg => "update_rule_failed",
@@ -419,6 +444,20 @@ param_path_id() ->
             {404, #{code => 'NOT_FOUND', message => <<"Rule Id Not Found">>}}
     end.
 
+'/rule_engine'(get, _Params) ->
+    {200, format_rule_engine_resp(emqx_conf:get([rule_engine]))};
+'/rule_engine'(put, #{body := Params}) ->
+    case emqx_conf:update([rule_engine], Params, #{override_to => cluster}) of
+        {ok, #{config := Config}} ->
+            {200, format_rule_engine_resp(Config)};
+        {error, Reason} ->
+            ?SLOG(error, #{
+                msg => "update_rule_engine_failed",
+                reason => Reason
+            }),
+            {400, #{code => 'BAD_REQUEST', message => ?ERR_BADARGS(Reason)}}
+    end.
+
 %%------------------------------------------------------------------------------
 %% Internal functions
 %%------------------------------------------------------------------------------
@@ -440,11 +479,11 @@ encode_nested_error(RuleError, Reason) ->
             {RuleError, Reason}
     end.
 
-format_rule_resp(Rules) when is_list(Rules) ->
-    [format_rule_resp(R) || R <- Rules];
-format_rule_resp({Id, Rule}) ->
-    format_rule_resp(Rule#{id => Id});
-format_rule_resp(#{
+format_rule_info_resp(Rules) when is_list(Rules) ->
+    [format_rule_info_resp(R) || R <- Rules];
+format_rule_info_resp({Id, Rule}) ->
+    format_rule_info_resp(Rule#{id => Id});
+format_rule_info_resp(#{
     id := Id,
     name := Name,
     created_at := CreatedAt,
@@ -465,6 +504,26 @@ format_rule_resp(#{
         description => Descr
     }.
 
+format_rule_engine_resp(#{rules := Rules} = Config) ->
+    Config#{rules => maps:map(fun format_rule_resp/2, Rules)}.
+
+format_rule_resp(_Id, #{
+    name := Name,
+    metadata := MetaData = #{created_at := CreatedAt},
+    actions := Action,
+    sql := SQL,
+    enable := Enable,
+    description := Descr
+}) ->
+    #{
+        name => Name,
+        actions => format_action(Action),
+        sql => SQL,
+        enable => Enable,
+        metadata => MetaData#{created_at => format_datetime(CreatedAt, millisecond)},
+        description => Descr
+    }.
+
 format_datetime(Timestamp, Unit) ->
     list_to_binary(calendar:system_time_to_rfc3339(Timestamp, [{unit, Unit}])).
 

+ 13 - 0
apps/emqx_rule_engine/test/emqx_rule_engine_api_SUITE.erl

@@ -281,3 +281,16 @@ test_rule_params(Sql, Payload) ->
             <<"sql">> => Sql
         }
     }.
+
+t_rule_engine(_) ->
+    {200, _} = emqx_rule_engine_api:'/rule_engine'(get, foo),
+    {200, #{
+        jq_function_default_timeout := 12000,
+        jq_implementation_module := jq_port
+    }} = emqx_rule_engine_api:'/rule_engine'(put, #{
+        body => #{
+            <<"jq_function_default_timeout">> => <<"12s">>,
+            <<"jq_implementation_module">> => <<"jq_port">>
+        }
+    }),
+    {400, _} = emqx_rule_engine_api:'/rule_engine'(put, #{body => #{<<"something">> => <<"weird">>}}).

+ 1 - 0
changes/ce/feat-10336.en.md

@@ -0,0 +1 @@
+Add `/rule_engine` API endpoint to manage configuration of rule engine.

+ 11 - 0
rel/i18n/emqx_rule_api_schema.hocon

@@ -638,6 +638,17 @@ emqx_rule_api_schema {
                           }
                   }
 
+    root_rule_engine {
+                   desc {
+                         en: "Rule engine configuration schema"
+                         zh: "规则引擎配置模式"
+                        }
+                   label: {
+                           en: "Configuration Schema"
+                           zh: "配置模式"
+                          }
+                  }
+
     root_rule_creation {
                    desc {
                          en: "Schema for creating rules"

+ 27 - 10
rel/i18n/emqx_rule_engine_api.hocon

@@ -50,7 +50,16 @@ emqx_rule_engine_api {
                          zh: "根据规则来源 Topic 过滤, 使用 MQTT Topic 匹配"
                         }
                   }
-
+    api1_resp {
+        desc {
+            en: "List of rules"
+            zh: "列出所有规则"
+        }
+        label: {
+            en: "List Rules"
+            zh: "列出所有规则"
+        }
+    }
     api2 {
                    desc {
                          en: "Create a new rule using given Id"
@@ -116,7 +125,6 @@ emqx_rule_engine_api {
                            zh: "删除集群规则"
                           }
                   }
-
     api7 {
                    desc {
                          en: "Reset a rule metrics"
@@ -127,7 +135,6 @@ emqx_rule_engine_api {
                            zh: "重置规则计数"
                           }
                   }
-
     api8 {
                    desc {
                          en: "Test a rule"
@@ -138,14 +145,24 @@ emqx_rule_engine_api {
                            zh: "测试规则"
                           }
                   }
-    desc9 {
+    api9 {
                    desc {
-                         en: "List of rules"
-                         zh: "列出所有规则"
+                         en: "Get rule engine configuration"
+                         zh: "获取规则引擎配置"
                         }
-                   label: {
-                           en: "List Rules"
-                           zh: "列出所有规则"
+                   label {
+                          en: "Get configuration"
+                          zh: "获取配置"
+                         }
+    }
+    api10 {
+                   desc {
+                         en: "Update rule engine configuration"
+                         zh: "更新规则引擎配置"
+                        }
+                   label {
+                          en: "Update configuration"
+                          zh: "更新配置"
                           }
-                  }
+    }
 }