emqx_bridge_iotdb.erl 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. %%--------------------------------------------------------------------
  2. %% Copyright (c) 2023 EMQ Technologies Co., Ltd. All Rights Reserved.
  3. %%--------------------------------------------------------------------
  4. -module(emqx_bridge_iotdb).
  5. -include("emqx_bridge_iotdb.hrl").
  6. -include_lib("typerefl/include/types.hrl").
  7. -include_lib("hocon/include/hoconsc.hrl").
  8. -include_lib("emqx_resource/include/emqx_resource.hrl").
  9. -import(hoconsc, [mk/2, enum/1, ref/2]).
  10. %% hocon_schema API
  11. -export([
  12. namespace/0,
  13. roots/0,
  14. fields/1,
  15. desc/1
  16. ]).
  17. %% emqx_ee_bridge "unofficial" API
  18. -export([conn_bridge_examples/1]).
  19. %%-------------------------------------------------------------------------------------------------
  20. %% `hocon_schema' API
  21. %%-------------------------------------------------------------------------------------------------
  22. namespace() -> "bridge_iotdb".
  23. roots() -> [].
  24. fields("config") ->
  25. basic_config() ++ request_config();
  26. fields("post") ->
  27. [
  28. type_field(),
  29. name_field()
  30. ] ++ fields("config");
  31. fields("put") ->
  32. fields("config");
  33. fields("get") ->
  34. emqx_bridge_schema:status_fields() ++ fields("post");
  35. fields("creation_opts") ->
  36. lists:filter(
  37. fun({K, _V}) ->
  38. not lists:member(K, unsupported_opts())
  39. end,
  40. emqx_resource_schema:fields("creation_opts")
  41. );
  42. fields(auth_basic) ->
  43. [
  44. {username, mk(binary(), #{required => true, desc => ?DESC("config_auth_basic_username")})},
  45. {password,
  46. mk(binary(), #{
  47. required => true,
  48. desc => ?DESC("config_auth_basic_password"),
  49. format => <<"password">>,
  50. sensitive => true,
  51. converter => fun emqx_schema:password_converter/2
  52. })}
  53. ].
  54. desc("config") ->
  55. ?DESC("desc_config");
  56. desc("creation_opts") ->
  57. ?DESC(emqx_resource_schema, "creation_opts");
  58. desc("post") ->
  59. ["Configuration for IoTDB using `POST` method."];
  60. desc(Name) ->
  61. lists:member(Name, struct_names()) orelse throw({missing_desc, Name}),
  62. ?DESC(Name).
  63. struct_names() ->
  64. [
  65. auth_basic
  66. ].
  67. basic_config() ->
  68. [
  69. {enable,
  70. mk(
  71. boolean(),
  72. #{
  73. desc => ?DESC("config_enable"),
  74. default => true
  75. }
  76. )},
  77. {authentication,
  78. mk(
  79. hoconsc:union([ref(?MODULE, auth_basic)]),
  80. #{
  81. default => auth_basic, desc => ?DESC("config_authentication")
  82. }
  83. )},
  84. {is_aligned,
  85. mk(
  86. boolean(),
  87. #{
  88. desc => ?DESC("config_is_aligned"),
  89. default => false
  90. }
  91. )},
  92. {device_id,
  93. mk(
  94. binary(),
  95. #{
  96. desc => ?DESC("config_device_id")
  97. }
  98. )},
  99. {iotdb_version,
  100. mk(
  101. hoconsc:enum([?VSN_1_1_X, ?VSN_1_0_X, ?VSN_0_13_X]),
  102. #{
  103. desc => ?DESC("config_iotdb_version"),
  104. default => ?VSN_1_1_X
  105. }
  106. )}
  107. ] ++ resource_creation_opts() ++
  108. proplists_without(
  109. [max_retries, base_url, request],
  110. emqx_connector_http:fields(config)
  111. ).
  112. proplists_without(Keys, List) ->
  113. [El || El = {K, _} <- List, not lists:member(K, Keys)].
  114. request_config() ->
  115. [
  116. {base_url,
  117. mk(
  118. emqx_schema:url(),
  119. #{
  120. required => true,
  121. desc => ?DESC("config_base_url")
  122. }
  123. )},
  124. {max_retries,
  125. mk(
  126. non_neg_integer(),
  127. #{
  128. default => 2,
  129. desc => ?DESC("config_max_retries")
  130. }
  131. )}
  132. ].
  133. resource_creation_opts() ->
  134. [
  135. {resource_opts,
  136. mk(
  137. ref(?MODULE, "creation_opts"),
  138. #{
  139. required => false,
  140. default => #{},
  141. desc => ?DESC(emqx_resource_schema, <<"resource_opts">>)
  142. }
  143. )}
  144. ].
  145. unsupported_opts() ->
  146. [
  147. batch_size,
  148. batch_time
  149. ].
  150. %%======================================================================================
  151. type_field() ->
  152. {type,
  153. mk(
  154. hoconsc:enum([iotdb]),
  155. #{
  156. required => true,
  157. desc => ?DESC("desc_type")
  158. }
  159. )}.
  160. name_field() ->
  161. {name,
  162. mk(
  163. binary(),
  164. #{
  165. required => true,
  166. desc => ?DESC("desc_name")
  167. }
  168. )}.
  169. %%======================================================================================
  170. conn_bridge_examples(Method) ->
  171. [
  172. #{
  173. <<"iotdb">> =>
  174. #{
  175. summary => <<"Apache IoTDB Bridge">>,
  176. value => conn_bridge_example(Method, iotdb)
  177. }
  178. }
  179. ].
  180. conn_bridge_example(_Method, Type) ->
  181. #{
  182. name => <<"My IoTDB Bridge">>,
  183. type => Type,
  184. enable => true,
  185. authentication => #{
  186. <<"username">> => <<"root">>,
  187. <<"password">> => <<"*****">>
  188. },
  189. is_aligned => false,
  190. device_id => <<"my_device">>,
  191. base_url => <<"http://iotdb.local:18080/">>,
  192. iotdb_version => ?VSN_1_1_X,
  193. connect_timeout => <<"15s">>,
  194. pool_type => <<"random">>,
  195. pool_size => 8,
  196. enable_pipelining => 100,
  197. ssl => #{enable => false},
  198. resource_opts => #{
  199. worker_pool_size => 8,
  200. health_check_interval => ?HEALTHCHECK_INTERVAL_RAW,
  201. query_mode => async,
  202. max_buffer_bytes => ?DEFAULT_BUFFER_BYTES
  203. }
  204. }.