Commit Graph

10811 Commits

Author SHA1 Message Date
Mickael Maison 40af3a7450
KAFKA-14413: Separate MirrorMaker configurations for each connector (#12899)
Reviewers: Luke Chen <showuon@gmail.com>, Chris Egerton <fearthecellos@gmail.com>, Christo Lolov  <christo_lolov@yahoo.com>
2022-11-30 18:37:37 +01:00
Joel Hamill d9946a7ffc
MINOR: Fix config documentation formatting (#12921)
Reviewers: José Armando García Sancio <jsancio@apache.org>
2022-11-30 08:54:39 -08:00
Chris Egerton 548348c9e7
KAFKA-13731: Allow standalone workers to be started without providing any connector configurations (#11890)
Reviewers: Yash Mayya <yash.mayya@gmail.com>, Mickael Maison <mickael.maison@gmail.com>
2022-11-30 11:49:24 -05:00
JK-Wang 9baa5023d3
MINOR: Fix docs in security.html (#12851)
Reviewers: Mickael Maison <mickael.maison@gmail.com>
2022-11-30 16:42:16 +01:00
Ismael Juma 528a4ba1a7
MINOR: Remove config/kraft/README.md from rat exclusion list (#12923)
This file was deleted a while back.

Reviewers: Luke Chen <showuon@gmail.com>
2022-11-30 05:28:05 -08:00
Ismael Juma 8d65271a0b
MINOR: Update Gradle to 7.6 (#12918)
The highlights are:
* Support for Java 19
* Support for incremental compilation following a compilation failure
* Flag for individual task rerun (eg "gradle test --rerun")
* Re-use Scala compiler between runs (will be enabled via #12280)

Release notes: https://docs.gradle.org/7.6/release-notes.html

Also adjusted the directory used by `retry_zinc` for the build output from
`build` to `logs` as `gradlew clean` was causing unintended deletion of
the file used by that tool to decide if a retry is required.

Reviewers: Manikumar Reddy <manikumar.reddy@gmail.com>
2022-11-30 05:25:56 -08:00
Divij Vaidya b2d8354e10
KAFKA-14414: Fix request/response header size calculation (#12917)
Reviewers: Mickael Maison <mickael.maison@gmail.com>, Luke Chen <showuon@gmail.com>
2022-11-30 12:17:21 +01:00
Greg Harris 3799125c2f
KAFKA-14339 : Do not perform producerCommit on serializationError when trying offsetWriter flush (#12920)
Reviewers: Chris Egerton <chrise@aiven.io>
2022-11-29 19:06:30 -05:00
David Jacot 98e19b3000
KAFKA-14367; Add `JoinGroup` to the new `GroupCoordinator` interface (#12845)
This patch adds `joinGroup` to the new `GroupCoordinator` interface and updates `KafkaApis` to use it.

For the context, I will do the same for all the other interactions with the current group coordinator. In order to limit the changes, I have chosen to introduce the `GroupCoordinatorAdapter` that translates the new interface to the old one. It is basically a wrapper. This allows keeping the current group coordinator untouched for now and focus on the `KafkaApis` changes. Eventually, we can remove `GroupCoordinatorAdapter`.

Reviewers: Justine Olshan <jolshan@confluent.io>, Jeff Kim <jeff.kim@confluent.io>, Luke Chen <showuon@gmail.com>, Jason Gustafson <jason@confluent.io>
2022-11-29 20:39:12 +01:00
Ismael Juma 471e029f0a
MINOR: buildoutput.log should be under the `build` directory (#12919)
Otherwise it can cause `rat` to fail.

Note that this file is created by the `retry_zinc` script.

Reviewers: Jason Gustafson <jason@confluent.io>
2022-11-29 11:03:39 -08:00
Greg Harris d3ee9341cc
KAFKA-12476: Prevent herder tick thread from sleeping excessively after slow operations (#12876)
Reviewers: Chris Egerton <chrise@aiven.io>
2022-11-29 09:40:39 -05:00
David Jacot c2c8b246c9
MINOR: JoinGroup and SyncGroup callbacks should catch exceptions (#12910)
We recently had a bug causing the JoinGroup callback to thrown an exception (https://github.com/apache/kafka/pull/12909). When it happens, the exception is propagated to the caller and the JoinGroup callback is never completed. To make it worst, the member whose callback failed become a zombie because the group coordinator does not expire member with a pending callback.

This patch catch exceptions for both invocation of JoinGroup and SyncGroup callbacks and retry to complete them with a `UNKNOWN_SERVER_ERROR` error if they failed.

Reviewers: Jason Gustafson <jason@confluent.io>
2022-11-29 09:48:31 +01:00
David Jacot be032735b3
KAFKA-14422; Consumer rebalance stuck after new static member joins a group with members not supporting static members (#12909)
When a consumer group on a version prior to 2.3 is upgraded to a newer version and static membership is enabled in the meantime, the consumer group remains stuck, iff the leader is still on the old version.

The issue is that setting `GroupInstanceId` in the response to the leader is only supported from JoinGroup version >= 5 and that `GroupInstanceId` is not ignorable nor handled anywhere else. Hence is there is at least one static member in the group, sending the JoinGroup response to the leader fails with a serialization error.

```
org.apache.kafka.common.errors.UnsupportedVersionException: Attempted to write a non-default groupInstanceId at version 2
```

When this happens, the member stays around until the group coordinator is bounced because a member with a non-null `awaitingJoinCallback` is never expired.

This patch fixes the issue by making `GroupInstanceId` ignorable. A unit test has been modified to cover this.

Reviewers: Jason Gustafson <jason@confluent.io>
2022-11-28 20:15:54 +01:00
José Armando García Sancio 2ab1e6cb57
KAFKA-14393; Default metadata retition by bytes (#12884)
Now that Kafka is generating a metadata snapshot every hour and
the default metadata retention is to delete snapshots after 7 days,
every cluster metadata partition will have 168 (1 snapshot per hour
* 24 hours per day * 7 days) snapshots. If we assume that in most
cases the size of the snapshot is determined by the number of
partitions in a cluster, a cluster with 100K partitions will have a
snapshot size of roughly 10MB (100 bytes per partition * 100k
partitions). For this kind of clusters the cluster metadata partition
will always consume around 1.7GB.

KIP-876 changed the default value for metadata.max.retention.bytes
to 100MB. This should limit the size of the cluster metadata
partition for large clusters but keep 7 days worth of snapshots for
small clusters.

Reviewers: Jason Gustafson <jason@confluent.io>
2022-11-28 10:39:57 -08:00
Lucas Brutschy 9ea3d0d1c8
KAFKA-12679: Handle lock exceptions in state updater (#12875)
In this change, we enable backing off when the state directory
is still locked during initialization of a task. When the state
directory is locked, the task is reinserted into the
initialization queue. We will reattempt to acquire the lock
after the next round of polling.

Tested through a new unit test.

Reviewer: Bruno Cadonna <cadonna@apache.org>
2022-11-28 17:17:14 +01:00
Divij Vaidya edfa894eb5
KAFKA-14414: Remove unnecessary usage of ObjectSerializationCache (#12890)
Reviewers: Mickael Maison <mickael.maison@gmail.com>
2022-11-28 15:15:34 +01:00
Lucas Brutschy fea0eb4ca3
KAFKA-14299: Handle double rebalances better (#12904)
The original implementation of the state updater could not
handle double rebalances within one poll phase correctly,
because it could create tasks more than once if they hadn't
finished initialization yet.

In a55071a, we
moved initialization to the state updater to fix this. However,
with more testing, I found out that this implementation has
it's problems as well: There are problems with locking the
state directory (state updater acquired the lock to the state
directory, so the main thread wouldn't be able to clear the
state directory when closing the task), and benchmarks also
show that this can lead to useless work (tasks are being
initialized, although they will be taken from the thread soon
after in a follow-up rebalance).

In this PR, I propose to revert the original change, and fix
the original problem in a much simpler way: When we
receive an assignment, we simply clear out the
list of tasks pending initialization. This way, no double
tasks instantiations can happen.

The change was tested in benchmarks, system tests,
and the existing unit & integration tests. We also add
the state updater to the smoke integration test, which
triggered the double task instantiations before.

Reviewer: Bruno Cadonna <cadonna@apache.org>
2022-11-28 13:16:44 +01:00
Luke Chen 5166890f3e
KAFKA-14242: use mock managers to avoid duplicated resource allocation (#12639)
Recently, we got a lot of build failed (and terminated) with core:unitTest failure. The failed messages look like this:

FAILURE: Build failed with an exception.
[2022-09-14T09:51:52.190Z] 
[2022-09-14T09:51:52.190Z] * What went wrong:
[2022-09-14T09:51:52.190Z] Execution failed for task ':core:unitTest'.
[2022-09-14T09:51:52.190Z] > Process 'Gradle Test Executor 128' finished with non-zero exit value 1

After investigation, I found one reason of it (maybe there are other reasons). In BrokerMetadataPublisherTest#testReloadUpdatedFilesWithoutConfigChange test, we created logManager twice, but when cleanup, we only close one of them. So, there will be a log cleaner keeping running. But during this time, the temp log dirs are deleted, so it will Exit.halt(1), and got the error we saw in gradle, like this code did when we encounter IOException in all our log dirs:

fatal(s"Shutdown broker because all log dirs in ${logDirs.mkString(", ")} have failed")
Exit.halt(1)

And, why does it sometimes pass, sometimes failed? Because during test cluster close, we shutdown broker first, and then other components. And the log cleaner is triggered in an interval. So, if the cluster can close fast enough, and finish this test, it'll be passed. Otherwise, it'll exit with 1.

Fixed it by mock log manager and other managers in mock publisher to avoid duplicate resource allocation. This change won't change the original test goal since we only want to make sure publisher will invoke reloadUpdatedFilesWithoutConfigChange when necessary.

Reviewers: dengziming <dengziming1993@gmail.com>
2022-11-28 10:37:40 +08:00
Divij Vaidya c8a228d122
MINOR: Improve Scala collection usage (#12900)
Reviewers: Mickael Maison <mickael.maison@gmail.com>
, Christo Lolov <christo_lolov@yahoo.com>
2022-11-25 11:14:21 +01:00
zou shengfu d139379e50
KAFKA-14009: Rebalance timeout should be updated when static member rejoins
When consumers use static membership protocol, they can not update the rebalance timeout because the group coordinator simply ignore any new values. This patch fixes this.

Reviewers: David Jacot <djacot@confluent.io>
2022-11-24 15:18:28 +01:00
Jeff Kim 9d8b4e94b7
KAFKA-14372: Choose replicas only from ISR for preferred read replica (#12877)
The default replica selector chooses a replica on whether the broker.rack matches the client.rack in the fetch request and whether the offset exists in the follower. If the follower is not in the ISR, we know it's lagging behind which will also lag the consumer behind. there are two cases:
1. the follower recovers and joins the isr. the consumer will no longer fall behind.
2. the follower continues to lag behind. after 5 minutes, the consumer will refresh its preferred read replica and the leader will return the same lagging follower since the offset the consumer fetched up to is capped by the follower's HWM. this can go on indefinitely.

If the replica selector chooses a broker in the ISR then we can ensure that at least every 5 minutes the consumer will consume from an up-to-date replica. 

Reviewers: David Jacot <djacot@confluent.io>
2022-11-24 15:04:43 +01:00
Greg Harris cc77a38d28
KAFKA-12610: Implement PluginClassLoader::getResource and getResources (#12805)
Reviewers: Chris Egerton <chrise@aiven.io>
2022-11-23 08:37:51 -05:00
Divij Vaidya 19286449ee
MINOR: Remove possibility of overriding test files clean up (#12889)
Reviewers: Chris Egerton <chrise@aiven.io>
2022-11-22 11:06:33 -05:00
行路难行路难 1874f2388c
MINOR: Don't call `scheduleAtFixedRate` when period is 0 (#12882)
Since `scheduleAtFixedRate` doesn't allow period <= 0, we should use `schedule` when period == 0.

Reviewers: Luke Chen <showuon@gmail.com>
2022-11-22 11:34:08 +08:00
José Armando García Sancio 72b535acaf
KAFKA-14307; Controller time-based snapshots (#12761)
Implement time based snapshot for the controller. The general strategy for this feature is that the controller will use the record-batch's append time to determine if a snapshot should be generated. If the oldest record that has been committed but is not included in the latest snapshot is older than `metadata.log.max.snapshot.interval.ms`, the controller will trigger a snapshot immediately. This is useful in case the controller was offline for more that `metadata.log.max.snapshot.interval.ms` milliseconds.

If the oldest record that has been committed but is not included in the latest snapshot is NOT older than `metadata.log.max.snapshot.interval.ms`, the controller will schedule a `maybeGenerateSnapshot` deferred task.

It is possible that when the controller wants to generate a new snapshot, either because of time or number of bytes, the controller is currently generating a snapshot. In this case the `SnapshotGeneratorManager` was changed so that it checks and potentially triggers another snapshot when the currently in-progress snapshot finishes.

To better support this feature the following additional changes were made:
1. The configuration `metadata.log.max.snapshot.interval.ms` was added to `KafkaConfig` with a default value of one hour.
2. `RaftClient` was extended to return the latest snapshot id. This snapshot id is used to determine if a given record is included in a snapshot.
3. Improve the `SnapshotReason` type to support the inclusion of values in the message.

Reviewers: Jason Gustafson <jason@confluent.io>, Niket Goel <niket-goel@users.noreply.github.com>
2022-11-21 17:30:50 -08:00
Artem Livshits 36f933fc5f
Minor; fix sticky partitioner doc to say at least batch.size (#12880)
Reviewers: Jun Rao <junrao@gmail.com>
2022-11-21 09:10:04 -08:00
Christo Lolov 54efc4f109
KAFKA-14133: Replace EasyMock with Mockito in streams tests (#12505)
Batch 2 of the tests detailed in https://issues.apache.org/jira/browse/KAFKA-14133 which use EasyMock and need to be moved to Mockito.

Reviewers: Matthew de Detrich <matthew.dedetrich@aiven.io>, Dalibor Plavcic <dalibor.os@proton.me>, Bruno Cadonna <cadonna@apache.org
2022-11-21 13:12:22 +01:00
Jorge Esteban Quilcate Otoya 0de037423b
KAFKA-14325: Fix NPE on Processor Parameters toString (#12859)
Handle null processor supplier

Reviewers: Anna Sophie Blee-Goldman <ableegoldman@apache.org>
2022-11-20 18:24:04 -08:00
A. Sophie Blee-Goldman 56ab2f8034
KAFKA-14382: wait for current rebalance to complete before triggering followup (#12869)
Fix for the subtle bug described in KAFKA-14382 that was causing rebalancing loops. If we trigger a new rebalance while the current one is still ongoing, it may cause some members to fail the first rebalance if they weren't able to send the SyncGroup request in time (for example due to processing records during the rebalance). This means those consumers never receive their assignment from the original rebalance, and won't revoke any partitions they might have needed to. This can send the group into a loop as each rebalance schedules a new followup cooperative rebalance due to partitions that need to be revoked, and each followup rebalance causes some consumer(s) to miss the SyncGroup and never revoke those partitions.

Reviewers: John Roesler <vvcephei@apache.org>
2022-11-18 22:38:58 -08:00
Nick Telford 1d6430249b
KAFKA-14406: Fix double iteration of restoring records (#12842)
While restoring a batch of records, RocksDBStore was iterating the ConsumerRecords, building a list of KeyValues, and then iterating that list of KeyValues to add them to the RocksDB batch.

Simply adding the key and value directly to the RocksDB batch prevents this unnecessary second iteration, and the creation of itermediate KeyValue objects, improving the performance of state restoration, and reducing unnecessary object allocation.

This also simplifies the API of RocksDBAccessor, as prepareBatchForRestore is no longer needed.

Reviewers: Anna Sophie Blee-Goldman <ableegoldman@apache.org>, Walker Carlson <wcarlson@confluent.io>
2022-11-18 20:44:56 -08:00
Pratim SC 795390a3c8
KAFKA-14320: Updated Jackson to version 2.13.4 for fixing CVE-2022-42004 (#12840)
* Updated Jackson to version 2.13.4 for fixing CVE-2022-42004, CVE-2020-36518
* Updated Jackson data bind to version 2.13.4.2 for fixing CVE-2022-42004

Co-authored-by: Pratim SC <pratim.sunilkumar.chaudhuri@mercer.com>

 Reviewers: Luke Chen <showuon@gmail.com>, Manikumar Reddy <manikumar.reddy@gmail.com>
2022-11-18 23:28:49 +05:30
Dan Stelljes 93dd6ce21a
KAFKA-13586: Prevent exception thrown during connector update from crashing distributed herder (#12295)
Reviewers: Kvicii <kvicii.yu@gmail.com>, Chris Egerton <chrise@aiven.io>
2022-11-18 09:49:52 -05:00
Joel Hamill 95499c409f
MINOR: fix syntax typo (#12868)
Reviewers: Luke Chen <showuon@gmail.com>
2022-11-18 11:13:11 +08:00
Greg Harris 31c69ae932
KAFKA-14346: Remove hard-to-mock javax.crypto calls (#12866)
Reviewers: Chris Egerton <chrise@aiven.io>
2022-11-17 18:10:17 -05:00
Greg Harris fca5bfe13c
KAFKA-14346: Remove hard-to-mock RestClient calls (#12828)
Reviewers: Chris Egerton <chrise@aiven.io>
2022-11-17 17:51:54 -05:00
Igor Soarez 5bd556a49b
KAFKA-14303 Producer.send without record key and batch.size=0 goes into infinite loop (#12752)
This fixes an bug which causes a call to producer.send(record) with a record without a key and configured with batch.size=0 never to return.

Without specifying a key or a custom partitioner the new BuiltInPartitioner, as described in KIP-749 kicks in.

BuiltInPartitioner seems to have been designed with the reasonable assumption that the batch size will never be lower than one.

However, documentation for producer configuration states batch.size=0 as a valid value, and even recommends its use directly. [1]

[1] clients/src/main/java/org/apache/kafka/clients/producer/ProducerConfig.java:87

Reviewers: Artem Livshits <alivshits@confluent.io>, Luke Chen <showuon@gmail.com>, Ismael Juma <ismael@juma.me.uk>, Jun Rao <junrao@gmail.com>
2022-11-17 14:27:02 -08:00
Proven Provenzano 529a44d5cf
KAFKA-14375: Remove use of "authorizer-properties" from EndToEndAuthorizerTest (#12843)
- This removes use of a deprecated feature and instead has all ACL
calls going through the brokers. This work is preliminary work
needed before I can make them run in KRAFT mode.

Reviewers: Manikumar Reddy <manikumar.reddy@gmail.com>,  Igor Soarez <soarez@apple.com>
2022-11-17 21:49:00 +05:30
Greg Harris 7a93d5c833
KAFKA-14346: Replace static mocking of WorkerConfig::lookupKafkaClusterId (#12839)
Reviewers: Mickael Maison <mickael.maison@gmail.com>
2022-11-17 10:32:39 +01:00
Bill Bejeck 3012332e3d
KAFKA-14388 - Fixes the NPE when using the new Processor API with the DSL (#12861)
With the addition of the new Processor API the newly added FixedKeyProcessorNodeFactory extends the ProcessorNodeFactory class. The ProcessorNodeFactory had a private field Set<String> stateStoreNames initialized to an empty see. The FixedKeyProcessorNodeFactory also had a private field Set<String> stateStoreNames.

When executing InternalTopologyBuilder.build executing the buildProcessorNode method passed any node factory as ProcessorNodeFactory and the method references the stateStoreNames field, it's pointing to the superclass field, which is empty so the corresponding StoreBuilder(s) are never added - causing NPE in the topology.

This PR makes the field protected on the ProcessorNodeFactory class so FixedKeyProcessorNodeFactory inherits it.

The added test fails without this change.

Reviewers: Matthias J. Sax <mjsax@apache.org>,  Sophie Blee-Goldman <sophie@confluent.io>, Jorge Esteban Quilcate Otoya <quilcate.jorge@gmail.com>
2022-11-16 17:06:15 -05:00
David Jacot c2fc36f331
MINOR: Handle JoinGroupResponseData.protocolName backward compatibility in JoinGroupResponse (#12864)
This is a small refactor extracted from https://github.com/apache/kafka/pull/12845. It basically moves the logic to handle the backward compatibility of `JoinGroupResponseData.protocolName` from `KafkaApis` to `JoinGroupResponse`.

The patch adds a new unit test for `JoinGroupResponse` and relies on existing tests as well.

Reviewers: Justine Olshan <jolshan@confluent.io>, Jason Gustafson <jason@confluent.io>
2022-11-16 12:43:00 -08:00
Hao Li 76214bfb85
KAFKA-13785: Add JavaDocs for emit final (#12867)
Reviewers: Matthias J. Sax <matthias@confluent.io>
2022-11-16 11:30:24 -08:00
Jeff Kim dbf5826cd5
KAFKA-14334: Complete delayed purgatory after replication (#12783)
When a consumer makes a fetch request to a follower (KIP-392), the fetch request will sit in the purgatory until `fetch.max.wait.ms` is reached because the purgatory is not completed after replication. This patch aims to complete the delayed fetch purgatory after successfully replicating from the leader.

Reviewers: Artem Livshits <alivshits@confluent.io>, Luke Chen <showuon@gmail.com>, David Jacot <djacot@confluent.io>
2022-11-16 14:54:42 +01:00
Shay Lin 039cccca24
KAFKA-14360: Fix links in documentation (#12857)
Reviewers: Matthias J. Sax <matthias@confluent.io>
2022-11-15 13:31:35 -08:00
Christo Lolov 1894856d0e
KAFKA-13414: Replace PowerMock/EasyMock with Mockito in connect.storage.KafkaOffsetBackingStoreTest (#12418)
Reviewers: Chris Egerton <chrise@aiven.io>
2022-11-15 16:30:52 -05:00
vamossagar12 09da44ed80
KAFKA-12495: Exponential backoff retry to prevent rebalance storms when worker joins after revoking rebalance (#12561)
Reviewers: Yash Mayya <yash.mayya@gmail.com>, Luke Chen <showuon@gmail.com>, Chris Egerton <chrise@aiven.io>
2022-11-15 16:26:21 -05:00
Omnia G H Ibrahim 46bee5bcf3
KAFKA-13401: KIP-787 - MM2 manage Kafka resources with custom Admin implementation. (#12577)
Reviewers: Mickael Maison <mickael.maison@gmail.com>, Tom Bentley <tombentley@users.noreply.github.com>

Co-authored-by: Tom Bentley <tombentley@users.noreply.github.com>
Co-authored-by: oibrahim3 <omnia@apple.com>
2022-11-15 11:21:24 +01:00
Lucas Brutschy a55071a99f
KAFKA-14299: Initialize tasks in state updater (#12795)
The state updater code path puts tasks into an
"initialization queue", with created, but not initialized tasks.
These are later, during the event-loop, initialized and added
to the state updater. This might lead to losing track of those 
tasks - in particular it is possible to create
tasks twice, if we do not go once around `runLoop` to initialize
the task. This leads to `IllegalStateExceptions`. 

By handing the task to the state updater immediately and let the
state updater initialize the task, we can fulfil our promise to 
preserve the invariant "every task is owned by either the task 
registry or the state updater".

Reviewer: Bruno Cadonna <cadonna@apache.org>
2022-11-14 10:00:29 +01:00
A. Sophie Blee-Goldman e422a67d3f
KAFKA-14294: check whether a transaction is in flight before skipping a commit (#12835)
Add a new #transactionInFlight API to the StreamsProducer to expose the flag of the same name, then check whether there is an open transaction when we determine whether or not to perform a commit in TaskExecutor. This is to avoid unnecessarily dropping out of the group on transaction timeout in the case a transaction was begun outside of regular processing, eg when a punctuator forwards records but there are no newly consumer records and thus no new offsets to commit.

Reviewer: Bruno Cadonna <cadonna@apache.org>
2022-11-14 09:43:46 +01:00
A. Sophie Blee-Goldman 51b7eb7937
KAFKA-14282: stop tracking Produced sensors by processor node id (#12836)
Users have been seeing a large number of these error messages being logged by the RecordCollectorImpl:

Unable to records bytes produced to topic XXX by sink node YYY as the node is not recognized.
It seems like we try to save all known sink nodes when the record collector is constructed, by we do so by going through the known sink topics which means we could miss some nodes, for example if dynamic topic routing is used. Previously we were logging an error and would skip recording the metric if we tried to send a record from a sink node it didn't recognize, but there's not really any reason to have been tracking the sensors by node in the first place -- we can just track the actual sink topics themselves.

Reviewers: John Roesler <vvcephei@apache.org>, Christo Lolov <lolovc@amazon.com>
2022-11-11 17:58:08 -08:00
Christo Lolov 876c338a60
[KAFKA-14324] Upgrade RocksDB to 7.1.2 (#12809)
Reviewers: Bruno Cadonna <cadonna@confluent.io>, Anna Sophie Blee-Goldman <ableegoldman@apache.org>
2022-11-11 17:48:38 -08:00