Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.apache.kafka.common.errors.TimeoutException;
import org.apache.kafka.common.serialization.ByteArraySerializer;
import org.apache.kafka.common.serialization.Deserializer;
import org.apache.kafka.common.serialization.Serde;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.kafka.common.utils.Exit;
import org.apache.kafka.common.utils.Utils;
Expand Down Expand Up @@ -60,7 +61,7 @@
import static org.apache.kafka.common.utils.Utils.mkEntry;

public class SmokeTestDriver extends SmokeTestUtil {
private static final String[] TOPICS = {
private static final String[] NUMERIC_VALUE_TOPICS = {
"data",
"echo",
"max",
Expand All @@ -72,6 +73,15 @@ public class SmokeTestDriver extends SmokeTestUtil {
"avg",
"tagg"
};
private static final String[] STRING_VALUE_TOPICS = {
"fk"
};

private static final String[] TOPICS = new String[NUMERIC_VALUE_TOPICS.length + STRING_VALUE_TOPICS.length];
static {
System.arraycopy(NUMERIC_VALUE_TOPICS, 0, TOPICS, 0, NUMERIC_VALUE_TOPICS.length);
System.arraycopy(STRING_VALUE_TOPICS, 0, TOPICS, NUMERIC_VALUE_TOPICS.length, STRING_VALUE_TOPICS.length);
}

private static final int MAX_RECORD_EMPTY_RETRIES = 30;

Expand Down Expand Up @@ -163,7 +173,8 @@ public static Map<String, Set<Integer>> generate(final String kafka,

final long recordPauseTime = timeToSpend.toMillis() / numKeys / maxRecordsPerKey;

List<ProducerRecord<byte[], byte[]>> needRetry = new ArrayList<>();
final List<ProducerRecord<byte[], byte[]>> dataNeedRetry = new ArrayList<>();
final List<ProducerRecord<byte[], byte[]>> fkNeedRetry = new ArrayList<>();

try (final KafkaProducer<byte[], byte[]> producer = new KafkaProducer<>(producerProps)) {
while (remaining > 0) {
Expand All @@ -183,7 +194,16 @@ public static Map<String, Set<Integer>> generate(final String kafka,
intSerde.serializer().serialize("", value)
);

producer.send(record, new TestCallback(record, needRetry));
producer.send(record, new TestCallback(record, dataNeedRetry));

final ProducerRecord<byte[], byte[]> fkRecord =
new ProducerRecord<>(
"fk",
intSerde.serializer().serialize("", value),
stringSerde.serializer().serialize("", key)
);

producer.send(fkRecord, new TestCallback(fkRecord, fkNeedRetry));

numRecordsProduced++;
allData.get(key).add(value);
Expand All @@ -195,36 +215,60 @@ public static Map<String, Set<Integer>> generate(final String kafka,
}
producer.flush();

int remainingRetries = 5;
while (!needRetry.isEmpty()) {
final List<ProducerRecord<byte[], byte[]>> needRetry2 = new ArrayList<>();
for (final ProducerRecord<byte[], byte[]> record : needRetry) {
System.out.println("retry producing " + stringSerde.deserializer().deserialize("", record.key()));
producer.send(record, new TestCallback(record, needRetry2));
}
producer.flush();
needRetry = needRetry2;
retry(producer, dataNeedRetry, stringSerde);
retry(producer, fkNeedRetry, intSerde);

if (--remainingRetries == 0 && !needRetry.isEmpty()) {
System.err.println("Failed to produce all records after multiple retries");
Exit.exit(1);
}
flush(producer,
"data",
stringSerde.serializer().serialize("", "flush"),
intSerde.serializer().serialize("", 0)
);
flush(producer,
"fk",
intSerde.serializer().serialize("", 0),
stringSerde.serializer().serialize("", "flush")
);

}
return Collections.unmodifiableMap(allData);
}

private static void retry(final KafkaProducer<byte[], byte[]> producer,
List<ProducerRecord<byte[], byte[]>> needRetry,
final Serde<?> keySerde) {
int remainingRetries = 5;
while (!needRetry.isEmpty()) {
final List<ProducerRecord<byte[], byte[]>> needRetry2 = new ArrayList<>();
for (final ProducerRecord<byte[], byte[]> record : needRetry) {
System.out.println("retry producing " + keySerde.deserializer().deserialize("", record.key()));
producer.send(record, new TestCallback(record, needRetry2));
}
producer.flush();
needRetry = needRetry2;

// now that we've sent everything, we'll send some final records with a timestamp high enough to flush out
// all suppressed records.
final List<PartitionInfo> partitions = producer.partitionsFor("data");
for (final PartitionInfo partition : partitions) {
producer.send(new ProducerRecord<>(
partition.topic(),
partition.partition(),
System.currentTimeMillis() + Duration.ofDays(2).toMillis(),
stringSerde.serializer().serialize("", "flush"),
intSerde.serializer().serialize("", 0)
));
if (--remainingRetries == 0 && !needRetry.isEmpty()) {
System.err.println("Failed to produce all records after multiple retries");
Exit.exit(1);
}
}
return Collections.unmodifiableMap(allData);
}

private static void flush(final KafkaProducer<byte[], byte[]> producer,
final String topic,
final byte[] keyBytes,
final byte[] valBytes) {
// now that we've sent everything, we'll send some final records with a timestamp high enough to flush out
// all suppressed records.
final List<PartitionInfo> partitions = producer.partitionsFor(topic);
for (final PartitionInfo partition : partitions) {
producer.send(new ProducerRecord<>(
partition.topic(),
partition.partition(),
System.currentTimeMillis() + Duration.ofDays(2).toMillis(),
keyBytes,
valBytes
));
}
}

private static Properties generatorProperties(final String kafka) {
Expand Down Expand Up @@ -315,14 +359,14 @@ public static VerificationResult verify(final String kafka,
props.put(ConsumerConfig.ISOLATION_LEVEL_CONFIG, "read_committed");

final KafkaConsumer<String, Number> consumer = new KafkaConsumer<>(props);
final List<TopicPartition> partitions = getAllPartitions(consumer, TOPICS);
final List<TopicPartition> partitions = getAllPartitions(consumer, NUMERIC_VALUE_TOPICS);
consumer.assign(partitions);
consumer.seekToBeginning(partitions);

final int recordsGenerated = inputs.size() * maxRecordsPerKey;
int recordsProcessed = 0;
final Map<String, AtomicInteger> processed =
Stream.of(TOPICS)
Stream.of(NUMERIC_VALUE_TOPICS)
.collect(Collectors.toMap(t -> t, t -> new AtomicInteger(0)));

final Map<String, Map<String, LinkedList<ConsumerRecord<String, Number>>>> events = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.apache.kafka.common.errors.TimeoutException;
import org.apache.kafka.common.serialization.ByteArraySerializer;
import org.apache.kafka.common.serialization.Deserializer;
import org.apache.kafka.common.serialization.Serde;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.kafka.common.utils.Exit;
import org.apache.kafka.common.utils.Utils;
Expand Down Expand Up @@ -60,7 +61,7 @@
import static org.apache.kafka.common.utils.Utils.mkEntry;

public class SmokeTestDriver extends SmokeTestUtil {
private static final String[] TOPICS = {
private static final String[] NUMERIC_VALUE_TOPICS = {
"data",
"echo",
"max",
Expand All @@ -72,6 +73,14 @@ public class SmokeTestDriver extends SmokeTestUtil {
"avg",
"tagg"
};
private static final String[] STRING_VALUE_TOPICS = {
"fk"
};
private static final String[] TOPICS = new String[NUMERIC_VALUE_TOPICS.length + STRING_VALUE_TOPICS.length];
static {
System.arraycopy(NUMERIC_VALUE_TOPICS, 0, TOPICS, 0, NUMERIC_VALUE_TOPICS.length);
System.arraycopy(STRING_VALUE_TOPICS, 0, TOPICS, NUMERIC_VALUE_TOPICS.length, STRING_VALUE_TOPICS.length);
}

private static final int MAX_RECORD_EMPTY_RETRIES = 30;

Expand Down Expand Up @@ -148,7 +157,6 @@ public static Map<String, Set<Integer>> generate(final String kafka,
final Duration timeToSpend) {
final Properties producerProps = generatorProperties(kafka);


int numRecordsProduced = 0;

final Map<String, Set<Integer>> allData = new HashMap<>();
Expand All @@ -163,7 +171,8 @@ public static Map<String, Set<Integer>> generate(final String kafka,

final long recordPauseTime = timeToSpend.toMillis() / numKeys / maxRecordsPerKey;

List<ProducerRecord<byte[], byte[]>> needRetry = new ArrayList<>();
final List<ProducerRecord<byte[], byte[]>> dataNeedRetry = new ArrayList<>();
final List<ProducerRecord<byte[], byte[]>> fkNeedRetry = new ArrayList<>();

try (final KafkaProducer<byte[], byte[]> producer = new KafkaProducer<>(producerProps)) {
while (remaining > 0) {
Expand All @@ -175,15 +184,21 @@ public static Map<String, Set<Integer>> generate(final String kafka,
remaining--;
data[index] = data[remaining];
} else {

final ProducerRecord<byte[], byte[]> record =
new ProducerRecord<>(
"data",
stringSerde.serializer().serialize("", key),
intSerde.serializer().serialize("", value)
);
producer.send(record, new TestCallback(record, dataNeedRetry));

producer.send(record, new TestCallback(record, needRetry));
final ProducerRecord<byte[], byte[]> fkRecord =
new ProducerRecord<>(
"fk",
intSerde.serializer().serialize("", value),
stringSerde.serializer().serialize("", key)
);
producer.send(fkRecord, new TestCallback(fkRecord, fkNeedRetry));

numRecordsProduced++;
allData.get(key).add(value);
Expand All @@ -195,36 +210,59 @@ public static Map<String, Set<Integer>> generate(final String kafka,
}
producer.flush();

int remainingRetries = 5;
while (!needRetry.isEmpty()) {
final List<ProducerRecord<byte[], byte[]>> needRetry2 = new ArrayList<>();
for (final ProducerRecord<byte[], byte[]> record : needRetry) {
System.out.println("retry producing " + stringSerde.deserializer().deserialize("", record.key()));
producer.send(record, new TestCallback(record, needRetry2));
}
producer.flush();
needRetry = needRetry2;
retry(producer, dataNeedRetry, stringSerde);
retry(producer, fkNeedRetry, intSerde);

flush(producer,
"data",
stringSerde.serializer().serialize("", "flush"),
intSerde.serializer().serialize("", 0)
);
flush(producer,
"fk",
intSerde.serializer().serialize("", 0),
stringSerde.serializer().serialize("", "flush")
);
}
return Collections.unmodifiableMap(allData);
}

if (--remainingRetries == 0 && !needRetry.isEmpty()) {
System.err.println("Failed to produce all records after multiple retries");
Exit.exit(1);
}
private static void retry(final KafkaProducer<byte[], byte[]> producer,
List<ProducerRecord<byte[], byte[]>> needRetry,
final Serde<?> keySerde) {
int remainingRetries = 5;
while (!needRetry.isEmpty()) {
final List<ProducerRecord<byte[], byte[]>> needRetry2 = new ArrayList<>();
for (final ProducerRecord<byte[], byte[]> record : needRetry) {
System.out.println(
"retry producing " + keySerde.deserializer().deserialize("", record.key()));
producer.send(record, new TestCallback(record, needRetry2));
}

// now that we've sent everything, we'll send some final records with a timestamp high enough to flush out
// all suppressed records.
final List<PartitionInfo> partitions = producer.partitionsFor("data");
for (final PartitionInfo partition : partitions) {
producer.send(new ProducerRecord<>(
partition.topic(),
partition.partition(),
System.currentTimeMillis() + Duration.ofDays(2).toMillis(),
stringSerde.serializer().serialize("", "flush"),
intSerde.serializer().serialize("", 0)
));
producer.flush();
needRetry = needRetry2;
if (--remainingRetries == 0 && !needRetry.isEmpty()) {
System.err.println("Failed to produce all records after multiple retries");
Exit.exit(1);
}
}
return Collections.unmodifiableMap(allData);
}

private static void flush(final KafkaProducer<byte[], byte[]> producer,
final String topic,
final byte[] keyBytes,
final byte[] valBytes) {
// now that we've sent everything, we'll send some final records with a timestamp high enough to flush out
// all suppressed records.
final List<PartitionInfo> partitions = producer.partitionsFor(topic);
for (final PartitionInfo partition : partitions) {
producer.send(new ProducerRecord<>(
partition.topic(),
partition.partition(),
System.currentTimeMillis() + Duration.ofDays(2).toMillis(),
keyBytes,
valBytes
));
}
}

private static Properties generatorProperties(final String kafka) {
Expand Down Expand Up @@ -315,14 +353,14 @@ public static VerificationResult verify(final String kafka,
props.put(ConsumerConfig.ISOLATION_LEVEL_CONFIG, "read_committed");

final KafkaConsumer<String, Number> consumer = new KafkaConsumer<>(props);
final List<TopicPartition> partitions = getAllPartitions(consumer, TOPICS);
final List<TopicPartition> partitions = getAllPartitions(consumer, NUMERIC_VALUE_TOPICS);
consumer.assign(partitions);
consumer.seekToBeginning(partitions);

final int recordsGenerated = inputs.size() * maxRecordsPerKey;
int recordsProcessed = 0;
final Map<String, AtomicInteger> processed =
Stream.of(TOPICS)
Stream.of(NUMERIC_VALUE_TOPICS)
.collect(Collectors.toMap(t -> t, t -> new AtomicInteger(0)));

final Map<String, Map<String, LinkedList<ConsumerRecord<String, Number>>>> events = new HashMap<>();
Expand Down
Loading