Search in sources :

Example 1 with StreamSourceNode

use of org.apache.kafka.streams.kstream.internals.graph.StreamSourceNode in project kafka by apache.

the class InternalStreamsBuilder method mergeDuplicateSourceNodes.

private void mergeDuplicateSourceNodes() {
    final Map<String, StreamSourceNode<?, ?>> topicsToSourceNodes = new HashMap<>();
    // We don't really care about the order here, but since Pattern does not implement equals() we can't rely on
    // a regular HashMap and containsKey(Pattern). But for our purposes it's sufficient to compare the compiled
    // string and flags to determine if two pattern subscriptions can be merged into a single source node
    final Map<Pattern, StreamSourceNode<?, ?>> patternsToSourceNodes = new TreeMap<>(Comparator.comparing(Pattern::pattern).thenComparing(Pattern::flags));
    for (final GraphNode graphNode : root.children()) {
        if (graphNode instanceof StreamSourceNode) {
            final StreamSourceNode<?, ?> currentSourceNode = (StreamSourceNode<?, ?>) graphNode;
            if (currentSourceNode.topicPattern().isPresent()) {
                final Pattern topicPattern = currentSourceNode.topicPattern().get();
                if (!patternsToSourceNodes.containsKey(topicPattern)) {
                    patternsToSourceNodes.put(topicPattern, currentSourceNode);
                } else {
                    final StreamSourceNode<?, ?> mainSourceNode = patternsToSourceNodes.get(topicPattern);
                    mainSourceNode.merge(currentSourceNode);
                    root.removeChild(graphNode);
                }
            } else {
                for (final String topic : currentSourceNode.topicNames().get()) {
                    if (!topicsToSourceNodes.containsKey(topic)) {
                        topicsToSourceNodes.put(topic, currentSourceNode);
                    } else {
                        final StreamSourceNode<?, ?> mainSourceNode = topicsToSourceNodes.get(topic);
                        // this by splitting these source nodes into one topic per node and routing to the subscribed children
                        if (!mainSourceNode.topicNames().equals(currentSourceNode.topicNames())) {
                            LOG.error("Topic {} was found in  subscription for non-equal source nodes {} and {}", topic, mainSourceNode, currentSourceNode);
                            throw new TopologyException("Two source nodes are subscribed to overlapping but not equal input topics");
                        }
                        mainSourceNode.merge(currentSourceNode);
                        root.removeChild(graphNode);
                    }
                }
            }
        }
    }
}
Also used : StreamSourceNode(org.apache.kafka.streams.kstream.internals.graph.StreamSourceNode) Pattern(java.util.regex.Pattern) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) GraphNode(org.apache.kafka.streams.kstream.internals.graph.GraphNode) TreeMap(java.util.TreeMap) TopologyException(org.apache.kafka.streams.errors.TopologyException)

Aggregations

HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 TreeMap (java.util.TreeMap)1 Pattern (java.util.regex.Pattern)1 TopologyException (org.apache.kafka.streams.errors.TopologyException)1 GraphNode (org.apache.kafka.streams.kstream.internals.graph.GraphNode)1 StreamSourceNode (org.apache.kafka.streams.kstream.internals.graph.StreamSourceNode)1