diff --git a/apps/emqx_connector/i18n/emqx_connector_mongo.conf b/apps/emqx_connector/i18n/emqx_connector_mongo.conf index 71e970574..158a547be 100644 --- a/apps/emqx_connector/i18n/emqx_connector_mongo.conf +++ b/apps/emqx_connector/i18n/emqx_connector_mongo.conf @@ -150,4 +150,48 @@ The MongoDB default port 27017 is used if `[:Port]` is not specified. } } + desc_single { + desc { + en: """Settings for a single MongoDB instance.""" + zh: """配置 Single 模式""" + } + label: { + en: "Setting Single MongoDB" + zh: "配置 Single 模式" + } + } + + desc_rs { + desc { + en: """Settings for replica set.""" + zh: """配置 Replica Set""" + } + label: { + en: "Setting Replica Set" + zh: "配置 Replica Set" + } + } + + desc_sharded { + desc { + en: """Settings for sharded cluster.""" + zh: """配置 Sharded Cluster""" + } + label: { + en: "Setting Sharded Cluster" + zh: "配置 Sharded Cluster" + } + } + + desc_topology { + desc { + en: """Topology of MongoDB.""" + zh: """配置 Topology""" + } + label: { + en: "Setting Topology" + zh: "配置 Topology" + } + } + } diff --git a/apps/emqx_connector/i18n/emqx_connector_mqtt_schema.conf b/apps/emqx_connector/i18n/emqx_connector_mqtt_schema.conf index a640625a6..ee6178845 100644 --- a/apps/emqx_connector/i18n/emqx_connector_mqtt_schema.conf +++ b/apps/emqx_connector/i18n/emqx_connector_mqtt_schema.conf @@ -297,4 +297,66 @@ Template with variables is allowed. } } + desc_connector { + desc { + en: """Generic configuration for the connector.""" + zh: """连接器的通用配置。""" + } + label: { + en: "Connector Generic Configuration" + zh: "连接器通用配置。" + } + } + + desc_ingress { + desc { + en: """ +The ingress config defines how this bridge receive messages from the remote MQTT broker, and then send them to the local broker.
+Template with variables is allowed in 'local_topic', 'remote_qos', 'qos', 'retain', 'payload'.
+NOTE: if this bridge is used as the input of a rule (emqx rule engine), and also local_topic is configured, then messages got from the remote broker will be sent to both the 'local_topic' and the rule. +""" + zh: """ +Ingress 模式定义了这个 bridge 如何从远程 MQTT broker 接收消息,然后将它们发送到本地 broker 。
+允许带有的模板变量: 'local_topic'、'remote_qos'、'qos'、'retain'、'payload' 。
+注意:如果这个 bridge 被用作规则的输入(emqx 规则引擎),并且还配置了 local_topic,那么从远程 broker 获取的消息将同时被发送到 'local_topic' 和规则引擎。 +""" + } + label: { + en: "Ingress Config" + zh: "Ingress 模式配置" + } + } + + desc_egress { + desc { + en: """ +The egress config defines how this bridge forwards messages from the local broker to the remote broker.
+Template with variables is allowed in 'remote_topic', 'qos', 'retain', 'payload'.
+NOTE: if this bridge is used as the output of a rule (emqx rule engine), and also local_topic is configured, then both the data got from the rule and the MQTT messages that matches local_topic will be forwarded. +""" + zh: """ +Egress 模式定义了 bridge 如何将消息从本地 broker 转发到远程 broker。
+允许带有的模板变量: 'remote_topic'、'qos'、'retain'、'payload' 。
+注意:如果这个 bridge 作为规则(emqx 规则引擎)的输出,并且还配置了 local_topic,那么从规则引擎中获取的数据和匹配 local_topic 的 MQTT 消息都会被转发到远程 broker 。 +""" + } + label: { + en: "Egress Config" + zh: "Egress 模式配置" + } + } + + desc_replayq { + desc { + en: """Queue messages in disk files.""" + zh: """本地磁盘消息队列""" + } + label: { + en: "Replayq" + zh: "本地磁盘消息队列" + } + } + + + } diff --git a/apps/emqx_connector/i18n/emqx_connector_schema.conf b/apps/emqx_connector/i18n/emqx_connector_schema.conf index dd3e6db37..0a94f5e88 100644 --- a/apps/emqx_connector/i18n/emqx_connector_schema.conf +++ b/apps/emqx_connector/i18n/emqx_connector_schema.conf @@ -11,4 +11,21 @@ emqx_connector_schema { } } + desc_connector { + desc { + en: """ +Configuration for EMQX connectors.
+A connector maintains the data related to the external resources, such as MySQL database. +""" + zh: """ +EMQX 连接器的配置。
+连接器维护与外部资源相关的数据,比如 MySQL 数据库。 +""" + } + label: { + en: "Connector" + zh: "连接器" + } + } + } diff --git a/apps/emqx_connector/src/emqx_connector_http.erl b/apps/emqx_connector/src/emqx_connector_http.erl index 641e70959..2dec73777 100644 --- a/apps/emqx_connector/src/emqx_connector_http.erl +++ b/apps/emqx_connector/src/emqx_connector_http.erl @@ -102,9 +102,7 @@ fields(config) -> })} , {request, hoconsc:mk( ref("request"), - #{ default => undefined - , required => false - , desc => ?DESC("request") + #{ desc => ?DESC("request") })} ] ++ emqx_connector_schema_lib:ssl_fields(); diff --git a/apps/emqx_connector/src/emqx_connector_ldap.erl b/apps/emqx_connector/src/emqx_connector_ldap.erl index 3e3bc36ff..918338ea1 100644 --- a/apps/emqx_connector/src/emqx_connector_ldap.erl +++ b/apps/emqx_connector/src/emqx_connector_ldap.erl @@ -144,6 +144,7 @@ ldap_fields() -> servers(type) -> list(); servers(validator) -> [?NOT_EMPTY("the value of the field 'servers' cannot be empty")]; servers(converter) -> fun to_servers_raw/1; +servers(required) -> true; servers(_) -> undefined. bind_dn(type) -> binary(); diff --git a/apps/emqx_connector/src/emqx_connector_mongo.erl b/apps/emqx_connector/src/emqx_connector_mongo.erl index 51da5d68e..d81aa04a4 100644 --- a/apps/emqx_connector/src/emqx_connector_mongo.erl +++ b/apps/emqx_connector/src/emqx_connector_mongo.erl @@ -94,13 +94,13 @@ fields(topology) -> ]. desc(single) -> - "Settings for a single MongoDB instance."; + ?DESC("desc_single"); desc(rs) -> - "Settings for replica set."; + ?DESC("desc_rs"); desc(sharded) -> - "Settings for sharded cluster."; + ?DESC("desc_sharded"); desc(topology) -> - "Topology of MongoDB."; + ?DESC("desc_topology"); desc(_) -> undefined. diff --git a/apps/emqx_connector/src/emqx_connector_redis.erl b/apps/emqx_connector/src/emqx_connector_redis.erl index 2fb7afad0..78607aac0 100644 --- a/apps/emqx_connector/src/emqx_connector_redis.erl +++ b/apps/emqx_connector/src/emqx_connector_redis.erl @@ -56,7 +56,6 @@ roots() -> fields(single) -> [ {server, fun server/1} , {redis_type, #{type => hoconsc:enum([single]), - default => single, required => true, desc => ?DESC("single") }} @@ -66,7 +65,6 @@ fields(single) -> fields(cluster) -> [ {servers, fun servers/1} , {redis_type, #{type => hoconsc:enum([cluster]), - default => cluster, required => true, desc => ?DESC("cluster") }} @@ -76,7 +74,6 @@ fields(cluster) -> fields(sentinel) -> [ {servers, fun servers/1} , {redis_type, #{type => hoconsc:enum([sentinel]), - default => sentinel, required => true, desc => ?DESC("sentinel") }} diff --git a/apps/emqx_connector/src/emqx_connector_schema.erl b/apps/emqx_connector/src/emqx_connector_schema.erl index 25f846e45..5b0309e00 100644 --- a/apps/emqx_connector/src/emqx_connector_schema.erl +++ b/apps/emqx_connector/src/emqx_connector_schema.erl @@ -64,10 +64,7 @@ fields("connectors") -> ]. desc(Record) when Record =:= connectors; - Record =:= "connectors" -> - "Configuration for EMQX connectors.
" - "A connector maintains the data related to the external resources,\n" - "such as MySQL database."; + Record =:= "connectors" -> ?DESC("desc_connector"); desc(_) -> undefined. diff --git a/apps/emqx_connector/src/mqtt/emqx_connector_mqtt_schema.erl b/apps/emqx_connector/src/mqtt/emqx_connector_mqtt_schema.erl index 2e512f14e..fb749505a 100644 --- a/apps/emqx_connector/src/mqtt/emqx_connector_mqtt_schema.erl +++ b/apps/emqx_connector/src/mqtt/emqx_connector_mqtt_schema.erl @@ -49,7 +49,7 @@ fields("connector") -> })} , {server, sc(emqx_schema:ip_port(), - #{ default => "127.0.0.1:1883" + #{ required => true , desc => ?DESC("server") })} , {reconnect_interval, mk_duration( @@ -117,7 +117,20 @@ fields("ingress") -> sc(binary(), #{ desc => ?DESC("ingress_hookpoint") })} - ] ++ common_inout_confs(); + + , {retain, + sc(hoconsc:union([boolean(), binary()]), + #{ default => <<"${retain}">> + , desc => ?DESC("retain") + })} + + , {payload, + sc(binary(), + #{ default => <<"${payload}">> + , desc => ?DESC("payload") + })} + ]; + fields("egress") -> %% the message maybe sent from rules, in this case 'local_topic' is not necessary @@ -128,16 +141,28 @@ fields("egress") -> })} , {remote_topic, sc(binary(), - #{ default => <<"${topic}">> + #{ required => true , validator => fun ?MODULE:non_empty_string/1 , desc => ?DESC("egress_remote_topic") })} , {remote_qos, sc(qos(), - #{ default => <<"${qos}">> + #{ required => true , desc => ?DESC("egress_remote_qos") })} - ] ++ common_inout_confs(); + + , {retain, + sc(hoconsc:union([boolean(), binary()]), + #{ required => true + , desc => ?DESC("retain") + })} + + , {payload, + sc(binary(), + #{ required => true + , desc => ?DESC("payload") + })} + ]; fields("replayq") -> [ {dir, @@ -157,13 +182,13 @@ fields("replayq") -> ]. desc("connector") -> - "Generic configuration for the connector."; + ?DESC("desc_connector"); desc("ingress") -> ingress_desc(); desc("egress") -> egress_desc(); desc("replayq") -> - "Queue messages in disk files."; + ?DESC("desc_replayq"); desc(_) -> undefined. @@ -197,19 +222,6 @@ is configured, then both the data got from the rule and the MQTT messages that m local_topic will be forwarded. ". -common_inout_confs() -> - [ {retain, - sc(hoconsc:union([boolean(), binary()]), - #{ default => <<"${retain}">> - , desc => ?DESC("retain") - })} - , {payload, - sc(binary(), - #{ default => <<"${payload}">> - , desc => ?DESC("payload") - })} - ]. - qos() -> hoconsc:union([emqx_schema:qos(), binary()]). diff --git a/apps/emqx_rule_engine/i18n/emqx_rule_engine_schema.conf b/apps/emqx_rule_engine/i18n/emqx_rule_engine_schema.conf index a09912c71..297413c38 100644 --- a/apps/emqx_rule_engine/i18n/emqx_rule_engine_schema.conf +++ b/apps/emqx_rule_engine/i18n/emqx_rule_engine_schema.conf @@ -239,4 +239,102 @@ of the rule, then the string "undefined" is used. } } + desc_rule_engine { + desc { + en: """Configuration for the EMQX Rule Engine.""" + zh: """配置 EMQX 规则引擎。""" + } + label: { + en: "Rule Engine Configuration" + zh: "配置规则引擎" + } + } + + desc_rules { + desc { + en: """Configuration for a rule.""" + zh: """配置规则""" + } + label: { + en: "Rule Configuration" + zh: "配置规则" + } + } + + desc_builtin_output_republish { + desc { + en: """Configuration for a built-in output.""" + zh: """配置重新发布。""" + } + label: { + en: "Republish Configuration" + zh: "配置重新发布" + } + } + + desc_builtin_output_console { + desc { + en: """Configuration for a built-in output.""" + zh: """配置打印到控制台""" + } + label: { + en: "Output Console Configuration" + zh: "配置打印到控制台" + } + } + + desc_user_provided_function { + desc { + en: """Configuration for a built-in output.""" + zh: """配置用户函数""" + } + label: { + en: "User Provid Function Configuration" + zh: "配置用户函数" + } + } + + desc_republish_args { + desc { + en: """The arguments of the built-in 'republish' output.
One can use variables in the args.
+The variables are selected by the rule. For example, if the rule SQL is defined as following: + + SELECT clientid, qos, payload FROM "t/1" + +Then there are 3 variables available: clientid, qos and +payload. And if we've set the args to: + + { + topic = "t/${clientid}" + qos = "${qos}" + payload = "msg: ${payload}" + } + +When the rule is triggered by an MQTT message with payload = `hello`, qos = 1, +clientid = `Steve`, the rule will republish a new MQTT message to topic `t/Steve`, +payload = `msg: hello`, and `qos = 1`.""" + zh: """ +内置 'republish' 动作的参数。
+可以在参数中使用变量。
+变量是规则中选择的字段。 例如规则 SQL 定义如下: + + SELECT clientid, qos, payload FROM "t/1" + +然后有 3 个变量可用:clientidqospayload。 如果我们将参数设置为: + + { + topic = "t/${clientid}" + qos = "${qos}" + payload = "msg: ${payload}" + } + +当收到一条消息 payload = `hello`, qos = 1, clientid = `Steve` 时,将重新发布一条新的 MQTT 消息到主题 `t/Steve` +消息内容为 payload = `msg: hello`, and `qos = 1""" + } + label: { + en: "Republish Args" + zh: "重新发布参数" + } + } + } diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine_schema.erl b/apps/emqx_rule_engine/src/emqx_rule_engine_schema.erl index d0f557d50..005d78c7f 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_engine_schema.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_engine_schema.erl @@ -81,7 +81,8 @@ fields("builtin_output_console") -> fields("user_provided_function") -> [ {function, sc(binary(), #{ desc => ?DESC("user_provided_function_function") - , example => "module:function" + , required => true + , example => "module:function" })} , {args, sc(map(), #{ desc => ?DESC("user_provided_function_args") @@ -113,34 +114,17 @@ fields("republish_args") -> ]. desc("rule_engine") -> - "Configuration for the EMQX Rule Engine."; + ?DESC("desc_rule_engine"); desc("rules") -> - "Configuration for a rule."; + ?DESC("desc_rules"); desc("builtin_output_republish") -> - "Configuration for a built-in output."; + ?DESC("desc_builtin_output_republish"); desc("builtin_output_console") -> - "Configuration for a built-in output."; + ?DESC("desc_builtin_output_console"); desc("user_provided_function") -> - "Configuration for a built-in output."; + ?DESC("desc_user_provided_function"); desc("republish_args") -> - "The arguments of the built-in 'republish' output.
" - "One can use variables in the args.
\n" - "The variables are selected by the rule. For example, if the rule SQL is defined as following:\n" - "\n" - " SELECT clientid, qos, payload FROM \"t/1\"\n" - "\n" - "Then there are 3 variables available: clientid, qos and\n" - "payload. And if we've set the args to:\n" - "\n" - " {\n" - " topic = \"t/${clientid}\"\n" - " qos = \"${qos}\"\n" - " payload = \"msg: ${payload}\"\n" - " }\n" - "\n" - "When the rule is triggered by an MQTT message with payload = `hello`, qos = 1,\n" - "clientid = `Steve`, the rule will republish a new MQTT message to topic `t/Steve`,\n" - "payload = `msg: hello`, and `qos = 1`."; + ?DESC("desc_republish_args"); desc(_) -> undefined.