@ohos-ports/confluentinc-kafka-javascript 1.10.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (628) hide show
  1. package/CHANGELOG.md +457 -0
  2. package/LICENSE.kafkajs +31 -0
  3. package/LICENSE.node-rdkafka +25 -0
  4. package/LICENSE.txt +20 -0
  5. package/README.md +133 -0
  6. package/binding.gyp +184 -0
  7. package/build/Release/confluent-kafka-javascript.node +0 -0
  8. package/build/deps/librdkafka++.so.1 +0 -0
  9. package/build/deps/librdkafka.Makefile +6 -0
  10. package/build/deps/librdkafka.so.1 +0 -0
  11. package/build/deps/librdkafka.target.mk +55 -0
  12. package/deps/librdkafka/.clang-format +136 -0
  13. package/deps/librdkafka/.clang-format-cpp +103 -0
  14. package/deps/librdkafka/.dir-locals.el +10 -0
  15. package/deps/librdkafka/.formatignore +35 -0
  16. package/deps/librdkafka/.gdbmacros +19 -0
  17. package/deps/librdkafka/CHANGELOG.md +2477 -0
  18. package/deps/librdkafka/CMakeLists.txt +291 -0
  19. package/deps/librdkafka/CODE_OF_CONDUCT.md +46 -0
  20. package/deps/librdkafka/CONFIGURATION.md +212 -0
  21. package/deps/librdkafka/CONTRIBUTING.md +431 -0
  22. package/deps/librdkafka/Doxyfile +2375 -0
  23. package/deps/librdkafka/INTRODUCTION.md +2752 -0
  24. package/deps/librdkafka/LICENSE +26 -0
  25. package/deps/librdkafka/LICENSE.cjson +22 -0
  26. package/deps/librdkafka/LICENSE.crc32c +28 -0
  27. package/deps/librdkafka/LICENSE.fnv1a +18 -0
  28. package/deps/librdkafka/LICENSE.hdrhistogram +27 -0
  29. package/deps/librdkafka/LICENSE.lz4 +26 -0
  30. package/deps/librdkafka/LICENSE.murmur2 +25 -0
  31. package/deps/librdkafka/LICENSE.nanopb +22 -0
  32. package/deps/librdkafka/LICENSE.opentelemetry +203 -0
  33. package/deps/librdkafka/LICENSE.pycrc +23 -0
  34. package/deps/librdkafka/LICENSE.queue +31 -0
  35. package/deps/librdkafka/LICENSE.regexp +5 -0
  36. package/deps/librdkafka/LICENSE.snappy +36 -0
  37. package/deps/librdkafka/LICENSE.tinycthread +26 -0
  38. package/deps/librdkafka/LICENSE.wingetopt +49 -0
  39. package/deps/librdkafka/LICENSES.txt +625 -0
  40. package/deps/librdkafka/Makefile +125 -0
  41. package/deps/librdkafka/README.md +201 -0
  42. package/deps/librdkafka/README.win32 +26 -0
  43. package/deps/librdkafka/STATISTICS.md +624 -0
  44. package/deps/librdkafka/configure +214 -0
  45. package/deps/librdkafka/configure.self +341 -0
  46. package/deps/librdkafka/dev-conf.sh +123 -0
  47. package/deps/librdkafka/lds-gen.py +73 -0
  48. package/deps/librdkafka/mainpage.doxy +40 -0
  49. package/deps/librdkafka/mklove/Makefile.base +329 -0
  50. package/deps/librdkafka/mklove/modules/configure.atomics +144 -0
  51. package/deps/librdkafka/mklove/modules/configure.base +2484 -0
  52. package/deps/librdkafka/mklove/modules/configure.builtin +70 -0
  53. package/deps/librdkafka/mklove/modules/configure.cc +186 -0
  54. package/deps/librdkafka/mklove/modules/configure.cxx +8 -0
  55. package/deps/librdkafka/mklove/modules/configure.fileversion +65 -0
  56. package/deps/librdkafka/mklove/modules/configure.gitversion +29 -0
  57. package/deps/librdkafka/mklove/modules/configure.good_cflags +18 -0
  58. package/deps/librdkafka/mklove/modules/configure.host +132 -0
  59. package/deps/librdkafka/mklove/modules/configure.lib +49 -0
  60. package/deps/librdkafka/mklove/modules/configure.libcurl +99 -0
  61. package/deps/librdkafka/mklove/modules/configure.libsasl2 +36 -0
  62. package/deps/librdkafka/mklove/modules/configure.libssl +147 -0
  63. package/deps/librdkafka/mklove/modules/configure.libzstd +58 -0
  64. package/deps/librdkafka/mklove/modules/configure.parseversion +95 -0
  65. package/deps/librdkafka/mklove/modules/configure.pic +16 -0
  66. package/deps/librdkafka/mklove/modules/configure.socket +20 -0
  67. package/deps/librdkafka/mklove/modules/configure.zlib +61 -0
  68. package/deps/librdkafka/mklove/modules/patches/README.md +8 -0
  69. package/deps/librdkafka/mklove/modules/patches/libcurl.0000-no-runtime-linking-check.patch +11 -0
  70. package/deps/librdkafka/mklove/modules/patches/libssl.0000-osx-rand-include-fix-OpenSSL-PR16409.patch +56 -0
  71. package/deps/librdkafka/service.yml +182 -0
  72. package/deps/librdkafka/src/CMakeLists.txt +379 -0
  73. package/deps/librdkafka/src/Makefile +105 -0
  74. package/deps/librdkafka/src/README.lz4.md +30 -0
  75. package/deps/librdkafka/src/cJSON.c +3191 -0
  76. package/deps/librdkafka/src/cJSON.h +306 -0
  77. package/deps/librdkafka/src/crc32c.c +430 -0
  78. package/deps/librdkafka/src/crc32c.h +38 -0
  79. package/deps/librdkafka/src/generate_proto.sh +66 -0
  80. package/deps/librdkafka/src/librdkafka_cgrp_synch.png +0 -0
  81. package/deps/librdkafka/src/lz4.c +2727 -0
  82. package/deps/librdkafka/src/lz4.h +842 -0
  83. package/deps/librdkafka/src/lz4frame.c +2078 -0
  84. package/deps/librdkafka/src/lz4frame.h +692 -0
  85. package/deps/librdkafka/src/lz4frame_static.h +47 -0
  86. package/deps/librdkafka/src/lz4hc.c +1631 -0
  87. package/deps/librdkafka/src/lz4hc.h +413 -0
  88. package/deps/librdkafka/src/nanopb/pb.h +917 -0
  89. package/deps/librdkafka/src/nanopb/pb_common.c +388 -0
  90. package/deps/librdkafka/src/nanopb/pb_common.h +49 -0
  91. package/deps/librdkafka/src/nanopb/pb_decode.c +1727 -0
  92. package/deps/librdkafka/src/nanopb/pb_decode.h +193 -0
  93. package/deps/librdkafka/src/nanopb/pb_encode.c +1000 -0
  94. package/deps/librdkafka/src/nanopb/pb_encode.h +185 -0
  95. package/deps/librdkafka/src/opentelemetry/common.pb.c +32 -0
  96. package/deps/librdkafka/src/opentelemetry/common.pb.h +170 -0
  97. package/deps/librdkafka/src/opentelemetry/metrics.options +2 -0
  98. package/deps/librdkafka/src/opentelemetry/metrics.pb.c +67 -0
  99. package/deps/librdkafka/src/opentelemetry/metrics.pb.h +966 -0
  100. package/deps/librdkafka/src/opentelemetry/resource.pb.c +12 -0
  101. package/deps/librdkafka/src/opentelemetry/resource.pb.h +58 -0
  102. package/deps/librdkafka/src/queue.h +850 -0
  103. package/deps/librdkafka/src/rd.h +592 -0
  104. package/deps/librdkafka/src/rdaddr.c +255 -0
  105. package/deps/librdkafka/src/rdaddr.h +202 -0
  106. package/deps/librdkafka/src/rdatomic.h +262 -0
  107. package/deps/librdkafka/src/rdavg.h +260 -0
  108. package/deps/librdkafka/src/rdavl.c +210 -0
  109. package/deps/librdkafka/src/rdavl.h +250 -0
  110. package/deps/librdkafka/src/rdbase64.c +200 -0
  111. package/deps/librdkafka/src/rdbase64.h +43 -0
  112. package/deps/librdkafka/src/rdbuf.c +1884 -0
  113. package/deps/librdkafka/src/rdbuf.h +375 -0
  114. package/deps/librdkafka/src/rdcrc32.c +114 -0
  115. package/deps/librdkafka/src/rdcrc32.h +170 -0
  116. package/deps/librdkafka/src/rddl.c +179 -0
  117. package/deps/librdkafka/src/rddl.h +43 -0
  118. package/deps/librdkafka/src/rdendian.h +175 -0
  119. package/deps/librdkafka/src/rdfloat.h +67 -0
  120. package/deps/librdkafka/src/rdfnv1a.c +113 -0
  121. package/deps/librdkafka/src/rdfnv1a.h +35 -0
  122. package/deps/librdkafka/src/rdgz.c +120 -0
  123. package/deps/librdkafka/src/rdgz.h +46 -0
  124. package/deps/librdkafka/src/rdhdrhistogram.c +721 -0
  125. package/deps/librdkafka/src/rdhdrhistogram.h +87 -0
  126. package/deps/librdkafka/src/rdhttp.c +831 -0
  127. package/deps/librdkafka/src/rdhttp.h +101 -0
  128. package/deps/librdkafka/src/rdinterval.h +177 -0
  129. package/deps/librdkafka/src/rdkafka.c +7287 -0
  130. package/deps/librdkafka/src/rdkafka.h +11795 -0
  131. package/deps/librdkafka/src/rdkafka_admin.c +10165 -0
  132. package/deps/librdkafka/src/rdkafka_admin.h +658 -0
  133. package/deps/librdkafka/src/rdkafka_assignment.c +1282 -0
  134. package/deps/librdkafka/src/rdkafka_assignment.h +73 -0
  135. package/deps/librdkafka/src/rdkafka_assignor.c +1800 -0
  136. package/deps/librdkafka/src/rdkafka_assignor.h +402 -0
  137. package/deps/librdkafka/src/rdkafka_aux.c +409 -0
  138. package/deps/librdkafka/src/rdkafka_aux.h +174 -0
  139. package/deps/librdkafka/src/rdkafka_background.c +222 -0
  140. package/deps/librdkafka/src/rdkafka_broker.c +6736 -0
  141. package/deps/librdkafka/src/rdkafka_broker.h +851 -0
  142. package/deps/librdkafka/src/rdkafka_buf.c +543 -0
  143. package/deps/librdkafka/src/rdkafka_buf.h +1525 -0
  144. package/deps/librdkafka/src/rdkafka_cert.c +576 -0
  145. package/deps/librdkafka/src/rdkafka_cert.h +62 -0
  146. package/deps/librdkafka/src/rdkafka_cgrp.c +8310 -0
  147. package/deps/librdkafka/src/rdkafka_cgrp.h +589 -0
  148. package/deps/librdkafka/src/rdkafka_conf.c +5177 -0
  149. package/deps/librdkafka/src/rdkafka_conf.h +746 -0
  150. package/deps/librdkafka/src/rdkafka_confval.h +97 -0
  151. package/deps/librdkafka/src/rdkafka_coord.c +623 -0
  152. package/deps/librdkafka/src/rdkafka_coord.h +132 -0
  153. package/deps/librdkafka/src/rdkafka_error.c +228 -0
  154. package/deps/librdkafka/src/rdkafka_error.h +80 -0
  155. package/deps/librdkafka/src/rdkafka_event.c +502 -0
  156. package/deps/librdkafka/src/rdkafka_event.h +126 -0
  157. package/deps/librdkafka/src/rdkafka_feature.c +898 -0
  158. package/deps/librdkafka/src/rdkafka_feature.h +104 -0
  159. package/deps/librdkafka/src/rdkafka_fetcher.c +3820 -0
  160. package/deps/librdkafka/src/rdkafka_fetcher.h +62 -0
  161. package/deps/librdkafka/src/rdkafka_header.c +220 -0
  162. package/deps/librdkafka/src/rdkafka_header.h +76 -0
  163. package/deps/librdkafka/src/rdkafka_idempotence.c +807 -0
  164. package/deps/librdkafka/src/rdkafka_idempotence.h +144 -0
  165. package/deps/librdkafka/src/rdkafka_int.h +1505 -0
  166. package/deps/librdkafka/src/rdkafka_interceptor.c +842 -0
  167. package/deps/librdkafka/src/rdkafka_interceptor.h +104 -0
  168. package/deps/librdkafka/src/rdkafka_lz4.c +450 -0
  169. package/deps/librdkafka/src/rdkafka_lz4.h +49 -0
  170. package/deps/librdkafka/src/rdkafka_metadata.c +2347 -0
  171. package/deps/librdkafka/src/rdkafka_metadata.h +350 -0
  172. package/deps/librdkafka/src/rdkafka_metadata_cache.c +1183 -0
  173. package/deps/librdkafka/src/rdkafka_mock.c +4514 -0
  174. package/deps/librdkafka/src/rdkafka_mock.h +867 -0
  175. package/deps/librdkafka/src/rdkafka_mock_cgrp.c +1877 -0
  176. package/deps/librdkafka/src/rdkafka_mock_handlers.c +5255 -0
  177. package/deps/librdkafka/src/rdkafka_mock_int.h +1005 -0
  178. package/deps/librdkafka/src/rdkafka_mock_sharegrp.c +1207 -0
  179. package/deps/librdkafka/src/rdkafka_msg.c +2619 -0
  180. package/deps/librdkafka/src/rdkafka_msg.h +629 -0
  181. package/deps/librdkafka/src/rdkafka_msgbatch.h +62 -0
  182. package/deps/librdkafka/src/rdkafka_msgset.h +105 -0
  183. package/deps/librdkafka/src/rdkafka_msgset_reader.c +2099 -0
  184. package/deps/librdkafka/src/rdkafka_msgset_writer.c +1474 -0
  185. package/deps/librdkafka/src/rdkafka_offset.c +1565 -0
  186. package/deps/librdkafka/src/rdkafka_offset.h +150 -0
  187. package/deps/librdkafka/src/rdkafka_op.c +1219 -0
  188. package/deps/librdkafka/src/rdkafka_op.h +1065 -0
  189. package/deps/librdkafka/src/rdkafka_partition.c +5109 -0
  190. package/deps/librdkafka/src/rdkafka_partition.h +1215 -0
  191. package/deps/librdkafka/src/rdkafka_pattern.c +228 -0
  192. package/deps/librdkafka/src/rdkafka_pattern.h +70 -0
  193. package/deps/librdkafka/src/rdkafka_plugin.c +213 -0
  194. package/deps/librdkafka/src/rdkafka_plugin.h +41 -0
  195. package/deps/librdkafka/src/rdkafka_proto.h +739 -0
  196. package/deps/librdkafka/src/rdkafka_protocol.h +131 -0
  197. package/deps/librdkafka/src/rdkafka_queue.c +1351 -0
  198. package/deps/librdkafka/src/rdkafka_queue.h +1235 -0
  199. package/deps/librdkafka/src/rdkafka_range_assignor.c +1748 -0
  200. package/deps/librdkafka/src/rdkafka_request.c +7298 -0
  201. package/deps/librdkafka/src/rdkafka_request.h +761 -0
  202. package/deps/librdkafka/src/rdkafka_roundrobin_assignor.c +123 -0
  203. package/deps/librdkafka/src/rdkafka_sasl.c +589 -0
  204. package/deps/librdkafka/src/rdkafka_sasl.h +63 -0
  205. package/deps/librdkafka/src/rdkafka_sasl_cyrus.c +722 -0
  206. package/deps/librdkafka/src/rdkafka_sasl_int.h +89 -0
  207. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer.c +1833 -0
  208. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer.h +52 -0
  209. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.c +1827 -0
  210. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.h +52 -0
  211. package/deps/librdkafka/src/rdkafka_sasl_plain.c +142 -0
  212. package/deps/librdkafka/src/rdkafka_sasl_scram.c +858 -0
  213. package/deps/librdkafka/src/rdkafka_sasl_win32.c +550 -0
  214. package/deps/librdkafka/src/rdkafka_share_acknowledgement.c +1445 -0
  215. package/deps/librdkafka/src/rdkafka_share_acknowledgement.h +373 -0
  216. package/deps/librdkafka/src/rdkafka_ssl.c +2235 -0
  217. package/deps/librdkafka/src/rdkafka_ssl.h +86 -0
  218. package/deps/librdkafka/src/rdkafka_sticky_assignor.c +4785 -0
  219. package/deps/librdkafka/src/rdkafka_subscription.c +411 -0
  220. package/deps/librdkafka/src/rdkafka_telemetry.c +761 -0
  221. package/deps/librdkafka/src/rdkafka_telemetry.h +52 -0
  222. package/deps/librdkafka/src/rdkafka_telemetry_decode.c +1307 -0
  223. package/deps/librdkafka/src/rdkafka_telemetry_decode.h +59 -0
  224. package/deps/librdkafka/src/rdkafka_telemetry_encode.c +1309 -0
  225. package/deps/librdkafka/src/rdkafka_telemetry_encode.h +459 -0
  226. package/deps/librdkafka/src/rdkafka_timer.c +407 -0
  227. package/deps/librdkafka/src/rdkafka_timer.h +117 -0
  228. package/deps/librdkafka/src/rdkafka_topic.c +2382 -0
  229. package/deps/librdkafka/src/rdkafka_topic.h +369 -0
  230. package/deps/librdkafka/src/rdkafka_transport.c +1309 -0
  231. package/deps/librdkafka/src/rdkafka_transport.h +99 -0
  232. package/deps/librdkafka/src/rdkafka_transport_int.h +100 -0
  233. package/deps/librdkafka/src/rdkafka_txnmgr.c +3256 -0
  234. package/deps/librdkafka/src/rdkafka_txnmgr.h +171 -0
  235. package/deps/librdkafka/src/rdkafka_zstd.c +226 -0
  236. package/deps/librdkafka/src/rdkafka_zstd.h +57 -0
  237. package/deps/librdkafka/src/rdlist.c +593 -0
  238. package/deps/librdkafka/src/rdlist.h +444 -0
  239. package/deps/librdkafka/src/rdlog.c +89 -0
  240. package/deps/librdkafka/src/rdlog.h +41 -0
  241. package/deps/librdkafka/src/rdmap.c +508 -0
  242. package/deps/librdkafka/src/rdmap.h +492 -0
  243. package/deps/librdkafka/src/rdmurmur2.c +167 -0
  244. package/deps/librdkafka/src/rdmurmur2.h +35 -0
  245. package/deps/librdkafka/src/rdports.c +61 -0
  246. package/deps/librdkafka/src/rdports.h +38 -0
  247. package/deps/librdkafka/src/rdposix.h +250 -0
  248. package/deps/librdkafka/src/rdrand.c +151 -0
  249. package/deps/librdkafka/src/rdrand.h +72 -0
  250. package/deps/librdkafka/src/rdregex.c +156 -0
  251. package/deps/librdkafka/src/rdregex.h +43 -0
  252. package/deps/librdkafka/src/rdsignal.h +57 -0
  253. package/deps/librdkafka/src/rdstring.c +645 -0
  254. package/deps/librdkafka/src/rdstring.h +98 -0
  255. package/deps/librdkafka/src/rdsysqueue.h +404 -0
  256. package/deps/librdkafka/src/rdtime.h +356 -0
  257. package/deps/librdkafka/src/rdtypes.h +86 -0
  258. package/deps/librdkafka/src/rdunittest.c +564 -0
  259. package/deps/librdkafka/src/rdunittest.h +232 -0
  260. package/deps/librdkafka/src/rdunittest_acknowledge.c +1177 -0
  261. package/deps/librdkafka/src/rdunittest_fetcher.c +1211 -0
  262. package/deps/librdkafka/src/rdunittest_msgset_errors.c +1521 -0
  263. package/deps/librdkafka/src/rdvarint.c +134 -0
  264. package/deps/librdkafka/src/rdvarint.h +165 -0
  265. package/deps/librdkafka/src/rdwin32.h +382 -0
  266. package/deps/librdkafka/src/rdxxhash.c +1030 -0
  267. package/deps/librdkafka/src/rdxxhash.h +328 -0
  268. package/deps/librdkafka/src/regexp.c +1352 -0
  269. package/deps/librdkafka/src/regexp.h +41 -0
  270. package/deps/librdkafka/src/snappy.c +1866 -0
  271. package/deps/librdkafka/src/snappy.h +62 -0
  272. package/deps/librdkafka/src/snappy_compat.h +138 -0
  273. package/deps/librdkafka/src/statistics_schema.json +444 -0
  274. package/deps/librdkafka/src/tinycthread.c +932 -0
  275. package/deps/librdkafka/src/tinycthread.h +503 -0
  276. package/deps/librdkafka/src/tinycthread_extra.c +210 -0
  277. package/deps/librdkafka/src/tinycthread_extra.h +218 -0
  278. package/deps/librdkafka/src/win32_config.h +58 -0
  279. package/deps/librdkafka/src-cpp/CMakeLists.txt +90 -0
  280. package/deps/librdkafka/src-cpp/ConfImpl.cpp +84 -0
  281. package/deps/librdkafka/src-cpp/ConsumerImpl.cpp +244 -0
  282. package/deps/librdkafka/src-cpp/HandleImpl.cpp +436 -0
  283. package/deps/librdkafka/src-cpp/HeadersImpl.cpp +48 -0
  284. package/deps/librdkafka/src-cpp/KafkaConsumerImpl.cpp +296 -0
  285. package/deps/librdkafka/src-cpp/Makefile +55 -0
  286. package/deps/librdkafka/src-cpp/MessageImpl.cpp +38 -0
  287. package/deps/librdkafka/src-cpp/MetadataImpl.cpp +170 -0
  288. package/deps/librdkafka/src-cpp/ProducerImpl.cpp +197 -0
  289. package/deps/librdkafka/src-cpp/QueueImpl.cpp +70 -0
  290. package/deps/librdkafka/src-cpp/README.md +16 -0
  291. package/deps/librdkafka/src-cpp/RdKafka.cpp +59 -0
  292. package/deps/librdkafka/src-cpp/TopicImpl.cpp +124 -0
  293. package/deps/librdkafka/src-cpp/TopicPartitionImpl.cpp +57 -0
  294. package/deps/librdkafka/src-cpp/rdkafkacpp.h +3797 -0
  295. package/deps/librdkafka/src-cpp/rdkafkacpp_int.h +1641 -0
  296. package/deps/librdkafka/tests/0000-unittests.c +72 -0
  297. package/deps/librdkafka/tests/0001-multiobj.c +102 -0
  298. package/deps/librdkafka/tests/0002-unkpart.c +244 -0
  299. package/deps/librdkafka/tests/0003-msgmaxsize.c +173 -0
  300. package/deps/librdkafka/tests/0004-conf.c +934 -0
  301. package/deps/librdkafka/tests/0005-order.c +133 -0
  302. package/deps/librdkafka/tests/0006-symbols.c +163 -0
  303. package/deps/librdkafka/tests/0007-autotopic.c +136 -0
  304. package/deps/librdkafka/tests/0008-reqacks.c +179 -0
  305. package/deps/librdkafka/tests/0009-mock_cluster.c +272 -0
  306. package/deps/librdkafka/tests/0011-produce_batch.c +753 -0
  307. package/deps/librdkafka/tests/0012-produce_consume.c +537 -0
  308. package/deps/librdkafka/tests/0013-null-msgs.c +473 -0
  309. package/deps/librdkafka/tests/0014-reconsume-191.c +512 -0
  310. package/deps/librdkafka/tests/0015-offset_seeks.c +172 -0
  311. package/deps/librdkafka/tests/0016-client_swname.c +181 -0
  312. package/deps/librdkafka/tests/0017-compression.c +140 -0
  313. package/deps/librdkafka/tests/0018-cgrp_term.c +444 -0
  314. package/deps/librdkafka/tests/0019-list_groups.c +289 -0
  315. package/deps/librdkafka/tests/0020-destroy_hang.c +162 -0
  316. package/deps/librdkafka/tests/0021-rkt_destroy.c +72 -0
  317. package/deps/librdkafka/tests/0022-consume_batch.c +331 -0
  318. package/deps/librdkafka/tests/0025-timers.c +147 -0
  319. package/deps/librdkafka/tests/0026-consume_pause.c +547 -0
  320. package/deps/librdkafka/tests/0028-long_topicnames.c +79 -0
  321. package/deps/librdkafka/tests/0029-assign_offset.c +202 -0
  322. package/deps/librdkafka/tests/0030-offset_commit.c +589 -0
  323. package/deps/librdkafka/tests/0031-get_offsets.c +235 -0
  324. package/deps/librdkafka/tests/0033-regex_subscribe.c +536 -0
  325. package/deps/librdkafka/tests/0034-offset_reset.c +398 -0
  326. package/deps/librdkafka/tests/0035-api_version.c +73 -0
  327. package/deps/librdkafka/tests/0036-partial_fetch.c +87 -0
  328. package/deps/librdkafka/tests/0037-destroy_hang_local.c +85 -0
  329. package/deps/librdkafka/tests/0038-performance.c +121 -0
  330. package/deps/librdkafka/tests/0039-event.c +284 -0
  331. package/deps/librdkafka/tests/0040-io_event.c +257 -0
  332. package/deps/librdkafka/tests/0041-fetch_max_bytes.c +97 -0
  333. package/deps/librdkafka/tests/0042-many_topics.c +252 -0
  334. package/deps/librdkafka/tests/0043-no_connection.c +77 -0
  335. package/deps/librdkafka/tests/0044-partition_cnt.c +94 -0
  336. package/deps/librdkafka/tests/0045-subscribe_update.c +1010 -0
  337. package/deps/librdkafka/tests/0046-rkt_cache.c +65 -0
  338. package/deps/librdkafka/tests/0047-partial_buf_tmout.c +98 -0
  339. package/deps/librdkafka/tests/0048-partitioner.c +283 -0
  340. package/deps/librdkafka/tests/0049-consume_conn_close.c +162 -0
  341. package/deps/librdkafka/tests/0050-subscribe_adds.c +145 -0
  342. package/deps/librdkafka/tests/0051-assign_adds.c +126 -0
  343. package/deps/librdkafka/tests/0052-msg_timestamps.c +238 -0
  344. package/deps/librdkafka/tests/0053-stats_cb.cpp +527 -0
  345. package/deps/librdkafka/tests/0054-offset_time.cpp +236 -0
  346. package/deps/librdkafka/tests/0055-producer_latency.c +539 -0
  347. package/deps/librdkafka/tests/0056-balanced_group_mt.c +315 -0
  348. package/deps/librdkafka/tests/0057-invalid_topic.cpp +112 -0
  349. package/deps/librdkafka/tests/0058-log.cpp +123 -0
  350. package/deps/librdkafka/tests/0059-bsearch.cpp +241 -0
  351. package/deps/librdkafka/tests/0060-op_prio.cpp +163 -0
  352. package/deps/librdkafka/tests/0061-consumer_lag.cpp +295 -0
  353. package/deps/librdkafka/tests/0062-stats_event.c +126 -0
  354. package/deps/librdkafka/tests/0063-clusterid.cpp +180 -0
  355. package/deps/librdkafka/tests/0064-interceptors.c +529 -0
  356. package/deps/librdkafka/tests/0065-yield.cpp +140 -0
  357. package/deps/librdkafka/tests/0066-plugins.cpp +143 -0
  358. package/deps/librdkafka/tests/0067-empty_topic.cpp +151 -0
  359. package/deps/librdkafka/tests/0068-produce_timeout.c +136 -0
  360. package/deps/librdkafka/tests/0069-consumer_add_parts.c +119 -0
  361. package/deps/librdkafka/tests/0070-null_empty.cpp +197 -0
  362. package/deps/librdkafka/tests/0072-headers_ut.c +448 -0
  363. package/deps/librdkafka/tests/0073-headers.c +381 -0
  364. package/deps/librdkafka/tests/0074-producev.c +87 -0
  365. package/deps/librdkafka/tests/0075-retry.c +290 -0
  366. package/deps/librdkafka/tests/0076-produce_retry.c +452 -0
  367. package/deps/librdkafka/tests/0077-compaction.c +366 -0
  368. package/deps/librdkafka/tests/0078-c_from_cpp.cpp +96 -0
  369. package/deps/librdkafka/tests/0079-fork.c +93 -0
  370. package/deps/librdkafka/tests/0080-admin_ut.c +3095 -0
  371. package/deps/librdkafka/tests/0081-admin.c +5633 -0
  372. package/deps/librdkafka/tests/0082-fetch_max_bytes.cpp +137 -0
  373. package/deps/librdkafka/tests/0083-cb_event.c +233 -0
  374. package/deps/librdkafka/tests/0084-destroy_flags.c +208 -0
  375. package/deps/librdkafka/tests/0085-headers.cpp +392 -0
  376. package/deps/librdkafka/tests/0086-purge.c +368 -0
  377. package/deps/librdkafka/tests/0088-produce_metadata_timeout.c +162 -0
  378. package/deps/librdkafka/tests/0089-max_poll_interval.c +511 -0
  379. package/deps/librdkafka/tests/0090-idempotence.c +171 -0
  380. package/deps/librdkafka/tests/0091-max_poll_interval_timeout.c +295 -0
  381. package/deps/librdkafka/tests/0092-mixed_msgver.c +103 -0
  382. package/deps/librdkafka/tests/0093-holb.c +200 -0
  383. package/deps/librdkafka/tests/0094-idempotence_msg_timeout.c +231 -0
  384. package/deps/librdkafka/tests/0095-all_brokers_down.cpp +122 -0
  385. package/deps/librdkafka/tests/0097-ssl_verify.cpp +674 -0
  386. package/deps/librdkafka/tests/0098-consumer-txn.cpp +1218 -0
  387. package/deps/librdkafka/tests/0099-commit_metadata.c +194 -0
  388. package/deps/librdkafka/tests/0100-thread_interceptors.cpp +195 -0
  389. package/deps/librdkafka/tests/0101-fetch-from-follower.cpp +446 -0
  390. package/deps/librdkafka/tests/0102-static_group_rebalance.c +836 -0
  391. package/deps/librdkafka/tests/0103-transactions.c +1383 -0
  392. package/deps/librdkafka/tests/0104-fetch_from_follower_mock.c +625 -0
  393. package/deps/librdkafka/tests/0105-transactions_mock.c +3930 -0
  394. package/deps/librdkafka/tests/0106-cgrp_sess_timeout.c +318 -0
  395. package/deps/librdkafka/tests/0107-topic_recreate.c +259 -0
  396. package/deps/librdkafka/tests/0109-auto_create_topics.cpp +278 -0
  397. package/deps/librdkafka/tests/0110-batch_size.cpp +182 -0
  398. package/deps/librdkafka/tests/0111-delay_create_topics.cpp +127 -0
  399. package/deps/librdkafka/tests/0112-assign_unknown_part.c +87 -0
  400. package/deps/librdkafka/tests/0113-cooperative_rebalance.cpp +3473 -0
  401. package/deps/librdkafka/tests/0114-sticky_partitioning.cpp +176 -0
  402. package/deps/librdkafka/tests/0115-producer_auth.cpp +182 -0
  403. package/deps/librdkafka/tests/0116-kafkaconsumer_close.cpp +216 -0
  404. package/deps/librdkafka/tests/0117-mock_errors.c +331 -0
  405. package/deps/librdkafka/tests/0118-commit_rebalance.c +154 -0
  406. package/deps/librdkafka/tests/0119-consumer_auth.cpp +167 -0
  407. package/deps/librdkafka/tests/0120-asymmetric_subscription.c +185 -0
  408. package/deps/librdkafka/tests/0121-clusterid.c +115 -0
  409. package/deps/librdkafka/tests/0122-buffer_cleaning_after_rebalance.c +227 -0
  410. package/deps/librdkafka/tests/0123-connections_max_idle.c +98 -0
  411. package/deps/librdkafka/tests/0124-openssl_invalid_engine.c +69 -0
  412. package/deps/librdkafka/tests/0125-immediate_flush.c +144 -0
  413. package/deps/librdkafka/tests/0126-oauthbearer_oidc.c +1164 -0
  414. package/deps/librdkafka/tests/0127-fetch_queue_backoff.cpp +165 -0
  415. package/deps/librdkafka/tests/0128-sasl_callback_queue.cpp +217 -0
  416. package/deps/librdkafka/tests/0129-fetch_aborted_msgs.c +79 -0
  417. package/deps/librdkafka/tests/0130-store_offsets.c +178 -0
  418. package/deps/librdkafka/tests/0131-connect_timeout.c +81 -0
  419. package/deps/librdkafka/tests/0132-strategy_ordering.c +179 -0
  420. package/deps/librdkafka/tests/0133-ssl_keys.c +150 -0
  421. package/deps/librdkafka/tests/0134-ssl_provider.c +92 -0
  422. package/deps/librdkafka/tests/0135-sasl_credentials.cpp +279 -0
  423. package/deps/librdkafka/tests/0136-resolve_cb.c +181 -0
  424. package/deps/librdkafka/tests/0137-barrier_batch_consume.c +752 -0
  425. package/deps/librdkafka/tests/0138-admin_mock.c +281 -0
  426. package/deps/librdkafka/tests/0139-offset_validation_mock.c +950 -0
  427. package/deps/librdkafka/tests/0140-commit_metadata.cpp +108 -0
  428. package/deps/librdkafka/tests/0142-reauthentication.c +931 -0
  429. package/deps/librdkafka/tests/0143-exponential_backoff_mock.c +552 -0
  430. package/deps/librdkafka/tests/0144-idempotence_mock.c +373 -0
  431. package/deps/librdkafka/tests/0145-pause_resume_mock.c +119 -0
  432. package/deps/librdkafka/tests/0146-metadata_mock.c +505 -0
  433. package/deps/librdkafka/tests/0147-consumer_group_consumer_mock.c +1210 -0
  434. package/deps/librdkafka/tests/0148-offset_fetch_commit_error_mock.c +569 -0
  435. package/deps/librdkafka/tests/0149-broker-same-host-port.c +140 -0
  436. package/deps/librdkafka/tests/0150-telemetry_mock.c +651 -0
  437. package/deps/librdkafka/tests/0151-purge-brokers.c +566 -0
  438. package/deps/librdkafka/tests/0152-rebootstrap.c +59 -0
  439. package/deps/librdkafka/tests/0153-memberid.c +128 -0
  440. package/deps/librdkafka/tests/0155-share_group_heartbeat_mock.c +2695 -0
  441. package/deps/librdkafka/tests/0156-share_consumer_fetch_mock.c +1551 -0
  442. package/deps/librdkafka/tests/0157-share_consumer_ack_mock.c +1788 -0
  443. package/deps/librdkafka/tests/0158-share_consumer_transactions_mock.c +467 -0
  444. package/deps/librdkafka/tests/0170-share_consumer_subscription.c +2192 -0
  445. package/deps/librdkafka/tests/0171-share_consumer_consume.c +2150 -0
  446. package/deps/librdkafka/tests/0172-share_consumer_acknowledge.c +1919 -0
  447. package/deps/librdkafka/tests/0173-share_consumer_commit_async.c +2735 -0
  448. package/deps/librdkafka/tests/0174-share_consumer_concurrency.c +1434 -0
  449. package/deps/librdkafka/tests/0175-share_consumer_groups.c +574 -0
  450. package/deps/librdkafka/tests/0176-share_consumer_commit_sync.c +2986 -0
  451. package/deps/librdkafka/tests/0177-share_consumer_transactions.c +1815 -0
  452. package/deps/librdkafka/tests/0178-share_consumer_close.c +2102 -0
  453. package/deps/librdkafka/tests/0179-share_consumer_destroy.c +2482 -0
  454. package/deps/librdkafka/tests/0180-share_consumer_config.c +1677 -0
  455. package/deps/librdkafka/tests/0181-share_consumer_topic_delete.c +354 -0
  456. package/deps/librdkafka/tests/0182-share_consumer_error_handling_mock.c +3358 -0
  457. package/deps/librdkafka/tests/0183-share_consumer_leader_change_mock.c +1234 -0
  458. package/deps/librdkafka/tests/0184-share_consumer_topic_recreate.c +1356 -0
  459. package/deps/librdkafka/tests/0185-share_consumer_max_poll_interval.c +557 -0
  460. package/deps/librdkafka/tests/0186-share_consumer_fatal_error.c +360 -0
  461. package/deps/librdkafka/tests/0190-share_consumer_telemetry.c +387 -0
  462. package/deps/librdkafka/tests/1000-unktopic.c +164 -0
  463. package/deps/librdkafka/tests/8000-idle.cpp +60 -0
  464. package/deps/librdkafka/tests/8001-fetch_from_follower_mock_manual.c +113 -0
  465. package/deps/librdkafka/tests/CMakeLists.txt +193 -0
  466. package/deps/librdkafka/tests/LibrdkafkaTestApp.py +291 -0
  467. package/deps/librdkafka/tests/Makefile +182 -0
  468. package/deps/librdkafka/tests/README.md +514 -0
  469. package/deps/librdkafka/tests/autotest.sh +33 -0
  470. package/deps/librdkafka/tests/backtrace.gdb +30 -0
  471. package/deps/librdkafka/tests/broker_version_tests.py +315 -0
  472. package/deps/librdkafka/tests/buildbox.sh +17 -0
  473. package/deps/librdkafka/tests/cleanup-checker-tests.sh +20 -0
  474. package/deps/librdkafka/tests/cluster_testing.py +203 -0
  475. package/deps/librdkafka/tests/delete-test-topics.sh +56 -0
  476. package/deps/librdkafka/tests/fixtures/oauthbearer/jwt_assertion_template.json +10 -0
  477. package/deps/librdkafka/tests/fixtures/ssl/Makefile +8 -0
  478. package/deps/librdkafka/tests/fixtures/ssl/README.md +13 -0
  479. package/deps/librdkafka/tests/fixtures/ssl/client.keystore.intermediate.p12 +0 -0
  480. package/deps/librdkafka/tests/fixtures/ssl/client.keystore.p12 +0 -0
  481. package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.intermediate.pem +72 -0
  482. package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.pem +50 -0
  483. package/deps/librdkafka/tests/fixtures/ssl/client2.intermediate.key +46 -0
  484. package/deps/librdkafka/tests/fixtures/ssl/client2.key +46 -0
  485. package/deps/librdkafka/tests/fixtures/ssl/create_keys.sh +168 -0
  486. package/deps/librdkafka/tests/fuzzers/Makefile +12 -0
  487. package/deps/librdkafka/tests/fuzzers/README.md +31 -0
  488. package/deps/librdkafka/tests/fuzzers/fuzz_regex.c +74 -0
  489. package/deps/librdkafka/tests/fuzzers/helpers.h +90 -0
  490. package/deps/librdkafka/tests/gen-ssl-certs.sh +165 -0
  491. package/deps/librdkafka/tests/interactive_broker_version.py +170 -0
  492. package/deps/librdkafka/tests/interceptor_test/CMakeLists.txt +16 -0
  493. package/deps/librdkafka/tests/interceptor_test/Makefile +22 -0
  494. package/deps/librdkafka/tests/interceptor_test/interceptor_test.c +314 -0
  495. package/deps/librdkafka/tests/interceptor_test/interceptor_test.h +54 -0
  496. package/deps/librdkafka/tests/java/IncrementalRebalanceCli.java +97 -0
  497. package/deps/librdkafka/tests/java/Makefile +13 -0
  498. package/deps/librdkafka/tests/java/Murmur2Cli.java +46 -0
  499. package/deps/librdkafka/tests/java/README.md +14 -0
  500. package/deps/librdkafka/tests/java/TransactionProducerCli.java +162 -0
  501. package/deps/librdkafka/tests/java/run-class.sh +11 -0
  502. package/deps/librdkafka/tests/librdkafka.suppressions +483 -0
  503. package/deps/librdkafka/tests/lz4_manual_test.sh +59 -0
  504. package/deps/librdkafka/tests/multi-broker-version-test.sh +50 -0
  505. package/deps/librdkafka/tests/parse-refcnt.sh +43 -0
  506. package/deps/librdkafka/tests/performance_plot.py +115 -0
  507. package/deps/librdkafka/tests/plugin_test/Makefile +19 -0
  508. package/deps/librdkafka/tests/plugin_test/plugin_test.c +58 -0
  509. package/deps/librdkafka/tests/requirements.txt +2 -0
  510. package/deps/librdkafka/tests/run-all-tests.sh +81 -0
  511. package/deps/librdkafka/tests/run-consumer-tests.sh +16 -0
  512. package/deps/librdkafka/tests/run-producer-tests.sh +16 -0
  513. package/deps/librdkafka/tests/run-test-batches.py +157 -0
  514. package/deps/librdkafka/tests/run-test.sh +141 -0
  515. package/deps/librdkafka/tests/rusage.c +249 -0
  516. package/deps/librdkafka/tests/sasl_test.py +289 -0
  517. package/deps/librdkafka/tests/scenarios/README.md +6 -0
  518. package/deps/librdkafka/tests/scenarios/ak23.json +6 -0
  519. package/deps/librdkafka/tests/scenarios/default.json +5 -0
  520. package/deps/librdkafka/tests/scenarios/noautocreate.json +5 -0
  521. package/deps/librdkafka/tests/share_telemetry_verify/share-otel-collector-config.yaml +28 -0
  522. package/deps/librdkafka/tests/sockem.c +801 -0
  523. package/deps/librdkafka/tests/sockem.h +85 -0
  524. package/deps/librdkafka/tests/sockem_ctrl.c +145 -0
  525. package/deps/librdkafka/tests/sockem_ctrl.h +61 -0
  526. package/deps/librdkafka/tests/test.c +8376 -0
  527. package/deps/librdkafka/tests/test.conf.example +27 -0
  528. package/deps/librdkafka/tests/test.h +1150 -0
  529. package/deps/librdkafka/tests/testcpp.cpp +131 -0
  530. package/deps/librdkafka/tests/testcpp.h +388 -0
  531. package/deps/librdkafka/tests/testshared.h +416 -0
  532. package/deps/librdkafka/tests/tools/README.md +4 -0
  533. package/deps/librdkafka/tests/tools/stats/README.md +21 -0
  534. package/deps/librdkafka/tests/tools/stats/filter.jq +42 -0
  535. package/deps/librdkafka/tests/tools/stats/graph.py +150 -0
  536. package/deps/librdkafka/tests/tools/stats/requirements.txt +3 -0
  537. package/deps/librdkafka/tests/tools/stats/to_csv.py +124 -0
  538. package/deps/librdkafka/tests/trivup/trivup-0.15.0.tar.gz +0 -0
  539. package/deps/librdkafka/tests/until-fail.sh +87 -0
  540. package/deps/librdkafka/tests/xxxx-assign_partition.c +122 -0
  541. package/deps/librdkafka/tests/xxxx-metadata.cpp +159 -0
  542. package/deps/librdkafka/vcpkg.json +23 -0
  543. package/deps/librdkafka/win32/README.md +5 -0
  544. package/deps/librdkafka/win32/build-package.bat +3 -0
  545. package/deps/librdkafka/win32/build.bat +19 -0
  546. package/deps/librdkafka/win32/common.vcxproj +84 -0
  547. package/deps/librdkafka/win32/interceptor_test/interceptor_test.vcxproj +87 -0
  548. package/deps/librdkafka/win32/librdkafka.autopkg.template +54 -0
  549. package/deps/librdkafka/win32/librdkafka.master.testing.targets +13 -0
  550. package/deps/librdkafka/win32/librdkafka.sln +226 -0
  551. package/deps/librdkafka/win32/librdkafka.vcxproj +282 -0
  552. package/deps/librdkafka/win32/librdkafkacpp/librdkafkacpp.vcxproj +104 -0
  553. package/deps/librdkafka/win32/msbuild.ps1 +58 -0
  554. package/deps/librdkafka/win32/openssl_engine_example/openssl_engine_example.vcxproj +132 -0
  555. package/deps/librdkafka/win32/package-zip.ps1 +46 -0
  556. package/deps/librdkafka/win32/packages/repositories.config +4 -0
  557. package/deps/librdkafka/win32/push-package.bat +4 -0
  558. package/deps/librdkafka/win32/rdkafka_complex_consumer_example_cpp/rdkafka_complex_consumer_example_cpp.vcxproj +67 -0
  559. package/deps/librdkafka/win32/rdkafka_example/rdkafka_example.vcxproj +97 -0
  560. package/deps/librdkafka/win32/rdkafka_performance/rdkafka_performance.vcxproj +97 -0
  561. package/deps/librdkafka/win32/setup-msys2.ps1 +47 -0
  562. package/deps/librdkafka/win32/setup-vcpkg.ps1 +34 -0
  563. package/deps/librdkafka/win32/tests/test.conf.example +25 -0
  564. package/deps/librdkafka/win32/tests/tests.vcxproj +278 -0
  565. package/deps/librdkafka/win32/win_ssl_cert_store/win_ssl_cert_store.vcxproj +132 -0
  566. package/deps/librdkafka/win32/wingetopt.c +564 -0
  567. package/deps/librdkafka/win32/wingetopt.h +101 -0
  568. package/deps/librdkafka/win32/wintime.h +33 -0
  569. package/deps/librdkafka.gyp +83 -0
  570. package/deps/windows-install.py +80 -0
  571. package/index.d.ts +3 -0
  572. package/lib/admin.js +732 -0
  573. package/lib/client.js +679 -0
  574. package/lib/error.js +501 -0
  575. package/lib/index.js +8 -0
  576. package/lib/kafka-consumer-stream.js +399 -0
  577. package/lib/kafka-consumer.js +798 -0
  578. package/lib/kafkajs/_admin.js +1052 -0
  579. package/lib/kafkajs/_common.js +887 -0
  580. package/lib/kafkajs/_consumer.js +2156 -0
  581. package/lib/kafkajs/_consumer_cache.js +310 -0
  582. package/lib/kafkajs/_error.js +298 -0
  583. package/lib/kafkajs/_kafka.js +125 -0
  584. package/lib/kafkajs/_linked-list.js +220 -0
  585. package/lib/kafkajs/_producer.js +863 -0
  586. package/lib/kafkajs/index.js +5 -0
  587. package/lib/producer/high-level-producer.js +400 -0
  588. package/lib/producer-stream.js +337 -0
  589. package/lib/producer.js +405 -0
  590. package/lib/rdkafka.js +44 -0
  591. package/lib/tools/ref-counter.js +53 -0
  592. package/lib/topic-partition.js +91 -0
  593. package/lib/topic.js +43 -0
  594. package/lib/util.js +55 -0
  595. package/librdkafka.js +12 -0
  596. package/package.json +85 -0
  597. package/shim/source_location +54 -0
  598. package/src/admin.cc +1597 -0
  599. package/src/admin.h +112 -0
  600. package/src/binding.cc +76 -0
  601. package/src/binding.h +25 -0
  602. package/src/callbacks.cc +676 -0
  603. package/src/callbacks.h +302 -0
  604. package/src/common.cc +1628 -0
  605. package/src/common.h +192 -0
  606. package/src/config.cc +219 -0
  607. package/src/config.h +61 -0
  608. package/src/connection.cc +703 -0
  609. package/src/connection.h +117 -0
  610. package/src/errors.cc +119 -0
  611. package/src/errors.h +60 -0
  612. package/src/kafka-consumer.cc +1539 -0
  613. package/src/kafka-consumer.h +147 -0
  614. package/src/producer.cc +917 -0
  615. package/src/producer.h +124 -0
  616. package/src/topic.cc +173 -0
  617. package/src/topic.h +54 -0
  618. package/src/workers.cc +1714 -0
  619. package/src/workers.h +690 -0
  620. package/types/config.d.ts +1269 -0
  621. package/types/errors.d.ts +373 -0
  622. package/types/kafkajs.d.ts +568 -0
  623. package/types/rdkafka.d.ts +571 -0
  624. package/util/configure.js +32 -0
  625. package/util/generate-docs.sh +18 -0
  626. package/util/get-env.js +6 -0
  627. package/util/test-compile.js +11 -0
  628. package/util/test-producer-delivery.js +100 -0
