emqx_plugin_kafka_schema.erl 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. -module(emqx_plugin_kafka_schema).
  2. -include_lib("hocon/include/hoconsc.hrl").
  3. -export([
  4. roots/0
  5. , fields/1
  6. , desc/1
  7. ]).
  8. -import(hoconsc, [enum/1]).
  9. roots() -> [plugin_kafka].
  10. fields(plugin_kafka) ->
  11. [
  12. {connection, ?HOCON(?R_REF(connection), #{desc => ?DESC("connect_timeout")})},
  13. {producer, ?HOCON(?R_REF(producer), #{desc => ?DESC("connect_timeout")})},
  14. {hooks, ?HOCON(?ARRAY(?R_REF(hook)),
  15. #{
  16. required => true,
  17. default => [],
  18. desc => ?DESC("hooks")
  19. })}
  20. ];
  21. fields(connection) ->
  22. [
  23. {client_id, ?HOCON(string(),
  24. #{
  25. desc => ?DESC("client_id"),
  26. default => "client"
  27. })},
  28. {bootstrap_hosts, bootstrap_hosts()},
  29. {connect_timeout, ?HOCON(emqx_schema:timeout_duration_ms(),
  30. #{
  31. default => <<"5s">>,
  32. desc => ?DESC("connect_timeout")
  33. })},
  34. {client_id, ?HOCON(string(),
  35. #{
  36. default => <<"emqx_plugin_kafka_connection">>,
  37. desc => ?DESC("client_id")
  38. })},
  39. {connection_strategy, ?HOCON(enum([per_partition, per_broker]),
  40. #{
  41. default => per_partition,
  42. desc => ?DESC("connection_strategy")
  43. }
  44. )},
  45. {min_metadata_refresh_interval, ?HOCON(emqx_schema:timeout_duration_ms(),
  46. #{
  47. default => <<"5s">>,
  48. desc => ?DESC("min_metadata_refresh_interval")
  49. }
  50. )},
  51. {query_api_versions, ?HOCON(boolean(),
  52. #{
  53. default => true,
  54. desc => ?DESC("query_api_versions")
  55. })},
  56. {request_timeout, ?HOCON(emqx_schema:timeout_duration_ms(),
  57. #{
  58. default => <<"3s">>,
  59. desc => ?DESC("request_timeout")
  60. }
  61. )},
  62. {sasl, ?HOCON(?R_REF(sasl),
  63. #{
  64. desc => ?DESC("sasl")
  65. }
  66. )},
  67. {ssl, ?HOCON(?R_REF(ssl),
  68. #{
  69. desc => ?DESC("ssl")
  70. }
  71. )},
  72. {health_check_interval, ?HOCON(emqx_schema:timeout_duration_ms(),
  73. #{
  74. default => <<"32s">>,
  75. desc => ?DESC("health_check_interval")
  76. }
  77. )}
  78. ];
  79. fields(bootstrap_host) ->
  80. [
  81. {host, ?HOCON(string(),
  82. #{
  83. validator => emqx_schema:servers_validator(
  84. #{default_port => 9092}, _Required = true)
  85. }
  86. )}
  87. ];
  88. fields(sasl) ->
  89. [
  90. {mechanism, ?HOCON(enum([plain, scram_sha_256, scram_sha_512]),
  91. #{
  92. default => plain,
  93. desc => ?DESC("sasl_mechanism"),
  94. required => true
  95. }
  96. )},
  97. {username, ?HOCON(string(),
  98. #{
  99. desc => ?DESC("sasl_username"),
  100. required => true
  101. }
  102. )},
  103. {password, ?HOCON(string(),
  104. #{
  105. desc => ?DESC("sasl_password"),
  106. required => true
  107. }
  108. )}
  109. ];
  110. fields(ssl) ->
  111. Schema = emqx_schema:client_ssl_opts_schema(#{}),
  112. lists:keydelete("user_lookup_fun", 1, Schema);
  113. fields(producer) ->
  114. [
  115. {max_batch_bytes, ?HOCON(emqx_schema:bytesize(),
  116. #{
  117. default => "896KB",
  118. desc => ?DESC("max_batch_bytes")
  119. }
  120. )},
  121. {compression, ?HOCON(enum([no_compression, snappy, gzip]),
  122. #{
  123. default => no_compression,
  124. desc => ?DESC("compression")
  125. }
  126. )},
  127. {partition_strategy, ?HOCON(enum([random, roundrobin, first_key_dispatch]),
  128. #{
  129. default => random,
  130. desc => ?DESC("partition_strategy")
  131. }
  132. )},
  133. {encode_payload_type, ?HOCON(enum([plain, base64]),
  134. #{
  135. default => plain,
  136. desc => ?DESC("encode_payload_type")
  137. }
  138. )}
  139. ];
  140. fields(hook) ->
  141. [
  142. {endpoint, ?HOCON(string(),
  143. #{
  144. desc => ?DESC("hook_endpoint"),
  145. required => true,
  146. validator => fun validate_endpoint/1
  147. })},
  148. {filter, ?HOCON(binary(),
  149. #{
  150. desc => ?DESC("hook_filter"),
  151. default => <<"#">>
  152. })},
  153. {kafka_topic, ?HOCON(string(),
  154. #{
  155. desc => ?DESC("hook_kafka_topic"),
  156. default => "emqx_test"
  157. })},
  158. {kafka_message, ?HOCON(?R_REF(kafka_message),
  159. #{
  160. desc => ?DESC("hook_kafka_message")
  161. })}
  162. ];
  163. fields(kafka_message) ->
  164. [
  165. {key, ?HOCON(string(),
  166. #{
  167. default => <<"${.clientid}">>,
  168. desc => ?DESC(kafka_message_key)
  169. })},
  170. {value, ?HOCON(string(),
  171. #{
  172. default => <<"${.}">>,
  173. desc => ?DESC(kafka_message_value)
  174. })},
  175. {timestamp, ?HOCON(string(),
  176. #{
  177. default => <<"${.timestamp}">>,
  178. desc => ?DESC(kafka_message_timestamp)
  179. })}
  180. ].
  181. desc(_) -> undefined.
  182. bootstrap_hosts() ->
  183. Meta = #{desc => ?DESC("bootstrap_hosts")},
  184. emqx_schema:servers_sc(Meta, #{default_port => 9092}).
  185. validate_endpoint(undefined) ->
  186. {error, "no matching mount point was found"};
  187. validate_endpoint(Endpoint0) when is_list(Endpoint0) ->
  188. case emqx_utils:safe_to_existing_atom(Endpoint0) of
  189. {ok, Endpoint} ->
  190. validate_endpoint(emqx_plugin_kafka_hook:endpoint_func(Endpoint));
  191. _ ->
  192. {error, "no matching mount point was found"}
  193. end;
  194. validate_endpoint(_) ->
  195. ok.