diff --git a/spring-integration-feed/pom.xml b/spring-integration-feed/pom.xml
index 71a3f219bf..d03f8c6c9b 100644
--- a/spring-integration-feed/pom.xml
+++ b/spring-integration-feed/pom.xml
@@ -19,7 +19,10 @@
org.springframework.integration
spring-integration-core
-
+
+ org.springframework.commons
+ spring-commons-serializer
+
commons-langcommons-lang2.5
@@ -28,7 +31,6 @@
rome-fetcher
1.0.0
-
net.java.dev.rome
rome
diff --git a/spring-integration-feed/src/main/java/org/springframework/integration/feed/FeedEntryReaderMessageSource.java b/spring-integration-feed/src/main/java/org/springframework/integration/feed/FeedEntryReaderMessageSource.java
index c8dc154fdb..1ac9072ba0 100644
--- a/spring-integration-feed/src/main/java/org/springframework/integration/feed/FeedEntryReaderMessageSource.java
+++ b/spring-integration-feed/src/main/java/org/springframework/integration/feed/FeedEntryReaderMessageSource.java
@@ -15,12 +15,15 @@
*/
package org.springframework.integration.feed;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
-import java.util.Map;
+import java.util.Properties;
import java.util.Queue;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.springframework.integration.Message;
@@ -28,6 +31,8 @@ import org.springframework.integration.context.IntegrationObjectSupport;
import org.springframework.integration.core.MessageSource;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.util.Assert;
+import org.springframework.util.DefaultPropertiesPersister;
+import org.springframework.util.StringUtils;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
@@ -41,14 +46,17 @@ import com.sun.syndication.feed.synd.SyndFeed;
* @author Oleg Zhurakousky
*/
public class FeedEntryReaderMessageSource extends IntegrationObjectSupport implements MessageSource{
-
- private volatile Map persisterMap = new ConcurrentHashMap();
+ private final DefaultPropertiesPersister persister = new DefaultPropertiesPersister();
+ private volatile Properties lastPersistentEntry = new Properties();
private volatile Queue entries = new ConcurrentLinkedQueue();
private volatile FeedReaderMessageSource feedReaderMessageSource;
private final Object monitor = new Object();
private volatile String feedMetadataIdKey;
- private volatile boolean initialized;
+ private volatile String persistentIdentifier;
+
+ private volatile boolean initialized;
private volatile long lastTime = -1;
+ private volatile File persisterFile;
private Comparator syndEntryComparator = new Comparator() {
public int compare(SyndEntry syndEntry, SyndEntry syndEntry1) {
@@ -68,15 +76,9 @@ public class FeedEntryReaderMessageSource extends IntegrationObjectSupport imple
Assert.notNull(feedReaderMessageSource, "'feedReaderMessageSource' must not be null");
this.feedReaderMessageSource = feedReaderMessageSource;
}
- /**
- * Allows you to provide your own implementation of 'persisterMap' instead of relying on
- * your own which is in-memory.
- *
- * @param persisterMap
- */
- public void setPersisterMap(Map persisterMap) {
- Assert.notNull(persisterMap, "'persisterMap' can not be null");
- this.persisterMap = persisterMap;
+
+ public void setPersistentIdentifier(String persistentIdentifier) {
+ this.persistentIdentifier = persistentIdentifier;
}
public String getComponentType(){
@@ -94,8 +96,9 @@ public class FeedEntryReaderMessageSource extends IntegrationObjectSupport imple
@SuppressWarnings("unchecked")
private SyndEntry doReceieve() {
+ SyndEntry nextUp = null;
synchronized (this.monitor) {
- SyndEntry nextUp = pollAndCache();
+ nextUp = pollAndCache();
if (nextUp != null) {
return nextUp;
@@ -114,17 +117,33 @@ public class FeedEntryReaderMessageSource extends IntegrationObjectSupport imple
}
}
}
- return pollAndCache();
+ nextUp = pollAndCache();
}
+ return nextUp;
}
@Override
protected void onInit() throws Exception {
- // setup persistence of metadata
- this.feedMetadataIdKey = FeedEntryReaderMessageSource.class.getName() + "#" + feedReaderMessageSource.getFeedUrl();
- String lastTime = (String) this.persisterMap.get(this.feedMetadataIdKey);
- if (lastTime != null && !lastTime.trim().equalsIgnoreCase("")) {
- this.lastTime = Long.parseLong(lastTime);
+ if (StringUtils.hasText(this.persistentIdentifier)){
+ File dir = new File(System.getProperty("user.home") + "/temp/spring-integration");
+ dir.mkdirs();
+ persisterFile = new File(dir, this.persistentIdentifier + ".last.entry");
+ if (!persisterFile.exists()){
+ persisterFile.createNewFile();
+ }
+ FileInputStream inStream = new FileInputStream(persisterFile);
+ persister.load(lastPersistentEntry, inStream);
+ }
+ else {
+ logger.info("Your '" + this.getComponentType() + "' is anonymous (no ID attribute), therefore no feed entries will be persisted " +
+ "which may result in a duplicate feed entries once this adapter is restarted");
+ }
+
+ this.feedMetadataIdKey = this.getComponentType() + "@" + this.getComponentName() +
+ "#" + feedReaderMessageSource.getFeedUrl();
+ String keyTime = (String) this.lastPersistentEntry.get(this.feedMetadataIdKey);
+ if (StringUtils.hasText(keyTime)){
+ this.lastTime = Long.parseLong(keyTime);
}
this.initialized = true;
}
@@ -135,9 +154,32 @@ public class FeedEntryReaderMessageSource extends IntegrationObjectSupport imple
if (next == null) {
return null;
}
-
+
this.lastTime = next.getPublishedDate().getTime();
- this.persisterMap.put(this.feedMetadataIdKey, this.lastTime + "");
+ this.lastPersistentEntry.put(this.feedMetadataIdKey, this.lastTime + "");
+
+ if (persisterFile != null){
+ FileOutputStream fo = null;
+ try {
+ fo = new FileOutputStream(persisterFile);
+ persister.store(this.lastPersistentEntry, fo, "Last feed entry");
+ }
+ catch (IOException e) {
+ // not fatal for the functionality of the component
+ logger.warn("Failed to persist feed entry. This may result in a duplicate " +
+ "feed entry after this component is restarted", e);
+ }
+ finally {
+ try {
+ fo.close();
+ }
+ catch (IOException e) {
+ // not fatal for the functionality of he component
+ logger.warn("Failed to close output stream to " + persisterFile.getAbsolutePath(), e);
+ }
+ }
+ }
+
return next;
}
}
\ No newline at end of file
diff --git a/spring-integration-feed/src/main/java/org/springframework/integration/feed/FeedReaderMessageSource.java b/spring-integration-feed/src/main/java/org/springframework/integration/feed/FeedReaderMessageSource.java
index e2b6f49983..7f1dfa5910 100644
--- a/spring-integration-feed/src/main/java/org/springframework/integration/feed/FeedReaderMessageSource.java
+++ b/spring-integration-feed/src/main/java/org/springframework/integration/feed/FeedReaderMessageSource.java
@@ -87,7 +87,6 @@ public class FeedReaderMessageSource extends IntegrationObjectSupport
}
}
} catch (Exception e) {
- e.printStackTrace();
throw new MessagingException("Exception thrown when trying to retrive feed at url '" + this.feedUrl + "'", e);
}
diff --git a/spring-integration-feed/src/main/java/org/springframework/integration/feed/config/FeedMessageSourceBeanDefinitionParser.java b/spring-integration-feed/src/main/java/org/springframework/integration/feed/config/FeedMessageSourceBeanDefinitionParser.java
index 12ecd2aa20..a80a291248 100644
--- a/spring-integration-feed/src/main/java/org/springframework/integration/feed/config/FeedMessageSourceBeanDefinitionParser.java
+++ b/spring-integration-feed/src/main/java/org/springframework/integration/feed/config/FeedMessageSourceBeanDefinitionParser.java
@@ -19,6 +19,7 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractPollingInboundChannelAdapterParser;
+import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.w3c.dom.Element;
/**
@@ -34,7 +35,7 @@ public class FeedMessageSourceBeanDefinitionParser extends AbstractPollingInboun
BeanDefinitionBuilder feedEntryBuilder =
BeanDefinitionBuilder.genericBeanDefinition("org.springframework.integration.feed.FeedEntryReaderMessageSource");
-
+ IntegrationNamespaceUtils.setValueIfAttributeDefined(feedEntryBuilder, element, "id", "persistentIdentifier");
BeanDefinitionBuilder feedBuilder =
BeanDefinitionBuilder.genericBeanDefinition("org.springframework.integration.feed.FeedReaderMessageSource");
feedBuilder.addConstructorArgValue(element.getAttribute("feedUrl"));
diff --git a/spring-integration-feed/src/main/resources/org/springframework/integration/feed/config/spring-integration-feed-2.0.xsd b/spring-integration-feed/src/main/resources/org/springframework/integration/feed/config/spring-integration-feed-2.0.xsd
index 71cb01657f..9e62fbf074 100644
--- a/spring-integration-feed/src/main/resources/org/springframework/integration/feed/config/spring-integration-feed-2.0.xsd
+++ b/spring-integration-feed/src/main/resources/org/springframework/integration/feed/config/spring-integration-feed-2.0.xsd
@@ -27,6 +27,7 @@
+
diff --git a/spring-integration-feed/src/test/java/org/springframework/integration/feed/FeedDeliveryEventServiceActivator.java b/spring-integration-feed/src/test/java/org/springframework/integration/feed/FeedDeliveryEventServiceActivator.java
deleted file mode 100644
index a055273b39..0000000000
--- a/spring-integration-feed/src/test/java/org/springframework/integration/feed/FeedDeliveryEventServiceActivator.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.springframework.integration.feed;
-
-import java.util.Properties;
-
-import org.springframework.integration.Message;
-import org.springframework.integration.annotation.ServiceActivator;
-import org.springframework.integration.history.MessageHistory;
-import org.springframework.stereotype.Component;
-
-import com.sun.syndication.feed.synd.SyndEntry;
-
-@Component
-public class FeedDeliveryEventServiceActivator {
-
- @ServiceActivator
- public void activate(Message message) throws Exception {
-
- MessageHistory history = MessageHistory.read(message);
- for (Properties properties : history) {
- System.out.println(properties);
- }
- SyndEntry syndEntry = message.getPayload();
-
- System.out.println( "Publishing new SyndEntry " + syndEntry.getUri() +":"+
- syndEntry.getPublishedDate().toString()+ ":"+ syndEntry.getPublishedDate().getTime());
-
-// System.out.println( syndEntry.toString());
- // System.out.println("Delivery! " + ToStringBuilder.reflectionToString(evtMsg));
-
- }
-
-}
diff --git a/spring-integration-feed/src/test/java/org/springframework/integration/feed/FeedEntryReaderMessageSourceTests.java b/spring-integration-feed/src/test/java/org/springframework/integration/feed/FeedEntryReaderMessageSourceTests.java
index 418b29cd2f..286054fd43 100644
--- a/spring-integration-feed/src/test/java/org/springframework/integration/feed/FeedEntryReaderMessageSourceTests.java
+++ b/spring-integration-feed/src/test/java/org/springframework/integration/feed/FeedEntryReaderMessageSourceTests.java
@@ -21,10 +21,13 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.when;
+import java.io.File;
+import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
+import org.junit.Before;
import org.junit.Test;
import org.springframework.integration.Message;
@@ -36,6 +39,13 @@ import com.sun.syndication.feed.synd.SyndFeed;
*
*/
public class FeedEntryReaderMessageSourceTests {
+ @Before
+ public void prepare(){
+ File persisterFile = new File(System.getProperty("user.home") + "/temp/spring-integration", "feedReader.last.entry");
+ if (persisterFile.exists()){
+ persisterFile.delete();
+ }
+ }
@Test(expected=IllegalArgumentException.class)
public void testFailureWhenNotInitialized(){
@@ -49,6 +59,7 @@ public class FeedEntryReaderMessageSourceTests {
SyndFeed feed = mock(SyndFeed.class);
when(feedReaderSource.receiveSyndFeed()).thenReturn(feed);
FeedEntryReaderMessageSource feedEntrySource = new FeedEntryReaderMessageSource(feedReaderSource);
+ feedEntrySource.setPersistentIdentifier("feedReader");
feedEntrySource.afterPropertiesSet();
assertNull(feedEntrySource.receive());
}
@@ -68,6 +79,7 @@ public class FeedEntryReaderMessageSourceTests {
when(feedReaderSource.receiveSyndFeed()).thenReturn(feed);
FeedEntryReaderMessageSource feedEntrySource = new FeedEntryReaderMessageSource(feedReaderSource);
+ feedEntrySource.setPersistentIdentifier("feedReader");
feedEntrySource.afterPropertiesSet();
Message entryMessage = feedEntrySource.receive();
assertEquals(entry2, entryMessage.getPayload());
@@ -77,4 +89,79 @@ public class FeedEntryReaderMessageSourceTests {
entryMessage = feedEntrySource.receive();
assertNull(entryMessage);
}
+ // will test, that last feed entry is remembered between the sessions
+ // and no duplicate entries are retrieved
+ @Test
+ public void testReceieveFeedWithRealEntriesAndRepeatWithPersistentIdentifier() throws Exception{
+ FeedReaderMessageSource feedReaderSource =
+ new FeedReaderMessageSource(new URL("file:src/test/java/org/springframework/integration/feed/sample.rss"));
+
+ FeedEntryReaderMessageSource feedEntrySource = new FeedEntryReaderMessageSource(feedReaderSource);
+ feedEntrySource.setPersistentIdentifier("feedReader");
+ feedEntrySource.afterPropertiesSet();
+ SyndEntry entry1 = feedEntrySource.receive().getPayload();
+ SyndEntry entry2 = feedEntrySource.receive().getPayload();
+ SyndEntry entry3 = feedEntrySource.receive().getPayload();
+ assertNull(feedEntrySource.receive()); // only 3 entries in the test feed
+
+ assertEquals("Spring Integration download", entry1.getTitle().trim());
+ assertEquals(1266088337000L, entry1.getPublishedDate().getTime());
+
+ assertEquals("Check out Spring Integration forums", entry2.getTitle().trim());
+ assertEquals(1268469501000L, entry2.getPublishedDate().getTime());
+
+ assertEquals("Spring Integration adapters", entry3.getTitle().trim());
+ assertEquals(1272044098000L, entry3.getPublishedDate().getTime());
+
+ // now test that what's been read is no longer retrieved
+ feedEntrySource = new FeedEntryReaderMessageSource(feedReaderSource);
+ feedEntrySource.setPersistentIdentifier("feedReader");
+ feedEntrySource.afterPropertiesSet();
+ assertNull(feedEntrySource.receive());
+ assertNull(feedEntrySource.receive());
+ assertNull(feedEntrySource.receive());
+ }
+ // will test, that last feed entry is NOT remembered between the sessions, since
+ // persister is not used due to the lack of persistentIdentifier (id attribute in xml)
+ // and the same entries are retrieved again
+ @Test
+ public void testReceieveFeedWithRealEntriesAndRepeatNoPersistentIdentifier() throws Exception{
+ FeedReaderMessageSource feedReaderSource =
+ new FeedReaderMessageSource(new URL("file:src/test/java/org/springframework/integration/feed/sample.rss"));
+
+ FeedEntryReaderMessageSource feedEntrySource = new FeedEntryReaderMessageSource(feedReaderSource);
+ feedEntrySource.afterPropertiesSet();
+ SyndEntry entry1 = feedEntrySource.receive().getPayload();
+ SyndEntry entry2 = feedEntrySource.receive().getPayload();
+ SyndEntry entry3 = feedEntrySource.receive().getPayload();
+ assertNull(feedEntrySource.receive()); // only 3 entries in the test feed
+
+ assertEquals("Spring Integration download", entry1.getTitle().trim());
+ assertEquals(1266088337000L, entry1.getPublishedDate().getTime());
+
+ assertEquals("Check out Spring Integration forums", entry2.getTitle().trim());
+ assertEquals(1268469501000L, entry2.getPublishedDate().getTime());
+
+ assertEquals("Spring Integration adapters", entry3.getTitle().trim());
+ assertEquals(1272044098000L, entry3.getPublishedDate().getTime());
+
+ // UNLIKE the previous test
+ // now test that what's been read is read AGAIN
+ feedEntrySource = new FeedEntryReaderMessageSource(feedReaderSource);
+ feedEntrySource.afterPropertiesSet();
+ entry1 = feedEntrySource.receive().getPayload();
+ entry2 = feedEntrySource.receive().getPayload();
+ entry3 = feedEntrySource.receive().getPayload();
+ assertNull(feedEntrySource.receive()); // only 3 entries in the test feed
+
+ assertEquals("Spring Integration download", entry1.getTitle().trim());
+ assertEquals(1266088337000L, entry1.getPublishedDate().getTime());
+
+ assertEquals("Check out Spring Integration forums", entry2.getTitle().trim());
+ assertEquals(1268469501000L, entry2.getPublishedDate().getTime());
+
+ assertEquals("Spring Integration adapters", entry3.getTitle().trim());
+ assertEquals(1272044098000L, entry3.getPublishedDate().getTime());
+ }
+
}
diff --git a/spring-integration-feed/src/test/java/org/springframework/integration/feed/TestFeedEventDelivery-context.xml b/spring-integration-feed/src/test/java/org/springframework/integration/feed/TestFeedEventDelivery-context.xml
deleted file mode 100644
index c5c80dca00..0000000000
--- a/spring-integration-feed/src/test/java/org/springframework/integration/feed/TestFeedEventDelivery-context.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-integration-feed/src/test/java/org/springframework/integration/feed/TestFeedEventDelivery.java b/spring-integration-feed/src/test/java/org/springframework/integration/feed/TestFeedEventDelivery.java
deleted file mode 100644
index 5878a4acb1..0000000000
--- a/spring-integration-feed/src/test/java/org/springframework/integration/feed/TestFeedEventDelivery.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2002-2010 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.feed;
-
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
-@ContextConfiguration
-@RunWith(SpringJUnit4ClassRunner.class)
-public class TestFeedEventDelivery {
-
- @Test
- @Ignore
- public void testDeliveryOfFeed() throws Exception {
- Thread.sleep(1000 * 60);
- }
-}
diff --git a/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedMessageSourceBeanDefinitionParserTests-file-context.xml b/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedMessageSourceBeanDefinitionParserTests-file-context.xml
index 17a1c35c40..215b8fa547 100644
--- a/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedMessageSourceBeanDefinitionParserTests-file-context.xml
+++ b/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedMessageSourceBeanDefinitionParserTests-file-context.xml
@@ -6,10 +6,14 @@
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
http://www.springframework.org/schema/integration/feed http://www.springframework.org/schema/integration/feed/spring-integration-feed-2.0.xsd">
-
-
+
+
+
+
\ No newline at end of file
diff --git a/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedMessageSourceBeanDefinitionParserTests-http-context.xml b/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedMessageSourceBeanDefinitionParserTests-http-context.xml
index 6756557d68..0f13051342 100644
--- a/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedMessageSourceBeanDefinitionParserTests-http-context.xml
+++ b/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedMessageSourceBeanDefinitionParserTests-http-context.xml
@@ -6,7 +6,7 @@
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
http://www.springframework.org/schema/integration/feed http://www.springframework.org/schema/integration/feed/spring-integration-feed-2.0.xsd">
-
diff --git a/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedMessageSourceBeanDefinitionParserTests.java b/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedMessageSourceBeanDefinitionParserTests.java
index 17f2bcab7b..66cce1826c 100644
--- a/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedMessageSourceBeanDefinitionParserTests.java
+++ b/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedMessageSourceBeanDefinitionParserTests.java
@@ -15,15 +15,20 @@
*/
package org.springframework.integration.feed.config;
+import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import java.io.File;
+import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.context.ApplicationContext;
@@ -36,21 +41,30 @@ import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.feed.FeedEntryReaderMessageSource;
import org.springframework.integration.feed.FeedReaderMessageSource;
import org.springframework.integration.feed.FileUrlFeedFetcher;
+import org.springframework.integration.history.MessageHistory;
import org.springframework.integration.test.util.TestUtils;
+import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.fetcher.impl.AbstractFeedFetcher;
import com.sun.syndication.fetcher.impl.HttpURLFeedFetcher;
-
/**
* @author Oleg Zhurakousky
*
*/
public class FeedMessageSourceBeanDefinitionParserTests {
+ private static CountDownLatch latch;
+ @Before
+ public void prepare(){
+ File persisterFile = new File(System.getProperty("user.home") + "/temp/spring-integration", "feedAdapter.last.entry");
+ if (persisterFile.exists()){
+ persisterFile.delete();
+ }
+ }
@Test
public void validateSuccessfullConfiguration(){
- ApplicationContext context =
+ ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("FeedMessageSourceBeanDefinitionParserTests-file-context.xml", this.getClass());
SourcePollingChannelAdapter adapter = context.getBean("feedAdapter", SourcePollingChannelAdapter.class);
FeedEntryReaderMessageSource source = (FeedEntryReaderMessageSource) TestUtils.getPropertyValue(adapter, "source");
@@ -65,26 +79,55 @@ public class FeedMessageSourceBeanDefinitionParserTests {
feedReaderMessageSource = (FeedReaderMessageSource) TestUtils.getPropertyValue(source, "feedReaderMessageSource");
fetcher = (AbstractFeedFetcher) TestUtils.getPropertyValue(feedReaderMessageSource, "fetcher");
assertTrue(fetcher instanceof HttpURLFeedFetcher);
+ context.destroy();
}
+
@Test
- public void validateSuccessfullNewsRetrievalFile() throws Exception{
+ public void validateSuccessfullNewsRetrievalWithFileUrlAndMessageHistory() throws Exception{
+ File persisterFile = new File(System.getProperty("user.home") + "/temp/spring-integration", "feedAdapterUsage.last.entry");
+ if (persisterFile.exists()){
+ persisterFile.delete();
+ }
//Test file samples.rss has 3 news items
- final CountDownLatch latch = new CountDownLatch(3);
- MessageHandler handler = spy(new MessageHandler() {
- public void handleMessage(Message> message) throws MessagingException {
- latch.countDown();
- }
- });
- ApplicationContext context =
- new ClassPathXmlApplicationContext("FeedMessageSourceBeanDefinitionParserTests-file-context.xml", this.getClass());
- DirectChannel feedChannel = context.getBean("feedChannel", DirectChannel.class);
- feedChannel.subscribe(handler);
+ latch = spy(new CountDownLatch(3));
+ ClassPathXmlApplicationContext context =
+ new ClassPathXmlApplicationContext("FeedMessageSourceBeanDefinitionParserTests-file-usage-context.xml", this.getClass());
latch.await(5, TimeUnit.SECONDS);
- verify(handler, times(3)).handleMessage(Mockito.any(Message.class));
+ verify(latch, times(3)).countDown();
+ context.destroy();
+
+ // since we are not deleting the persister file
+ // in this iteration no new feeds will be received and the latch will timeout
+ latch = spy(new CountDownLatch(3));
+ context =
+ new ClassPathXmlApplicationContext("FeedMessageSourceBeanDefinitionParserTests-file-usage-context.xml", this.getClass());
+ latch.await(5, TimeUnit.SECONDS);
+ verify(latch, times(0)).countDown();
+ context.destroy();
}
@Test
- public void validateSuccessfullNewsRetrievalHttp() throws Exception{
+ public void validateSuccessfullNewsRetrievalWithFileUrlNoPersistentIdentifier() throws Exception{
//Test file samples.rss has 3 news items
+ latch = spy(new CountDownLatch(3));
+ ClassPathXmlApplicationContext context =
+ new ClassPathXmlApplicationContext("FeedMessageSourceBeanDefinitionParserTests-file-usage-noid-context.xml", this.getClass());
+ latch.await(5, TimeUnit.SECONDS);
+ verify(latch, times(3)).countDown();
+ context.destroy();
+
+ // since we are not deleting the persister file
+ // in this iteration no new feeds will be received and the latch will timeout
+ latch = spy(new CountDownLatch(3));
+ context =
+ new ClassPathXmlApplicationContext("FeedMessageSourceBeanDefinitionParserTests-file-usage-noid-context.xml", this.getClass());
+ latch.await(5, TimeUnit.SECONDS);
+ verify(latch, times(3)).countDown();
+ context.destroy();
+ }
+
+ @Test
+ @Ignore // goes against the real feed
+ public void validateSuccessfullNewsRetrievalWithHttpUrl() throws Exception{
final CountDownLatch latch = new CountDownLatch(3);
MessageHandler handler = spy(new MessageHandler() {
public void handleMessage(Message> message) throws MessagingException {
@@ -98,4 +141,29 @@ public class FeedMessageSourceBeanDefinitionParserTests {
latch.await(5, TimeUnit.SECONDS);
verify(handler, atLeast(3)).handleMessage(Mockito.any(Message.class));
}
+
+ public static class SampleService{
+ public void receiveFeedEntry(Message> message){
+ MessageHistory history = MessageHistory.read(message);
+ assertTrue(history.size() == 3);
+ Properties historyItem = history.get(0);
+ assertEquals("feedAdapterUsage", historyItem.get("name"));
+ assertEquals("feed:inbound-channel-adapter", historyItem.get("type"));
+
+ historyItem = history.get(1);
+ assertEquals("feedChannelUsage", historyItem.get("name"));
+ assertEquals("channel", historyItem.get("type"));
+
+ historyItem = history.get(2);
+ assertEquals("sampleActivator", historyItem.get("name"));
+ assertEquals("service-activator", historyItem.get("type"));
+ latch.countDown();
+ }
+ }
+
+ public static class SampleServiceNoHistory{
+ public void receiveFeedEntry(SyndEntry entry){
+ latch.countDown();
+ }
+ }
}
diff --git a/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/sample.rss b/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/sample.rss
index cbe572a200..31fa532a39 100644
--- a/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/sample.rss
+++ b/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/sample.rss
@@ -1,52 +1,52 @@
-ASP @ BellaOnline
-http://www.bellaonline.com/Site/asp
+Spring Integration
+http://www.springsource.org/spring-integration
-Learn to program in ASP, and enhance your ASP skills to add great new functionality to your website!
+Spring Integration is a really cool framework
en-us
-Copyright 2001-2005 BellaOnline.com
+Copyright 2004-2010 SpringSource/VMWare
All Rights Reserved.
-Tue, 12 Apr 2005 14:21:32 EST
+Tue, 12 Apr 2010 18:21:32 EST
240
-http://www.bellaonline.com/images/bella.gif
-ASP @ BellaOnline
-http://asp.bellaonline.com
+http://www.springsource.org/sites/all/themes/dotorg09/images/dotorg09_logo.png
+Spring Integration
+http://www.springsource.org/spring-integration
-
-Using ASP to Code an RSS Feed
+Spring Integration adapters
-http://www.bellaonline.com/articles/art30646.asp
+http://www.springsource.org/extensions/se-sia
-RSS feeds let you easily syndicate your content to an end user or another website. ASP can help you easily create your own RSS feed for your website.
+Spring Integration adapters are realy cool
-Tue, 12 Apr 2005 13:59:56 EST
+Tue, 23 Apr 2010 12:34:58 EST
-
-RecordCount and Count
+Spring Integration download
-http://www.bellaonline.com/articles/art30403.asp
+http://www.springsource.com/products/spring-community-download
-If you're trying to figure out how many records are in a given SQL result set, you can use either the RecordCount or Count command. Both work in different ways.
+Download Spring Integration
-Sun, 3 Apr 2005 17:12:17 EST
+Sun, 13 Feb 2010 14:12:17 EST
-
-Bubble Sort Code Technique
+Check out Spring Integration forums
-http://www.bellaonline.com/articles/art29843.asp
+http://forum.springsource.org/forumdisplay.php?f=42
-If you are sorting content into an order, one of the most simple techniques that exists is the bubble sort technique.
+Spring Integration forums are awesome
-Wed, 16 Mar 2005 00:38:21 EST
+Wed, 13 Mar 2010 03:38:21 EST