Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
57c1422
KAFKA-12820: Upgrade maven-artifact dependency to resolve CVE-2021-26291
dongjinleekr May 21, 2021
0c707b1
KAFKA-12522: Cast SMT should allow null value records to pass through…
May 21, 2021
b46e17b
KAFKA-12808: Remove Deprecated Methods under StreamsMetrics (#10724)
jlprat May 21, 2021
aa25176
MINOR: Kafka Streams code samples formating unification (#10651)
jlprat May 21, 2021
72d1082
KAFKA-12620 Allocate producer ids on the controller (#10504)
mumrah May 21, 2021
ae8b784
KAFKA-12499: add transaction timeout verification (#10482)
May 21, 2021
47796d2
MINOR: Fix deprecation warnings in SlidingWindowedCogroupedKStreamImp…
ijuma May 22, 2021
efb7cda
MINOR: update java doc for deprecated methods (#10722)
showuon May 24, 2021
c92e62a
MINOR: Add log identifier/prefix printing in Log layer static functio…
kowshik May 24, 2021
33df5c6
MINOR: clarify message ordering with max in-flight requests and idemp…
ableegoldman May 24, 2021
1d59a3b
Update StateDirectory and Assignment/SubscriptionInfo
ableegoldman Apr 13, 2021
17de7d9
Implement TopologyMetadata
ableegoldman Apr 13, 2021
de43e2d
fix merge error
ableegoldman May 25, 2021
93f0d0a
adding tests, fixing up minor bugs
ableegoldman May 25, 2021
c6e5d3b
fix typo
ableegoldman May 25, 2021
63b6db3
KAFKA-12800: Configure generator to fail on trailing JSON tokens (#10…
cursedquail May 25, 2021
e579148
flush out NamedTopologyTest
ableegoldman May 26, 2021
ca3a0f2
checkstyle
ableegoldman May 26, 2021
22a1281
initial integration tests passing
ableegoldman May 26, 2021
96a0c96
fix clipped newline
ableegoldman May 26, 2021
e3cfcd9
fix restriction
ableegoldman May 26, 2021
f546d84
fixing pattern handling
ableegoldman May 26, 2021
bddc293
fixing up tests
ableegoldman May 26, 2021
e580d43
more tests
ableegoldman May 26, 2021
a74f633
Merge branch 'trunk' of https://github.com/apache/kafka into 12648-To…
ableegoldman May 26, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions checkstyle/suppressions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@

<!-- Streams -->
<suppress checks="ClassFanOutComplexity"
files="(KafkaStreams|KStreamImpl|KTableImpl|StreamsPartitionAssignor).java"/>
files="(KafkaStreams|KStreamImpl|KTableImpl|InternalTopologyBuilder|StreamsPartitionAssignor).java"/>

<suppress checks="MethodLength"
files="KTableImpl.java"/>
Expand Down Expand Up @@ -195,7 +195,7 @@

<!-- Streams tests -->
<suppress checks="ClassFanOutComplexity"
files="(StreamsPartitionAssignorTest|StreamThreadTest|StreamTaskTest|TopologyTestDriverTest).java"/>
files="(StreamsPartitionAssignorTest|StreamThreadTest|StreamTaskTest|TaskManagerTest|TopologyTestDriverTest).java"/>

<suppress checks="MethodLength"
files="(EosIntegrationTest|EosV2UpgradeIntegrationTest|KStreamKStreamJoinTest|RocksDBWindowStoreTest).java"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ public class ProducerConfig extends AbstractConfig {
/** <code>max.in.flight.requests.per.connection</code> */
public static final String MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION = "max.in.flight.requests.per.connection";
private static final String MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION_DOC = "The maximum number of unacknowledged requests the client will send on a single connection before blocking."
+ " Note that if this setting is set to be greater than 1 and there are failed sends, there is a risk of"
+ " message re-ordering due to retries (i.e., if retries are enabled).";
+ " Note that if this config is set to be greater than 1 and <code>enable.idempotence</code> is set to false, there is a risk of"
+ " message re-ordering after a failed send due to retries (i.e., if retries are enabled).";

/** <code>retries</code> */
public static final String RETRIES_CONFIG = CommonClientConfigs.RETRIES_CONFIG;
Expand Down Expand Up @@ -246,10 +246,10 @@ public class ProducerConfig extends AbstractConfig {
public static final String ENABLE_IDEMPOTENCE_CONFIG = "enable.idempotence";
public static final String ENABLE_IDEMPOTENCE_DOC = "When set to 'true', the producer will ensure that exactly one copy of each message is written in the stream. If 'false', producer "
+ "retries due to broker failures, etc., may write duplicates of the retried message in the stream. "
+ "Note that enabling idempotence requires <code>" + MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION + "</code> to be less than or equal to 5, "
+ "<code>" + RETRIES_CONFIG + "</code> to be greater than 0 and <code>" + ACKS_CONFIG + "</code> must be 'all'. If these values "
+ "are not explicitly set by the user, suitable values will be chosen. If incompatible values are set, "
+ "a <code>ConfigException</code> will be thrown.";
+ "Note that enabling idempotence requires <code>" + MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION + "</code> to be less than or equal to 5 "
+ "(with message ordering preserved for any allowable value), <code>" + RETRIES_CONFIG + "</code> to be greater than 0, and <code>"
+ ACKS_CONFIG + "</code> must be 'all'. If these values are not explicitly set by the user, suitable values will be chosen. If incompatible "
+ "values are set, a <code>ConfigException</code> will be thrown.";

/** <code> transaction.timeout.ms </code> */
public static final String TRANSACTION_TIMEOUT_CONFIG = "transaction.timeout.ms";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ public enum ApiKeys {
BROKER_HEARTBEAT(ApiMessageType.BROKER_HEARTBEAT, true, RecordBatch.MAGIC_VALUE_V0, false),
UNREGISTER_BROKER(ApiMessageType.UNREGISTER_BROKER, false, RecordBatch.MAGIC_VALUE_V0, true),
DESCRIBE_TRANSACTIONS(ApiMessageType.DESCRIBE_TRANSACTIONS),
LIST_TRANSACTIONS(ApiMessageType.LIST_TRANSACTIONS);
LIST_TRANSACTIONS(ApiMessageType.LIST_TRANSACTIONS),
ALLOCATE_PRODUCER_IDS(ApiMessageType.ALLOCATE_PRODUCER_IDS, true, false);

private static final Map<ApiMessageType.ListenerType, EnumSet<ApiKeys>> APIS_BY_LISTENER =
new EnumMap<>(ApiMessageType.ListenerType.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,8 @@ private static AbstractRequest doParseRequest(ApiKeys apiKey, short apiVersion,
return DescribeTransactionsRequest.parse(buffer, apiVersion);
case LIST_TRANSACTIONS:
return ListTransactionsRequest.parse(buffer, apiVersion);
case ALLOCATE_PRODUCER_IDS:
return AllocateProducerIdsRequest.parse(buffer, apiVersion);
default:
throw new AssertionError(String.format("ApiKey %s is not currently handled in `parseRequest`, the " +
"code should be updated to do so.", apiKey));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ public static AbstractResponse parseResponse(ApiKeys apiKey, ByteBuffer response
return DescribeTransactionsResponse.parse(responseBuffer, version);
case LIST_TRANSACTIONS:
return ListTransactionsResponse.parse(responseBuffer, version);
case ALLOCATE_PRODUCER_IDS:
return AllocateProducerIdsResponse.parse(responseBuffer, version);
default:
throw new AssertionError(String.format("ApiKey %s is not currently handled in `parseResponse`, the " +
"code should be updated to do so.", apiKey));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.kafka.common.requests;

import org.apache.kafka.common.message.AllocateProducerIdsRequestData;
import org.apache.kafka.common.message.AllocateProducerIdsResponseData;
import org.apache.kafka.common.protocol.ApiKeys;
import org.apache.kafka.common.protocol.ByteBufferAccessor;
import org.apache.kafka.common.protocol.Errors;

import java.nio.ByteBuffer;

public class AllocateProducerIdsRequest extends AbstractRequest {
private final AllocateProducerIdsRequestData data;

public AllocateProducerIdsRequest(AllocateProducerIdsRequestData data, short version) {
super(ApiKeys.ALLOCATE_PRODUCER_IDS, version);
this.data = data;
}

@Override
public AbstractResponse getErrorResponse(int throttleTimeMs, Throwable e) {
return new AllocateProducerIdsResponse(new AllocateProducerIdsResponseData()
.setThrottleTimeMs(throttleTimeMs)
.setErrorCode(Errors.forException(e).code()));
}

@Override
public AllocateProducerIdsRequestData data() {
return data;
}

public static class Builder extends AbstractRequest.Builder<AllocateProducerIdsRequest> {

private final AllocateProducerIdsRequestData data;

public Builder(AllocateProducerIdsRequestData data) {
super(ApiKeys.ALLOCATE_PRODUCER_IDS);
this.data = data;
}

@Override
public AllocateProducerIdsRequest build(short version) {
return new AllocateProducerIdsRequest(data, version);
}

@Override
public String toString() {
return data.toString();
}
}

public static AllocateProducerIdsRequest parse(ByteBuffer buffer, short version) {
return new AllocateProducerIdsRequest(new AllocateProducerIdsRequestData(
new ByteBufferAccessor(buffer), version), version);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.kafka.common.requests;

import org.apache.kafka.common.message.AllocateProducerIdsResponseData;
import org.apache.kafka.common.protocol.ApiKeys;
import org.apache.kafka.common.protocol.ByteBufferAccessor;
import org.apache.kafka.common.protocol.Errors;

import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.Map;

public class AllocateProducerIdsResponse extends AbstractResponse {

private final AllocateProducerIdsResponseData data;

public AllocateProducerIdsResponse(AllocateProducerIdsResponseData data) {
super(ApiKeys.ALLOCATE_PRODUCER_IDS);
this.data = data;
}

@Override
public AllocateProducerIdsResponseData data() {
return data;
}

/**
* The number of each type of error in the response, including {@link Errors#NONE} and top-level errors as well as
* more specifically scoped errors (such as topic or partition-level errors).
*
* @return A count of errors.
*/
@Override
public Map<Errors, Integer> errorCounts() {
return Collections.singletonMap(Errors.forCode(data.errorCode()), 1);
}

@Override
public int throttleTimeMs() {
return data.throttleTimeMs();
}

public static AllocateProducerIdsResponse parse(ByteBuffer buffer, short version) {
return new AllocateProducerIdsResponse(new AllocateProducerIdsResponseData(
new ByteBufferAccessor(buffer), version));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implie
// See the License for the specific language governing permissions and
// limitations under the License.

{
"apiKey": 67,
"type": "request",
"listeners": ["controller", "zkBroker"],
"name": "AllocateProducerIdsRequest",
"validVersions": "0",
"flexibleVersions": "0+",
"fields": [
{ "name": "BrokerId", "type": "int32", "versions": "0+", "entityType": "brokerId",
"about": "The ID of the requesting broker" },
{ "name": "BrokerEpoch", "type": "int64", "versions": "0+", "default": "-1",
"about": "The epoch of the requesting broker" }
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

{
"apiKey": 67,
"type": "response",
"name": "AllocateProducerIdsResponse",
"validVersions": "0",
"flexibleVersions": "0+",
"fields": [
{ "name": "ThrottleTimeMs", "type": "int32", "versions": "0+",
"about": "The duration in milliseconds for which the request was throttled due to a quota violation, or zero if the request did not violate any quota." },
{ "name": "ErrorCode", "type": "int16", "versions": "0+",
"about": "The top level response error code" },
{ "name": "ProducerIdStart", "type": "int64", "versions": "0+", "entityType": "producerId",
"about": "The first producer ID in this range, inclusive"},
{ "name": "ProducerIdLen", "type": "int32", "versions": "0+",
"about": "The number of producer IDs in this range"}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public void testAlterIsrIsClusterAction() {
public void testResponseThrottleTime() {
Set<ApiKeys> authenticationKeys = EnumSet.of(ApiKeys.SASL_HANDSHAKE, ApiKeys.SASL_AUTHENTICATE);
// Newer protocol apis include throttle time ms even for cluster actions
Set<ApiKeys> clusterActionsWithThrottleTimeMs = EnumSet.of(ApiKeys.ALTER_ISR);
Set<ApiKeys> clusterActionsWithThrottleTimeMs = EnumSet.of(ApiKeys.ALTER_ISR, ApiKeys.ALLOCATE_PRODUCER_IDS);
for (ApiKeys apiKey: ApiKeys.zkBrokerApis()) {
Schema responseSchema = apiKey.messageType.responseSchemas()[apiKey.latestVersion()];
BoundField throttleTimeField = responseSchema.get("throttle_time_ms");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ public void configure(Map<String, ?> props) {

@Override
public R apply(R record) {
if (operatingValue(record) == null) {
return record;
}

if (operatingSchema(record) == null) {
return applySchemaless(record);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,42 @@ public void testConfigMixWholeAndFieldTransformation() {
assertThrows(ConfigException.class, () -> xformKey.configure(Collections.singletonMap(Cast.SPEC_CONFIG, "foo:int8,int32")));
}

@Test
public void castNullValueRecordWithSchema() {
xformValue.configure(Collections.singletonMap(Cast.SPEC_CONFIG, "foo:int64"));
SourceRecord original = new SourceRecord(null, null, "topic", 0,
Schema.STRING_SCHEMA, "key", Schema.STRING_SCHEMA, null);
SourceRecord transformed = xformValue.apply(original);
assertEquals(original, transformed);
}

@Test
public void castNullValueRecordSchemaless() {
xformValue.configure(Collections.singletonMap(Cast.SPEC_CONFIG, "foo:int64"));
SourceRecord original = new SourceRecord(null, null, "topic", 0,
Schema.STRING_SCHEMA, "key", null, null);
SourceRecord transformed = xformValue.apply(original);
assertEquals(original, transformed);
}

@Test
public void castNullKeyRecordWithSchema() {
xformKey.configure(Collections.singletonMap(Cast.SPEC_CONFIG, "foo:int64"));
SourceRecord original = new SourceRecord(null, null, "topic", 0,
Schema.STRING_SCHEMA, null, Schema.STRING_SCHEMA, "value");
SourceRecord transformed = xformKey.apply(original);
assertEquals(original, transformed);
}

@Test
public void castNullKeyRecordSchemaless() {
xformKey.configure(Collections.singletonMap(Cast.SPEC_CONFIG, "foo:int64"));
SourceRecord original = new SourceRecord(null, null, "topic", 0,
null, null, Schema.STRING_SCHEMA, "value");
SourceRecord transformed = xformKey.apply(original);
assertEquals(original, transformed);
}

@Test
public void castWholeRecordKeyWithSchema() {
xformKey.configure(Collections.singletonMap(Cast.SPEC_CONFIG, "int8"));
Expand Down
13 changes: 12 additions & 1 deletion core/src/main/scala/kafka/api/ApiVersion.scala
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ object ApiVersion {
// Flexible versioning on ListOffsets, WriteTxnMarkers and OffsetsForLeaderEpoch. Also adds topic IDs (KIP-516)
KAFKA_2_8_IV0,
// Introduced topic IDs to LeaderAndIsr and UpdateMetadata requests/responses (KIP-516)
KAFKA_2_8_IV1
KAFKA_2_8_IV1,
// Introduce AllocateProducerIds (KIP-730)
KAFKA_3_0_IV0
)

// Map keys are the union of the short and full versions
Expand Down Expand Up @@ -197,6 +199,8 @@ sealed trait ApiVersion extends Ordered[ApiVersion] {

def isAlterIsrSupported: Boolean = this >= KAFKA_2_7_IV2

def isAllocateProducerIdsSupported: Boolean = this >= KAFKA_3_0_IV0

override def compare(that: ApiVersion): Int =
ApiVersion.orderingByVersion.compare(this, that)

Expand Down Expand Up @@ -447,6 +451,13 @@ case object KAFKA_2_8_IV1 extends DefaultApiVersion {
val id: Int = 32
}

case object KAFKA_3_0_IV0 extends DefaultApiVersion {
val shortVersion: String = "3.0"
val subVersion = "IV0"
val recordVersion = RecordVersion.V2
val id: Int = 33
}

object ApiVersionValidator extends Validator {

override def ensureValid(name: String, value: Any): Unit = {
Expand Down
Loading