org.apache.kafka.streams.kstream.StreamJoined Maven / Gradle / Ivy
/*
* 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.streams.kstream;
import org.apache.kafka.common.serialization.Serde;
import org.apache.kafka.streams.state.WindowBytesStoreSupplier;
import java.util.HashMap;
import java.util.Map;
/**
* Class used to configure the name of the join processor, the repartition topic name,
* state stores or state store names in Stream-Stream join.
* @param the key type
* @param this value type
* @param other value type
*/
public class StreamJoined implements NamedOperation> {
protected final Serde keySerde;
protected final Serde valueSerde;
protected final Serde otherValueSerde;
protected final WindowBytesStoreSupplier thisStoreSupplier;
protected final WindowBytesStoreSupplier otherStoreSupplier;
protected final String name;
protected final String storeName;
protected final boolean loggingEnabled;
protected final Map topicConfig;
protected StreamJoined(final StreamJoined streamJoined) {
this(streamJoined.keySerde,
streamJoined.valueSerde,
streamJoined.otherValueSerde,
streamJoined.thisStoreSupplier,
streamJoined.otherStoreSupplier,
streamJoined.name,
streamJoined.storeName,
streamJoined.loggingEnabled,
streamJoined.topicConfig);
}
private StreamJoined(final Serde keySerde,
final Serde valueSerde,
final Serde otherValueSerde,
final WindowBytesStoreSupplier thisStoreSupplier,
final WindowBytesStoreSupplier otherStoreSupplier,
final String name,
final String storeName,
final boolean loggingEnabled,
final Map topicConfig) {
this.keySerde = keySerde;
this.valueSerde = valueSerde;
this.otherValueSerde = otherValueSerde;
this.thisStoreSupplier = thisStoreSupplier;
this.otherStoreSupplier = otherStoreSupplier;
this.name = name;
this.storeName = storeName;
this.loggingEnabled = loggingEnabled;
this.topicConfig = topicConfig;
}
/**
* Creates a StreamJoined instance with the provided store suppliers. The store suppliers must implement
* the {@link WindowBytesStoreSupplier} interface. The store suppliers must provide unique names or a
* {@link org.apache.kafka.streams.errors.StreamsException} is thrown.
*
* @param storeSupplier this store supplier
* @param otherStoreSupplier other store supplier
* @param the key type
* @param this value type
* @param other value type
* @return {@link StreamJoined} instance
*/
public static StreamJoined with(final WindowBytesStoreSupplier storeSupplier,
final WindowBytesStoreSupplier otherStoreSupplier) {
return new StreamJoined<>(
null,
null,
null,
storeSupplier,
otherStoreSupplier,
null,
null,
true,
new HashMap<>()
);
}
/**
* Creates a {@link StreamJoined} instance using the provided name for the state stores and hence the changelog
* topics for the join stores. The name for the stores will be ${applicationId}-<storeName>-this-join and ${applicationId}-<storeName>-other-join
* or ${applicationId}-<storeName>-outer-this-join and ${applicationId}-<storeName>-outer-other-join depending if the join is an inner-join
* or an outer join. The changelog topics will have the -changelog suffix. The user should note that even though the join stores will have a
* specified name, the stores will remain unavailable for querying.
*
* @param storeName The name to use for the store
* @param The key type
* @param This value type
* @param Other value type
* @return {@link StreamJoined} instance
*/
public static StreamJoined as(final String storeName) {
return new StreamJoined<>(
null,
null,
null,
null,
null,
null,
storeName,
true,
new HashMap<>()
);
}
/**
* Creates a {@link StreamJoined} instance with the provided serdes to configure the stores
* for the join.
* @param keySerde The key serde
* @param valueSerde This value serde
* @param otherValueSerde Other value serde
* @param The key type
* @param This value type
* @param Other value type
* @return {@link StreamJoined} instance
*/
public static StreamJoined with(final Serde keySerde,
final Serde valueSerde,
final Serde otherValueSerde
) {
return new StreamJoined<>(
keySerde,
valueSerde,
otherValueSerde,
null,
null,
null,
null,
true,
new HashMap<>()
);
}
/**
* Set the name to use for the join processor and the repartition topic(s) if required.
* @param name the name to use
* @return a new {@link StreamJoined} instance
*/
@Override
public StreamJoined withName(final String name) {
return new StreamJoined<>(
keySerde,
valueSerde,
otherValueSerde,
thisStoreSupplier,
otherStoreSupplier,
name,
storeName,
loggingEnabled,
topicConfig
);
}
/**
* Sets the base store name to use for both sides of the join. The name for the state stores and hence the changelog
* topics for the join stores. The name for the stores will be ${applicationId}-<storeName>-this-join and ${applicationId}-<storeName>-other-join
* or ${applicationId}-<storeName>-outer-this-join and ${applicationId}-<storeName>-outer-other-join depending if the join is an inner-join
* or an outer join. The changelog topics will have the -changelog suffix. The user should note that even though the join stores will have a
* specified name, the stores will remain unavailable for querying.
*
* @param storeName the storeName to use
* @return a new {@link StreamJoined} instance
*/
public StreamJoined withStoreName(final String storeName) {
return new StreamJoined<>(
keySerde,
valueSerde,
otherValueSerde,
thisStoreSupplier,
otherStoreSupplier,
name,
storeName,
loggingEnabled,
topicConfig
);
}
/**
* Configure with the provided {@link Serde Serde} for the key
* @param keySerde the serde to use for the key
* @return a new {@link StreamJoined} configured with the keySerde
*/
public StreamJoined withKeySerde(final Serde keySerde) {
return new StreamJoined<>(
keySerde,
valueSerde,
otherValueSerde,
thisStoreSupplier,
otherStoreSupplier,
name,
storeName,
loggingEnabled,
topicConfig
);
}
/**
* Configure with the provided {@link Serde Serde} for this value
* @param valueSerde the serde to use for this value (calling or left side of the join)
* @return a new {@link StreamJoined} configured with the valueSerde
*/
public StreamJoined withValueSerde(final Serde valueSerde) {
return new StreamJoined<>(
keySerde,
valueSerde,
otherValueSerde,
thisStoreSupplier,
otherStoreSupplier,
name,
storeName,
loggingEnabled,
topicConfig
);
}
/**
* Configure with the provided {@link Serde Serde} for the other value
* @param otherValueSerde the serde to use for the other value (other or right side of the join)
* @return a new {@link StreamJoined} configured with the otherValueSerde
*/
public StreamJoined withOtherValueSerde(final Serde otherValueSerde) {
return new StreamJoined<>(
keySerde,
valueSerde,
otherValueSerde,
thisStoreSupplier,
otherStoreSupplier,
name,
storeName,
loggingEnabled,
topicConfig
);
}
/**
* Configure with the provided {@link WindowBytesStoreSupplier} for this store supplier. Please note
* this method only provides the store supplier for the left side of the join. If you wish to also provide a
* store supplier for the right (i.e., other) side you must use the {@link StreamJoined#withOtherStoreSupplier(WindowBytesStoreSupplier)}
* method
* @param thisStoreSupplier the store supplier to use for this store supplier (calling or left side of the join)
* @return a new {@link StreamJoined} configured with thisStoreSupplier
*/
public StreamJoined withThisStoreSupplier(final WindowBytesStoreSupplier thisStoreSupplier) {
return new StreamJoined<>(
keySerde,
valueSerde,
otherValueSerde,
thisStoreSupplier,
otherStoreSupplier,
name,
storeName,
loggingEnabled,
topicConfig
);
}
/**
* Configure with the provided {@link WindowBytesStoreSupplier} for the other store supplier. Please note
* this method only provides the store supplier for the right side of the join. If you wish to also provide a
* store supplier for the left side you must use the {@link StreamJoined#withThisStoreSupplier(WindowBytesStoreSupplier)}
* method
* @param otherStoreSupplier the store supplier to use for the other store supplier (other or right side of the join)
* @return a new {@link StreamJoined} configured with otherStoreSupplier
*/
public StreamJoined withOtherStoreSupplier(final WindowBytesStoreSupplier otherStoreSupplier) {
return new StreamJoined<>(
keySerde,
valueSerde,
otherValueSerde,
thisStoreSupplier,
otherStoreSupplier,
name,
storeName,
loggingEnabled,
topicConfig
);
}
/**
* Configures logging for both state stores. The changelog will be created with the provided configs.
*
* Note: Any unrecognized configs will be ignored
* @param config configs applied to the changelog topic
* @return a new {@link StreamJoined} configured with logging enabled
*/
public StreamJoined withLoggingEnabled(final Map config) {
return new StreamJoined<>(
keySerde,
valueSerde,
otherValueSerde,
thisStoreSupplier,
otherStoreSupplier,
name,
storeName,
true,
config
);
}
/**
* Disable change logging for both state stores.
* @return a new {@link StreamJoined} configured with logging disabled
*/
public StreamJoined withLoggingDisabled() {
return new StreamJoined<>(
keySerde,
valueSerde,
otherValueSerde,
thisStoreSupplier,
otherStoreSupplier,
name,
storeName,
false,
new HashMap<>()
);
}
@Override
public String toString() {
return "StreamJoin{" +
"keySerde=" + keySerde +
", valueSerde=" + valueSerde +
", otherValueSerde=" + otherValueSerde +
", thisStoreSupplier=" + thisStoreSupplier +
", otherStoreSupplier=" + otherStoreSupplier +
", name='" + name + '\'' +
", storeName='" + storeName + '\'' +
", loggingEnabled=" + loggingEnabled +
", topicConfig=" + topicConfig +
'}';
}
}