diff --git a/.ci/docker-compose-file/docker-compose-greptimedb.yaml b/.ci/docker-compose-file/docker-compose-greptimedb.yaml new file mode 100644 index 000000000..f379969bd --- /dev/null +++ b/.ci/docker-compose-file/docker-compose-greptimedb.yaml @@ -0,0 +1,15 @@ +version: '3.9' + +services: + greptimedb: + container_name: greptimedb + image: greptime/greptimedb:0.3.2 + expose: + - "4000" + - "4001" + restart: always + networks: + - emqx_bridge + command: + standalone start + --user-provider=static_user_provider:cmd:greptime_user=greptime_pwd diff --git a/.ci/docker-compose-file/docker-compose-toxiproxy.yaml b/.ci/docker-compose-file/docker-compose-toxiproxy.yaml index 74d2583c9..d648d9d78 100644 --- a/.ci/docker-compose-file/docker-compose-toxiproxy.yaml +++ b/.ci/docker-compose-file/docker-compose-toxiproxy.yaml @@ -51,6 +51,9 @@ services: - 15670:5670 # Kinesis - 4566:4566 + # GreptimeDB + - 4000:4000 + - 4001:4001 command: - "-host=0.0.0.0" - "-config=/config/toxiproxy.json" diff --git a/.ci/docker-compose-file/toxiproxy.json b/.ci/docker-compose-file/toxiproxy.json index c9590354b..a8e2f086c 100644 --- a/.ci/docker-compose-file/toxiproxy.json +++ b/.ci/docker-compose-file/toxiproxy.json @@ -160,6 +160,17 @@ "name": "hstreamdb", "listen": "0.0.0.0:6570", "upstream": "hstreamdb:6570", + }, + { + "name": "greptimedb_http", + "listen": "0.0.0.0:4000", + "upstream": "iotdb:4000", + "enabled": true + }, + { + "name": "greptimedb_grpc", + "listen": "0.0.0.0:4001", + "upstream": "iotdb:4001", "enabled": true }, { diff --git a/apps/emqx_bridge/src/schema/emqx_bridge_enterprise.erl b/apps/emqx_bridge/src/schema/emqx_bridge_enterprise.erl index 048dcbf90..4a0428675 100644 --- a/apps/emqx_bridge/src/schema/emqx_bridge_enterprise.erl +++ b/apps/emqx_bridge/src/schema/emqx_bridge_enterprise.erl @@ -200,14 +200,6 @@ fields(bridges) -> desc => <<"Apache IoTDB Bridge Config">>, required => false } - )}, - {greptimedb, - mk( - hoconsc:map(name, ref(emqx_bridge_greptimedb, "config")), - #{ - desc => <<"GreptimeDB Bridge Config">>, - required => false - } )} ] ++ kafka_structs() ++ pulsar_structs() ++ gcp_pubsub_structs() ++ mongodb_structs() ++ influxdb_structs() ++ diff --git a/apps/emqx_bridge_greptimedb/src/emqx_bridge_greptimedb.erl b/apps/emqx_bridge_greptimedb/src/emqx_bridge_greptimedb.erl index 5bd8f6852..415544fcf 100644 --- a/apps/emqx_bridge_greptimedb/src/emqx_bridge_greptimedb.erl +++ b/apps/emqx_bridge_greptimedb/src/emqx_bridge_greptimedb.erl @@ -107,6 +107,7 @@ method_fields(put, ConnectorType) -> greptimedb_bridge_common_fields() -> emqx_bridge_schema:common_bridge_fields() ++ [ + {local_topic, mk(binary(), #{desc => ?DESC("local_topic")})}, {write_syntax, fun write_syntax/1} ] ++ emqx_resource_schema:fields("resource_opts"). diff --git a/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl b/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl index e694060f5..57ffed926 100644 --- a/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl +++ b/apps/emqx_bridge_greptimedb/test/emqx_bridge_greptimedb_SUITE.erl @@ -30,11 +30,12 @@ groups() -> {group, sync_query} ]}, {sync_query, [ - {group, grpcv1_tcp}, - {group, grpcv1_tls} + {group, grpcv1_tcp} + %% uncomment tls when we are ready + %% {group, grpcv1_tls} ]}, - {grpcv1_tcp, TCs}, - {grpcv1_tls, TCs} + {grpcv1_tcp, TCs} + %%{grpcv1_tls, TCs} ]. init_per_suite(Config) -> diff --git a/rel/i18n/emqx_bridge_greptimedb.hocon b/rel/i18n/emqx_bridge_greptimedb.hocon new file mode 100644 index 000000000..939ed48d3 --- /dev/null +++ b/rel/i18n/emqx_bridge_greptimedb.hocon @@ -0,0 +1,50 @@ +emqx_bridge_greptimedb { + +config_enable.desc: +"""Enable or disable this bridge.""" + +config_enable.label: +"""Enable Or Disable Bridge""" + +desc_config.desc: +"""Configuration for an GreptimeDB bridge.""" + +desc_config.label: +"""GreptimeDB Bridge Configuration""" + +desc_name.desc: +"""Bridge name.""" + +desc_name.label: +"""Bridge Name""" + +desc_type.desc: +"""The Bridge Type.""" + +desc_type.label: +"""Bridge Type""" + +local_topic.desc: +"""The MQTT topic filter to be forwarded to the GreptimeDB. All MQTT 'PUBLISH' messages with the topic +matching the local_topic will be forwarded.
+NOTE: if this bridge is used as the action 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 match local_topic +will be forwarded.""" + +local_topic.label: +"""Local Topic""" + +write_syntax.desc: +"""Conf of GreptimeDB gRPC protocol to write data points.The write syntax is a text-based format that provides the measurement, tag set, field set, and timestamp of a data point, and placeholder supported, which is the same as InfluxDB line protocol. +See also [InfluxDB 2.3 Line Protocol](https://docs.influxdata.com/influxdb/v2.3/reference/syntax/line-protocol/) and +[GreptimeDB 1.8 Line Protocol](https://docs.influxdata.com/influxdb/v1.8/write_protocols/line_protocol_tutorial/)
+TLDR:
+``` +[,=[,=]] =[,=] [] +``` +Please note that a placeholder for an integer value must be annotated with a suffix `i`. For example `${payload.int_value}i`.""" + +write_syntax.label: +"""Write Syntax""" + +} diff --git a/rel/i18n/emqx_bridge_greptimedb_connector.hocon b/rel/i18n/emqx_bridge_greptimedb_connector.hocon new file mode 100644 index 000000000..87370b211 --- /dev/null +++ b/rel/i18n/emqx_bridge_greptimedb_connector.hocon @@ -0,0 +1,47 @@ +emqx_bridge_greptimedb_connector { + +dbname.desc: +"""GreptimeDB database.""" + +dbname.label: +"""Database""" + +greptimedb_grpc_v1.desc: +"""GreptimeDB's protocol. Support GreptimeDB v1.8 and before.""" + +greptimedb_grpc_v1.label: +"""HTTP API Protocol""" + +password.desc: +"""GreptimeDB password.""" + +password.label: +"""Password""" + +precision.desc: +"""GreptimeDB time precision.""" + +precision.label: +"""Time Precision""" + +protocol.desc: +"""GreptimeDB's protocol. gRPC API.""" + +protocol.label: +"""Protocol""" + +server.desc: +"""The IPv4 or IPv6 address or the hostname to connect to.
+A host entry has the following form: `Host[:Port]`.
+The GreptimeDB default port 8086 is used if `[:Port]` is not specified.""" + +server.label: +"""Server Host""" + +username.desc: +"""GreptimeDB username.""" + +username.label: +"""Username""" + +} diff --git a/scripts/ct/run.sh b/scripts/ct/run.sh index 785d4065d..578b9c4de 100755 --- a/scripts/ct/run.sh +++ b/scripts/ct/run.sh @@ -222,6 +222,9 @@ for dep in ${CT_DEPS}; do kinesis) FILES+=( '.ci/docker-compose-file/docker-compose-kinesis.yaml' ) ;; + greptimedb) + FILES+=( '.ci/docker-compose-file/docker-compose-greptimedb.yaml' ) + ;; *) echo "unknown_ct_dependency $dep" exit 1