@@ -0,0 +1,1539 @@
1
+ /*
2
+ * confluent-kafka-javascript - Node.js wrapper for RdKafka C/C++ library
3
+ *
4
+ * Copyright (c) 2016-2023 Blizzard Entertainment
5
+ * (c) 2023 Confluent, Inc.
6
+ *
7
+ * This software may be modified and distributed under the terms
8
+ * of the MIT license. See the LICENSE.txt file for details.
9
+ */
10
+
11
+ #include <iostream>
12
+ #include <string>
13
+ #include <vector>
14
+
15
+ #include "src/kafka-consumer.h"
16
+ #include "src/workers.h"
17
+
18
+ using Nan::FunctionCallbackInfo;
19
+
20
+ namespace NodeKafka {
21
+
22
+ /**
23
+ * @brief KafkaConsumer v8 wrapped object.
24
+ *
25
+ * Specializes the connection to wrap a consumer object through compositional
26
+ * inheritence. Establishes its prototype in node through `Init`
27
+ *
28
+ * @sa RdKafka::Handle
29
+ * @sa NodeKafka::Client
30
+ */
31
+
32
+ KafkaConsumer::KafkaConsumer(Conf* gconfig, Conf* tconfig):
33
+ Connection(gconfig, tconfig) {
34
+ std::string errstr;
35
+
36
+ if (m_tconfig)
37
+ m_gconfig->set("default_topic_conf", m_tconfig, errstr);
38
+
39
+ m_consume_loop = nullptr;
40
+ }
41
+
42
+ KafkaConsumer::~KafkaConsumer() {
43
+ // We only want to run this if it hasn't been run already
44
+ Disconnect();
45
+ }
46
+
47
+ Baton KafkaConsumer::Connect() {
48
+ if (IsConnected()) {
49
+ return Baton(RdKafka::ERR_NO_ERROR);
50
+ }
51
+
52
+ Baton baton = setupSaslOAuthBearerConfig();
53
+ if (baton.err() != RdKafka::ERR_NO_ERROR) {
54
+ return baton;
55
+ }
56
+
57
+ std::string errstr;
58
+ {
59
+ scoped_shared_write_lock lock(m_connection_lock);
60
+ m_consumer = RdKafka::KafkaConsumer::create(m_gconfig, errstr);
61
+ m_client = m_consumer;
62
+ }
63
+
64
+ if (!m_client || !errstr.empty()) {
65
+ return Baton(RdKafka::ERR__STATE, errstr);
66
+ }
67
+
68
+ /* Set the client name at the first possible opportunity for logging. */
69
+ m_event_cb.dispatcher.SetClientName(m_client->name());
70
+
71
+ baton = setupSaslOAuthBearerBackgroundQueue();
72
+ if (baton.err() != RdKafka::ERR_NO_ERROR) {
73
+ return baton;
74
+ }
75
+
76
+ if (m_partitions.size() > 0) {
77
+ m_client->resume(m_partitions);
78
+ }
79
+
80
+ rd_kafka_queue_t* queue = rd_kafka_queue_get_consumer(m_client->c_ptr());
81
+ rd_kafka_queue_cb_event_enable(
82
+ queue, &m_queue_not_empty_cb.queue_not_empty_cb, &m_queue_not_empty_cb);
83
+ rd_kafka_queue_destroy(queue);
84
+
85
+ return Baton(RdKafka::ERR_NO_ERROR);
86
+ }
87
+
88
+ void KafkaConsumer::ActivateDispatchers() {
89
+ // Listen to global config
90
+ m_gconfig->listen();
91
+
92
+ // Listen to non global config
93
+ // tconfig->listen();
94
+
95
+ // This should be refactored to config based management
96
+ m_event_cb.dispatcher.Activate();
97
+ m_queue_not_empty_cb.dispatcher.Activate();
98
+ }
99
+
100
+ Baton KafkaConsumer::Disconnect() {
101
+ // Only close client if it is connected
102
+ RdKafka::ErrorCode err = RdKafka::ERR_NO_ERROR;
103
+
104
+ if (IsConnected()) {
105
+ m_is_closing = true;
106
+ {
107
+ scoped_shared_write_lock lock(m_connection_lock);
108
+
109
+ err = m_consumer->close();
110
+
111
+ delete m_client;
112
+ m_client = NULL;
113
+ m_consumer = nullptr;
114
+ }
115
+ }
116
+
117
+ m_is_closing = false;
118
+
119
+ return Baton(err);
120
+ }
121
+
122
+ void KafkaConsumer::DeactivateDispatchers() {
123
+ // Stop listening to the config dispatchers
124
+ m_gconfig->stop();
125
+
126
+ // Also this one
127
+ m_event_cb.dispatcher.Deactivate();
128
+ m_queue_not_empty_cb.dispatcher.Deactivate();
129
+ }
130
+
131
+ void KafkaConsumer::ConfigureCallback(const std::string& string_key,
132
+ const v8::Local<v8::Function>& cb,
133
+ bool add) {
134
+ if (string_key.compare("queue_non_empty_cb") == 0) {
135
+ if (add) {
136
+ this->m_queue_not_empty_cb.dispatcher.AddCallback(cb);
137
+ } else {
138
+ this->m_queue_not_empty_cb.dispatcher.RemoveCallback(cb);
139
+ }
140
+ } else {
141
+ Connection::ConfigureCallback(string_key, cb, add);
142
+ }
143
+ }
144
+
145
+ bool KafkaConsumer::IsSubscribed() {
146
+ if (!IsConnected()) {
147
+ return false;
148
+ }
149
+
150
+ if (!m_is_subscribed) {
151
+ return false;
152
+ }
153
+
154
+ return true;
155
+ }
156
+
157
+
158
+ bool KafkaConsumer::HasAssignedPartitions() {
159
+ return !m_partitions.empty();
160
+ }
161
+
162
+ int KafkaConsumer::AssignedPartitionCount() {
163
+ return m_partition_cnt;
164
+ }
165
+
166
+ Baton KafkaConsumer::GetWatermarkOffsets(
167
+ std::string topic_name, int32_t partition,
168
+ int64_t* low_offset, int64_t* high_offset) {
169
+ // Check if we are connected first
170
+
171
+ RdKafka::ErrorCode err;
172
+
173
+ if (IsConnected()) {
174
+ scoped_shared_read_lock lock(m_connection_lock);
175
+ if (IsConnected()) {
176
+ // Always send true - we
177
+ err = m_client->get_watermark_offsets(topic_name, partition,
178
+ low_offset, high_offset);
179
+ } else {
180
+ err = RdKafka::ERR__STATE;
181
+ }
182
+ } else {
183
+ err = RdKafka::ERR__STATE;
184
+ }
185
+
186
+ return Baton(err);
187
+ }
188
+
189
+ void KafkaConsumer::part_list_print(const std::vector<RdKafka::TopicPartition*> &partitions) { // NOLINT
190
+ for (unsigned int i = 0 ; i < partitions.size() ; i++)
191
+ std::cerr << partitions[i]->topic() <<
192
+ "[" << partitions[i]->partition() << "], ";
193
+ std::cerr << std::endl;
194
+ }
195
+
196
+ Baton KafkaConsumer::Assign(std::vector<RdKafka::TopicPartition*> partitions) {
197
+ if (!IsConnected()) {
198
+ return Baton(RdKafka::ERR__STATE, "KafkaConsumer is disconnected");
199
+ }
200
+
201
+
202
+ RdKafka::ErrorCode errcode = m_consumer->assign(partitions);
203
+
204
+ if (errcode == RdKafka::ERR_NO_ERROR) {
205
+ m_partition_cnt = partitions.size();
206
+ m_partitions.swap(partitions);
207
+ }
208
+
209
+ // Destroy the partitions: Either we're using them (and partitions
210
+ // is now our old vector), or we're not using it as there was an
211
+ // error.
212
+ RdKafka::TopicPartition::destroy(partitions);
213
+
214
+ return Baton(errcode);
215
+ }
216
+
217
+ Baton KafkaConsumer::Unassign() {
218
+ if (!IsClosing() && !IsConnected()) {
219
+ return Baton(RdKafka::ERR__STATE);
220
+ }
221
+
222
+ RdKafka::ErrorCode errcode = m_consumer->unassign();
223
+
224
+ if (errcode != RdKafka::ERR_NO_ERROR) {
225
+ return Baton(errcode);
226
+ }
227
+
228
+ // Destroy the old list of partitions since we are no longer using it
229
+ RdKafka::TopicPartition::destroy(m_partitions);
230
+
231
+ m_partition_cnt = 0;
232
+
233
+ return Baton(RdKafka::ERR_NO_ERROR);
234
+ }
235
+
236
+ Baton KafkaConsumer::IncrementalAssign(
237
+ std::vector<RdKafka::TopicPartition*> partitions) {
238
+ if (!IsConnected()) {
239
+ return Baton(RdKafka::ERR__STATE, "KafkaConsumer is disconnected");
240
+ }
241
+
242
+ RdKafka::Error* error = m_consumer->incremental_assign(partitions);
243
+
244
+ if (error == NULL) {
245
+ m_partition_cnt += partitions.size();
246
+ // We assume here that there are no duplicate assigns and just transfer.
247
+ m_partitions.insert(m_partitions.end(), partitions.begin(), partitions.end()); // NOLINT
248
+ } else {
249
+ // If we're in error, destroy it, otherwise, don't (since we're using them).
250
+ RdKafka::TopicPartition::destroy(partitions);
251
+ }
252
+
253
+ return rdkafkaErrorToBaton(error);
254
+ }
255
+
256
+ Baton KafkaConsumer::IncrementalUnassign(
257
+ std::vector<RdKafka::TopicPartition*> partitions) {
258
+ if (!IsClosing() && !IsConnected()) {
259
+ return Baton(RdKafka::ERR__STATE);
260
+ }
261
+
262
+ RdKafka::Error* error = m_consumer->incremental_unassign(partitions);
263
+
264
+ std::vector<RdKafka::TopicPartition*> delete_partitions;
265
+
266
+ if (error == NULL) {
267
+ // For now, use two for loops. Make more efficient if needed later.
268
+ for (unsigned int i = 0; i < partitions.size(); i++) {
269
+ for (unsigned int j = 0; j < m_partitions.size(); j++) {
270
+ if (partitions[i]->partition() == m_partitions[j]->partition() &&
271
+ partitions[i]->topic() == m_partitions[j]->topic()) {
272
+ delete_partitions.push_back(m_partitions[j]);
273
+ m_partitions.erase(m_partitions.begin() + j);
274
+ m_partition_cnt--;
275
+ break;
276
+ }
277
+ }
278
+ }
279
+ }
280
+
281
+ // Destroy the old list of partitions since we are no longer using it
282
+ RdKafka::TopicPartition::destroy(delete_partitions);
283
+
284
+ // Destroy the partition args since those are only used to lookup the
285
+ // partitions that needed to be deleted.
286
+ RdKafka::TopicPartition::destroy(partitions);
287
+
288
+ return rdkafkaErrorToBaton(error);
289
+ }
290
+
291
+ Baton KafkaConsumer::Commit(std::vector<RdKafka::TopicPartition*> toppars) {
292
+ if (!IsConnected()) {
293
+ return Baton(RdKafka::ERR__STATE);
294
+ }
295
+
296
+ RdKafka::ErrorCode err = m_consumer->commitAsync(toppars);
297
+
298
+ return Baton(err);
299
+ }
300
+
301
+ Baton KafkaConsumer::Commit(RdKafka::TopicPartition * toppar) {
302
+ if (!IsConnected()) {
303
+ return Baton(RdKafka::ERR__STATE, "KafkaConsumer is not connected");
304
+ }
305
+
306
+ // Need to put topic in a vector for it to work
307
+ std::vector<RdKafka::TopicPartition*> offsets = {toppar};
308
+ RdKafka::ErrorCode err = m_consumer->commitAsync(offsets);
309
+
310
+ return Baton(err);
311
+ }
312
+
313
+ Baton KafkaConsumer::Commit() {
314
+ // sets an error message
315
+ if (!IsConnected()) {
316
+ return Baton(RdKafka::ERR__STATE, "KafkaConsumer is not connected");
317
+ }
318
+
319
+ RdKafka::ErrorCode err = m_consumer->commitAsync();
320
+
321
+ return Baton(err);
322
+ }
323
+
324
+ // Synchronous commit events
325
+ Baton KafkaConsumer::CommitSync(std::vector<RdKafka::TopicPartition*> toppars) {
326
+ if (!IsConnected()) {
327
+ return Baton(RdKafka::ERR__STATE, "KafkaConsumer is not connected");
328
+ }
329
+
330
+ RdKafka::ErrorCode err = m_consumer->commitSync(toppars);
331
+ // RdKafka::TopicPartition::destroy(toppars);
332
+
333
+ return Baton(err);
334
+ }
335
+
336
+ Baton KafkaConsumer::CommitSync(RdKafka::TopicPartition * toppar) {
337
+ if (!IsConnected()) {
338
+ return Baton(RdKafka::ERR__STATE);
339
+ }
340
+
341
+ // Need to put topic in a vector for it to work
342
+ std::vector<RdKafka::TopicPartition*> offsets = {toppar};
343
+ RdKafka::ErrorCode err = m_consumer->commitSync(offsets);
344
+
345
+ return Baton(err);
346
+ }
347
+
348
+ Baton KafkaConsumer::CommitSync() {
349
+ // sets an error message
350
+ if (!IsConnected()) {
351
+ return Baton(RdKafka::ERR__STATE, "KafkaConsumer is not connected");
352
+ }
353
+
354
+ RdKafka::ErrorCode err = m_consumer->commitSync();
355
+
356
+ return Baton(err);
357
+ }
358
+
359
+ Baton KafkaConsumer::Seek(const RdKafka::TopicPartition &partition, int timeout_ms) { // NOLINT
360
+ if (!IsConnected()) {
361
+ return Baton(RdKafka::ERR__STATE, "KafkaConsumer is not connected");
362
+ }
363
+
364
+ RdKafka::ErrorCode err = m_consumer->seek(partition, timeout_ms);
365
+
366
+ return Baton(err);
367
+ }
368
+
369
+ Baton KafkaConsumer::Committed(std::vector<RdKafka::TopicPartition*> &toppars,
370
+ int timeout_ms) {
371
+ if (!IsConnected()) {
372
+ return Baton(RdKafka::ERR__STATE, "KafkaConsumer is not connected");
373
+ }
374
+
375
+ RdKafka::ErrorCode err = m_consumer->committed(toppars, timeout_ms);
376
+
377
+ return Baton(err);
378
+ }
379
+
380
+ Baton KafkaConsumer::Position(std::vector<RdKafka::TopicPartition*> &toppars) {
381
+ if (!IsConnected()) {
382
+ return Baton(RdKafka::ERR__STATE, "KafkaConsumer is not connected");
383
+ }
384
+
385
+ RdKafka::ErrorCode err = m_consumer->position(toppars);
386
+
387
+ return Baton(err);
388
+ }
389
+
390
+ Baton KafkaConsumer::Subscription() {
391
+ if (!IsConnected()) {
392
+ return Baton(RdKafka::ERR__STATE, "Consumer is not connected");
393
+ }
394
+
395
+ // Needs to be a pointer since we're returning it through the baton
396
+ std::vector<std::string> * topics = new std::vector<std::string>;
397
+
398
+ RdKafka::ErrorCode err = m_consumer->subscription(*topics);
399
+
400
+ if (err == RdKafka::ErrorCode::ERR_NO_ERROR) {
401
+ // Good to go
402
+ return Baton(topics);
403
+ }
404
+
405
+ return Baton(err);
406
+ }
407
+
408
+ Baton KafkaConsumer::Unsubscribe() {
409
+ if (IsConnected() && IsSubscribed()) {
410
+ m_consumer->unsubscribe();
411
+ m_is_subscribed = false;
412
+ }
413
+
414
+ return Baton(RdKafka::ERR_NO_ERROR);
415
+ }
416
+
417
+ Baton KafkaConsumer::Pause(std::vector<RdKafka::TopicPartition*> & toppars) {
418
+ if (IsConnected()) {
419
+ RdKafka::ErrorCode err = m_consumer->pause(toppars);
420
+ return Baton(err);
421
+ }
422
+
423
+ return Baton(RdKafka::ERR__STATE);
424
+ }
425
+
426
+ Baton KafkaConsumer::Resume(std::vector<RdKafka::TopicPartition*> & toppars) {
427
+ if (IsConnected()) {
428
+ RdKafka::ErrorCode err = m_consumer->resume(toppars);
429
+
430
+ return Baton(err);
431
+ }
432
+
433
+ return Baton(RdKafka::ERR__STATE);
434
+ }
435
+
436
+ Baton KafkaConsumer::OffsetsStore(
437
+ std::vector<RdKafka::TopicPartition*>& toppars) { // NOLINT
438
+ if (!IsSubscribed()) { /* IsSubscribed also checks IsConnected */
439
+ return Baton(RdKafka::ERR__STATE);
440
+ }
441
+
442
+ RdKafka::ErrorCode err = m_consumer->offsets_store(toppars);
443
+
444
+ return Baton(err);
445
+ }
446
+
447
+ Baton KafkaConsumer::Subscribe(std::vector<std::string> topics) {
448
+ if (!IsConnected()) {
449
+ return Baton(RdKafka::ERR__STATE);
450
+ }
451
+
452
+ RdKafka::ErrorCode errcode = m_consumer->subscribe(topics);
453
+ if (errcode != RdKafka::ERR_NO_ERROR) {
454
+ return Baton(errcode);
455
+ }
456
+
457
+ m_is_subscribed = true;
458
+
459
+ return Baton(RdKafka::ERR_NO_ERROR);
460
+ }
461
+
462
+ Baton KafkaConsumer::Consume(int timeout_ms) {
463
+ if (IsConnected()) {
464
+ scoped_shared_read_lock lock(m_connection_lock);
465
+ if (!IsConnected()) {
466
+ return Baton(RdKafka::ERR__STATE, "KafkaConsumer is not connected");
467
+ } else {
468
+ RdKafka::Message * message = m_consumer->consume(timeout_ms);
469
+ RdKafka::ErrorCode response_code = message->err();
470
+ // we want to handle these errors at the call site
471
+ if (response_code != RdKafka::ERR_NO_ERROR &&
472
+ response_code != RdKafka::ERR__PARTITION_EOF &&
473
+ response_code != RdKafka::ERR__TIMED_OUT &&
474
+ response_code != RdKafka::ERR__TIMED_OUT_QUEUE
475
+ ) {
476
+ delete message;
477
+ return Baton(response_code);
478
+ }
479
+
480
+ return Baton(message);
481
+ }
482
+ } else {
483
+ return Baton(RdKafka::ERR__STATE, "KafkaConsumer is not connected");
484
+ }
485
+ }
486
+
487
+ Baton KafkaConsumer::RefreshAssignments() {
488
+ if (!IsConnected()) {
489
+ return Baton(RdKafka::ERR__STATE);
490
+ }
491
+
492
+ std::vector<RdKafka::TopicPartition*> partition_list;
493
+ RdKafka::ErrorCode err = m_consumer->assignment(partition_list);
494
+
495
+ switch (err) {
496
+ case RdKafka::ERR_NO_ERROR:
497
+ m_partition_cnt = partition_list.size();
498
+ m_partitions.swap(partition_list);
499
+
500
+ // These are pointers so we need to delete them somewhere.
501
+ // Do it here because we're only going to convert when we're ready
502
+ // to return to v8.
503
+ RdKafka::TopicPartition::destroy(partition_list);
504
+ return Baton(RdKafka::ERR_NO_ERROR);
505
+ break;
506
+ default:
507
+ return Baton(err);
508
+ break;
509
+ }
510
+ }
511
+
512
+ Baton KafkaConsumer::AssignmentLost() {
513
+ bool lost = m_consumer->assignment_lost();
514
+ return Baton(reinterpret_cast<void *>(lost));
515
+ }
516
+
517
+ std::string KafkaConsumer::RebalanceProtocol() {
518
+ if (!IsConnected()) {
519
+ return std::string("NONE");
520
+ }
521
+
522
+ return m_consumer->rebalance_protocol();
523
+ }
524
+
525
+ Nan::Persistent<v8::Function> KafkaConsumer::constructor;
526
+
527
+ void KafkaConsumer::Init(v8::Local<v8::Object> exports) {
528
+ Nan::HandleScope scope;
529
+
530
+ v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
531
+ tpl->SetClassName(Nan::New("KafkaConsumer").ToLocalChecked());
532
+ tpl->InstanceTemplate()->SetInternalFieldCount(1);
533
+
534
+ /*
535
+ * Lifecycle events inherited from NodeKafka::Connection
536
+ *
537
+ * @sa NodeKafka::Connection
538
+ */
539
+
540
+ Nan::SetPrototypeMethod(tpl, "configureCallbacks", NodeConfigureCallbacks);
541
+
542
+ /*
543
+ * @brief Methods to do with establishing state
544
+ */
545
+
546
+ Nan::SetPrototypeMethod(tpl, "connect", NodeConnect);
547
+ Nan::SetPrototypeMethod(tpl, "disconnect", NodeDisconnect);
548
+ Nan::SetPrototypeMethod(tpl, "getMetadata", NodeGetMetadata);
549
+ Nan::SetPrototypeMethod(tpl, "queryWatermarkOffsets", NodeQueryWatermarkOffsets); // NOLINT
550
+ Nan::SetPrototypeMethod(tpl, "offsetsForTimes", NodeOffsetsForTimes);
551
+ Nan::SetPrototypeMethod(tpl, "getWatermarkOffsets", NodeGetWatermarkOffsets);
552
+ Nan::SetPrototypeMethod(tpl, "setSaslCredentials", NodeSetSaslCredentials);
553
+ Nan::SetPrototypeMethod(tpl, "setOAuthBearerToken", NodeSetOAuthBearerToken);
554
+ Nan::SetPrototypeMethod(tpl, "setOAuthBearerTokenFailure",
555
+ NodeSetOAuthBearerTokenFailure);
556
+
557
+ /*
558
+ * @brief Methods exposed to do with message retrieval
559
+ */
560
+ Nan::SetPrototypeMethod(tpl, "subscription", NodeSubscription);
561
+ Nan::SetPrototypeMethod(tpl, "subscribe", NodeSubscribe);
562
+ Nan::SetPrototypeMethod(tpl, "unsubscribe", NodeUnsubscribe);
563
+ Nan::SetPrototypeMethod(tpl, "consumeLoop", NodeConsumeLoop);
564
+ Nan::SetPrototypeMethod(tpl, "consume", NodeConsume);
565
+ Nan::SetPrototypeMethod(tpl, "seek", NodeSeek);
566
+
567
+ /**
568
+ * @brief Pausing and resuming
569
+ */
570
+ Nan::SetPrototypeMethod(tpl, "pause", NodePause);
571
+ Nan::SetPrototypeMethod(tpl, "resume", NodeResume);
572
+
573
+ /*
574
+ * @brief Methods to do with partition assignment / rebalancing
575
+ */
576
+
577
+ Nan::SetPrototypeMethod(tpl, "committed", NodeCommitted);
578
+ Nan::SetPrototypeMethod(tpl, "position", NodePosition);
579
+ Nan::SetPrototypeMethod(tpl, "assign", NodeAssign);
580
+ Nan::SetPrototypeMethod(tpl, "unassign", NodeUnassign);
581
+ Nan::SetPrototypeMethod(tpl, "incrementalAssign", NodeIncrementalAssign);
582
+ Nan::SetPrototypeMethod(tpl, "incrementalUnassign", NodeIncrementalUnassign);
583
+ Nan::SetPrototypeMethod(tpl, "assignments", NodeAssignments);
584
+ Nan::SetPrototypeMethod(tpl, "assignmentLost", NodeAssignmentLost);
585
+ Nan::SetPrototypeMethod(tpl, "rebalanceProtocol", NodeRebalanceProtocol);
586
+
587
+ Nan::SetPrototypeMethod(tpl, "commit", NodeCommit);
588
+ Nan::SetPrototypeMethod(tpl, "commitSync", NodeCommitSync);
589
+ Nan::SetPrototypeMethod(tpl, "commitCb", NodeCommitCb);
590
+ Nan::SetPrototypeMethod(tpl, "offsetsStore", NodeOffsetsStore);
591
+ Nan::SetPrototypeMethod(tpl, "offsetsStoreSingle", NodeOffsetsStoreSingle);
592
+
593
+ constructor.Reset((tpl->GetFunction(Nan::GetCurrentContext()))
594
+ .ToLocalChecked());
595
+ Nan::Set(exports, Nan::New("KafkaConsumer").ToLocalChecked(),
596
+ (tpl->GetFunction(Nan::GetCurrentContext())).ToLocalChecked());
597
+ }
598
+
599
+ void KafkaConsumer::New(const Nan::FunctionCallbackInfo<v8::Value>& info) {
600
+ if (!info.IsConstructCall()) {
601
+ return Nan::ThrowError("non-constructor invocation not supported");
602
+ }
603
+
604
+ if (info.Length() < 2) {
605
+ return Nan::ThrowError("You must supply global and topic configuration");
606
+ }
607
+
608
+ if (!info[0]->IsObject()) {
609
+ return Nan::ThrowError("Global configuration data must be specified");
610
+ }
611
+
612
+ std::string errstr;
613
+
614
+ Conf* gconfig =
615
+ Conf::create(RdKafka::Conf::CONF_GLOBAL,
616
+ (info[0]->ToObject(Nan::GetCurrentContext())).ToLocalChecked(), errstr);
617
+
618
+ if (!gconfig) {
619
+ return Nan::ThrowError(errstr.c_str());
620
+ }
621
+
622
+ // If tconfig isn't set, then just let us pick properties from gconf.
623
+ Conf* tconfig = nullptr;
624
+ if (info[1]->IsObject()) {
625
+ tconfig = Conf::create(RdKafka::Conf::CONF_TOPIC,
626
+ (info[1]->ToObject(Nan::GetCurrentContext())).ToLocalChecked(), errstr);
627
+
628
+ if (!tconfig) {
629
+ delete gconfig;
630
+ return Nan::ThrowError(errstr.c_str());
631
+ }
632
+ }
633
+
634
+ // TODO: fix this - this memory is leaked.
635
+ KafkaConsumer* consumer = new KafkaConsumer(gconfig, tconfig);
636
+
637
+ // Wrap it
638
+ consumer->Wrap(info.This());
639
+
640
+ // Then there is some weird initialization that happens
641
+ // basically it sets the configuration data
642
+ // we don't need to do that because we lazy load it
643
+
644
+ info.GetReturnValue().Set(info.This());
645
+ }
646
+
647
+ v8::Local<v8::Object> KafkaConsumer::NewInstance(v8::Local<v8::Value> arg) {
648
+ Nan::EscapableHandleScope scope;
649
+
650
+ const unsigned argc = 1;
651
+
652
+ v8::Local<v8::Value> argv[argc] = { arg };
653
+ v8::Local<v8::Function> cons = Nan::New<v8::Function>(constructor);
654
+ v8::Local<v8::Object> instance =
655
+ Nan::NewInstance(cons, argc, argv).ToLocalChecked();
656
+
657
+ return scope.Escape(instance);
658
+ }
659
+
660
+ /* Node exposed methods */
661
+
662
+ NAN_METHOD(KafkaConsumer::NodeCommitted) {
663
+ Nan::HandleScope scope;
664
+
665
+ if (info.Length() < 3 || !info[0]->IsArray()) {
666
+ // Just throw an exception
667
+ return Nan::ThrowError("Need to specify an array of topic partitions");
668
+ }
669
+
670
+ std::vector<RdKafka::TopicPartition *> toppars =
671
+ Conversion::TopicPartition::FromV8Array(info[0].As<v8::Array>());
672
+
673
+ int timeout_ms;
674
+ Nan::Maybe<uint32_t> maybeTimeout =
675
+ Nan::To<uint32_t>(info[1].As<v8::Number>());
676
+
677
+ if (maybeTimeout.IsNothing()) {
678
+ timeout_ms = 1000;
679
+ } else {
680
+ timeout_ms = static_cast<int>(maybeTimeout.FromJust());
681
+ }
682
+
683
+ v8::Local<v8::Function> cb = info[2].As<v8::Function>();
684
+ Nan::Callback *callback = new Nan::Callback(cb);
685
+
686
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
687
+
688
+ Nan::AsyncQueueWorker(
689
+ new Workers::KafkaConsumerCommitted(callback, consumer,
690
+ toppars, timeout_ms));
691
+
692
+ info.GetReturnValue().Set(Nan::Null());
693
+ }
694
+
695
+ NAN_METHOD(KafkaConsumer::NodeSubscription) {
696
+ Nan::HandleScope scope;
697
+
698
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
699
+
700
+ Baton b = consumer->Subscription();
701
+
702
+ if (b.err() != RdKafka::ErrorCode::ERR_NO_ERROR) {
703
+ // Let the JS library throw if we need to so the error can be more rich
704
+ int error_code = static_cast<int>(b.err());
705
+ return info.GetReturnValue().Set(Nan::New<v8::Number>(error_code));
706
+ }
707
+
708
+ std::vector<std::string> * topics = b.data<std::vector<std::string>*>();
709
+
710
+ info.GetReturnValue().Set(Conversion::Util::ToV8Array(*topics));
711
+
712
+ delete topics;
713
+ }
714
+
715
+ NAN_METHOD(KafkaConsumer::NodePosition) {
716
+ Nan::HandleScope scope;
717
+
718
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
719
+
720
+ if (info.Length() < 1 || !info[0]->IsArray()) {
721
+ // Just throw an exception
722
+ return Nan::ThrowError("Need to specify an array of topic partitions");
723
+ }
724
+
725
+ std::vector<RdKafka::TopicPartition *> toppars =
726
+ Conversion::TopicPartition::FromV8Array(info[0].As<v8::Array>());
727
+
728
+ Baton b = consumer->Position(toppars);
729
+
730
+ if (b.err() != RdKafka::ErrorCode::ERR_NO_ERROR) {
731
+ // Let the JS library throw if we need to so the error can be more rich
732
+ int error_code = static_cast<int>(b.err());
733
+ return info.GetReturnValue().Set(Nan::New<v8::Number>(error_code));
734
+ }
735
+
736
+ info.GetReturnValue().Set(
737
+ Conversion::TopicPartition::ToV8Array(toppars));
738
+
739
+ // Delete the underlying topic partitions
740
+ RdKafka::TopicPartition::destroy(toppars);
741
+ }
742
+
743
+ NAN_METHOD(KafkaConsumer::NodeAssignments) {
744
+ Nan::HandleScope scope;
745
+
746
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
747
+
748
+ Baton b = consumer->RefreshAssignments();
749
+
750
+ if (b.err() != RdKafka::ERR_NO_ERROR) {
751
+ // Let the JS library throw if we need to so the error can be more rich
752
+ int error_code = static_cast<int>(b.err());
753
+ return info.GetReturnValue().Set(Nan::New<v8::Number>(error_code));
754
+ }
755
+
756
+ info.GetReturnValue().Set(
757
+ Conversion::TopicPartition::ToV8Array(consumer->m_partitions));
758
+ }
759
+
760
+ NAN_METHOD(KafkaConsumer::NodeAssignmentLost) {
761
+ Nan::HandleScope scope;
762
+
763
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
764
+
765
+ Baton b = consumer->AssignmentLost();
766
+
767
+ bool lost = b.data<bool>();
768
+ info.GetReturnValue().Set(Nan::New<v8::Boolean>(lost));
769
+ }
770
+
771
+ NAN_METHOD(KafkaConsumer::NodeRebalanceProtocol) {
772
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
773
+ std::string protocol = consumer->RebalanceProtocol();
774
+ info.GetReturnValue().Set(Nan::New<v8::String>(protocol).ToLocalChecked());
775
+ }
776
+
777
+ NAN_METHOD(KafkaConsumer::NodeAssign) {
778
+ Nan::HandleScope scope;
779
+
780
+ if (info.Length() < 1 || !info[0]->IsArray()) {
781
+ // Just throw an exception
782
+ return Nan::ThrowError("Need to specify an array of partitions");
783
+ }
784
+
785
+ v8::Local<v8::Array> partitions = info[0].As<v8::Array>();
786
+ std::vector<RdKafka::TopicPartition*> topic_partitions;
787
+
788
+ for (unsigned int i = 0; i < partitions->Length(); ++i) {
789
+ v8::Local<v8::Value> partition_obj_value;
790
+ if (!(
791
+ Nan::Get(partitions, i).ToLocal(&partition_obj_value) &&
792
+ partition_obj_value->IsObject())) {
793
+ Nan::ThrowError("Must pass topic-partition objects");
794
+ }
795
+
796
+ v8::Local<v8::Object> partition_obj = partition_obj_value.As<v8::Object>();
797
+
798
+ // Got the object
799
+ int64_t partition = GetParameter<int64_t>(partition_obj, "partition", -1);
800
+ std::string topic = GetParameter<std::string>(partition_obj, "topic", "");
801
+
802
+ if (!topic.empty()) {
803
+ RdKafka::TopicPartition* part;
804
+
805
+ if (partition < 0) {
806
+ part = Connection::GetPartition(topic);
807
+ } else {
808
+ part = Connection::GetPartition(topic, partition);
809
+ }
810
+
811
+ // Set the default value to offset invalid. If provided, we will not set
812
+ // the offset.
813
+ int64_t offset = GetParameter<int64_t>(
814
+ partition_obj, "offset", RdKafka::Topic::OFFSET_INVALID);
815
+ if (offset != RdKafka::Topic::OFFSET_INVALID) {
816
+ part->set_offset(offset);
817
+ }
818
+
819
+ topic_partitions.push_back(part);
820
+ }
821
+ }
822
+
823
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
824
+
825
+ // Hand over the partitions to the consumer.
826
+ Baton b = consumer->Assign(topic_partitions);
827
+
828
+ if (b.err() != RdKafka::ERR_NO_ERROR) {
829
+ Nan::ThrowError(RdKafka::err2str(b.err()).c_str());
830
+ }
831
+
832
+ info.GetReturnValue().Set(Nan::True());
833
+ }
834
+
835
+ NAN_METHOD(KafkaConsumer::NodeUnassign) {
836
+ Nan::HandleScope scope;
837
+
838
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
839
+
840
+
841
+ if (!consumer->IsClosing() && !consumer->IsConnected()) {
842
+ Nan::ThrowError("KafkaConsumer is disconnected");
843
+ return;
844
+ }
845
+
846
+ Baton b = consumer->Unassign();
847
+
848
+ if (b.err() != RdKafka::ERR_NO_ERROR) {
849
+ Nan::ThrowError(RdKafka::err2str(b.err()).c_str());
850
+ }
851
+
852
+ info.GetReturnValue().Set(Nan::True());
853
+ }
854
+
855
+ NAN_METHOD(KafkaConsumer::NodeIncrementalAssign) {
856
+ Nan::HandleScope scope;
857
+
858
+ if (info.Length() < 1 || !info[0]->IsArray()) {
859
+ // Just throw an exception
860
+ return Nan::ThrowError("Need to specify an array of partitions");
861
+ }
862
+
863
+ v8::Local<v8::Array> partitions = info[0].As<v8::Array>();
864
+ std::vector<RdKafka::TopicPartition*> topic_partitions;
865
+
866
+ for (unsigned int i = 0; i < partitions->Length(); ++i) {
867
+ v8::Local<v8::Value> partition_obj_value;
868
+ if (!(
869
+ Nan::Get(partitions, i).ToLocal(&partition_obj_value) &&
870
+ partition_obj_value->IsObject())) {
871
+ Nan::ThrowError("Must pass topic-partition objects");
872
+ }
873
+
874
+ v8::Local<v8::Object> partition_obj = partition_obj_value.As<v8::Object>();
875
+
876
+ // Got the object
877
+ int64_t partition = GetParameter<int64_t>(partition_obj, "partition", -1);
878
+ std::string topic = GetParameter<std::string>(partition_obj, "topic", "");
879
+
880
+ if (!topic.empty()) {
881
+ RdKafka::TopicPartition* part;
882
+
883
+ if (partition < 0) {
884
+ part = Connection::GetPartition(topic);
885
+ } else {
886
+ part = Connection::GetPartition(topic, partition);
887
+ }
888
+
889
+ // Set the default value to offset invalid. If provided, we will not set
890
+ // the offset.
891
+ int64_t offset = GetParameter<int64_t>(
892
+ partition_obj, "offset", RdKafka::Topic::OFFSET_INVALID);
893
+ if (offset != RdKafka::Topic::OFFSET_INVALID) {
894
+ part->set_offset(offset);
895
+ }
896
+
897
+ topic_partitions.push_back(part);
898
+ }
899
+ }
900
+
901
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
902
+
903
+ // Hand over the partitions to the consumer.
904
+ Baton b = consumer->IncrementalAssign(topic_partitions);
905
+
906
+ if (b.err() != RdKafka::ERR_NO_ERROR) {
907
+ v8::Local<v8::Value> errorObject = b.ToObject();
908
+ Nan::ThrowError(errorObject);
909
+ }
910
+
911
+ info.GetReturnValue().Set(Nan::True());
912
+ }
913
+
914
+ NAN_METHOD(KafkaConsumer::NodeIncrementalUnassign) {
915
+ Nan::HandleScope scope;
916
+
917
+ if (info.Length() < 1 || !info[0]->IsArray()) {
918
+ // Just throw an exception
919
+ return Nan::ThrowError("Need to specify an array of partitions");
920
+ }
921
+
922
+ v8::Local<v8::Array> partitions = info[0].As<v8::Array>();
923
+ std::vector<RdKafka::TopicPartition*> topic_partitions;
924
+
925
+ for (unsigned int i = 0; i < partitions->Length(); ++i) {
926
+ v8::Local<v8::Value> partition_obj_value;
927
+ if (!(
928
+ Nan::Get(partitions, i).ToLocal(&partition_obj_value) &&
929
+ partition_obj_value->IsObject())) {
930
+ Nan::ThrowError("Must pass topic-partition objects");
931
+ }
932
+
933
+ v8::Local<v8::Object> partition_obj = partition_obj_value.As<v8::Object>();
934
+
935
+ // Got the object
936
+ int64_t partition = GetParameter<int64_t>(partition_obj, "partition", -1);
937
+ std::string topic = GetParameter<std::string>(partition_obj, "topic", "");
938
+
939
+ if (!topic.empty()) {
940
+ RdKafka::TopicPartition* part;
941
+
942
+ if (partition < 0) {
943
+ part = Connection::GetPartition(topic);
944
+ } else {
945
+ part = Connection::GetPartition(topic, partition);
946
+ }
947
+
948
+ // Set the default value to offset invalid. If provided, we will not set
949
+ // the offset.
950
+ int64_t offset = GetParameter<int64_t>(
951
+ partition_obj, "offset", RdKafka::Topic::OFFSET_INVALID);
952
+ if (offset != RdKafka::Topic::OFFSET_INVALID) {
953
+ part->set_offset(offset);
954
+ }
955
+
956
+ topic_partitions.push_back(part);
957
+ }
958
+ }
959
+
960
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
961
+
962
+ // Hand over the partitions to the consumer.
963
+ Baton b = consumer->IncrementalUnassign(topic_partitions);
964
+
965
+ if (b.err() != RdKafka::ERR_NO_ERROR) {
966
+ v8::Local<v8::Value> errorObject = b.ToObject();
967
+ Nan::ThrowError(errorObject);
968
+ }
969
+
970
+ info.GetReturnValue().Set(Nan::True());
971
+ }
972
+
973
+
974
+ NAN_METHOD(KafkaConsumer::NodeUnsubscribe) {
975
+ Nan::HandleScope scope;
976
+
977
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
978
+
979
+ Baton b = consumer->Unsubscribe();
980
+
981
+ info.GetReturnValue().Set(Nan::New<v8::Number>(static_cast<int>(b.err())));
982
+ }
983
+
984
+ NAN_METHOD(KafkaConsumer::NodeCommit) {
985
+ Nan::HandleScope scope;
986
+ int error_code;
987
+
988
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
989
+
990
+ if (!consumer->IsConnected()) {
991
+ Nan::ThrowError("KafkaConsumer is disconnected");
992
+ return;
993
+ }
994
+
995
+ if (info[0]->IsNull() || info[0]->IsUndefined()) {
996
+ Baton b = consumer->Commit();
997
+ error_code = static_cast<int>(b.err());
998
+ } else if (info[0]->IsArray()) {
999
+ std::vector<RdKafka::TopicPartition *> toppars =
1000
+ Conversion::TopicPartition::FromV8Array(info[0].As<v8::Array>());
1001
+
1002
+ Baton b = consumer->Commit(toppars);
1003
+ error_code = static_cast<int>(b.err());
1004
+
1005
+ RdKafka::TopicPartition::destroy(toppars);
1006
+ } else if (info[0]->IsObject()) {
1007
+ RdKafka::TopicPartition * toppar =
1008
+ Conversion::TopicPartition::FromV8Object(info[0].As<v8::Object>());
1009
+
1010
+ if (toppar == NULL) {
1011
+ Nan::ThrowError("Invalid topic partition provided");
1012
+ return;
1013
+ }
1014
+
1015
+ Baton b = consumer->Commit(toppar);
1016
+ error_code = static_cast<int>(b.err());
1017
+
1018
+ delete toppar;
1019
+ } else {
1020
+ Nan::ThrowError("First parameter must be an object or an array");
1021
+ return;
1022
+ }
1023
+
1024
+ info.GetReturnValue().Set(Nan::New<v8::Number>(error_code));
1025
+ }
1026
+
1027
+ NAN_METHOD(KafkaConsumer::NodeCommitSync) {
1028
+ Nan::HandleScope scope;
1029
+ int error_code;
1030
+
1031
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
1032
+
1033
+ if (!consumer->IsConnected()) {
1034
+ Nan::ThrowError("KafkaConsumer is disconnected");
1035
+ return;
1036
+ }
1037
+
1038
+ if (info[0]->IsNull() || info[0]->IsUndefined()) {
1039
+ Baton b = consumer->CommitSync();
1040
+ error_code = static_cast<int>(b.err());
1041
+ } else if (info[0]->IsArray()) {
1042
+ std::vector<RdKafka::TopicPartition *> toppars =
1043
+ Conversion::TopicPartition::FromV8Array(info[0].As<v8::Array>());
1044
+
1045
+ Baton b = consumer->CommitSync(toppars);
1046
+ error_code = static_cast<int>(b.err());
1047
+
1048
+ RdKafka::TopicPartition::destroy(toppars);
1049
+ } else if (info[0]->IsObject()) {
1050
+ RdKafka::TopicPartition * toppar =
1051
+ Conversion::TopicPartition::FromV8Object(info[0].As<v8::Object>());
1052
+
1053
+ if (toppar == NULL) {
1054
+ Nan::ThrowError("Invalid topic partition provided");
1055
+ return;
1056
+ }
1057
+
1058
+ Baton b = consumer->CommitSync(toppar);
1059
+ error_code = static_cast<int>(b.err());
1060
+
1061
+ delete toppar;
1062
+ } else {
1063
+ Nan::ThrowError("First parameter must be an object or an array");
1064
+ return;
1065
+ }
1066
+
1067
+ info.GetReturnValue().Set(Nan::New<v8::Number>(error_code));
1068
+ }
1069
+
1070
+ NAN_METHOD(KafkaConsumer::NodeCommitCb) {
1071
+ Nan::HandleScope scope;
1072
+ int error_code;
1073
+ std::optional<std::vector<RdKafka::TopicPartition *>> toppars = std::nullopt;
1074
+ Nan::Callback *callback;
1075
+
1076
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
1077
+
1078
+ if (!consumer->IsConnected()) {
1079
+ Nan::ThrowError("KafkaConsumer is disconnected");
1080
+ return;
1081
+ }
1082
+
1083
+ if (info.Length() != 2) {
1084
+ Nan::ThrowError("Two arguments are required");
1085
+ return;
1086
+ }
1087
+
1088
+ if (!(
1089
+ (info[0]->IsArray() || info[0]->IsNull()) &&
1090
+ info[1]->IsFunction())) {
1091
+ Nan::ThrowError(
1092
+ "First argument should be an array or null and second one a callback");
1093
+ return;
1094
+ }
1095
+
1096
+ if (info[0]->IsArray()) {
1097
+ toppars =
1098
+ Conversion::TopicPartition::FromV8Array(info[0].As<v8::Array>());
1099
+ }
1100
+ callback = new Nan::Callback(info[1].As<v8::Function>());
1101
+
1102
+ Nan::AsyncQueueWorker(
1103
+ new Workers::KafkaConsumerCommitCb(callback, consumer,
1104
+ toppars));
1105
+
1106
+ info.GetReturnValue().Set(Nan::Null());
1107
+ }
1108
+
1109
+ NAN_METHOD(KafkaConsumer::NodeSubscribe) {
1110
+ Nan::HandleScope scope;
1111
+
1112
+ if (info.Length() < 1 || !info[0]->IsArray()) {
1113
+ // Just throw an exception
1114
+ return Nan::ThrowError("First parameter must be an array");
1115
+ }
1116
+
1117
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
1118
+
1119
+ v8::Local<v8::Array> topicsArray = info[0].As<v8::Array>();
1120
+ std::vector<std::string> topics =
1121
+ Conversion::Util::ToStringVector(topicsArray);
1122
+
1123
+ Baton b = consumer->Subscribe(topics);
1124
+
1125
+ int error_code = static_cast<int>(b.err());
1126
+ info.GetReturnValue().Set(Nan::New<v8::Number>(error_code));
1127
+ }
1128
+
1129
+ NAN_METHOD(KafkaConsumer::NodeSeek) {
1130
+ Nan::HandleScope scope;
1131
+
1132
+ // If number of parameters is less than 3 (need topic partition, timeout,
1133
+ // and callback), we can't call this thing
1134
+ if (info.Length() < 3) {
1135
+ return Nan::ThrowError("Must provide a topic partition, timeout, and callback"); // NOLINT
1136
+ }
1137
+
1138
+ if (!info[0]->IsObject()) {
1139
+ return Nan::ThrowError("Topic partition must be an object");
1140
+ }
1141
+
1142
+ if (!info[1]->IsNumber() && !info[1]->IsNull()) {
1143
+ return Nan::ThrowError("Timeout must be a number.");
1144
+ }
1145
+
1146
+ if (!info[2]->IsFunction()) {
1147
+ return Nan::ThrowError("Callback must be a function");
1148
+ }
1149
+
1150
+ int timeout_ms;
1151
+ Nan::Maybe<uint32_t> maybeTimeout =
1152
+ Nan::To<uint32_t>(info[1].As<v8::Number>());
1153
+
1154
+ if (maybeTimeout.IsNothing()) {
1155
+ timeout_ms = 1000;
1156
+ } else {
1157
+ timeout_ms = static_cast<int>(maybeTimeout.FromJust());
1158
+ // Do not allow timeouts of less than 10. Providing 0 causes segfaults
1159
+ // because it makes it asynchronous.
1160
+ if (timeout_ms < 10) {
1161
+ timeout_ms = 10;
1162
+ }
1163
+ }
1164
+
1165
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
1166
+
1167
+ const RdKafka::TopicPartition * toppar =
1168
+ Conversion::TopicPartition::FromV8Object(info[0].As<v8::Object>());
1169
+
1170
+ if (!toppar) {
1171
+ return Nan::ThrowError("Invalid topic partition provided");
1172
+ }
1173
+
1174
+ Nan::Callback *callback = new Nan::Callback(info[2].As<v8::Function>());
1175
+ Nan::AsyncQueueWorker(
1176
+ new Workers::KafkaConsumerSeek(callback, consumer, toppar, timeout_ms));
1177
+
1178
+ info.GetReturnValue().Set(Nan::Null());
1179
+ }
1180
+
1181
+ NAN_METHOD(KafkaConsumer::NodeOffsetsStore) {
1182
+ Nan::HandleScope scope;
1183
+
1184
+ // If number of parameters is less than 3 (need topic partition, timeout,
1185
+ // and callback), we can't call this thing
1186
+ if (info.Length() < 1) {
1187
+ return Nan::ThrowError("Must provide a list of topic partitions");
1188
+ }
1189
+
1190
+ if (!info[0]->IsArray()) {
1191
+ return Nan::ThrowError("Topic partition must be an array of objects");
1192
+ }
1193
+
1194
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
1195
+
1196
+ std::vector<RdKafka::TopicPartition *> toppars =
1197
+ Conversion::TopicPartition::FromV8Array(info[0].As<v8::Array>());
1198
+
1199
+ Baton b = consumer->OffsetsStore(toppars);
1200
+ RdKafka::TopicPartition::destroy(toppars);
1201
+
1202
+ int error_code = static_cast<int>(b.err());
1203
+ info.GetReturnValue().Set(Nan::New<v8::Number>(error_code));
1204
+ }
1205
+
1206
+ NAN_METHOD(KafkaConsumer::NodeOffsetsStoreSingle) {
1207
+ Nan::HandleScope scope;
1208
+
1209
+ // If number of parameters is less than 3 (need topic partition, partition,
1210
+ // offset, and leader epoch), we can't call this.
1211
+ if (info.Length() < 4) {
1212
+ return Nan::ThrowError(
1213
+ "Must provide topic, partition, offset and leaderEpoch");
1214
+ }
1215
+
1216
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
1217
+
1218
+ // Get string pointer for the topic name
1219
+ Nan::Utf8String topicUTF8(Nan::To<v8::String>(info[0]).ToLocalChecked());
1220
+ const std::string& topic_name(*topicUTF8);
1221
+
1222
+ int64_t partition = Nan::To<int64_t>(info[1]).FromJust();
1223
+ int64_t offset = Nan::To<int64_t>(info[2]).FromJust();
1224
+ int64_t leader_epoch = Nan::To<int64_t>(info[3]).FromJust();
1225
+
1226
+ RdKafka::TopicPartition* toppar =
1227
+ RdKafka::TopicPartition::create(topic_name, partition, offset);
1228
+ toppar->set_leader_epoch(leader_epoch);
1229
+ std::vector<RdKafka::TopicPartition*> toppars = {toppar};
1230
+
1231
+ Baton b = consumer->OffsetsStore(toppars);
1232
+
1233
+ delete toppar;
1234
+
1235
+ int error_code = static_cast<int>(b.err());
1236
+ info.GetReturnValue().Set(Nan::New<v8::Number>(error_code));
1237
+ }
1238
+
1239
+ NAN_METHOD(KafkaConsumer::NodePause) {
1240
+ Nan::HandleScope scope;
1241
+
1242
+ // If number of parameters is less than 3 (need topic partition, timeout,
1243
+ // and callback), we can't call this thing
1244
+ if (info.Length() < 1) {
1245
+ return Nan::ThrowError("Must provide a list of topic partitions");
1246
+ }
1247
+
1248
+ if (!info[0]->IsArray()) {
1249
+ return Nan::ThrowError("Topic partition must be an array of objects");
1250
+ }
1251
+
1252
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
1253
+
1254
+ std::vector<RdKafka::TopicPartition *> toppars =
1255
+ Conversion::TopicPartition::FromV8Array(info[0].As<v8::Array>());
1256
+
1257
+ Baton b = consumer->Pause(toppars);
1258
+ RdKafka::TopicPartition::destroy(toppars);
1259
+
1260
+ #if 0
1261
+ // Now iterate through and delete these toppars
1262
+ for (std::vector<RdKafka::TopicPartition *>::const_iterator it = toppars.begin(); // NOLINT
1263
+ it != toppars.end(); it++) {
1264
+ RdKafka::TopicPartition* toppar = *it;
1265
+ if (toppar->err() != RdKafka::ERR_NO_ERROR) {
1266
+ // Need to somehow transmit this information.
1267
+ // @TODO(webmakersteve)
1268
+ }
1269
+ delete toppar;
1270
+ }
1271
+ #endif
1272
+
1273
+ int error_code = static_cast<int>(b.err());
1274
+ info.GetReturnValue().Set(Nan::New<v8::Number>(error_code));
1275
+ }
1276
+
1277
+ NAN_METHOD(KafkaConsumer::NodeResume) {
1278
+ Nan::HandleScope scope;
1279
+
1280
+ // If number of parameters is less than 3 (need topic partition, timeout,
1281
+ // and callback), we can't call this thing
1282
+ if (info.Length() < 1) {
1283
+ return Nan::ThrowError("Must provide a list of topic partitions"); // NOLINT
1284
+ }
1285
+
1286
+ if (!info[0]->IsArray()) {
1287
+ return Nan::ThrowError("Topic partition must be an array of objects");
1288
+ }
1289
+
1290
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
1291
+
1292
+ std::vector<RdKafka::TopicPartition *> toppars =
1293
+ Conversion::TopicPartition::FromV8Array(info[0].As<v8::Array>());
1294
+
1295
+ Baton b = consumer->Resume(toppars);
1296
+
1297
+ // Now iterate through and delete these toppars
1298
+ for (std::vector<RdKafka::TopicPartition *>::const_iterator it = toppars.begin(); // NOLINT
1299
+ it != toppars.end(); it++) {
1300
+ RdKafka::TopicPartition* toppar = *it;
1301
+ if (toppar->err() != RdKafka::ERR_NO_ERROR) {
1302
+ // Need to somehow transmit this information.
1303
+ // @TODO(webmakersteve)
1304
+ }
1305
+ delete toppar;
1306
+ }
1307
+
1308
+ int error_code = static_cast<int>(b.err());
1309
+ info.GetReturnValue().Set(Nan::New<v8::Number>(error_code));
1310
+ }
1311
+
1312
+ NAN_METHOD(KafkaConsumer::NodeConsumeLoop) {
1313
+ Nan::HandleScope scope;
1314
+
1315
+ if (info.Length() < 3) {
1316
+ // Just throw an exception
1317
+ return Nan::ThrowError("Invalid number of parameters");
1318
+ }
1319
+
1320
+ if (!info[0]->IsNumber()) {
1321
+ return Nan::ThrowError("Need to specify a timeout");
1322
+ }
1323
+
1324
+ if (!info[1]->IsNumber()) {
1325
+ return Nan::ThrowError("Need to specify a sleep delay");
1326
+ }
1327
+
1328
+ if (!info[2]->IsFunction()) {
1329
+ return Nan::ThrowError("Need to specify a callback");
1330
+ }
1331
+
1332
+ int timeout_ms;
1333
+ Nan::Maybe<uint32_t> maybeTimeout =
1334
+ Nan::To<uint32_t>(info[0].As<v8::Number>());
1335
+
1336
+ if (maybeTimeout.IsNothing()) {
1337
+ timeout_ms = 1000;
1338
+ } else {
1339
+ timeout_ms = static_cast<int>(maybeTimeout.FromJust());
1340
+ }
1341
+
1342
+ int timeout_sleep_delay_ms;
1343
+ Nan::Maybe<uint32_t> maybeSleep =
1344
+ Nan::To<uint32_t>(info[1].As<v8::Number>());
1345
+
1346
+ if (maybeSleep.IsNothing()) {
1347
+ timeout_sleep_delay_ms = 500;
1348
+ } else {
1349
+ timeout_sleep_delay_ms = static_cast<int>(maybeSleep.FromJust());
1350
+ }
1351
+
1352
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
1353
+
1354
+ if (consumer->m_consume_loop != nullptr) {
1355
+ return Nan::ThrowError("Consume was already called");
1356
+ }
1357
+
1358
+ if (!consumer->IsConnected()) {
1359
+ return Nan::ThrowError("Connect must be called before consume");
1360
+ }
1361
+
1362
+ v8::Local<v8::Function> cb = info[2].As<v8::Function>();
1363
+
1364
+ Nan::Callback *callback = new Nan::Callback(cb);
1365
+
1366
+ consumer->m_consume_loop =
1367
+ new Workers::KafkaConsumerConsumeLoop(callback, consumer, timeout_ms, timeout_sleep_delay_ms); // NOLINT
1368
+
1369
+ info.GetReturnValue().Set(Nan::Null());
1370
+ }
1371
+
1372
+ NAN_METHOD(KafkaConsumer::NodeConsume) {
1373
+ Nan::HandleScope scope;
1374
+
1375
+ if (info.Length() < 2) {
1376
+ // Just throw an exception
1377
+ return Nan::ThrowError("Invalid number of parameters");
1378
+ }
1379
+
1380
+ int timeout_ms;
1381
+ Nan::Maybe<uint32_t> maybeTimeout =
1382
+ Nan::To<uint32_t>(info[0].As<v8::Number>());
1383
+
1384
+ if (maybeTimeout.IsNothing()) {
1385
+ timeout_ms = 1000;
1386
+ } else {
1387
+ timeout_ms = static_cast<int>(maybeTimeout.FromJust());
1388
+ }
1389
+
1390
+ if (info[1]->IsNumber()) {
1391
+ if (!info[2]->IsBoolean()) {
1392
+ return Nan::ThrowError("Need to specify a boolean");
1393
+ }
1394
+
1395
+ if (!info[3]->IsFunction()) {
1396
+ return Nan::ThrowError("Need to specify a callback");
1397
+ }
1398
+
1399
+ v8::Local<v8::Number> numMessagesNumber = info[1].As<v8::Number>();
1400
+ Nan::Maybe<uint32_t> numMessagesMaybe = Nan::To<uint32_t>(numMessagesNumber); // NOLINT
1401
+
1402
+ uint32_t numMessages;
1403
+ if (numMessagesMaybe.IsNothing()) {
1404
+ return Nan::ThrowError("Parameter must be a number over 0");
1405
+ } else {
1406
+ numMessages = numMessagesMaybe.FromJust();
1407
+ }
1408
+
1409
+ v8::Local<v8::Boolean> isTimeoutOnlyForFirstMessageBoolean = info[2].As<v8::Boolean>(); // NOLINT
1410
+ Nan::Maybe<bool> isTimeoutOnlyForFirstMessageMaybe =
1411
+ Nan::To<bool>(isTimeoutOnlyForFirstMessageBoolean);
1412
+
1413
+ bool isTimeoutOnlyForFirstMessage;
1414
+ if (isTimeoutOnlyForFirstMessageMaybe.IsNothing()) {
1415
+ return Nan::ThrowError("Parameter must be a boolean");
1416
+ } else {
1417
+ isTimeoutOnlyForFirstMessage = isTimeoutOnlyForFirstMessageMaybe.FromJust(); // NOLINT
1418
+ }
1419
+
1420
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
1421
+
1422
+ v8::Local<v8::Function> cb = info[3].As<v8::Function>();
1423
+ Nan::Callback *callback = new Nan::Callback(cb);
1424
+ Nan::AsyncQueueWorker(
1425
+ new Workers::KafkaConsumerConsumeNum(callback, consumer, numMessages, timeout_ms, isTimeoutOnlyForFirstMessage)); // NOLINT
1426
+
1427
+ } else {
1428
+ if (!info[1]->IsFunction()) {
1429
+ return Nan::ThrowError("Need to specify a callback");
1430
+ }
1431
+
1432
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
1433
+
1434
+ v8::Local<v8::Function> cb = info[1].As<v8::Function>();
1435
+ Nan::Callback *callback = new Nan::Callback(cb);
1436
+ Nan::AsyncQueueWorker(
1437
+ new Workers::KafkaConsumerConsume(callback, consumer, timeout_ms));
1438
+ }
1439
+
1440
+ info.GetReturnValue().Set(Nan::Null());
1441
+ }
1442
+
1443
+ NAN_METHOD(KafkaConsumer::NodeConnect) {
1444
+ Nan::HandleScope scope;
1445
+
1446
+ if (info.Length() < 1 || !info[0]->IsFunction()) {
1447
+ // Just throw an exception
1448
+ return Nan::ThrowError("Need to specify a callback");
1449
+ }
1450
+
1451
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
1452
+
1453
+ // Activate the dispatchers before the connection, as some callbacks may run
1454
+ // on the background thread.
1455
+ // We will deactivate them if the connection fails.
1456
+ consumer->ActivateDispatchers();
1457
+
1458
+ Nan::Callback *callback = new Nan::Callback(info[0].As<v8::Function>());
1459
+ Nan::AsyncQueueWorker(new Workers::KafkaConsumerConnect(callback, consumer));
1460
+
1461
+ info.GetReturnValue().Set(Nan::Null());
1462
+ }
1463
+
1464
+ NAN_METHOD(KafkaConsumer::NodeDisconnect) {
1465
+ Nan::HandleScope scope;
1466
+
1467
+ if (info.Length() < 1 || !info[0]->IsFunction()) {
1468
+ // Just throw an exception
1469
+ return Nan::ThrowError("Need to specify a callback");
1470
+ }
1471
+
1472
+ v8::Local<v8::Function> cb = info[0].As<v8::Function>();
1473
+ Nan::Callback *callback = new Nan::Callback(cb);
1474
+ KafkaConsumer* consumer = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
1475
+
1476
+ Workers::KafkaConsumerConsumeLoop* consumeLoop =
1477
+ (Workers::KafkaConsumerConsumeLoop*)consumer->m_consume_loop;
1478
+ if (consumeLoop != nullptr) {
1479
+ // stop the consume loop
1480
+ consumeLoop->Close();
1481
+
1482
+ // cleanup the async worker
1483
+ consumeLoop->WorkComplete();
1484
+ consumeLoop->Destroy();
1485
+
1486
+ consumer->m_consume_loop = nullptr;
1487
+ }
1488
+
1489
+ Nan::AsyncQueueWorker(
1490
+ new Workers::KafkaConsumerDisconnect(callback, consumer));
1491
+ info.GetReturnValue().Set(Nan::Null());
1492
+ }
1493
+
1494
+ NAN_METHOD(KafkaConsumer::NodeGetWatermarkOffsets) {
1495
+ Nan::HandleScope scope;
1496
+
1497
+ KafkaConsumer* obj = ObjectWrap::Unwrap<KafkaConsumer>(info.This());
1498
+
1499
+ if (!info[0]->IsString()) {
1500
+ Nan::ThrowError("1st parameter must be a topic string");;
1501
+ return;
1502
+ }
1503
+
1504
+ if (!info[1]->IsNumber()) {
1505
+ Nan::ThrowError("2nd parameter must be a partition number");
1506
+ return;
1507
+ }
1508
+
1509
+ // Get string pointer for the topic name
1510
+ Nan::Utf8String topicUTF8(Nan::To<v8::String>(info[0]).ToLocalChecked());
1511
+ // The first parameter is the topic
1512
+ std::string topic_name(*topicUTF8);
1513
+
1514
+ // Second parameter is the partition
1515
+ int32_t partition = Nan::To<int32_t>(info[1]).FromJust();
1516
+
1517
+ // Set these ints which will store the return data
1518
+ int64_t low_offset;
1519
+ int64_t high_offset;
1520
+
1521
+ Baton b = obj->GetWatermarkOffsets(
1522
+ topic_name, partition, &low_offset, &high_offset);
1523
+
1524
+ if (b.err() != RdKafka::ERR_NO_ERROR) {
1525
+ // Let the JS library throw if we need to so the error can be more rich
1526
+ int error_code = static_cast<int>(b.err());
1527
+ return info.GetReturnValue().Set(Nan::New<v8::Number>(error_code));
1528
+ } else {
1529
+ v8::Local<v8::Object> offsetsObj = Nan::New<v8::Object>();
1530
+ Nan::Set(offsetsObj, Nan::New<v8::String>("lowOffset").ToLocalChecked(),
1531
+ Nan::New<v8::Number>(low_offset));
1532
+ Nan::Set(offsetsObj, Nan::New<v8::String>("highOffset").ToLocalChecked(),
1533
+ Nan::New<v8::Number>(high_offset));
1534
+
1535
+ return info.GetReturnValue().Set(offsetsObj);
1536
+ }
1537
+ }
1538
+
1539
+ } // namespace NodeKafka