From 2759b34d59cab9040e3e47473324f5f418b31b85 Mon Sep 17 00:00:00 2001 From: Milind L Date: Wed, 28 Jun 2023 09:48:51 +0530 Subject: [PATCH 1/9] [mock]: Fix passing null pointer to strndup, which is UB (#4321) UBSan diagnostic: librdkafka/override/src/rd.h:166:27: runtime error: null pointer passed as argument 1, which is declared to never be null Root cause: - rdkafka_mock_cgrp.c:570, `GroupInstanceId` is passed to `RD_KAFKAP_STR_DUP` while potentially NULL - l568, we have the check `if (GroupInstanceId)` which only checks whether the pointer is null (it can never be null based on construction). It does not check whether the string inside is null. - rdkafka_mock_handlers.c:1149, `GroupInstanceId` is set only if `rkbuf->rkbuf_reqhdr.ApiVersion >= 5`, otherwise it is NULL. Fix: - check `if (RD_KAFKAP_STR_LEN(GroupInstanceId))` instead Co-authored-by: Pierre Hallot --- src/rdkafka_mock_cgrp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rdkafka_mock_cgrp.c b/src/rdkafka_mock_cgrp.c index 3fa5367793..57fe550925 100644 --- a/src/rdkafka_mock_cgrp.c +++ b/src/rdkafka_mock_cgrp.c @@ -565,7 +565,7 @@ rd_kafka_mock_cgrp_member_add(rd_kafka_mock_cgrp_t *mcgrp, } else member->id = RD_KAFKAP_STR_DUP(MemberId); - if (GroupInstanceId) + if (RD_KAFKAP_STR_LEN(GroupInstanceId)) member->group_instance_id = RD_KAFKAP_STR_DUP(GroupInstanceId); From 49f05db36e5bff78e856e33da951a5f998f9d55b Mon Sep 17 00:00:00 2001 From: Emanuele Sabellico Date: Thu, 29 Jun 2023 16:01:30 +0200 Subject: [PATCH 2/9] Update copyright notice of files changed (#4327) with PRs started in 2023, global copyright notice, support email, github links --- .github/ISSUE_TEMPLATE | 6 ++--- CHANGELOG.md | 4 +-- CODE_OF_CONDUCT.md | 2 +- CONTRIBUTING.md | 2 +- Doxyfile | 10 ++++---- INTRODUCTION.md | 9 ++----- LICENSE | 3 ++- LICENSES.txt | 3 ++- README.md | 25 ++++++++++--------- configure.self | 2 +- debian/control | 2 +- debian/copyright | 6 ++--- debian/watch | 2 +- dev-conf.sh | 2 +- examples/consumer.c | 5 ++-- examples/delete_records.c | 2 +- examples/idempotent_producer.c | 2 +- examples/openssl_engine_example.cpp | 2 +- examples/producer.c | 4 +-- examples/producer.cpp | 4 +-- examples/rdkafka_complex_consumer_example.c | 4 +-- examples/rdkafka_complex_consumer_example.cpp | 4 +-- examples/rdkafka_consume_batch.cpp | 4 +-- examples/rdkafka_example.c | 4 +-- examples/rdkafka_example.cpp | 4 +-- examples/rdkafka_performance.c | 5 ++-- examples/transactions-older-broker.c | 2 +- examples/transactions.c | 2 +- examples/win_ssl_cert_store.cpp | 2 +- lds-gen.py | 2 +- mklove/modules/configure.base | 2 +- packaging/RELEASE.md | 2 +- packaging/archlinux/PKGBUILD | 4 +-- packaging/debian/control | 6 ++--- packaging/debian/copyright | 6 ++--- packaging/debian/librdkafka.dsc | 8 +++--- packaging/debian/watch | 2 +- packaging/homebrew/brew-update-pr.sh | 2 +- packaging/nuget/README.md | 6 +++++ packaging/rpm/librdkafka.spec | 2 +- packaging/tools/build-deb-package.sh | 4 +-- packaging/tools/gh-release-checksums.py | 4 +-- src-cpp/ConfImpl.cpp | 2 +- src-cpp/ConsumerImpl.cpp | 2 +- src-cpp/HandleImpl.cpp | 3 ++- src-cpp/HeadersImpl.cpp | 2 +- src-cpp/KafkaConsumerImpl.cpp | 2 +- src-cpp/MessageImpl.cpp | 2 +- src-cpp/MetadataImpl.cpp | 2 +- src-cpp/ProducerImpl.cpp | 2 +- src-cpp/QueueImpl.cpp | 2 +- src-cpp/RdKafka.cpp | 2 +- src-cpp/TopicImpl.cpp | 2 +- src-cpp/TopicPartitionImpl.cpp | 2 +- src-cpp/rdkafkacpp.h | 3 ++- src-cpp/rdkafkacpp_int.h | 3 ++- src/crc32c.h | 2 +- src/generate_proto.sh | 2 +- src/rd.h | 2 +- src/rdaddr.c | 2 +- src/rdaddr.h | 2 +- src/rdatomic.h | 2 +- src/rdavg.h | 2 +- src/rdavl.c | 2 +- src/rdavl.h | 2 +- src/rdbuf.c | 2 +- src/rdbuf.h | 2 +- src/rdcrc32.c | 2 +- src/rdcrc32.h | 2 +- src/rddl.c | 2 +- src/rddl.h | 2 +- src/rdendian.h | 2 +- src/rdfloat.h | 2 +- src/rdfnv1a.c | 2 +- src/rdfnv1a.h | 2 +- src/rdgz.c | 2 +- src/rdgz.h | 2 +- src/rdhdrhistogram.c | 2 +- src/rdhdrhistogram.h | 2 +- src/rdhttp.c | 2 +- src/rdhttp.h | 2 +- src/rdinterval.h | 2 +- src/rdkafka.c | 3 ++- src/rdkafka.h | 5 ++-- src/rdkafka_admin.c | 3 ++- src/rdkafka_admin.h | 2 +- src/rdkafka_assignment.c | 3 ++- src/rdkafka_assignment.h | 2 +- src/rdkafka_assignor.c | 3 ++- src/rdkafka_assignor.h | 3 ++- src/rdkafka_aux.c | 3 ++- src/rdkafka_aux.h | 3 ++- src/rdkafka_background.c | 2 +- src/rdkafka_broker.c | 3 ++- src/rdkafka_broker.h | 3 ++- src/rdkafka_buf.c | 2 +- src/rdkafka_buf.h | 3 ++- src/rdkafka_cert.c | 2 +- src/rdkafka_cert.h | 2 +- src/rdkafka_cgrp.c | 3 ++- src/rdkafka_cgrp.h | 2 +- src/rdkafka_conf.c | 8 +++--- src/rdkafka_conf.h | 2 +- src/rdkafka_confval.h | 2 +- src/rdkafka_coord.c | 2 +- src/rdkafka_coord.h | 2 +- src/rdkafka_error.c | 2 +- src/rdkafka_error.h | 2 +- src/rdkafka_event.c | 2 +- src/rdkafka_event.h | 2 +- src/rdkafka_feature.c | 3 ++- src/rdkafka_feature.h | 2 +- src/rdkafka_fetcher.c | 2 +- src/rdkafka_fetcher.h | 2 +- src/rdkafka_header.c | 2 +- src/rdkafka_header.h | 2 +- src/rdkafka_idempotence.c | 2 +- src/rdkafka_idempotence.h | 2 +- src/rdkafka_int.h | 3 ++- src/rdkafka_interceptor.c | 2 +- src/rdkafka_interceptor.h | 2 +- src/rdkafka_lz4.c | 2 +- src/rdkafka_lz4.h | 2 +- src/rdkafka_metadata.c | 3 ++- src/rdkafka_metadata.h | 3 ++- src/rdkafka_metadata_cache.c | 3 ++- src/rdkafka_mock.c | 3 ++- src/rdkafka_mock.h | 2 +- src/rdkafka_mock_cgrp.c | 3 ++- src/rdkafka_mock_handlers.c | 3 ++- src/rdkafka_mock_int.h | 3 ++- src/rdkafka_msg.c | 3 ++- src/rdkafka_msg.h | 2 +- src/rdkafka_msgbatch.h | 2 +- src/rdkafka_msgset.h | 2 +- src/rdkafka_msgset_reader.c | 2 +- src/rdkafka_msgset_writer.c | 2 +- src/rdkafka_offset.c | 3 ++- src/rdkafka_offset.h | 3 ++- src/rdkafka_op.c | 3 ++- src/rdkafka_op.h | 3 ++- src/rdkafka_partition.c | 3 ++- src/rdkafka_partition.h | 3 ++- src/rdkafka_pattern.c | 2 +- src/rdkafka_pattern.h | 2 +- src/rdkafka_plugin.c | 2 +- src/rdkafka_plugin.h | 2 +- src/rdkafka_proto.h | 2 +- src/rdkafka_protocol.h | 2 +- src/rdkafka_queue.c | 3 ++- src/rdkafka_queue.h | 3 ++- src/rdkafka_range_assignor.c | 3 ++- src/rdkafka_request.c | 3 ++- src/rdkafka_request.h | 3 ++- src/rdkafka_roundrobin_assignor.c | 2 +- src/rdkafka_sasl.c | 3 ++- src/rdkafka_sasl.h | 2 +- src/rdkafka_sasl_cyrus.c | 3 ++- src/rdkafka_sasl_int.h | 2 +- src/rdkafka_sasl_oauthbearer.c | 3 ++- src/rdkafka_sasl_oauthbearer.h | 2 +- src/rdkafka_sasl_oauthbearer_oidc.c | 2 +- src/rdkafka_sasl_oauthbearer_oidc.h | 2 +- src/rdkafka_sasl_plain.c | 2 +- src/rdkafka_sasl_scram.c | 3 ++- src/rdkafka_sasl_win32.c | 3 ++- src/rdkafka_ssl.c | 3 ++- src/rdkafka_ssl.h | 2 +- src/rdkafka_sticky_assignor.c | 3 ++- src/rdkafka_subscription.c | 2 +- src/rdkafka_timer.c | 2 +- src/rdkafka_timer.h | 2 +- src/rdkafka_topic.c | 3 ++- src/rdkafka_topic.h | 3 ++- src/rdkafka_transport.c | 3 ++- src/rdkafka_transport.h | 2 +- src/rdkafka_transport_int.h | 2 +- src/rdkafka_txnmgr.c | 2 +- src/rdkafka_txnmgr.h | 2 +- src/rdkafka_zstd.c | 2 +- src/rdkafka_zstd.h | 2 +- src/rdlist.c | 3 ++- src/rdlist.h | 3 ++- src/rdlog.c | 2 +- src/rdlog.h | 2 +- src/rdmap.c | 2 +- src/rdmap.h | 2 +- src/rdmurmur2.c | 2 +- src/rdmurmur2.h | 2 +- src/rdports.c | 2 +- src/rdports.h | 2 +- src/rdposix.h | 2 +- src/rdrand.c | 2 +- src/rdrand.h | 2 +- src/rdregex.c | 2 +- src/rdregex.h | 2 +- src/rdsignal.h | 2 +- src/rdstring.c | 3 ++- src/rdstring.h | 3 ++- src/rdsysqueue.h | 4 +-- src/rdtime.h | 2 +- src/rdtypes.h | 2 +- src/rdunittest.c | 2 +- src/rdunittest.h | 2 +- src/rdvarint.c | 2 +- src/rdvarint.h | 2 +- src/rdwin32.h | 2 +- src/snappy.h | 2 +- src/statistics_schema.json | 2 +- src/tinycthread_extra.c | 2 +- src/tinycthread_extra.h | 2 +- src/win32_config.h | 2 +- tests/0000-unittests.c | 2 +- tests/0001-multiobj.c | 2 +- tests/0002-unkpart.c | 2 +- tests/0003-msgmaxsize.c | 2 +- tests/0004-conf.c | 2 +- tests/0005-order.c | 2 +- tests/0006-symbols.c | 2 +- tests/0007-autotopic.c | 2 +- tests/0008-reqacks.c | 2 +- tests/0009-mock_cluster.c | 2 +- tests/0011-produce_batch.c | 2 +- tests/0012-produce_consume.c | 2 +- tests/0013-null-msgs.c | 2 +- tests/0014-reconsume-191.c | 2 +- tests/0015-offset_seeks.c | 2 +- tests/0016-client_swname.c | 2 +- tests/0017-compression.c | 2 +- tests/0018-cgrp_term.c | 2 +- tests/0019-list_groups.c | 2 +- tests/0020-destroy_hang.c | 2 +- tests/0021-rkt_destroy.c | 2 +- tests/0022-consume_batch.c | 2 +- tests/0025-timers.c | 2 +- tests/0026-consume_pause.c | 2 +- tests/0028-long_topicnames.c | 2 +- tests/0029-assign_offset.c | 2 +- tests/0030-offset_commit.c | 2 +- tests/0031-get_offsets.c | 2 +- tests/0033-regex_subscribe.c | 3 ++- tests/0034-offset_reset.c | 2 +- tests/0035-api_version.c | 2 +- tests/0036-partial_fetch.c | 2 +- tests/0037-destroy_hang_local.c | 2 +- tests/0038-performance.c | 2 +- tests/0039-event.c | 2 +- tests/0040-io_event.c | 2 +- tests/0041-fetch_max_bytes.c | 2 +- tests/0042-many_topics.c | 2 +- tests/0043-no_connection.c | 2 +- tests/0044-partition_cnt.c | 2 +- tests/0045-subscribe_update.c | 3 ++- tests/0046-rkt_cache.c | 2 +- tests/0047-partial_buf_tmout.c | 2 +- tests/0048-partitioner.c | 2 +- tests/0049-consume_conn_close.c | 2 +- tests/0050-subscribe_adds.c | 2 +- tests/0051-assign_adds.c | 2 +- tests/0052-msg_timestamps.c | 2 +- tests/0053-stats_cb.cpp | 2 +- tests/0054-offset_time.cpp | 2 +- tests/0055-producer_latency.c | 2 +- tests/0056-balanced_group_mt.c | 2 +- tests/0057-invalid_topic.cpp | 2 +- tests/0058-log.cpp | 2 +- tests/0059-bsearch.cpp | 2 +- tests/0060-op_prio.cpp | 2 +- tests/0061-consumer_lag.cpp | 2 +- tests/0062-stats_event.c | 2 +- tests/0063-clusterid.cpp | 2 +- tests/0064-interceptors.c | 2 +- tests/0065-yield.cpp | 2 +- tests/0066-plugins.cpp | 2 +- tests/0067-empty_topic.cpp | 2 +- tests/0068-produce_timeout.c | 2 +- tests/0069-consumer_add_parts.c | 2 +- tests/0070-null_empty.cpp | 2 +- tests/0072-headers_ut.c | 2 +- tests/0073-headers.c | 2 +- tests/0074-producev.c | 2 +- tests/0075-retry.c | 2 +- tests/0076-produce_retry.c | 2 +- tests/0077-compaction.c | 2 +- tests/0078-c_from_cpp.cpp | 2 +- tests/0079-fork.c | 2 +- tests/0080-admin_ut.c | 3 ++- tests/0081-admin.c | 3 ++- tests/0082-fetch_max_bytes.cpp | 4 +-- tests/0083-cb_event.c | 2 +- tests/0084-destroy_flags.c | 3 ++- tests/0085-headers.cpp | 2 +- tests/0086-purge.c | 3 ++- tests/0088-produce_metadata_timeout.c | 2 +- tests/0089-max_poll_interval.c | 3 ++- tests/0090-idempotence.c | 2 +- tests/0091-max_poll_interval_timeout.c | 2 +- tests/0092-mixed_msgver.c | 2 +- tests/0093-holb.c | 2 +- tests/0094-idempotence_msg_timeout.c | 2 +- tests/0095-all_brokers_down.cpp | 2 +- tests/0097-ssl_verify.cpp | 2 +- tests/0098-consumer-txn.cpp | 2 +- tests/0099-commit_metadata.c | 2 +- tests/0100-thread_interceptors.cpp | 2 +- tests/0101-fetch-from-follower.cpp | 2 +- tests/0102-static_group_rebalance.c | 2 +- tests/0103-transactions.c | 2 +- tests/0104-fetch_from_follower_mock.c | 3 ++- tests/0105-transactions_mock.c | 2 +- tests/0106-cgrp_sess_timeout.c | 2 +- tests/0107-topic_recreate.c | 2 +- tests/0109-auto_create_topics.cpp | 2 +- tests/0110-batch_size.cpp | 2 +- tests/0111-delay_create_topics.cpp | 2 +- tests/0112-assign_unknown_part.c | 2 +- tests/0113-cooperative_rebalance.cpp | 2 +- tests/0114-sticky_partitioning.cpp | 2 +- tests/0115-producer_auth.cpp | 2 +- tests/0116-kafkaconsumer_close.cpp | 2 +- tests/0117-mock_errors.c | 2 +- tests/0118-commit_rebalance.c | 2 +- tests/0119-consumer_auth.cpp | 2 +- tests/0120-asymmetric_subscription.c | 2 +- tests/0121-clusterid.c | 2 +- tests/0122-buffer_cleaning_after_rebalance.c | 3 ++- tests/0123-connections_max_idle.c | 2 +- tests/0124-openssl_invalid_engine.c | 2 +- tests/0125-immediate_flush.c | 3 ++- tests/0126-oauthbearer_oidc.c | 2 +- tests/0127-fetch_queue_backoff.cpp | 2 +- tests/0128-sasl_callback_queue.cpp | 2 +- tests/0129-fetch_aborted_msgs.c | 2 +- tests/0130-store_offsets.c | 3 ++- tests/0133-ssl_keys.c | 2 +- tests/0137-barrier_batch_consume.c | 1 + tests/1000-unktopic.c | 2 +- tests/8000-idle.cpp | 2 +- tests/fuzzers/fuzz_regex.c | 2 +- tests/fuzzers/helpers.h | 2 +- tests/interceptor_test/interceptor_test.c | 2 +- tests/java/IncrementalRebalanceCli.java | 2 +- tests/java/Murmur2Cli.java | 2 +- tests/java/TransactionProducerCli.java | 2 +- tests/plugin_test/plugin_test.c | 2 +- tests/rusage.c | 2 +- tests/sockem.c | 2 +- tests/sockem.h | 2 +- tests/sockem_ctrl.c | 2 +- tests/sockem_ctrl.h | 2 +- tests/test.c | 5 ++-- tests/test.h | 3 ++- tests/testcpp.cpp | 2 +- tests/testcpp.h | 2 +- tests/testshared.h | 2 +- tests/xxxx-assign_partition.c | 2 +- tests/xxxx-metadata.cpp | 2 +- win32/librdkafka.autopkg.template | 17 ++++++------- 358 files changed, 486 insertions(+), 415 deletions(-) diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE index ed7b6165fc..648040edd7 100644 --- a/.github/ISSUE_TEMPLATE +++ b/.github/ISSUE_TEMPLATE @@ -1,6 +1,6 @@ -Read the FAQ first: https://github.com/edenhill/librdkafka/wiki/FAQ +Read the FAQ first: https://github.com/confluentinc/librdkafka/wiki/FAQ -Do NOT create issues for questions, use the discussion forum: https://github.com/edenhill/librdkafka/discussions +Do NOT create issues for questions, use the discussion forum: https://github.com/confluentinc/librdkafka/discussions @@ -14,7 +14,7 @@ How to reproduce -**IMPORTANT**: Always try to reproduce the issue on the latest released version (see https://github.com/edenhill/librdkafka/releases), if it can't be reproduced on the latest version the issue has been fixed. +**IMPORTANT**: Always try to reproduce the issue on the latest released version (see https://github.com/confluentinc/librdkafka/releases), if it can't be reproduced on the latest version the issue has been fixed. Checklist diff --git a/CHANGELOG.md b/CHANGELOG.md index acc40f9ffc..87005fc0d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -619,7 +619,7 @@ librdkafka v1.8.0 is a security release: * Upgrade bundled zlib version from 1.2.8 to 1.2.11 in the `librdkafka.redist` NuGet package. The updated zlib version fixes CVEs: CVE-2016-9840, CVE-2016-9841, CVE-2016-9842, CVE-2016-9843 - See https://github.com/edenhill/librdkafka/issues/2934 for more information. + See https://github.com/confluentinc/librdkafka/issues/2934 for more information. * librdkafka now uses [vcpkg](https://vcpkg.io/) for up-to-date Windows dependencies in the `librdkafka.redist` NuGet package: OpenSSL 1.1.1l, zlib 1.2.11, zstd 1.5.0. @@ -1332,4 +1332,4 @@ v1.4.2 is a maintenance release with the following fixes and enhancements: # Older releases -See https://github.com/edenhill/librdkafka/releases +See https://github.com/confluentinc/librdkafka/releases diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index dbbde19c9c..83503cf4a1 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -34,7 +34,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe ## Enforcement -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at rdkafka@edenhill.se. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at cloud-support@confluent.io. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 49aad5ef6b..e6afdc1ea0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -164,7 +164,7 @@ For more information on the test suite see [tests/README.md]. ## How to get your changes into the main sources -File a [pull request on github](https://github.com/edenhill/librdkafka/pulls) +File a [pull request on github](https://github.com/confluentinc/librdkafka/pulls) Your change will be reviewed and discussed there and you will be expected to correct flaws pointed out and update accordingly, or the change diff --git a/Doxyfile b/Doxyfile index 33fc31a4e0..e283b73b48 100644 --- a/Doxyfile +++ b/Doxyfile @@ -1210,7 +1210,7 @@ DOCSET_FEEDNAME = "librdkafka documentation" # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_DOCSET is set to YES. -DOCSET_BUNDLE_ID = se.edenhill.librdkafka +DOCSET_BUNDLE_ID = io.confluent.librdkafka # The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style @@ -1218,13 +1218,13 @@ DOCSET_BUNDLE_ID = se.edenhill.librdkafka # The default value is: org.doxygen.Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. -DOCSET_PUBLISHER_ID = se.edenhill +DOCSET_PUBLISHER_ID = io.confluent # The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. # The default value is: Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. -DOCSET_PUBLISHER_NAME = Magnus Edenhill +DOCSET_PUBLISHER_NAME = Confluent Inc. # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The @@ -1309,7 +1309,7 @@ QCH_FILE = # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. -QHP_NAMESPACE = se.edenhill.librdkafka +QHP_NAMESPACE = io.confluent.librdkafka # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual @@ -1368,7 +1368,7 @@ GENERATE_ECLIPSEHELP = NO # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. -ECLIPSE_DOC_ID = se.edenhill.librdkafka +ECLIPSE_DOC_ID = io.confluent.librdkafka # If you want full control over the layout of the generated HTML pages it might # be necessary to disable the index and replace it with your own. The diff --git a/INTRODUCTION.md b/INTRODUCTION.md index 67504dd133..101a338b55 100644 --- a/INTRODUCTION.md +++ b/INTRODUCTION.md @@ -184,7 +184,7 @@ soon as possible. Lower buffering time leads to smaller batches and larger per-message overheads, increasing network, memory and CPU usage for producers, brokers and consumers. -See [How to decrease message latency](https://github.com/edenhill/librdkafka/wiki/How-to-decrease-message-latency) for more info. +See [How to decrease message latency](https://github.com/confluentinc/librdkafka/wiki/How-to-decrease-message-latency) for more info. #### Latency measurement @@ -2062,9 +2062,4 @@ librdkafka (file a github pull request). ## Community support -You are welcome to direct your users to -[librdkafka's Gitter chat room](http://gitter.im/edenhill/librdkafka) as long as -you monitor the conversions in there to pick up questions specific to your -bindings. -But for the most part user questions are usually generic enough to apply to all -librdkafka bindings. +Community support is offered through GitHub Issues and Discussions. diff --git a/LICENSE b/LICENSE index 193ffaae28..660e3cfb00 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ librdkafka - Apache Kafka C driver library -Copyright (c) 2012-2020, Magnus Edenhill +Copyright (c) 2012-2022, Magnus Edenhill + 2023, Confluent Inc. All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/LICENSES.txt b/LICENSES.txt index 1ab8a1dd4d..d045048a5d 100644 --- a/LICENSES.txt +++ b/LICENSES.txt @@ -2,7 +2,8 @@ LICENSE -------------------------------------------------------------- librdkafka - Apache Kafka C driver library -Copyright (c) 2012-2020, Magnus Edenhill +Copyright (c) 2012-2022, Magnus Edenhill + 2023 Confluent Inc. All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/README.md b/README.md index 640b8791c5..06f196bc0e 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,9 @@ librdkafka - the Apache Kafka C/C++ client library ================================================== Copyright (c) 2012-2022, [Magnus Edenhill](http://www.edenhill.se/). + 2023 [Confluent Inc.](https://www.confluent.io/). -[https://github.com/edenhill/librdkafka](https://github.com/edenhill/librdkafka) +[https://github.com/confluentinc/librdkafka](https://github.com/confluentinc/librdkafka) **librdkafka** is a C library implementation of the [Apache Kafka](https://kafka.apache.org/) protocol, providing Producer, Consumer @@ -25,8 +26,8 @@ affiliation with and is not endorsed by The Apache Software Foundation. * Simple (legacy) consumer * Admin client * Compression: snappy, gzip, lz4, zstd - * [SSL](https://github.com/edenhill/librdkafka/wiki/Using-SSL-with-librdkafka) support - * [SASL](https://github.com/edenhill/librdkafka/wiki/Using-SASL-with-librdkafka) (GSSAPI/Kerberos/SSPI, PLAIN, SCRAM, OAUTHBEARER) support + * [SSL](https://github.com/confluentinc/librdkafka/wiki/Using-SSL-with-librdkafka) support + * [SASL](https://github.com/confluentinc/librdkafka/wiki/Using-SASL-with-librdkafka) (GSSAPI/Kerberos/SSPI, PLAIN, SCRAM, OAUTHBEARER) support * Full list of [supported KIPs](INTRODUCTION.md#supported-kips) * Broker version support: >=0.8 (see [Broker version compatibility](INTRODUCTION.md#broker-version-compatibility)) * Guaranteed API stability for C & C++ APIs (ABI safety guaranteed for C) @@ -39,14 +40,14 @@ affiliation with and is not endorsed by The Apache Software Foundation. # Documentation * Public API in [C header](src/rdkafka.h) and [C++ header](src-cpp/rdkafkacpp.h). - * Introduction and manual in [INTRODUCTION.md](https://github.com/edenhill/librdkafka/blob/master/INTRODUCTION.md). + * Introduction and manual in [INTRODUCTION.md](https://github.com/confluentinc/librdkafka/blob/master/INTRODUCTION.md). * Configuration properties in -[CONFIGURATION.md](https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md). - * Statistics metrics in [STATISTICS.md](https://github.com/edenhill/librdkafka/blob/master/STATISTICS.md). - * [Frequently asked questions](https://github.com/edenhill/librdkafka/wiki). +[CONFIGURATION.md](https://github.com/confluentinc/librdkafka/blob/master/CONFIGURATION.md). + * Statistics metrics in [STATISTICS.md](https://github.com/confluentinc/librdkafka/blob/master/STATISTICS.md). + * [Frequently asked questions](https://github.com/confluentinc/librdkafka/wiki). * Step-by-step tutorial [Getting Started with Apache Kafka and C/C++](https://developer.confluent.io/get-started/c/). -**NOTE**: The `master` branch is actively developed, use latest [release](https://github.com/edenhill/librdkafka/releases) for production use. +**NOTE**: The `master` branch is actively developed, use latest [release](https://github.com/confluentinc/librdkafka/releases) for production use. # Installation @@ -160,11 +161,11 @@ Commercial support is available from [Confluent Inc](https://www.confluent.io/) ## Community support -**Only the [latest official release](https://github.com/edenhill/librdkafka/releases) is supported for community members.** +**Only the [latest official release](https://github.com/confluentinc/librdkafka/releases) is supported for community members.** -File bug reports and feature requests using [GitHub Issues](https://github.com/edenhill/librdkafka/issues). +File bug reports and feature requests using [GitHub Issues](https://github.com/confluentinc/librdkafka/issues). -Questions and discussions are welcome on the [Discussions](https://github.com/edenhill/librdkafka/discussions) forum, and on the [Confluent Community slack](https://launchpass.com/confluentcommunity) #clients channel. +Questions and discussions are welcome on the [Discussions](https://github.com/confluentinc/librdkafka/discussions) forum, and on the [Confluent Community slack](https://launchpass.com/confluentcommunity) #clients channel. # Language bindings # @@ -195,4 +196,4 @@ Questions and discussions are welcome on the [Discussions](https://github.com/ed * Swift: [Perfect-Kafka](https://github.com/PerfectlySoft/Perfect-Kafka) -See [Powered by librdkafka](https://github.com/edenhill/librdkafka/wiki/Powered-by-librdkafka) for an incomplete list of librdkafka users. +See [Powered by librdkafka](https://github.com/confluentinc/librdkafka/wiki/Powered-by-librdkafka) for an incomplete list of librdkafka users. diff --git a/configure.self b/configure.self index bb0a975c94..3c49956b46 100644 --- a/configure.self +++ b/configure.self @@ -4,7 +4,7 @@ mkl_meta_set "description" "name" "librdkafka" mkl_meta_set "description" "oneline" "The Apache Kafka C/C++ library" mkl_meta_set "description" "long" "Full Apache Kafka protocol support, including producer and consumer" -mkl_meta_set "description" "copyright" "Copyright (c) 2012-2019 Magnus Edenhill" +mkl_meta_set "description" "copyright" "Copyright (c) 2012-2022, Magnus Edenhill, 2023, Confluent Inc." # Enable generation of pkg-config .pc file mkl_mkvar_set "" GEN_PKG_CONFIG y diff --git a/debian/control b/debian/control index bddaf4724d..c14b664f3e 100644 --- a/debian/control +++ b/debian/control @@ -5,7 +5,7 @@ Uploaders: Christos Trochalakis Build-Depends: debhelper (>= 9), zlib1g-dev, libssl-dev, libsasl2-dev, liblz4-dev, python3 Standards-Version: 3.9.7 Section: libs -Homepage: https://github.com/edenhill/librdkafka +Homepage: https://github.com/confluentinc/librdkafka Vcs-Git: https://anonscm.debian.org/cgit/pkg-kafka/librdkafka.git -b debian Vcs-Browser: https://anonscm.debian.org/cgit/pkg-kafka/librdkafka.git diff --git a/debian/copyright b/debian/copyright index aa6c33cce4..965cbae058 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,6 +1,6 @@ Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: librdkafka -Source: https://github.com/edenhill/librdkafka +Source: https://github.com/confluentinc/librdkafka License: BSD-2-clause Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ License: BSD-2-clause POSSIBILITY OF SUCH DAMAGE. Files: * -Copyright: 2012-2015, Magnus Edenhill +Copyright: 2012-2022, Magnus Edenhill; 2023, Confluent Inc. License: BSD-2-clause Files: src/rdcrc32.c src/rdcrc32.h @@ -40,7 +40,7 @@ License: MIT . The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - . + . THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/debian/watch b/debian/watch index 7b3bdea113..ed5855f0c9 100644 --- a/debian/watch +++ b/debian/watch @@ -1,2 +1,2 @@ version=3 -https://github.com/edenhill/librdkafka/tags .*/v?(\d[\d\.]*)\.tar\.gz +https://github.com/confluentinc/librdkafka/tags .*/v?(\d[\d\.]*)\.tar\.gz diff --git a/dev-conf.sh b/dev-conf.sh index 23931a77e6..ebc4451b94 100755 --- a/dev-conf.sh +++ b/dev-conf.sh @@ -2,7 +2,7 @@ # # librdkafka - Apache Kafka C library # -# Copyright (c) 2018 Magnus Edenhill +# Copyright (c) 2018-2022, Magnus Edenhill # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/examples/consumer.c b/examples/consumer.c index 21b27ca782..8ce6f77f4d 100644 --- a/examples/consumer.c +++ b/examples/consumer.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019, Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +30,7 @@ /** * Simple high-level balanced Apache Kafka consumer * using the Kafka driver from librdkafka - * (https://github.com/edenhill/librdkafka) + * (https://github.com/confluentinc/librdkafka) */ #include diff --git a/examples/delete_records.c b/examples/delete_records.c index 2660996a57..5a7cc6848e 100644 --- a/examples/delete_records.c +++ b/examples/delete_records.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/examples/idempotent_producer.c b/examples/idempotent_producer.c index 91b42a4b9d..bb34610c42 100644 --- a/examples/idempotent_producer.c +++ b/examples/idempotent_producer.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019, Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/examples/openssl_engine_example.cpp b/examples/openssl_engine_example.cpp index 401857e6b2..7279747176 100644 --- a/examples/openssl_engine_example.cpp +++ b/examples/openssl_engine_example.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2021, Magnus Edenhill + * Copyright (c) 2021-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/examples/producer.c b/examples/producer.c index b6fb711500..40e77b79ed 100644 --- a/examples/producer.c +++ b/examples/producer.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2017, Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +29,7 @@ /** * Simple Apache Kafka producer * using the Kafka driver from librdkafka - * (https://github.com/edenhill/librdkafka) + * (https://github.com/confluentinc/librdkafka) */ #include diff --git a/examples/producer.cpp b/examples/producer.cpp index d4a8a0c49e..76560eb6be 100755 --- a/examples/producer.cpp +++ b/examples/producer.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019, Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +29,7 @@ /** * Apache Kafka producer * using the Kafka driver from librdkafka - * (https://github.com/edenhill/librdkafka) + * (https://github.com/confluentinc/librdkafka) */ #include diff --git a/examples/rdkafka_complex_consumer_example.c b/examples/rdkafka_complex_consumer_example.c index 1632b30305..ac56e659f2 100644 --- a/examples/rdkafka_complex_consumer_example.c +++ b/examples/rdkafka_complex_consumer_example.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2015, Magnus Edenhill + * Copyright (c) 2015-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +29,7 @@ /** * Apache Kafka high level consumer example program * using the Kafka driver from librdkafka - * (https://github.com/edenhill/librdkafka) + * (https://github.com/confluentinc/librdkafka) */ #include diff --git a/examples/rdkafka_complex_consumer_example.cpp b/examples/rdkafka_complex_consumer_example.cpp index b4f158cbd9..dc193df89d 100644 --- a/examples/rdkafka_complex_consumer_example.cpp +++ b/examples/rdkafka_complex_consumer_example.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2014, Magnus Edenhill + * Copyright (c) 2014-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +29,7 @@ /** * Apache Kafka consumer & producer example programs * using the Kafka driver from librdkafka - * (https://github.com/edenhill/librdkafka) + * (https://github.com/confluentinc/librdkafka) */ #include diff --git a/examples/rdkafka_consume_batch.cpp b/examples/rdkafka_consume_batch.cpp index 576b396f87..d916630352 100644 --- a/examples/rdkafka_consume_batch.cpp +++ b/examples/rdkafka_consume_batch.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018, Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +29,7 @@ /** * Apache Kafka consumer & producer example programs * using the Kafka driver from librdkafka - * (https://github.com/edenhill/librdkafka) + * (https://github.com/confluentinc/librdkafka) * * This example shows how to read batches of messages. * Note that messages are fetched from the broker in batches regardless diff --git a/examples/rdkafka_example.c b/examples/rdkafka_example.c index 91415318ac..b4fc4793f4 100644 --- a/examples/rdkafka_example.c +++ b/examples/rdkafka_example.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +29,7 @@ /** * Apache Kafka consumer & producer example programs * using the Kafka driver from librdkafka - * (https://github.com/edenhill/librdkafka) + * (https://github.com/confluentinc/librdkafka) */ #include diff --git a/examples/rdkafka_example.cpp b/examples/rdkafka_example.cpp index 91c3440b3d..e4c832b064 100644 --- a/examples/rdkafka_example.cpp +++ b/examples/rdkafka_example.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2014, Magnus Edenhill + * Copyright (c) 2014-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +29,7 @@ /** * Apache Kafka consumer & producer example programs * using the Kafka driver from librdkafka - * (https://github.com/edenhill/librdkafka) + * (https://github.com/confluentinc/librdkafka) */ #include diff --git a/examples/rdkafka_performance.c b/examples/rdkafka_performance.c index a12bb74710..dab0b06b8f 100644 --- a/examples/rdkafka_performance.c +++ b/examples/rdkafka_performance.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +30,7 @@ /** * Apache Kafka consumer & producer performance tester * using the Kafka driver from librdkafka - * (https://github.com/edenhill/librdkafka) + * (https://github.com/confluentinc/librdkafka) */ #ifdef _MSC_VER diff --git a/examples/transactions-older-broker.c b/examples/transactions-older-broker.c index e9f8d06f75..711d51a8a3 100644 --- a/examples/transactions-older-broker.c +++ b/examples/transactions-older-broker.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/examples/transactions.c b/examples/transactions.c index 0a8b9a8cf0..705e504e96 100644 --- a/examples/transactions.c +++ b/examples/transactions.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/examples/win_ssl_cert_store.cpp b/examples/win_ssl_cert_store.cpp index a80dfea30c..5158f961b1 100644 --- a/examples/win_ssl_cert_store.cpp +++ b/examples/win_ssl_cert_store.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019, Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/lds-gen.py b/lds-gen.py index 44c718d130..aca163a559 100755 --- a/lds-gen.py +++ b/lds-gen.py @@ -2,7 +2,7 @@ # # librdkafka - Apache Kafka C library # -# Copyright (c) 2018 Magnus Edenhill +# Copyright (c) 2018-2022, Magnus Edenhill # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/mklove/modules/configure.base b/mklove/modules/configure.base index 1e216692bc..77cee61a68 100644 --- a/mklove/modules/configure.base +++ b/mklove/modules/configure.base @@ -2208,7 +2208,7 @@ function mkl_require { MKL_USAGE="Usage: ./configure [OPTIONS...] mklove configure script - mklove, not autoconf - Copyright (c) 2014-2019 Magnus Edenhill - https://github.com/edenhill/mklove + Copyright (c) 2014-2023, Magnus Edenhill - https://github.com/edenhill/mklove " function mkl_usage { diff --git a/packaging/RELEASE.md b/packaging/RELEASE.md index 930636db47..36cf38198a 100644 --- a/packaging/RELEASE.md +++ b/packaging/RELEASE.md @@ -149,7 +149,7 @@ is finished, then download the relevant artifacts for further use, see ## Publish release on github -Create a release on github by going to https://github.com/edenhill/librdkafka/releases +Create a release on github by going to https://github.com/confluentinc/librdkafka/releases and Draft a new release. Name the release the same as the final release tag (e.g., `v1.9.0`) and set the tag to the same. diff --git a/packaging/archlinux/PKGBUILD b/packaging/archlinux/PKGBUILD index 7063d5cef8..36fef055b7 100644 --- a/packaging/archlinux/PKGBUILD +++ b/packaging/archlinux/PKGBUILD @@ -2,10 +2,10 @@ pkgname=librdkafka pkgver=1.0.0.RC5.r11.g3cf68480 pkgrel=1 pkgdesc='The Apache Kafka C/C++ client library' -url='https://github.com/edenhill/librdkafka' +url='https://github.com/confluentinc/librdkafka' license=('BSD') arch=('x86_64') -source=('git+https://github.com/edenhill/librdkafka#branch=master') +source=('git+https://github.com/confluentinc/librdkafka#branch=master') sha256sums=('SKIP') depends=(glibc libsasl lz4 openssl zlib zstd) makedepends=(bash git python3) diff --git a/packaging/debian/control b/packaging/debian/control index 510db8f231..87f8a8490f 100644 --- a/packaging/debian/control +++ b/packaging/debian/control @@ -4,9 +4,9 @@ Maintainer: Faidon Liambotis Build-Depends: debhelper (>= 9), zlib1g-dev, libssl-dev, libsasl2-dev, python3 Standards-Version: 3.9.6 Section: libs -Homepage: https://github.com/edenhill/librdkafka -Vcs-Git: git://github.com/edenhill/librdkafka.git -b debian -Vcs-Browser: https://github.com/edenhill/librdkafka/tree/debian +Homepage: https://github.com/confluentinc/librdkafka +Vcs-Git: git://github.com/confluentinc/librdkafka.git -b debian +Vcs-Browser: https://github.com/confluentinc/librdkafka/tree/debian Package: librdkafka1 Architecture: any diff --git a/packaging/debian/copyright b/packaging/debian/copyright index 20885d9f3b..2ee03af7a0 100644 --- a/packaging/debian/copyright +++ b/packaging/debian/copyright @@ -1,6 +1,6 @@ Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: librdkafka -Source: https://github.com/edenhill/librdkafka +Source: https://github.com/confluentinc/librdkafka License: BSD-2-clause Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ License: BSD-2-clause POSSIBILITY OF SUCH DAMAGE. Files: * -Copyright: 2012-2015, Magnus Edenhill +Copyright: 2012-2022, Magnus Edenhill; 2023 Confluent Inc. License: BSD-2-clause Files: src/rdcrc32.c src/rdcrc32.h @@ -40,7 +40,7 @@ License: MIT . The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - . + . THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/packaging/debian/librdkafka.dsc b/packaging/debian/librdkafka.dsc index 447b9e656f..1514513450 100644 --- a/packaging/debian/librdkafka.dsc +++ b/packaging/debian/librdkafka.dsc @@ -3,11 +3,11 @@ Source: librdkafka Binary: librdkafka1, librdkafka-dev, librdkafka1-dbg Architecture: any Version: 0.9.1-1pre1 -Maintainer: Magnus Edenhill -Homepage: https://github.com/edenhill/librdkafka +Maintainer: Confluent Inc. +Homepage: https://github.com/confluentinc/librdkafka Standards-Version: 3.9.6 -Vcs-Browser: https://github.com/edenhill/librdkafka/tree/master -Vcs-Git: git://github.com/edenhill/librdkafka.git -b master +Vcs-Browser: https://github.com/confluentinc/librdkafka/tree/master +Vcs-Git: git://github.com/confluentinc/librdkafka.git -b master Build-Depends: debhelper (>= 9), zlib1g-dev, libssl-dev, libsasl2-dev, python3 Package-List: librdkafka-dev deb libdevel optional arch=any diff --git a/packaging/debian/watch b/packaging/debian/watch index fc9aec86fc..f08e19f895 100644 --- a/packaging/debian/watch +++ b/packaging/debian/watch @@ -1,2 +1,2 @@ version=3 -http://github.com/edenhill/librdkafka/tags .*/(\d[\d\.]*)\.tar\.gz +http://github.com/confluentinc/librdkafka/tags .*/(\d[\d\.]*)\.tar\.gz diff --git a/packaging/homebrew/brew-update-pr.sh b/packaging/homebrew/brew-update-pr.sh index f756159cda..9c6cd838cf 100755 --- a/packaging/homebrew/brew-update-pr.sh +++ b/packaging/homebrew/brew-update-pr.sh @@ -27,5 +27,5 @@ fi set -eu brew bump-formula-pr $DRY_RUN --strict \ - --url=https://github.com/edenhill/librdkafka/archive/${TAG}.tar.gz \ + --url=https://github.com/confluentinc/librdkafka/archive/${TAG}.tar.gz \ librdkafka diff --git a/packaging/nuget/README.md b/packaging/nuget/README.md index 87b1769302..d4394afb88 100644 --- a/packaging/nuget/README.md +++ b/packaging/nuget/README.md @@ -27,6 +27,12 @@ The finalized nuget package maybe uploaded manually to NuGet.org 2. Wait for CI builds to finish, monitor the builds here: + New builds + + * https://confluentinc.semaphoreci.com/projects/librdkafka + + Previous builds + * https://travis-ci.org/edenhill/librdkafka * https://ci.appveyor.com/project/edenhill/librdkafka diff --git a/packaging/rpm/librdkafka.spec b/packaging/rpm/librdkafka.spec index 4f9e8c0d0e..ac2ddd0114 100644 --- a/packaging/rpm/librdkafka.spec +++ b/packaging/rpm/librdkafka.spec @@ -6,7 +6,7 @@ Release: %{__release}%{?dist} Summary: The Apache Kafka C library Group: Development/Libraries/C and C++ License: BSD-2-Clause -URL: https://github.com/edenhill/librdkafka +URL: https://github.com/confluentinc/librdkafka Source: librdkafka-%{version}.tar.gz BuildRequires: zlib-devel libstdc++-devel gcc >= 4.1 gcc-c++ cyrus-sasl-devel diff --git a/packaging/tools/build-deb-package.sh b/packaging/tools/build-deb-package.sh index d9cad6d25a..86b806ee92 100755 --- a/packaging/tools/build-deb-package.sh +++ b/packaging/tools/build-deb-package.sh @@ -35,8 +35,8 @@ git clone /v librdkafka pushd librdkafka -export DEBEMAIL="librdkafka packaging " -git config user.email "rdkafka@edenhill.se" +export DEBEMAIL="librdkafka packaging " +git config user.email "cloud-support@confluent.io" git config user.name "librdkafka packaging" DEB_BRANCH=origin/confluent-debian diff --git a/packaging/tools/gh-release-checksums.py b/packaging/tools/gh-release-checksums.py index e7259dc202..5b51f38325 100755 --- a/packaging/tools/gh-release-checksums.py +++ b/packaging/tools/gh-release-checksums.py @@ -24,8 +24,8 @@ print("Release asset checksums:") for ftype in ["zip", "tar.gz"]: - url = "https://github.com/edenhill/librdkafka/archive/{}.{}".format( - tag, ftype) + url = "https://github.com/confluentinc/" + \ + "librdkafka/archive/{}.{}".format(tag, ftype) h = hashlib.sha256() diff --git a/src-cpp/ConfImpl.cpp b/src-cpp/ConfImpl.cpp index 53d7b30c56..4f1f709082 100644 --- a/src-cpp/ConfImpl.cpp +++ b/src-cpp/ConfImpl.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C/C++ library * - * Copyright (c) 2014 Magnus Edenhill + * Copyright (c) 2014-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src-cpp/ConsumerImpl.cpp b/src-cpp/ConsumerImpl.cpp index b7f5e3b220..a467acfb0d 100644 --- a/src-cpp/ConsumerImpl.cpp +++ b/src-cpp/ConsumerImpl.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C/C++ library * - * Copyright (c) 2014 Magnus Edenhill + * Copyright (c) 2014-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src-cpp/HandleImpl.cpp b/src-cpp/HandleImpl.cpp index 356af369bf..8d16c0d198 100644 --- a/src-cpp/HandleImpl.cpp +++ b/src-cpp/HandleImpl.cpp @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C/C++ library * - * Copyright (c) 2014 Magnus Edenhill + * Copyright (c) 2014-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src-cpp/HeadersImpl.cpp b/src-cpp/HeadersImpl.cpp index b567ef36c0..2b29488dc5 100644 --- a/src-cpp/HeadersImpl.cpp +++ b/src-cpp/HeadersImpl.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C/C++ library * - * Copyright (c) 2014 Magnus Edenhill + * Copyright (c) 2014-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src-cpp/KafkaConsumerImpl.cpp b/src-cpp/KafkaConsumerImpl.cpp index 6f3b81c727..984710b214 100644 --- a/src-cpp/KafkaConsumerImpl.cpp +++ b/src-cpp/KafkaConsumerImpl.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C/C++ library * - * Copyright (c) 2015 Magnus Edenhill + * Copyright (c) 2015-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src-cpp/MessageImpl.cpp b/src-cpp/MessageImpl.cpp index c6d83150fd..8261b1f6e1 100644 --- a/src-cpp/MessageImpl.cpp +++ b/src-cpp/MessageImpl.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C/C++ library * - * Copyright (c) 2014 Magnus Edenhill + * Copyright (c) 2014-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src-cpp/MetadataImpl.cpp b/src-cpp/MetadataImpl.cpp index 62cbf9042e..df58d4dbd7 100644 --- a/src-cpp/MetadataImpl.cpp +++ b/src-cpp/MetadataImpl.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C/C++ library * - * Copyright (c) 2014 Magnus Edenhill + * Copyright (c) 2014-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src-cpp/ProducerImpl.cpp b/src-cpp/ProducerImpl.cpp index 8300dfb3b6..88752156c1 100644 --- a/src-cpp/ProducerImpl.cpp +++ b/src-cpp/ProducerImpl.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C/C++ library * - * Copyright (c) 2014 Magnus Edenhill + * Copyright (c) 2014-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src-cpp/QueueImpl.cpp b/src-cpp/QueueImpl.cpp index 19ebce9d68..7148d72011 100644 --- a/src-cpp/QueueImpl.cpp +++ b/src-cpp/QueueImpl.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C/C++ library * - * Copyright (c) 2014 Magnus Edenhill + * Copyright (c) 2014-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src-cpp/RdKafka.cpp b/src-cpp/RdKafka.cpp index b6cb33c288..c7c41ec984 100644 --- a/src-cpp/RdKafka.cpp +++ b/src-cpp/RdKafka.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C/C++ library * - * Copyright (c) 2014 Magnus Edenhill + * Copyright (c) 2014-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src-cpp/TopicImpl.cpp b/src-cpp/TopicImpl.cpp index bf9734df94..6868b5932d 100644 --- a/src-cpp/TopicImpl.cpp +++ b/src-cpp/TopicImpl.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C/C++ library * - * Copyright (c) 2014 Magnus Edenhill + * Copyright (c) 2014-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src-cpp/TopicPartitionImpl.cpp b/src-cpp/TopicPartitionImpl.cpp index 90ef820bf6..d453d96425 100644 --- a/src-cpp/TopicPartitionImpl.cpp +++ b/src-cpp/TopicPartitionImpl.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C/C++ library * - * Copyright (c) 2015 Magnus Edenhill + * Copyright (c) 2015-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src-cpp/rdkafkacpp.h b/src-cpp/rdkafkacpp.h index 8b5bcf3d40..1695cae8a6 100644 --- a/src-cpp/rdkafkacpp.h +++ b/src-cpp/rdkafkacpp.h @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C/C++ library * - * Copyright (c) 2014-2022 Magnus Edenhill + * Copyright (c) 2014-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src-cpp/rdkafkacpp_int.h b/src-cpp/rdkafkacpp_int.h index d6db4f33b7..167b83a072 100644 --- a/src-cpp/rdkafkacpp_int.h +++ b/src-cpp/rdkafkacpp_int.h @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C/C++ library * - * Copyright (c) 2014 Magnus Edenhill + * Copyright (c) 2014-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/crc32c.h b/src/crc32c.h index 21c7badc7f..d768afc676 100644 --- a/src/crc32c.h +++ b/src/crc32c.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/generate_proto.sh b/src/generate_proto.sh index c7023f47ab..4402022607 100755 --- a/src/generate_proto.sh +++ b/src/generate_proto.sh @@ -2,7 +2,7 @@ # # librdkafka - Apache Kafka C library # -# Copyright (c) 2020 Magnus Edenhill +# Copyright (c) 2020-2022, Magnus Edenhill # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/src/rd.h b/src/rd.h index 670605de44..fd6c307fd0 100644 --- a/src/rd.h +++ b/src/rd.h @@ -1,7 +1,7 @@ /* * librd - Rapid Development C library * - * Copyright (c) 2012, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdaddr.c b/src/rdaddr.c index 092406233b..6fb2c66ca5 100644 --- a/src/rdaddr.c +++ b/src/rdaddr.c @@ -1,7 +1,7 @@ /* * librd - Rapid Development C library * - * Copyright (c) 2012, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdaddr.h b/src/rdaddr.h index c8574d0194..0c407a2969 100644 --- a/src/rdaddr.h +++ b/src/rdaddr.h @@ -1,7 +1,7 @@ /* * librd - Rapid Development C library * - * Copyright (c) 2012, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdatomic.h b/src/rdatomic.h index aa7d3d7705..4b97dd7d08 100644 --- a/src/rdatomic.h +++ b/src/rdatomic.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2014-2016 Magnus Edenhill + * Copyright (c) 2014-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdavg.h b/src/rdavg.h index a170e8da53..55469e2466 100644 --- a/src/rdavg.h +++ b/src/rdavg.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018 Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdavl.c b/src/rdavl.c index f25251de8e..0bb4118096 100644 --- a/src/rdavl.c +++ b/src/rdavl.c @@ -1,7 +1,7 @@ /* * librd - Rapid Development C library * - * Copyright (c) 2012-2016, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdavl.h b/src/rdavl.h index f3e539242b..dc6fe2e2c9 100644 --- a/src/rdavl.h +++ b/src/rdavl.h @@ -1,7 +1,7 @@ /* * librd - Rapid Development C library * - * Copyright (c) 2012-2016, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdbuf.c b/src/rdbuf.c index 1392cf7b18..6df64a9dee 100644 --- a/src/rdbuf.c +++ b/src/rdbuf.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdbuf.h b/src/rdbuf.h index 1ef30e4a95..90d61401b0 100644 --- a/src/rdbuf.h +++ b/src/rdbuf.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdcrc32.c b/src/rdcrc32.c index 2a6e126c14..f7a6885504 100644 --- a/src/rdcrc32.c +++ b/src/rdcrc32.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018 Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdcrc32.h b/src/rdcrc32.h index c3195fca62..676cd7d236 100644 --- a/src/rdcrc32.h +++ b/src/rdcrc32.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018 Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rddl.c b/src/rddl.c index 785e28c486..826d0a7912 100644 --- a/src/rddl.c +++ b/src/rddl.c @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rddl.h b/src/rddl.h index eaf6eb6d5e..d1176c3e52 100644 --- a/src/rddl.h +++ b/src/rddl.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdendian.h b/src/rdendian.h index 613d44bfaf..8a1c4148ce 100644 --- a/src/rdendian.h +++ b/src/rdendian.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015 Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdfloat.h b/src/rdfloat.h index 310045f0ea..3868d35f5d 100644 --- a/src/rdfloat.h +++ b/src/rdfloat.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2018, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdfnv1a.c b/src/rdfnv1a.c index e951ec59f2..c412348c2a 100644 --- a/src/rdfnv1a.c +++ b/src/rdfnv1a.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2020, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdfnv1a.h b/src/rdfnv1a.h index 8df66b0d62..8d956ab68c 100644 --- a/src/rdfnv1a.h +++ b/src/rdfnv1a.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020 Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdgz.c b/src/rdgz.c index 794bd9cc1c..d820bcfcac 100644 --- a/src/rdgz.c +++ b/src/rdgz.c @@ -1,7 +1,7 @@ /* * librd - Rapid Development C library * - * Copyright (c) 2012, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdgz.h b/src/rdgz.h index 10d661cb3b..1161091f29 100644 --- a/src/rdgz.h +++ b/src/rdgz.h @@ -1,7 +1,7 @@ /* * librd - Rapid Development C library * - * Copyright (c) 2012, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdhdrhistogram.c b/src/rdhdrhistogram.c index 3f2b6758b5..08240ac7a3 100644 --- a/src/rdhdrhistogram.c +++ b/src/rdhdrhistogram.c @@ -31,7 +31,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018, Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdhdrhistogram.h b/src/rdhdrhistogram.h index 868614b7b0..7bfae84f4b 100644 --- a/src/rdhdrhistogram.h +++ b/src/rdhdrhistogram.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018, Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdhttp.c b/src/rdhttp.c index 7457a7fbe4..cea2d1c97d 100644 --- a/src/rdhttp.c +++ b/src/rdhttp.c @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2021 Magnus Edenhill + * Copyright (c) 2021-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdhttp.h b/src/rdhttp.h index 80512e5ac2..9691cc800e 100644 --- a/src/rdhttp.h +++ b/src/rdhttp.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2021 Magnus Edenhill + * Copyright (c) 2021-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdinterval.h b/src/rdinterval.h index 4283376462..d43ff95358 100644 --- a/src/rdinterval.h +++ b/src/rdinterval.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018 Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka.c b/src/rdkafka.c index 2a5e040b68..0311285587 100644 --- a/src/rdkafka.c +++ b/src/rdkafka.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka.h b/src/rdkafka.h index dbb7e7152e..e53123d3cd 100644 --- a/src/rdkafka.h +++ b/src/rdkafka.h @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2022 Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -2101,7 +2102,7 @@ void rd_kafka_conf_set_log_cb(rd_kafka_conf_t *conf, * rd_kafka_conf_set_opaque(). * * For more information on the format of \p json, see - * https://github.com/edenhill/librdkafka/wiki/Statistics + * https://github.com/confluentinc/librdkafka/wiki/Statistics * * If the application wishes to hold on to the \p json pointer and free * it at a later time it must return 1 from the \p stats_cb. diff --git a/src/rdkafka_admin.c b/src/rdkafka_admin.c index 2226899477..35f4f150d8 100644 --- a/src/rdkafka_admin.c +++ b/src/rdkafka_admin.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018 Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_admin.h b/src/rdkafka_admin.h index 62fe9e87a3..3935c00c04 100644 --- a/src/rdkafka_admin.h +++ b/src/rdkafka_admin.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018 Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_assignment.c b/src/rdkafka_assignment.c index 2afc648193..3b0d7e83d7 100644 --- a/src/rdkafka_assignment.c +++ b/src/rdkafka_assignment.c @@ -1,7 +1,8 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2020 Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill + * 2023 Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_assignment.h b/src/rdkafka_assignment.h index fa51bb10c3..1f73c4ede8 100644 --- a/src/rdkafka_assignment.h +++ b/src/rdkafka_assignment.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2020 Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_assignor.c b/src/rdkafka_assignor.c index fe5615ad7c..607a7bfd5a 100644 --- a/src/rdkafka_assignor.c +++ b/src/rdkafka_assignor.c @@ -1,7 +1,8 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2015 Magnus Edenhill + * Copyright (c) 2015-2022, Magnus Edenhill + * 2023 Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_assignor.h b/src/rdkafka_assignor.h index 9d01d38065..6797e70b11 100644 --- a/src/rdkafka_assignor.h +++ b/src/rdkafka_assignor.h @@ -1,7 +1,8 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2015 Magnus Edenhill + * Copyright (c) 2015-2022, Magnus Edenhill + * 2023 Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_aux.c b/src/rdkafka_aux.c index da565d1594..8f4f2b9f05 100644 --- a/src/rdkafka_aux.c +++ b/src/rdkafka_aux.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018 Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill + * 2023 Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_aux.h b/src/rdkafka_aux.h index 7d5339bd73..cc9db3bbda 100644 --- a/src/rdkafka_aux.h +++ b/src/rdkafka_aux.h @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018 Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill + * 2023 Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_background.c b/src/rdkafka_background.c index c69ec1767d..a9c96606c0 100644 --- a/src/rdkafka_background.c +++ b/src/rdkafka_background.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018 Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_broker.c b/src/rdkafka_broker.c index cb319aec11..da6a2b1803 100644 --- a/src/rdkafka_broker.c +++ b/src/rdkafka_broker.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023 Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_broker.h b/src/rdkafka_broker.h index be7ce0536b..1e03dba850 100644 --- a/src/rdkafka_broker.h +++ b/src/rdkafka_broker.h @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012,2013 Magnus Edenhill + * Copyright (c) 2012,2022, Magnus Edenhill + * 2023 Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_buf.c b/src/rdkafka_buf.c index 5a0e131e8b..e31ae00a29 100644 --- a/src/rdkafka_buf.c +++ b/src/rdkafka_buf.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_buf.h b/src/rdkafka_buf.h index 9cb30a0df8..cedcf22919 100644 --- a/src/rdkafka_buf.h +++ b/src/rdkafka_buf.h @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023 Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_cert.c b/src/rdkafka_cert.c index 2a19e45493..a14814d0a1 100644 --- a/src/rdkafka_cert.c +++ b/src/rdkafka_cert.c @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2019 Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_cert.h b/src/rdkafka_cert.h index b53f46c010..819773ba30 100644 --- a/src/rdkafka_cert.h +++ b/src/rdkafka_cert.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2019 Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_cgrp.c b/src/rdkafka_cgrp.c index 48ef02514c..8d150fc59b 100644 --- a/src/rdkafka_cgrp.c +++ b/src/rdkafka_cgrp.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023 Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_cgrp.h b/src/rdkafka_cgrp.h index 4fa51e5489..ff62e8d285 100644 --- a/src/rdkafka_cgrp.h +++ b/src/rdkafka_cgrp.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_conf.c b/src/rdkafka_conf.c index e5c1415fce..285c8e4458 100644 --- a/src/rdkafka_conf.c +++ b/src/rdkafka_conf.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2022 Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -897,11 +897,13 @@ static const struct rd_kafka_property rd_kafka_properties[] = { "Java TrustStores are not supported, use `ssl.ca.location` " "and a certificate file instead. " "See " - "https://github.com/edenhill/librdkafka/wiki/Using-SSL-with-librdkafka " + "https://github.com/confluentinc/librdkafka/" + "wiki/Using-SSL-with-librdkafka " "for more information."}, {_RK_GLOBAL, "sasl.jaas.config", _RK_C_INVALID, _RK(dummy), "Java JAAS configuration is not supported, see " - "https://github.com/edenhill/librdkafka/wiki/Using-SASL-with-librdkafka " + "https://github.com/confluentinc/librdkafka/" + "wiki/Using-SASL-with-librdkafka " "for more information."}, {_RK_GLOBAL | _RK_HIGH, "sasl.mechanisms", _RK_C_STR, _RK(sasl.mechanisms), diff --git a/src/rdkafka_conf.h b/src/rdkafka_conf.h index 2d625ce05f..6a79515c2a 100644 --- a/src/rdkafka_conf.h +++ b/src/rdkafka_conf.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2014-2018 Magnus Edenhill + * Copyright (c) 2014-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_confval.h b/src/rdkafka_confval.h index 3f2bad549e..ca82616957 100644 --- a/src/rdkafka_confval.h +++ b/src/rdkafka_confval.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2014-2018 Magnus Edenhill + * Copyright (c) 2014-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_coord.c b/src/rdkafka_coord.c index 9e41bab72a..a880f23a46 100644 --- a/src/rdkafka_coord.c +++ b/src/rdkafka_coord.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019 Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_coord.h b/src/rdkafka_coord.h index 4e00a552bc..a04ca222e2 100644 --- a/src/rdkafka_coord.h +++ b/src/rdkafka_coord.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019 Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_error.c b/src/rdkafka_error.c index 4a218daffe..680593630d 100644 --- a/src/rdkafka_error.c +++ b/src/rdkafka_error.c @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2020 Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_error.h b/src/rdkafka_error.h index 79984f5efb..4b4d912f30 100644 --- a/src/rdkafka_error.h +++ b/src/rdkafka_error.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2020 Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_event.c b/src/rdkafka_event.c index ffd1a17805..58b0dc37b2 100644 --- a/src/rdkafka_event.c +++ b/src/rdkafka_event.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016 Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_event.h b/src/rdkafka_event.h index 3f9c22e34b..e5447f1467 100644 --- a/src/rdkafka_event.h +++ b/src/rdkafka_event.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016 Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_feature.c b/src/rdkafka_feature.c index cc7fafd879..b32cdf689d 100644 --- a/src/rdkafka_feature.c +++ b/src/rdkafka_feature.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016, Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_feature.h b/src/rdkafka_feature.h index a651a07df0..9597956ee8 100644 --- a/src/rdkafka_feature.h +++ b/src/rdkafka_feature.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016, Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_fetcher.c b/src/rdkafka_fetcher.c index 7870ed6638..ed8702239b 100644 --- a/src/rdkafka_fetcher.c +++ b/src/rdkafka_fetcher.c @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2022 Magnus Edenhill + * Copyright (c) 2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_fetcher.h b/src/rdkafka_fetcher.h index c2235b0d0c..8c64f3b0d9 100644 --- a/src/rdkafka_fetcher.h +++ b/src/rdkafka_fetcher.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2022 Magnus Edenhill + * Copyright (c) 2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_header.c b/src/rdkafka_header.c index 98359b424c..eb3024c51e 100644 --- a/src/rdkafka_header.c +++ b/src/rdkafka_header.c @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_header.h b/src/rdkafka_header.h index bd6b0e9593..6d6747ea66 100644 --- a/src/rdkafka_header.h +++ b/src/rdkafka_header.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_idempotence.c b/src/rdkafka_idempotence.c index 3245e856ed..1c189f5c87 100644 --- a/src/rdkafka_idempotence.c +++ b/src/rdkafka_idempotence.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018 Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_idempotence.h b/src/rdkafka_idempotence.h index 5be8d606d5..87de3b97a0 100644 --- a/src/rdkafka_idempotence.h +++ b/src/rdkafka_idempotence.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018 Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_int.h b/src/rdkafka_int.h index 6da9ecd52b..f3554963ad 100644 --- a/src/rdkafka_int.h +++ b/src/rdkafka_int.h @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_interceptor.c b/src/rdkafka_interceptor.c index c962d2d99e..b5bacece3c 100644 --- a/src/rdkafka_interceptor.c +++ b/src/rdkafka_interceptor.c @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_interceptor.h b/src/rdkafka_interceptor.h index 85f061ba91..d9aa415326 100644 --- a/src/rdkafka_interceptor.h +++ b/src/rdkafka_interceptor.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_lz4.c b/src/rdkafka_lz4.c index b52108bb1f..87024ff8ed 100644 --- a/src/rdkafka_lz4.c +++ b/src/rdkafka_lz4.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_lz4.h b/src/rdkafka_lz4.h index eb0ef98836..c724ea2124 100644 --- a/src/rdkafka_lz4.h +++ b/src/rdkafka_lz4.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_metadata.c b/src/rdkafka_metadata.c index 498512043d..f6d2bfbb49 100644 --- a/src/rdkafka_metadata.c +++ b/src/rdkafka_metadata.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_metadata.h b/src/rdkafka_metadata.h index 2598401363..03586618db 100644 --- a/src/rdkafka_metadata.h +++ b/src/rdkafka_metadata.h @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_metadata_cache.c b/src/rdkafka_metadata_cache.c index d579301b79..18f19a4d04 100644 --- a/src/rdkafka_metadata_cache.c +++ b/src/rdkafka_metadata_cache.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_mock.c b/src/rdkafka_mock.c index d4bf595a3a..6ec89b8468 100644 --- a/src/rdkafka_mock.c +++ b/src/rdkafka_mock.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019 Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_mock.h b/src/rdkafka_mock.h index f06efe8fd5..a9fd86f12f 100644 --- a/src/rdkafka_mock.h +++ b/src/rdkafka_mock.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019-2022 Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_mock_cgrp.c b/src/rdkafka_mock_cgrp.c index 57fe550925..60b3aa1567 100644 --- a/src/rdkafka_mock_cgrp.c +++ b/src/rdkafka_mock_cgrp.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020 Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_mock_handlers.c b/src/rdkafka_mock_handlers.c index 59d40e421a..efebd33da5 100644 --- a/src/rdkafka_mock_handlers.c +++ b/src/rdkafka_mock_handlers.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019 Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill, + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_mock_int.h b/src/rdkafka_mock_int.h index 1f33476aff..390e8631ff 100644 --- a/src/rdkafka_mock_int.h +++ b/src/rdkafka_mock_int.h @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019 Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_msg.c b/src/rdkafka_msg.c index a433e29b15..6b129ace1d 100644 --- a/src/rdkafka_msg.c +++ b/src/rdkafka_msg.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012,2013 Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill, + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_msg.h b/src/rdkafka_msg.h index 877fac15cd..db09892d57 100644 --- a/src/rdkafka_msg.h +++ b/src/rdkafka_msg.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012,2013 Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_msgbatch.h b/src/rdkafka_msgbatch.h index 09c7977067..b65a0f9c0a 100644 --- a/src/rdkafka_msgbatch.h +++ b/src/rdkafka_msgbatch.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019 Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_msgset.h b/src/rdkafka_msgset.h index b79f1c946c..9336e0c6b3 100644 --- a/src/rdkafka_msgset.h +++ b/src/rdkafka_msgset.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_msgset_reader.c b/src/rdkafka_msgset_reader.c index 58779f3be6..8b23d23ca7 100644 --- a/src/rdkafka_msgset_reader.c +++ b/src/rdkafka_msgset_reader.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_msgset_writer.c b/src/rdkafka_msgset_writer.c index beb36bfac0..21f16b5a81 100644 --- a/src/rdkafka_msgset_writer.c +++ b/src/rdkafka_msgset_writer.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_offset.c b/src/rdkafka_offset.c index fd76f138d2..00cf8638f5 100644 --- a/src/rdkafka_offset.c +++ b/src/rdkafka_offset.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012,2013 Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_offset.h b/src/rdkafka_offset.h index ba449995de..de9b5dec98 100644 --- a/src/rdkafka_offset.h +++ b/src/rdkafka_offset.h @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012,2013 Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_op.c b/src/rdkafka_op.c index 0a4635f9ab..a3ea9a39a6 100644 --- a/src/rdkafka_op.c +++ b/src/rdkafka_op.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_op.h b/src/rdkafka_op.h index 45f8d55bbb..f3df1df806 100644 --- a/src/rdkafka_op.h +++ b/src/rdkafka_op.h @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_partition.c b/src/rdkafka_partition.c index fcf6ae2f07..ab40168ac3 100644 --- a/src/rdkafka_partition.c +++ b/src/rdkafka_partition.c @@ -1,7 +1,8 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2015 Magnus Edenhill + * Copyright (c) 2015-2022, Magnus Edenhill, + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_partition.h b/src/rdkafka_partition.h index 355cbeb7ac..f9dd686423 100644 --- a/src/rdkafka_partition.h +++ b/src/rdkafka_partition.h @@ -1,7 +1,8 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2015 Magnus Edenhill + * Copyright (c) 2015-2022, Magnus Edenhill, + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_pattern.c b/src/rdkafka_pattern.c index dfe3ef03e6..425f8201a5 100644 --- a/src/rdkafka_pattern.c +++ b/src/rdkafka_pattern.c @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2015 Magnus Edenhill + * Copyright (c) 2015-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_pattern.h b/src/rdkafka_pattern.h index 88d183cd32..5ef6a3464c 100644 --- a/src/rdkafka_pattern.h +++ b/src/rdkafka_pattern.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2015 Magnus Edenhill + * Copyright (c) 2015-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_plugin.c b/src/rdkafka_plugin.c index f58bc5060c..f084eff7a7 100644 --- a/src/rdkafka_plugin.c +++ b/src/rdkafka_plugin.c @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_plugin.h b/src/rdkafka_plugin.h index 1783d5f53c..cb50a8647a 100644 --- a/src/rdkafka_plugin.h +++ b/src/rdkafka_plugin.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_proto.h b/src/rdkafka_proto.h index 396765857c..cac898a55c 100644 --- a/src/rdkafka_proto.h +++ b/src/rdkafka_proto.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012,2013 Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_protocol.h b/src/rdkafka_protocol.h index 60c0999861..99c6aa16a2 100644 --- a/src/rdkafka_protocol.h +++ b/src/rdkafka_protocol.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2020 Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_queue.c b/src/rdkafka_queue.c index 59a751abd9..b8749123f4 100644 --- a/src/rdkafka_queue.c +++ b/src/rdkafka_queue.c @@ -1,7 +1,8 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2016 Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill, + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_queue.h b/src/rdkafka_queue.h index 82abe4deef..eb329d1c1d 100644 --- a/src/rdkafka_queue.h +++ b/src/rdkafka_queue.h @@ -1,7 +1,8 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2016 Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill, + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_range_assignor.c b/src/rdkafka_range_assignor.c index 60f7c1e112..a869c139bd 100644 --- a/src/rdkafka_range_assignor.c +++ b/src/rdkafka_range_assignor.c @@ -1,7 +1,8 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2015 Magnus Edenhill + * Copyright (c) 2015-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_request.c b/src/rdkafka_request.c index e9f1506945..3b6f75b997 100644 --- a/src/rdkafka_request.c +++ b/src/rdkafka_request.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_request.h b/src/rdkafka_request.h index de5b8510a6..79254099cb 100644 --- a/src/rdkafka_request.h +++ b/src/rdkafka_request.h @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_roundrobin_assignor.c b/src/rdkafka_roundrobin_assignor.c index 6cb9193645..28d437f4f7 100644 --- a/src/rdkafka_roundrobin_assignor.c +++ b/src/rdkafka_roundrobin_assignor.c @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2015 Magnus Edenhill + * Copyright (c) 2015-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_sasl.c b/src/rdkafka_sasl.c index 89054fe4dd..32ebe3b198 100644 --- a/src/rdkafka_sasl.c +++ b/src/rdkafka_sasl.c @@ -1,7 +1,8 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2015 Magnus Edenhill + * Copyright (c) 2015-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_sasl.h b/src/rdkafka_sasl.h index d0dd01b8b2..0ac12c5d21 100644 --- a/src/rdkafka_sasl.h +++ b/src/rdkafka_sasl.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2015 Magnus Edenhill + * Copyright (c) 2015-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_sasl_cyrus.c b/src/rdkafka_sasl_cyrus.c index 49d9eef0dd..89ff15c427 100644 --- a/src/rdkafka_sasl_cyrus.c +++ b/src/rdkafka_sasl_cyrus.c @@ -1,7 +1,8 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2015 Magnus Edenhill + * Copyright (c) 2015-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_sasl_int.h b/src/rdkafka_sasl_int.h index 33e3bdd05f..8a49a6a296 100644 --- a/src/rdkafka_sasl_int.h +++ b/src/rdkafka_sasl_int.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2015 Magnus Edenhill + * Copyright (c) 2015-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_sasl_oauthbearer.c b/src/rdkafka_sasl_oauthbearer.c index 58ff1ba1fa..2065751ccb 100644 --- a/src/rdkafka_sasl_oauthbearer.c +++ b/src/rdkafka_sasl_oauthbearer.c @@ -1,7 +1,8 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2019 Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_sasl_oauthbearer.h b/src/rdkafka_sasl_oauthbearer.h index 75ab51d02f..cdcea0608c 100644 --- a/src/rdkafka_sasl_oauthbearer.h +++ b/src/rdkafka_sasl_oauthbearer.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2019 Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_sasl_oauthbearer_oidc.c b/src/rdkafka_sasl_oauthbearer_oidc.c index 6c2773b027..9fa0972a39 100644 --- a/src/rdkafka_sasl_oauthbearer_oidc.c +++ b/src/rdkafka_sasl_oauthbearer_oidc.c @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2021 Magnus Edenhill + * Copyright (c) 2021-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_sasl_oauthbearer_oidc.h b/src/rdkafka_sasl_oauthbearer_oidc.h index a944f2efa1..f46bf1beb7 100644 --- a/src/rdkafka_sasl_oauthbearer_oidc.h +++ b/src/rdkafka_sasl_oauthbearer_oidc.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2021 Magnus Edenhill + * Copyright (c) 2021-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_sasl_plain.c b/src/rdkafka_sasl_plain.c index 1e715cfba2..cca9957c83 100644 --- a/src/rdkafka_sasl_plain.c +++ b/src/rdkafka_sasl_plain.c @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_sasl_scram.c b/src/rdkafka_sasl_scram.c index 00b9061d27..1a4aebb835 100644 --- a/src/rdkafka_sasl_scram.c +++ b/src/rdkafka_sasl_scram.c @@ -1,7 +1,8 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_sasl_win32.c b/src/rdkafka_sasl_win32.c index 70e707e3cd..b968bcece3 100644 --- a/src/rdkafka_sasl_win32.c +++ b/src/rdkafka_sasl_win32.c @@ -1,7 +1,8 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2016 Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_ssl.c b/src/rdkafka_ssl.c index f9c9aee469..19178c84b3 100644 --- a/src/rdkafka_ssl.c +++ b/src/rdkafka_ssl.c @@ -1,7 +1,8 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2019 Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_ssl.h b/src/rdkafka_ssl.h index 325abbe1d4..9fb07e3312 100644 --- a/src/rdkafka_ssl.h +++ b/src/rdkafka_ssl.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2019 Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_sticky_assignor.c b/src/rdkafka_sticky_assignor.c index 8d2bc27982..462da61478 100644 --- a/src/rdkafka_sticky_assignor.c +++ b/src/rdkafka_sticky_assignor.c @@ -1,7 +1,8 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2020 Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_subscription.c b/src/rdkafka_subscription.c index 0805893587..46ab544ee2 100644 --- a/src/rdkafka_subscription.c +++ b/src/rdkafka_subscription.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_timer.c b/src/rdkafka_timer.c index 5240af7857..776b5d995f 100644 --- a/src/rdkafka_timer.c +++ b/src/rdkafka_timer.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_timer.h b/src/rdkafka_timer.h index e3cadd7b9f..d3e8fba61e 100644 --- a/src/rdkafka_timer.h +++ b/src/rdkafka_timer.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_topic.c b/src/rdkafka_topic.c index ba0d18e51f..4341637bc0 100644 --- a/src/rdkafka_topic.c +++ b/src/rdkafka_topic.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012,2013 Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_topic.h b/src/rdkafka_topic.h index f5d4c00c95..b8c0b66c99 100644 --- a/src/rdkafka_topic.h +++ b/src/rdkafka_topic.h @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012,2013 Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_transport.c b/src/rdkafka_transport.c index 2f241a9dfe..f133d8fdde 100644 --- a/src/rdkafka_transport.c +++ b/src/rdkafka_transport.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2015, Magnus Edenhill + * Copyright (c) 2015-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_transport.h b/src/rdkafka_transport.h index 83af5ae901..c5f73163f9 100644 --- a/src/rdkafka_transport.h +++ b/src/rdkafka_transport.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2015, Magnus Edenhill + * Copyright (c) 2015-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_transport_int.h b/src/rdkafka_transport_int.h index 4b053b98fa..9e00f238c3 100644 --- a/src/rdkafka_transport_int.h +++ b/src/rdkafka_transport_int.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2015, Magnus Edenhill + * Copyright (c) 2015-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_txnmgr.c b/src/rdkafka_txnmgr.c index afbc28b71c..cd8a60f30a 100644 --- a/src/rdkafka_txnmgr.c +++ b/src/rdkafka_txnmgr.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019 Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_txnmgr.h b/src/rdkafka_txnmgr.h index 3c088d09a6..d67b57bce2 100644 --- a/src/rdkafka_txnmgr.h +++ b/src/rdkafka_txnmgr.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019 Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_zstd.c b/src/rdkafka_zstd.c index 68b01a4e1c..dac2c4dfcc 100644 --- a/src/rdkafka_zstd.c +++ b/src/rdkafka_zstd.c @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2018 Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdkafka_zstd.h b/src/rdkafka_zstd.h index f87c4c6fbc..7f5a749041 100644 --- a/src/rdkafka_zstd.h +++ b/src/rdkafka_zstd.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2018 Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdlist.c b/src/rdlist.c index 82150f99e4..65e3eb97e0 100644 --- a/src/rdlist.c +++ b/src/rdlist.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdlist.h b/src/rdlist.h index 334b05f916..3a1316c389 100644 --- a/src/rdlist.h +++ b/src/rdlist.h @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill, + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdlog.c b/src/rdlog.c index 19fbbb1614..3ddc82d06e 100644 --- a/src/rdlog.c +++ b/src/rdlog.c @@ -1,7 +1,7 @@ /* * librd - Rapid Development C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdlog.h b/src/rdlog.h index f360a0b66e..a83701f6a3 100644 --- a/src/rdlog.h +++ b/src/rdlog.h @@ -1,7 +1,7 @@ /* * librd - Rapid Development C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdmap.c b/src/rdmap.c index 4b85470336..8e1a0546cc 100644 --- a/src/rdmap.c +++ b/src/rdmap.c @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2020 Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdmap.h b/src/rdmap.h index a79dcda06a..bea8a1aca6 100644 --- a/src/rdmap.h +++ b/src/rdmap.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2020 Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdmurmur2.c b/src/rdmurmur2.c index c3e4095d4c..c54fa2f51c 100644 --- a/src/rdmurmur2.c +++ b/src/rdmurmur2.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdmurmur2.h b/src/rdmurmur2.h index 5991caa50c..fc23dfec94 100644 --- a/src/rdmurmur2.h +++ b/src/rdmurmur2.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018 Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdports.c b/src/rdports.c index 15c57e9289..9af8ede531 100644 --- a/src/rdports.c +++ b/src/rdports.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016 Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdports.h b/src/rdports.h index 0cdbcd85fc..41314ebfbe 100644 --- a/src/rdports.h +++ b/src/rdports.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016 Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdposix.h b/src/rdposix.h index 7b2376823f..0af5948168 100644 --- a/src/rdposix.h +++ b/src/rdposix.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015 Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdrand.c b/src/rdrand.c index e36d79380b..bdab002968 100644 --- a/src/rdrand.c +++ b/src/rdrand.c @@ -1,7 +1,7 @@ /* * librd - Rapid Development C library * - * Copyright (c) 2012, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdrand.h b/src/rdrand.h index 0e3a927c2c..f86fb83e79 100644 --- a/src/rdrand.h +++ b/src/rdrand.h @@ -1,7 +1,7 @@ /* * librd - Rapid Development C library * - * Copyright (c) 2012, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdregex.c b/src/rdregex.c index 0c70cb334b..4a09286b81 100644 --- a/src/rdregex.c +++ b/src/rdregex.c @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2016 Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdregex.h b/src/rdregex.h index 135229d626..94edcf661c 100644 --- a/src/rdregex.h +++ b/src/rdregex.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2016 Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdsignal.h b/src/rdsignal.h index a2c0de1b0c..6f3462130a 100644 --- a/src/rdsignal.h +++ b/src/rdsignal.h @@ -1,7 +1,7 @@ /* * librd - Rapid Development C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdstring.c b/src/rdstring.c index 2e15cf7e35..c981f7705a 100644 --- a/src/rdstring.c +++ b/src/rdstring.c @@ -1,7 +1,8 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2016 Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdstring.h b/src/rdstring.h index a036e6bff8..dc0627a138 100644 --- a/src/rdstring.h +++ b/src/rdstring.h @@ -1,7 +1,8 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdsysqueue.h b/src/rdsysqueue.h index ecba4154eb..738cdad792 100644 --- a/src/rdsysqueue.h +++ b/src/rdsysqueue.h @@ -1,8 +1,8 @@ /* * librd - Rapid Development C library * - * Copyright (c) 2012-2013, Magnus Edenhill - * Copyright (c) 2012-2013, Andreas Öman + * Copyright (c) 2012-2022, Magnus Edenhill + * Copyright (c) 2012-2022, Andreas Öman * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdtime.h b/src/rdtime.h index 4a3e5d8559..4a7e76d752 100644 --- a/src/rdtime.h +++ b/src/rdtime.h @@ -1,7 +1,7 @@ /* * librd - Rapid Development C library * - * Copyright (c) 2012, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdtypes.h b/src/rdtypes.h index 8f3625512d..a22bb90649 100644 --- a/src/rdtypes.h +++ b/src/rdtypes.h @@ -1,7 +1,7 @@ /* * librd - Rapid Development C library * - * Copyright (c) 2012, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdunittest.c b/src/rdunittest.c index aa14b6aa84..18236ca9ec 100644 --- a/src/rdunittest.c +++ b/src/rdunittest.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdunittest.h b/src/rdunittest.h index a154885680..a9e709fa73 100644 --- a/src/rdunittest.h +++ b/src/rdunittest.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdvarint.c b/src/rdvarint.c index fb0cbd0466..cb8b8a9837 100644 --- a/src/rdvarint.c +++ b/src/rdvarint.c @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2016 Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdvarint.h b/src/rdvarint.h index 6fe112ba95..c628822fc8 100644 --- a/src/rdvarint.h +++ b/src/rdvarint.h @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2016 Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/rdwin32.h b/src/rdwin32.h index 73edd41d6a..37c25843ac 100644 --- a/src/rdwin32.h +++ b/src/rdwin32.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015 Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/snappy.h b/src/snappy.h index b3742f1ac5..c366fb5aa6 100644 --- a/src/snappy.h +++ b/src/snappy.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018 Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/statistics_schema.json b/src/statistics_schema.json index d0dbedda7d..185bc2637e 100644 --- a/src/statistics_schema.json +++ b/src/statistics_schema.json @@ -1,5 +1,5 @@ { "$schema": "http://json-schema.org/schema#", - "id": "https://github.com/edenhill/librdkafka/src/statistics_schema.json", + "id": "https://github.com/confluentinc/librdkafka/src/statistics_schema.json", "title": "librdkafka statistics schema - INCOMPLETE - WORK IN PROGRESS", "definitions": { "window": { diff --git a/src/tinycthread_extra.c b/src/tinycthread_extra.c index 58049448ce..11dc0f212f 100644 --- a/src/tinycthread_extra.c +++ b/src/tinycthread_extra.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018 Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/tinycthread_extra.h b/src/tinycthread_extra.h index e5f6731739..2207022592 100644 --- a/src/tinycthread_extra.h +++ b/src/tinycthread_extra.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018 Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/win32_config.h b/src/win32_config.h index dd61b2c92f..e1b416ba3c 100644 --- a/src/win32_config.h +++ b/src/win32_config.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015 Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0000-unittests.c b/tests/0000-unittests.c index e0a02fb625..dd3655e655 100644 --- a/tests/0000-unittests.c +++ b/tests/0000-unittests.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2017, Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0001-multiobj.c b/tests/0001-multiobj.c index c2a4eb57af..423bd15ae3 100644 --- a/tests/0001-multiobj.c +++ b/tests/0001-multiobj.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0002-unkpart.c b/tests/0002-unkpart.c index 087e37ae62..f70250e6ea 100644 --- a/tests/0002-unkpart.c +++ b/tests/0002-unkpart.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0003-msgmaxsize.c b/tests/0003-msgmaxsize.c index 97b5111258..64d105df0a 100644 --- a/tests/0003-msgmaxsize.c +++ b/tests/0003-msgmaxsize.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0004-conf.c b/tests/0004-conf.c index 51401e17d3..b5f293921e 100644 --- a/tests/0004-conf.c +++ b/tests/0004-conf.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0005-order.c b/tests/0005-order.c index 722cef3b06..f4e2f75ccf 100644 --- a/tests/0005-order.c +++ b/tests/0005-order.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0006-symbols.c b/tests/0006-symbols.c index 8a25f6a1d2..1e5378c39e 100644 --- a/tests/0006-symbols.c +++ b/tests/0006-symbols.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0007-autotopic.c b/tests/0007-autotopic.c index cf196d60c2..afcb8dd0df 100644 --- a/tests/0007-autotopic.c +++ b/tests/0007-autotopic.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0008-reqacks.c b/tests/0008-reqacks.c index d52081b758..b03878b9cb 100644 --- a/tests/0008-reqacks.c +++ b/tests/0008-reqacks.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0009-mock_cluster.c b/tests/0009-mock_cluster.c index 32590820e7..23a953fbe3 100644 --- a/tests/0009-mock_cluster.c +++ b/tests/0009-mock_cluster.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019, Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0011-produce_batch.c b/tests/0011-produce_batch.c index 584d37bc63..fd8d2e2d47 100644 --- a/tests/0011-produce_batch.c +++ b/tests/0011-produce_batch.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0012-produce_consume.c b/tests/0012-produce_consume.c index 30ff392c42..97f592b3c3 100644 --- a/tests/0012-produce_consume.c +++ b/tests/0012-produce_consume.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0013-null-msgs.c b/tests/0013-null-msgs.c index 26a7ac070d..8cb2af255f 100644 --- a/tests/0013-null-msgs.c +++ b/tests/0013-null-msgs.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0014-reconsume-191.c b/tests/0014-reconsume-191.c index edae85f5cd..2965b8d6c1 100644 --- a/tests/0014-reconsume-191.c +++ b/tests/0014-reconsume-191.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0015-offset_seeks.c b/tests/0015-offset_seeks.c index a551a0b531..1bbd9be132 100644 --- a/tests/0015-offset_seeks.c +++ b/tests/0015-offset_seeks.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0016-client_swname.c b/tests/0016-client_swname.c index 2d0605b887..f8b2cf6074 100644 --- a/tests/0016-client_swname.c +++ b/tests/0016-client_swname.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0017-compression.c b/tests/0017-compression.c index f28f63f244..d13bb1bf6c 100644 --- a/tests/0017-compression.c +++ b/tests/0017-compression.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0018-cgrp_term.c b/tests/0018-cgrp_term.c index 6b22339d7d..99a98df4fd 100644 --- a/tests/0018-cgrp_term.c +++ b/tests/0018-cgrp_term.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0019-list_groups.c b/tests/0019-list_groups.c index 02729c3396..3337e34707 100644 --- a/tests/0019-list_groups.c +++ b/tests/0019-list_groups.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0020-destroy_hang.c b/tests/0020-destroy_hang.c index a8a6552fa8..ca2a2362be 100644 --- a/tests/0020-destroy_hang.c +++ b/tests/0020-destroy_hang.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0021-rkt_destroy.c b/tests/0021-rkt_destroy.c index 76b4dd16b3..f1517b8476 100644 --- a/tests/0021-rkt_destroy.c +++ b/tests/0021-rkt_destroy.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0022-consume_batch.c b/tests/0022-consume_batch.c index ea7bdf1f2e..5deccc378f 100644 --- a/tests/0022-consume_batch.c +++ b/tests/0022-consume_batch.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0025-timers.c b/tests/0025-timers.c index 318fc0a1b4..79d765160a 100644 --- a/tests/0025-timers.c +++ b/tests/0025-timers.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0026-consume_pause.c b/tests/0026-consume_pause.c index c8adc3885c..dfac4572d9 100644 --- a/tests/0026-consume_pause.c +++ b/tests/0026-consume_pause.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0028-long_topicnames.c b/tests/0028-long_topicnames.c index 999d8f135f..a20f4308b5 100644 --- a/tests/0028-long_topicnames.c +++ b/tests/0028-long_topicnames.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0029-assign_offset.c b/tests/0029-assign_offset.c index 5b3595baf0..29ec6d9ea8 100644 --- a/tests/0029-assign_offset.c +++ b/tests/0029-assign_offset.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0030-offset_commit.c b/tests/0030-offset_commit.c index 9b05cb420b..e53b0aefe4 100644 --- a/tests/0030-offset_commit.c +++ b/tests/0030-offset_commit.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0031-get_offsets.c b/tests/0031-get_offsets.c index 327be43df4..ab62f01e3a 100644 --- a/tests/0031-get_offsets.c +++ b/tests/0031-get_offsets.c @@ -2,7 +2,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0033-regex_subscribe.c b/tests/0033-regex_subscribe.c index 07ae3d4a37..be974d0628 100644 --- a/tests/0033-regex_subscribe.c +++ b/tests/0033-regex_subscribe.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016, Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0034-offset_reset.c b/tests/0034-offset_reset.c index 9276764c8e..4a6a58f4dc 100644 --- a/tests/0034-offset_reset.c +++ b/tests/0034-offset_reset.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016, Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0035-api_version.c b/tests/0035-api_version.c index d005b1e9ec..36eff1243c 100644 --- a/tests/0035-api_version.c +++ b/tests/0035-api_version.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016, Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0036-partial_fetch.c b/tests/0036-partial_fetch.c index 69ee9864c8..50c64c35c6 100644 --- a/tests/0036-partial_fetch.c +++ b/tests/0036-partial_fetch.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016, Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0037-destroy_hang_local.c b/tests/0037-destroy_hang_local.c index 3b543fb6f4..abb94e1177 100644 --- a/tests/0037-destroy_hang_local.c +++ b/tests/0037-destroy_hang_local.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0038-performance.c b/tests/0038-performance.c index 674964dc9c..c795354637 100644 --- a/tests/0038-performance.c +++ b/tests/0038-performance.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016, Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0039-event.c b/tests/0039-event.c index 8d6b9f0ee1..faee0d4c46 100644 --- a/tests/0039-event.c +++ b/tests/0039-event.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0040-io_event.c b/tests/0040-io_event.c index d47da52060..fba8f9d3b9 100644 --- a/tests/0040-io_event.c +++ b/tests/0040-io_event.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0041-fetch_max_bytes.c b/tests/0041-fetch_max_bytes.c index e243dc8ac8..75ea4f80cc 100644 --- a/tests/0041-fetch_max_bytes.c +++ b/tests/0041-fetch_max_bytes.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016, Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0042-many_topics.c b/tests/0042-many_topics.c index 6ea5aa6695..c580b4a756 100644 --- a/tests/0042-many_topics.c +++ b/tests/0042-many_topics.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0043-no_connection.c b/tests/0043-no_connection.c index 3470c4ae13..594b4868a8 100644 --- a/tests/0043-no_connection.c +++ b/tests/0043-no_connection.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0044-partition_cnt.c b/tests/0044-partition_cnt.c index 51ef318c35..b4b66bd482 100644 --- a/tests/0044-partition_cnt.c +++ b/tests/0044-partition_cnt.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0045-subscribe_update.c b/tests/0045-subscribe_update.c index 19462ab36a..cf013c5bda 100644 --- a/tests/0045-subscribe_update.c +++ b/tests/0045-subscribe_update.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0046-rkt_cache.c b/tests/0046-rkt_cache.c index 541c030376..93f7fc78ff 100644 --- a/tests/0046-rkt_cache.c +++ b/tests/0046-rkt_cache.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0047-partial_buf_tmout.c b/tests/0047-partial_buf_tmout.c index d90004a3aa..e999afa367 100644 --- a/tests/0047-partial_buf_tmout.c +++ b/tests/0047-partial_buf_tmout.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0048-partitioner.c b/tests/0048-partitioner.c index 84efee7dbd..63761506c5 100644 --- a/tests/0048-partitioner.c +++ b/tests/0048-partitioner.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0049-consume_conn_close.c b/tests/0049-consume_conn_close.c index 6083a1a764..61f6d7a9dd 100644 --- a/tests/0049-consume_conn_close.c +++ b/tests/0049-consume_conn_close.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0050-subscribe_adds.c b/tests/0050-subscribe_adds.c index d55e6e09a2..299c6b95d8 100644 --- a/tests/0050-subscribe_adds.c +++ b/tests/0050-subscribe_adds.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0051-assign_adds.c b/tests/0051-assign_adds.c index 6f97b2ee49..31866627dd 100644 --- a/tests/0051-assign_adds.c +++ b/tests/0051-assign_adds.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0052-msg_timestamps.c b/tests/0052-msg_timestamps.c index ef9b89878f..7921cd4594 100644 --- a/tests/0052-msg_timestamps.c +++ b/tests/0052-msg_timestamps.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0053-stats_cb.cpp b/tests/0053-stats_cb.cpp index a61755c30b..d7254a6ca3 100644 --- a/tests/0053-stats_cb.cpp +++ b/tests/0053-stats_cb.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2018, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0054-offset_time.cpp b/tests/0054-offset_time.cpp index 58c88b4a13..082357f663 100644 --- a/tests/0054-offset_time.cpp +++ b/tests/0054-offset_time.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0055-producer_latency.c b/tests/0055-producer_latency.c index e0244cec95..a8cbb4efe8 100644 --- a/tests/0055-producer_latency.c +++ b/tests/0055-producer_latency.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0056-balanced_group_mt.c b/tests/0056-balanced_group_mt.c index e6205ddb63..59dc8691bc 100644 --- a/tests/0056-balanced_group_mt.c +++ b/tests/0056-balanced_group_mt.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0057-invalid_topic.cpp b/tests/0057-invalid_topic.cpp index 0b50b40ad7..c2da2c9879 100644 --- a/tests/0057-invalid_topic.cpp +++ b/tests/0057-invalid_topic.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0058-log.cpp b/tests/0058-log.cpp index 4da46e7f76..bf1c97a74e 100644 --- a/tests/0058-log.cpp +++ b/tests/0058-log.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0059-bsearch.cpp b/tests/0059-bsearch.cpp index 67508ff824..18ea216bda 100644 --- a/tests/0059-bsearch.cpp +++ b/tests/0059-bsearch.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016, Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0060-op_prio.cpp b/tests/0060-op_prio.cpp index 156b8a57a9..43371fd6b2 100644 --- a/tests/0060-op_prio.cpp +++ b/tests/0060-op_prio.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016, Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0061-consumer_lag.cpp b/tests/0061-consumer_lag.cpp index 7595415834..10a18afb33 100644 --- a/tests/0061-consumer_lag.cpp +++ b/tests/0061-consumer_lag.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016, Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0062-stats_event.c b/tests/0062-stats_event.c index bdddda5e08..3e57e9a1dc 100644 --- a/tests/0062-stats_event.c +++ b/tests/0062-stats_event.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2017, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0063-clusterid.cpp b/tests/0063-clusterid.cpp index dda8d6ddb2..8ff565db7f 100644 --- a/tests/0063-clusterid.cpp +++ b/tests/0063-clusterid.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016, Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0064-interceptors.c b/tests/0064-interceptors.c index e5c5b047a7..ddfb9e6bb4 100644 --- a/tests/0064-interceptors.c +++ b/tests/0064-interceptors.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2017, Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0065-yield.cpp b/tests/0065-yield.cpp index 6f2dbb0acb..26b1e4bbc6 100644 --- a/tests/0065-yield.cpp +++ b/tests/0065-yield.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016, Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0066-plugins.cpp b/tests/0066-plugins.cpp index 9f9f312400..7b5e7b00fb 100644 --- a/tests/0066-plugins.cpp +++ b/tests/0066-plugins.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016, Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0067-empty_topic.cpp b/tests/0067-empty_topic.cpp index f71489fa16..2db9ee8735 100644 --- a/tests/0067-empty_topic.cpp +++ b/tests/0067-empty_topic.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016, Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0068-produce_timeout.c b/tests/0068-produce_timeout.c index a7ad37e164..7f19506888 100644 --- a/tests/0068-produce_timeout.c +++ b/tests/0068-produce_timeout.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0069-consumer_add_parts.c b/tests/0069-consumer_add_parts.c index 933e53775b..b43c4c3a69 100644 --- a/tests/0069-consumer_add_parts.c +++ b/tests/0069-consumer_add_parts.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0070-null_empty.cpp b/tests/0070-null_empty.cpp index fac48185c3..154f0b079b 100644 --- a/tests/0070-null_empty.cpp +++ b/tests/0070-null_empty.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016, Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0072-headers_ut.c b/tests/0072-headers_ut.c index 0576d611ae..d4b453ec04 100644 --- a/tests/0072-headers_ut.c +++ b/tests/0072-headers_ut.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0073-headers.c b/tests/0073-headers.c index e7e5c4074d..15e8ab40fd 100644 --- a/tests/0073-headers.c +++ b/tests/0073-headers.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0074-producev.c b/tests/0074-producev.c index 544a847348..8cd67fe8b3 100644 --- a/tests/0074-producev.c +++ b/tests/0074-producev.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2020, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0075-retry.c b/tests/0075-retry.c index 7e1e4f0f58..86eeb56d15 100644 --- a/tests/0075-retry.c +++ b/tests/0075-retry.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0076-produce_retry.c b/tests/0076-produce_retry.c index 16d6f602c6..86cc0bfb35 100644 --- a/tests/0076-produce_retry.c +++ b/tests/0076-produce_retry.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0077-compaction.c b/tests/0077-compaction.c index 01667114c7..623461b7f8 100644 --- a/tests/0077-compaction.c +++ b/tests/0077-compaction.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0078-c_from_cpp.cpp b/tests/0078-c_from_cpp.cpp index 41d6886cb9..b405be0b30 100644 --- a/tests/0078-c_from_cpp.cpp +++ b/tests/0078-c_from_cpp.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016, Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0079-fork.c b/tests/0079-fork.c index 506dd62a31..0f217fc90b 100644 --- a/tests/0079-fork.c +++ b/tests/0079-fork.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0080-admin_ut.c b/tests/0080-admin_ut.c index 9d049e5b14..e187297b84 100644 --- a/tests/0080-admin_ut.c +++ b/tests/0080-admin_ut.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0081-admin.c b/tests/0081-admin.c index 7da2dff156..285b8c0f65 100644 --- a/tests/0081-admin.c +++ b/tests/0081-admin.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0082-fetch_max_bytes.cpp b/tests/0082-fetch_max_bytes.cpp index 16eb5a21a1..4ecb370f75 100644 --- a/tests/0082-fetch_max_bytes.cpp +++ b/tests/0082-fetch_max_bytes.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016, Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -71,7 +71,7 @@ static void do_test_fetch_max_bytes(void) { * but due to batching overhead it would result in situations where * the consumer asked for 1000000 bytes and got 1000096 bytes batch, which * was higher than the 1000000 limit. - * See https://github.com/edenhill/librdkafka/issues/1616 + * See https://github.com/confluentinc/librdkafka/issues/1616 * * With the added configuration strictness checks, a user-supplied * value is no longer over-written: diff --git a/tests/0083-cb_event.c b/tests/0083-cb_event.c index 23ce798208..ec84ee6e99 100644 --- a/tests/0083-cb_event.c +++ b/tests/0083-cb_event.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018, Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0084-destroy_flags.c b/tests/0084-destroy_flags.c index cd8bbf7ded..df98a742d7 100644 --- a/tests/0084-destroy_flags.c +++ b/tests/0084-destroy_flags.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018, Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0085-headers.cpp b/tests/0085-headers.cpp index a342478c15..aa9c424641 100644 --- a/tests/0085-headers.cpp +++ b/tests/0085-headers.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0086-purge.c b/tests/0086-purge.c index 4dbf937f3a..1bf235a313 100644 --- a/tests/0086-purge.c +++ b/tests/0086-purge.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0088-produce_metadata_timeout.c b/tests/0088-produce_metadata_timeout.c index c71b5a69fd..68d02449c1 100644 --- a/tests/0088-produce_metadata_timeout.c +++ b/tests/0088-produce_metadata_timeout.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0089-max_poll_interval.c b/tests/0089-max_poll_interval.c index 908bc33474..660e7ce62c 100644 --- a/tests/0089-max_poll_interval.c +++ b/tests/0089-max_poll_interval.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2018, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0090-idempotence.c b/tests/0090-idempotence.c index 02d16df565..c665b5f635 100644 --- a/tests/0090-idempotence.c +++ b/tests/0090-idempotence.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018, Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0091-max_poll_interval_timeout.c b/tests/0091-max_poll_interval_timeout.c index c1506afd9b..f736c108a3 100644 --- a/tests/0091-max_poll_interval_timeout.c +++ b/tests/0091-max_poll_interval_timeout.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2018, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0092-mixed_msgver.c b/tests/0092-mixed_msgver.c index 46308ddf47..877fc48e07 100644 --- a/tests/0092-mixed_msgver.c +++ b/tests/0092-mixed_msgver.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018, Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0093-holb.c b/tests/0093-holb.c index 366deca328..8e80b1550e 100644 --- a/tests/0093-holb.c +++ b/tests/0093-holb.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2018, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0094-idempotence_msg_timeout.c b/tests/0094-idempotence_msg_timeout.c index 8704adc09c..4f2b3cbe5f 100644 --- a/tests/0094-idempotence_msg_timeout.c +++ b/tests/0094-idempotence_msg_timeout.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0095-all_brokers_down.cpp b/tests/0095-all_brokers_down.cpp index 6ebd5f500e..759eb8ffe6 100644 --- a/tests/0095-all_brokers_down.cpp +++ b/tests/0095-all_brokers_down.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019, Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0097-ssl_verify.cpp b/tests/0097-ssl_verify.cpp index 8a3a0bce51..a5e8885267 100644 --- a/tests/0097-ssl_verify.cpp +++ b/tests/0097-ssl_verify.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019, Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0098-consumer-txn.cpp b/tests/0098-consumer-txn.cpp index 1bdb46d0bf..6045e785a3 100644 --- a/tests/0098-consumer-txn.cpp +++ b/tests/0098-consumer-txn.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016, Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0099-commit_metadata.c b/tests/0099-commit_metadata.c index 902849fb24..9acdb07f55 100644 --- a/tests/0099-commit_metadata.c +++ b/tests/0099-commit_metadata.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0100-thread_interceptors.cpp b/tests/0100-thread_interceptors.cpp index a34ccac980..b428c1a892 100644 --- a/tests/0100-thread_interceptors.cpp +++ b/tests/0100-thread_interceptors.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019, Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0101-fetch-from-follower.cpp b/tests/0101-fetch-from-follower.cpp index 342ec4f8f9..db438b2a7e 100644 --- a/tests/0101-fetch-from-follower.cpp +++ b/tests/0101-fetch-from-follower.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019, Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0102-static_group_rebalance.c b/tests/0102-static_group_rebalance.c index 231a09065f..ad8bac4dbb 100644 --- a/tests/0102-static_group_rebalance.c +++ b/tests/0102-static_group_rebalance.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019, Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0103-transactions.c b/tests/0103-transactions.c index eaab2f217d..6478ce04e1 100644 --- a/tests/0103-transactions.c +++ b/tests/0103-transactions.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019, Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0104-fetch_from_follower_mock.c b/tests/0104-fetch_from_follower_mock.c index 11460beaf0..5863638da3 100644 --- a/tests/0104-fetch_from_follower_mock.c +++ b/tests/0104-fetch_from_follower_mock.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019, Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0105-transactions_mock.c b/tests/0105-transactions_mock.c index 014642df1d..8d6173c7f0 100644 --- a/tests/0105-transactions_mock.c +++ b/tests/0105-transactions_mock.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2019, Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0106-cgrp_sess_timeout.c b/tests/0106-cgrp_sess_timeout.c index 0451e4a00c..ca0a08c20a 100644 --- a/tests/0106-cgrp_sess_timeout.c +++ b/tests/0106-cgrp_sess_timeout.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0107-topic_recreate.c b/tests/0107-topic_recreate.c index 1f91e2a84d..474ed2f27a 100644 --- a/tests/0107-topic_recreate.c +++ b/tests/0107-topic_recreate.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0109-auto_create_topics.cpp b/tests/0109-auto_create_topics.cpp index cabee67041..b64050fee4 100644 --- a/tests/0109-auto_create_topics.cpp +++ b/tests/0109-auto_create_topics.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0110-batch_size.cpp b/tests/0110-batch_size.cpp index 1f36b3a763..5b216c2804 100644 --- a/tests/0110-batch_size.cpp +++ b/tests/0110-batch_size.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0111-delay_create_topics.cpp b/tests/0111-delay_create_topics.cpp index 4b6683add9..a46282bd17 100644 --- a/tests/0111-delay_create_topics.cpp +++ b/tests/0111-delay_create_topics.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0112-assign_unknown_part.c b/tests/0112-assign_unknown_part.c index d945a2c32c..a32d8f39ad 100644 --- a/tests/0112-assign_unknown_part.c +++ b/tests/0112-assign_unknown_part.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2020, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0113-cooperative_rebalance.cpp b/tests/0113-cooperative_rebalance.cpp index 430798d7f7..2ac03aafe8 100644 --- a/tests/0113-cooperative_rebalance.cpp +++ b/tests/0113-cooperative_rebalance.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0114-sticky_partitioning.cpp b/tests/0114-sticky_partitioning.cpp index 8ef88e7df4..f3b33301ef 100644 --- a/tests/0114-sticky_partitioning.cpp +++ b/tests/0114-sticky_partitioning.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0115-producer_auth.cpp b/tests/0115-producer_auth.cpp index c4d1a96aa9..644ff1af24 100644 --- a/tests/0115-producer_auth.cpp +++ b/tests/0115-producer_auth.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0116-kafkaconsumer_close.cpp b/tests/0116-kafkaconsumer_close.cpp index c674d4443b..dd68c99f70 100644 --- a/tests/0116-kafkaconsumer_close.cpp +++ b/tests/0116-kafkaconsumer_close.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0117-mock_errors.c b/tests/0117-mock_errors.c index 7a82f713ea..b91a3b61e8 100644 --- a/tests/0117-mock_errors.c +++ b/tests/0117-mock_errors.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0118-commit_rebalance.c b/tests/0118-commit_rebalance.c index 1cdcda4623..1ca0a68366 100644 --- a/tests/0118-commit_rebalance.c +++ b/tests/0118-commit_rebalance.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0119-consumer_auth.cpp b/tests/0119-consumer_auth.cpp index 507b673024..40c81ea32b 100644 --- a/tests/0119-consumer_auth.cpp +++ b/tests/0119-consumer_auth.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0120-asymmetric_subscription.c b/tests/0120-asymmetric_subscription.c index 2031dcba19..11ee5f705e 100644 --- a/tests/0120-asymmetric_subscription.c +++ b/tests/0120-asymmetric_subscription.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0121-clusterid.c b/tests/0121-clusterid.c index 35f5d529e9..0a463a88d0 100644 --- a/tests/0121-clusterid.c +++ b/tests/0121-clusterid.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0122-buffer_cleaning_after_rebalance.c b/tests/0122-buffer_cleaning_after_rebalance.c index 4f8727017f..9778391e89 100644 --- a/tests/0122-buffer_cleaning_after_rebalance.c +++ b/tests/0122-buffer_cleaning_after_rebalance.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2021, Magnus Edenhill + * Copyright (c) 2021-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0123-connections_max_idle.c b/tests/0123-connections_max_idle.c index 734467017d..6c7eb8eef9 100644 --- a/tests/0123-connections_max_idle.c +++ b/tests/0123-connections_max_idle.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2021, Magnus Edenhill + * Copyright (c) 2021-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0124-openssl_invalid_engine.c b/tests/0124-openssl_invalid_engine.c index 5c61e5318a..33371f4f0b 100644 --- a/tests/0124-openssl_invalid_engine.c +++ b/tests/0124-openssl_invalid_engine.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2021, Magnus Edenhill + * Copyright (c) 2021-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0125-immediate_flush.c b/tests/0125-immediate_flush.c index b03714194c..c7cbcca174 100644 --- a/tests/0125-immediate_flush.c +++ b/tests/0125-immediate_flush.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2021, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0126-oauthbearer_oidc.c b/tests/0126-oauthbearer_oidc.c index 8eb1870684..0db40ea1dc 100644 --- a/tests/0126-oauthbearer_oidc.c +++ b/tests/0126-oauthbearer_oidc.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2021, Magnus Edenhill + * Copyright (c) 2021-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0127-fetch_queue_backoff.cpp b/tests/0127-fetch_queue_backoff.cpp index f242212974..41c2db8c3b 100644 --- a/tests/0127-fetch_queue_backoff.cpp +++ b/tests/0127-fetch_queue_backoff.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0128-sasl_callback_queue.cpp b/tests/0128-sasl_callback_queue.cpp index 784f09bf60..aaf23a081b 100644 --- a/tests/0128-sasl_callback_queue.cpp +++ b/tests/0128-sasl_callback_queue.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2021, Magnus Edenhill + * Copyright (c) 2021-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0129-fetch_aborted_msgs.c b/tests/0129-fetch_aborted_msgs.c index cc150feccb..7805e6094f 100644 --- a/tests/0129-fetch_aborted_msgs.c +++ b/tests/0129-fetch_aborted_msgs.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2021, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0130-store_offsets.c b/tests/0130-store_offsets.c index f06f31f3ac..e451d7569b 100644 --- a/tests/0130-store_offsets.c +++ b/tests/0130-store_offsets.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/0133-ssl_keys.c b/tests/0133-ssl_keys.c index 850fa27613..4c3e66fee7 100644 --- a/tests/0133-ssl_keys.c +++ b/tests/0133-ssl_keys.c @@ -34,7 +34,7 @@ * file. Decoding it with the correct password or not. * * Ensures it's read correctly on Windows too. - * See https://github.com/edenhill/librdkafka/issues/3992 + * See https://github.com/confluentinc/librdkafka/issues/3992 */ static void do_test_ssl_keys(const char *type, rd_bool_t correct_password) { #define TEST_FIXTURES_FOLDER "./fixtures" diff --git a/tests/0137-barrier_batch_consume.c b/tests/0137-barrier_batch_consume.c index 4e3c855d23..d5c2b32d07 100644 --- a/tests/0137-barrier_batch_consume.c +++ b/tests/0137-barrier_batch_consume.c @@ -2,6 +2,7 @@ * librdkafka - Apache Kafka C library * * Copyright (c) 2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/1000-unktopic.c b/tests/1000-unktopic.c index ad2b7e8709..af4a45a188 100644 --- a/tests/1000-unktopic.c +++ b/tests/1000-unktopic.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/8000-idle.cpp b/tests/8000-idle.cpp index 9659ade97a..3004df406f 100644 --- a/tests/8000-idle.cpp +++ b/tests/8000-idle.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2016, Magnus Edenhill + * Copyright (c) 2016-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/fuzzers/fuzz_regex.c b/tests/fuzzers/fuzz_regex.c index 2facc19f02..8e75848ddc 100644 --- a/tests/fuzzers/fuzz_regex.c +++ b/tests/fuzzers/fuzz_regex.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/fuzzers/helpers.h b/tests/fuzzers/helpers.h index cfab037779..37d956b233 100644 --- a/tests/fuzzers/helpers.h +++ b/tests/fuzzers/helpers.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/interceptor_test/interceptor_test.c b/tests/interceptor_test/interceptor_test.c index ee8a63ba98..ee1f3978a9 100644 --- a/tests/interceptor_test/interceptor_test.c +++ b/tests/interceptor_test/interceptor_test.c @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/java/IncrementalRebalanceCli.java b/tests/java/IncrementalRebalanceCli.java index de044ae585..75622f06a7 100644 --- a/tests/java/IncrementalRebalanceCli.java +++ b/tests/java/IncrementalRebalanceCli.java @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/java/Murmur2Cli.java b/tests/java/Murmur2Cli.java index 22444532d2..08105d4e65 100644 --- a/tests/java/Murmur2Cli.java +++ b/tests/java/Murmur2Cli.java @@ -2,7 +2,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/java/TransactionProducerCli.java b/tests/java/TransactionProducerCli.java index f880c1422d..6bc09712aa 100644 --- a/tests/java/TransactionProducerCli.java +++ b/tests/java/TransactionProducerCli.java @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2020, Magnus Edenhill + * Copyright (c) 2020-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/plugin_test/plugin_test.c b/tests/plugin_test/plugin_test.c index 54639a5a83..dab8687b65 100644 --- a/tests/plugin_test/plugin_test.c +++ b/tests/plugin_test/plugin_test.c @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2017 Magnus Edenhill + * Copyright (c) 2017-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/rusage.c b/tests/rusage.c index 48e702f3f4..7d4048adb9 100644 --- a/tests/rusage.c +++ b/tests/rusage.c @@ -1,7 +1,7 @@ /* * librdkafka - The Apache Kafka C/C++ library * - * Copyright (c) 2019 Magnus Edenhill + * Copyright (c) 2019-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/sockem.c b/tests/sockem.c index 2de01627d8..bf707a9b27 100644 --- a/tests/sockem.c +++ b/tests/sockem.c @@ -1,7 +1,7 @@ /* * sockem - socket-level network emulation * - * Copyright (c) 2016, Magnus Edenhill, Andreas Smas + * Copyright (c) 2016-2022, Magnus Edenhill, Andreas Smas * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/sockem.h b/tests/sockem.h index 8a2ddcd875..02fa55fba0 100644 --- a/tests/sockem.h +++ b/tests/sockem.h @@ -1,7 +1,7 @@ /* * sockem - socket-level network emulation * - * Copyright (c) 2016, Magnus Edenhill, Andreas Smas + * Copyright (c) 2016-2022, Magnus Edenhill, Andreas Smas * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/sockem_ctrl.c b/tests/sockem_ctrl.c index c3e8ce92ed..4396d273a9 100644 --- a/tests/sockem_ctrl.c +++ b/tests/sockem_ctrl.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018, Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/sockem_ctrl.h b/tests/sockem_ctrl.h index d33c87fca0..db616d6765 100644 --- a/tests/sockem_ctrl.h +++ b/tests/sockem_ctrl.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2018, Magnus Edenhill + * Copyright (c) 2018-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/test.c b/tests/test.c index 93887dffee..0027d28c0d 100644 --- a/tests/test.c +++ b/tests/test.c @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2013, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -322,7 +323,7 @@ struct test tests[] = { _TEST(0028_long_topicnames, TEST_F_KNOWN_ISSUE, TEST_BRKVER(0, 9, 0, 0), - .extra = "https://github.com/edenhill/librdkafka/issues/529"), + .extra = "https://github.com/confluentinc/librdkafka/issues/529"), _TEST(0029_assign_offset, 0), _TEST(0030_offset_commit, 0, diff --git a/tests/test.h b/tests/test.h index 71a5402050..596824f918 100644 --- a/tests/test.h +++ b/tests/test.h @@ -1,7 +1,8 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill + * 2023, Confluent Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/testcpp.cpp b/tests/testcpp.cpp index e965e249f1..c1a7f12810 100644 --- a/tests/testcpp.cpp +++ b/tests/testcpp.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/testcpp.h b/tests/testcpp.h index 2ecaed3948..1c5bc17d40 100644 --- a/tests/testcpp.h +++ b/tests/testcpp.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/testshared.h b/tests/testshared.h index efdd5d5550..0ba512b273 100644 --- a/tests/testshared.h +++ b/tests/testshared.h @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/xxxx-assign_partition.c b/tests/xxxx-assign_partition.c index 18431ba723..801919c3c7 100644 --- a/tests/xxxx-assign_partition.c +++ b/tests/xxxx-assign_partition.c @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2015, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tests/xxxx-metadata.cpp b/tests/xxxx-metadata.cpp index 00c31bc824..163b68f241 100644 --- a/tests/xxxx-metadata.cpp +++ b/tests/xxxx-metadata.cpp @@ -1,7 +1,7 @@ /* * librdkafka - Apache Kafka C library * - * Copyright (c) 2012-2014, Magnus Edenhill + * Copyright (c) 2012-2022, Magnus Edenhill * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/win32/librdkafka.autopkg.template b/win32/librdkafka.autopkg.template index 5ad8b1026c..4a4ccfbddc 100644 --- a/win32/librdkafka.autopkg.template +++ b/win32/librdkafka.autopkg.template @@ -1,9 +1,9 @@ configurations { - Toolset { - key : "PlatformToolset"; + Toolset { + key : "PlatformToolset"; choices: { v120, v140, v142 }; - - // Explicitly Not including pivot variants: "WindowsKernelModeDriver8.0", "WindowsApplicationForDrivers8.0", "WindowsUserModeDriver8.0" + + // Explicitly Not including pivot variants: "WindowsKernelModeDriver8.0", "WindowsApplicationForDrivers8.0", "WindowsUserModeDriver8.0" // We're normalizing out the concept of the v140 platform -- Overloading the $(PlatformToolset) variable for additional pivots was a dumb idea. v140.condition = "( $(PlatformToolset.ToLower().IndexOf('v140')) > -1 Or '$(PlatformToolset.ToLower())' == 'windowskernelmodedriver8.0' Or '$(PlatformToolset.ToLower())' == 'windowsapplicationfordrivers8.0' Or '$(PlatformToolset.ToLower())' == 'windowsusermodedriver8.0' )"; @@ -17,10 +17,9 @@ nuget { // pre-deployment script. version : @version; title: "librdkafka"; - authors: {Magnus Edenhill, edenhill}; - owners: {Magnus Edenhill, edenhill}; - licenseUrl: "https://github.com/edenhill/librdkafka/blob/master/LICENSES.txt"; - projectUrl: "https://github.com/edenhill/librdkafka"; + authors: {Magnus Edenhill, edenhill, confluent}; + licenseUrl: "https://github.com/confluentinc/librdkafka/blob/master/LICENSES.txt"; + projectUrl: "https://github.com/confluentinc/librdkafka"; requireLicenseAcceptance: false; summary: "The Apache Kafka C/C++ client library"; description:"The Apache Kafka C/C++ client library"; @@ -52,4 +51,4 @@ nuget { targets { Defines += HAS_LIBRDKAFKA; }; -}; \ No newline at end of file +}; From d174c0dddc1a6c17a93b9b3e1d10e5cf4b2b61b2 Mon Sep 17 00:00:00 2001 From: ConfluentTools <96149134+ConfluentTools@users.noreply.github.com> Date: Thu, 29 Jun 2023 23:58:22 -0500 Subject: [PATCH 3/9] chore: update repo semaphore project (#4338) Co-authored-by: Confluent Jenkins Bot --- .semaphore/project_public.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .semaphore/project_public.yml diff --git a/.semaphore/project_public.yml b/.semaphore/project_public.yml new file mode 100644 index 0000000000..7e095c94d9 --- /dev/null +++ b/.semaphore/project_public.yml @@ -0,0 +1,20 @@ +# This file is managed by ServiceBot plugin - Semaphore. The content in this file is created using a common +# template and configurations in service.yml. +# Modifications in this file will be overwritten by generated content in the nightly run. +# For more information, please refer to the page: +# https://confluentinc.atlassian.net/wiki/spaces/Foundations/pages/2871296194/Add+SemaphoreCI +apiVersion: v1alpha +kind: Project +metadata: + name: librdkafka + description: "" +spec: + visibility: private + repository: + url: git@github.com:confluentinc/librdkafka.git + pipeline_file: .semaphore/semaphore.yml + integration_type: github_app + status: + pipeline_files: + - path: .semaphore/semaphore.yml + level: pipeline From 961946e55fb3f89eb782d4011af4bf5cd3c31f17 Mon Sep 17 00:00:00 2001 From: Anchit Jain <112778471+anchitj@users.noreply.github.com> Date: Fri, 7 Jul 2023 16:27:01 +0530 Subject: [PATCH 4/9] Add KIP-235 implementation (#4292) Add DNS alias support for secured connection, needed for Kerberos SASL authentication. --- CHANGELOG.md | 2 + CONFIGURATION.md | 1 + INTRODUCTION.md | 2 +- src/rdaddr.h | 2 +- src/rdkafka.c | 3 +- src/rdkafka_broker.c | 88 +++++++++++++++++++++++++++++++++++--------- src/rdkafka_broker.h | 4 +- src/rdkafka_conf.c | 13 +++++++ src/rdkafka_conf.h | 6 +++ tests/0004-conf.c | 2 + 10 files changed, 102 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87005fc0d7..b39a7249ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ librdkafka v2.2.0 is a feature release: closes as normal ones (#4294). * Added `fetch.queue.backoff.ms` to the consumer to control how long the consumer backs off next fetch attempt. (@bitemyapp, @edenhill, #2879) + * [KIP-235](https://cwiki.apache.org/confluence/display/KAFKA/KIP-235%3A+Add+DNS+alias+support+for+secured+connection): + Add DNS alias support for secured connection (#4292). ## Enhancements diff --git a/CONFIGURATION.md b/CONFIGURATION.md index 9a0e7ab4c7..127fe4c88f 100644 --- a/CONFIGURATION.md +++ b/CONFIGURATION.md @@ -152,6 +152,7 @@ delivery.report.only.error | P | true, false | false dr_cb | P | | | low | Delivery report callback (set with rd_kafka_conf_set_dr_cb())
*Type: see dedicated API* dr_msg_cb | P | | | low | Delivery report callback (set with rd_kafka_conf_set_dr_msg_cb())
*Type: see dedicated API* sticky.partitioning.linger.ms | P | 0 .. 900000 | 10 | low | Delay in milliseconds to wait to assign new sticky partitions for each topic. By default, set to double the time of linger.ms. To disable sticky behavior, set to 0. This behavior affects messages with the key NULL in all cases, and messages with key lengths of zero when the consistent_random partitioner is in use. These messages would otherwise be assigned randomly. A higher value allows for more effective batching of these messages.
*Type: integer* +client.dns.lookup | * | use_all_dns_ips, resolve_canonical_bootstrap_servers_only | use_all_dns_ips | low | Controls how the client uses DNS lookups. By default, when the lookup returns multiple IP addresses for a hostname, they will all be attempted for connection before the connection is considered failed. This applies to both bootstrap and advertised servers. If the value is set to `resolve_canonical_bootstrap_servers_only`, each entry will be resolved and expanded into a list of canonical names. NOTE: Default here is different from the Java client's default behavior, which connects only to the first IP address returned for a hostname.
*Type: enum value* ## Topic configuration properties diff --git a/INTRODUCTION.md b/INTRODUCTION.md index 101a338b55..32d42bd1aa 100644 --- a/INTRODUCTION.md +++ b/INTRODUCTION.md @@ -1900,7 +1900,7 @@ The [Apache Kafka Implementation Proposals (KIPs)](https://cwiki.apache.org/conf | KIP-226 - AdminAPI: Dynamic broker config | 1.1.0 | Supported | | KIP-227 - Consumer Incremental Fetch | 1.1.0 | Not supported | | KIP-229 - AdminAPI: DeleteGroups | 1.1.0 | Supported | -| KIP-235 - DNS alias for secure connections | 2.1.0 | Not supported | +| KIP-235 - DNS alias for secure connections | 2.1.0 | Supported | | KIP-249 - AdminAPI: Deletegation Tokens | 2.0.0 | Not supported | | KIP-255 - SASL OAUTHBEARER | 2.0.0 | Supported | | KIP-266 - Fix indefinite consumer timeouts | 2.0.0 | Supported (bound by session.timeout.ms and max.poll.interval.ms) | diff --git a/src/rdaddr.h b/src/rdaddr.h index 0c407a2969..7e86a549a8 100644 --- a/src/rdaddr.h +++ b/src/rdaddr.h @@ -139,7 +139,7 @@ rd_sockaddr_list_next(rd_sockaddr_list_t *rsal) { #define RD_SOCKADDR_LIST_FOREACH(sinx, rsal) \ for ((sinx) = &(rsal)->rsal_addr[0]; \ - (sinx) < &(rsal)->rsal_addr[(rsal)->rsal_len]; (sinx)++) + (sinx) < &(rsal)->rsal_addr[(rsal)->rsal_cnt]; (sinx)++) /** * Wrapper for getaddrinfo(3) that performs these additional tasks: diff --git a/src/rdkafka.c b/src/rdkafka.c index 0311285587..4f37ecc974 100644 --- a/src/rdkafka.c +++ b/src/rdkafka.c @@ -2524,7 +2524,8 @@ rd_kafka_t *rd_kafka_new(rd_kafka_type_t type, /* Add initial list of brokers from configuration */ if (rk->rk_conf.brokerlist) { - if (rd_kafka_brokers_add0(rk, rk->rk_conf.brokerlist) == 0) + if (rd_kafka_brokers_add0(rk, rk->rk_conf.brokerlist, + rd_true) == 0) rd_kafka_op_err(rk, RD_KAFKA_RESP_ERR__ALL_BROKERS_DOWN, "No brokers configured"); } diff --git a/src/rdkafka_broker.c b/src/rdkafka_broker.c index da6a2b1803..481c21d9c5 100644 --- a/src/rdkafka_broker.c +++ b/src/rdkafka_broker.c @@ -50,6 +50,7 @@ #include #include "rd.h" +#include "rdaddr.h" #include "rdkafka_int.h" #include "rdkafka_msg.h" #include "rdkafka_msgset.h" @@ -5257,6 +5258,31 @@ static int rd_kafka_broker_name_parse(rd_kafka_t *rk, return 0; } +/** + * @brief Add a broker from a string of type "[proto://]host[:port]" to the list + * of brokers. *cnt is increased by one if a broker was added, else not. + */ +static void rd_kafka_find_or_add_broker(rd_kafka_t *rk, + rd_kafka_secproto_t proto, + const char *host, + uint16_t port, + int *cnt) { + rd_kafka_broker_t *rkb = NULL; + + if ((rkb = rd_kafka_broker_find(rk, proto, host, port)) && + rkb->rkb_source == RD_KAFKA_CONFIGURED) { + (*cnt)++; + } else if (rd_kafka_broker_add(rk, RD_KAFKA_CONFIGURED, proto, host, + port, RD_KAFKA_NODEID_UA) != NULL) + (*cnt)++; + + /* If rd_kafka_broker_find returned a broker its + * reference needs to be released + * See issue #193 */ + if (rkb) + rd_kafka_broker_destroy(rkb); +} + /** * @brief Adds a (csv list of) broker(s). * Returns the number of brokers succesfully added. @@ -5264,17 +5290,22 @@ static int rd_kafka_broker_name_parse(rd_kafka_t *rk, * @locality any thread * @locks none */ -int rd_kafka_brokers_add0(rd_kafka_t *rk, const char *brokerlist) { +int rd_kafka_brokers_add0(rd_kafka_t *rk, + const char *brokerlist, + rd_bool_t is_bootstrap_server_list) { char *s_copy = rd_strdup(brokerlist); char *s = s_copy; int cnt = 0; - rd_kafka_broker_t *rkb; - int pre_cnt = rd_atomic32_get(&rk->rk_broker_cnt); + int pre_cnt = rd_atomic32_get(&rk->rk_broker_cnt); + rd_sockaddr_inx_t *sinx; + rd_sockaddr_list_t *sockaddr_list; /* Parse comma-separated list of brokers. */ while (*s) { uint16_t port; const char *host; + const char *err_str; + const char *resolved_FQDN; rd_kafka_secproto_t proto; if (*s == ',' || *s == ' ') { @@ -5287,20 +5318,43 @@ int rd_kafka_brokers_add0(rd_kafka_t *rk, const char *brokerlist) { break; rd_kafka_wrlock(rk); + if (is_bootstrap_server_list && + rk->rk_conf.client_dns_lookup == + RD_KAFKA_RESOLVE_CANONICAL_BOOTSTRAP_SERVERS_ONLY) { + rd_kafka_dbg(rk, ALL, "INIT", + "Canonicalizing bootstrap broker %s:%d", + host, port); + sockaddr_list = rd_getaddrinfo( + host, RD_KAFKA_PORT_STR, AI_ADDRCONFIG, + rk->rk_conf.broker_addr_family, SOCK_STREAM, + IPPROTO_TCP, rk->rk_conf.resolve_cb, + rk->rk_conf.opaque, &err_str); + + if (!sockaddr_list) { + rd_kafka_log(rk, LOG_WARNING, "BROKER", + "Failed to resolve '%s': %s", host, + err_str); + rd_kafka_wrunlock(rk); + continue; + } - if ((rkb = rd_kafka_broker_find(rk, proto, host, port)) && - rkb->rkb_source == RD_KAFKA_CONFIGURED) { - cnt++; - } else if (rd_kafka_broker_add(rk, RD_KAFKA_CONFIGURED, proto, - host, port, - RD_KAFKA_NODEID_UA) != NULL) - cnt++; - - /* If rd_kafka_broker_find returned a broker its - * reference needs to be released - * See issue #193 */ - if (rkb) - rd_kafka_broker_destroy(rkb); + RD_SOCKADDR_LIST_FOREACH(sinx, sockaddr_list) { + resolved_FQDN = rd_sockaddr2str( + sinx, RD_SOCKADDR2STR_F_RESOLVE); + rd_kafka_dbg( + rk, ALL, "INIT", + "Adding broker with resolved hostname %s", + resolved_FQDN); + + rd_kafka_find_or_add_broker( + rk, proto, resolved_FQDN, port, &cnt); + }; + + rd_sockaddr_list_destroy(sockaddr_list); + } else { + rd_kafka_find_or_add_broker(rk, proto, host, port, + &cnt); + } rd_kafka_wrunlock(rk); } @@ -5322,7 +5376,7 @@ int rd_kafka_brokers_add0(rd_kafka_t *rk, const char *brokerlist) { int rd_kafka_brokers_add(rd_kafka_t *rk, const char *brokerlist) { - return rd_kafka_brokers_add0(rk, brokerlist); + return rd_kafka_brokers_add0(rk, brokerlist, rd_false); } diff --git a/src/rdkafka_broker.h b/src/rdkafka_broker.h index 1e03dba850..30f66b25c9 100644 --- a/src/rdkafka_broker.h +++ b/src/rdkafka_broker.h @@ -469,7 +469,9 @@ rd_kafka_broker_t *rd_kafka_broker_controller_async(rd_kafka_t *rk, int state, rd_kafka_enq_once_t *eonce); -int rd_kafka_brokers_add0(rd_kafka_t *rk, const char *brokerlist); +int rd_kafka_brokers_add0(rd_kafka_t *rk, + const char *brokerlist, + rd_bool_t is_bootstrap_server_list); void rd_kafka_broker_set_state(rd_kafka_broker_t *rkb, int state); void rd_kafka_broker_fail(rd_kafka_broker_t *rkb, diff --git a/src/rdkafka_conf.c b/src/rdkafka_conf.c index 285c8e4458..9200af4c6a 100644 --- a/src/rdkafka_conf.c +++ b/src/rdkafka_conf.c @@ -1439,6 +1439,19 @@ static const struct rd_kafka_property rd_kafka_properties[] = { "A higher value allows for more effective batching of these " "messages.", 0, 900000, 10}, + {_RK_GLOBAL, "client.dns.lookup", _RK_C_S2I, _RK(client_dns_lookup), + "Controls how the client uses DNS lookups. By default, when the lookup " + "returns multiple IP addresses for a hostname, they will all be attempted " + "for connection before the connection is considered failed. This applies " + "to both bootstrap and advertised servers. If the value is set to " + "`resolve_canonical_bootstrap_servers_only`, each entry will be resolved " + "and expanded into a list of canonical names. NOTE: Default here is " + "different from the Java client's default behavior, which connects only " + "to the first IP address returned for a hostname. ", + .vdef = RD_KAFKA_USE_ALL_DNS_IPS, + .s2i = {{RD_KAFKA_USE_ALL_DNS_IPS, "use_all_dns_ips"}, + {RD_KAFKA_RESOLVE_CANONICAL_BOOTSTRAP_SERVERS_ONLY, + "resolve_canonical_bootstrap_servers_only"}}}, /* diff --git a/src/rdkafka_conf.h b/src/rdkafka_conf.h index 6a79515c2a..01b6258d2e 100644 --- a/src/rdkafka_conf.h +++ b/src/rdkafka_conf.h @@ -158,6 +158,11 @@ typedef enum { RD_KAFKA_SSL_ENDPOINT_ID_HTTPS, /**< RFC2818 */ } rd_kafka_ssl_endpoint_id_t; +typedef enum { + RD_KAFKA_USE_ALL_DNS_IPS, + RD_KAFKA_RESOLVE_CANONICAL_BOOTSTRAP_SERVERS_ONLY, +} rd_kafka_client_dns_lookup_t; + /* Increase in steps of 64 as needed. * This must be larger than sizeof(rd_kafka_[topic_]conf_t) */ #define RD_KAFKA_CONF_PROPS_IDX_MAX (64 * 33) @@ -224,6 +229,7 @@ struct rd_kafka_conf_s { int api_version_fallback_ms; char *broker_version_fallback; rd_kafka_secproto_t security_protocol; + rd_kafka_client_dns_lookup_t client_dns_lookup; struct { #if WITH_SSL diff --git a/tests/0004-conf.c b/tests/0004-conf.c index b5f293921e..5dbd9f0b1d 100644 --- a/tests/0004-conf.c +++ b/tests/0004-conf.c @@ -529,6 +529,8 @@ int main_0004_conf(int argc, char **argv) { "ssl.ca.certificate.stores", "Intermediate ,, Root ,", #endif + "client.dns.lookup", + "resolve_canonical_bootstrap_servers_only", NULL }; static const char *tconfs[] = {"request.required.acks", From 53a6a50bfba000e5fb8956b99ca48ce09282e2ce Mon Sep 17 00:00:00 2001 From: prasanthV <40450906+PrasanthV454@users.noreply.github.com> Date: Mon, 10 Jul 2023 22:41:16 +0530 Subject: [PATCH 5/9] Incremental alter configs implementation [KIP-339] (#4110) requires broker version >= 2.3.0 --------- Co-authored-by: Emanuele Sabellico --- CHANGELOG.md | 4 +- INTRODUCTION.md | 67 ++--- LICENSES.txt | 2 +- examples/.gitignore | 1 + examples/CMakeLists.txt | 23 ++ examples/Makefile | 5 + examples/README.md | 1 + examples/incremental_alter_configs.c | 348 ++++++++++++++++++++++++ src/rdkafka.c | 1 + src/rdkafka.h | 121 ++++++++- src/rdkafka_admin.c | 385 +++++++++++++++++++++++---- src/rdkafka_admin.h | 25 +- src/rdkafka_event.c | 11 + src/rdkafka_event.h | 1 + src/rdkafka_int.h | 1 + src/rdkafka_op.c | 147 +++++----- src/rdkafka_op.h | 26 +- src/rdkafka_request.c | 124 +++++++-- src/rdkafka_request.h | 10 + tests/0081-admin.c | 251 +++++++++++++++++ tests/test.c | 82 +++++- tests/test.h | 7 + 22 files changed, 1427 insertions(+), 216 deletions(-) create mode 100644 examples/incremental_alter_configs.c diff --git a/CHANGELOG.md b/CHANGELOG.md index b39a7249ae..95c4dbd0ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,8 +21,10 @@ librdkafka v2.2.0 is a feature release: closes as normal ones (#4294). * Added `fetch.queue.backoff.ms` to the consumer to control how long the consumer backs off next fetch attempt. (@bitemyapp, @edenhill, #2879) - * [KIP-235](https://cwiki.apache.org/confluence/display/KAFKA/KIP-235%3A+Add+DNS+alias+support+for+secured+connection): + * [KIP-235](https://cwiki.apache.org/confluence/display/KAFKA/KIP-235%3A+Add+DNS+alias+support+for+secured+connection): Add DNS alias support for secured connection (#4292). + * [KIP-339](https://cwiki.apache.org/confluence/display/KAFKA/KIP-339%3A+Create+a+new+IncrementalAlterConfigs+API): + IncrementalAlterConfigs API (started by @PrasanthV454, #4110). ## Enhancements diff --git a/INTRODUCTION.md b/INTRODUCTION.md index 32d42bd1aa..d7b9a84a1c 100644 --- a/INTRODUCTION.md +++ b/INTRODUCTION.md @@ -1909,7 +1909,7 @@ The [Apache Kafka Implementation Proposals (KIPs)](https://cwiki.apache.org/conf | KIP-302 - Use all addresses for resolved broker hostname | 2.1.0 | Supported | | KIP-320 - Consumer: handle log truncation | 2.1.0, 2.2.0 | Supported | | KIP-322 - DeleteTopics disabled error code | 2.1.0 | Supported | -| KIP-339 - AdminAPI: incrementalAlterConfigs | 2.3.0 | Not supported | +| KIP-339 - AdminAPI: incrementalAlterConfigs | 2.3.0 | Supported | | KIP-341 - Update Sticky partition assignment data | 2.3.0 | Not supported (superceeded by KIP-429) | | KIP-342 - Custom SASL OAUTHBEARER extensions | 2.1.0 | Supported | | KIP-345 - Consumer: Static membership | 2.4.0 | Supported | @@ -1964,42 +1964,43 @@ The [Apache Kafka Implementation Proposals (KIPs)](https://cwiki.apache.org/conf ### Supported protocol versions -"Kafka max" is the maximum ApiVersion supported in Apache Kafka 3.3.1, while +"Kafka max" is the maximum ApiVersion supported in Apache Kafka 3.4.0, while "librdkafka max" is the maximum ApiVersion supported in the latest release of librdkafka. -| ApiKey | Request name | Kafka max | librdkafka max | -| ------- | ------------------- | ----------- | ----------------------- | -| 0 | Produce | 9 | 7 | -| 1 | Fetch | 13 | 11 | -| 2 | ListOffsets | 7 | 2 | -| 3 | Metadata | 12 | 9 | -| 8 | OffsetCommit | 8 | 7 | -| 9 | OffsetFetch | 8 | 7 | -| 10 | FindCoordinator | 4 | 2 | -| 11 | JoinGroup | 9 | 5 | -| 12 | Heartbeat | 4 | 3 | -| 13 | LeaveGroup | 5 | 1 | -| 14 | SyncGroup | 5 | 3 | -| 15 | DescribeGroups | 5 | 4 | -| 16 | ListGroups | 4 | 4 | -| 17 | SaslHandshake | 1 | 1 | -| 18 | ApiVersions | 3 | 3 | -| 19 | CreateTopics | 7 | 4 | -| 20 | DeleteTopics | 6 | 1 | -| 21 | DeleteRecords | 2 | 1 | -| 22 | InitProducerId | 4 | 4 | -| 24 | AddPartitionsToTxn | 3 | 0 | -| 25 | AddOffsetsToTxn | 3 | 0 | -| 26 | EndTxn | 3 | 1 | -| 28 | TxnOffsetCommit | 3 | 3 | -| 32 | DescribeConfigs | 4 | 1 | -| 33 | AlterConfigs | 2 | 1 | -| 36 | SaslAuthenticate | 2 | 1 | -| 37 | CreatePartitions | 3 | 0 | -| 42 | DeleteGroups | 2 | 1 | -| 47 | OffsetDelete | 0 | 0 | +| ApiKey | Request name | Kafka max | librdkafka max | +| ------- | ------------------------| ----------- | ----------------------- | +| 0 | Produce | 9 | 7 | +| 1 | Fetch | 13 | 11 | +| 2 | ListOffsets | 7 | 2 | +| 3 | Metadata | 12 | 9 | +| 8 | OffsetCommit | 8 | 7 | +| 9 | OffsetFetch | 8 | 7 | +| 10 | FindCoordinator | 4 | 2 | +| 11 | JoinGroup | 9 | 5 | +| 12 | Heartbeat | 4 | 3 | +| 13 | LeaveGroup | 5 | 1 | +| 14 | SyncGroup | 5 | 3 | +| 15 | DescribeGroups | 5 | 4 | +| 16 | ListGroups | 4 | 4 | +| 17 | SaslHandshake | 1 | 1 | +| 18 | ApiVersions | 3 | 3 | +| 19 | CreateTopics | 7 | 4 | +| 20 | DeleteTopics | 6 | 1 | +| 21 | DeleteRecords | 2 | 1 | +| 22 | InitProducerId | 4 | 4 | +| 24 | AddPartitionsToTxn | 3 | 0 | +| 25 | AddOffsetsToTxn | 3 | 0 | +| 26 | EndTxn | 3 | 1 | +| 28 | TxnOffsetCommit | 3 | 3 | +| 32 | DescribeConfigs | 4 | 1 | +| 33 | AlterConfigs | 2 | 2 | +| 36 | SaslAuthenticate | 2 | 0 | +| 37 | CreatePartitions | 3 | 0 | +| 42 | DeleteGroups | 2 | 1 | +| 44 | IncrementalAlterConfigs | 1 | 1 | +| 47 | OffsetDelete | 0 | 0 | diff --git a/LICENSES.txt b/LICENSES.txt index d045048a5d..ed89214919 100644 --- a/LICENSES.txt +++ b/LICENSES.txt @@ -3,7 +3,7 @@ LICENSE librdkafka - Apache Kafka C driver library Copyright (c) 2012-2022, Magnus Edenhill - 2023 Confluent Inc. + 2023, Confluent Inc. All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/examples/.gitignore b/examples/.gitignore index 4190608c42..893f84179b 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -17,3 +17,4 @@ list_consumer_groups describe_consumer_groups list_consumer_group_offsets alter_consumer_group_offsets +incremental_alter_configs diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index bbbb89ad90..748abad572 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -26,6 +26,29 @@ target_link_libraries(openssl_engine_example_cpp PUBLIC rdkafka++) add_executable(misc misc.c ${win32_sources}) target_link_libraries(misc PUBLIC rdkafka) +add_executable(idempotent_producer idempotent_producer.c ${win32_sources}) +target_link_libraries(idempotent_producer PUBLIC rdkafka) + +add_executable(transactions transactions.c ${win32_sources}) +target_link_libraries(transactions PUBLIC rdkafka) + +add_executable(delete_records delete_records.c ${win32_sources}) +target_link_libraries(delete_records PUBLIC rdkafka) + +add_executable(list_consumer_groups list_consumer_groups.c ${win32_sources}) +target_link_libraries(list_consumer_groups PUBLIC rdkafka) + +add_executable(describe_consumer_groups describe_consumer_groups.c ${win32_sources}) +target_link_libraries(describe_consumer_groups PUBLIC rdkafka) + +add_executable(list_consumer_group_offsets list_consumer_group_offsets.c ${win32_sources}) +target_link_libraries(list_consumer_group_offsets PUBLIC rdkafka) + +add_executable(alter_consumer_group_offsets alter_consumer_group_offsets.c ${win32_sources}) +target_link_libraries(alter_consumer_group_offsets PUBLIC rdkafka) + +add_executable(incremental_alter_configs incremental_alter_configs.c ${win32_sources}) +target_link_libraries(incremental_alter_configs PUBLIC rdkafka) # The targets below has Unix include dirs and do not compile on Windows. if(NOT WIN32) diff --git a/examples/Makefile b/examples/Makefile index 15fba3c2af..d06e8fc04a 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -8,6 +8,7 @@ EXAMPLES ?= rdkafka_example rdkafka_performance rdkafka_example_cpp \ describe_consumer_groups \ list_consumer_group_offsets \ alter_consumer_group_offsets \ + incremental_alter_configs \ misc all: $(EXAMPLES) @@ -80,6 +81,10 @@ alter_consumer_group_offsets: ../src/librdkafka.a alter_consumer_group_offsets.c $(CC) $(CPPFLAGS) $(CFLAGS) $@.c -o $@ $(LDFLAGS) \ ../src/librdkafka.a $(LIBS) +incremental_alter_configs: ../src/librdkafka.a incremental_alter_configs.c + $(CC) $(CPPFLAGS) $(CFLAGS) $@.c -o $@ $(LDFLAGS) \ + ../src/librdkafka.a $(LIBS) + rdkafka_complex_consumer_example: ../src/librdkafka.a rdkafka_complex_consumer_example.c $(CC) $(CPPFLAGS) $(CFLAGS) rdkafka_complex_consumer_example.c -o $@ $(LDFLAGS) \ ../src/librdkafka.a $(LIBS) diff --git a/examples/README.md b/examples/README.md index 3caee3b861..34afac2157 100644 --- a/examples/README.md +++ b/examples/README.md @@ -36,3 +36,4 @@ For more complex uses, see: * [describe_consumer_groups.c](describe_consumer_groups.c) - Describe consumer groups. * [list_consumer_group_offsets.c](list_consumer_group_offsets.c) - List offsets of a consumer group. * [alter_consumer_group_offsets.c](alter_consumer_group_offsets.c) - Alter offsets of a consumer group. + * [incremental_alter_configs.c](incremental_alter_configs.c) - Incrementally alter resource configurations. diff --git a/examples/incremental_alter_configs.c b/examples/incremental_alter_configs.c new file mode 100644 index 0000000000..40a16cf842 --- /dev/null +++ b/examples/incremental_alter_configs.c @@ -0,0 +1,348 @@ +/* + * librdkafka - Apache Kafka C library + * + * Copyright (c) 2023, Confluent Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * IncrementalAlterConfigs usage example. + */ + +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include "../win32/wingetopt.h" +#else +#include +#endif + + +/* Typical include path would be , but this program + * is builtin from within the librdkafka source tree and thus differs. */ +#include "rdkafka.h" + + +const char *argv0; + +static rd_kafka_queue_t *queue; /** Admin result queue. + * This is a global so we can + * yield in stop() */ +static volatile sig_atomic_t run = 1; + +/** + * @brief Signal termination of program + */ +static void stop(int sig) { + if (!run) { + fprintf(stderr, "%% Forced termination\n"); + exit(2); + } + run = 0; + rd_kafka_queue_yield(queue); +} + + +static void usage(const char *reason, ...) { + + fprintf(stderr, + "Incremental alter config usage examples\n" + "\n" + "Usage: %s " + " ...\n" + "\n" + "Options:\n" + " -b Bootstrap server list to connect to.\n" + " -X Set librdkafka configuration property.\n" + " See CONFIGURATION.md for full list.\n" + " -d Enable librdkafka debugging (%s).\n" + "\n", + argv0, rd_kafka_get_debug_contexts()); + + if (reason) { + va_list ap; + char reasonbuf[512]; + + va_start(ap, reason); + vsnprintf(reasonbuf, sizeof(reasonbuf), reason, ap); + va_end(ap); + + fprintf(stderr, "ERROR: %s\n", reasonbuf); + } + + exit(reason ? 1 : 0); +} + + +#define fatal(...) \ + do { \ + fprintf(stderr, "ERROR: "); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + exit(2); \ + } while (0) + + +/** + * @brief Set config property. Exit on failure. + */ +static void conf_set(rd_kafka_conf_t *conf, const char *name, const char *val) { + char errstr[512]; + + if (rd_kafka_conf_set(conf, name, val, errstr, sizeof(errstr)) != + RD_KAFKA_CONF_OK) + fatal("Failed to set %s=%s: %s", name, val, errstr); +} + + + +static void print_alter_configs_result( + FILE *fp, + const rd_kafka_IncrementalAlterConfigs_result_t *result, + const char *prefix) { + size_t i; + size_t config_cnt; + const rd_kafka_ConfigResource_t **configs = + rd_kafka_IncrementalAlterConfigs_result_resources(result, + &config_cnt); + + for (i = 0; i < config_cnt; i++) { + const rd_kafka_ConfigResource_t *config = configs[i]; + + const char *resname = rd_kafka_ConfigResource_name(config); + rd_kafka_ResourceType_t restype = + rd_kafka_ConfigResource_type(config); + rd_kafka_resp_err_t err = rd_kafka_ConfigResource_error(config); + + fprintf(fp, "%sResource type: %s name: %s error: %s: %s\n", + prefix, rd_kafka_ResourceType_name(restype), resname, + rd_kafka_err2str(err), + rd_kafka_ConfigResource_error_string(config)); + } +} + + +/** + * @brief Call rd_kafka_IncrementalAlterConfigs() with a list of + * configs to alter. + */ +static void +cmd_incremental_alter_configs(rd_kafka_conf_t *conf, int argc, char **argv) { + rd_kafka_t *rk; + char errstr[512]; + rd_kafka_AdminOptions_t *options; + rd_kafka_event_t *event = NULL; + rd_kafka_error_t *error; + int retval = 0; + const char *prefix = " "; + int i = 0; + int resources = 0; + int config_cnt; + rd_kafka_ResourceType_t prev_restype = RD_KAFKA_RESOURCE_UNKNOWN; + char *prev_resname = NULL; + rd_kafka_ConfigResource_t **configs; + + if (argc % 5 != 0) { + usage("Invalid number of arguments: %d", argc); + } + + config_cnt = argc / 5; + configs = calloc(config_cnt, sizeof(*configs)); + + for (i = 0; i < config_cnt; i++) { + char *restype_s = argv[i * 5]; + char *resname = argv[i * 5 + 1]; + char *alter_op_type_s = argv[i * 5 + 2]; + char *config_name = argv[i * 5 + 3]; + char *config_value = argv[i * 5 + 4]; + rd_kafka_ConfigResource_t *config; + rd_kafka_AlterConfigOpType_t op_type; + rd_kafka_ResourceType_t restype = + !strcmp(restype_s, "TOPIC") + ? RD_KAFKA_RESOURCE_TOPIC + : !strcmp(restype_s, "BROKER") + ? RD_KAFKA_RESOURCE_BROKER + : RD_KAFKA_RESOURCE_UNKNOWN; + + if (restype == RD_KAFKA_RESOURCE_UNKNOWN) { + usage("Invalid resource type: %s", restype_s); + } + + /* It's not necessary, but cleaner and more efficient to group + * incremental alterations for the same ConfigResource.*/ + if (restype != prev_restype || strcmp(resname, prev_resname)) { + configs[resources++] = + rd_kafka_ConfigResource_new(restype, resname); + } + + config = configs[resources - 1]; + prev_restype = restype; + prev_resname = resname; + + if (!strcmp(alter_op_type_s, "SET")) { + op_type = RD_KAFKA_ALTER_CONFIG_OP_TYPE_SET; + } else if (!strcmp(alter_op_type_s, "APPEND")) { + op_type = RD_KAFKA_ALTER_CONFIG_OP_TYPE_APPEND; + } else if (!strcmp(alter_op_type_s, "SUBTRACT")) { + op_type = RD_KAFKA_ALTER_CONFIG_OP_TYPE_SUBTRACT; + } else if (!strcmp(alter_op_type_s, "DELETE")) { + op_type = RD_KAFKA_ALTER_CONFIG_OP_TYPE_DELETE; + } else { + usage("Invalid alter config operation: %s", + alter_op_type_s); + } + + error = rd_kafka_ConfigResource_add_incremental_config( + config, config_name, op_type, config_value); + + if (error) { + usage( + "Error setting incremental config alteration %s" + " at index %d: %s", + alter_op_type_s, i, rd_kafka_error_string(error)); + } + } + + /* + * Create consumer instance + * NOTE: rd_kafka_new() takes ownership of the conf object + * and the application must not reference it again after + * this call. + */ + rk = rd_kafka_new(RD_KAFKA_CONSUMER, conf, errstr, sizeof(errstr)); + if (!rk) + fatal("Failed to create new consumer: %s", errstr); + + /* + * Incremental alter configs + */ + queue = rd_kafka_queue_new(rk); + + /* Signal handler for clean shutdown */ + signal(SIGINT, stop); + + options = rd_kafka_AdminOptions_new( + rk, RD_KAFKA_ADMIN_OP_INCREMENTALALTERCONFIGS); + + if (rd_kafka_AdminOptions_set_request_timeout( + options, 10 * 1000 /* 10s */, errstr, sizeof(errstr))) { + fprintf(stderr, "%% Failed to set timeout: %s\n", errstr); + goto exit; + } + + rd_kafka_IncrementalAlterConfigs(rk, configs, resources, options, + queue); + + rd_kafka_ConfigResource_destroy_array(configs, resources); + free(configs); + + /* Wait for results */ + event = rd_kafka_queue_poll(queue, -1 /* indefinitely but limited by + * the request timeout set + * above (10s) */); + + if (!event) { + /* User hit Ctrl-C, + * see yield call in stop() signal handler */ + fprintf(stderr, "%% Cancelled by user\n"); + + } else if (rd_kafka_event_error(event)) { + rd_kafka_resp_err_t err = rd_kafka_event_error(event); + /* IncrementalAlterConfigs request failed */ + fprintf(stderr, "%% IncrementalAlterConfigs failed: %s: %s\n", + rd_kafka_err2str(err), + rd_kafka_event_error_string(event)); + goto exit; + + } else { + /* IncrementalAlterConfigs request succeeded, but individual + * configs may have errors. */ + const rd_kafka_IncrementalAlterConfigs_result_t *result = + rd_kafka_event_IncrementalAlterConfigs_result(event); + printf("IncrementalAlterConfigs results:\n"); + print_alter_configs_result(stdout, result, prefix); + } + + +exit: + if (event) + rd_kafka_event_destroy(event); + rd_kafka_AdminOptions_destroy(options); + rd_kafka_queue_destroy(queue); + /* Destroy the client instance */ + rd_kafka_destroy(rk); + + exit(retval); +} + +int main(int argc, char **argv) { + rd_kafka_conf_t *conf; /**< Client configuration object */ + int opt; + argv0 = argv[0]; + + /* + * Create Kafka client configuration place-holder + */ + conf = rd_kafka_conf_new(); + + + /* + * Parse common options + */ + while ((opt = getopt(argc, argv, "b:X:d:")) != -1) { + switch (opt) { + case 'b': + conf_set(conf, "bootstrap.servers", optarg); + break; + + case 'X': { + char *name = optarg, *val; + + if (!(val = strchr(name, '='))) + fatal("-X expects a name=value argument"); + + *val = '\0'; + val++; + + conf_set(conf, name, val); + break; + } + + case 'd': + conf_set(conf, "debug", optarg); + break; + + default: + usage("Unknown option %c", (char)opt); + } + } + + cmd_incremental_alter_configs(conf, argc - optind, &argv[optind]); + + return 0; +} diff --git a/src/rdkafka.c b/src/rdkafka.c index 4f37ecc974..4a8ec30dfb 100644 --- a/src/rdkafka.c +++ b/src/rdkafka.c @@ -3951,6 +3951,7 @@ rd_kafka_op_res_t rd_kafka_poll_cb(rd_kafka_t *rk, case RD_KAFKA_OP_DELETETOPICS: case RD_KAFKA_OP_CREATEPARTITIONS: case RD_KAFKA_OP_ALTERCONFIGS: + case RD_KAFKA_OP_INCREMENTALALTERCONFIGS: case RD_KAFKA_OP_DESCRIBECONFIGS: case RD_KAFKA_OP_DELETERECORDS: case RD_KAFKA_OP_DELETEGROUPS: diff --git a/src/rdkafka.h b/src/rdkafka.h index e53123d3cd..0e14b8d273 100644 --- a/src/rdkafka.h +++ b/src/rdkafka.h @@ -5367,7 +5367,8 @@ typedef int rd_kafka_event_type_t; #define RD_KAFKA_EVENT_LISTCONSUMERGROUPOFFSETS_RESULT 0x8000 /** AlterConsumerGroupOffsets_result_t */ #define RD_KAFKA_EVENT_ALTERCONSUMERGROUPOFFSETS_RESULT 0x10000 - +/** IncrementalAlterConfigs_result_t */ +#define RD_KAFKA_EVENT_INCREMENTALALTERCONFIGS_RESULT 0x20000 /** * @returns the event type for the given event. @@ -5514,6 +5515,7 @@ int rd_kafka_event_error_is_fatal(rd_kafka_event_t *rkev); * - RD_KAFKA_EVENT_DESCRIBEACLS_RESULT * - RD_KAFKA_EVENT_DELETEACLS_RESULT * - RD_KAFKA_EVENT_ALTERCONFIGS_RESULT + * - RD_KAFKA_EVENT_INCREMENTAL_ALTERCONFIGS_RESULT * - RD_KAFKA_EVENT_DESCRIBECONFIGS_RESULT * - RD_KAFKA_EVENT_DELETEGROUPS_RESULT * - RD_KAFKA_EVENT_DELETECONSUMERGROUPOFFSETS_RESULT @@ -5617,6 +5619,8 @@ typedef rd_kafka_event_t rd_kafka_DeleteAcls_result_t; typedef rd_kafka_event_t rd_kafka_CreatePartitions_result_t; /*! AlterConfigs result type */ typedef rd_kafka_event_t rd_kafka_AlterConfigs_result_t; +/*! IncrementalAlterConfigs result type */ +typedef rd_kafka_event_t rd_kafka_IncrementalAlterConfigs_result_t; /*! CreateTopics result type */ typedef rd_kafka_event_t rd_kafka_DescribeConfigs_result_t; /*! DeleteRecords result type */ @@ -5682,6 +5686,18 @@ rd_kafka_event_CreatePartitions_result(rd_kafka_event_t *rkev); RD_EXPORT const rd_kafka_AlterConfigs_result_t * rd_kafka_event_AlterConfigs_result(rd_kafka_event_t *rkev); +/** + * @brief Get IncrementalAlterConfigs result. + * + * @returns the result of a IncrementalAlterConfigs request, or NULL if event is + * of different type. + * + * Event types: + * RD_KAFKA_EVENT_INCREMENTALALTERCONFIGS_RESULT + */ +RD_EXPORT const rd_kafka_IncrementalAlterConfigs_result_t * +rd_kafka_event_IncrementalAlterConfigs_result(rd_kafka_event_t *rkev); + /** * @brief Get DescribeConfigs result. * @@ -6721,6 +6737,8 @@ typedef enum rd_kafka_admin_op_t { RD_KAFKA_ADMIN_OP_LISTCONSUMERGROUPOFFSETS, /** AlterConsumerGroupOffsets */ RD_KAFKA_ADMIN_OP_ALTERCONSUMERGROUPOFFSETS, + /** IncrementalAlterConfigs */ + RD_KAFKA_ADMIN_OP_INCREMENTALALTERCONFIGS, RD_KAFKA_ADMIN_OP__CNT /**< Number of ops defined */ } rd_kafka_admin_op_t; @@ -6856,6 +6874,8 @@ rd_kafka_AdminOptions_set_validate_only(rd_kafka_AdminOptions_t *options, * the following exceptions: * - AlterConfigs with a BROKER resource are sent to the broker id set * as the resource name. + * - IncrementalAlterConfigs with a BROKER resource are sent to the broker id + * set as the resource name. * - DescribeConfigs with a BROKER resource are sent to the broker id set * as the resource name. * @@ -7416,6 +7436,18 @@ typedef enum rd_kafka_ResourcePatternType_t { RD_KAFKA_RESOURCE_PATTERN_TYPE__CNT, } rd_kafka_ResourcePatternType_t; +/** + * @enum rd_kafka_AlterConfigOpType_t + * @brief Incremental alter configs operations. + */ +typedef enum rd_kafka_AlterConfigOpType_t { + RD_KAFKA_ALTER_CONFIG_OP_TYPE_SET = 0, + RD_KAFKA_ALTER_CONFIG_OP_TYPE_DELETE = 1, + RD_KAFKA_ALTER_CONFIG_OP_TYPE_APPEND = 2, + RD_KAFKA_ALTER_CONFIG_OP_TYPE_SUBTRACT = 3, + RD_KAFKA_ALTER_CONFIG_OP_TYPE__CNT, +} rd_kafka_AlterConfigOpType_t; + /** * @returns a string representation of the \p resource_pattern_type */ @@ -7481,6 +7513,31 @@ rd_kafka_ConfigResource_set_config(rd_kafka_ConfigResource_t *config, const char *value); +/** + * @brief Add the value of the configuration entry for a subsequent + * incremental alter config operation. APPEND and SUBTRACT are + * possible for list-type configuration entries only. + * + * @param config ConfigResource to add config property to. + * @param name Configuration name, depends on resource type. + * @param op_type Operation type, one of rd_kafka_AlterConfigOpType_t. + * @param value Configuration value, depends on resource type and \p name. + * Set to \c NULL, only with with op_type set to DELETE, + * to revert configuration value to default. + * + * @returns NULL on success, or an rd_kafka_error_t * + * with the corresponding error code and string. + * Error ownership belongs to the caller. + * Possible error codes: + * - RD_KAFKA_RESP_ERR__INVALID_ARG on invalid input. + */ +RD_EXPORT rd_kafka_error_t *rd_kafka_ConfigResource_add_incremental_config( + rd_kafka_ConfigResource_t *config, + const char *name, + rd_kafka_AlterConfigOpType_t op_type, + const char *value); + + /** * @brief Get an array of config entries from a ConfigResource object. * @@ -7546,6 +7603,8 @@ rd_kafka_ConfigResource_error_string(const rd_kafka_ConfigResource_t *config); * since these resource requests must be sent to the broker specified * in the resource. * + * @deprecated Use rd_kafka_IncrementalAlterConfigs(). + * */ RD_EXPORT void rd_kafka_AlterConfigs(rd_kafka_t *rk, @@ -7580,6 +7639,66 @@ rd_kafka_AlterConfigs_result_resources( +/* + * IncrementalAlterConfigs - alter cluster configuration incrementally. + * + */ + + +/** + * @brief Incrementally update the configuration for the specified resources. + * Updates are not transactional so they may succeed for some resources + * while fail for others. The configs for a particular resource are + * updated atomically, executing the corresponding incremental operations + * on the provided configurations. + * + * @remark Requires broker version >=2.3.0 + * + * @remark Multiple resources and resource types may be set, but at most one + * resource of type \c RD_KAFKA_RESOURCE_BROKER is allowed per call + * since these resource requests must be sent to the broker specified + * in the resource. Broker option will be ignored in this case. + * + * @param rk Client instance. + * @param configs Array of config entries to alter. + * @param config_cnt Number of elements in \p configs array. + * @param options Optional admin options, or NULL for defaults. + * @param rkqu Queue to emit result on. + */ +RD_EXPORT +void rd_kafka_IncrementalAlterConfigs(rd_kafka_t *rk, + rd_kafka_ConfigResource_t **configs, + size_t config_cnt, + const rd_kafka_AdminOptions_t *options, + rd_kafka_queue_t *rkqu); + + +/* + * IncrementalAlterConfigs result type and methods + */ + +/** + * @brief Get an array of resource results from a IncrementalAlterConfigs + * result. + * + * Use \c rd_kafka_ConfigResource_error() and + * \c rd_kafka_ConfigResource_error_string() to extract per-resource error + * results on the returned array elements. + * + * The returned object life-times are the same as the \p result object. + * + * @param result Result object to get resource results from. + * @param cntp is updated to the number of elements in the array. + * + * @returns an array of ConfigResource elements, or NULL if not available. + */ +RD_EXPORT const rd_kafka_ConfigResource_t ** +rd_kafka_IncrementalAlterConfigs_result_resources( + const rd_kafka_IncrementalAlterConfigs_result_t *result, + size_t *cntp); + + + /* * DescribeConfigs - retrieve cluster configuration. * diff --git a/src/rdkafka_admin.c b/src/rdkafka_admin.c index 35f4f150d8..6c4419b3a2 100644 --- a/src/rdkafka_admin.c +++ b/src/rdkafka_admin.c @@ -529,7 +529,8 @@ rd_kafka_admin_result_ret_resources(const rd_kafka_op_t *rko, size_t *cntp) { rd_kafka_op_type_t reqtype = rko->rko_u.admin_result.reqtype & ~RD_KAFKA_OP_FLAGMASK; rd_assert(reqtype == RD_KAFKA_OP_ALTERCONFIGS || - reqtype == RD_KAFKA_OP_DESCRIBECONFIGS); + reqtype == RD_KAFKA_OP_DESCRIBECONFIGS || + reqtype == RD_KAFKA_OP_INCREMENTALALTERCONFIGS); *cntp = rd_list_cnt(&rko->rko_u.admin_result.results); return (const rd_kafka_ConfigResource_t **) @@ -1523,20 +1524,6 @@ rd_kafka_AdminOptions_set_validate_only(rd_kafka_AdminOptions_t *options, errstr, errstr_size); } -rd_kafka_resp_err_t -rd_kafka_AdminOptions_set_incremental(rd_kafka_AdminOptions_t *options, - int true_or_false, - char *errstr, - size_t errstr_size) { - rd_snprintf(errstr, errstr_size, - "Incremental updates currently not supported, see KIP-248"); - return RD_KAFKA_RESP_ERR__NOT_IMPLEMENTED; - - return rd_kafka_confval_set_type(&options->incremental, - RD_KAFKA_CONFVAL_INT, &true_or_false, - errstr, errstr_size); -} - rd_kafka_resp_err_t rd_kafka_AdminOptions_set_broker(rd_kafka_AdminOptions_t *options, int32_t broker_id, @@ -1636,20 +1623,14 @@ static void rd_kafka_AdminOptions_init(rd_kafka_t *rk, if (options->for_api == RD_KAFKA_ADMIN_OP_ANY || options->for_api == RD_KAFKA_ADMIN_OP_CREATETOPICS || options->for_api == RD_KAFKA_ADMIN_OP_CREATEPARTITIONS || - options->for_api == RD_KAFKA_ADMIN_OP_ALTERCONFIGS) + options->for_api == RD_KAFKA_ADMIN_OP_ALTERCONFIGS || + options->for_api == RD_KAFKA_ADMIN_OP_INCREMENTALALTERCONFIGS) rd_kafka_confval_init_int(&options->validate_only, "validate_only", 0, 1, 0); else rd_kafka_confval_disable(&options->validate_only, "validate_only"); - if (options->for_api == RD_KAFKA_ADMIN_OP_ANY || - options->for_api == RD_KAFKA_ADMIN_OP_ALTERCONFIGS) - rd_kafka_confval_init_int(&options->incremental, "incremental", - 0, 1, 0); - else - rd_kafka_confval_disable(&options->incremental, "incremental"); - if (options->for_api == RD_KAFKA_ADMIN_OP_ANY || options->for_api == RD_KAFKA_ADMIN_OP_LISTCONSUMERGROUPOFFSETS) rd_kafka_confval_init_int(&options->require_stable_offsets, @@ -1884,18 +1865,14 @@ rd_kafka_NewTopic_set_replica_assignment(rd_kafka_NewTopic_t *new_topic, * @brief Generic constructor of ConfigEntry which is also added to \p rl */ static rd_kafka_resp_err_t -rd_kafka_admin_add_config0(rd_list_t *rl, - const char *name, - const char *value, - rd_kafka_AlterOperation_t operation) { +rd_kafka_admin_add_config0(rd_list_t *rl, const char *name, const char *value) { rd_kafka_ConfigEntry_t *entry; if (!name) return RD_KAFKA_RESP_ERR__INVALID_ARG; - entry = rd_calloc(1, sizeof(*entry)); - entry->kv = rd_strtup_new(name, value); - entry->a.operation = operation; + entry = rd_calloc(1, sizeof(*entry)); + entry->kv = rd_strtup_new(name, value); rd_list_add(rl, entry); @@ -1903,11 +1880,36 @@ rd_kafka_admin_add_config0(rd_list_t *rl, } +/** + * @brief Generic constructor of ConfigEntry for Incremental Alter Operations + * which is also added to \p rl + */ +static rd_kafka_error_t * +rd_kafka_admin_incremental_add_config0(rd_list_t *rl, + const char *name, + rd_kafka_AlterConfigOpType_t op_type, + const char *value) { + rd_kafka_ConfigEntry_t *entry; + + if (!name) { + return rd_kafka_error_new(RD_KAFKA_RESP_ERR__INVALID_ARG, + "Config name is required"); + } + + entry = rd_calloc(1, sizeof(*entry)); + entry->kv = rd_strtup_new(name, value); + entry->a.op_type = op_type; + + rd_list_add(rl, entry); + + return NULL; +} + + rd_kafka_resp_err_t rd_kafka_NewTopic_set_config(rd_kafka_NewTopic_t *new_topic, const char *name, const char *value) { - return rd_kafka_admin_add_config0(&new_topic->config, name, value, - RD_KAFKA_ALTER_OP_ADD); + return rd_kafka_admin_add_config0(&new_topic->config, name, value); } @@ -2832,37 +2834,42 @@ rd_kafka_ConfigResource_add_ConfigEntry(rd_kafka_ConfigResource_t *config, rd_list_add(&config->config, entry); } - rd_kafka_resp_err_t -rd_kafka_ConfigResource_add_config(rd_kafka_ConfigResource_t *config, +rd_kafka_ConfigResource_set_config(rd_kafka_ConfigResource_t *config, const char *name, const char *value) { if (!name || !*name || !value) return RD_KAFKA_RESP_ERR__INVALID_ARG; - return rd_kafka_admin_add_config0(&config->config, name, value, - RD_KAFKA_ALTER_OP_ADD); + return rd_kafka_admin_add_config0(&config->config, name, value); } -rd_kafka_resp_err_t -rd_kafka_ConfigResource_set_config(rd_kafka_ConfigResource_t *config, - const char *name, - const char *value) { - if (!name || !*name || !value) - return RD_KAFKA_RESP_ERR__INVALID_ARG; - return rd_kafka_admin_add_config0(&config->config, name, value, - RD_KAFKA_ALTER_OP_SET); -} +rd_kafka_error_t *rd_kafka_ConfigResource_add_incremental_config( + rd_kafka_ConfigResource_t *config, + const char *name, + rd_kafka_AlterConfigOpType_t op_type, + const char *value) { + if (op_type < 0 || op_type >= RD_KAFKA_ALTER_CONFIG_OP_TYPE__CNT) { + return rd_kafka_error_new( + RD_KAFKA_RESP_ERR__INVALID_ARG, + "Invalid alter config operation type"); + } -rd_kafka_resp_err_t -rd_kafka_ConfigResource_delete_config(rd_kafka_ConfigResource_t *config, - const char *name) { - if (!name || !*name) - return RD_KAFKA_RESP_ERR__INVALID_ARG; + if (!name || !*name) { + return rd_kafka_error_new(RD_KAFKA_RESP_ERR__INVALID_ARG, + !name + ? "Config name is required" + : "Config name mustn't be empty"); + } - return rd_kafka_admin_add_config0(&config->config, name, NULL, - RD_KAFKA_ALTER_OP_DELETE); + if (op_type != RD_KAFKA_ALTER_CONFIG_OP_TYPE_DELETE && !value) { + return rd_kafka_error_new(RD_KAFKA_RESP_ERR__INVALID_ARG, + "Config value is required"); + } + + return rd_kafka_admin_incremental_add_config0(&config->config, name, + op_type, value); } @@ -2996,7 +3003,7 @@ rd_kafka_AlterConfigsResponse_parse(rd_kafka_op_t *rko_req, rd_kafka_buf_read_i32(reply, &Throttle_Time); rd_kafka_op_throttle_time(rkb, rk->rk_rep, Throttle_Time); - rd_kafka_buf_read_i32(reply, &res_cnt); + rd_kafka_buf_read_arraycnt(reply, &res_cnt, RD_KAFKAP_CONFIGS_MAX); if (res_cnt > rd_list_cnt(&rko_req->rko_u.admin_request.args)) { rd_snprintf(errstr, errstr_size, @@ -3029,6 +3036,7 @@ rd_kafka_AlterConfigsResponse_parse(rd_kafka_op_t *rko_req, rd_kafka_buf_read_i8(reply, &res_type); rd_kafka_buf_read_str(reply, &kres_name); RD_KAFKAP_STR_DUPA(&res_name, &kres_name); + rd_kafka_buf_skip_tags(reply); if (error_code) { if (RD_KAFKAP_STR_IS_NULL(&error_msg) || @@ -3158,6 +3166,277 @@ const rd_kafka_ConfigResource_t **rd_kafka_AlterConfigs_result_resources( +/** + * @name IncrementalAlterConfigs + * @{ + * + * + * + */ + + + +/** + * @brief Parse IncrementalAlterConfigsResponse and create ADMIN_RESULT op. + */ +static rd_kafka_resp_err_t +rd_kafka_IncrementalAlterConfigsResponse_parse(rd_kafka_op_t *rko_req, + rd_kafka_op_t **rko_resultp, + rd_kafka_buf_t *reply, + char *errstr, + size_t errstr_size) { + const int log_decode_errors = LOG_ERR; + rd_kafka_broker_t *rkb = reply->rkbuf_rkb; + rd_kafka_t *rk = rkb->rkb_rk; + rd_kafka_op_t *rko_result = NULL; + int32_t res_cnt; + int i; + int32_t Throttle_Time; + + rd_kafka_buf_read_i32(reply, &Throttle_Time); + rd_kafka_op_throttle_time(rkb, rk->rk_rep, Throttle_Time); + + rd_kafka_buf_read_arraycnt(reply, &res_cnt, RD_KAFKAP_CONFIGS_MAX); + + if (res_cnt != rd_list_cnt(&rko_req->rko_u.admin_request.args)) { + rd_snprintf(errstr, errstr_size, + "Received %" PRId32 + " ConfigResources in response " + "when %d were requested", + res_cnt, + rd_list_cnt(&rko_req->rko_u.admin_request.args)); + return RD_KAFKA_RESP_ERR__BAD_MSG; + } + + rko_result = rd_kafka_admin_result_new(rko_req); + + rd_list_init(&rko_result->rko_u.admin_result.results, res_cnt, + rd_kafka_ConfigResource_free); + + for (i = 0; i < (int)res_cnt; i++) { + int16_t error_code; + rd_kafkap_str_t error_msg; + int8_t res_type; + rd_kafkap_str_t kres_name; + char *res_name; + char *this_errstr = NULL; + rd_kafka_ConfigResource_t *config; + rd_kafka_ConfigResource_t skel; + int orig_pos; + + rd_kafka_buf_read_i16(reply, &error_code); + rd_kafka_buf_read_str(reply, &error_msg); + rd_kafka_buf_read_i8(reply, &res_type); + rd_kafka_buf_read_str(reply, &kres_name); + RD_KAFKAP_STR_DUPA(&res_name, &kres_name); + rd_kafka_buf_skip_tags(reply); + + if (error_code) { + if (RD_KAFKAP_STR_IS_NULL(&error_msg) || + RD_KAFKAP_STR_LEN(&error_msg) == 0) + this_errstr = + (char *)rd_kafka_err2str(error_code); + else + RD_KAFKAP_STR_DUPA(&this_errstr, &error_msg); + } + + config = rd_kafka_ConfigResource_new(res_type, res_name); + if (!config) { + rd_kafka_log(rko_req->rko_rk, LOG_ERR, "ADMIN", + "IncrementalAlterConfigs returned " + "unsupported ConfigResource #%d with " + "type %d and name \"%s\": ignoring", + i, res_type, res_name); + continue; + } + + config->err = error_code; + if (this_errstr) + config->errstr = rd_strdup(this_errstr); + + /* As a convenience to the application we insert result + * in the same order as they were requested. The broker + * does not maintain ordering unfortunately. */ + skel.restype = config->restype; + skel.name = config->name; + orig_pos = rd_list_index(&rko_result->rko_u.admin_result.args, + &skel, rd_kafka_ConfigResource_cmp); + if (orig_pos == -1) { + rd_kafka_ConfigResource_destroy(config); + rd_kafka_buf_parse_fail( + reply, + "Broker returned ConfigResource %d,%s " + "that was not " + "included in the original request", + res_type, res_name); + } + + if (rd_list_elem(&rko_result->rko_u.admin_result.results, + orig_pos) != NULL) { + rd_kafka_ConfigResource_destroy(config); + rd_kafka_buf_parse_fail( + reply, + "Broker returned ConfigResource %d,%s " + "multiple times", + res_type, res_name); + } + + rd_list_set(&rko_result->rko_u.admin_result.results, orig_pos, + config); + } + + *rko_resultp = rko_result; + + return RD_KAFKA_RESP_ERR_NO_ERROR; + +err_parse: + if (rko_result) + rd_kafka_op_destroy(rko_result); + + rd_snprintf( + errstr, errstr_size, + "IncrementalAlterConfigs response protocol parse failure: %s", + rd_kafka_err2str(reply->rkbuf_err)); + + return reply->rkbuf_err; +} + +typedef RD_MAP_TYPE(const char *, const rd_bool_t *) map_str_bool; + + +void rd_kafka_IncrementalAlterConfigs(rd_kafka_t *rk, + rd_kafka_ConfigResource_t **configs, + size_t config_cnt, + const rd_kafka_AdminOptions_t *options, + rd_kafka_queue_t *rkqu) { + rd_kafka_op_t *rko; + size_t i; + rd_kafka_resp_err_t err; + char errstr[256]; + rd_bool_t value = rd_true; + + static const struct rd_kafka_admin_worker_cbs cbs = { + rd_kafka_IncrementalAlterConfigsRequest, + rd_kafka_IncrementalAlterConfigsResponse_parse, + }; + + rd_assert(rkqu); + + rko = rd_kafka_admin_request_op_new( + rk, RD_KAFKA_OP_INCREMENTALALTERCONFIGS, + RD_KAFKA_EVENT_INCREMENTALALTERCONFIGS_RESULT, &cbs, options, + rkqu->rkqu_q); + + rd_list_init(&rko->rko_u.admin_request.args, (int)config_cnt, + rd_kafka_ConfigResource_free); + + /* Check duplicate ConfigResource */ + map_str_bool configs_map = RD_MAP_INITIALIZER( + config_cnt, rd_map_str_cmp, rd_map_str_hash, NULL, NULL); + + for (i = 0; i < config_cnt; i++) { + /* 2 chars for the decimal restype + 1 for the comma + * + 1 for the trailing zero. */ + size_t len = 4 + strlen(configs[i]->name); + char *key = rd_alloca(len); + const rd_kafka_ConfigEntry_t **entries; + size_t entry_cnt, j; + + rd_snprintf(key, len - 1, "%d,%s", configs[i]->restype, + configs[i]->name); + if (RD_MAP_GET(&configs_map, key)) { + /* Duplicate ConfigResource found */ + break; + } + RD_MAP_SET(&configs_map, key, &value); + entries = + rd_kafka_ConfigResource_configs(configs[i], &entry_cnt); + + /* Check duplicate ConfigEntry */ + map_str_bool entries_map = RD_MAP_INITIALIZER( + entry_cnt, rd_map_str_cmp, rd_map_str_hash, NULL, NULL); + + for (j = 0; j < entry_cnt; j++) { + const rd_kafka_ConfigEntry_t *entry = entries[j]; + const char *key = rd_kafka_ConfigEntry_name(entry); + + if (RD_MAP_GET(&entries_map, key)) { + /* Duplicate ConfigEntry found */ + break; + } + RD_MAP_SET(&entries_map, key, &value); + } + RD_MAP_DESTROY(&entries_map); + + if (j != entry_cnt) { + RD_MAP_DESTROY(&configs_map); + rd_kafka_admin_result_fail( + rko, RD_KAFKA_RESP_ERR__INVALID_ARG, + "Duplicate ConfigEntry found"); + rd_kafka_admin_common_worker_destroy( + rk, rko, rd_true /*destroy*/); + return; + } + + rd_list_add(&rko->rko_u.admin_request.args, + rd_kafka_ConfigResource_copy(configs[i])); + } + + RD_MAP_DESTROY(&configs_map); + + if (i != config_cnt) { + rd_kafka_admin_result_fail(rko, RD_KAFKA_RESP_ERR__INVALID_ARG, + "Duplicate ConfigResource found"); + rd_kafka_admin_common_worker_destroy(rk, rko, + rd_true /*destroy*/); + return; + } + + /* If there's a BROKER resource in the list we need to + * speak directly to that broker rather than the controller. + * + * Multiple BROKER resources are not allowed. + */ + err = rd_kafka_ConfigResource_get_single_broker_id( + &rko->rko_u.admin_request.args, &rko->rko_u.admin_request.broker_id, + errstr, sizeof(errstr)); + if (err) { + rd_kafka_admin_result_fail(rko, err, "%s", errstr); + rd_kafka_admin_common_worker_destroy(rk, rko, + rd_true /*destroy*/); + return; + } + if (rko->rko_u.admin_request.broker_id != + RD_KAFKA_ADMIN_TARGET_CONTROLLER) { + /* Revert broker option to default if altering + * broker configs. */ + err = rd_kafka_confval_set_type( + &rko->rko_u.admin_request.options.broker, + RD_KAFKA_CONFVAL_INT, NULL, errstr, sizeof(errstr)); + if (err) { + rd_kafka_admin_result_fail(rko, err, "%s", errstr); + rd_kafka_admin_common_worker_destroy( + rk, rko, rd_true /*destroy*/); + return; + } + } + + rd_kafka_q_enq(rk->rk_ops, rko); +} + + +const rd_kafka_ConfigResource_t ** +rd_kafka_IncrementalAlterConfigs_result_resources( + const rd_kafka_IncrementalAlterConfigs_result_t *result, + size_t *cntp) { + return rd_kafka_admin_result_ret_resources( + (const rd_kafka_op_t *)result, cntp); +} + +/**@}*/ + + + /** * @name DescribeConfigs * @{ diff --git a/src/rdkafka_admin.h b/src/rdkafka_admin.h index 3935c00c04..380f49dd0c 100644 --- a/src/rdkafka_admin.h +++ b/src/rdkafka_admin.h @@ -31,6 +31,7 @@ #include "rdstring.h" +#include "rdmap.h" #include "rdkafka_error.h" #include "rdkafka_confval.h" @@ -69,15 +70,9 @@ struct rd_kafka_AdminOptions_s { * CreateTopics * CreatePartitions * AlterConfigs + * IncrementalAlterConfigs */ - rd_kafka_confval_t incremental; /**< BOOL: Incremental rather than - * absolute application - * of config. - * Valid for: - * AlterConfigs - */ - rd_kafka_confval_t broker; /**< INT: Explicitly override * broker id to send * requests to. @@ -188,13 +183,6 @@ struct rd_kafka_NewPartitions_s { * @{ */ -/* KIP-248 */ -typedef enum rd_kafka_AlterOperation_t { - RD_KAFKA_ALTER_OP_ADD = 0, - RD_KAFKA_ALTER_OP_SET = 1, - RD_KAFKA_ALTER_OP_DELETE = 2, -} rd_kafka_AlterOperation_t; - struct rd_kafka_ConfigEntry_s { rd_strtup_t *kv; /**< Name/Value pair */ @@ -202,8 +190,9 @@ struct rd_kafka_ConfigEntry_s { /* Attributes: this is a struct for easy copying */ struct { - rd_kafka_AlterOperation_t operation; /**< Operation */ - rd_kafka_ConfigSource_t source; /**< Config source */ + /** Operation type, used for IncrementalAlterConfigs */ + rd_kafka_AlterConfigOpType_t op_type; + rd_kafka_ConfigSource_t source; /**< Config source */ rd_bool_t is_readonly; /**< Value is read-only (on broker) */ rd_bool_t is_default; /**< Value is at its default */ rd_bool_t is_sensitive; /**< Value is sensitive */ @@ -250,6 +239,10 @@ struct rd_kafka_AlterConfigs_result_s { rd_list_t resources; /**< Type (rd_kafka_ConfigResource_t *) */ }; +struct rd_kafka_IncrementalAlterConfigs_result_s { + rd_list_t resources; /**< Type (rd_kafka_ConfigResource_t *) */ +}; + struct rd_kafka_ConfigResource_result_s { rd_list_t resources; /**< Type (struct rd_kafka_ConfigResource *): * List of config resources, sans config diff --git a/src/rdkafka_event.c b/src/rdkafka_event.c index 58b0dc37b2..b2a6843ca2 100644 --- a/src/rdkafka_event.c +++ b/src/rdkafka_event.c @@ -60,6 +60,8 @@ const char *rd_kafka_event_name(const rd_kafka_event_t *rkev) { return "CreatePartitionsResult"; case RD_KAFKA_EVENT_ALTERCONFIGS_RESULT: return "AlterConfigsResult"; + case RD_KAFKA_EVENT_INCREMENTALALTERCONFIGS_RESULT: + return "IncrementalAlterConfigsResult"; case RD_KAFKA_EVENT_DESCRIBECONFIGS_RESULT: return "DescribeConfigsResult"; case RD_KAFKA_EVENT_DELETERECORDS_RESULT: @@ -329,6 +331,15 @@ rd_kafka_event_AlterConfigs_result(rd_kafka_event_t *rkev) { return (const rd_kafka_AlterConfigs_result_t *)rkev; } +const rd_kafka_IncrementalAlterConfigs_result_t * +rd_kafka_event_IncrementalAlterConfigs_result(rd_kafka_event_t *rkev) { + if (!rkev || + rkev->rko_evtype != RD_KAFKA_EVENT_INCREMENTALALTERCONFIGS_RESULT) + return NULL; + else + return (const rd_kafka_IncrementalAlterConfigs_result_t *)rkev; +} + const rd_kafka_DescribeConfigs_result_t * rd_kafka_event_DescribeConfigs_result(rd_kafka_event_t *rkev) { diff --git a/src/rdkafka_event.h b/src/rdkafka_event.h index e5447f1467..52c2d191a2 100644 --- a/src/rdkafka_event.h +++ b/src/rdkafka_event.h @@ -98,6 +98,7 @@ static RD_UNUSED RD_INLINE int rd_kafka_event_setup(rd_kafka_t *rk, case RD_KAFKA_EVENT_DELETETOPICS_RESULT: case RD_KAFKA_EVENT_CREATEPARTITIONS_RESULT: case RD_KAFKA_EVENT_ALTERCONFIGS_RESULT: + case RD_KAFKA_EVENT_INCREMENTALALTERCONFIGS_RESULT: case RD_KAFKA_EVENT_DESCRIBECONFIGS_RESULT: case RD_KAFKA_EVENT_DELETERECORDS_RESULT: case RD_KAFKA_EVENT_LISTCONSUMERGROUPS_RESULT: diff --git a/src/rdkafka_int.h b/src/rdkafka_int.h index f3554963ad..8a29c1f623 100644 --- a/src/rdkafka_int.h +++ b/src/rdkafka_int.h @@ -131,6 +131,7 @@ typedef struct rd_kafka_fetch_pos_s { #define RD_KAFKAP_TOPICS_MAX 1000000 #define RD_KAFKAP_PARTITIONS_MAX 100000 #define RD_KAFKAP_GROUPS_MAX 100000 +#define RD_KAFKAP_CONFIGS_MAX 10000 #define RD_KAFKA_OFFSET_IS_LOGICAL(OFF) ((OFF) < 0) diff --git a/src/rdkafka_op.c b/src/rdkafka_op.c index a3ea9a39a6..32cf4b3623 100644 --- a/src/rdkafka_op.c +++ b/src/rdkafka_op.c @@ -44,42 +44,44 @@ rd_atomic32_t rd_kafka_op_cnt; const char *rd_kafka_op2str(rd_kafka_op_type_t type) { int skiplen = 6; static const char *names[RD_KAFKA_OP__END] = { - [RD_KAFKA_OP_NONE] = "REPLY:NONE", - [RD_KAFKA_OP_FETCH] = "REPLY:FETCH", - [RD_KAFKA_OP_ERR] = "REPLY:ERR", - [RD_KAFKA_OP_CONSUMER_ERR] = "REPLY:CONSUMER_ERR", - [RD_KAFKA_OP_DR] = "REPLY:DR", - [RD_KAFKA_OP_STATS] = "REPLY:STATS", - [RD_KAFKA_OP_OFFSET_COMMIT] = "REPLY:OFFSET_COMMIT", - [RD_KAFKA_OP_NODE_UPDATE] = "REPLY:NODE_UPDATE", - [RD_KAFKA_OP_XMIT_BUF] = "REPLY:XMIT_BUF", - [RD_KAFKA_OP_RECV_BUF] = "REPLY:RECV_BUF", - [RD_KAFKA_OP_XMIT_RETRY] = "REPLY:XMIT_RETRY", - [RD_KAFKA_OP_FETCH_START] = "REPLY:FETCH_START", - [RD_KAFKA_OP_FETCH_STOP] = "REPLY:FETCH_STOP", - [RD_KAFKA_OP_SEEK] = "REPLY:SEEK", - [RD_KAFKA_OP_PAUSE] = "REPLY:PAUSE", - [RD_KAFKA_OP_OFFSET_FETCH] = "REPLY:OFFSET_FETCH", - [RD_KAFKA_OP_PARTITION_JOIN] = "REPLY:PARTITION_JOIN", - [RD_KAFKA_OP_PARTITION_LEAVE] = "REPLY:PARTITION_LEAVE", - [RD_KAFKA_OP_REBALANCE] = "REPLY:REBALANCE", - [RD_KAFKA_OP_TERMINATE] = "REPLY:TERMINATE", - [RD_KAFKA_OP_COORD_QUERY] = "REPLY:COORD_QUERY", - [RD_KAFKA_OP_SUBSCRIBE] = "REPLY:SUBSCRIBE", - [RD_KAFKA_OP_ASSIGN] = "REPLY:ASSIGN", - [RD_KAFKA_OP_GET_SUBSCRIPTION] = "REPLY:GET_SUBSCRIPTION", - [RD_KAFKA_OP_GET_ASSIGNMENT] = "REPLY:GET_ASSIGNMENT", - [RD_KAFKA_OP_THROTTLE] = "REPLY:THROTTLE", - [RD_KAFKA_OP_NAME] = "REPLY:NAME", - [RD_KAFKA_OP_CG_METADATA] = "REPLY:CG_METADATA", - [RD_KAFKA_OP_OFFSET_RESET] = "REPLY:OFFSET_RESET", - [RD_KAFKA_OP_METADATA] = "REPLY:METADATA", - [RD_KAFKA_OP_LOG] = "REPLY:LOG", - [RD_KAFKA_OP_WAKEUP] = "REPLY:WAKEUP", - [RD_KAFKA_OP_CREATETOPICS] = "REPLY:CREATETOPICS", - [RD_KAFKA_OP_DELETETOPICS] = "REPLY:DELETETOPICS", - [RD_KAFKA_OP_CREATEPARTITIONS] = "REPLY:CREATEPARTITIONS", - [RD_KAFKA_OP_ALTERCONFIGS] = "REPLY:ALTERCONFIGS", + [RD_KAFKA_OP_NONE] = "REPLY:NONE", + [RD_KAFKA_OP_FETCH] = "REPLY:FETCH", + [RD_KAFKA_OP_ERR] = "REPLY:ERR", + [RD_KAFKA_OP_CONSUMER_ERR] = "REPLY:CONSUMER_ERR", + [RD_KAFKA_OP_DR] = "REPLY:DR", + [RD_KAFKA_OP_STATS] = "REPLY:STATS", + [RD_KAFKA_OP_OFFSET_COMMIT] = "REPLY:OFFSET_COMMIT", + [RD_KAFKA_OP_NODE_UPDATE] = "REPLY:NODE_UPDATE", + [RD_KAFKA_OP_XMIT_BUF] = "REPLY:XMIT_BUF", + [RD_KAFKA_OP_RECV_BUF] = "REPLY:RECV_BUF", + [RD_KAFKA_OP_XMIT_RETRY] = "REPLY:XMIT_RETRY", + [RD_KAFKA_OP_FETCH_START] = "REPLY:FETCH_START", + [RD_KAFKA_OP_FETCH_STOP] = "REPLY:FETCH_STOP", + [RD_KAFKA_OP_SEEK] = "REPLY:SEEK", + [RD_KAFKA_OP_PAUSE] = "REPLY:PAUSE", + [RD_KAFKA_OP_OFFSET_FETCH] = "REPLY:OFFSET_FETCH", + [RD_KAFKA_OP_PARTITION_JOIN] = "REPLY:PARTITION_JOIN", + [RD_KAFKA_OP_PARTITION_LEAVE] = "REPLY:PARTITION_LEAVE", + [RD_KAFKA_OP_REBALANCE] = "REPLY:REBALANCE", + [RD_KAFKA_OP_TERMINATE] = "REPLY:TERMINATE", + [RD_KAFKA_OP_COORD_QUERY] = "REPLY:COORD_QUERY", + [RD_KAFKA_OP_SUBSCRIBE] = "REPLY:SUBSCRIBE", + [RD_KAFKA_OP_ASSIGN] = "REPLY:ASSIGN", + [RD_KAFKA_OP_GET_SUBSCRIPTION] = "REPLY:GET_SUBSCRIPTION", + [RD_KAFKA_OP_GET_ASSIGNMENT] = "REPLY:GET_ASSIGNMENT", + [RD_KAFKA_OP_THROTTLE] = "REPLY:THROTTLE", + [RD_KAFKA_OP_NAME] = "REPLY:NAME", + [RD_KAFKA_OP_CG_METADATA] = "REPLY:CG_METADATA", + [RD_KAFKA_OP_OFFSET_RESET] = "REPLY:OFFSET_RESET", + [RD_KAFKA_OP_METADATA] = "REPLY:METADATA", + [RD_KAFKA_OP_LOG] = "REPLY:LOG", + [RD_KAFKA_OP_WAKEUP] = "REPLY:WAKEUP", + [RD_KAFKA_OP_CREATETOPICS] = "REPLY:CREATETOPICS", + [RD_KAFKA_OP_DELETETOPICS] = "REPLY:DELETETOPICS", + [RD_KAFKA_OP_CREATEPARTITIONS] = "REPLY:CREATEPARTITIONS", + [RD_KAFKA_OP_ALTERCONFIGS] = "REPLY:ALTERCONFIGS", + [RD_KAFKA_OP_INCREMENTALALTERCONFIGS] = + "REPLY:INCREMENTALALTERCONFIGS", [RD_KAFKA_OP_DESCRIBECONFIGS] = "REPLY:DESCRIBECONFIGS", [RD_KAFKA_OP_DELETERECORDS] = "REPLY:DELETERECORDS", [RD_KAFKA_OP_LISTCONSUMERGROUPS] = "REPLY:LISTCONSUMERGROUPS", @@ -195,41 +197,43 @@ rd_kafka_op_t *rd_kafka_op_new0(const char *source, rd_kafka_op_type_t type) { * if we forgot to add an op type to \ * this list. */ static const size_t op2size[RD_KAFKA_OP__END] = { - [RD_KAFKA_OP_FETCH] = sizeof(rko->rko_u.fetch), - [RD_KAFKA_OP_ERR] = sizeof(rko->rko_u.err), - [RD_KAFKA_OP_CONSUMER_ERR] = sizeof(rko->rko_u.err), - [RD_KAFKA_OP_DR] = sizeof(rko->rko_u.dr), - [RD_KAFKA_OP_STATS] = sizeof(rko->rko_u.stats), - [RD_KAFKA_OP_OFFSET_COMMIT] = sizeof(rko->rko_u.offset_commit), - [RD_KAFKA_OP_NODE_UPDATE] = sizeof(rko->rko_u.node), - [RD_KAFKA_OP_XMIT_BUF] = sizeof(rko->rko_u.xbuf), - [RD_KAFKA_OP_RECV_BUF] = sizeof(rko->rko_u.xbuf), - [RD_KAFKA_OP_XMIT_RETRY] = sizeof(rko->rko_u.xbuf), - [RD_KAFKA_OP_FETCH_START] = sizeof(rko->rko_u.fetch_start), - [RD_KAFKA_OP_FETCH_STOP] = _RD_KAFKA_OP_EMPTY, - [RD_KAFKA_OP_SEEK] = sizeof(rko->rko_u.fetch_start), - [RD_KAFKA_OP_PAUSE] = sizeof(rko->rko_u.pause), - [RD_KAFKA_OP_OFFSET_FETCH] = sizeof(rko->rko_u.offset_fetch), - [RD_KAFKA_OP_PARTITION_JOIN] = _RD_KAFKA_OP_EMPTY, - [RD_KAFKA_OP_PARTITION_LEAVE] = _RD_KAFKA_OP_EMPTY, - [RD_KAFKA_OP_REBALANCE] = sizeof(rko->rko_u.rebalance), - [RD_KAFKA_OP_TERMINATE] = _RD_KAFKA_OP_EMPTY, - [RD_KAFKA_OP_COORD_QUERY] = _RD_KAFKA_OP_EMPTY, - [RD_KAFKA_OP_SUBSCRIBE] = sizeof(rko->rko_u.subscribe), - [RD_KAFKA_OP_ASSIGN] = sizeof(rko->rko_u.assign), - [RD_KAFKA_OP_GET_SUBSCRIPTION] = sizeof(rko->rko_u.subscribe), - [RD_KAFKA_OP_GET_ASSIGNMENT] = sizeof(rko->rko_u.assign), - [RD_KAFKA_OP_THROTTLE] = sizeof(rko->rko_u.throttle), - [RD_KAFKA_OP_NAME] = sizeof(rko->rko_u.name), - [RD_KAFKA_OP_CG_METADATA] = sizeof(rko->rko_u.cg_metadata), - [RD_KAFKA_OP_OFFSET_RESET] = sizeof(rko->rko_u.offset_reset), - [RD_KAFKA_OP_METADATA] = sizeof(rko->rko_u.metadata), - [RD_KAFKA_OP_LOG] = sizeof(rko->rko_u.log), - [RD_KAFKA_OP_WAKEUP] = _RD_KAFKA_OP_EMPTY, - [RD_KAFKA_OP_CREATETOPICS] = sizeof(rko->rko_u.admin_request), - [RD_KAFKA_OP_DELETETOPICS] = sizeof(rko->rko_u.admin_request), - [RD_KAFKA_OP_CREATEPARTITIONS] = sizeof(rko->rko_u.admin_request), - [RD_KAFKA_OP_ALTERCONFIGS] = sizeof(rko->rko_u.admin_request), + [RD_KAFKA_OP_FETCH] = sizeof(rko->rko_u.fetch), + [RD_KAFKA_OP_ERR] = sizeof(rko->rko_u.err), + [RD_KAFKA_OP_CONSUMER_ERR] = sizeof(rko->rko_u.err), + [RD_KAFKA_OP_DR] = sizeof(rko->rko_u.dr), + [RD_KAFKA_OP_STATS] = sizeof(rko->rko_u.stats), + [RD_KAFKA_OP_OFFSET_COMMIT] = sizeof(rko->rko_u.offset_commit), + [RD_KAFKA_OP_NODE_UPDATE] = sizeof(rko->rko_u.node), + [RD_KAFKA_OP_XMIT_BUF] = sizeof(rko->rko_u.xbuf), + [RD_KAFKA_OP_RECV_BUF] = sizeof(rko->rko_u.xbuf), + [RD_KAFKA_OP_XMIT_RETRY] = sizeof(rko->rko_u.xbuf), + [RD_KAFKA_OP_FETCH_START] = sizeof(rko->rko_u.fetch_start), + [RD_KAFKA_OP_FETCH_STOP] = _RD_KAFKA_OP_EMPTY, + [RD_KAFKA_OP_SEEK] = sizeof(rko->rko_u.fetch_start), + [RD_KAFKA_OP_PAUSE] = sizeof(rko->rko_u.pause), + [RD_KAFKA_OP_OFFSET_FETCH] = sizeof(rko->rko_u.offset_fetch), + [RD_KAFKA_OP_PARTITION_JOIN] = _RD_KAFKA_OP_EMPTY, + [RD_KAFKA_OP_PARTITION_LEAVE] = _RD_KAFKA_OP_EMPTY, + [RD_KAFKA_OP_REBALANCE] = sizeof(rko->rko_u.rebalance), + [RD_KAFKA_OP_TERMINATE] = _RD_KAFKA_OP_EMPTY, + [RD_KAFKA_OP_COORD_QUERY] = _RD_KAFKA_OP_EMPTY, + [RD_KAFKA_OP_SUBSCRIBE] = sizeof(rko->rko_u.subscribe), + [RD_KAFKA_OP_ASSIGN] = sizeof(rko->rko_u.assign), + [RD_KAFKA_OP_GET_SUBSCRIPTION] = sizeof(rko->rko_u.subscribe), + [RD_KAFKA_OP_GET_ASSIGNMENT] = sizeof(rko->rko_u.assign), + [RD_KAFKA_OP_THROTTLE] = sizeof(rko->rko_u.throttle), + [RD_KAFKA_OP_NAME] = sizeof(rko->rko_u.name), + [RD_KAFKA_OP_CG_METADATA] = sizeof(rko->rko_u.cg_metadata), + [RD_KAFKA_OP_OFFSET_RESET] = sizeof(rko->rko_u.offset_reset), + [RD_KAFKA_OP_METADATA] = sizeof(rko->rko_u.metadata), + [RD_KAFKA_OP_LOG] = sizeof(rko->rko_u.log), + [RD_KAFKA_OP_WAKEUP] = _RD_KAFKA_OP_EMPTY, + [RD_KAFKA_OP_CREATETOPICS] = sizeof(rko->rko_u.admin_request), + [RD_KAFKA_OP_DELETETOPICS] = sizeof(rko->rko_u.admin_request), + [RD_KAFKA_OP_CREATEPARTITIONS] = sizeof(rko->rko_u.admin_request), + [RD_KAFKA_OP_ALTERCONFIGS] = sizeof(rko->rko_u.admin_request), + [RD_KAFKA_OP_INCREMENTALALTERCONFIGS] = + sizeof(rko->rko_u.admin_request), [RD_KAFKA_OP_DESCRIBECONFIGS] = sizeof(rko->rko_u.admin_request), [RD_KAFKA_OP_DELETERECORDS] = sizeof(rko->rko_u.admin_request), [RD_KAFKA_OP_LISTCONSUMERGROUPS] = sizeof(rko->rko_u.admin_request), @@ -392,6 +396,7 @@ void rd_kafka_op_destroy(rd_kafka_op_t *rko) { case RD_KAFKA_OP_DELETETOPICS: case RD_KAFKA_OP_CREATEPARTITIONS: case RD_KAFKA_OP_ALTERCONFIGS: + case RD_KAFKA_OP_INCREMENTALALTERCONFIGS: case RD_KAFKA_OP_DESCRIBECONFIGS: case RD_KAFKA_OP_DELETERECORDS: case RD_KAFKA_OP_LISTCONSUMERGROUPS: diff --git a/src/rdkafka_op.h b/src/rdkafka_op.h index f3df1df806..f9ccec2373 100644 --- a/src/rdkafka_op.h +++ b/src/rdkafka_op.h @@ -127,17 +127,20 @@ typedef enum { RD_KAFKA_OP_DELETETOPICS, /**< Admin: DeleteTopics: u.admin_request*/ RD_KAFKA_OP_CREATEPARTITIONS, /**< Admin: CreatePartitions: * u.admin_request*/ - RD_KAFKA_OP_ALTERCONFIGS, /**< Admin: AlterConfigs: u.admin_request*/ - RD_KAFKA_OP_DESCRIBECONFIGS, /**< Admin: DescribeConfigs: - * u.admin_request*/ - RD_KAFKA_OP_DELETERECORDS, /**< Admin: DeleteRecords: - * u.admin_request*/ - RD_KAFKA_OP_LISTCONSUMERGROUPS, /**< Admin: - * ListConsumerGroups - * u.admin_request */ - RD_KAFKA_OP_DESCRIBECONSUMERGROUPS, /**< Admin: - * DescribeConsumerGroups - * u.admin_request */ + RD_KAFKA_OP_ALTERCONFIGS, /**< Admin: AlterConfigs: u.admin_request*/ + RD_KAFKA_OP_INCREMENTALALTERCONFIGS, /**< Admin: + * IncrementalAlterConfigs: + * u.admin_request */ + RD_KAFKA_OP_DESCRIBECONFIGS, /**< Admin: DescribeConfigs: + * u.admin_request*/ + RD_KAFKA_OP_DELETERECORDS, /**< Admin: DeleteRecords: + * u.admin_request*/ + RD_KAFKA_OP_LISTCONSUMERGROUPS, /**< Admin: + * ListConsumerGroups + * u.admin_request */ + RD_KAFKA_OP_DESCRIBECONSUMERGROUPS, /**< Admin: + * DescribeConsumerGroups + * u.admin_request */ RD_KAFKA_OP_DELETEGROUPS, /**< Admin: DeleteGroups: u.admin_request*/ RD_KAFKA_OP_DELETECONSUMERGROUPOFFSETS, /**< Admin: * DeleteConsumerGroupOffsets @@ -521,6 +524,7 @@ struct rd_kafka_op_s { * * (rd_kafka_ConfigResource_t *): * AlterConfigs, DescribeConfigs + * IncrementalAlterConfigs */ void *opaque; /**< Application's opaque as set by diff --git a/src/rdkafka_request.c b/src/rdkafka_request.c index 3b6f75b997..a2b6656de1 100644 --- a/src/rdkafka_request.c +++ b/src/rdkafka_request.c @@ -4214,7 +4214,7 @@ rd_kafka_AlterConfigsRequest(rd_kafka_broker_t *rkb, } ApiVersion = rd_kafka_broker_ApiVersion_supported( - rkb, RD_KAFKAP_AlterConfigs, 0, 1, NULL); + rkb, RD_KAFKAP_AlterConfigs, 0, 2, NULL); if (ApiVersion == -1) { rd_snprintf(errstr, errstr_size, "AlterConfigs (KIP-133) not supported " @@ -4223,52 +4223,121 @@ rd_kafka_AlterConfigsRequest(rd_kafka_broker_t *rkb, return RD_KAFKA_RESP_ERR__UNSUPPORTED_FEATURE; } - /* Incremental requires IncrementalAlterConfigs */ - if (rd_kafka_confval_get_int(&options->incremental)) { + rkbuf = rd_kafka_buf_new_flexver_request(rkb, RD_KAFKAP_AlterConfigs, 1, + rd_list_cnt(configs) * 200, + ApiVersion >= 2); + + /* #Resources */ + rd_kafka_buf_write_arraycnt(rkbuf, rd_list_cnt(configs)); + + RD_LIST_FOREACH(config, configs, i) { + const rd_kafka_ConfigEntry_t *entry; + int ei; + + /* ResourceType */ + rd_kafka_buf_write_i8(rkbuf, config->restype); + + /* ResourceName */ + rd_kafka_buf_write_str(rkbuf, config->name, -1); + + /* #Configs */ + rd_kafka_buf_write_arraycnt(rkbuf, + rd_list_cnt(&config->config)); + + RD_LIST_FOREACH(entry, &config->config, ei) { + /* Name */ + rd_kafka_buf_write_str(rkbuf, entry->kv->name, -1); + /* Value (nullable) */ + rd_kafka_buf_write_str(rkbuf, entry->kv->value, -1); + + rd_kafka_buf_write_tags(rkbuf); + } + + rd_kafka_buf_write_tags(rkbuf); + } + + /* timeout */ + op_timeout = rd_kafka_confval_get_int(&options->operation_timeout); + if (op_timeout > rkb->rkb_rk->rk_conf.socket_timeout_ms) + rd_kafka_buf_set_abs_timeout(rkbuf, op_timeout + 1000, 0); + + /* validate_only */ + rd_kafka_buf_write_i8( + rkbuf, rd_kafka_confval_get_int(&options->validate_only)); + + rd_kafka_buf_ApiVersion_set(rkbuf, ApiVersion, 0); + + rd_kafka_broker_buf_enq_replyq(rkb, rkbuf, replyq, resp_cb, opaque); + + return RD_KAFKA_RESP_ERR_NO_ERROR; +} + + +rd_kafka_resp_err_t rd_kafka_IncrementalAlterConfigsRequest( + rd_kafka_broker_t *rkb, + const rd_list_t *configs /*(ConfigResource_t*)*/, + rd_kafka_AdminOptions_t *options, + char *errstr, + size_t errstr_size, + rd_kafka_replyq_t replyq, + rd_kafka_resp_cb_t *resp_cb, + void *opaque) { + rd_kafka_buf_t *rkbuf; + int16_t ApiVersion = 0; + int i; + const rd_kafka_ConfigResource_t *config; + int op_timeout; + + if (rd_list_cnt(configs) == 0) { + rd_snprintf(errstr, errstr_size, + "No config resources specified"); + rd_kafka_replyq_destroy(&replyq); + return RD_KAFKA_RESP_ERR__INVALID_ARG; + } + + ApiVersion = rd_kafka_broker_ApiVersion_supported( + rkb, RD_KAFKAP_IncrementalAlterConfigs, 0, 1, NULL); + if (ApiVersion == -1) { rd_snprintf(errstr, errstr_size, - "AlterConfigs.incremental=true (KIP-248) " - "not supported by broker, " - "replaced by IncrementalAlterConfigs"); + "IncrementalAlterConfigs (KIP-339) not supported " + "by broker, requires broker version >= 2.3.0"); rd_kafka_replyq_destroy(&replyq); return RD_KAFKA_RESP_ERR__UNSUPPORTED_FEATURE; } - rkbuf = rd_kafka_buf_new_request(rkb, RD_KAFKAP_AlterConfigs, 1, - rd_list_cnt(configs) * 200); + rkbuf = rd_kafka_buf_new_flexver_request( + rkb, RD_KAFKAP_IncrementalAlterConfigs, 1, + rd_list_cnt(configs) * 200, ApiVersion >= 1); - /* #resources */ - rd_kafka_buf_write_i32(rkbuf, rd_list_cnt(configs)); + /* #Resources */ + rd_kafka_buf_write_arraycnt(rkbuf, rd_list_cnt(configs)); RD_LIST_FOREACH(config, configs, i) { const rd_kafka_ConfigEntry_t *entry; int ei; - /* resource_type */ + /* ResourceType */ rd_kafka_buf_write_i8(rkbuf, config->restype); - /* resource_name */ + /* ResourceName */ rd_kafka_buf_write_str(rkbuf, config->name, -1); - /* #config */ - rd_kafka_buf_write_i32(rkbuf, rd_list_cnt(&config->config)); + /* #Configs */ + rd_kafka_buf_write_arraycnt(rkbuf, + rd_list_cnt(&config->config)); RD_LIST_FOREACH(entry, &config->config, ei) { - /* config_name */ + /* Name */ rd_kafka_buf_write_str(rkbuf, entry->kv->name, -1); - /* config_value (nullable) */ + /* ConfigOperation */ + rd_kafka_buf_write_i8(rkbuf, entry->a.op_type); + /* Value (nullable) */ rd_kafka_buf_write_str(rkbuf, entry->kv->value, -1); - if (entry->a.operation != RD_KAFKA_ALTER_OP_SET) { - rd_snprintf(errstr, errstr_size, - "IncrementalAlterConfigs required " - "for add/delete config " - "entries: only set supported " - "by this operation"); - rd_kafka_buf_destroy(rkbuf); - rd_kafka_replyq_destroy(&replyq); - return RD_KAFKA_RESP_ERR__UNSUPPORTED_FEATURE; - } + rd_kafka_buf_write_tags(rkbuf); } + + rd_kafka_buf_write_tags(rkbuf); } /* timeout */ @@ -4276,7 +4345,7 @@ rd_kafka_AlterConfigsRequest(rd_kafka_broker_t *rkb, if (op_timeout > rkb->rkb_rk->rk_conf.socket_timeout_ms) rd_kafka_buf_set_abs_timeout(rkbuf, op_timeout + 1000, 0); - /* validate_only */ + /* ValidateOnly */ rd_kafka_buf_write_i8( rkbuf, rd_kafka_confval_get_int(&options->validate_only)); @@ -4287,7 +4356,6 @@ rd_kafka_AlterConfigsRequest(rd_kafka_broker_t *rkb, return RD_KAFKA_RESP_ERR_NO_ERROR; } - /** * @brief Construct and send DescribeConfigsRequest to \p rkb * with the configs (ConfigResource_t*) in \p configs, using diff --git a/src/rdkafka_request.h b/src/rdkafka_request.h index 79254099cb..6f08e7a8a6 100644 --- a/src/rdkafka_request.h +++ b/src/rdkafka_request.h @@ -341,6 +341,16 @@ rd_kafka_AlterConfigsRequest(rd_kafka_broker_t *rkb, rd_kafka_resp_cb_t *resp_cb, void *opaque); +rd_kafka_resp_err_t rd_kafka_IncrementalAlterConfigsRequest( + rd_kafka_broker_t *rkb, + const rd_list_t *configs /*(ConfigResource_t*)*/, + rd_kafka_AdminOptions_t *options, + char *errstr, + size_t errstr_size, + rd_kafka_replyq_t replyq, + rd_kafka_resp_cb_t *resp_cb, + void *opaque); + rd_kafka_resp_err_t rd_kafka_DescribeConfigsRequest( rd_kafka_broker_t *rkb, const rd_list_t *configs /*(ConfigResource_t*)*/, diff --git a/tests/0081-admin.c b/tests/0081-admin.c index 285b8c0f65..7d8799ea23 100644 --- a/tests/0081-admin.c +++ b/tests/0081-admin.c @@ -897,6 +897,252 @@ static void do_test_AlterConfigs(rd_kafka_t *rk, rd_kafka_queue_t *rkqu) { SUB_TEST_PASS(); } +/** + * @brief Test IncrementalAlterConfigs + */ +static void do_test_IncrementalAlterConfigs(rd_kafka_t *rk, + rd_kafka_queue_t *rkqu) { +#define MY_CONFRES_CNT 3 + char *topics[MY_CONFRES_CNT]; + rd_kafka_ConfigResource_t *configs[MY_CONFRES_CNT]; + rd_kafka_AdminOptions_t *options; + rd_kafka_resp_err_t exp_err[MY_CONFRES_CNT]; + rd_kafka_event_t *rkev; + rd_kafka_resp_err_t err; + rd_kafka_error_t *error; + const rd_kafka_IncrementalAlterConfigs_result_t *res; + const rd_kafka_ConfigResource_t **rconfigs; + size_t rconfig_cnt; + char errstr[128]; + const char *errstr2; + int ci = 0; + int i; + int fails = 0; + + SUB_TEST_QUICK(); + + /* + * Only create one topic, the others will be non-existent. + */ + for (i = 0; i < MY_CONFRES_CNT; i++) + rd_strdupa(&topics[i], test_mk_topic_name(__FUNCTION__, 1)); + + test_CreateTopics_simple(rk, NULL, topics, 1, 1, NULL); + + test_wait_topic_exists(rk, topics[0], 10000); + + + /** Test the test helper, for use in other tests. */ + do { + const char *broker_id = tsprintf("%d", avail_brokers[0]); + const char *confs_set_append[] = { + "compression.type", "SET", "lz4", + "cleanup.policy", "APPEND", "compact"}; + const char *confs_delete_subtract[] = { + "compression.type", "DELETE", "lz4", + "cleanup.policy", "SUBTRACT", "compact"}; + const char *confs_set_append_broker[] = { + "background.threads", "SET", "9", + "log.cleanup.policy", "APPEND", "compact"}; + const char *confs_delete_subtract_broker[] = { + "background.threads", "DELETE", "", + "log.cleanup.policy", "SUBTRACT", "compact"}; + + TEST_SAY("Testing test helper with SET and APPEND\n"); + test_IncrementalAlterConfigs_simple(rk, RD_KAFKA_RESOURCE_TOPIC, + topics[0], confs_set_append, + 2); + TEST_SAY("Testing test helper with SUBTRACT and DELETE\n"); + test_IncrementalAlterConfigs_simple(rk, RD_KAFKA_RESOURCE_TOPIC, + topics[0], + confs_delete_subtract, 2); + + TEST_SAY( + "Testing test helper with SET and APPEND with BROKER " + "resource type\n"); + test_IncrementalAlterConfigs_simple( + rk, RD_KAFKA_RESOURCE_BROKER, broker_id, + confs_set_append_broker, 2); + TEST_SAY( + "Testing test helper with SUBTRACT and DELETE with BROKER " + "resource type\n"); + test_IncrementalAlterConfigs_simple( + rk, RD_KAFKA_RESOURCE_BROKER, broker_id, + confs_delete_subtract_broker, 2); + TEST_SAY("End testing test helper\n"); + } while (0); + + /* + * ConfigResource #0: valid topic config + */ + configs[ci] = + rd_kafka_ConfigResource_new(RD_KAFKA_RESOURCE_TOPIC, topics[ci]); + + error = rd_kafka_ConfigResource_add_incremental_config( + configs[ci], "compression.type", RD_KAFKA_ALTER_CONFIG_OP_TYPE_SET, + "gzip"); + TEST_ASSERT(!error, "%s", rd_kafka_error_string(error)); + + error = rd_kafka_ConfigResource_add_incremental_config( + configs[ci], "flush.ms", RD_KAFKA_ALTER_CONFIG_OP_TYPE_SET, + "12345678"); + TEST_ASSERT(!error, "%s", rd_kafka_error_string(error)); + + exp_err[ci] = RD_KAFKA_RESP_ERR_NO_ERROR; + ci++; + + + if (test_broker_version >= TEST_BRKVER(1, 1, 0, 0)) { + /* + * ConfigResource #1: valid broker config + */ + configs[ci] = rd_kafka_ConfigResource_new( + RD_KAFKA_RESOURCE_BROKER, + tsprintf("%" PRId32, avail_brokers[0])); + + error = rd_kafka_ConfigResource_add_incremental_config( + configs[ci], "sasl.kerberos.min.time.before.relogin", + RD_KAFKA_ALTER_CONFIG_OP_TYPE_SET, "58000"); + TEST_ASSERT(!error, "%s", rd_kafka_error_string(error)); + + exp_err[ci] = RD_KAFKA_RESP_ERR_NO_ERROR; + ci++; + } else { + TEST_WARN( + "Skipping RESOURCE_BROKER test on unsupported " + "broker version\n"); + } + + /* + * ConfigResource #2: valid topic config, non-existent topic + */ + configs[ci] = + rd_kafka_ConfigResource_new(RD_KAFKA_RESOURCE_TOPIC, topics[ci]); + + error = rd_kafka_ConfigResource_add_incremental_config( + configs[ci], "compression.type", RD_KAFKA_ALTER_CONFIG_OP_TYPE_SET, + "lz4"); + TEST_ASSERT(!error, "%s", rd_kafka_error_string(error)); + + error = rd_kafka_ConfigResource_add_incremental_config( + configs[ci], "offset.metadata.max.bytes", + RD_KAFKA_ALTER_CONFIG_OP_TYPE_SET, "12345"); + TEST_ASSERT(!error, "%s", rd_kafka_error_string(error)); + + if (test_broker_version >= TEST_BRKVER(2, 7, 0, 0)) + exp_err[ci] = RD_KAFKA_RESP_ERR_UNKNOWN_TOPIC_OR_PART; + else + exp_err[ci] = RD_KAFKA_RESP_ERR_UNKNOWN; + ci++; + + /* + * Timeout options + */ + options = rd_kafka_AdminOptions_new( + rk, RD_KAFKA_ADMIN_OP_INCREMENTALALTERCONFIGS); + err = rd_kafka_AdminOptions_set_request_timeout(options, 10000, errstr, + sizeof(errstr)); + TEST_ASSERT(!err, "%s", errstr); + + + /* + * Fire off request + */ + rd_kafka_IncrementalAlterConfigs(rk, configs, ci, options, rkqu); + + rd_kafka_AdminOptions_destroy(options); + + /* + * Wait for result + */ + rkev = test_wait_admin_result( + rkqu, RD_KAFKA_EVENT_INCREMENTALALTERCONFIGS_RESULT, 10000 + 1000); + + /* + * Extract result + */ + res = rd_kafka_event_IncrementalAlterConfigs_result(rkev); + TEST_ASSERT(res, "Expected AlterConfigs result, not %s", + rd_kafka_event_name(rkev)); + + err = rd_kafka_event_error(rkev); + errstr2 = rd_kafka_event_error_string(rkev); + TEST_ASSERT(!err, "Expected success, not %s: %s", + rd_kafka_err2name(err), errstr2); + + rconfigs = rd_kafka_IncrementalAlterConfigs_result_resources( + res, &rconfig_cnt); + TEST_ASSERT((int)rconfig_cnt == ci, + "Expected %d result resources, got %" PRIusz "\n", ci, + rconfig_cnt); + + /* + * Verify status per resource + */ + for (i = 0; i < (int)rconfig_cnt; i++) { + const rd_kafka_ConfigEntry_t **entries; + size_t entry_cnt; + + err = rd_kafka_ConfigResource_error(rconfigs[i]); + errstr2 = rd_kafka_ConfigResource_error_string(rconfigs[i]); + + entries = + rd_kafka_ConfigResource_configs(rconfigs[i], &entry_cnt); + + TEST_SAY( + "ConfigResource #%d: type %s (%d), \"%s\": " + "%" PRIusz " ConfigEntries, error %s (%s)\n", + i, + rd_kafka_ResourceType_name( + rd_kafka_ConfigResource_type(rconfigs[i])), + rd_kafka_ConfigResource_type(rconfigs[i]), + rd_kafka_ConfigResource_name(rconfigs[i]), entry_cnt, + rd_kafka_err2name(err), errstr2 ? errstr2 : ""); + + test_print_ConfigEntry_array(entries, entry_cnt, 1); + + if (rd_kafka_ConfigResource_type(rconfigs[i]) != + rd_kafka_ConfigResource_type(configs[i]) || + strcmp(rd_kafka_ConfigResource_name(rconfigs[i]), + rd_kafka_ConfigResource_name(configs[i]))) { + TEST_FAIL_LATER( + "ConfigResource #%d: " + "expected type %s name %s, " + "got type %s name %s", + i, + rd_kafka_ResourceType_name( + rd_kafka_ConfigResource_type(configs[i])), + rd_kafka_ConfigResource_name(configs[i]), + rd_kafka_ResourceType_name( + rd_kafka_ConfigResource_type(rconfigs[i])), + rd_kafka_ConfigResource_name(rconfigs[i])); + fails++; + continue; + } + + + if (err != exp_err[i]) { + TEST_FAIL_LATER( + "ConfigResource #%d: " + "expected %s (%d), got %s (%s)", + i, rd_kafka_err2name(exp_err[i]), exp_err[i], + rd_kafka_err2name(err), errstr2 ? errstr2 : ""); + fails++; + } + } + + TEST_ASSERT(!fails, "See %d previous failure(s)", fails); + + rd_kafka_event_destroy(rkev); + + rd_kafka_ConfigResource_destroy_array(configs, ci); + + TEST_LATER_CHECK(); +#undef MY_CONFRES_CNT + + SUB_TEST_PASS(); +} + /** @@ -3714,6 +3960,11 @@ static void do_test_apis(rd_kafka_type_t cltype) { /* AlterConfigs */ do_test_AlterConfigs(rk, mainq); + if (test_broker_version >= TEST_BRKVER(2, 3, 0, 0)) { + /* IncrementalAlterConfigs */ + do_test_IncrementalAlterConfigs(rk, mainq); + } + /* DescribeConfigs */ do_test_DescribeConfigs(rk, mainq); diff --git a/tests/test.c b/tests/test.c index 0027d28c0d..06ade264eb 100644 --- a/tests/test.c +++ b/tests/test.c @@ -5835,6 +5835,7 @@ rd_kafka_event_t *test_wait_admin_result(rd_kafka_queue_t *q, * * Supported APIs: * - AlterConfigs + * - IncrementalAlterConfigs * - CreatePartitions * - CreateTopics * - DeleteGroups @@ -5918,6 +5919,17 @@ rd_kafka_resp_err_t test_wait_topic_admin_result(rd_kafka_queue_t *q, cres = rd_kafka_AlterConfigs_result_resources(res, &cres_cnt); + } else if (evtype == RD_KAFKA_EVENT_INCREMENTALALTERCONFIGS_RESULT) { + const rd_kafka_IncrementalAlterConfigs_result_t *res; + + if (!(res = + rd_kafka_event_IncrementalAlterConfigs_result(rkev))) + TEST_FAIL( + "Expected a IncrementalAlterConfigs result, not %s", + rd_kafka_event_name(rkev)); + + cres = rd_kafka_IncrementalAlterConfigs_result_resources( + res, &cres_cnt); } else if (evtype == RD_KAFKA_EVENT_CREATEACLS_RESULT) { const rd_kafka_CreateAcls_result_t *res; @@ -6496,7 +6508,7 @@ rd_kafka_resp_err_t test_AlterConfigs_simple(rd_kafka_t *rk, size_t result_cnt; const rd_kafka_ConfigEntry_t **configents; size_t configent_cnt; - + config_cnt = config_cnt * 2; q = rd_kafka_queue_new(rk); @@ -6581,6 +6593,74 @@ rd_kafka_resp_err_t test_AlterConfigs_simple(rd_kafka_t *rk, return err; } +/** + * @brief Delta Incremental Alter configuration for the given resource, + * overwriting/setting the configs provided in \p configs. + * Existing configuration remains intact. + * + * @param configs 'const char *name, const char *op_type', const char *value' + * tuples + * @param config_cnt is the number of tuples in \p configs + */ +rd_kafka_resp_err_t +test_IncrementalAlterConfigs_simple(rd_kafka_t *rk, + rd_kafka_ResourceType_t restype, + const char *resname, + const char **configs, + size_t config_cnt) { + rd_kafka_queue_t *q; + rd_kafka_ConfigResource_t *confres; + size_t i; + rd_kafka_resp_err_t err; + rd_kafka_error_t *error; + + + TEST_SAY("Incrementally altering configuration for %d %s\n", restype, + resname); + + q = rd_kafka_queue_new(rk); + confres = rd_kafka_ConfigResource_new(restype, resname); + config_cnt = config_cnt * 3; + + /* Apply the configuration to change. */ + for (i = 0; i < config_cnt; i += 3) { + const char *confname = configs[i]; + const char *op_string = configs[i + 1]; + const char *confvalue = configs[i + 2]; + rd_kafka_AlterConfigOpType_t op_type = + RD_KAFKA_ALTER_CONFIG_OP_TYPE__CNT; + + if (!strcmp(op_string, "SET")) + op_type = RD_KAFKA_ALTER_CONFIG_OP_TYPE_SET; + else if (!strcmp(op_string, "DELETE")) + op_type = RD_KAFKA_ALTER_CONFIG_OP_TYPE_DELETE; + else if (!strcmp(op_string, "APPEND")) + op_type = RD_KAFKA_ALTER_CONFIG_OP_TYPE_APPEND; + else if (!strcmp(op_string, "SUBTRACT")) + op_type = RD_KAFKA_ALTER_CONFIG_OP_TYPE_SUBTRACT; + else + TEST_FAIL("Unknown op type %s\n", op_string); + + error = rd_kafka_ConfigResource_add_incremental_config( + confres, confname, op_type, confvalue); + TEST_ASSERT(!error, + "Failed to set incremental %s config %s=%s on " + "local resource object", + op_string, confname, confvalue); + } + + rd_kafka_IncrementalAlterConfigs(rk, &confres, 1, NULL, q); + + rd_kafka_ConfigResource_destroy(confres); + + err = test_wait_topic_admin_result( + q, RD_KAFKA_EVENT_INCREMENTALALTERCONFIGS_RESULT, NULL, 15 * 1000); + + rd_kafka_queue_destroy(q); + + return err; +} + /** * @brief Topic Admin API helpers * diff --git a/tests/test.h b/tests/test.h index 596824f918..a1f5cc2cb6 100644 --- a/tests/test.h +++ b/tests/test.h @@ -801,6 +801,13 @@ rd_kafka_resp_err_t test_AlterConfigs_simple(rd_kafka_t *rk, const char **configs, size_t config_cnt); +rd_kafka_resp_err_t +test_IncrementalAlterConfigs_simple(rd_kafka_t *rk, + rd_kafka_ResourceType_t restype, + const char *resname, + const char **configs, + size_t config_cnt); + rd_kafka_resp_err_t test_DeleteGroups_simple(rd_kafka_t *rk, rd_kafka_queue_t *useq, char **groups, From c23adb959192aadfcf7461371bb9f8dfe79958d2 Mon Sep 17 00:00:00 2001 From: mahajanadhitya <115617755+mahajanadhitya@users.noreply.github.com> Date: Mon, 10 Jul 2023 23:34:51 +0530 Subject: [PATCH 6/9] Scram Config API in Admin Client [KIP-554] (#4241) requires broker version >= 2.7.0 --------- Co-authored-by: Emanuele Sabellico --- CHANGELOG.md | 1 + INTRODUCTION.md | 68 +-- examples/.gitignore | 1 + examples/CMakeLists.txt | 3 + examples/Makefile | 5 + examples/README.md | 1 + examples/user_scram.c | 492 ++++++++++++++++++++++ src/rdkafka.c | 5 +- src/rdkafka.h | 291 ++++++++++++- src/rdkafka_admin.c | 796 +++++++++++++++++++++++++++++++++++- src/rdkafka_admin.h | 11 +- src/rdkafka_buf.h | 71 ++-- src/rdkafka_cgrp.c | 8 +- src/rdkafka_event.c | 23 ++ src/rdkafka_event.h | 2 + src/rdkafka_mock_handlers.c | 13 +- src/rdkafka_msgset_reader.c | 8 +- src/rdkafka_op.c | 10 + src/rdkafka_op.h | 6 + src/rdkafka_partition.c | 2 - src/rdkafka_proto.h | 8 +- src/rdkafka_request.c | 2 +- src/rdkafka_request.h | 1 - src/rdkafka_sasl_scram.c | 51 +-- src/rdkafka_ssl.c | 53 +++ src/rdkafka_ssl.h | 7 + tests/0080-admin_ut.c | 140 +++++++ tests/0081-admin.c | 322 ++++++++++++++- 28 files changed, 2253 insertions(+), 148 deletions(-) create mode 100644 examples/user_scram.c diff --git a/CHANGELOG.md b/CHANGELOG.md index 95c4dbd0ff..e7577a989a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ librdkafka v2.2.0 is a feature release: Add DNS alias support for secured connection (#4292). * [KIP-339](https://cwiki.apache.org/confluence/display/KAFKA/KIP-339%3A+Create+a+new+IncrementalAlterConfigs+API): IncrementalAlterConfigs API (started by @PrasanthV454, #4110). + * [KIP-554](https://cwiki.apache.org/confluence/display/KAFKA/KIP-554%3A+Add+Broker-side+SCRAM+Config+API): Add Broker-side SCRAM Config API (#4241). ## Enhancements diff --git a/INTRODUCTION.md b/INTRODUCTION.md index d7b9a84a1c..7cb45a2f3d 100644 --- a/INTRODUCTION.md +++ b/INTRODUCTION.md @@ -1945,6 +1945,7 @@ The [Apache Kafka Implementation Proposals (KIPs)](https://cwiki.apache.org/conf | KIP-526 - Reduce Producer Metadata Lookups for Large Number of Topics | 2.5.0 | Not supported | | KIP-533 - Add default API timeout to AdminClient | 2.5.0 | Not supported | | KIP-546 - Add Client Quota APIs to AdminClient | 2.6.0 | Not supported | +| KIP-554 - Add Broker-side SCRAM Config API | 2.7.0 | Supported | | KIP-559 - Make the Kafka Protocol Friendlier with L7 Proxies | 2.5.0 | Not supported | | KIP-568 - Explicit rebalance triggering on the Consumer | 2.6.0 | Not supported | | KIP-659 - Add metadata to DescribeConfigsResponse | 2.6.0 | Not supported | @@ -1969,39 +1970,40 @@ The [Apache Kafka Implementation Proposals (KIPs)](https://cwiki.apache.org/conf release of librdkafka. -| ApiKey | Request name | Kafka max | librdkafka max | -| ------- | ------------------------| ----------- | ----------------------- | -| 0 | Produce | 9 | 7 | -| 1 | Fetch | 13 | 11 | -| 2 | ListOffsets | 7 | 2 | -| 3 | Metadata | 12 | 9 | -| 8 | OffsetCommit | 8 | 7 | -| 9 | OffsetFetch | 8 | 7 | -| 10 | FindCoordinator | 4 | 2 | -| 11 | JoinGroup | 9 | 5 | -| 12 | Heartbeat | 4 | 3 | -| 13 | LeaveGroup | 5 | 1 | -| 14 | SyncGroup | 5 | 3 | -| 15 | DescribeGroups | 5 | 4 | -| 16 | ListGroups | 4 | 4 | -| 17 | SaslHandshake | 1 | 1 | -| 18 | ApiVersions | 3 | 3 | -| 19 | CreateTopics | 7 | 4 | -| 20 | DeleteTopics | 6 | 1 | -| 21 | DeleteRecords | 2 | 1 | -| 22 | InitProducerId | 4 | 4 | -| 24 | AddPartitionsToTxn | 3 | 0 | -| 25 | AddOffsetsToTxn | 3 | 0 | -| 26 | EndTxn | 3 | 1 | -| 28 | TxnOffsetCommit | 3 | 3 | -| 32 | DescribeConfigs | 4 | 1 | -| 33 | AlterConfigs | 2 | 2 | -| 36 | SaslAuthenticate | 2 | 0 | -| 37 | CreatePartitions | 3 | 0 | -| 42 | DeleteGroups | 2 | 1 | -| 44 | IncrementalAlterConfigs | 1 | 1 | -| 47 | OffsetDelete | 0 | 0 | - +| ApiKey | Request name | Kafka max | librdkafka max | +| ------- | ------------------------------| ----------- | ----------------------- | +| 0 | Produce | 9 | 7 | +| 1 | Fetch | 13 | 11 | +| 2 | ListOffsets | 7 | 2 | +| 3 | Metadata | 12 | 9 | +| 8 | OffsetCommit | 8 | 7 | +| 9 | OffsetFetch | 8 | 7 | +| 10 | FindCoordinator | 4 | 2 | +| 11 | JoinGroup | 9 | 5 | +| 12 | Heartbeat | 4 | 3 | +| 13 | LeaveGroup | 5 | 1 | +| 14 | SyncGroup | 5 | 3 | +| 15 | DescribeGroups | 5 | 4 | +| 16 | ListGroups | 4 | 4 | +| 17 | SaslHandshake | 1 | 1 | +| 18 | ApiVersions | 3 | 3 | +| 19 | CreateTopics | 7 | 4 | +| 20 | DeleteTopics | 6 | 1 | +| 21 | DeleteRecords | 2 | 1 | +| 22 | InitProducerId | 4 | 4 | +| 24 | AddPartitionsToTxn | 3 | 0 | +| 25 | AddOffsetsToTxn | 3 | 0 | +| 26 | EndTxn | 3 | 1 | +| 28 | TxnOffsetCommit | 3 | 3 | +| 32 | DescribeConfigs | 4 | 1 | +| 33 | AlterConfigs | 2 | 2 | +| 36 | SaslAuthenticate | 2 | 1 | +| 37 | CreatePartitions | 3 | 0 | +| 42 | DeleteGroups | 2 | 1 | +| 44 | IncrementalAlterConfigs | 1 | 1 | +| 47 | OffsetDelete | 0 | 0 | +| 50 | DescribeUserScramCredentials | 0 | 0 | +| 51 | AlterUserScramCredentials | 0 | 0 | # Recommendations for language binding developers diff --git a/examples/.gitignore b/examples/.gitignore index 893f84179b..4df12d6233 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -18,3 +18,4 @@ describe_consumer_groups list_consumer_group_offsets alter_consumer_group_offsets incremental_alter_configs +user_scram \ No newline at end of file diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 748abad572..b3f974424f 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -50,6 +50,9 @@ target_link_libraries(alter_consumer_group_offsets PUBLIC rdkafka) add_executable(incremental_alter_configs incremental_alter_configs.c ${win32_sources}) target_link_libraries(incremental_alter_configs PUBLIC rdkafka) +add_executable(user_scram user_scram.c ${win32_sources}) +target_link_libraries(user_scram PUBLIC rdkafka) + # The targets below has Unix include dirs and do not compile on Windows. if(NOT WIN32) add_executable(rdkafka_example rdkafka_example.c) diff --git a/examples/Makefile b/examples/Makefile index d06e8fc04a..add586de8c 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -9,6 +9,7 @@ EXAMPLES ?= rdkafka_example rdkafka_performance rdkafka_example_cpp \ list_consumer_group_offsets \ alter_consumer_group_offsets \ incremental_alter_configs \ + user_scram \ misc all: $(EXAMPLES) @@ -133,6 +134,10 @@ openssl_engine_example_cpp: ../src-cpp/librdkafka++.a ../src/librdkafka.a openss $(CXX) $(CPPFLAGS) $(CXXFLAGS) openssl_engine_example.cpp -o $@ $(LDFLAGS) \ ../src-cpp/librdkafka++.a ../src/librdkafka.a $(LIBS) +user_scram: ../src/librdkafka.a user_scram.c + $(CC) $(CPPFLAGS) $(CFLAGS) $@.c -o $@ $(LDFLAGS) \ + ../src/librdkafka.a $(LIBS) + misc: ../src/librdkafka.a misc.c $(CC) $(CPPFLAGS) $(CFLAGS) $@.c -o $@ $(LDFLAGS) \ ../src/librdkafka.a $(LIBS) diff --git a/examples/README.md b/examples/README.md index 34afac2157..32e93e6056 100644 --- a/examples/README.md +++ b/examples/README.md @@ -37,3 +37,4 @@ For more complex uses, see: * [list_consumer_group_offsets.c](list_consumer_group_offsets.c) - List offsets of a consumer group. * [alter_consumer_group_offsets.c](alter_consumer_group_offsets.c) - Alter offsets of a consumer group. * [incremental_alter_configs.c](incremental_alter_configs.c) - Incrementally alter resource configurations. + * [user_scram.c](user_scram.c) - Describe or alter user SCRAM credentials. diff --git a/examples/user_scram.c b/examples/user_scram.c new file mode 100644 index 0000000000..95d6809b40 --- /dev/null +++ b/examples/user_scram.c @@ -0,0 +1,492 @@ +/* + * librdkafka - Apache Kafka C library + * + * Copyright (c) 2023, Confluent Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SH THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * Example utility that shows how to use SCRAM APIs (AdminAPI) + * DescribeUserScramCredentials -> Describe user SCRAM credentials + * AlterUserScramCredentials -> Upsert or delete user SCRAM credentials + */ + +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include "../win32/wingetopt.h" +#else +#include +#endif + +/* Typical include path would be , but this program + * is builtin from within the librdkafka source tree and thus differs. */ +#include "rdkafka.h" + +const char *argv0; + +static rd_kafka_queue_t *queue; /** Admin result queue. + * This is a global so we can + * yield in stop() */ +static volatile sig_atomic_t run = 1; + +/** + * @brief Signal termination of program + */ +static void stop(int sig) { + if (!run) { + fprintf(stderr, "%% Forced termination\n"); + exit(2); + } + run = 0; + rd_kafka_queue_yield(queue); +} + + +static void usage(const char *reason, ...) { + fprintf(stderr, + "Describe/Alter user SCRAM credentials\n" + "\n" + "Usage: %s \n" + " DESCRIBE ... \n" + " UPSERT " + " ... \n" + " DELETE ... \n" + "\n" + "Options:\n" + " -b Bootstrap server list to connect to.\n" + " -X Set librdkafka configuration property.\n" + " See CONFIGURATION.md for full list.\n" + " -d Enable librdkafka debugging (%s).\n" + "\n", + argv0, rd_kafka_get_debug_contexts()); + + if (reason) { + va_list ap; + char reasonbuf[512]; + + va_start(ap, reason); + vsnprintf(reasonbuf, sizeof(reasonbuf), reason, ap); + va_end(ap); + + fprintf(stderr, "ERROR: %s\n", reasonbuf); + } + + exit(reason ? 1 : 0); +} + +#define fatal(...) \ + do { \ + fprintf(stderr, "ERROR: "); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + exit(2); \ + } while (0) + + +/** + * @brief Set config property. Exit on failure. + */ +static void conf_set(rd_kafka_conf_t *conf, const char *name, const char *val) { + char errstr[512]; + + if (rd_kafka_conf_set(conf, name, val, errstr, sizeof(errstr)) != + RD_KAFKA_CONF_OK) + fatal("Failed to set %s=%s: %s", name, val, errstr); +} + + +/** + * @brief Parse an integer or fail. + */ +int64_t parse_int(const char *what, const char *str) { + char *end; + unsigned long n = strtoull(str, &end, 0); + + if (end != str + strlen(str)) { + fprintf(stderr, "%% Invalid input for %s: %s: not an integer\n", + what, str); + exit(1); + } + + return (int64_t)n; +} + +rd_kafka_ScramMechanism_t parse_mechanism(const char *arg) { + return !strcmp(arg, "SCRAM-SHA-256") + ? RD_KAFKA_SCRAM_MECHANISM_SHA_256 + : !strcmp(arg, "SCRAM-SHA-512") + ? RD_KAFKA_SCRAM_MECHANISM_SHA_512 + : RD_KAFKA_SCRAM_MECHANISM_UNKNOWN; +} + +static void print_descriptions( + const rd_kafka_UserScramCredentialsDescription_t **descriptions, + size_t description_cnt) { + size_t i; + printf("DescribeUserScramCredentials descriptions[%zu]\n", + description_cnt); + for (i = 0; i < description_cnt; i++) { + const rd_kafka_UserScramCredentialsDescription_t *description; + description = descriptions[i]; + const char *username; + const rd_kafka_error_t *error; + username = + rd_kafka_UserScramCredentialsDescription_user(description); + error = + rd_kafka_UserScramCredentialsDescription_error(description); + rd_kafka_resp_err_t err = rd_kafka_error_code(error); + printf(" Username: \"%s\" Error: \"%s\"\n", username, + rd_kafka_err2str(err)); + if (err) { + const char *errstr = rd_kafka_error_string(error); + printf(" ErrorMessage: \"%s\"\n", errstr); + } + size_t num_credentials = + rd_kafka_UserScramCredentialsDescription_scramcredentialinfo_count( + description); + size_t itr; + for (itr = 0; itr < num_credentials; itr++) { + const rd_kafka_ScramCredentialInfo_t *scram_credential = + rd_kafka_UserScramCredentialsDescription_scramcredentialinfo( + description, itr); + rd_kafka_ScramMechanism_t mechanism; + int32_t iterations; + mechanism = rd_kafka_ScramCredentialInfo_mechanism( + scram_credential); + iterations = rd_kafka_ScramCredentialInfo_iterations( + scram_credential); + switch (mechanism) { + case RD_KAFKA_SCRAM_MECHANISM_UNKNOWN: + printf( + " Mechanism is " + "UNKNOWN\n"); + break; + case RD_KAFKA_SCRAM_MECHANISM_SHA_256: + printf( + " Mechanism is " + "SCRAM-SHA-256\n"); + break; + case RD_KAFKA_SCRAM_MECHANISM_SHA_512: + printf( + " Mechanism is " + "SCRAM-SHA-512\n"); + break; + default: + printf( + " Mechanism does " + "not match enums\n"); + } + printf(" Iterations are %d\n", iterations); + } + } +} + +static void print_alteration_responses( + const rd_kafka_AlterUserScramCredentials_result_response_t **responses, + size_t responses_cnt) { + size_t i; + printf("AlterUserScramCredentials responses [%zu]:\n", responses_cnt); + for (i = 0; i < responses_cnt; i++) { + const rd_kafka_AlterUserScramCredentials_result_response_t + *response = responses[i]; + const char *username; + const rd_kafka_error_t *error; + username = + rd_kafka_AlterUserScramCredentials_result_response_user( + response); + error = + rd_kafka_AlterUserScramCredentials_result_response_error( + response); + rd_kafka_resp_err_t err = rd_kafka_error_code(error); + if (err) { + const char *errstr = rd_kafka_error_string(error); + printf(" Username: \"%s\", Error: \"%s\"\n", + username, rd_kafka_err2str(err)); + printf(" ErrorMessage: \"%s\"\n", errstr); + } else { + printf(" Username: \"%s\" Success\n", username); + } + } +} + +static void Describe(rd_kafka_t *rk, const char **users, size_t user_cnt) { + rd_kafka_event_t *event; + char errstr[512]; /* librdkafka API error reporting buffer */ + + rd_kafka_AdminOptions_t *options = rd_kafka_AdminOptions_new( + rk, RD_KAFKA_ADMIN_OP_DESCRIBEUSERSCRAMCREDENTIALS); + + if (rd_kafka_AdminOptions_set_request_timeout( + options, 30 * 1000 /* 30s */, errstr, sizeof(errstr))) { + fprintf(stderr, "%% Failed to set timeout: %s\n", errstr); + return; + } + + /* NULL argument gives us all the users*/ + rd_kafka_DescribeUserScramCredentials(rk, users, user_cnt, options, + queue); + rd_kafka_AdminOptions_destroy(options); + + /* Wait for results */ + event = rd_kafka_queue_poll(queue, -1 /*indefinitely*/); + if (!event) { + /* User hit Ctrl-C */ + fprintf(stderr, "%% Cancelled by user\n"); + + } else if (rd_kafka_event_error(event)) { + /* Request failed */ + fprintf(stderr, "%% DescribeUserScramCredentials failed: %s\n", + rd_kafka_event_error_string(event)); + + } else { + /* Request succeeded */ + const rd_kafka_DescribeUserScramCredentials_result_t *result; + const rd_kafka_UserScramCredentialsDescription_t **descriptions; + size_t description_cnt; + result = + rd_kafka_event_DescribeUserScramCredentials_result(event); + descriptions = + rd_kafka_DescribeUserScramCredentials_result_descriptions( + result, &description_cnt); + print_descriptions(descriptions, description_cnt); + } + rd_kafka_event_destroy(event); +} + +static void Alter(rd_kafka_t *rk, + rd_kafka_UserScramCredentialAlteration_t **alterations, + size_t alteration_cnt) { + rd_kafka_event_t *event; + char errstr[512]; /* librdkafka API error reporting buffer */ + + /* Set timeout (optional) */ + rd_kafka_AdminOptions_t *options = rd_kafka_AdminOptions_new( + rk, RD_KAFKA_ADMIN_OP_ALTERUSERSCRAMCREDENTIALS); + + if (rd_kafka_AdminOptions_set_request_timeout( + options, 30 * 1000 /* 30s */, errstr, sizeof(errstr))) { + fprintf(stderr, "%% Failed to set timeout: %s\n", errstr); + return; + } + + /* Call the AlterUserScramCredentials function*/ + rd_kafka_AlterUserScramCredentials(rk, alterations, alteration_cnt, + options, queue); + rd_kafka_AdminOptions_destroy(options); + + /* Wait for results */ + event = rd_kafka_queue_poll(queue, -1 /*indefinitely*/); + if (!event) { + /* User hit Ctrl-C */ + fprintf(stderr, "%% Cancelled by user\n"); + + } else if (rd_kafka_event_error(event)) { + /* Request failed */ + fprintf(stderr, "%% AlterUserScramCredentials failed: %s\n", + rd_kafka_event_error_string(event)); + + } else { + /* Request succeeded */ + const rd_kafka_AlterUserScramCredentials_result_t *result = + rd_kafka_event_AlterUserScramCredentials_result(event); + const rd_kafka_AlterUserScramCredentials_result_response_t * + *responses; + size_t responses_cnt; + responses = rd_kafka_AlterUserScramCredentials_result_responses( + result, &responses_cnt); + + print_alteration_responses(responses, responses_cnt); + } + rd_kafka_event_destroy(event); +} + +static void cmd_user_scram(rd_kafka_conf_t *conf, int argc, const char **argv) { + char errstr[512]; /* librdkafka API error reporting buffer */ + rd_kafka_t *rk; /* Admin client instance */ + size_t i; + const int min_argc = 1; + const int args_rest = argc - min_argc; + + int is_describe = 0; + int is_upsert = 0; + int is_delete = 0; + + /* + * Argument validation + */ + int correct_argument_cnt = argc >= min_argc; + + if (!correct_argument_cnt) + usage("Wrong number of arguments"); + + is_describe = !strcmp(argv[0], "DESCRIBE"); + is_upsert = !strcmp(argv[0], "UPSERT"); + is_delete = !strcmp(argv[0], "DELETE"); + + correct_argument_cnt = is_describe || + (is_upsert && (args_rest % 5) == 0) || + (is_delete && (args_rest % 2) == 0) || 0; + + if (!correct_argument_cnt) + usage("Wrong number of arguments"); + + + /* + * Create an admin client, it can be created using any client type, + * so we choose producer since it requires no extra configuration + * and is more light-weight than the consumer. + * + * NOTE: rd_kafka_new() takes ownership of the conf object + * and the application must not reference it again after + * this call. + */ + rk = rd_kafka_new(RD_KAFKA_PRODUCER, conf, errstr, sizeof(errstr)); + if (!rk) { + fprintf(stderr, "%% Failed to create new producer: %s\n", + errstr); + exit(1); + } + + /* The Admin API is completely asynchronous, results are emitted + * on the result queue that is passed to DeleteRecords() */ + queue = rd_kafka_queue_new(rk); + + /* Signal handler for clean shutdown */ + signal(SIGINT, stop); + + if (is_describe) { + + /* Describe the users */ + Describe(rk, &argv[min_argc], argc - min_argc); + + } else if (is_upsert) { + size_t upsert_cnt = args_rest / 5; + const char **upsert_args = &argv[min_argc]; + rd_kafka_UserScramCredentialAlteration_t **upserts = + calloc(upsert_cnt, sizeof(*upserts)); + for (i = 0; i < upsert_cnt; i++) { + const char **upsert_args_curr = &upsert_args[i * 5]; + size_t salt_size = 0; + const char *username = upsert_args_curr[0]; + rd_kafka_ScramMechanism_t mechanism = + parse_mechanism(upsert_args_curr[1]); + int iterations = + parse_int("iterations", upsert_args_curr[2]); + const char *password = upsert_args_curr[3]; + const char *salt = upsert_args_curr[4]; + + if (strlen(salt) == 0) + salt = NULL; + else + salt_size = strlen(salt); + + upserts[i] = rd_kafka_UserScramCredentialUpsertion_new( + username, mechanism, iterations, + (const unsigned char *)password, strlen(password), + (const unsigned char *)salt, salt_size); + } + Alter(rk, upserts, upsert_cnt); + rd_kafka_UserScramCredentialAlteration_destroy_array( + upserts, upsert_cnt); + free(upserts); + } else { + size_t deletion_cnt = args_rest / 2; + const char **delete_args = &argv[min_argc]; + rd_kafka_UserScramCredentialAlteration_t **deletions = + calloc(deletion_cnt, sizeof(*deletions)); + for (i = 0; i < deletion_cnt; i++) { + const char **delete_args_curr = &delete_args[i * 2]; + rd_kafka_ScramMechanism_t mechanism = + parse_mechanism(delete_args_curr[1]); + const char *username = delete_args_curr[0]; + + deletions[i] = rd_kafka_UserScramCredentialDeletion_new( + username, mechanism); + } + Alter(rk, deletions, deletion_cnt); + rd_kafka_UserScramCredentialAlteration_destroy_array( + deletions, deletion_cnt); + free(deletions); + } + + signal(SIGINT, SIG_DFL); + + /* Destroy queue */ + rd_kafka_queue_destroy(queue); + + + /* Destroy the producer instance */ + rd_kafka_destroy(rk); +} + +int main(int argc, char **argv) { + rd_kafka_conf_t *conf; /**< Client configuration object */ + int opt; + argv0 = argv[0]; + + /* + * Create Kafka client configuration place-holder + */ + conf = rd_kafka_conf_new(); + + + /* + * Parse common options + */ + while ((opt = getopt(argc, argv, "b:X:d:")) != -1) { + switch (opt) { + case 'b': + conf_set(conf, "bootstrap.servers", optarg); + break; + + case 'X': { + char *name = optarg, *val; + + if (!(val = strchr(name, '='))) + fatal("-X expects a name=value argument"); + + *val = '\0'; + val++; + + conf_set(conf, name, val); + break; + } + + case 'd': + conf_set(conf, "debug", optarg); + break; + + default: + usage("Unknown option %c", (char)opt); + } + } + + cmd_user_scram(conf, argc - optind, (const char **)&argv[optind]); + return 0; +} diff --git a/src/rdkafka.c b/src/rdkafka.c index 4a8ec30dfb..a353f7b46f 100644 --- a/src/rdkafka.c +++ b/src/rdkafka.c @@ -700,7 +700,6 @@ static const struct rd_kafka_err_desc rd_kafka_err_descs[] = { _ERR_DESC(RD_KAFKA_RESP_ERR_PRINCIPAL_DESERIALIZATION_FAILURE, "Broker: Request principal deserialization failed during " "forwarding"), - _ERR_DESC(RD_KAFKA_RESP_ERR__END, NULL)}; @@ -4694,8 +4693,8 @@ static void rd_kafka_DescribeGroups_resp_cb(rd_kafka_t *rk, rd_kafka_buf_read_str(reply, &MemberId); rd_kafka_buf_read_str(reply, &ClientId); rd_kafka_buf_read_str(reply, &ClientHost); - rd_kafka_buf_read_bytes(reply, &Meta); - rd_kafka_buf_read_bytes(reply, &Assignment); + rd_kafka_buf_read_kbytes(reply, &Meta); + rd_kafka_buf_read_kbytes(reply, &Assignment); mi->member_id = RD_KAFKAP_STR_DUP(&MemberId); mi->client_id = RD_KAFKAP_STR_DUP(&ClientId); diff --git a/src/rdkafka.h b/src/rdkafka.h index 0e14b8d273..2065e72533 100644 --- a/src/rdkafka.h +++ b/src/rdkafka.h @@ -909,7 +909,6 @@ typedef struct rd_kafka_topic_partition_s { * rd_kafka_t INSTANCES. */ } rd_kafka_topic_partition_t; - /** * @brief Destroy a rd_kafka_topic_partition_t. * @remark This must not be called for elements in a topic partition list. @@ -953,7 +952,6 @@ typedef struct rd_kafka_topic_partition_list_s { rd_kafka_topic_partition_t *elems; /**< Element array[] */ } rd_kafka_topic_partition_list_t; - /** * @brief Create a new list/vector Topic+Partition container. * @@ -971,7 +969,6 @@ typedef struct rd_kafka_topic_partition_list_s { RD_EXPORT rd_kafka_topic_partition_list_t *rd_kafka_topic_partition_list_new(int size); - /** * @brief Free all resources used by the list and the list itself. */ @@ -5369,6 +5366,10 @@ typedef int rd_kafka_event_type_t; #define RD_KAFKA_EVENT_ALTERCONSUMERGROUPOFFSETS_RESULT 0x10000 /** IncrementalAlterConfigs_result_t */ #define RD_KAFKA_EVENT_INCREMENTALALTERCONFIGS_RESULT 0x20000 +/** DescribeUserScramCredentials_result_t */ +#define RD_KAFKA_EVENT_DESCRIBEUSERSCRAMCREDENTIALS_RESULT 0x40000 +/** AlterUserScramCredentials_result_t */ +#define RD_KAFKA_EVENT_ALTERUSERSCRAMCREDENTIALS_RESULT 0x80000 /** * @returns the event type for the given event. @@ -5637,6 +5638,10 @@ typedef rd_kafka_event_t rd_kafka_DeleteConsumerGroupOffsets_result_t; typedef rd_kafka_event_t rd_kafka_AlterConsumerGroupOffsets_result_t; /*! ListConsumerGroupOffsets result type */ typedef rd_kafka_event_t rd_kafka_ListConsumerGroupOffsets_result_t; +/*! DescribeUserScramCredentials result type */ +typedef rd_kafka_event_t rd_kafka_DescribeUserScramCredentials_result_t; +/*! AlterUserScramCredentials result type */ +typedef rd_kafka_event_t rd_kafka_AlterUserScramCredentials_result_t; /** * @brief Get CreateTopics result. @@ -5804,6 +5809,21 @@ rd_kafka_event_DescribeAcls_result(rd_kafka_event_t *rkev); RD_EXPORT const rd_kafka_DeleteAcls_result_t * rd_kafka_event_DeleteAcls_result(rd_kafka_event_t *rkev); +/** + * @brief Get ListConsumerGroupOffsets result. + * + * @returns the result of a ListConsumerGroupOffsets request, or NULL if + * event is of different type. + * + * @remark The lifetime of the returned memory is the same + * as the lifetime of the \p rkev object. + * + * Event types: + * RD_KAFKA_EVENT_LISTCONSUMERGROUPOFFSETS_RESULT + */ +RD_EXPORT const rd_kafka_ListConsumerGroupOffsets_result_t * +rd_kafka_event_ListConsumerGroupOffsets_result(rd_kafka_event_t *rkev); + /** * @brief Get AlterConsumerGroupOffsets result. * @@ -5820,19 +5840,34 @@ RD_EXPORT const rd_kafka_AlterConsumerGroupOffsets_result_t * rd_kafka_event_AlterConsumerGroupOffsets_result(rd_kafka_event_t *rkev); /** - * @brief Get ListConsumerGroupOffsets result. + * @brief Get DescribeUserScramCredentials result. * - * @returns the result of a ListConsumerGroupOffsets request, or NULL if + * @returns the result of a DescribeUserScramCredentials request, or NULL if * event is of different type. * * @remark The lifetime of the returned memory is the same * as the lifetime of the \p rkev object. * * Event types: - * RD_KAFKA_EVENT_LISTCONSUMERGROUPOFFSETS_RESULT + * RD_KAFKA_EVENT_DESCRIBEUSERSCRAMCREDENTIALS_RESULT */ -RD_EXPORT const rd_kafka_ListConsumerGroupOffsets_result_t * -rd_kafka_event_ListConsumerGroupOffsets_result(rd_kafka_event_t *rkev); +RD_EXPORT const rd_kafka_DescribeUserScramCredentials_result_t * +rd_kafka_event_DescribeUserScramCredentials_result(rd_kafka_event_t *rkev); + +/** + * @brief Get AlterUserScramCredentials result. + * + * @returns the result of a AlterUserScramCredentials request, or NULL if + * event is of different type. + * + * @remark The lifetime of the returned memory is the same + * as the lifetime of the \p rkev object. + * + * Event types: + * RD_KAFKA_EVENT_ALTERUSERSCRAMCREDENTIALS_RESULT + */ +RD_EXPORT const rd_kafka_AlterUserScramCredentials_result_t * +rd_kafka_event_AlterUserScramCredentials_result(rd_kafka_event_t *rkev); /** * @brief Poll a queue for an event for max \p timeout_ms. @@ -6739,6 +6774,10 @@ typedef enum rd_kafka_admin_op_t { RD_KAFKA_ADMIN_OP_ALTERCONSUMERGROUPOFFSETS, /** IncrementalAlterConfigs */ RD_KAFKA_ADMIN_OP_INCREMENTALALTERCONFIGS, + /** DescribeUserScramCredentials */ + RD_KAFKA_ADMIN_OP_DESCRIBEUSERSCRAMCREDENTIALS, + /** AlterUserScramCredentials */ + RD_KAFKA_ADMIN_OP_ALTERUSERSCRAMCREDENTIALS, RD_KAFKA_ADMIN_OP__CNT /**< Number of ops defined */ } rd_kafka_admin_op_t; @@ -8575,6 +8614,242 @@ rd_kafka_DeleteConsumerGroupOffsets_result_groups( /**@}*/ + +/** + * @name Admin API - User SCRAM credentials + * @{ + */ + +/** + * @enum rd_kafka_ScramMechanism_t + * @brief Apache Kafka ScramMechanism values. + */ +typedef enum rd_kafka_ScramMechanism_t { + RD_KAFKA_SCRAM_MECHANISM_UNKNOWN = 0, + RD_KAFKA_SCRAM_MECHANISM_SHA_256 = 1, + RD_KAFKA_SCRAM_MECHANISM_SHA_512 = 2, + RD_KAFKA_SCRAM_MECHANISM__CNT +} rd_kafka_ScramMechanism_t; + +/** + * @brief Scram credential info. + * Mechanism and iterations for a SASL/SCRAM + * credential associated with a user. + */ +typedef struct rd_kafka_ScramCredentialInfo_s rd_kafka_ScramCredentialInfo_t; + +/** + * @brief Returns the mechanism of a given ScramCredentialInfo. + */ +RD_EXPORT +rd_kafka_ScramMechanism_t rd_kafka_ScramCredentialInfo_mechanism( + const rd_kafka_ScramCredentialInfo_t *scram_credential_info); + +/** + * @brief Returns the iterations of a given ScramCredentialInfo. + */ +RD_EXPORT +int32_t rd_kafka_ScramCredentialInfo_iterations( + const rd_kafka_ScramCredentialInfo_t *scram_credential_info); + +/** + * @brief Representation of all SASL/SCRAM credentials associated + * with a user that can be retrieved, + * or an error indicating why credentials + * could not be retrieved. + */ +typedef struct rd_kafka_UserScramCredentialsDescription_s + rd_kafka_UserScramCredentialsDescription_t; + +/** + * @brief Returns the username of a UserScramCredentialsDescription. + */ +RD_EXPORT +const char *rd_kafka_UserScramCredentialsDescription_user( + const rd_kafka_UserScramCredentialsDescription_t *description); + +/** + * @brief Returns the error associated with a UserScramCredentialsDescription. + */ +RD_EXPORT +const rd_kafka_error_t *rd_kafka_UserScramCredentialsDescription_error( + const rd_kafka_UserScramCredentialsDescription_t *description); + +/** + * @brief Returns the count of ScramCredentialInfos of a + * UserScramCredentialsDescription. + */ +RD_EXPORT +size_t rd_kafka_UserScramCredentialsDescription_scramcredentialinfo_count( + const rd_kafka_UserScramCredentialsDescription_t *description); + +/** + * @brief Returns the ScramCredentialInfo at index idx of + * UserScramCredentialsDescription. + */ +RD_EXPORT +const rd_kafka_ScramCredentialInfo_t * +rd_kafka_UserScramCredentialsDescription_scramcredentialinfo( + const rd_kafka_UserScramCredentialsDescription_t *description, + size_t idx); + +/** + * @brief Get an array of descriptions from a DescribeUserScramCredentials + * result. + * + * The returned value life-time is the same as the \p result object. + * + * @param result Result to get descriptions from. + * @param cntp is updated to the number of elements in the array. + */ +RD_EXPORT +const rd_kafka_UserScramCredentialsDescription_t ** +rd_kafka_DescribeUserScramCredentials_result_descriptions( + const rd_kafka_DescribeUserScramCredentials_result_t *result, + size_t *cntp); + +/** + * @brief Describe SASL/SCRAM credentials. + * This operation is supported by brokers with version 2.7.0 or higher. + * + * @param rk Client instance. + * @param users The users for which credentials are to be described. + * All users' credentials are described if NULL. + * @param user_cnt Number of elements in \p users array. + * @param options Optional admin options, or NULL for defaults. + * @param rkqu Queue to emit result on. + */ +RD_EXPORT +void rd_kafka_DescribeUserScramCredentials( + rd_kafka_t *rk, + const char **users, + size_t user_cnt, + const rd_kafka_AdminOptions_t *options, + rd_kafka_queue_t *rkqu); + +/** + * @brief A request to alter a user's SASL/SCRAM credentials. + */ +typedef struct rd_kafka_UserScramCredentialAlteration_s + rd_kafka_UserScramCredentialAlteration_t; + +/** + * @brief Allocates a new UserScramCredentialUpsertion given its fields. + * If salt isn't given a 64 B salt is generated using OpenSSL + * RAND_bytes, if available. + * + * @param username The username (not empty). + * @param mechanism SASL/SCRAM mechanism. + * @param iterations SASL/SCRAM iterations. + * @param password Password bytes (not empty). + * @param password_size Size of \p password (greater than 0). + * @param salt Salt bytes (optional). + * @param salt_size Size of \p salt (optional). + * + * @return A newly created instance of rd_kafka_UserScramCredentialAlteration_t. + * Ownership belongs to the caller, use + * rd_kafka_UserScramCredentialAlteration_destroy to destroy. + */ +RD_EXPORT +rd_kafka_UserScramCredentialAlteration_t * +rd_kafka_UserScramCredentialUpsertion_new(const char *username, + rd_kafka_ScramMechanism_t mechanism, + int32_t iterations, + const unsigned char *password, + size_t password_size, + const unsigned char *salt, + size_t salt_size); + +/** + * @brief Allocates a new UserScramCredentialDeletion given its fields. + * + * @param username The username (not empty). + * @param mechanism SASL/SCRAM mechanism. + * @return A newly created instance of rd_kafka_UserScramCredentialAlteration_t. + * Ownership belongs to the caller, use + * rd_kafka_UserScramCredentialAlteration_destroy to destroy. + */ +RD_EXPORT +rd_kafka_UserScramCredentialAlteration_t * +rd_kafka_UserScramCredentialDeletion_new(const char *username, + rd_kafka_ScramMechanism_t mechanism); + + +/** + * @brief Destroys a UserScramCredentialAlteration given its pointer + */ +RD_EXPORT +void rd_kafka_UserScramCredentialAlteration_destroy( + rd_kafka_UserScramCredentialAlteration_t *alteration); + +/** + * @brief Destroys an array of UserScramCredentialAlteration + */ +RD_EXPORT +void rd_kafka_UserScramCredentialAlteration_destroy_array( + rd_kafka_UserScramCredentialAlteration_t **alterations, + size_t alteration_cnt); + +/** + * @brief Result of a single user SCRAM alteration. + */ +typedef struct rd_kafka_AlterUserScramCredentials_result_response_s + rd_kafka_AlterUserScramCredentials_result_response_t; + +/** + * @brief Returns the username for a + * rd_kafka_AlterUserScramCredentials_result_response. + */ +RD_EXPORT +const char *rd_kafka_AlterUserScramCredentials_result_response_user( + const rd_kafka_AlterUserScramCredentials_result_response_t *response); + +/** + * @brief Returns the error of a + * rd_kafka_AlterUserScramCredentials_result_response. + */ +RD_EXPORT +const rd_kafka_error_t * +rd_kafka_AlterUserScramCredentials_result_response_error( + const rd_kafka_AlterUserScramCredentials_result_response_t *response); + +/** + * @brief Get an array of responses from a AlterUserScramCredentials result. + * + * The returned value life-time is the same as the \p result object. + * + * @param result Result to get responses from. + * @param cntp is updated to the number of elements in the array. + */ +RD_EXPORT +const rd_kafka_AlterUserScramCredentials_result_response_t ** +rd_kafka_AlterUserScramCredentials_result_responses( + const rd_kafka_AlterUserScramCredentials_result_t *result, + size_t *cntp); + +/** + * @brief Alter SASL/SCRAM credentials. + * This operation is supported by brokers with version 2.7.0 or higher. + * + * @remark For upsertions to be processed, librdkfka must be build with + * OpenSSL support. It's needed to calculate the HMAC. + * + * @param rk Client instance. + * @param alterations The alterations to be applied. + * @param alteration_cnt Number of elements in \p alterations array. + * @param options Optional admin options, or NULL for defaults. + * @param rkqu Queue to emit result on. + */ +RD_EXPORT +void rd_kafka_AlterUserScramCredentials( + rd_kafka_t *rk, + rd_kafka_UserScramCredentialAlteration_t **alterations, + size_t alteration_cnt, + const rd_kafka_AdminOptions_t *options, + rd_kafka_queue_t *rkqu); + +/**@}*/ + /** * @name Admin API - ACL operations * @{ diff --git a/src/rdkafka_admin.c b/src/rdkafka_admin.c index 6c4419b3a2..dfa38e55d0 100644 --- a/src/rdkafka_admin.c +++ b/src/rdkafka_admin.c @@ -3883,7 +3883,6 @@ rd_kafka_DeleteRecordsResponse_parse(rd_kafka_op_t *rko_req, return reply->rkbuf_err; } - /** * @brief Call when leaders have been queried to progress the DeleteRecords * admin op to its next phase, sending DeleteRecords to partition @@ -5089,6 +5088,796 @@ void rd_kafka_DescribeAcls(rd_kafka_t *rk, rd_kafka_q_enq(rk->rk_ops, rko); } +struct rd_kafka_ScramCredentialInfo_s { + rd_kafka_ScramMechanism_t mechanism; + int32_t iterations; +}; + +rd_kafka_ScramMechanism_t rd_kafka_ScramCredentialInfo_mechanism( + const rd_kafka_ScramCredentialInfo_t *scram_credential_info) { + return scram_credential_info->mechanism; +} + +int32_t rd_kafka_ScramCredentialInfo_iterations( + const rd_kafka_ScramCredentialInfo_t *scram_credential_info) { + return scram_credential_info->iterations; +} + +struct rd_kafka_UserScramCredentialsDescription_s { + char *user; + rd_kafka_error_t *error; + size_t credential_info_cnt; + rd_kafka_ScramCredentialInfo_t *credential_infos; +}; + +rd_kafka_UserScramCredentialsDescription_t * +rd_kafka_UserScramCredentialsDescription_new(const char *username, + size_t num_credentials) { + rd_kafka_UserScramCredentialsDescription_t *description; + description = rd_calloc(1, sizeof(*description)); + description->user = rd_strdup(username); + description->error = NULL; + description->credential_info_cnt = num_credentials; + description->credential_infos = NULL; + if (num_credentials > 0) { + rd_kafka_ScramCredentialInfo_t *credentialinfo; + description->credential_infos = + rd_calloc(num_credentials, sizeof(*credentialinfo)); + } + return description; +} + +void rd_kafka_UserScramCredentialsDescription_destroy( + rd_kafka_UserScramCredentialsDescription_t *description) { + if (!description) + return; + rd_free(description->user); + rd_kafka_error_destroy(description->error); + if (description->credential_infos) + rd_free(description->credential_infos); + rd_free(description); +} + +void rd_kafka_UserScramCredentialsDescription_destroy_free(void *description) { + rd_kafka_UserScramCredentialsDescription_destroy(description); +} + +void rd_kafka_UserScramCredentailsDescription_set_error( + rd_kafka_UserScramCredentialsDescription_t *description, + rd_kafka_resp_err_t errorcode, + const char *err) { + rd_kafka_error_destroy(description->error); + description->error = rd_kafka_error_new(errorcode, "%s", err); +} + +const char *rd_kafka_UserScramCredentialsDescription_user( + const rd_kafka_UserScramCredentialsDescription_t *description) { + return description->user; +} + +const rd_kafka_error_t *rd_kafka_UserScramCredentialsDescription_error( + const rd_kafka_UserScramCredentialsDescription_t *description) { + return description->error; +} + +size_t rd_kafka_UserScramCredentialsDescription_scramcredentialinfo_count( + const rd_kafka_UserScramCredentialsDescription_t *description) { + return description->credential_info_cnt; +} + +const rd_kafka_ScramCredentialInfo_t * +rd_kafka_UserScramCredentialsDescription_scramcredentialinfo( + const rd_kafka_UserScramCredentialsDescription_t *description, + size_t idx) { + return &description->credential_infos[idx]; +} + +const rd_kafka_UserScramCredentialsDescription_t ** +rd_kafka_DescribeUserScramCredentials_result_descriptions( + const rd_kafka_DescribeUserScramCredentials_result_t *result, + size_t *cntp) { + *cntp = rd_list_cnt(&result->rko_u.admin_result.results); + return (const rd_kafka_UserScramCredentialsDescription_t **) + result->rko_u.admin_result.results.rl_elems; +} + +rd_kafka_resp_err_t +rd_kafka_DescribeUserScramCredentialsRequest(rd_kafka_broker_t *rkb, + const rd_list_t *userlist, + rd_kafka_AdminOptions_t *options, + char *errstr, + size_t errstr_size, + rd_kafka_replyq_t replyq, + rd_kafka_resp_cb_t *resp_cb, + void *opaque) { + rd_kafka_buf_t *rkbuf; + int16_t ApiVersion = 0; + int features; + size_t i; + size_t num_users; + + ApiVersion = rd_kafka_broker_ApiVersion_supported( + rkb, RD_KAFKAP_DescribeUserScramCredentials, 0, 0, &features); + if (ApiVersion == -1) { + rd_snprintf( + errstr, errstr_size, + "DescribeUserScramCredentials API (KIP-554) not supported " + "by broker"); + return RD_KAFKA_RESP_ERR__UNSUPPORTED_FEATURE; + } + + num_users = rd_list_cnt(userlist); + + rkbuf = rd_kafka_buf_new_flexver_request( + rkb, RD_KAFKAP_DescribeUserScramCredentials, 1, num_users * 25, + rd_true); + /* #Users */ + rd_kafka_buf_write_arraycnt(rkbuf, num_users); + for (i = 0; i < num_users; i++) { + rd_kafkap_str_t *user = rd_list_elem(userlist, i); + /* Name */ + rd_kafka_buf_write_str(rkbuf, user->str, user->len); + rd_kafka_buf_write_tags(rkbuf); + } + rd_kafka_buf_ApiVersion_set(rkbuf, ApiVersion, 0); + /* Last Tag buffer included automatically*/ + rd_kafka_broker_buf_enq_replyq(rkb, rkbuf, replyq, resp_cb, opaque); + return RD_KAFKA_RESP_ERR_NO_ERROR; +} + +static rd_kafka_resp_err_t +rd_kafka_DescribeUserScramCredentialsResponse_parse(rd_kafka_op_t *rko_req, + rd_kafka_op_t **rko_resultp, + rd_kafka_buf_t *reply, + char *errstr, + size_t errstr_size) { + const int log_decode_errors = LOG_ERR; + rd_kafka_op_t *rko_result = NULL; + int32_t num_users; + int16_t ErrorCode; + rd_kafkap_str_t ErrorMessage = RD_KAFKAP_STR_INITIALIZER; + int32_t i; + + rko_result = rd_kafka_admin_result_new(rko_req); + + /* ThrottleTimeMs */ + rd_kafka_buf_read_throttle_time(reply); + + /* ErrorCode */ + rd_kafka_buf_read_i16(reply, &ErrorCode); + rko_result->rko_err = ErrorCode; /*Request Level Error Code */ + + /* ErrorMessage */ + rd_kafka_buf_read_str(reply, &ErrorMessage); + if (ErrorCode) { + if (RD_KAFKAP_STR_LEN(&ErrorMessage) == 0) + errstr = (char *)rd_kafka_err2str(ErrorCode); + else + RD_KAFKAP_STR_DUPA(&errstr, &ErrorMessage); + rko_result->rko_u.admin_result.errstr = + errstr; /* Request Level Error string*/ + } + + /* #Results */ + rd_kafka_buf_read_arraycnt(reply, &num_users, 10000); + rd_list_init(&rko_result->rko_u.admin_result.results, num_users, + rd_kafka_UserScramCredentialsDescription_destroy_free); + + for (i = 0; i < num_users; i++) { + rd_kafkap_str_t User; + int16_t ErrorCode; + rd_kafkap_str_t ErrorMessage = RD_KAFKAP_STR_INITIALIZER; + size_t itr; + /* User */ + rd_kafka_buf_read_str(reply, &User); + /* ErrorCode */ + rd_kafka_buf_read_i16(reply, &ErrorCode); + /* ErrorMessage */ + rd_kafka_buf_read_str(reply, &ErrorMessage); + + int32_t num_credentials; + /* #CredentialInfos */ + rd_kafka_buf_read_arraycnt(reply, &num_credentials, 10000); + rd_kafka_UserScramCredentialsDescription_t *description = + rd_kafka_UserScramCredentialsDescription_new( + User.str, num_credentials); + rd_kafka_UserScramCredentailsDescription_set_error( + description, ErrorCode, ErrorMessage.str); + for (itr = 0; itr < (size_t)num_credentials; itr++) { + int8_t Mechanism; + int32_t Iterations; + /* Mechanism */ + rd_kafka_buf_read_i8(reply, &Mechanism); + /* Iterations */ + rd_kafka_buf_read_i32(reply, &Iterations); + rd_kafka_buf_skip_tags(reply); + rd_kafka_ScramCredentialInfo_t *scram_credential = + &description->credential_infos[itr]; + scram_credential->mechanism = Mechanism; + scram_credential->iterations = Iterations; + } + rd_kafka_buf_skip_tags(reply); + rd_list_add(&rko_result->rko_u.admin_result.results, + description); + } + *rko_resultp = rko_result; + + return RD_KAFKA_RESP_ERR_NO_ERROR; + +err_parse: + if (rko_result) + rd_kafka_op_destroy(rko_result); + + rd_snprintf( + errstr, errstr_size, + "DescribeUserScramCredentials response protocol parse failure: %s", + rd_kafka_err2str(reply->rkbuf_err)); + + return reply->rkbuf_err; +} + +void rd_kafka_DescribeUserScramCredentials( + rd_kafka_t *rk, + const char **users, + size_t user_cnt, + const rd_kafka_AdminOptions_t *options, + rd_kafka_queue_t *rkqu) { + + rd_kafka_op_t *rko; + size_t i; + rd_list_t *userlist = NULL; + + static const struct rd_kafka_admin_worker_cbs cbs = { + rd_kafka_DescribeUserScramCredentialsRequest, + rd_kafka_DescribeUserScramCredentialsResponse_parse, + }; + + rko = rd_kafka_admin_request_op_new( + rk, RD_KAFKA_OP_DESCRIBEUSERSCRAMCREDENTIALS, + RD_KAFKA_EVENT_DESCRIBEUSERSCRAMCREDENTIALS_RESULT, &cbs, options, + rkqu->rkqu_q); + + /* Check empty strings */ + for (i = 0; i < user_cnt; i++) { + if (!*users[i]) { + rd_kafka_admin_result_fail( + rko, RD_KAFKA_RESP_ERR__INVALID_ARG, + "Empty users aren't allowed, " + "index %" PRIusz, + i); + goto err; + } + } + + /* Check Duplicates */ + if (user_cnt > 1) { + userlist = rd_list_new(user_cnt, rd_free); + for (i = 0; i < user_cnt; i++) { + rd_list_add(userlist, rd_strdup(users[i])); + } + rd_list_sort(userlist, rd_strcmp2); + if (rd_list_find_duplicate(userlist, rd_strcmp2)) { + rd_kafka_admin_result_fail( + rko, RD_KAFKA_RESP_ERR__INVALID_ARG, + "Duplicate users aren't allowed " + "in the same request"); + goto err; + } + rd_list_destroy(userlist); + } + + rd_list_init(&rko->rko_u.admin_request.args, user_cnt, rd_free); + for (i = 0; i < user_cnt; i++) { + rd_list_add(&rko->rko_u.admin_request.args, + rd_kafkap_str_new(users[i], -1)); + } + rd_kafka_q_enq(rk->rk_ops, rko); + return; +err: + RD_IF_FREE(userlist, rd_list_destroy); + rd_kafka_admin_common_worker_destroy(rk, rko, rd_true /*destroy*/); +} + +/** + * @enum rd_kafka_UserScramCredentialAlteration_type_t + * @brief Types of user SCRAM alterations. + */ +typedef enum rd_kafka_UserScramCredentialAlteration_type_s { + RD_KAFKA_USER_SCRAM_CREDENTIAL_ALTERATION_TYPE_UPSERT = 0, + RD_KAFKA_USER_SCRAM_CREDENTIAL_ALTERATION_TYPE_DELETE = 1, + RD_KAFKA_USER_SCRAM_CREDENTIAL_ALTERATION_TYPE__CNT +} rd_kafka_UserScramCredentialAlteration_type_t; + +struct rd_kafka_UserScramCredentialAlteration_s { + char *user; + rd_kafka_UserScramCredentialAlteration_type_t alteration_type; + union { + struct { + rd_kafka_ScramCredentialInfo_t credential_info; + rd_kafkap_bytes_t *salt; + rd_kafkap_bytes_t *password; + } upsertion; + struct { + rd_kafka_ScramMechanism_t mechanism; + } deletion; + } alteration; +}; + +rd_kafka_UserScramCredentialAlteration_t * +rd_kafka_UserScramCredentialUpsertion_new(const char *username, + rd_kafka_ScramMechanism_t mechanism, + int32_t iterations, + const unsigned char *password, + size_t password_size, + const unsigned char *salt, + size_t salt_size) { + rd_kafka_UserScramCredentialAlteration_t *alteration; + alteration = rd_calloc(1, sizeof(*alteration)); + alteration->user = rd_strdup(username); + alteration->alteration_type = + RD_KAFKA_USER_SCRAM_CREDENTIAL_ALTERATION_TYPE_UPSERT; + alteration->alteration.upsertion.credential_info.mechanism = mechanism; + alteration->alteration.upsertion.credential_info.iterations = + iterations; + + alteration->alteration.upsertion.password = + rd_kafkap_bytes_new(password, password_size); + if (salt_size != 0) { + alteration->alteration.upsertion.salt = + rd_kafkap_bytes_new(salt, salt_size); + } else { +#if WITH_SSL + unsigned char random_salt[64]; + if (RAND_priv_bytes(random_salt, sizeof(random_salt)) == 1) { + alteration->alteration.upsertion.salt = + rd_kafkap_bytes_new(random_salt, + sizeof(random_salt)); + } +#endif + } + return alteration; +} + +rd_kafka_UserScramCredentialAlteration_t * +rd_kafka_UserScramCredentialDeletion_new(const char *username, + rd_kafka_ScramMechanism_t mechanism) { + rd_kafka_UserScramCredentialAlteration_t *alteration; + alteration = rd_calloc(1, sizeof(*alteration)); + alteration->user = rd_strdup(username); + alteration->alteration_type = + RD_KAFKA_USER_SCRAM_CREDENTIAL_ALTERATION_TYPE_DELETE; + alteration->alteration.deletion.mechanism = mechanism; + return alteration; +} + +void rd_kafka_UserScramCredentialAlteration_destroy( + rd_kafka_UserScramCredentialAlteration_t *alteration) { + if (!alteration) + return; + rd_free(alteration->user); + if (alteration->alteration_type == + RD_KAFKA_USER_SCRAM_CREDENTIAL_ALTERATION_TYPE_UPSERT) { + rd_kafkap_bytes_destroy(alteration->alteration.upsertion.salt); + rd_kafkap_bytes_destroy( + alteration->alteration.upsertion.password); + } + rd_free(alteration); +} + +void rd_kafka_UserScramCredentialAlteration_destroy_free(void *alteration) { + rd_kafka_UserScramCredentialAlteration_destroy(alteration); +} + +void rd_kafka_UserScramCredentialAlteration_destroy_array( + rd_kafka_UserScramCredentialAlteration_t **alterations, + size_t alteration_cnt) { + size_t i; + for (i = 0; i < alteration_cnt; i++) + rd_kafka_UserScramCredentialAlteration_destroy(alterations[i]); +} + +static rd_kafka_UserScramCredentialAlteration_t * +rd_kafka_UserScramCredentialAlteration_copy( + const rd_kafka_UserScramCredentialAlteration_t *alteration) { + rd_kafka_UserScramCredentialAlteration_t *copied_alteration = + rd_calloc(1, sizeof(*alteration)); + copied_alteration->user = rd_strdup(alteration->user); + copied_alteration->alteration_type = alteration->alteration_type; + + if (alteration->alteration_type == + RD_KAFKA_USER_SCRAM_CREDENTIAL_ALTERATION_TYPE_UPSERT /*Upsert*/) { + copied_alteration->alteration.upsertion.salt = + rd_kafkap_bytes_copy(alteration->alteration.upsertion.salt); + copied_alteration->alteration.upsertion.password = + rd_kafkap_bytes_copy( + alteration->alteration.upsertion.password); + copied_alteration->alteration.upsertion.credential_info + .mechanism = + alteration->alteration.upsertion.credential_info.mechanism; + copied_alteration->alteration.upsertion.credential_info + .iterations = + alteration->alteration.upsertion.credential_info.iterations; + } else if ( + alteration->alteration_type == + RD_KAFKA_USER_SCRAM_CREDENTIAL_ALTERATION_TYPE_DELETE /*Delete*/) { + copied_alteration->alteration.deletion.mechanism = + alteration->alteration.deletion.mechanism; + } + + return copied_alteration; +} + +struct rd_kafka_AlterUserScramCredentials_result_response_s { + char *user; + rd_kafka_error_t *error; +}; + +rd_kafka_AlterUserScramCredentials_result_response_t * +rd_kafka_AlterUserScramCredentials_result_response_new(const char *username) { + rd_kafka_AlterUserScramCredentials_result_response_t *response; + response = rd_calloc(1, sizeof(*response)); + response->user = rd_strdup(username); + response->error = NULL; + return response; +} + +void rd_kafka_AlterUserScramCredentials_result_response_destroy( + rd_kafka_AlterUserScramCredentials_result_response_t *response) { + if (response->user) + rd_free(response->user); + rd_kafka_error_destroy(response->error); + rd_free(response); +} + +void rd_kafka_AlterUserScramCredentials_result_response_destroy_free( + void *response) { + rd_kafka_AlterUserScramCredentials_result_response_destroy(response); +} + +void rd_kafka_AlterUserScramCredentials_result_response_set_error( + rd_kafka_AlterUserScramCredentials_result_response_t *response, + rd_kafka_resp_err_t errorcode, + const char *errstr) { + rd_kafka_error_destroy(response->error); + response->error = rd_kafka_error_new(errorcode, "%s", errstr); +} + +const char *rd_kafka_AlterUserScramCredentials_result_response_user( + const rd_kafka_AlterUserScramCredentials_result_response_t *response) { + return response->user; +} + +const rd_kafka_error_t * +rd_kafka_AlterUserScramCredentials_result_response_error( + const rd_kafka_AlterUserScramCredentials_result_response_t *response) { + return response->error; +} + +const rd_kafka_AlterUserScramCredentials_result_response_t ** +rd_kafka_AlterUserScramCredentials_result_responses( + const rd_kafka_AlterUserScramCredentials_result_t *result, + size_t *cntp) { + *cntp = rd_list_cnt(&result->rko_u.admin_result.results); + return (const rd_kafka_AlterUserScramCredentials_result_response_t **) + result->rko_u.admin_result.results.rl_elems; +} + + +#if WITH_SSL +static rd_kafkap_bytes_t * +rd_kafka_AlterUserScramCredentialsRequest_salted_password( + rd_kafka_broker_t *rkb, + rd_kafkap_bytes_t *salt, + rd_kafkap_bytes_t *password, + rd_kafka_ScramMechanism_t mechanism, + int32_t iterations) { + rd_chariov_t saltedpassword_chariov = {.ptr = + rd_alloca(EVP_MAX_MD_SIZE)}; + + rd_chariov_t salt_chariov; + salt_chariov.ptr = (char *)salt->data; + salt_chariov.size = RD_KAFKAP_BYTES_LEN(salt); + + rd_chariov_t password_chariov; + password_chariov.ptr = (char *)password->data; + password_chariov.size = RD_KAFKAP_BYTES_LEN(password); + + const EVP_MD *evp = NULL; + if (mechanism == RD_KAFKA_SCRAM_MECHANISM_SHA_256) + evp = EVP_sha256(); + else if (mechanism == RD_KAFKA_SCRAM_MECHANISM_SHA_512) + evp = EVP_sha512(); + rd_assert(evp != NULL); + + rd_kafka_ssl_hmac(rkb, evp, &password_chariov, &salt_chariov, + iterations, &saltedpassword_chariov); + + return rd_kafkap_bytes_new( + (const unsigned char *)saltedpassword_chariov.ptr, + saltedpassword_chariov.size); +} +#endif + +rd_kafka_resp_err_t rd_kafka_AlterUserScramCredentialsRequest( + rd_kafka_broker_t *rkb, + const rd_list_t *user_scram_credential_alterations, + rd_kafka_AdminOptions_t *options, + char *errstr, + size_t errstr_size, + rd_kafka_replyq_t replyq, + rd_kafka_resp_cb_t *resp_cb, + void *opaque) { + + rd_kafka_buf_t *rkbuf; + int16_t ApiVersion = 0; + int features; + size_t num_deletions = 0; + size_t i; + size_t num_alterations; + size_t of_deletions; + ApiVersion = rd_kafka_broker_ApiVersion_supported( + rkb, RD_KAFKAP_DescribeUserScramCredentials, 0, 0, &features); + if (ApiVersion == -1) { + rd_snprintf( + errstr, errstr_size, + "AlterUserScramCredentials API (KIP-554) not supported " + "by broker"); + return RD_KAFKA_RESP_ERR__UNSUPPORTED_FEATURE; + } + + num_alterations = rd_list_cnt(user_scram_credential_alterations); + + rkbuf = rd_kafka_buf_new_flexver_request( + rkb, RD_KAFKAP_AlterUserScramCredentials, 1, num_alterations * 100, + rd_true); + + /* Deletion scram requests*/ + + /* #Deletions */ + of_deletions = rd_kafka_buf_write_arraycnt_pos(rkbuf); + + for (i = 0; i < num_alterations; i++) { + rd_kafka_UserScramCredentialAlteration_t *alteration = + rd_list_elem(user_scram_credential_alterations, i); + if (alteration->alteration_type != + RD_KAFKA_USER_SCRAM_CREDENTIAL_ALTERATION_TYPE_DELETE) + continue; + + num_deletions++; + /* Name */ + rd_kafka_buf_write_str(rkbuf, alteration->user, + strlen(alteration->user)); + /* Mechanism */ + rd_kafka_buf_write_i8( + rkbuf, alteration->alteration.deletion.mechanism); + rd_kafka_buf_write_tags(rkbuf); + } + rd_kafka_buf_finalize_arraycnt(rkbuf, of_deletions, num_deletions); + + /* Upsertion scram request*/ + + /* #Upsertions */ + rd_kafka_buf_write_arraycnt(rkbuf, num_alterations - num_deletions); + for (i = 0; i < num_alterations; i++) { + rd_kafka_UserScramCredentialAlteration_t *alteration = + rd_list_elem(user_scram_credential_alterations, i); + if (alteration->alteration_type != + RD_KAFKA_USER_SCRAM_CREDENTIAL_ALTERATION_TYPE_UPSERT) + continue; + +#if !WITH_SSL + rd_assert(!*"OpenSSL is required for upsertions"); +#else + char *user = alteration->user; + size_t usersize = strlen(user); + rd_kafka_ScramMechanism_t mechanism = + alteration->alteration.upsertion.credential_info.mechanism; + int32_t iterations = + alteration->alteration.upsertion.credential_info.iterations; + /* Name */ + rd_kafka_buf_write_str(rkbuf, user, usersize); + + /* Mechanism */ + rd_kafka_buf_write_i8(rkbuf, mechanism); + + /* Iterations */ + rd_kafka_buf_write_i32(rkbuf, iterations); + + /* Salt */ + rd_kafka_buf_write_kbytes( + rkbuf, alteration->alteration.upsertion.salt); + + rd_kafkap_bytes_t *password_bytes = + rd_kafka_AlterUserScramCredentialsRequest_salted_password( + rkb, alteration->alteration.upsertion.salt, + alteration->alteration.upsertion.password, mechanism, + iterations); + + /* SaltedPassword */ + rd_kafka_buf_write_kbytes(rkbuf, password_bytes); + rd_kafkap_bytes_destroy(password_bytes); + rd_kafka_buf_write_tags(rkbuf); +#endif + } + + rd_kafka_buf_write_tags(rkbuf); + rd_kafka_buf_ApiVersion_set(rkbuf, ApiVersion, 0); + rd_kafka_broker_buf_enq_replyq(rkb, rkbuf, replyq, resp_cb, opaque); + return RD_KAFKA_RESP_ERR_NO_ERROR; +} + +rd_kafka_resp_err_t +rd_kafka_AlterUserScramCredentialsResponse_parse(rd_kafka_op_t *rko_req, + rd_kafka_op_t **rko_resultp, + rd_kafka_buf_t *reply, + char *errstr, + size_t errstr_size) { + const int log_decode_errors = LOG_ERR; + rd_kafka_op_t *rko_result = NULL; + int32_t num_results; + int32_t i; + + rko_result = rd_kafka_admin_result_new(rko_req); + + /* ThrottleTimeMs */ + rd_kafka_buf_read_throttle_time(reply); + + /* #Results */ + rd_kafka_buf_read_arraycnt(reply, &num_results, 10000); + + rd_list_init( + &rko_result->rko_u.admin_result.results, num_results, + rd_kafka_AlterUserScramCredentials_result_response_destroy_free); + for (i = 0; i < num_results; i++) { + rd_kafkap_str_t User; + int16_t ErrorCode; + rd_kafkap_str_t ErrorMessage = RD_KAFKAP_STR_INITIALIZER; + + /* User */ + rd_kafka_buf_read_str(reply, &User); + + /* ErrorCode */ + rd_kafka_buf_read_i16(reply, &ErrorCode); + + /* ErrorMessage */ + rd_kafka_buf_read_str(reply, &ErrorMessage); + + rd_kafka_buf_skip_tags(reply); + + rd_kafka_AlterUserScramCredentials_result_response_t *response = + rd_kafka_AlterUserScramCredentials_result_response_new( + User.str); + rd_kafka_AlterUserScramCredentials_result_response_set_error( + response, ErrorCode, ErrorMessage.str); + rd_list_add(&rko_result->rko_u.admin_result.results, response); + } + *rko_resultp = rko_result; + + return RD_KAFKA_RESP_ERR_NO_ERROR; + +err_parse: + if (rko_result) + rd_kafka_op_destroy(rko_result); + + rd_snprintf( + errstr, errstr_size, + "AlterUserScramCredentials response protocol parse failure: %s", + rd_kafka_err2str(reply->rkbuf_err)); + + return reply->rkbuf_err; +} + +void rd_kafka_AlterUserScramCredentials( + rd_kafka_t *rk, + rd_kafka_UserScramCredentialAlteration_t **alterations, + size_t alteration_cnt, + const rd_kafka_AdminOptions_t *options, + rd_kafka_queue_t *rkqu) { + + rd_kafka_op_t *rko; + size_t i; + + static const struct rd_kafka_admin_worker_cbs cbs = { + rd_kafka_AlterUserScramCredentialsRequest, + rd_kafka_AlterUserScramCredentialsResponse_parse, + }; + + rko = rd_kafka_admin_request_op_new( + rk, RD_KAFKA_OP_ALTERUSERSCRAMCREDENTIALS, + RD_KAFKA_EVENT_ALTERUSERSCRAMCREDENTIALS_RESULT, &cbs, options, + rkqu->rkqu_q); + + if (alteration_cnt > 0) { + const char *errstr = NULL; + for (i = 0; i < alteration_cnt; i++) { + rd_bool_t is_upsert = + alterations[i]->alteration_type == + RD_KAFKA_USER_SCRAM_CREDENTIAL_ALTERATION_TYPE_UPSERT; + rd_bool_t is_delete = + alterations[i]->alteration_type == + RD_KAFKA_USER_SCRAM_CREDENTIAL_ALTERATION_TYPE_DELETE; + + if ((is_upsert || is_delete) && + alterations[i] + ->alteration.upsertion.credential_info + .mechanism == + RD_KAFKA_SCRAM_MECHANISM_UNKNOWN) { + errstr = + "SCRAM mechanism must be specified at " + "index %" PRIusz; + break; + } + + + if (!alterations[i]->user || !*alterations[i]->user) { + errstr = "Empty user at index %" PRIusz; + break; + } + + if (is_upsert) { +#if !WITH_SSL + errstr = + "OpenSSL required for upsertion at index " + "%" PRIusz; + break; +#endif + if (RD_KAFKAP_BYTES_LEN( + alterations[i] + ->alteration.upsertion.password) == + 0) { + errstr = + "Empty password at index %" PRIusz; + break; + } + + if (!alterations[i] + ->alteration.upsertion.salt || + RD_KAFKAP_BYTES_LEN( + alterations[i] + ->alteration.upsertion.salt) == 0) { + errstr = "Empty salt at index %" PRIusz; + break; + } + + if (alterations[i] + ->alteration.upsertion.credential_info + .iterations <= 0) { + errstr = + "Non-positive iterations at index " + "%" PRIusz; + break; + } + } + } + + if (errstr) { + rd_kafka_admin_result_fail( + rko, RD_KAFKA_RESP_ERR__INVALID_ARG, errstr, i); + rd_kafka_admin_common_worker_destroy( + rk, rko, rd_true /*destroy*/); + return; + } + } else { + rd_kafka_admin_result_fail( + rko, RD_KAFKA_RESP_ERR__INVALID_ARG, + "At least one alteration is required"); + rd_kafka_admin_common_worker_destroy(rk, rko, + rd_true /*destroy*/); + return; + } + + rd_list_init(&rko->rko_u.admin_request.args, alteration_cnt, + rd_kafka_UserScramCredentialAlteration_destroy_free); + + for (i = 0; i < alteration_cnt; i++) { + rd_list_add(&rko->rko_u.admin_request.args, + rd_kafka_UserScramCredentialAlteration_copy( + alterations[i])); + } + rd_kafka_q_enq(rk->rk_ops, rko); + return; +} + /** * @brief Get an array of rd_kafka_AclBinding_t from a DescribeAcls result. * @@ -5586,7 +6375,6 @@ void rd_kafka_AlterConsumerGroupOffsets( rd_kafka_admin_common_worker_destroy(rk, rko, rd_true /*destroy*/); } - /** * @brief Get an array of group results from a AlterGroups result. * @@ -6713,8 +7501,8 @@ rd_kafka_DescribeConsumerGroupsResponse_parse(rd_kafka_op_t *rko_req, } rd_kafka_buf_read_str(reply, &ClientId); rd_kafka_buf_read_str(reply, &ClientHost); - rd_kafka_buf_read_bytes(reply, &MemberMetadata); - rd_kafka_buf_read_bytes(reply, &MemberAssignment); + rd_kafka_buf_read_kbytes(reply, &MemberMetadata); + rd_kafka_buf_read_kbytes(reply, &MemberAssignment); if (error != NULL) continue; diff --git a/src/rdkafka_admin.h b/src/rdkafka_admin.h index 380f49dd0c..05fbf8db97 100644 --- a/src/rdkafka_admin.h +++ b/src/rdkafka_admin.h @@ -34,8 +34,15 @@ #include "rdmap.h" #include "rdkafka_error.h" #include "rdkafka_confval.h" - - +#if WITH_SSL +typedef struct rd_kafka_broker_s rd_kafka_broker_t; +extern int rd_kafka_ssl_hmac(rd_kafka_broker_t *rkb, + const EVP_MD *evp, + const rd_chariov_t *in, + const rd_chariov_t *salt, + int itcnt, + rd_chariov_t *out); +#endif /** * @brief Common AdminOptions type used for all admin APIs. diff --git a/src/rdkafka_buf.h b/src/rdkafka_buf.h index cedcf22919..7845beff90 100644 --- a/src/rdkafka_buf.h +++ b/src/rdkafka_buf.h @@ -711,12 +711,21 @@ struct rd_kafka_buf_s { /* rd_kafka_buf_t */ rd_kafka_buf_skip(rkbuf, RD_KAFKAP_STR_LEN0(_slen)); \ } while (0) -/* Read Kafka Bytes representation (4+N). - * The 'kbytes' will be updated to point to rkbuf data */ -#define rd_kafka_buf_read_bytes(rkbuf, kbytes) \ +/** + * Read Kafka COMPACT_BYTES representation (VARINT+N) or + * standard BYTES representation(4+N). + * The 'kbytes' will be updated to point to rkbuf data. + */ +#define rd_kafka_buf_read_kbytes(rkbuf, kbytes) \ do { \ - int _klen; \ - rd_kafka_buf_read_i32a(rkbuf, _klen); \ + int32_t _klen; \ + if (!(rkbuf->rkbuf_flags & RD_KAFKA_OP_F_FLEXVER)) { \ + rd_kafka_buf_read_i32a(rkbuf, _klen); \ + } else { \ + uint64_t _uva; \ + rd_kafka_buf_read_uvarint(rkbuf, &_uva); \ + _klen = ((int32_t)_uva) - 1; \ + } \ (kbytes)->len = _klen; \ if (RD_KAFKAP_BYTES_IS_NULL(kbytes)) { \ (kbytes)->data = NULL; \ @@ -728,7 +737,6 @@ struct rd_kafka_buf_s { /* rd_kafka_buf_t */ rd_kafka_buf_check_len(rkbuf, _klen); \ } while (0) - /** * @brief Read \p size bytes from buffer, setting \p *ptr to the start * of the memory region. @@ -745,7 +753,7 @@ struct rd_kafka_buf_s { /* rd_kafka_buf_t */ /** * @brief Read varint-lengted Kafka Bytes representation */ -#define rd_kafka_buf_read_bytes_varint(rkbuf, kbytes) \ +#define rd_kafka_buf_read_kbytes_varint(rkbuf, kbytes) \ do { \ int64_t _len2; \ size_t _r = \ @@ -1304,30 +1312,40 @@ static RD_INLINE void rd_kafka_buf_push_kstr(rd_kafka_buf_t *rkbuf, static RD_INLINE size_t rd_kafka_buf_write_kbytes(rd_kafka_buf_t *rkbuf, const rd_kafkap_bytes_t *kbytes) { - size_t len; + size_t len, r; - if (!kbytes || RD_KAFKAP_BYTES_IS_NULL(kbytes)) - return rd_kafka_buf_write_i32(rkbuf, -1); + if (!(rkbuf->rkbuf_flags & RD_KAFKA_OP_F_FLEXVER)) { + if (!kbytes || RD_KAFKAP_BYTES_IS_NULL(kbytes)) + return rd_kafka_buf_write_i32(rkbuf, -1); - if (RD_KAFKAP_BYTES_IS_SERIALIZED(kbytes)) - return rd_kafka_buf_write(rkbuf, RD_KAFKAP_BYTES_SER(kbytes), - RD_KAFKAP_BYTES_SIZE(kbytes)); + if (RD_KAFKAP_BYTES_IS_SERIALIZED(kbytes)) + return rd_kafka_buf_write(rkbuf, + RD_KAFKAP_BYTES_SER(kbytes), + RD_KAFKAP_BYTES_SIZE(kbytes)); - len = RD_KAFKAP_BYTES_LEN(kbytes); - rd_kafka_buf_write_i32(rkbuf, (int32_t)len); - rd_kafka_buf_write(rkbuf, kbytes->data, len); + len = RD_KAFKAP_BYTES_LEN(kbytes); + rd_kafka_buf_write_i32(rkbuf, (int32_t)len); + rd_kafka_buf_write(rkbuf, kbytes->data, len); - return 4 + len; -} + return 4 + len; + } -/** - * Push (i.e., no copy) Kafka bytes to buffer iovec - */ -static RD_INLINE void -rd_kafka_buf_push_kbytes(rd_kafka_buf_t *rkbuf, - const rd_kafkap_bytes_t *kbytes) { - rd_kafka_buf_push(rkbuf, RD_KAFKAP_BYTES_SER(kbytes), - RD_KAFKAP_BYTES_SIZE(kbytes), NULL); + /* COMPACT_BYTES lengths are: + * 0 = NULL, + * 1 = empty + * N.. = length + 1 + */ + if (!kbytes) + len = 0; + else + len = kbytes->len + 1; + + r = rd_kafka_buf_write_uvarint(rkbuf, (uint64_t)len); + if (len > 1) { + rd_kafka_buf_write(rkbuf, kbytes->data, len - 1); + r += len - 1; + } + return r; } /** @@ -1410,5 +1428,4 @@ void rd_kafka_buf_set_maker(rd_kafka_buf_t *rkbuf, rd_kafka_make_req_cb_t *make_cb, void *make_opaque, void (*free_make_opaque_cb)(void *make_opaque)); - #endif /* _RDKAFKA_BUF_H_ */ diff --git a/src/rdkafka_cgrp.c b/src/rdkafka_cgrp.c index 8d150fc59b..9926f8632c 100644 --- a/src/rdkafka_cgrp.c +++ b/src/rdkafka_cgrp.c @@ -1512,7 +1512,7 @@ static void rd_kafka_cgrp_handle_SyncGroup_memberstate( if (!(assignment = rd_kafka_buf_read_topic_partitions(rkbuf, 0, fields))) goto err_parse; - rd_kafka_buf_read_bytes(rkbuf, &UserData); + rd_kafka_buf_read_kbytes(rkbuf, &UserData); done: rd_kafka_cgrp_update_session_timeout(rkcg, rd_true /*reset timeout*/); @@ -1617,7 +1617,7 @@ static void rd_kafka_cgrp_handle_SyncGroup(rd_kafka_t *rk, rd_kafka_buf_read_throttle_time(rkbuf); rd_kafka_buf_read_i16(rkbuf, &ErrorCode); - rd_kafka_buf_read_bytes(rkbuf, &MemberState); + rd_kafka_buf_read_kbytes(rkbuf, &MemberState); err: actions = rd_kafka_err_action(rkb, ErrorCode, request, @@ -1803,7 +1803,7 @@ static int rd_kafka_group_MemberMetadata_consumer_read( rkgm->rkgm_subscription, topic_name, RD_KAFKA_PARTITION_UA); } - rd_kafka_buf_read_bytes(rkbuf, &UserData); + rd_kafka_buf_read_kbytes(rkbuf, &UserData); rkgm->rkgm_userdata = rd_kafkap_bytes_copy(&UserData); const rd_kafka_topic_partition_field_t fields[] = { @@ -1990,7 +1990,7 @@ static void rd_kafka_cgrp_handle_JoinGroup(rd_kafka_t *rk, rd_kafka_buf_read_str(rkbuf, &MemberId); if (request->rkbuf_reqhdr.ApiVersion >= 5) rd_kafka_buf_read_str(rkbuf, &GroupInstanceId); - rd_kafka_buf_read_bytes(rkbuf, &MemberMetadata); + rd_kafka_buf_read_kbytes(rkbuf, &MemberMetadata); rkgm = &members[sub_cnt]; rkgm->rkgm_member_id = rd_kafkap_str_copy(&MemberId); diff --git a/src/rdkafka_event.c b/src/rdkafka_event.c index b2a6843ca2..28e602b23b 100644 --- a/src/rdkafka_event.c +++ b/src/rdkafka_event.c @@ -86,6 +86,10 @@ const char *rd_kafka_event_name(const rd_kafka_event_t *rkev) { return "ListConsumerGroupOffsetsResult"; case RD_KAFKA_EVENT_OAUTHBEARER_TOKEN_REFRESH: return "SaslOAuthBearerTokenRefresh"; + case RD_KAFKA_EVENT_DESCRIBEUSERSCRAMCREDENTIALS_RESULT: + return "DescribeUserScramCredentials"; + case RD_KAFKA_EVENT_ALTERUSERSCRAMCREDENTIALS_RESULT: + return "AlterUserScramCredentials"; default: return "?unknown?"; } @@ -427,6 +431,25 @@ rd_kafka_event_AlterConsumerGroupOffsets_result(rd_kafka_event_t *rkev) { const rd_kafka_AlterConsumerGroupOffsets_result_t *)rkev; } +const rd_kafka_DescribeUserScramCredentials_result_t * +rd_kafka_event_DescribeUserScramCredentials_result(rd_kafka_event_t *rkev) { + if (!rkev || rkev->rko_evtype != + RD_KAFKA_EVENT_DESCRIBEUSERSCRAMCREDENTIALS_RESULT) + return NULL; + else + return ( + const rd_kafka_DescribeUserScramCredentials_result_t *)rkev; +} + +const rd_kafka_AlterUserScramCredentials_result_t * +rd_kafka_event_AlterUserScramCredentials_result(rd_kafka_event_t *rkev) { + if (!rkev || + rkev->rko_evtype != RD_KAFKA_EVENT_ALTERUSERSCRAMCREDENTIALS_RESULT) + return NULL; + else + return ( + const rd_kafka_AlterUserScramCredentials_result_t *)rkev; +} const rd_kafka_ListConsumerGroupOffsets_result_t * rd_kafka_event_ListConsumerGroupOffsets_result(rd_kafka_event_t *rkev) { if (!rkev || diff --git a/src/rdkafka_event.h b/src/rdkafka_event.h index 52c2d191a2..aa8e4c6270 100644 --- a/src/rdkafka_event.h +++ b/src/rdkafka_event.h @@ -111,6 +111,8 @@ static RD_UNUSED RD_INLINE int rd_kafka_event_setup(rd_kafka_t *rk, case RD_KAFKA_EVENT_ALTERCONSUMERGROUPOFFSETS_RESULT: case RD_KAFKA_EVENT_LISTCONSUMERGROUPOFFSETS_RESULT: case RD_KAFKA_EVENT_OAUTHBEARER_TOKEN_REFRESH: + case RD_KAFKA_EVENT_DESCRIBEUSERSCRAMCREDENTIALS_RESULT: + case RD_KAFKA_EVENT_ALTERUSERSCRAMCREDENTIALS_RESULT: return 1; default: diff --git a/src/rdkafka_mock_handlers.c b/src/rdkafka_mock_handlers.c index efebd33da5..f3d9f1134a 100644 --- a/src/rdkafka_mock_handlers.c +++ b/src/rdkafka_mock_handlers.c @@ -97,7 +97,7 @@ static int rd_kafka_mock_handle_Produce(rd_kafka_mock_connection_t *mconn, mpart = rd_kafka_mock_partition_find(mtopic, Partition); - rd_kafka_buf_read_bytes(rkbuf, &records); + rd_kafka_buf_read_kbytes(rkbuf, &records); /* Response: Partition */ rd_kafka_buf_write_i32(resp, Partition); @@ -353,9 +353,10 @@ static int rd_kafka_mock_handle_Fetch(rd_kafka_mock_connection_t *mconn, if (mset && partsize < (size_t)PartMaxBytes && totsize < (size_t)MaxBytes) { /* Response: Records */ - rd_kafka_buf_write_kbytes(resp, &mset->bytes); - partsize += RD_KAFKAP_BYTES_SIZE(&mset->bytes); - totsize += RD_KAFKAP_BYTES_SIZE(&mset->bytes); + size_t written = rd_kafka_buf_write_kbytes( + resp, &mset->bytes); + partsize += written; + totsize += written; /* FIXME: Multiple messageSets ? */ } else { @@ -1166,7 +1167,7 @@ static int rd_kafka_mock_handle_JoinGroup(rd_kafka_mock_connection_t *mconn, rd_kafkap_str_t ProtocolName; rd_kafkap_bytes_t Metadata; rd_kafka_buf_read_str(rkbuf, &ProtocolName); - rd_kafka_buf_read_bytes(rkbuf, &Metadata); + rd_kafka_buf_read_kbytes(rkbuf, &Metadata); protos[i].name = rd_kafkap_str_copy(&ProtocolName); protos[i].metadata = rd_kafkap_bytes_copy(&Metadata); } @@ -1454,7 +1455,7 @@ static int rd_kafka_mock_handle_SyncGroup(rd_kafka_mock_connection_t *mconn, rd_kafka_mock_cgrp_member_t *member2; rd_kafka_buf_read_str(rkbuf, &MemberId2); - rd_kafka_buf_read_bytes(rkbuf, &Metadata); + rd_kafka_buf_read_kbytes(rkbuf, &Metadata); if (err) continue; diff --git a/src/rdkafka_msgset_reader.c b/src/rdkafka_msgset_reader.c index 8b23d23ca7..c1b08fbbcd 100644 --- a/src/rdkafka_msgset_reader.c +++ b/src/rdkafka_msgset_reader.c @@ -631,10 +631,10 @@ rd_kafka_msgset_reader_msg_v0_1(rd_kafka_msgset_reader_t *msetr) { /* Extract key */ - rd_kafka_buf_read_bytes(rkbuf, &Key); + rd_kafka_buf_read_kbytes(rkbuf, &Key); /* Extract Value */ - rd_kafka_buf_read_bytes(rkbuf, &Value); + rd_kafka_buf_read_kbytes(rkbuf, &Value); Value_len = RD_KAFKAP_BYTES_LEN(&Value); /* MessageSets may contain offsets earlier than we @@ -894,8 +894,8 @@ rd_kafka_msgset_reader_msg_v2(rd_kafka_msgset_reader_t *msetr) { /* Note: messages in aborted transactions are skipped at the MessageSet * level */ - rd_kafka_buf_read_bytes_varint(rkbuf, &hdr.Key); - rd_kafka_buf_read_bytes_varint(rkbuf, &hdr.Value); + rd_kafka_buf_read_kbytes_varint(rkbuf, &hdr.Key); + rd_kafka_buf_read_kbytes_varint(rkbuf, &hdr.Value); /* We parse the Headers later, just store the size (possibly truncated) * and pointer to the headers. */ diff --git a/src/rdkafka_op.c b/src/rdkafka_op.c index 32cf4b3623..6ecb6cd14c 100644 --- a/src/rdkafka_op.c +++ b/src/rdkafka_op.c @@ -110,6 +110,10 @@ const char *rd_kafka_op2str(rd_kafka_op_type_t type) { [RD_KAFKA_OP_LEADERS] = "REPLY:LEADERS", [RD_KAFKA_OP_BARRIER] = "REPLY:BARRIER", [RD_KAFKA_OP_SASL_REAUTH] = "REPLY:SASL_REAUTH", + [RD_KAFKA_OP_ALTERUSERSCRAMCREDENTIALS] = + "REPLY:ALTERUSERSCRAMCREDENTIALS", + [RD_KAFKA_OP_DESCRIBEUSERSCRAMCREDENTIALS] = + "REPLY:DESCRIBEUSERSCRAMCREDENTIALS", }; if (type & RD_KAFKA_OP_REPLY) @@ -262,6 +266,10 @@ rd_kafka_op_t *rd_kafka_op_new0(const char *source, rd_kafka_op_type_t type) { [RD_KAFKA_OP_LEADERS] = sizeof(rko->rko_u.leaders), [RD_KAFKA_OP_BARRIER] = _RD_KAFKA_OP_EMPTY, [RD_KAFKA_OP_SASL_REAUTH] = _RD_KAFKA_OP_EMPTY, + [RD_KAFKA_OP_ALTERUSERSCRAMCREDENTIALS] = + sizeof(rko->rko_u.admin_request), + [RD_KAFKA_OP_DESCRIBEUSERSCRAMCREDENTIALS] = + sizeof(rko->rko_u.admin_request), }; size_t tsize = op2size[type & ~RD_KAFKA_OP_FLAGMASK]; @@ -408,6 +416,8 @@ void rd_kafka_op_destroy(rd_kafka_op_t *rko) { case RD_KAFKA_OP_DELETEACLS: case RD_KAFKA_OP_ALTERCONSUMERGROUPOFFSETS: case RD_KAFKA_OP_LISTCONSUMERGROUPOFFSETS: + case RD_KAFKA_OP_ALTERUSERSCRAMCREDENTIALS: + case RD_KAFKA_OP_DESCRIBEUSERSCRAMCREDENTIALS: rd_kafka_replyq_destroy(&rko->rko_u.admin_request.replyq); rd_list_destroy(&rko->rko_u.admin_request.args); if (rko->rko_u.admin_request.options.match_consumer_group_states diff --git a/src/rdkafka_op.h b/src/rdkafka_op.h index f9ccec2373..6018a2659d 100644 --- a/src/rdkafka_op.h +++ b/src/rdkafka_op.h @@ -166,6 +166,12 @@ typedef enum { RD_KAFKA_OP_LEADERS, /**< Partition leader query */ RD_KAFKA_OP_BARRIER, /**< Version barrier bump */ RD_KAFKA_OP_SASL_REAUTH, /**< Sasl reauthentication for broker */ + RD_KAFKA_OP_DESCRIBEUSERSCRAMCREDENTIALS, /* < Admin: + DescribeUserScramCredentials + u.admin_request >*/ + RD_KAFKA_OP_ALTERUSERSCRAMCREDENTIALS, /* < Admin: + AlterUserScramCredentials + u.admin_request >*/ RD_KAFKA_OP__END } rd_kafka_op_type_t; diff --git a/src/rdkafka_partition.c b/src/rdkafka_partition.c index ab40168ac3..1a9066d3d9 100644 --- a/src/rdkafka_partition.c +++ b/src/rdkafka_partition.c @@ -2487,7 +2487,6 @@ void rd_kafka_topic_partition_get(const rd_kafka_topic_partition_t *rktpar, } - /** * * rd_kafka_topic_partition_t lists @@ -2766,7 +2765,6 @@ void rd_kafka_topic_partition_list_destroy_free(void *ptr) { (rd_kafka_topic_partition_list_t *)ptr); } - /** * @brief Add a partition to an rktpar list. * The list must have enough room to fit it. diff --git a/src/rdkafka_proto.h b/src/rdkafka_proto.h index cac898a55c..24fce04106 100644 --- a/src/rdkafka_proto.h +++ b/src/rdkafka_proto.h @@ -378,7 +378,7 @@ typedef struct rd_kafkap_bytes_s { int32_t len; /* Kafka bytes length (-1=NULL, 0=empty, >0=data) */ const void *data; /* points just past the struct, or other memory, * not NULL-terminated */ - const char _data[1]; /* Bytes following struct when new()ed */ + const unsigned char _data[1]; /* Bytes following struct when new()ed */ } rd_kafkap_bytes_t; @@ -423,7 +423,7 @@ static RD_UNUSED void rd_kafkap_bytes_destroy(rd_kafkap_bytes_t *kbytes) { * - No-copy, just alloc (bytes==NULL,len>0) */ static RD_INLINE RD_UNUSED rd_kafkap_bytes_t * -rd_kafkap_bytes_new(const char *bytes, int32_t len) { +rd_kafkap_bytes_new(const unsigned char *bytes, int32_t len) { rd_kafkap_bytes_t *kbytes; int32_t klen; @@ -440,7 +440,7 @@ rd_kafkap_bytes_new(const char *bytes, int32_t len) { if (len == RD_KAFKAP_BYTES_LEN_NULL) kbytes->data = NULL; else { - kbytes->data = ((const char *)(kbytes + 1)) + 4; + kbytes->data = ((const unsigned char *)(kbytes + 1)) + 4; if (bytes) memcpy((void *)kbytes->data, bytes, len); } @@ -455,7 +455,7 @@ rd_kafkap_bytes_new(const char *bytes, int32_t len) { */ static RD_INLINE RD_UNUSED rd_kafkap_bytes_t * rd_kafkap_bytes_copy(const rd_kafkap_bytes_t *src) { - return rd_kafkap_bytes_new((const char *)src->data, src->len); + return rd_kafkap_bytes_new((const unsigned char *)src->data, src->len); } diff --git a/src/rdkafka_request.c b/src/rdkafka_request.c index a2b6656de1..8d0789cfc7 100644 --- a/src/rdkafka_request.c +++ b/src/rdkafka_request.c @@ -2610,7 +2610,7 @@ void rd_kafka_handle_SaslAuthenticate(rd_kafka_t *rk, goto err; } - rd_kafka_buf_read_bytes(rkbuf, &auth_data); + rd_kafka_buf_read_kbytes(rkbuf, &auth_data); if (request->rkbuf_reqhdr.ApiVersion >= 1) { int64_t session_lifetime_ms; diff --git a/src/rdkafka_request.h b/src/rdkafka_request.h index 6f08e7a8a6..097b2fcb36 100644 --- a/src/rdkafka_request.h +++ b/src/rdkafka_request.h @@ -430,7 +430,6 @@ rd_kafka_resp_err_t rd_kafka_EndTxnRequest(rd_kafka_broker_t *rkb, int unittest_request(void); - rd_kafka_resp_err_t rd_kafka_DeleteRecordsRequest(rd_kafka_broker_t *rkb, /*(rd_topic_partition_list_t*)*/ diff --git a/src/rdkafka_sasl_scram.c b/src/rdkafka_sasl_scram.c index 1a4aebb835..32f13a4c04 100644 --- a/src/rdkafka_sasl_scram.c +++ b/src/rdkafka_sasl_scram.c @@ -256,8 +256,6 @@ static int rd_kafka_sasl_scram_HMAC(rd_kafka_transport_t *rktrans, return 0; } - - /** * @brief Perform \p itcnt iterations of HMAC() on the given buffer \p in * using \p salt, writing the output into \p out which must be @@ -269,57 +267,14 @@ static int rd_kafka_sasl_scram_Hi(rd_kafka_transport_t *rktrans, const rd_chariov_t *salt, int itcnt, rd_chariov_t *out) { + rd_kafka_broker_t *rkb = rktrans->rktrans_rkb; const EVP_MD *evp = rktrans->rktrans_rkb->rkb_rk->rk_conf.sasl.scram_evp; - unsigned int ressize = 0; - unsigned char tempres[EVP_MAX_MD_SIZE]; - unsigned char *saltplus; - int i; - - /* U1 := HMAC(str, salt + INT(1)) */ - saltplus = rd_alloca(salt->size + 4); - memcpy(saltplus, salt->ptr, salt->size); - saltplus[salt->size] = 0; - saltplus[salt->size + 1] = 0; - saltplus[salt->size + 2] = 0; - saltplus[salt->size + 3] = 1; - - /* U1 := HMAC(str, salt + INT(1)) */ - if (!HMAC(evp, (const unsigned char *)in->ptr, (int)in->size, saltplus, - salt->size + 4, tempres, &ressize)) { - rd_rkb_dbg(rktrans->rktrans_rkb, SECURITY, "SCRAM", - "HMAC priming failed"); - return -1; - } - - memcpy(out->ptr, tempres, ressize); - - /* Ui-1 := HMAC(str, Ui-2) .. */ - for (i = 1; i < itcnt; i++) { - unsigned char tempdest[EVP_MAX_MD_SIZE]; - int j; - - if (unlikely(!HMAC(evp, (const unsigned char *)in->ptr, - (int)in->size, tempres, ressize, tempdest, - NULL))) { - rd_rkb_dbg(rktrans->rktrans_rkb, SECURITY, "SCRAM", - "Hi() HMAC #%d/%d failed", i, itcnt); - return -1; - } - - /* U1 XOR U2 .. */ - for (j = 0; j < (int)ressize; j++) { - out->ptr[j] ^= tempdest[j]; - tempres[j] = tempdest[j]; - } - } - - out->size = ressize; - - return 0; + return rd_kafka_ssl_hmac(rkb, evp, in, salt, itcnt, out); } + /** * @returns a SASL value-safe-char encoded string, replacing "," and "=" * with their escaped counterparts in a newly allocated string. diff --git a/src/rdkafka_ssl.c b/src/rdkafka_ssl.c index 19178c84b3..85f745cb9c 100644 --- a/src/rdkafka_ssl.c +++ b/src/rdkafka_ssl.c @@ -1848,3 +1848,56 @@ void rd_kafka_ssl_init(void) { OpenSSL_add_all_algorithms(); #endif } + +int rd_kafka_ssl_hmac(rd_kafka_broker_t *rkb, + const EVP_MD *evp, + const rd_chariov_t *in, + const rd_chariov_t *salt, + int itcnt, + rd_chariov_t *out) { + unsigned int ressize = 0; + unsigned char tempres[EVP_MAX_MD_SIZE]; + unsigned char *saltplus; + int i; + + /* U1 := HMAC(str, salt + INT(1)) */ + saltplus = rd_alloca(salt->size + 4); + memcpy(saltplus, salt->ptr, salt->size); + saltplus[salt->size] = 0; + saltplus[salt->size + 1] = 0; + saltplus[salt->size + 2] = 0; + saltplus[salt->size + 3] = 1; + + /* U1 := HMAC(str, salt + INT(1)) */ + if (!HMAC(evp, (const unsigned char *)in->ptr, (int)in->size, saltplus, + salt->size + 4, tempres, &ressize)) { + rd_rkb_dbg(rkb, SECURITY, "SSLHMAC", "HMAC priming failed"); + return -1; + } + + memcpy(out->ptr, tempres, ressize); + + /* Ui-1 := HMAC(str, Ui-2) .. */ + for (i = 1; i < itcnt; i++) { + unsigned char tempdest[EVP_MAX_MD_SIZE]; + int j; + + if (unlikely(!HMAC(evp, (const unsigned char *)in->ptr, + (int)in->size, tempres, ressize, tempdest, + NULL))) { + rd_rkb_dbg(rkb, SECURITY, "SSLHMAC", + "Hi() HMAC #%d/%d failed", i, itcnt); + return -1; + } + + /* U1 XOR U2 .. */ + for (j = 0; j < (int)ressize; j++) { + out->ptr[j] ^= tempdest[j]; + tempres[j] = tempdest[j]; + } + } + + out->size = ressize; + + return 0; +} diff --git a/src/rdkafka_ssl.h b/src/rdkafka_ssl.h index 9fb07e3312..4dce0b1f87 100644 --- a/src/rdkafka_ssl.h +++ b/src/rdkafka_ssl.h @@ -54,4 +54,11 @@ void rd_kafka_ssl_init(void); const char *rd_kafka_ssl_last_error_str(void); +int rd_kafka_ssl_hmac(rd_kafka_broker_t *rkb, + const EVP_MD *evp, + const rd_chariov_t *in, + const rd_chariov_t *salt, + int itcnt, + rd_chariov_t *out); + #endif /* _RDKAFKA_SSL_H_ */ diff --git a/tests/0080-admin_ut.c b/tests/0080-admin_ut.c index e187297b84..66693d3fdd 100644 --- a/tests/0080-admin_ut.c +++ b/tests/0080-admin_ut.c @@ -1988,6 +1988,140 @@ static void do_test_ListConsumerGroupOffsets(const char *what, SUB_TEST_PASS(); } +static void do_test_DescribeUserScramCredentials(const char *what, + rd_kafka_t *rk, + rd_kafka_queue_t *useq) { + char errstr[512]; + rd_kafka_AdminOptions_t *options; + rd_kafka_event_t *rkev; + rd_kafka_queue_t *rkqu; + + SUB_TEST_QUICK("%s", what); + + rkqu = useq ? useq : rd_kafka_queue_new(rk); + + const char *users[2]; + users[0] = "Sam"; + users[1] = "Sam"; + + /* Whenever a duplicate user is passed, + * the request should fail with error code + * RD_KAFKA_RESP_ERR__INVALID_ARG */ + options = rd_kafka_AdminOptions_new( + rk, RD_KAFKA_ADMIN_OP_DESCRIBEUSERSCRAMCREDENTIALS); + TEST_CALL_ERR__(rd_kafka_AdminOptions_set_request_timeout( + options, 30 * 1000 /* 30s */, errstr, sizeof(errstr))); + + rd_kafka_DescribeUserScramCredentials(rk, users, RD_ARRAY_SIZE(users), + options, rkqu); + rd_kafka_AdminOptions_destroy(options); + + rkev = test_wait_admin_result( + rkqu, RD_KAFKA_EVENT_DESCRIBEUSERSCRAMCREDENTIALS_RESULT, 2000); + + TEST_ASSERT( + rd_kafka_event_error(rkev) == RD_KAFKA_RESP_ERR__INVALID_ARG, + "Expected \"Local: Invalid argument or configuration\", not %s", + rd_kafka_err2str(rd_kafka_event_error(rkev))); + + rd_kafka_event_destroy(rkev); + + if (!useq) + rd_kafka_queue_destroy(rkqu); + + SUB_TEST_PASS(); +} + +static void do_test_AlterUserScramCredentials(const char *what, + rd_kafka_t *rk, + rd_kafka_queue_t *useq) { + char errstr[512]; + rd_kafka_AdminOptions_t *options; + rd_kafka_event_t *rkev; + rd_kafka_queue_t *rkqu; + + SUB_TEST_QUICK("%s", what); + + rkqu = useq ? useq : rd_kafka_queue_new(rk); + +#if !WITH_SSL + /* Whenever librdkafka wasn't built with OpenSSL, + * the request should fail with error code + * RD_KAFKA_RESP_ERR__INVALID_ARG */ + rd_kafka_UserScramCredentialAlteration_t *alterations_ssl[1]; + alterations_ssl[0] = rd_kafka_UserScramCredentialUpsertion_new( + "user", RD_KAFKA_SCRAM_MECHANISM_SHA_256, 10000, + (unsigned char *)"password", 8, (unsigned char *)"salt", 4); + options = rd_kafka_AdminOptions_new( + rk, RD_KAFKA_ADMIN_OP_ALTERUSERSCRAMCREDENTIALS); + TEST_CALL_ERR__(rd_kafka_AdminOptions_set_request_timeout( + options, 30 * 1000 /* 30s */, errstr, sizeof(errstr))); + + rd_kafka_AlterUserScramCredentials(rk, alterations_ssl, 1, options, + rkqu); + rd_kafka_UserScramCredentialAlteration_destroy_array( + alterations_ssl, RD_ARRAY_SIZE(alterations_ssl)); + rd_kafka_AdminOptions_destroy(options); + + rkev = test_wait_admin_result( + rkqu, RD_KAFKA_EVENT_ALTERUSERSCRAMCREDENTIALS_RESULT, 2000); + + TEST_ASSERT( + rd_kafka_event_error(rkev) == RD_KAFKA_RESP_ERR__INVALID_ARG, + "Expected \"Local: Invalid argument or configuration\", not %s", + rd_kafka_err2str(rd_kafka_event_error(rkev))); + + rd_kafka_event_destroy(rkev); +#endif + + rd_kafka_UserScramCredentialAlteration_t *alterations[1]; + alterations[0] = rd_kafka_UserScramCredentialDeletion_new( + "", RD_KAFKA_SCRAM_MECHANISM_SHA_256); + options = rd_kafka_AdminOptions_new( + rk, RD_KAFKA_ADMIN_OP_ALTERUSERSCRAMCREDENTIALS); + TEST_CALL_ERR__(rd_kafka_AdminOptions_set_request_timeout( + options, 30 * 1000 /* 30s */, errstr, sizeof(errstr))); + + /* Whenever an empty array is passed, + * the request should fail with error code + * RD_KAFKA_RESP_ERR__INVALID_ARG */ + rd_kafka_AlterUserScramCredentials(rk, alterations, 0, options, rkqu); + + rkev = test_wait_admin_result( + rkqu, RD_KAFKA_EVENT_ALTERUSERSCRAMCREDENTIALS_RESULT, 2000); + + TEST_ASSERT( + rd_kafka_event_error(rkev) == RD_KAFKA_RESP_ERR__INVALID_ARG, + "Expected \"Local: Invalid argument or configuration\", not %s", + rd_kafka_err2str(rd_kafka_event_error(rkev))); + + rd_kafka_event_destroy(rkev); + + /* Whenever an empty user is passed, + * the request should fail with error code + * RD_KAFKA_RESP_ERR__INVALID_ARG */ + rd_kafka_AlterUserScramCredentials( + rk, alterations, RD_ARRAY_SIZE(alterations), options, rkqu); + rkev = test_wait_admin_result( + rkqu, RD_KAFKA_EVENT_ALTERUSERSCRAMCREDENTIALS_RESULT, 2000); + + TEST_ASSERT( + rd_kafka_event_error(rkev) == RD_KAFKA_RESP_ERR__INVALID_ARG, + "Expected \"Local: Invalid argument or configuration\", not %s", + rd_kafka_err2str(rd_kafka_event_error(rkev))); + + rd_kafka_event_destroy(rkev); + + + rd_kafka_UserScramCredentialAlteration_destroy_array( + alterations, RD_ARRAY_SIZE(alterations)); + rd_kafka_AdminOptions_destroy(options); + + if (!useq) + rd_kafka_queue_destroy(rkqu); + + SUB_TEST_PASS(); +} /** * @brief Test a mix of APIs using the same replyq. @@ -2496,6 +2630,12 @@ static void do_test_apis(rd_kafka_type_t cltype) { do_test_ListConsumerGroupOffsets("main queue, options", rk, mainq, 1, rd_true); + do_test_DescribeUserScramCredentials("main queue", rk, mainq); + do_test_DescribeUserScramCredentials("temp queue", rk, NULL); + + do_test_AlterUserScramCredentials("main queue", rk, mainq); + do_test_AlterUserScramCredentials("temp queue", rk, NULL); + do_test_mix(rk, mainq); do_test_configs(rk, mainq); diff --git a/tests/0081-admin.c b/tests/0081-admin.c index 7d8799ea23..e960342f17 100644 --- a/tests/0081-admin.c +++ b/tests/0081-admin.c @@ -3899,6 +3899,321 @@ static void do_test_ListConsumerGroupOffsets(const char *what, SUB_TEST_PASS(); } +static void do_test_UserScramCredentials(const char *what, + rd_kafka_t *rk, + rd_kafka_queue_t *useq, + rd_bool_t null_bytes) { + rd_kafka_event_t *event; + rd_kafka_resp_err_t err; + const rd_kafka_DescribeUserScramCredentials_result_t *describe_result; + const rd_kafka_UserScramCredentialsDescription_t **descriptions; + const rd_kafka_UserScramCredentialsDescription_t *description; + const rd_kafka_AlterUserScramCredentials_result_t *alter_result; + const rd_kafka_AlterUserScramCredentials_result_response_t * + *alter_responses; + const rd_kafka_AlterUserScramCredentials_result_response_t *response; + const rd_kafka_ScramCredentialInfo_t *scram_credential; + rd_kafka_ScramMechanism_t mechanism; + size_t response_cnt; + size_t description_cnt; + size_t num_credentials; + char errstr[512]; + const char *username; + const rd_kafka_error_t *error; + int32_t iterations; + rd_kafka_UserScramCredentialAlteration_t *alterations[1]; + char *salt = tsprintf("%s", "salt"); + size_t salt_size = 4; + char *password = tsprintf("%s", "password"); + size_t password_size = 8; + rd_kafka_queue_t *queue; + const char *users[1]; + users[0] = "testuserforscram"; + + if (null_bytes) { + salt[1] = '\0'; + salt[3] = '\0'; + password[0] = '\0'; + password[3] = '\0'; + } + + SUB_TEST_QUICK("%s, null bytes: %s", what, RD_STR_ToF(null_bytes)); + + queue = useq ? useq : rd_kafka_queue_new(rk); + + rd_kafka_AdminOptions_t *options = rd_kafka_AdminOptions_new( + rk, RD_KAFKA_ADMIN_OP_DESCRIBEUSERSCRAMCREDENTIALS); + + TEST_CALL_ERR__(rd_kafka_AdminOptions_set_request_timeout( + options, 30 * 1000 /* 30s */, errstr, sizeof(errstr))); + + /* Describe an unknown user */ + rd_kafka_DescribeUserScramCredentials(rk, users, RD_ARRAY_SIZE(users), + options, queue); + rd_kafka_AdminOptions_destroy(options); + event = rd_kafka_queue_poll(queue, -1 /*indefinitely*/); + + /* Request level error code should be 0*/ + TEST_CALL_ERR__(rd_kafka_event_error(event)); + err = rd_kafka_event_error(event); + TEST_ASSERT(err == RD_KAFKA_RESP_ERR_NO_ERROR, + "Expected NO_ERROR, not %s", rd_kafka_err2name(err)); + + describe_result = + rd_kafka_event_DescribeUserScramCredentials_result(event); + descriptions = + rd_kafka_DescribeUserScramCredentials_result_descriptions( + describe_result, &description_cnt); + + /* Assert num_results should be 1 */ + TEST_ASSERT(description_cnt == 1, + "There should be exactly 1 description, got %" PRIusz, + description_cnt); + + description = descriptions[0]; + username = rd_kafka_UserScramCredentialsDescription_user(description); + error = rd_kafka_UserScramCredentialsDescription_error(description); + err = rd_kafka_error_code(error); + + num_credentials = + rd_kafka_UserScramCredentialsDescription_scramcredentialinfo_count( + description); + /* username should be the same, err should be RESOURCE_NOT_FOUND + * and num_credentials should be 0 */ + TEST_ASSERT(strcmp(users[0], username) == 0, + "Username should be %s, got %s", users[0], username); + TEST_ASSERT(err == RD_KAFKA_RESP_ERR_RESOURCE_NOT_FOUND, + "Error code should be RESOURCE_NOT_FOUND as user " + "does not exist, got %s", + rd_kafka_err2name(err)); + TEST_ASSERT(num_credentials == 0, + "Credentials count should be 0, got %" PRIusz, + num_credentials); + rd_kafka_event_destroy(event); + + /* Create a credential for user 0 */ + mechanism = RD_KAFKA_SCRAM_MECHANISM_SHA_256; + iterations = 10000; + alterations[0] = rd_kafka_UserScramCredentialUpsertion_new( + users[0], mechanism, iterations, (unsigned char *)password, + password_size, (unsigned char *)salt, salt_size); + + options = rd_kafka_AdminOptions_new( + rk, RD_KAFKA_ADMIN_OP_ALTERUSERSCRAMCREDENTIALS); + + TEST_CALL_ERR__(rd_kafka_AdminOptions_set_request_timeout( + options, 30 * 1000 /* 30s */, errstr, sizeof(errstr))); + + rd_kafka_AlterUserScramCredentials( + rk, alterations, RD_ARRAY_SIZE(alterations), options, queue); + rd_kafka_AdminOptions_destroy(options); + rd_kafka_UserScramCredentialAlteration_destroy_array( + alterations, RD_ARRAY_SIZE(alterations)); + + /* Wait for results */ + event = rd_kafka_queue_poll(queue, -1 /*indefinitely*/); + err = rd_kafka_event_error(event); +#if !WITH_SSL + TEST_ASSERT(err == RD_KAFKA_RESP_ERR__INVALID_ARG, + "Expected _INVALID_ARG, not %s", rd_kafka_err2name(err)); + rd_kafka_event_destroy(event); + goto final_checks; +#else + TEST_ASSERT(err == RD_KAFKA_RESP_ERR_NO_ERROR, + "Expected NO_ERROR, not %s", rd_kafka_err2name(err)); + + alter_result = rd_kafka_event_AlterUserScramCredentials_result(event); + alter_responses = rd_kafka_AlterUserScramCredentials_result_responses( + alter_result, &response_cnt); + + /* response_cnt should be 1*/ + TEST_ASSERT(response_cnt == 1, + "There should be exactly 1 response, got %" PRIusz, + response_cnt); + + response = alter_responses[0]; + username = + rd_kafka_AlterUserScramCredentials_result_response_user(response); + error = + rd_kafka_AlterUserScramCredentials_result_response_error(response); + + err = rd_kafka_error_code(error); + /* username should be the same and err should be NO_ERROR*/ + TEST_ASSERT(strcmp(users[0], username) == 0, + "Username should be %s, got %s", users[0], username); + TEST_ASSERT(err == RD_KAFKA_RESP_ERR_NO_ERROR, + "Error code should be NO_ERROR, got %s", + rd_kafka_err2name(err)); + + rd_kafka_event_destroy(event); +#endif + + /* Credential should be retrieved */ + options = rd_kafka_AdminOptions_new( + rk, RD_KAFKA_ADMIN_OP_DESCRIBEUSERSCRAMCREDENTIALS); + + TEST_CALL_ERR__(rd_kafka_AdminOptions_set_request_timeout( + options, 30 * 1000 /* 30s */, errstr, sizeof(errstr))); + + rd_kafka_DescribeUserScramCredentials(rk, users, RD_ARRAY_SIZE(users), + options, queue); + rd_kafka_AdminOptions_destroy(options); + + /* Wait for results */ + event = rd_kafka_queue_poll(queue, -1 /*indefinitely*/); + err = rd_kafka_event_error(event); + TEST_ASSERT(err == RD_KAFKA_RESP_ERR_NO_ERROR, + "Expected NO_ERROR, not %s", rd_kafka_err2name(err)); + + describe_result = + rd_kafka_event_DescribeUserScramCredentials_result(event); + descriptions = + rd_kafka_DescribeUserScramCredentials_result_descriptions( + describe_result, &description_cnt); + /* Assert description_cnt should be 1 , request level error code should + * be 0*/ + TEST_ASSERT(description_cnt == 1, + "There should be exactly 1 description, got %" PRIusz, + description_cnt); + + description = descriptions[0]; + username = rd_kafka_UserScramCredentialsDescription_user(description); + error = rd_kafka_UserScramCredentialsDescription_error(description); + err = rd_kafka_error_code(error); + + num_credentials = + rd_kafka_UserScramCredentialsDescription_scramcredentialinfo_count( + description); + /* username should be the same, err should be NO_ERROR and + * num_credentials should be 1 */ + TEST_ASSERT(strcmp(users[0], username) == 0, + "Username should be %s, got %s", users[0], username); + TEST_ASSERT(err == RD_KAFKA_RESP_ERR_NO_ERROR, + "Error code should be NO_ERROR, got %s", + rd_kafka_err2name(err)); + TEST_ASSERT(num_credentials == 1, + "Credentials count should be 1, got %" PRIusz, + num_credentials); + + scram_credential = + rd_kafka_UserScramCredentialsDescription_scramcredentialinfo( + description, 0); + mechanism = rd_kafka_ScramCredentialInfo_mechanism(scram_credential); + iterations = rd_kafka_ScramCredentialInfo_iterations(scram_credential); + /* mechanism should be SHA 256 and iterations 10000 */ + TEST_ASSERT(mechanism == RD_KAFKA_SCRAM_MECHANISM_SHA_256, + "Mechanism should be %d, got: %d", + RD_KAFKA_SCRAM_MECHANISM_SHA_256, mechanism); + TEST_ASSERT(iterations == 10000, + "Iterations should be 10000, got %" PRId32, iterations); + + rd_kafka_event_destroy(event); + + /* Delete the credential */ + alterations[0] = + rd_kafka_UserScramCredentialDeletion_new(users[0], mechanism); + + options = rd_kafka_AdminOptions_new( + rk, RD_KAFKA_ADMIN_OP_ALTERUSERSCRAMCREDENTIALS); + + TEST_CALL_ERR__(rd_kafka_AdminOptions_set_request_timeout( + options, 30 * 1000 /* 30s */, errstr, sizeof(errstr))); + + rd_kafka_AlterUserScramCredentials( + rk, alterations, RD_ARRAY_SIZE(alterations), options, queue); + rd_kafka_AdminOptions_destroy(options); + rd_kafka_UserScramCredentialAlteration_destroy_array( + alterations, RD_ARRAY_SIZE(alterations)); + + /* Wait for results */ + event = rd_kafka_queue_poll(queue, -1 /*indefinitely*/); + err = rd_kafka_event_error(event); + TEST_ASSERT(err == RD_KAFKA_RESP_ERR_NO_ERROR, + "Expected NO_ERROR, not %s", rd_kafka_err2name(err)); + + alter_result = rd_kafka_event_AlterUserScramCredentials_result(event); + alter_responses = rd_kafka_AlterUserScramCredentials_result_responses( + alter_result, &response_cnt); + + /* response_cnt should be 1*/ + TEST_ASSERT(response_cnt == 1, + "There should be exactly 1 response, got %" PRIusz, + response_cnt); + + response = alter_responses[0]; + username = + rd_kafka_AlterUserScramCredentials_result_response_user(response); + error = + rd_kafka_AlterUserScramCredentials_result_response_error(response); + + err = rd_kafka_error_code(error); + /* username should be the same and err should be NO_ERROR*/ + TEST_ASSERT(strcmp(users[0], username) == 0, + "Username should be %s, got %s", users[0], username); + TEST_ASSERT(err == RD_KAFKA_RESP_ERR_NO_ERROR, + "Error code should be NO_ERROR, got %s", + rd_kafka_err2name(err)); + + rd_kafka_event_destroy(event); + +#if !WITH_SSL +final_checks: +#endif + + /* Credential doesn't exist anymore for this user */ + + options = rd_kafka_AdminOptions_new( + rk, RD_KAFKA_ADMIN_OP_DESCRIBEUSERSCRAMCREDENTIALS); + + TEST_CALL_ERR__(rd_kafka_AdminOptions_set_request_timeout( + options, 30 * 1000 /* 30s */, errstr, sizeof(errstr))); + + rd_kafka_DescribeUserScramCredentials(rk, users, RD_ARRAY_SIZE(users), + options, queue); + rd_kafka_AdminOptions_destroy(options); + /* Wait for results */ + event = rd_kafka_queue_poll(queue, -1 /*indefinitely*/); + err = rd_kafka_event_error(event); + TEST_ASSERT(err == RD_KAFKA_RESP_ERR_NO_ERROR, + "Expected NO_ERROR, not %s", rd_kafka_err2name(err)); + + describe_result = + rd_kafka_event_DescribeUserScramCredentials_result(event); + descriptions = + rd_kafka_DescribeUserScramCredentials_result_descriptions( + describe_result, &description_cnt); + /* Assert description_cnt should be 1, request level error code should + * be 0*/ + TEST_ASSERT(description_cnt == 1, + "There should be exactly 1 description, got %" PRIusz, + description_cnt); + + description = descriptions[0]; + username = rd_kafka_UserScramCredentialsDescription_user(description); + error = rd_kafka_UserScramCredentialsDescription_error(description); + err = rd_kafka_error_code(error); + num_credentials = + rd_kafka_UserScramCredentialsDescription_scramcredentialinfo_count( + description); + /* username should be the same, err should be RESOURCE_NOT_FOUND + * and num_credentials should be 0 */ + TEST_ASSERT(strcmp(users[0], username) == 0, + "Username should be %s, got %s", users[0], username); + TEST_ASSERT(err == RD_KAFKA_RESP_ERR_RESOURCE_NOT_FOUND, + "Error code should be RESOURCE_NOT_FOUND, got %s", + rd_kafka_err2name(err)); + TEST_ASSERT(num_credentials == 0, + "Credentials count should be 0, got %" PRIusz, + num_credentials); + + rd_kafka_event_destroy(event); + + if (!useq) + rd_kafka_queue_destroy(queue); + + SUB_TEST_PASS(); +} + static void do_test_apis(rd_kafka_type_t cltype) { rd_kafka_t *rk; rd_kafka_conf_t *conf; @@ -4026,6 +4341,12 @@ static void do_test_apis(rd_kafka_type_t cltype) { rd_true /*with subscribing consumer*/, rd_true); } + if (test_broker_version >= TEST_BRKVER(2, 7, 0, 0)) { + do_test_UserScramCredentials("main queue", rk, mainq, rd_false); + do_test_UserScramCredentials("temp queue", rk, NULL, rd_false); + do_test_UserScramCredentials("main queue", rk, mainq, rd_true); + } + rd_kafka_queue_destroy(mainq); rd_kafka_destroy(rk); @@ -4037,7 +4358,6 @@ static void do_test_apis(rd_kafka_type_t cltype) { int main_0081_admin(int argc, char **argv) { do_test_apis(RD_KAFKA_PRODUCER); - if (test_quick) { TEST_SAY("Skipping further 0081 tests due to quick mode\n"); return 0; From e75de5be191b6b8e9602efc969f4af64071550de Mon Sep 17 00:00:00 2001 From: Emanuele Sabellico Date: Wed, 12 Jul 2023 11:03:32 +0200 Subject: [PATCH 7/9] Generates a random salt only when (#4350) RAND_priv_bytes is available, since OpenSSL 1.1.1 --- src/rdkafka.h | 5 ++++- src/rdkafka_admin.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/rdkafka.h b/src/rdkafka.h index 2065e72533..b24a9917f9 100644 --- a/src/rdkafka.h +++ b/src/rdkafka.h @@ -8736,7 +8736,7 @@ typedef struct rd_kafka_UserScramCredentialAlteration_s /** * @brief Allocates a new UserScramCredentialUpsertion given its fields. * If salt isn't given a 64 B salt is generated using OpenSSL - * RAND_bytes, if available. + * RAND_priv_bytes, if available. * * @param username The username (not empty). * @param mechanism SASL/SCRAM mechanism. @@ -8746,6 +8746,9 @@ typedef struct rd_kafka_UserScramCredentialAlteration_s * @param salt Salt bytes (optional). * @param salt_size Size of \p salt (optional). * + * @remark A random salt is generated, when NULL, only if OpenSSL >= 1.1.1. + * Otherwise it's a required param. + * * @return A newly created instance of rd_kafka_UserScramCredentialAlteration_t. * Ownership belongs to the caller, use * rd_kafka_UserScramCredentialAlteration_destroy to destroy. diff --git a/src/rdkafka_admin.c b/src/rdkafka_admin.c index dfa38e55d0..8628dd14c3 100644 --- a/src/rdkafka_admin.c +++ b/src/rdkafka_admin.c @@ -5426,7 +5426,7 @@ rd_kafka_UserScramCredentialUpsertion_new(const char *username, alteration->alteration.upsertion.salt = rd_kafkap_bytes_new(salt, salt_size); } else { -#if WITH_SSL +#if WITH_SSL && OPENSSL_VERSION_NUMBER >= 0x10101000L unsigned char random_salt[64]; if (RAND_priv_bytes(random_salt, sizeof(random_salt)) == 1) { alteration->alteration.upsertion.salt = From efc65e776d85e60321950fb4e167d4e2c215f183 Mon Sep 17 00:00:00 2001 From: Emanuele Sabellico Date: Tue, 18 Jul 2023 16:27:34 +0200 Subject: [PATCH 8/9] Update AK 3.5.0 RPCs versions (#4356) --- INTRODUCTION.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/INTRODUCTION.md b/INTRODUCTION.md index 7cb45a2f3d..7d96f8b8fd 100644 --- a/INTRODUCTION.md +++ b/INTRODUCTION.md @@ -1965,7 +1965,7 @@ The [Apache Kafka Implementation Proposals (KIPs)](https://cwiki.apache.org/conf ### Supported protocol versions -"Kafka max" is the maximum ApiVersion supported in Apache Kafka 3.4.0, while +"Kafka max" is the maximum ApiVersion supported in Apache Kafka 3.5.0, while "librdkafka max" is the maximum ApiVersion supported in the latest release of librdkafka. @@ -1973,8 +1973,8 @@ release of librdkafka. | ApiKey | Request name | Kafka max | librdkafka max | | ------- | ------------------------------| ----------- | ----------------------- | | 0 | Produce | 9 | 7 | -| 1 | Fetch | 13 | 11 | -| 2 | ListOffsets | 7 | 2 | +| 1 | Fetch | 15 | 11 | +| 2 | ListOffsets | 8 | 5 | | 3 | Metadata | 12 | 9 | | 8 | OffsetCommit | 8 | 7 | | 9 | OffsetFetch | 8 | 7 | @@ -1991,10 +1991,14 @@ release of librdkafka. | 20 | DeleteTopics | 6 | 1 | | 21 | DeleteRecords | 2 | 1 | | 22 | InitProducerId | 4 | 4 | -| 24 | AddPartitionsToTxn | 3 | 0 | +| 23 | OffsetForLeaderEpoch | 4 | 2 | +| 24 | AddPartitionsToTxn | 4 | 0 | | 25 | AddOffsetsToTxn | 3 | 0 | | 26 | EndTxn | 3 | 1 | | 28 | TxnOffsetCommit | 3 | 3 | +| 29 | DescribeAcls | 3 | 1 | +| 30 | CreateAcls | 3 | 1 | +| 31 | DeleteAcls | 3 | 1 | | 32 | DescribeConfigs | 4 | 1 | | 33 | AlterConfigs | 2 | 2 | | 36 | SaslAuthenticate | 2 | 1 | From c07a3351200704558119fedaf3e61399dbe39482 Mon Sep 17 00:00:00 2001 From: Jeremy Kuhnash <111304461+jkuhnashconfluent@users.noreply.github.com> Date: Mon, 24 Jul 2023 14:25:16 -0400 Subject: [PATCH 9/9] remove semaphore cache as it will not be available on public clusters (#4347) * add debug * remove cache * increase timeout to 3h due to non-caching --- .semaphore/semaphore.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index e46fcdc337..85eabe1e95 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -3,6 +3,8 @@ name: 'librdkafka build and release artifact pipeline' agent: machine: type: s1-prod-macos-arm64 +execution_time_limit: + hours: 3 global_job_config: prologue: commands: @@ -239,11 +241,8 @@ blocks: value: UCRT64 prologue: commands: - - cache restore msys2-x64-${Env:ARTIFACT_KEY} # Set up msys2 - "& .\\win32\\setup-msys2.ps1" - - cache delete msys2-x64-${Env:ARTIFACT_KEY} - - cache store msys2-x64-${Env:ARTIFACT_KEY} c:/msys64 epilogue: commands: - if ($env:SEMAPHORE_GIT_TAG_NAME -ne "") { artifact push workflow artifacts/ --destination artifacts/$Env:ARTIFACT_KEY/ } @@ -277,8 +276,6 @@ blocks: # install vcpkg in the parent directory. - pwd - cd .. - # Restore vcpkg caches, if any. - - cache restore vcpkg-archives-$Env:ARTIFACT_KEY # Setup vcpkg - "& .\\librdkafka\\win32\\setup-vcpkg.ps1" - cd librdkafka @@ -287,11 +284,8 @@ blocks: - ..\vcpkg\vcpkg --feature-flags=versions install --triplet $Env:triplet - cd .. - pwd - # Store vcpkg caches - ls vcpkg/ - echo $Env:VCPKG_ROOT - - cache delete vcpkg-archives-$Env:ARTIFACT_KEY - - cache store vcpkg-archives-$Env:ARTIFACT_KEY C:/Users/semaphore/AppData/Local/vcpkg/archives - pwd - cd librdkafka epilogue: