INT-3147: (3167,3173,1941) Improve MetadataStore
Previously, `MetadataStore` couldn't be configured for Twitter Adapters - only a global one could be used. The `metadataKey` was generated automatically with a 'difficult' value. * Register all `MessageSource` for `SourcePollingChannelAdapter` as beans with id based on adapter id and prefix '.source' (INT-3147) * Polishing parser to get rid of explicit `MessageSource` beans. (INT-3147) * Make Feed and Twitter adapters `id` attribute as required - now it presents a `metadataKey` for `MetadataStore` (INT-3147) * Add to Twitter adapters a reference attribute for `MetadataStore` (INT-3173) * Add Twitter adapters `poll-skip-period` attribute (INT-3167) * Add and implement `MetadataStore#remove` (INT-1941) * Make `MetadataStore` as `@ManagedResource` (INT-1941) * Polishing tests JIRAs: https://jira.springsource.org/browse/INT-3147 https://jira.springsource.org/browse/INT-3167 https://jira.springsource.org/browse/INT-3173 https://jira.springsource.org/browse/INT-1941 INT-3147: Polishing and fixes * add domain suffix to `metadataKey` * change contract of `MetadataStore.remove` * remove timeout window from `AbstractTwitterMessageSource` * polishing and fix `SearchReceivingMessageSourceWithRedisTests` INT-3147: Rebasing and polishing INT-3147: fix 'metadata' package tangle INT-3147 Doc Polishing
This commit is contained in:
committed by
Gary Russell
parent
1fb838dd1a
commit
5be8ef3fd8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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.
|
||||
@@ -23,6 +23,7 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.config.xml.AbstractPollingInboundChannelAdapterParser;
|
||||
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
|
||||
import org.springframework.integration.feed.inbound.FeedEntryMessageSource;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -31,20 +32,23 @@ import org.springframework.util.StringUtils;
|
||||
* @author Josh Long
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Mark Fisher
|
||||
* @author Gunnar Hillert
|
||||
* @author Artem Bilan
|
||||
* @since 2.0
|
||||
*/
|
||||
public class FeedInboundChannelAdapterParser extends AbstractPollingInboundChannelAdapterParser {
|
||||
|
||||
@Override
|
||||
protected BeanMetadataElement parseSource(final Element element, final ParserContext parserContext) {
|
||||
BeanDefinitionBuilder sourceBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
"org.springframework.integration.feed.inbound.FeedEntryMessageSource");
|
||||
BeanDefinitionBuilder sourceBuilder = BeanDefinitionBuilder.genericBeanDefinition(FeedEntryMessageSource.class);
|
||||
sourceBuilder.addConstructorArgValue(element.getAttribute("url"));
|
||||
sourceBuilder.addConstructorArgValue(element.getAttribute(ID_ATTRIBUTE));
|
||||
String feedFetcherRef = element.getAttribute("feed-fetcher");
|
||||
if (StringUtils.hasText(feedFetcherRef)) {
|
||||
sourceBuilder.addConstructorArgReference(feedFetcherRef);
|
||||
}
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(sourceBuilder, element, "metadata-store");
|
||||
|
||||
return sourceBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@ import org.springframework.integration.MessagingException;
|
||||
import org.springframework.integration.context.IntegrationContextUtils;
|
||||
import org.springframework.integration.context.IntegrationObjectSupport;
|
||||
import org.springframework.integration.core.MessageSource;
|
||||
import org.springframework.integration.store.metadata.MetadataStore;
|
||||
import org.springframework.integration.store.metadata.SimpleMetadataStore;
|
||||
import org.springframework.integration.metadata.MetadataStore;
|
||||
import org.springframework.integration.metadata.SimpleMetadataStore;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@@ -52,6 +52,7 @@ import com.sun.syndication.fetcher.impl.HttpURLFeedFetcher;
|
||||
* @author Josh Long
|
||||
* @author Mario Gray
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Artem Bilan
|
||||
* @since 2.0
|
||||
*/
|
||||
public class FeedEntryMessageSource extends IntegrationObjectSupport implements MessageSource<SyndEntry> {
|
||||
@@ -62,7 +63,7 @@ public class FeedEntryMessageSource extends IntegrationObjectSupport implements
|
||||
|
||||
private final Queue<SyndEntry> entries = new ConcurrentLinkedQueue<SyndEntry>();
|
||||
|
||||
private volatile String metadataKey;
|
||||
private final String metadataKey;
|
||||
|
||||
private volatile MetadataStore metadataStore;
|
||||
|
||||
@@ -82,17 +83,19 @@ public class FeedEntryMessageSource extends IntegrationObjectSupport implements
|
||||
* If the feed URL has a protocol other than http*, consider providing a custom implementation of the
|
||||
* {@link FeedFetcher} via the alternate constructor.
|
||||
*/
|
||||
public FeedEntryMessageSource(URL feedUrl) {
|
||||
this(feedUrl, new HttpURLFeedFetcher(HashMapFeedInfoCache.getInstance()));
|
||||
public FeedEntryMessageSource(URL feedUrl, String metadataKey) {
|
||||
this(feedUrl, metadataKey, new HttpURLFeedFetcher(HashMapFeedInfoCache.getInstance()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a FeedEntryMessageSource that will use the provided FeedFetcher to read from the given feed URL.
|
||||
*/
|
||||
public FeedEntryMessageSource(URL feedUrl, FeedFetcher feedFetcher) {
|
||||
public FeedEntryMessageSource(URL feedUrl, String metadataKey, FeedFetcher feedFetcher) {
|
||||
Assert.notNull(feedUrl, "feedUrl must not be null");
|
||||
Assert.notNull(metadataKey, "metadataKey must not be null");
|
||||
Assert.notNull(feedFetcher, "feedFetcher must not be null");
|
||||
this.feedUrl = feedUrl;
|
||||
this.metadataKey = metadataKey + "." + this.feedUrl;
|
||||
this.feedFetcher = feedFetcher;
|
||||
}
|
||||
|
||||
@@ -130,18 +133,7 @@ public class FeedEntryMessageSource extends IntegrationObjectSupport implements
|
||||
this.metadataStore = new SimpleMetadataStore();
|
||||
}
|
||||
}
|
||||
StringBuilder metadataKeyBuilder = new StringBuilder();
|
||||
if (StringUtils.hasText(this.getComponentType())) {
|
||||
metadataKeyBuilder.append(this.getComponentType() + ".");
|
||||
}
|
||||
if (StringUtils.hasText(this.getComponentName())) {
|
||||
metadataKeyBuilder.append(this.getComponentName() + ".");
|
||||
}
|
||||
else if (logger.isWarnEnabled()) {
|
||||
logger.warn("FeedEntryMessageSource has no name. MetadataStore key might not be unique.");
|
||||
}
|
||||
metadataKeyBuilder.append(this.feedUrl);
|
||||
this.metadataKey = metadataKeyBuilder.toString();
|
||||
|
||||
String lastTimeValue = this.metadataStore.get(this.metadataKey);
|
||||
if (StringUtils.hasText(lastTimeValue)) {
|
||||
this.lastTime = Long.parseLong(lastTimeValue);
|
||||
@@ -237,6 +229,7 @@ public class FeedEntryMessageSource extends IntegrationObjectSupport implements
|
||||
}
|
||||
return (date2 == null) ? 1 : 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -258,6 +251,7 @@ public class FeedEntryMessageSource extends IntegrationObjectSupport implements
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +22,28 @@
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="integration:poller" minOccurs="0" maxOccurs="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="integration:channelAdapterAttributes"/>
|
||||
<xsd:attribute name="id" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The bean id of this Polling Endpoint; the MessageSource is also registered with this id
|
||||
plus a suffix '.source'; also used as the
|
||||
MetaDataStore key with suffix '.' + feedUrl - The URL for an RSS or ATOM feed.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="channel" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.MessageChannel" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Identifies the channel attached to this adapter, to which messages will be sent.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attributeGroup ref="integration:smartLifeCycleAttributeGroup"/>
|
||||
<xsd:attribute name="url" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
@@ -54,7 +75,7 @@
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.store.MetadataStore" />
|
||||
<tool:expected-type type="org.springframework.integration.metadata.MetadataStore" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
|
||||
Reference in New Issue
Block a user