mirror of https://github.com/apache/kafka.git
KAFKA-2707: make KStream processor names deterministic
guozhangwang Author: Yasuhiro Matsuda <yasuhiro@confluent.io> Reviewers: Guozhang Wang Closes #408 from ymatsuda/kstream_processor_name
This commit is contained in:
parent
1f5d05fe71
commit
e466ccd711
|
|
@ -22,12 +22,15 @@ import org.apache.kafka.streams.kstream.internals.KStreamImpl;
|
|||
import org.apache.kafka.streams.processor.TopologyBuilder;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* KStreamBuilder is the class to create KStream instances.
|
||||
*/
|
||||
public class KStreamBuilder extends TopologyBuilder {
|
||||
|
||||
private final AtomicInteger index = new AtomicInteger(0);
|
||||
|
||||
public KStreamBuilder() {
|
||||
super();
|
||||
}
|
||||
|
|
@ -40,7 +43,7 @@ public class KStreamBuilder extends TopologyBuilder {
|
|||
* @return KStream
|
||||
*/
|
||||
public <K, V> KStream<K, V> from(String... topics) {
|
||||
String name = KStreamImpl.SOURCE_NAME + KStreamImpl.INDEX.getAndIncrement();
|
||||
String name = newName(KStreamImpl.SOURCE_NAME);
|
||||
|
||||
addSource(name, topics);
|
||||
|
||||
|
|
@ -58,10 +61,14 @@ public class KStreamBuilder extends TopologyBuilder {
|
|||
* @return KStream
|
||||
*/
|
||||
public <K, V> KStream<K, V> from(Deserializer<? extends K> keyDeserializer, Deserializer<? extends V> valDeserializer, String... topics) {
|
||||
String name = KStreamImpl.SOURCE_NAME + KStreamImpl.INDEX.getAndIncrement();
|
||||
String name = newName(KStreamImpl.SOURCE_NAME);
|
||||
|
||||
addSource(name, keyDeserializer, valDeserializer, topics);
|
||||
|
||||
return new KStreamImpl<>(this, name, Collections.singleton(name));
|
||||
}
|
||||
|
||||
public String newName(String prefix) {
|
||||
return prefix + String.format("%010d", index.getAndIncrement());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.apache.kafka.streams.kstream.internals;
|
|||
|
||||
import org.apache.kafka.common.serialization.Deserializer;
|
||||
import org.apache.kafka.common.serialization.Serializer;
|
||||
import org.apache.kafka.streams.kstream.KStreamBuilder;
|
||||
import org.apache.kafka.streams.kstream.KeyValue;
|
||||
import org.apache.kafka.streams.kstream.TransformerSupplier;
|
||||
import org.apache.kafka.streams.kstream.ValueTransformerSupplier;
|
||||
|
|
@ -29,12 +30,10 @@ import org.apache.kafka.streams.kstream.Predicate;
|
|||
import org.apache.kafka.streams.kstream.ValueMapper;
|
||||
import org.apache.kafka.streams.kstream.WindowSupplier;
|
||||
import org.apache.kafka.streams.processor.ProcessorSupplier;
|
||||
import org.apache.kafka.streams.processor.TopologyBuilder;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class KStreamImpl<K, V> implements KStream<K, V> {
|
||||
|
||||
|
|
@ -70,13 +69,11 @@ public class KStreamImpl<K, V> implements KStream<K, V> {
|
|||
|
||||
public static final String SOURCE_NAME = "KAFKA-SOURCE-";
|
||||
|
||||
public static final AtomicInteger INDEX = new AtomicInteger(1);
|
||||
|
||||
protected final TopologyBuilder topology;
|
||||
protected final KStreamBuilder topology;
|
||||
protected final String name;
|
||||
protected final Set<String> sourceNodes;
|
||||
|
||||
public KStreamImpl(TopologyBuilder topology, String name, Set<String> sourceNodes) {
|
||||
public KStreamImpl(KStreamBuilder topology, String name, Set<String> sourceNodes) {
|
||||
this.topology = topology;
|
||||
this.name = name;
|
||||
this.sourceNodes = sourceNodes;
|
||||
|
|
@ -84,7 +81,7 @@ public class KStreamImpl<K, V> implements KStream<K, V> {
|
|||
|
||||
@Override
|
||||
public KStream<K, V> filter(Predicate<K, V> predicate) {
|
||||
String name = FILTER_NAME + INDEX.getAndIncrement();
|
||||
String name = topology.newName(FILTER_NAME);
|
||||
|
||||
topology.addProcessor(name, new KStreamFilter<>(predicate, false), this.name);
|
||||
|
||||
|
|
@ -93,7 +90,7 @@ public class KStreamImpl<K, V> implements KStream<K, V> {
|
|||
|
||||
@Override
|
||||
public KStream<K, V> filterOut(final Predicate<K, V> predicate) {
|
||||
String name = FILTER_NAME + INDEX.getAndIncrement();
|
||||
String name = topology.newName(FILTER_NAME);
|
||||
|
||||
topology.addProcessor(name, new KStreamFilter<>(predicate, true), this.name);
|
||||
|
||||
|
|
@ -102,7 +99,7 @@ public class KStreamImpl<K, V> implements KStream<K, V> {
|
|||
|
||||
@Override
|
||||
public <K1, V1> KStream<K1, V1> map(KeyValueMapper<K, V, KeyValue<K1, V1>> mapper) {
|
||||
String name = MAP_NAME + INDEX.getAndIncrement();
|
||||
String name = topology.newName(MAP_NAME);
|
||||
|
||||
topology.addProcessor(name, new KStreamMap<>(mapper), this.name);
|
||||
|
||||
|
|
@ -111,7 +108,7 @@ public class KStreamImpl<K, V> implements KStream<K, V> {
|
|||
|
||||
@Override
|
||||
public <V1> KStream<K, V1> mapValues(ValueMapper<V, V1> mapper) {
|
||||
String name = MAPVALUES_NAME + INDEX.getAndIncrement();
|
||||
String name = topology.newName(MAPVALUES_NAME);
|
||||
|
||||
topology.addProcessor(name, new KStreamMapValues<>(mapper), this.name);
|
||||
|
||||
|
|
@ -120,7 +117,7 @@ public class KStreamImpl<K, V> implements KStream<K, V> {
|
|||
|
||||
@Override
|
||||
public <K1, V1> KStream<K1, V1> flatMap(KeyValueMapper<K, V, Iterable<KeyValue<K1, V1>>> mapper) {
|
||||
String name = FLATMAP_NAME + INDEX.getAndIncrement();
|
||||
String name = topology.newName(FLATMAP_NAME);
|
||||
|
||||
topology.addProcessor(name, new KStreamFlatMap<>(mapper), this.name);
|
||||
|
||||
|
|
@ -129,7 +126,7 @@ public class KStreamImpl<K, V> implements KStream<K, V> {
|
|||
|
||||
@Override
|
||||
public <V1> KStream<K, V1> flatMapValues(ValueMapper<V, Iterable<V1>> mapper) {
|
||||
String name = FLATMAPVALUES_NAME + INDEX.getAndIncrement();
|
||||
String name = topology.newName(FLATMAPVALUES_NAME);
|
||||
|
||||
topology.addProcessor(name, new KStreamFlatMapValues<>(mapper), this.name);
|
||||
|
||||
|
|
@ -138,7 +135,7 @@ public class KStreamImpl<K, V> implements KStream<K, V> {
|
|||
|
||||
@Override
|
||||
public KStreamWindowed<K, V> with(WindowSupplier<K, V> windowSupplier) {
|
||||
String name = WINDOWED_NAME + INDEX.getAndIncrement();
|
||||
String name = topology.newName(WINDOWED_NAME);
|
||||
|
||||
topology.addProcessor(name, new KStreamWindow<>(windowSupplier), this.name);
|
||||
|
||||
|
|
@ -148,13 +145,13 @@ public class KStreamImpl<K, V> implements KStream<K, V> {
|
|||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public KStream<K, V>[] branch(Predicate<K, V>... predicates) {
|
||||
String branchName = BRANCH_NAME + INDEX.getAndIncrement();
|
||||
String branchName = topology.newName(BRANCH_NAME);
|
||||
|
||||
topology.addProcessor(branchName, new KStreamBranch(predicates.clone()), this.name);
|
||||
|
||||
KStream<K, V>[] branchChildren = (KStream<K, V>[]) Array.newInstance(KStream.class, predicates.length);
|
||||
for (int i = 0; i < predicates.length; i++) {
|
||||
String childName = BRANCHCHILD_NAME + INDEX.getAndIncrement();
|
||||
String childName = topology.newName(BRANCHCHILD_NAME);
|
||||
|
||||
topology.addProcessor(childName, new KStreamPassThrough<K, V>(), branchName);
|
||||
|
||||
|
|
@ -170,11 +167,11 @@ public class KStreamImpl<K, V> implements KStream<K, V> {
|
|||
Serializer<V> valSerializer,
|
||||
Deserializer<K1> keyDeserializer,
|
||||
Deserializer<V1> valDeserializer) {
|
||||
String sendName = SINK_NAME + INDEX.getAndIncrement();
|
||||
String sendName = topology.newName(SINK_NAME);
|
||||
|
||||
topology.addSink(sendName, topic, keySerializer, valSerializer, this.name);
|
||||
|
||||
String sourceName = SOURCE_NAME + INDEX.getAndIncrement();
|
||||
String sourceName = topology.newName(SOURCE_NAME);
|
||||
|
||||
topology.addSource(sourceName, keyDeserializer, valDeserializer, topic);
|
||||
|
||||
|
|
@ -188,21 +185,21 @@ public class KStreamImpl<K, V> implements KStream<K, V> {
|
|||
|
||||
@Override
|
||||
public void to(String topic) {
|
||||
String name = SINK_NAME + INDEX.getAndIncrement();
|
||||
String name = topology.newName(SINK_NAME);
|
||||
|
||||
topology.addSink(name, topic, this.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void to(String topic, Serializer<K> keySerializer, Serializer<V> valSerializer) {
|
||||
String name = SINK_NAME + INDEX.getAndIncrement();
|
||||
String name = topology.newName(SINK_NAME);
|
||||
|
||||
topology.addSink(name, topic, keySerializer, valSerializer, this.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K1, V1> KStream<K1, V1> transform(TransformerSupplier<K, V, KeyValue<K1, V1>> transformerSupplier, String... stateStoreNames) {
|
||||
String name = TRANSFORM_NAME + INDEX.getAndIncrement();
|
||||
String name = topology.newName(TRANSFORM_NAME);
|
||||
|
||||
topology.addProcessor(name, new KStreamTransform<>(transformerSupplier), this.name);
|
||||
topology.connectProcessorAndStateStores(name, stateStoreNames);
|
||||
|
|
@ -212,7 +209,7 @@ public class KStreamImpl<K, V> implements KStream<K, V> {
|
|||
|
||||
@Override
|
||||
public <V1> KStream<K, V1> transformValues(ValueTransformerSupplier<V, V1> valueTransformerSupplier, String... stateStoreNames) {
|
||||
String name = TRANSFORMVALUES_NAME + INDEX.getAndIncrement();
|
||||
String name = topology.newName(TRANSFORMVALUES_NAME);
|
||||
|
||||
topology.addProcessor(name, new KStreamTransformValues<>(valueTransformerSupplier), this.name);
|
||||
topology.connectProcessorAndStateStores(name, stateStoreNames);
|
||||
|
|
@ -222,7 +219,7 @@ public class KStreamImpl<K, V> implements KStream<K, V> {
|
|||
|
||||
@Override
|
||||
public void process(final ProcessorSupplier<K, V> processorSupplier, String... stateStoreNames) {
|
||||
String name = PROCESSOR_NAME + INDEX.getAndIncrement();
|
||||
String name = topology.newName(PROCESSOR_NAME);
|
||||
|
||||
topology.addProcessor(name, processorSupplier, this.name);
|
||||
topology.connectProcessorAndStateStores(name, stateStoreNames);
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@ package org.apache.kafka.streams.kstream.internals;
|
|||
|
||||
import org.apache.kafka.common.KafkaException;
|
||||
import org.apache.kafka.streams.kstream.KStream;
|
||||
import org.apache.kafka.streams.kstream.KStreamBuilder;
|
||||
import org.apache.kafka.streams.kstream.KStreamWindowed;
|
||||
import org.apache.kafka.streams.kstream.ValueJoiner;
|
||||
import org.apache.kafka.streams.kstream.WindowSupplier;
|
||||
import org.apache.kafka.streams.processor.TopologyBuilder;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
|
@ -31,7 +31,7 @@ public final class KStreamWindowedImpl<K, V> extends KStreamImpl<K, V> implement
|
|||
|
||||
private final WindowSupplier<K, V> windowSupplier;
|
||||
|
||||
public KStreamWindowedImpl(TopologyBuilder topology, String name, Set<String> sourceNodes, WindowSupplier<K, V> windowSupplier) {
|
||||
public KStreamWindowedImpl(KStreamBuilder topology, String name, Set<String> sourceNodes, WindowSupplier<K, V> windowSupplier) {
|
||||
super(topology, name, sourceNodes);
|
||||
this.windowSupplier = windowSupplier;
|
||||
}
|
||||
|
|
@ -53,9 +53,9 @@ public final class KStreamWindowedImpl<K, V> extends KStreamImpl<K, V> implement
|
|||
KStreamJoin<K, V2, V1, V> joinOther = new KStreamJoin<>(thisWindowName, KStreamJoin.reverseJoiner(valueJoiner));
|
||||
KStreamPassThrough<K, V2> joinMerge = new KStreamPassThrough<>();
|
||||
|
||||
String joinThisName = JOINTHIS_NAME + INDEX.getAndIncrement();
|
||||
String joinOtherName = JOINOTHER_NAME + INDEX.getAndIncrement();
|
||||
String joinMergeName = JOINMERGE_NAME + INDEX.getAndIncrement();
|
||||
String joinThisName = topology.newName(JOINTHIS_NAME);
|
||||
String joinOtherName = topology.newName(JOINOTHER_NAME);
|
||||
String joinMergeName = topology.newName(JOINMERGE_NAME);
|
||||
|
||||
topology.addProcessor(joinThisName, joinThis, this.name);
|
||||
topology.addProcessor(joinOtherName, joinOther, ((KStreamImpl) other).name);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ import org.apache.kafka.streams.kstream.internals.KStreamImpl;
|
|||
import org.apache.kafka.streams.processor.TopologyException;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class KStreamBuilderTest {
|
||||
|
||||
@Test(expected = TopologyException.class)
|
||||
|
|
@ -29,6 +31,21 @@ public class KStreamBuilderTest {
|
|||
|
||||
builder.from("topic-1", "topic-2");
|
||||
|
||||
builder.addSource(KStreamImpl.SOURCE_NAME + KStreamImpl.INDEX.decrementAndGet(), "topic-3");
|
||||
builder.addSource(KStreamImpl.SOURCE_NAME + "0000000000", "topic-3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNewName() {
|
||||
KStreamBuilder builder = new KStreamBuilder();
|
||||
|
||||
assertEquals("X-0000000000", builder.newName("X-"));
|
||||
assertEquals("Y-0000000001", builder.newName("Y-"));
|
||||
assertEquals("Z-0000000002", builder.newName("Z-"));
|
||||
|
||||
builder = new KStreamBuilder();
|
||||
|
||||
assertEquals("X-0000000000", builder.newName("X-"));
|
||||
assertEquals("Y-0000000001", builder.newName("Y-"));
|
||||
assertEquals("Z-0000000002", builder.newName("Z-"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue