@platformatic/rdkafka 4.0.1 → 4.1.0
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.
- package/README.md +5 -5
- package/bench/seed.sh +0 -0
- package/binding.gyp +8 -1
- package/ci/prepublish.js +0 -1
- package/config.d.ts +126 -10
- package/configure +0 -0
- package/deps/librdkafka/.semaphore/run-all-tests.yml +77 -0
- package/deps/librdkafka/.semaphore/semaphore-integration.yml +250 -0
- package/deps/librdkafka/.semaphore/semaphore.yml +67 -44
- package/deps/librdkafka/.semaphore/verify-linux-packages.yml +41 -0
- package/deps/librdkafka/CHANGELOG.md +471 -1
- package/deps/librdkafka/CONFIGURATION.md +29 -9
- package/deps/librdkafka/INTRODUCTION.md +909 -601
- package/deps/librdkafka/LICENSES.txt +592 -1
- package/deps/librdkafka/Makefile +2 -1
- package/deps/librdkafka/_mkltmpuuWEwa.c +13 -0
- package/deps/librdkafka/configure +0 -0
- package/deps/librdkafka/debian/rules +0 -0
- package/deps/librdkafka/dev-conf.sh +0 -0
- package/deps/librdkafka/examples/consumer.c +18 -8
- package/deps/librdkafka/examples/describe_consumer_groups.c +25 -6
- package/deps/librdkafka/examples/incremental_alter_configs.c +4 -5
- package/deps/librdkafka/examples/kafkatest_verifiable_client.cpp +26 -42
- package/deps/librdkafka/examples/openssl_engine_example.cpp +3 -4
- package/deps/librdkafka/examples/producer.cpp +2 -2
- package/deps/librdkafka/examples/user_scram.c +4 -5
- package/deps/librdkafka/examples/win_ssl_cert_store.cpp +4 -3
- package/deps/librdkafka/lds-gen.py +0 -0
- package/deps/librdkafka/mklove/Makefile.base +0 -0
- package/deps/librdkafka/packaging/RELEASE.md +8 -0
- package/deps/librdkafka/packaging/alpine/build-alpine.sh +0 -0
- package/deps/librdkafka/packaging/cp/README.md +4 -1
- package/deps/librdkafka/packaging/cp/check_features.c +12 -4
- package/deps/librdkafka/packaging/cp/verify-deb.sh +6 -6
- package/deps/librdkafka/packaging/cp/verify-packages.sh +52 -31
- package/deps/librdkafka/packaging/cp/verify-rpm.sh +6 -13
- package/deps/librdkafka/packaging/debian/rules +0 -0
- package/deps/librdkafka/packaging/get_version.py +0 -0
- package/deps/librdkafka/packaging/homebrew/brew-update-pr.sh +0 -0
- package/deps/librdkafka/packaging/mingw-w64/{travis-before-install.sh → export-variables.sh} +0 -7
- package/deps/librdkafka/packaging/mingw-w64/semaphoreci-build.sh +1 -1
- package/deps/librdkafka/packaging/nuget/artifact.py +0 -0
- package/deps/librdkafka/packaging/nuget/cleanup-s3.py +0 -0
- package/deps/librdkafka/packaging/nuget/nuget.sh +0 -0
- package/deps/librdkafka/packaging/nuget/packaging.py +0 -0
- package/deps/librdkafka/packaging/nuget/push-to-nuget.sh +0 -0
- package/deps/librdkafka/packaging/nuget/release.py +0 -0
- package/deps/librdkafka/packaging/nuget/requirements.txt +3 -3
- package/deps/librdkafka/packaging/rpm/mock-on-docker.sh +0 -0
- package/deps/librdkafka/packaging/rpm/tests/run-test.sh +0 -0
- package/deps/librdkafka/packaging/rpm/tests/test-on-docker.sh +0 -0
- package/deps/librdkafka/packaging/tools/build-configurations-checks.sh +3 -1
- package/deps/librdkafka/packaging/tools/build-deb-package.sh +0 -0
- package/deps/librdkafka/packaging/tools/build-debian.sh +0 -0
- package/deps/librdkafka/packaging/tools/build-manylinux.sh +0 -0
- package/deps/librdkafka/packaging/tools/build-release-artifacts.sh +0 -0
- package/deps/librdkafka/packaging/tools/distro-build.sh +0 -0
- package/deps/librdkafka/packaging/tools/gh-release-checksums.py +0 -0
- package/deps/librdkafka/packaging/tools/rdutcoverage.sh +0 -0
- package/deps/librdkafka/packaging/tools/run-in-docker.sh +28 -0
- package/deps/librdkafka/packaging/tools/run-integration-tests.sh +31 -0
- package/deps/librdkafka/packaging/tools/run-style-check.sh +4 -0
- package/deps/librdkafka/packaging/tools/style-format.sh +6 -5
- package/deps/librdkafka/packaging/tools/update_rpcs_max_versions.py +100 -0
- package/deps/librdkafka/service.yml +154 -0
- package/deps/librdkafka/src/generate_proto.sh +0 -0
- package/deps/librdkafka/src/rd.h +145 -2
- package/deps/librdkafka/src/rdaddr.h +6 -7
- package/deps/librdkafka/src/rdatomic.h +15 -11
- package/deps/librdkafka/src/rdavg.h +3 -2
- package/deps/librdkafka/src/rdbase64.c +33 -2
- package/deps/librdkafka/src/rdbase64.h +2 -0
- package/deps/librdkafka/src/rdendian.h +10 -9
- package/deps/librdkafka/src/rdhttp.c +418 -100
- package/deps/librdkafka/src/rdhttp.h +23 -5
- package/deps/librdkafka/src/rdkafka.c +299 -145
- package/deps/librdkafka/src/rdkafka.h +89 -6
- package/deps/librdkafka/src/rdkafka_admin.c +482 -105
- package/deps/librdkafka/src/rdkafka_admin.h +42 -0
- package/deps/librdkafka/src/rdkafka_broker.c +463 -312
- package/deps/librdkafka/src/rdkafka_broker.h +68 -10
- package/deps/librdkafka/src/rdkafka_buf.c +8 -5
- package/deps/librdkafka/src/rdkafka_buf.h +4 -3
- package/deps/librdkafka/src/rdkafka_cert.c +25 -1
- package/deps/librdkafka/src/rdkafka_cert.h +4 -3
- package/deps/librdkafka/src/rdkafka_cgrp.c +468 -143
- package/deps/librdkafka/src/rdkafka_cgrp.h +36 -2
- package/deps/librdkafka/src/rdkafka_conf.c +526 -102
- package/deps/librdkafka/src/rdkafka_conf.h +68 -4
- package/deps/librdkafka/src/rdkafka_feature.c +472 -35
- package/deps/librdkafka/src/rdkafka_feature.h +2 -0
- package/deps/librdkafka/src/rdkafka_fetcher.c +22 -2
- package/deps/librdkafka/src/rdkafka_fetcher.h +2 -2
- package/deps/librdkafka/src/rdkafka_int.h +84 -46
- package/deps/librdkafka/src/rdkafka_metadata.c +221 -136
- package/deps/librdkafka/src/rdkafka_metadata.h +15 -11
- package/deps/librdkafka/src/rdkafka_metadata_cache.c +279 -73
- package/deps/librdkafka/src/rdkafka_mock.c +795 -19
- package/deps/librdkafka/src/rdkafka_mock.h +119 -0
- package/deps/librdkafka/src/rdkafka_mock_cgrp.c +1298 -132
- package/deps/librdkafka/src/rdkafka_mock_handlers.c +345 -49
- package/deps/librdkafka/src/rdkafka_mock_int.h +180 -61
- package/deps/librdkafka/src/rdkafka_msg.c +35 -19
- package/deps/librdkafka/src/rdkafka_msg.h +3 -3
- package/deps/librdkafka/src/rdkafka_msgset_writer.c +14 -10
- package/deps/librdkafka/src/rdkafka_offset.c +33 -5
- package/deps/librdkafka/src/rdkafka_op.c +1 -1
- package/deps/librdkafka/src/rdkafka_op.h +45 -21
- package/deps/librdkafka/src/rdkafka_partition.c +118 -23
- package/deps/librdkafka/src/rdkafka_partition.h +16 -7
- package/deps/librdkafka/src/rdkafka_proto.h +4 -1
- package/deps/librdkafka/src/rdkafka_protocol.h +1 -0
- package/deps/librdkafka/src/rdkafka_queue.c +125 -48
- package/deps/librdkafka/src/rdkafka_queue.h +19 -0
- package/deps/librdkafka/src/rdkafka_range_assignor.c +1 -1
- package/deps/librdkafka/src/rdkafka_request.c +336 -64
- package/deps/librdkafka/src/rdkafka_request.h +24 -1
- package/deps/librdkafka/src/rdkafka_sasl.c +5 -3
- package/deps/librdkafka/src/rdkafka_sasl_oauthbearer.c +14 -10
- package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.c +1166 -89
- package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.h +13 -3
- package/deps/librdkafka/src/rdkafka_sasl_plain.c +3 -3
- package/deps/librdkafka/src/rdkafka_sasl_scram.c +4 -3
- package/deps/librdkafka/src/rdkafka_ssl.c +306 -81
- package/deps/librdkafka/src/rdkafka_ssl.h +22 -0
- package/deps/librdkafka/src/rdkafka_sticky_assignor.c +4 -0
- package/deps/librdkafka/src/rdkafka_telemetry.c +80 -23
- package/deps/librdkafka/src/rdkafka_telemetry_encode.c +5 -1
- package/deps/librdkafka/src/rdkafka_telemetry_encode.h +20 -20
- package/deps/librdkafka/src/rdkafka_topic.c +220 -137
- package/deps/librdkafka/src/rdkafka_topic.h +14 -8
- package/deps/librdkafka/src/rdkafka_transport.c +59 -47
- package/deps/librdkafka/src/rdkafka_transport.h +5 -0
- package/deps/librdkafka/src/rdkafka_txnmgr.c +6 -1
- package/deps/librdkafka/src/rdmap.c +6 -1
- package/deps/librdkafka/src/rdrand.c +11 -1
- package/deps/librdkafka/src/rdtime.h +48 -17
- package/deps/librdkafka/src/rdunittest.c +42 -25
- package/deps/librdkafka/src/rdunittest.h +2 -0
- package/deps/librdkafka/src/rdwin32.h +1 -1
- package/deps/librdkafka/src/regexp.c +47 -42
- package/deps/librdkafka/src/tinycthread_extra.c +45 -21
- package/deps/librdkafka/src/tinycthread_extra.h +7 -3
- package/deps/librdkafka/src-cpp/rdkafkacpp.h +28 -2
- package/deps/librdkafka/tests/0001-multiobj.c +4 -0
- package/deps/librdkafka/tests/0004-conf.c +103 -36
- package/deps/librdkafka/tests/0009-mock_cluster.c +1 -0
- package/deps/librdkafka/tests/0011-produce_batch.c +2 -1
- package/deps/librdkafka/tests/0016-client_swname.c +18 -3
- package/deps/librdkafka/tests/0017-compression.c +6 -8
- package/deps/librdkafka/tests/0018-cgrp_term.c +8 -3
- package/deps/librdkafka/tests/0021-rkt_destroy.c +1 -0
- package/deps/librdkafka/tests/0022-consume_batch.c +4 -1
- package/deps/librdkafka/tests/0026-consume_pause.c +12 -14
- package/deps/librdkafka/tests/0028-long_topicnames.c +1 -1
- package/deps/librdkafka/tests/0029-assign_offset.c +6 -8
- package/deps/librdkafka/tests/0030-offset_commit.c +2 -2
- package/deps/librdkafka/tests/0033-regex_subscribe.c +33 -17
- package/deps/librdkafka/tests/0034-offset_reset.c +25 -4
- package/deps/librdkafka/tests/0036-partial_fetch.c +1 -0
- package/deps/librdkafka/tests/0038-performance.c +1 -0
- package/deps/librdkafka/tests/0040-io_event.c +11 -5
- package/deps/librdkafka/tests/0041-fetch_max_bytes.c +1 -0
- package/deps/librdkafka/tests/0044-partition_cnt.c +3 -2
- package/deps/librdkafka/tests/0045-subscribe_update.c +284 -20
- package/deps/librdkafka/tests/0047-partial_buf_tmout.c +1 -0
- package/deps/librdkafka/tests/0048-partitioner.c +1 -1
- package/deps/librdkafka/tests/0050-subscribe_adds.c +1 -0
- package/deps/librdkafka/tests/0051-assign_adds.c +1 -0
- package/deps/librdkafka/tests/0052-msg_timestamps.c +22 -4
- package/deps/librdkafka/tests/0053-stats_cb.cpp +12 -20
- package/deps/librdkafka/tests/0055-producer_latency.c +176 -3
- package/deps/librdkafka/tests/0056-balanced_group_mt.c +6 -2
- package/deps/librdkafka/tests/0058-log.cpp +3 -3
- package/deps/librdkafka/tests/0059-bsearch.cpp +8 -4
- package/deps/librdkafka/tests/0061-consumer_lag.cpp +25 -5
- package/deps/librdkafka/tests/0067-empty_topic.cpp +3 -0
- package/deps/librdkafka/tests/0068-produce_timeout.c +21 -23
- package/deps/librdkafka/tests/0069-consumer_add_parts.c +3 -7
- package/deps/librdkafka/tests/0075-retry.c +38 -1
- package/deps/librdkafka/tests/0076-produce_retry.c +2 -0
- package/deps/librdkafka/tests/0077-compaction.c +8 -2
- package/deps/librdkafka/tests/0080-admin_ut.c +34 -4
- package/deps/librdkafka/tests/0081-admin.c +455 -155
- package/deps/librdkafka/tests/0082-fetch_max_bytes.cpp +4 -0
- package/deps/librdkafka/tests/0083-cb_event.c +8 -3
- package/deps/librdkafka/tests/0084-destroy_flags.c +14 -18
- package/deps/librdkafka/tests/0085-headers.cpp +4 -0
- package/deps/librdkafka/tests/0086-purge.c +40 -7
- package/deps/librdkafka/tests/0088-produce_metadata_timeout.c +1 -1
- package/deps/librdkafka/tests/0089-max_poll_interval.c +12 -7
- package/deps/librdkafka/tests/0090-idempotence.c +1 -2
- package/deps/librdkafka/tests/0091-max_poll_interval_timeout.c +5 -7
- package/deps/librdkafka/tests/0092-mixed_msgver.c +6 -0
- package/deps/librdkafka/tests/0093-holb.c +8 -5
- package/deps/librdkafka/tests/0094-idempotence_msg_timeout.c +1 -0
- package/deps/librdkafka/tests/0097-ssl_verify.cpp +262 -70
- package/deps/librdkafka/tests/0098-consumer-txn.cpp +16 -16
- package/deps/librdkafka/tests/0099-commit_metadata.c +1 -1
- package/deps/librdkafka/tests/0101-fetch-from-follower.cpp +1 -1
- package/deps/librdkafka/tests/0102-static_group_rebalance.c +317 -16
- package/deps/librdkafka/tests/0103-transactions.c +7 -7
- package/deps/librdkafka/tests/0104-fetch_from_follower_mock.c +1 -0
- package/deps/librdkafka/tests/0105-transactions_mock.c +18 -11
- package/deps/librdkafka/tests/0106-cgrp_sess_timeout.c +35 -14
- package/deps/librdkafka/tests/0107-topic_recreate.c +2 -2
- package/deps/librdkafka/tests/0109-auto_create_topics.cpp +86 -26
- package/deps/librdkafka/tests/0110-batch_size.cpp +1 -2
- package/deps/librdkafka/tests/0112-assign_unknown_part.c +3 -14
- package/deps/librdkafka/tests/0113-cooperative_rebalance.cpp +248 -104
- package/deps/librdkafka/tests/0114-sticky_partitioning.cpp +3 -3
- package/deps/librdkafka/tests/0115-producer_auth.cpp +4 -1
- package/deps/librdkafka/tests/0116-kafkaconsumer_close.cpp +7 -5
- package/deps/librdkafka/tests/0117-mock_errors.c +15 -5
- package/deps/librdkafka/tests/0118-commit_rebalance.c +41 -8
- package/deps/librdkafka/tests/0119-consumer_auth.cpp +20 -1
- package/deps/librdkafka/tests/0120-asymmetric_subscription.c +8 -3
- package/deps/librdkafka/tests/0125-immediate_flush.c +1 -1
- package/deps/librdkafka/tests/0126-oauthbearer_oidc.c +323 -8
- package/deps/librdkafka/tests/0129-fetch_aborted_msgs.c +1 -0
- package/deps/librdkafka/tests/0132-strategy_ordering.c +12 -4
- package/deps/librdkafka/tests/0133-ssl_keys.c +28 -6
- package/deps/librdkafka/tests/0137-barrier_batch_consume.c +24 -14
- package/deps/librdkafka/tests/0139-offset_validation_mock.c +510 -2
- package/deps/librdkafka/tests/0140-commit_metadata.cpp +1 -1
- package/deps/librdkafka/tests/0142-reauthentication.c +37 -17
- package/deps/librdkafka/tests/0143-exponential_backoff_mock.c +39 -40
- package/deps/librdkafka/tests/0146-metadata_mock.c +76 -15
- package/deps/librdkafka/tests/0147-consumer_group_consumer_mock.c +952 -0
- package/deps/librdkafka/tests/0148-offset_fetch_commit_error_mock.c +563 -0
- package/deps/librdkafka/tests/0149-broker-same-host-port.c +140 -0
- package/deps/librdkafka/tests/0150-telemetry_mock.c +9 -6
- package/deps/librdkafka/tests/0151-purge-brokers.c +566 -0
- package/deps/librdkafka/tests/0152-rebootstrap.c +59 -0
- package/deps/librdkafka/tests/0153-memberid.c +128 -0
- package/deps/librdkafka/tests/CMakeLists.txt +6 -0
- package/deps/librdkafka/tests/LibrdkafkaTestApp.py +34 -9
- package/deps/librdkafka/tests/autotest.sh +0 -0
- package/deps/librdkafka/tests/broker_version_tests.py +0 -0
- package/deps/librdkafka/tests/buildbox.sh +0 -0
- package/deps/librdkafka/tests/cleanup-checker-tests.sh +0 -0
- package/deps/librdkafka/tests/cluster_testing.py +0 -0
- package/deps/librdkafka/tests/delete-test-topics.sh +0 -0
- package/deps/librdkafka/tests/fixtures/oauthbearer/jwt_assertion_template.json +10 -0
- package/deps/librdkafka/tests/fixtures/ssl/client.keystore.intermediate.p12 +0 -0
- package/deps/librdkafka/tests/fixtures/ssl/client.keystore.p12 +0 -0
- package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.intermediate.pem +72 -0
- package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.pem +42 -101
- package/deps/librdkafka/tests/fixtures/ssl/client2.intermediate.key +46 -0
- package/deps/librdkafka/tests/fixtures/ssl/client2.key +41 -29
- package/deps/librdkafka/tests/fixtures/ssl/create_keys.sh +112 -37
- package/deps/librdkafka/tests/gen-ssl-certs.sh +0 -0
- package/deps/librdkafka/tests/interactive_broker_version.py +0 -0
- package/deps/librdkafka/tests/java/Makefile +2 -1
- package/deps/librdkafka/tests/java/run-class.sh +0 -0
- package/deps/librdkafka/tests/lz4_manual_test.sh +0 -0
- package/deps/librdkafka/tests/multi-broker-version-test.sh +0 -0
- package/deps/librdkafka/tests/parse-refcnt.sh +0 -0
- package/deps/librdkafka/tests/performance_plot.py +0 -0
- package/deps/librdkafka/tests/requirements.txt +1 -1
- package/deps/librdkafka/tests/run-all-tests.sh +79 -0
- package/deps/librdkafka/tests/run-consumer-tests.sh +0 -0
- package/deps/librdkafka/tests/run-producer-tests.sh +0 -0
- package/deps/librdkafka/tests/run-test-batches.py +157 -0
- package/deps/librdkafka/tests/run-test.sh +0 -0
- package/deps/librdkafka/tests/sasl_test.py +0 -0
- package/deps/librdkafka/tests/test.c +478 -18
- package/deps/librdkafka/tests/test.h +62 -13
- package/deps/librdkafka/tests/testcpp.cpp +6 -1
- package/deps/librdkafka/tests/testcpp.h +30 -2
- package/deps/librdkafka/tests/testshared.h +16 -2
- package/deps/librdkafka/tests/tools/stats/graph.py +0 -0
- package/deps/librdkafka/tests/tools/stats/to_csv.py +1 -1
- package/deps/librdkafka/tests/trivup/trivup-0.14.0.tar.gz +0 -0
- package/deps/librdkafka/tests/until-fail.sh +0 -0
- package/deps/librdkafka/tests/xxxx-metadata.cpp +1 -1
- package/deps/librdkafka/vcpkg.json +1 -1
- package/deps/librdkafka/win32/setup-msys2.ps1 +24 -8
- package/deps/librdkafka/win32/setup-vcpkg.ps1 +28 -6
- package/deps/librdkafka/win32/tests/tests.vcxproj +6 -0
- package/deps/librdkafka/win32/wingetopt.h +5 -4
- package/errors.d.ts +27 -1
- package/lib/error.js +29 -3
- package/make_docs.sh +0 -0
- package/package.json +11 -11
- package/run_docker.sh +0 -0
- package/src/callbacks.cc +6 -9
- package/src/callbacks.h +1 -5
- package/test/kafka-consumer-worker.js +10 -7
- package/test/kafka-consumer.spec.js +32 -21
- package/ci/update-version.js +0 -123
- package/deps/librdkafka/.semaphore/project.yml +0 -43
- package/deps/librdkafka/.semaphore/project_public.yml +0 -20
- package/deps/librdkafka/win32/install-openssl.ps1 +0 -33
|
@@ -86,7 +86,7 @@ static void do_test_producer(bool topic_known) {
|
|
|
86
86
|
|
|
87
87
|
/* Create topic */
|
|
88
88
|
std::string topic_unauth = Test::mk_topic_name("0115-unauthorized", 1);
|
|
89
|
-
Test::
|
|
89
|
+
Test::create_topic_wait_exists(NULL, topic_unauth.c_str(), 3, 1, 5000);
|
|
90
90
|
|
|
91
91
|
int exp_dr_cnt = 0;
|
|
92
92
|
|
|
@@ -112,6 +112,9 @@ static void do_test_producer(bool topic_known) {
|
|
|
112
112
|
"--topic '%s'",
|
|
113
113
|
bootstraps.c_str(), topic_unauth.c_str());
|
|
114
114
|
|
|
115
|
+
/* Allow ACLs to propagate */
|
|
116
|
+
rd_sleep(1);
|
|
117
|
+
|
|
115
118
|
/* Produce message to any partition. */
|
|
116
119
|
Test::Say("Producing message 1 to any partition\n");
|
|
117
120
|
err = p->produce(topic_unauth, RdKafka::Topic::PARTITION_UA,
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* librdkafka - Apache Kafka C library
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) 2020-2022, Magnus Edenhill
|
|
5
|
+
* 2025, Confluent Inc.
|
|
5
6
|
* All rights reserved.
|
|
6
7
|
*
|
|
7
8
|
* Redistribution and use in source and binary forms, with or without
|
|
@@ -81,11 +82,10 @@ static void do_test_consumer_close(bool do_subscribe,
|
|
|
81
82
|
bool do_unsubscribe,
|
|
82
83
|
bool do_close,
|
|
83
84
|
bool with_queue) {
|
|
84
|
-
std::string testname =
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
<< ", close=" << do_close << ", queue=" << with_queue;
|
|
85
|
+
std::string testname =
|
|
86
|
+
tostr() << "Test C++ KafkaConsumer close " << "subscribe=" << do_subscribe
|
|
87
|
+
<< ", unsubscribe=" << do_unsubscribe << ", close=" << do_close
|
|
88
|
+
<< ", queue=" << with_queue;
|
|
89
89
|
SUB_TEST("%s", testname.c_str());
|
|
90
90
|
|
|
91
91
|
rd_kafka_mock_cluster_t *mcluster;
|
|
@@ -199,6 +199,8 @@ static void do_test_consumer_close(bool do_subscribe,
|
|
|
199
199
|
|
|
200
200
|
extern "C" {
|
|
201
201
|
int main_0116_kafkaconsumer_close(int argc, char **argv) {
|
|
202
|
+
TEST_SKIP_MOCK_CLUSTER(0);
|
|
203
|
+
|
|
202
204
|
/* Parameters:
|
|
203
205
|
* subscribe, unsubscribe, close, with_queue */
|
|
204
206
|
for (int i = 0; i < 1 << 4; i++) {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* librdkafka - Apache Kafka C library
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) 2020-2022, Magnus Edenhill
|
|
5
|
+
* 2025, Confluent Inc.
|
|
5
6
|
* All rights reserved.
|
|
6
7
|
*
|
|
7
8
|
* Redistribution and use in source and binary forms, with or without
|
|
@@ -102,8 +103,10 @@ static void do_test_offset_commit_error_during_rebalance(void) {
|
|
|
102
103
|
rd_kafka_t *c1, *c2;
|
|
103
104
|
rd_kafka_mock_cluster_t *mcluster;
|
|
104
105
|
const char *bootstraps;
|
|
105
|
-
const char *topic
|
|
106
|
-
const int msgcnt
|
|
106
|
+
const char *topic = "test";
|
|
107
|
+
const int msgcnt = 100;
|
|
108
|
+
const int exp_msg_cnt_intial = 1;
|
|
109
|
+
int exp_msg_cnt_final = msgcnt;
|
|
107
110
|
rd_kafka_resp_err_t err;
|
|
108
111
|
|
|
109
112
|
SUB_TEST();
|
|
@@ -136,8 +139,8 @@ static void do_test_offset_commit_error_during_rebalance(void) {
|
|
|
136
139
|
|
|
137
140
|
|
|
138
141
|
/* Wait for assignment and one message */
|
|
139
|
-
test_consumer_poll("C1.PRE", c1, 0, -1, -1,
|
|
140
|
-
test_consumer_poll("C2.PRE", c2, 0, -1, -1,
|
|
142
|
+
test_consumer_poll("C1.PRE", c1, 0, -1, -1, exp_msg_cnt_intial, NULL);
|
|
143
|
+
test_consumer_poll("C2.PRE", c2, 0, -1, -1, exp_msg_cnt_intial, NULL);
|
|
141
144
|
|
|
142
145
|
/* Trigger rebalance */
|
|
143
146
|
test_consumer_close(c2);
|
|
@@ -161,8 +164,15 @@ static void do_test_offset_commit_error_during_rebalance(void) {
|
|
|
161
164
|
"not %s",
|
|
162
165
|
rd_kafka_err2name(err));
|
|
163
166
|
|
|
167
|
+
/* Since all the assignors in the `consumer` protocol are COOPERATIVE
|
|
168
|
+
* only the new partitions are assigned to the consumer. All the
|
|
169
|
+
* previously assigned partitions will start consuming from the last
|
|
170
|
+
* offset. */
|
|
171
|
+
if (!test_consumer_group_protocol_classic())
|
|
172
|
+
exp_msg_cnt_final = msgcnt - exp_msg_cnt_intial;
|
|
173
|
+
|
|
164
174
|
/* Wait for new assignment and able to read all messages */
|
|
165
|
-
test_consumer_poll("C1.
|
|
175
|
+
test_consumer_poll("C1.POST", c1, 0, -1, -1, exp_msg_cnt_final, NULL);
|
|
166
176
|
|
|
167
177
|
rd_kafka_destroy(c1);
|
|
168
178
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* librdkafka - Apache Kafka C library
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) 2020-2022, Magnus Edenhill
|
|
5
|
+
* 2025, Confluent Inc.
|
|
5
6
|
* All rights reserved.
|
|
6
7
|
*
|
|
7
8
|
* Redistribution and use in source and binary forms, with or without
|
|
@@ -34,6 +35,7 @@
|
|
|
34
35
|
|
|
35
36
|
static rd_kafka_t *c1, *c2;
|
|
36
37
|
|
|
38
|
+
static int rebalances = 0;
|
|
37
39
|
|
|
38
40
|
static void rebalance_cb(rd_kafka_t *rk,
|
|
39
41
|
rd_kafka_resp_err_t err,
|
|
@@ -42,16 +44,18 @@ static void rebalance_cb(rd_kafka_t *rk,
|
|
|
42
44
|
|
|
43
45
|
TEST_SAY("Rebalance for %s: %s: %d partition(s)\n", rd_kafka_name(rk),
|
|
44
46
|
rd_kafka_err2name(err), parts->cnt);
|
|
45
|
-
|
|
47
|
+
rebalances++;
|
|
46
48
|
if (err == RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS) {
|
|
47
|
-
|
|
49
|
+
test_consumer_assign_by_rebalance_protocol("rebalance", rk,
|
|
50
|
+
parts);
|
|
48
51
|
|
|
49
52
|
} else if (err == RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS) {
|
|
50
53
|
rd_kafka_resp_err_t commit_err;
|
|
51
54
|
|
|
52
55
|
TEST_CALL_ERR__(rd_kafka_position(rk, parts));
|
|
53
56
|
|
|
54
|
-
|
|
57
|
+
test_consumer_unassign_by_rebalance_protocol("rebalance", rk,
|
|
58
|
+
parts);
|
|
55
59
|
|
|
56
60
|
if (rk == c1)
|
|
57
61
|
return;
|
|
@@ -86,7 +90,11 @@ static void rebalance_cb(rd_kafka_t *rk,
|
|
|
86
90
|
int main_0118_commit_rebalance(int argc, char **argv) {
|
|
87
91
|
const char *topic = test_mk_topic_name(__FUNCTION__, 1);
|
|
88
92
|
rd_kafka_conf_t *conf;
|
|
89
|
-
const int msgcnt
|
|
93
|
+
const int msgcnt = 1000;
|
|
94
|
+
const int exp_msg_cnt_pre = 10;
|
|
95
|
+
int exp_msg_cnt_post = msgcnt;
|
|
96
|
+
int exp_msg_cnt_c1_pre = exp_msg_cnt_pre;
|
|
97
|
+
int exp_msg_cnt_c2_pre = exp_msg_cnt_pre;
|
|
90
98
|
|
|
91
99
|
test_conf_init(&conf, NULL, 60);
|
|
92
100
|
test_conf_set(conf, "enable.auto.commit", "false");
|
|
@@ -103,17 +111,42 @@ int main_0118_commit_rebalance(int argc, char **argv) {
|
|
|
103
111
|
test_consumer_subscribe(c1, topic);
|
|
104
112
|
test_consumer_subscribe(c2, topic);
|
|
105
113
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
114
|
+
while (exp_msg_cnt_c1_pre > 0 || exp_msg_cnt_c2_pre > 0) {
|
|
115
|
+
if (exp_msg_cnt_c1_pre > 0 ||
|
|
116
|
+
exp_msg_cnt_c2_pre == exp_msg_cnt_pre) {
|
|
117
|
+
exp_msg_cnt_c1_pre -=
|
|
118
|
+
test_consumer_poll_once(c1, NULL, 100);
|
|
119
|
+
if (exp_msg_cnt_c2_pre == exp_msg_cnt_pre)
|
|
120
|
+
/* Slow down consumption until both have
|
|
121
|
+
* partitions assigned. */
|
|
122
|
+
rd_usleep(100 * 1000, 0);
|
|
123
|
+
}
|
|
124
|
+
if (exp_msg_cnt_c2_pre > 0 ||
|
|
125
|
+
exp_msg_cnt_c1_pre == exp_msg_cnt_pre) {
|
|
126
|
+
exp_msg_cnt_c2_pre -=
|
|
127
|
+
test_consumer_poll_once(c2, NULL, 100);
|
|
128
|
+
if (exp_msg_cnt_c1_pre == exp_msg_cnt_pre)
|
|
129
|
+
/* Slow down consumption until both have
|
|
130
|
+
* partitions assigned. */
|
|
131
|
+
rd_usleep(100 * 1000, 0);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
109
134
|
|
|
110
135
|
/* Trigger rebalance */
|
|
111
136
|
test_consumer_close(c2);
|
|
112
137
|
rd_kafka_destroy(c2);
|
|
113
138
|
|
|
139
|
+
/* Since all the assignors in the `consumer` protocol are COOPERATIVE
|
|
140
|
+
* only the new partitions are assigned to the consumer. All the
|
|
141
|
+
* previously assigned partitions will start consuming from the last
|
|
142
|
+
* offset. */
|
|
143
|
+
if (!test_consumer_group_protocol_classic())
|
|
144
|
+
exp_msg_cnt_post =
|
|
145
|
+
msgcnt - exp_msg_cnt_pre + exp_msg_cnt_c1_pre;
|
|
146
|
+
|
|
114
147
|
/* Since no offsets were successfully committed the remaining consumer
|
|
115
148
|
* should be able to receive all messages. */
|
|
116
|
-
test_consumer_poll("C1.POST", c1, 0, -1, -1,
|
|
149
|
+
test_consumer_poll("C1.POST", c1, 0, -1, -1, exp_msg_cnt_post, NULL);
|
|
117
150
|
|
|
118
151
|
rd_kafka_destroy(c1);
|
|
119
152
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* librdkafka - Apache Kafka C library
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) 2020-2022, Magnus Edenhill
|
|
5
|
+
* 2025, Confluent Inc.
|
|
5
6
|
* All rights reserved.
|
|
6
7
|
*
|
|
7
8
|
* Redistribution and use in source and binary forms, with or without
|
|
@@ -61,7 +62,7 @@ static void do_test_fetch_unauth() {
|
|
|
61
62
|
|
|
62
63
|
/* Create topic */
|
|
63
64
|
const int partition_cnt = 3;
|
|
64
|
-
Test::
|
|
65
|
+
Test::create_topic_wait_exists(NULL, topic.c_str(), partition_cnt, 1, 5000);
|
|
65
66
|
|
|
66
67
|
/* Produce messages */
|
|
67
68
|
test_produce_msgs_easy(topic.c_str(), 0, RdKafka::Topic::PARTITION_UA, 1000);
|
|
@@ -85,6 +86,9 @@ static void do_test_fetch_unauth() {
|
|
|
85
86
|
"--topic '%s'",
|
|
86
87
|
bootstraps.c_str(), topic.c_str());
|
|
87
88
|
|
|
89
|
+
/* Allow ACLs to propagate */
|
|
90
|
+
rd_sleep(1);
|
|
91
|
+
|
|
88
92
|
Test::subscribe(c, topic);
|
|
89
93
|
|
|
90
94
|
int auth_err_cnt = 0;
|
|
@@ -128,8 +132,23 @@ static void do_test_fetch_unauth() {
|
|
|
128
132
|
"Expected exactly %d auth errors, saw %d", partition_cnt,
|
|
129
133
|
auth_err_cnt);
|
|
130
134
|
|
|
135
|
+
c->close();
|
|
131
136
|
delete c;
|
|
132
137
|
|
|
138
|
+
test_kafka_cmd(
|
|
139
|
+
"kafka-acls.sh --bootstrap-server %s "
|
|
140
|
+
"--remove --force --allow-principal 'User:*' "
|
|
141
|
+
"--operation Describe --allow-host '*' "
|
|
142
|
+
"--topic '%s'",
|
|
143
|
+
bootstraps.c_str(), topic.c_str());
|
|
144
|
+
|
|
145
|
+
test_kafka_cmd(
|
|
146
|
+
"kafka-acls.sh --bootstrap-server %s "
|
|
147
|
+
"--remove --force --deny-principal 'User:*' "
|
|
148
|
+
"--operation Read --deny-host '*' "
|
|
149
|
+
"--topic '%s'",
|
|
150
|
+
bootstraps.c_str(), topic.c_str());
|
|
151
|
+
|
|
133
152
|
Test::Say(tostr() << _C_GRN << "[ Test unauthorized Fetch PASS ]\n");
|
|
134
153
|
}
|
|
135
154
|
|
|
@@ -169,10 +169,15 @@ int main_0120_asymmetric_subscription(int argc, char **argv) {
|
|
|
169
169
|
rd_kafka_mock_topic_create(mcluster, "t3", _PART_CNT, 1);
|
|
170
170
|
rd_kafka_mock_topic_create(mcluster, "t4", _PART_CNT, 1);
|
|
171
171
|
|
|
172
|
-
|
|
173
|
-
do_test_asymmetric("roundrobin", bootstraps);
|
|
174
172
|
do_test_asymmetric("range", bootstraps);
|
|
175
|
-
|
|
173
|
+
|
|
174
|
+
/* These tests would be duplicate with KIP 848 protocol,
|
|
175
|
+
* given we're not testing the assignment here,
|
|
176
|
+
* as it's mocked. */
|
|
177
|
+
if (test_consumer_group_protocol_classic()) {
|
|
178
|
+
do_test_asymmetric("roundrobin", bootstraps);
|
|
179
|
+
do_test_asymmetric("cooperative-sticky", bootstraps);
|
|
180
|
+
}
|
|
176
181
|
|
|
177
182
|
test_mock_cluster_destroy(mcluster);
|
|
178
183
|
|
|
@@ -48,7 +48,7 @@ void do_test_flush_overrides_linger_ms_time() {
|
|
|
48
48
|
rd_kafka_conf_set_dr_msg_cb(conf, test_dr_msg_cb);
|
|
49
49
|
rk = test_create_handle(RD_KAFKA_PRODUCER, conf);
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
test_create_topic_wait_exists(rk, topic, 1, 1, 5000);
|
|
52
52
|
|
|
53
53
|
/* Produce half set of messages without waiting for delivery. */
|
|
54
54
|
test_produce_msgs2_nowait(rk, topic, 0, 0, 0, msgcnt / 2, NULL, 50,
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* librdkafka - Apache Kafka C library
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) 2021-2022, Magnus Edenhill
|
|
5
|
+
* 2025, Confluent Inc.
|
|
5
6
|
* All rights reserved.
|
|
6
7
|
*
|
|
7
8
|
* Redistribution and use in source and binary forms, with or without
|
|
@@ -31,6 +32,11 @@
|
|
|
31
32
|
* is built from within the librdkafka source tree and thus differs. */
|
|
32
33
|
#include "rdkafka.h" /* for Kafka driver */
|
|
33
34
|
|
|
35
|
+
#define TEST_FIXTURES_FOLDER "./fixtures"
|
|
36
|
+
#define TEST_FIXTURES_OAUTHBEARER_FOLDER TEST_FIXTURES_FOLDER "/oauthbearer/"
|
|
37
|
+
#define TEST_FIXTURES_JWT_ASSERTION_TEMPLATE \
|
|
38
|
+
TEST_FIXTURES_OAUTHBEARER_FOLDER "jwt_assertion_template.json"
|
|
39
|
+
|
|
34
40
|
static rd_bool_t error_seen;
|
|
35
41
|
/**
|
|
36
42
|
* @brief After config OIDC, make sure the producer and consumer
|
|
@@ -38,7 +44,8 @@ static rd_bool_t error_seen;
|
|
|
38
44
|
*
|
|
39
45
|
*/
|
|
40
46
|
static void
|
|
41
|
-
do_test_produce_consumer_with_OIDC(const
|
|
47
|
+
do_test_produce_consumer_with_OIDC(const char *test_name,
|
|
48
|
+
const rd_kafka_conf_t *base_conf) {
|
|
42
49
|
const char *topic;
|
|
43
50
|
uint64_t testid;
|
|
44
51
|
rd_kafka_t *p1;
|
|
@@ -47,7 +54,8 @@ do_test_produce_consumer_with_OIDC(const rd_kafka_conf_t *base_conf) {
|
|
|
47
54
|
|
|
48
55
|
const char *url = test_getenv("VALID_OIDC_URL", NULL);
|
|
49
56
|
|
|
50
|
-
SUB_TEST("Test producer and consumer with oidc configuration"
|
|
57
|
+
SUB_TEST("Test producer and consumer with oidc configuration: %s",
|
|
58
|
+
test_name);
|
|
51
59
|
|
|
52
60
|
if (!url) {
|
|
53
61
|
SUB_TEST_SKIP(
|
|
@@ -65,13 +73,13 @@ do_test_produce_consumer_with_OIDC(const rd_kafka_conf_t *base_conf) {
|
|
|
65
73
|
p1 = test_create_handle(RD_KAFKA_PRODUCER, rd_kafka_conf_dup(conf));
|
|
66
74
|
|
|
67
75
|
topic = test_mk_topic_name("0126-oauthbearer_oidc", 1);
|
|
68
|
-
|
|
76
|
+
test_create_topic_wait_exists(p1, topic, 1, 3, 5000);
|
|
69
77
|
TEST_SAY("Topic: %s is created\n", topic);
|
|
70
78
|
|
|
71
79
|
test_produce_msgs2(p1, topic, testid, 0, 0, 1, NULL, 0);
|
|
72
80
|
|
|
73
81
|
test_conf_set(conf, "auto.offset.reset", "earliest");
|
|
74
|
-
c1 = test_create_consumer(topic, NULL,
|
|
82
|
+
c1 = test_create_consumer(topic, NULL, conf, NULL);
|
|
75
83
|
test_consumer_subscribe(c1, topic);
|
|
76
84
|
|
|
77
85
|
/* Give it some time to trigger the token refresh. */
|
|
@@ -142,11 +150,53 @@ static void do_test_produce_consumer_with_OIDC_expired_token_should_fail(
|
|
|
142
150
|
|
|
143
151
|
|
|
144
152
|
/**
|
|
145
|
-
* @brief After
|
|
153
|
+
* @brief After configiguring OIDC, make sure the
|
|
154
|
+
* authentication fails as expected.
|
|
155
|
+
*/
|
|
156
|
+
static void do_test_produce_consumer_with_OIDC_should_fail(
|
|
157
|
+
const char *test_name,
|
|
158
|
+
const rd_kafka_conf_t *base_conf) {
|
|
159
|
+
rd_kafka_t *c1;
|
|
160
|
+
uint64_t testid;
|
|
161
|
+
rd_kafka_conf_t *conf;
|
|
162
|
+
|
|
163
|
+
const char *url = test_getenv("VALID_OIDC_URL", NULL);
|
|
164
|
+
|
|
165
|
+
SUB_TEST("Test authentication failure with oidc configuration: %s",
|
|
166
|
+
test_name);
|
|
167
|
+
if (!url) {
|
|
168
|
+
SUB_TEST_SKIP(
|
|
169
|
+
"VALID_OIDC_URL environment variable is not set\n");
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
error_seen = rd_false;
|
|
174
|
+
|
|
175
|
+
conf = rd_kafka_conf_dup(base_conf);
|
|
176
|
+
test_conf_set(conf, "sasl.oauthbearer.token.endpoint.url", url);
|
|
177
|
+
|
|
178
|
+
rd_kafka_conf_set_error_cb(conf, auth_error_cb);
|
|
179
|
+
|
|
180
|
+
testid = test_id_generate();
|
|
181
|
+
|
|
182
|
+
c1 = test_create_consumer("OIDC.fail.C1", NULL, conf, NULL);
|
|
183
|
+
|
|
184
|
+
test_consumer_poll_no_msgs("OIDC.fail.C1", c1, testid, 5 * 1000);
|
|
185
|
+
|
|
186
|
+
TEST_ASSERT(error_seen);
|
|
187
|
+
|
|
188
|
+
test_consumer_close(c1);
|
|
189
|
+
rd_kafka_destroy(c1);
|
|
190
|
+
SUB_TEST_PASS();
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* @brief After config OIDC, if the token endpoint is not valid, make sure the
|
|
146
195
|
* authentication fail as expected.
|
|
147
196
|
*
|
|
148
197
|
*/
|
|
149
|
-
static void
|
|
198
|
+
static void
|
|
199
|
+
do_test_produce_consumer_with_OIDC_should_fail_invalid_token_endpoint(
|
|
150
200
|
const rd_kafka_conf_t *base_conf) {
|
|
151
201
|
rd_kafka_t *c1;
|
|
152
202
|
uint64_t testid;
|
|
@@ -183,6 +233,266 @@ static void do_test_produce_consumer_with_OIDC_should_fail(
|
|
|
183
233
|
SUB_TEST_PASS();
|
|
184
234
|
}
|
|
185
235
|
|
|
236
|
+
typedef enum oidc_configuration_jwt_bearer_variation_t {
|
|
237
|
+
/** Use a private key file. */
|
|
238
|
+
OIDC_CONFIGURATION_JWT_BEARER_VARIATION_PRIVATE_KEY_FILE,
|
|
239
|
+
/** Use an encrypted private key file. */
|
|
240
|
+
OIDC_CONFIGURATION_JWT_BEARER_VARIATION_PRIVATE_KEY_FILE_ENCRYPTED,
|
|
241
|
+
/** Use a private key file
|
|
242
|
+
* set as a configuration property. */
|
|
243
|
+
OIDC_CONFIGURATION_JWT_BEARER_VARIATION_PRIVATE_KEY_STRING,
|
|
244
|
+
/** Use an encrypted private key file
|
|
245
|
+
* set as a configuration property. */
|
|
246
|
+
OIDC_CONFIGURATION_JWT_BEARER_VARIATION_PRIVATE_KEY_STRING_ENCRYPTED,
|
|
247
|
+
/** Use a private key file
|
|
248
|
+
* and a template for the JWT assertion. */
|
|
249
|
+
OIDC_CONFIGURATION_JWT_BEARER_VARIATION_TEMPLATE_FILE,
|
|
250
|
+
/** Use a private key file and set the JOSE algorithm to ES256.
|
|
251
|
+
* This variation will fail as the private key is RSA in trivup */
|
|
252
|
+
OIDC_CONFIGURATION_JWT_BEARER_VARIATION_JOSE_ALGORITHM_ES256,
|
|
253
|
+
/** Invalid scope */
|
|
254
|
+
OIDC_CONFIGURATION_JWT_BEARER_VARIATION_INVALID_SCOPE,
|
|
255
|
+
OIDC_CONFIGURATION_JWT_BEARER_VARIATION__CNT
|
|
256
|
+
} oidc_configuration_jwt_bearer_variation_t;
|
|
257
|
+
|
|
258
|
+
#define OIDC_CONFIGURATION_JWT_BEARER_VARIATION__FIRST_FAILING \
|
|
259
|
+
OIDC_CONFIGURATION_JWT_BEARER_VARIATION_JOSE_ALGORITHM_ES256
|
|
260
|
+
|
|
261
|
+
static const char *oidc_configuration_jwt_bearer_variation_name(
|
|
262
|
+
oidc_configuration_jwt_bearer_variation_t variation) {
|
|
263
|
+
rd_assert(
|
|
264
|
+
variation >=
|
|
265
|
+
OIDC_CONFIGURATION_JWT_BEARER_VARIATION_PRIVATE_KEY_FILE &&
|
|
266
|
+
variation < OIDC_CONFIGURATION_JWT_BEARER_VARIATION__CNT);
|
|
267
|
+
static const char *names[] = {
|
|
268
|
+
"private key file", "private key encrypted file",
|
|
269
|
+
"private key pem string", "private key encrypted pem string",
|
|
270
|
+
"template file", "JOSE algorithm ES256",
|
|
271
|
+
"invalid scope"};
|
|
272
|
+
return names[variation];
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
static rd_kafka_conf_t *oidc_configuration_jwt_bearer(
|
|
276
|
+
rd_kafka_conf_t *conf,
|
|
277
|
+
oidc_configuration_jwt_bearer_variation_t variation) {
|
|
278
|
+
char file_content[4096];
|
|
279
|
+
const char *private_key_file =
|
|
280
|
+
test_getenv("OAUTHBEARER_CLIENT_PRIVATE_KEY", NULL);
|
|
281
|
+
const char *private_key_encrypted_file =
|
|
282
|
+
test_getenv("OAUTHBEARER_CLIENT_PRIVATE_KEY_ENCRYPTED", NULL);
|
|
283
|
+
const char *private_key_password =
|
|
284
|
+
test_getenv("OAUTHBEARER_CLIENT_PRIVATE_KEY_PASSWORD", NULL);
|
|
285
|
+
|
|
286
|
+
conf = rd_kafka_conf_dup(conf);
|
|
287
|
+
test_conf_set(conf, "sasl.oauthbearer.grant.type",
|
|
288
|
+
"urn:ietf:params:oauth:grant-type:jwt-bearer");
|
|
289
|
+
/* "sub" isn't mandatory if already defined in the template. */
|
|
290
|
+
if (variation != OIDC_CONFIGURATION_JWT_BEARER_VARIATION_TEMPLATE_FILE)
|
|
291
|
+
test_conf_set(conf, "sasl.oauthbearer.assertion.claim.sub",
|
|
292
|
+
"testuser");
|
|
293
|
+
else
|
|
294
|
+
test_conf_set(conf,
|
|
295
|
+
"sasl.oauthbearer.assertion.jwt.template.file",
|
|
296
|
+
TEST_FIXTURES_JWT_ASSERTION_TEMPLATE);
|
|
297
|
+
|
|
298
|
+
if (variation ==
|
|
299
|
+
OIDC_CONFIGURATION_JWT_BEARER_VARIATION_JOSE_ALGORITHM_ES256)
|
|
300
|
+
test_conf_set(conf, "sasl.oauthbearer.assertion.algorithm",
|
|
301
|
+
"ES256");
|
|
302
|
+
if (variation == OIDC_CONFIGURATION_JWT_BEARER_VARIATION_INVALID_SCOPE)
|
|
303
|
+
test_conf_set(conf, "sasl.oauthbearer.scope", "invalid_scope");
|
|
304
|
+
|
|
305
|
+
switch (variation) {
|
|
306
|
+
case OIDC_CONFIGURATION_JWT_BEARER_VARIATION_PRIVATE_KEY_FILE:
|
|
307
|
+
case OIDC_CONFIGURATION_JWT_BEARER_VARIATION_TEMPLATE_FILE:
|
|
308
|
+
case OIDC_CONFIGURATION_JWT_BEARER_VARIATION_JOSE_ALGORITHM_ES256:
|
|
309
|
+
case OIDC_CONFIGURATION_JWT_BEARER_VARIATION_INVALID_SCOPE:
|
|
310
|
+
if (!private_key_file)
|
|
311
|
+
goto fail;
|
|
312
|
+
|
|
313
|
+
test_conf_set(conf,
|
|
314
|
+
"sasl.oauthbearer.assertion.private.key.file",
|
|
315
|
+
private_key_file);
|
|
316
|
+
break;
|
|
317
|
+
case OIDC_CONFIGURATION_JWT_BEARER_VARIATION_PRIVATE_KEY_FILE_ENCRYPTED:
|
|
318
|
+
if (!private_key_encrypted_file || !private_key_password)
|
|
319
|
+
goto fail;
|
|
320
|
+
test_conf_set(conf,
|
|
321
|
+
"sasl.oauthbearer.assertion.private.key.file",
|
|
322
|
+
private_key_encrypted_file);
|
|
323
|
+
test_conf_set(
|
|
324
|
+
conf, "sasl.oauthbearer.assertion.private.key.passphrase",
|
|
325
|
+
private_key_password);
|
|
326
|
+
break;
|
|
327
|
+
case OIDC_CONFIGURATION_JWT_BEARER_VARIATION_PRIVATE_KEY_STRING:
|
|
328
|
+
if (!private_key_file)
|
|
329
|
+
goto fail;
|
|
330
|
+
TEST_ASSERT(test_read_file(private_key_file, file_content,
|
|
331
|
+
sizeof(file_content)) > 0);
|
|
332
|
+
|
|
333
|
+
test_conf_set(conf,
|
|
334
|
+
"sasl.oauthbearer.assertion.private.key.pem",
|
|
335
|
+
file_content);
|
|
336
|
+
break;
|
|
337
|
+
case OIDC_CONFIGURATION_JWT_BEARER_VARIATION_PRIVATE_KEY_STRING_ENCRYPTED:
|
|
338
|
+
if (!private_key_encrypted_file || !private_key_password)
|
|
339
|
+
goto fail;
|
|
340
|
+
TEST_ASSERT(test_read_file(private_key_file, file_content,
|
|
341
|
+
sizeof(file_content)) > 0);
|
|
342
|
+
|
|
343
|
+
test_conf_set(conf,
|
|
344
|
+
"sasl.oauthbearer.assertion.private.key.pem",
|
|
345
|
+
file_content);
|
|
346
|
+
test_conf_set(
|
|
347
|
+
conf, "sasl.oauthbearer.assertion.private.key.passphrase",
|
|
348
|
+
private_key_password);
|
|
349
|
+
break;
|
|
350
|
+
default:
|
|
351
|
+
rd_assert(!*"Unknown OIDC JWT bearer test variation");
|
|
352
|
+
}
|
|
353
|
+
return conf;
|
|
354
|
+
fail:
|
|
355
|
+
rd_kafka_conf_destroy(conf);
|
|
356
|
+
TEST_WARN("Skipping OIDC JWT bearer test variation: %s",
|
|
357
|
+
oidc_configuration_jwt_bearer_variation_name(variation));
|
|
358
|
+
return NULL;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
void do_test_produce_consumer_with_OIDC_jwt_bearer(rd_kafka_conf_t *conf) {
|
|
362
|
+
rd_kafka_conf_t *jwt_bearer_conf;
|
|
363
|
+
oidc_configuration_jwt_bearer_variation_t variation;
|
|
364
|
+
for (variation =
|
|
365
|
+
OIDC_CONFIGURATION_JWT_BEARER_VARIATION_PRIVATE_KEY_FILE;
|
|
366
|
+
variation < OIDC_CONFIGURATION_JWT_BEARER_VARIATION__CNT;
|
|
367
|
+
variation++) {
|
|
368
|
+
const char *test_name;
|
|
369
|
+
jwt_bearer_conf =
|
|
370
|
+
oidc_configuration_jwt_bearer(conf, variation);
|
|
371
|
+
if (!jwt_bearer_conf)
|
|
372
|
+
continue;
|
|
373
|
+
|
|
374
|
+
test_name = tsprintf(
|
|
375
|
+
"JWT bearer: %s\n",
|
|
376
|
+
oidc_configuration_jwt_bearer_variation_name(variation));
|
|
377
|
+
|
|
378
|
+
if (variation <
|
|
379
|
+
OIDC_CONFIGURATION_JWT_BEARER_VARIATION__FIRST_FAILING)
|
|
380
|
+
do_test_produce_consumer_with_OIDC(test_name,
|
|
381
|
+
jwt_bearer_conf);
|
|
382
|
+
else
|
|
383
|
+
do_test_produce_consumer_with_OIDC_should_fail(
|
|
384
|
+
test_name, jwt_bearer_conf);
|
|
385
|
+
rd_kafka_conf_destroy(jwt_bearer_conf);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
typedef enum oidc_configuration_metadata_authentication_variation_t {
|
|
391
|
+
/** Azure IMDS. Successful case. */
|
|
392
|
+
OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_SUCCESS,
|
|
393
|
+
/** Azure IMDS. Missing client ID. */
|
|
394
|
+
OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_MISSING_CLIENT_ID,
|
|
395
|
+
/** Azure IMDS. Missing resource parameter. */
|
|
396
|
+
OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_MISSING_RESOURCE,
|
|
397
|
+
/** Azure IMDS. Missing API version. */
|
|
398
|
+
OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_MISSING_API_VERSION,
|
|
399
|
+
OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION__CNT
|
|
400
|
+
} oidc_configuration_metadata_authentication_variation_t;
|
|
401
|
+
|
|
402
|
+
#define OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION__FIRST_FAILING \
|
|
403
|
+
OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_MISSING_CLIENT_ID
|
|
404
|
+
|
|
405
|
+
static const char *oidc_configuration_metadata_authentication_variation_name(
|
|
406
|
+
oidc_configuration_metadata_authentication_variation_t variation) {
|
|
407
|
+
rd_assert(
|
|
408
|
+
variation >=
|
|
409
|
+
OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_SUCCESS &&
|
|
410
|
+
variation <
|
|
411
|
+
OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION__CNT);
|
|
412
|
+
static const char *names[] = {
|
|
413
|
+
"Azure IMDS: success", "Azure IMDS: missing client ID",
|
|
414
|
+
"Azure IMDS: missing resource", "Azure IMDS: missing API version"};
|
|
415
|
+
return names[variation];
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
static rd_kafka_conf_t *oidc_configuration_metadata_authentication(
|
|
419
|
+
rd_kafka_conf_t *conf,
|
|
420
|
+
oidc_configuration_metadata_authentication_variation_t variation) {
|
|
421
|
+
conf = rd_kafka_conf_dup(conf);
|
|
422
|
+
switch (variation) {
|
|
423
|
+
case OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_SUCCESS:
|
|
424
|
+
test_conf_set(conf,
|
|
425
|
+
"sasl.oauthbearer.metadata.authentication.type",
|
|
426
|
+
"azure_imds");
|
|
427
|
+
test_conf_set(conf, "sasl.oauthbearer.config",
|
|
428
|
+
"query=__metadata_authentication_type=azure_imds&"
|
|
429
|
+
"api-version=2025-04-07&resource="
|
|
430
|
+
"api://external_resource_id&client_id=client_id");
|
|
431
|
+
break;
|
|
432
|
+
case OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_MISSING_CLIENT_ID:
|
|
433
|
+
test_conf_set(conf,
|
|
434
|
+
"sasl.oauthbearer.metadata.authentication.type",
|
|
435
|
+
"azure_imds");
|
|
436
|
+
test_conf_set(conf, "sasl.oauthbearer.config",
|
|
437
|
+
"query=__metadata_authentication_type=azure_imds&"
|
|
438
|
+
"api-version=2025-04-07&resource="
|
|
439
|
+
"api://external_resource_id");
|
|
440
|
+
break;
|
|
441
|
+
case OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_MISSING_RESOURCE:
|
|
442
|
+
test_conf_set(conf,
|
|
443
|
+
"sasl.oauthbearer.metadata.authentication.type",
|
|
444
|
+
"azure_imds");
|
|
445
|
+
test_conf_set(conf, "sasl.oauthbearer.config",
|
|
446
|
+
"query=__metadata_authentication_type=azure_imds&"
|
|
447
|
+
"api-version=2025-04-07&"
|
|
448
|
+
"client_id=client_id");
|
|
449
|
+
break;
|
|
450
|
+
case OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_MISSING_API_VERSION:
|
|
451
|
+
test_conf_set(conf,
|
|
452
|
+
"sasl.oauthbearer.metadata.authentication.type",
|
|
453
|
+
"azure_imds");
|
|
454
|
+
test_conf_set(conf, "sasl.oauthbearer.config",
|
|
455
|
+
"query=__metadata_authentication_type=azure_imds&"
|
|
456
|
+
"resource="
|
|
457
|
+
"api://external_resource_id&client_id=client_id");
|
|
458
|
+
break;
|
|
459
|
+
default:
|
|
460
|
+
TEST_ASSERT(rd_false,
|
|
461
|
+
"Unknown OIDC metadata authentication type");
|
|
462
|
+
}
|
|
463
|
+
return conf;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/* Test metadata-based authentication cases against Trivup. */
|
|
467
|
+
void do_test_produce_consumer_with_OIDC_metadata_authentication(
|
|
468
|
+
rd_kafka_conf_t *conf) {
|
|
469
|
+
rd_kafka_conf_t *metadata_authentication_conf;
|
|
470
|
+
oidc_configuration_metadata_authentication_variation_t variation;
|
|
471
|
+
for (
|
|
472
|
+
variation =
|
|
473
|
+
OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION_AZURE_IMDS_SUCCESS;
|
|
474
|
+
variation <
|
|
475
|
+
OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION__CNT;
|
|
476
|
+
variation++) {
|
|
477
|
+
const char *test_name;
|
|
478
|
+
metadata_authentication_conf =
|
|
479
|
+
oidc_configuration_metadata_authentication(conf, variation);
|
|
480
|
+
|
|
481
|
+
test_name = tsprintf(
|
|
482
|
+
"Metadata authentication variation: %s\n",
|
|
483
|
+
oidc_configuration_metadata_authentication_variation_name(
|
|
484
|
+
variation));
|
|
485
|
+
|
|
486
|
+
if (variation <
|
|
487
|
+
OIDC_CONFIGURATION_METADATA_AUTHENTICATION_VARIATION__FIRST_FAILING)
|
|
488
|
+
do_test_produce_consumer_with_OIDC(
|
|
489
|
+
test_name, metadata_authentication_conf);
|
|
490
|
+
else
|
|
491
|
+
do_test_produce_consumer_with_OIDC_should_fail(
|
|
492
|
+
test_name, metadata_authentication_conf);
|
|
493
|
+
rd_kafka_conf_destroy(metadata_authentication_conf);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
186
496
|
|
|
187
497
|
int main_0126_oauthbearer_oidc(int argc, char **argv) {
|
|
188
498
|
rd_kafka_conf_t *conf;
|
|
@@ -194,18 +504,23 @@ int main_0126_oauthbearer_oidc(int argc, char **argv) {
|
|
|
194
504
|
sec = test_conf_get(conf, "security.protocol");
|
|
195
505
|
if (!strstr(sec, "sasl")) {
|
|
196
506
|
TEST_SKIP("Apache Kafka cluster not configured for SASL\n");
|
|
507
|
+
rd_kafka_conf_destroy(conf);
|
|
197
508
|
return 0;
|
|
198
509
|
}
|
|
199
510
|
|
|
200
511
|
oidc = test_conf_get(conf, "sasl.oauthbearer.method");
|
|
201
512
|
if (rd_strcasecmp(oidc, "OIDC")) {
|
|
202
513
|
TEST_SKIP("`sasl.oauthbearer.method=OIDC` is required\n");
|
|
514
|
+
rd_kafka_conf_destroy(conf);
|
|
203
515
|
return 0;
|
|
204
516
|
}
|
|
205
517
|
|
|
206
|
-
do_test_produce_consumer_with_OIDC(conf);
|
|
207
|
-
|
|
518
|
+
do_test_produce_consumer_with_OIDC("client_credentials", conf);
|
|
519
|
+
do_test_produce_consumer_with_OIDC_should_fail_invalid_token_endpoint(
|
|
520
|
+
conf);
|
|
208
521
|
do_test_produce_consumer_with_OIDC_expired_token_should_fail(conf);
|
|
522
|
+
do_test_produce_consumer_with_OIDC_jwt_bearer(conf);
|
|
523
|
+
do_test_produce_consumer_with_OIDC_metadata_authentication(conf);
|
|
209
524
|
|
|
210
525
|
rd_kafka_conf_destroy(conf);
|
|
211
526
|
|