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 个变量可用:clientid
、qos
和 payload
。 如果我们将参数设置为:
+
+ {
+ 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.