Kafka-GH-92: Allow PP for the <topic-filter>

Fixes https://github.com/spring-projects/spring-integration-extensions/issues/92
This commit is contained in:
Artem Bilan
2014-08-12 22:57:50 +03:00
committed by Artem Bilan
parent 999878f048
commit bacf8d2ceb
6 changed files with 473 additions and 419 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,9 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.kafka.config.xml;
import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.w3c.dom.Element;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
@@ -24,14 +29,20 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.kafka.support.*;
import org.springframework.integration.kafka.support.ConsumerConfigFactoryBean;
import org.springframework.integration.kafka.support.ConsumerConfiguration;
import org.springframework.integration.kafka.support.ConsumerConnectionProvider;
import org.springframework.integration.kafka.support.ConsumerMetadata;
import org.springframework.integration.kafka.support.KafkaConsumerContext;
import org.springframework.integration.kafka.support.MessageLeftOverTracker;
import org.springframework.integration.kafka.support.TopicFilterConfiguration;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
/**
* @author Soby Chacko
* @author Rajasekar Elango
* @author Artem Bilan
* @since 0.5
*/
public class KafkaConsumerContextParser extends AbstractSingleBeanDefinitionParser {
@@ -50,7 +61,7 @@ public class KafkaConsumerContextParser extends AbstractSingleBeanDefinitionPars
}
private void parseConsumerConfigurations(final Element consumerConfigurations, final ParserContext parserContext,
final BeanDefinitionBuilder builder, final Element parentElem) {
final BeanDefinitionBuilder builder, final Element parentElem) {
for (final Element consumerConfiguration : DomUtils.getChildElementsByTagName(consumerConfigurations, "consumer-configuration")) {
final BeanDefinitionBuilder consumerConfigurationBuilder = BeanDefinitionBuilder.genericBeanDefinition(ConsumerConfiguration.class);
final BeanDefinitionBuilder consumerMetadataBuilder = BeanDefinitionBuilder.genericBeanDefinition(ConsumerMetadata.class);
@@ -68,7 +79,7 @@ public class KafkaConsumerContextParser extends AbstractSingleBeanDefinitionPars
final List<Element> topicConfigurations = DomUtils.getChildElementsByTagName(consumerConfiguration, "topic");
if (topicConfigurations != null){
if (topicConfigurations != null) {
for (final Element topicConfiguration : topicConfigurations) {
final String topic = topicConfiguration.getAttribute("id");
final String streams = topicConfiguration.getAttribute("streams");
@@ -80,9 +91,14 @@ public class KafkaConsumerContextParser extends AbstractSingleBeanDefinitionPars
final Element topicFilter = DomUtils.getChildElementByTagName(consumerConfiguration, "topic-filter");
if (topicFilter != null){
final TopicFilterConfiguration topicFilterConfiguration = new TopicFilterConfiguration(topicFilter.getAttribute("pattern"),Integer.valueOf(topicFilter.getAttribute("streams")), Boolean.valueOf(topicFilter.getAttribute("exclude")));
consumerMetadataBuilder.addPropertyValue("topicFilterConfiguration", topicFilterConfiguration);
if (topicFilter != null) {
BeanDefinition topicFilterConfigurationBeanDefinition =
BeanDefinitionBuilder.genericBeanDefinition(TopicFilterConfiguration.class)
.addConstructorArgValue(topicFilter.getAttribute("pattern"))
.addConstructorArgValue(topicFilter.getAttribute("streams"))
.addConstructorArgValue(topicFilter.getAttribute("exclude"))
.getBeanDefinition();
consumerMetadataBuilder.addPropertyValue("topicFilterConfiguration", topicFilterConfigurationBeanDefinition);
}
final BeanDefinition consumerMetadataBeanDef = consumerMetadataBuilder.getBeanDefinition();

View File

@@ -1,11 +1,19 @@
/*
* Copyright 2002-2013 the original author or authors. Licensed 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.
* Copyright 2002-2014 the original author or authors.
*
* Licensed 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.springframework.integration.kafka.support;
import kafka.consumer.Blacklist;
@@ -14,33 +22,36 @@ import kafka.consumer.Whitelist;
/**
* @author Rajasekar Elango
* @author Artem Bilan
* @since 0.5
*/
public class TopicFilterConfiguration {
private final int numberOfStreams;
private TopicFilter topicFilter;
private final TopicFilter topicFilter;
public TopicFilterConfiguration(final String pattern, final int numberOfStreams, final boolean exclude) {
this.numberOfStreams = numberOfStreams;
if (exclude) {
topicFilter = new Blacklist(pattern);
this.topicFilter = new Blacklist(pattern);
}
else {
topicFilter = new Whitelist(pattern);
this.topicFilter = new Whitelist(pattern);
}
}
public TopicFilter getTopicFilter() {
return topicFilter;
return this.topicFilter;
}
public int getNumberOfStreams() {
return numberOfStreams;
return this.numberOfStreams;
}
@Override
public String toString() {
return new StringBuilder(topicFilter.toString()).append(" : ").append(numberOfStreams).toString();
return this.topicFilter.toString() + " : " + this.numberOfStreams;
}
}

View File

@@ -1,389 +1,392 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://www.springframework.org/schema/integration/kafka"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:integration="http://www.springframework.org/schema/integration"
targetNamespace="http://www.springframework.org/schema/integration/kafka"
elementFormDefault="qualified" attributeFormDefault="unqualified">
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:integration="http://www.springframework.org/schema/integration"
targetNamespace="http://www.springframework.org/schema/integration/kafka"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans"/>
<xsd:import namespace="http://www.springframework.org/schema/tool"/>
<xsd:import namespace="http://www.springframework.org/schema/integration"
schemaLocation="http://www.springframework.org/schema/integration/spring-integration-4.0.xsd"/>
<xsd:import namespace="http://www.springframework.org/schema/beans"/>
<xsd:import namespace="http://www.springframework.org/schema/tool"/>
<xsd:import namespace="http://www.springframework.org/schema/integration"
schemaLocation="http://www.springframework.org/schema/integration/spring-integration-4.0.xsd"/>
<xsd:annotation>
<xsd:documentation><![CDATA[
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines the configuration elements for the Spring Integration
Kafka Adapter.
]]></xsd:documentation>
</xsd:annotation>
</xsd:annotation>
<xsd:element name="zookeeper-connect">
<xsd:annotation>
<xsd:documentation><![CDATA[
<xsd:element name="zookeeper-connect">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines a Kafka server information.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="required"/>
<xsd:attribute name="zk-connect" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="required"/>
<xsd:attribute name="zk-connect" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates the Kafka server URL
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="zk-connection-timeout" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="zk-connection-timeout" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates the Kafka consumer zkConnectionTimeout value
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.Integer"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.Integer"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="zk-session-timeout" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
<xsd:attribute name="zk-session-timeout" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates the Kafka consumer group id
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="zk-sync-time" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="zk-sync-time" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates the Kafka consumer group id
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="auto-commit-interval" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="auto-commit-interval" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates the Kafka consumer group id
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="producer-context">
<xsd:annotation>
<xsd:documentation><![CDATA[
<xsd:element name="producer-context">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines a producer context.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="producer-configurations" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation><![CDATA[
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="producer-configurations" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation><![CDATA[
Groups kafka topic configurations.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:choice>
<xsd:element name="producer-configuration" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
</xsd:annotation>
<xsd:complexType>
<xsd:choice>
<xsd:element name="producer-configuration" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
Declares a kafka topic configuration which drives how and where a topic is sent to broker/s.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="topic" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation>
The topic configured by this configuration.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="broker-list" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="topic" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation>
The topic configured by this configuration.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="broker-list" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
list of comma separated kafka brokers.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="value-encoder" use="optional" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Custom implemenation of a Kafka Encoder for encoding message values.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="key-encoder" use="optional"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Custom implemenation of a Kafka Encoder for encoding message keys.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="key-class-type" use="optional"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Class type used for the key
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="value-class-type" use="optional"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Class type used for the value
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="compression-codec" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="value-encoder" use="optional" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Custom implemenation of a Kafka Encoder for encoding message values.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="key-encoder" use="optional"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Custom implemenation of a Kafka Encoder for encoding message keys.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="key-class-type" use="optional"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Class type used for the key
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="value-class-type" use="optional"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Class type used for the value
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="compression-codec" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates the type of compression codec used for message compression.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="partitioner" use="optional"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Custom Kafka key partitioner.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="async" use="optional"
type="xsd:boolean">
<xsd:annotation>
<xsd:documentation>
Indicates if this producer is async or not.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="batch-num-messages" use="optional"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
number of messages to batch at this producer.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" use="required"/>
<xsd:attribute name="producer-properties" use="optional"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Kafka producer properties to use for all producers
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="partitioner" use="optional"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Custom Kafka key partitioner.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="async" use="optional"
type="xsd:boolean">
<xsd:annotation>
<xsd:documentation>
Indicates if this producer is async or not.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="batch-num-messages" use="optional"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
number of messages to batch at this producer.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" use="required"/>
<xsd:attribute name="producer-properties" use="optional"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Kafka producer properties to use for all producers
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="consumer-context">
<xsd:annotation>
<xsd:documentation><![CDATA[
<xsd:element name="consumer-context">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines a producer context.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="consumer-configurations" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation><![CDATA[
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="consumer-configurations" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation><![CDATA[
Groups kafka topic configurations.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:choice>
<xsd:element name="consumer-configuration" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
</xsd:annotation>
<xsd:complexType>
<xsd:choice>
<xsd:element name="consumer-configuration" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
Declares a kafka topic configuration which drives how and where a topic is sent to broker/s.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:choice>
<xsd:element name="topic" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="required"/>
<xsd:attribute name="streams" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="topic-filter" maxOccurs="1">
<xsd:complexType>
<xsd:attribute name="pattern" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
</xsd:annotation>
<xsd:complexType>
<xsd:choice>
<xsd:element name="topic" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="required"/>
<xsd:attribute name="streams" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="topic-filter" maxOccurs="1">
<xsd:complexType>
<xsd:attribute name="pattern" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
Regex pattern to match topic
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="streams" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="streams" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
Number of streams (threads) to use to consume messages
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="exclude" type="xsd:boolean" use="optional" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="exclude" use="optional" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
If exclude is false, it uses whitelist to include topics matching given pattern.
If exclude is true, it uses blacklist to exclude topics matching given patttern.
If exclude is true, it uses blacklist to exclude topics matching given pattern.
Default value is false.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:choice>
<xsd:attribute name="max-messages" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:simpleType>
<xsd:union memberTypes="xsd:boolean xsd:string"/>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:choice>
<xsd:attribute name="max-messages" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates max messages to aggregate in a single call to receive
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="group-id" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="group-id" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates the Kafka consumer group id
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="value-decoder" use="optional"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Kafka Server Bean Name
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="key-decoder" use="optional"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Kafka Server Bean Name
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="value-decoder" use="optional"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Kafka Server Bean Name
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="key-decoder" use="optional"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Kafka Server Bean Name
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" use="required"/>
<xsd:attribute name="consumer-timeout" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
</xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" use="required"/>
<xsd:attribute name="consumer-timeout" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates the Kafka consumer timeout ms
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="zookeeper-connect" use="required"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Kafka Server Bean Name
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="consumer-properties" use="optional"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Kafka consumer properties to use for all consumers
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="zookeeper-connect" use="required"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Kafka Server Bean Name
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="consumer-properties" use="optional"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Kafka consumer properties to use for all consumers
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="inbound-channel-adapter">
<xsd:annotation>
<xsd:documentation>
The definition for the Spring Integration Kafka
Inbound Channel Adapter.
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="integration:poller" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attributeGroup ref="integration:channelAdapterAttributes"/>
<xsd:attribute name="send-timeout" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
<xsd:element name="inbound-channel-adapter">
<xsd:annotation>
<xsd:documentation>
The definition for the Spring Integration Kafka
Inbound Channel Adapter.
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="integration:poller" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attributeGroup ref="integration:channelAdapterAttributes"/>
<xsd:attribute name="send-timeout" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Allows you to specify how long this inbound-channel-adapter
will wait for the message (containing the retrieved entities)
to be sent successfully to the message channel, before throwing
@@ -395,59 +398,59 @@
further downstream. By default the Inbound Channel Adapter
will wait indefinitely. The value is specified in milliseconds.
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="group-id" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="group-id" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates the Kafka consumer group id
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="kafka-consumer-context-ref" use="required" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Kafka Server Bean Name
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:appinfo>
<tool:annotation kind="direct">
<tool:expected-type type="java.lang.String"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="kafka-consumer-context-ref" use="required" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Kafka Server Bean Name
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="outbound-channel-adapter">
<xsd:annotation>
<xsd:documentation>
Defines kafka outbound channel adapter that writes the contents of the
Message to kafka broker.
</xsd:documentation>
</xsd:annotation>
<xsd:element name="outbound-channel-adapter">
<xsd:annotation>
<xsd:documentation>
Defines kafka outbound channel adapter that writes the contents of the
Message to kafka broker.
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="integration:poller" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="integration:poller" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attributeGroup ref="integration:channelAdapterAttributes"/>
<xsd:attribute name="kafka-producer-context-ref" use="required" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Kafka producer context reference.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="order">
<xsd:annotation>
<xsd:documentation>
Specifies the order for invocation when this endpoint is connected as a
subscriber to a SubscribableChannel.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:attribute name="kafka-producer-context-ref" use="required" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Kafka producer context reference.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="order">
<xsd:annotation>
<xsd:documentation>
Specifies the order for invocation when this endpoint is connected as a
subscriber to a SubscribableChannel.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:schema>

View File

@@ -1,9 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int-kafka="http://www.springframework.org/schema/integration/kafka"
xsi:schemaLocation="http://www.springframework.org/schema/integration/kafka http://www.springframework.org/schema/integration/kafka/spring-integration-kafka.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int-kafka="http://www.springframework.org/schema/integration/kafka"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/integration/kafka http://www.springframework.org/schema/integration/kafka/spring-integration-kafka.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<int-kafka:zookeeper-connect id="zookeeperConnect" zk-connect="localhost:2181" zk-connection-timeout="6000"
zk-session-timeout="6000"
@@ -25,6 +27,14 @@
</property>
</bean>
<util:properties id="placeholderProperties">
<prop key="topic.filter.pattern">foo</prop>
<prop key="topic.filter.streams">10</prop>
<prop key="topic.filter.exclude">true</prop>
</util:properties>
<context:property-placeholder properties-ref="placeholderProperties"/>
<int-kafka:consumer-context id="consumerContext"
consumer-timeout="4000"
zookeeper-connect="zookeeperConnect"
@@ -34,9 +44,11 @@
value-decoder="valueDecoder"
key-decoder="valueDecoder"
max-messages="5000">
<int-kafka:topic id="test1" streams="4"/>
<int-kafka:topic id="test2" streams="4"/>
<int-kafka:topic-filter pattern="${topic.filter.pattern}"
streams="${topic.filter.streams}"
exclude="${topic.filter.exclude}"/>
</int-kafka:consumer-configuration>
</int-kafka:consumer-configurations>
</int-kafka:consumer-context>
</beans>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,23 +15,29 @@
*/
package org.springframework.integration.kafka.config.xml;
import org.junit.Assert;
import static org.junit.Assert.*;
import kafka.consumer.Blacklist;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.integration.kafka.support.ConsumerMetadata;
import org.springframework.integration.kafka.support.KafkaConsumerContext;
import org.springframework.integration.kafka.support.TopicFilterConfiguration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Soby Chacko
* @author Artem Bilan
* @since 0.5
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class KafkaConsumerContextParserTests<K,V> {
public class KafkaConsumerContextParserTests<K, V> {
@Autowired
private ApplicationContext appContext;
@@ -39,10 +45,15 @@ public class KafkaConsumerContextParserTests<K,V> {
@Test
@SuppressWarnings("unchecked")
public void testConsumerContextConfiguration() {
final KafkaConsumerContext<K,V> consumerContext = appContext.getBean("consumerContext", KafkaConsumerContext.class);
Assert.assertNotNull(consumerContext);
final KafkaConsumerContext<K, V> consumerContext =
appContext.getBean("consumerContext", KafkaConsumerContext.class);
assertNotNull(consumerContext);
final ConsumerMetadata<K,V> cm = appContext.getBean("consumerMetadata_default1", ConsumerMetadata.class);
Assert.assertNotNull(cm);
ConsumerMetadata<K, V> cm = appContext.getBean("consumerMetadata_default1", ConsumerMetadata.class);
assertNotNull(cm);
TopicFilterConfiguration topicFilterConfiguration = cm.getTopicFilterConfiguration();
assertEquals("foo : 10", topicFilterConfiguration.toString());
assertThat(topicFilterConfiguration.getTopicFilter(), Matchers.instanceOf(Blacklist.class));
}
}

View File

@@ -9,9 +9,10 @@
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="org.springframework.integration.kafka.inbound"></context:component-scan>
<int:channel id="inputFromKafka">
</int:channel>
<context:component-scan base-package="org.springframework.integration.kafka.inbound"/>
<int:channel id="inputFromKafka"/>
<stream:stdout-channel-adapter id="stdout" channel="inputFromKafka" append-newline="true"/>
</beans>