From f385d984f95018f6ddbb5e7db74681807552d97d Mon Sep 17 00:00:00 2001 From: Aaron Loes Date: Fri, 17 Apr 2015 19:00:27 +0300 Subject: [PATCH] INT-3700: Fix FeedEntryMS for correct `lastTime` JIRA: https://jira.spring.io/browse/INT-3700 Change to calculate proper syndicate entry date for comparison when adding feeds for processing. I have signed and agree to the terms of the SpringSource Individual Contributor License Agreement. unit test for recent changes to FeedEntryMessageSourceTests to verify proper last seen date calculation. updates for comments from code review * newline at EOF on atom.xml * removed question from code * fetch files via classpath instead of file system * 'else' on newline * authorship on class Polishing Conflicts: spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedInboundChannelAdapterParserTests.java Conflicts: spring-integration-feed/src/main/java/org/springframework/integration/feed/inbound/FeedEntryMessageSource.java spring-integration-feed/src/test/java/org/springframework/integration/feed/inbound/FeedEntryMessageSourceTests.java --- .../feed/inbound/FeedEntryMessageSource.java | 9 ++-- .../springframework/integration/feed/atom.xml | 45 ++++++++++++++++ ...ChannelAdapterParserTests-file-context.xml | 10 ++-- ...lAdapterParserTests-file-usage-context.xml | 2 +- .../FeedInboundChannelAdapterParserTests.java | 4 +- .../inbound/FeedEntryMessageSourceTests.java | 51 ++++++++++++++++--- 6 files changed, 102 insertions(+), 19 deletions(-) create mode 100644 spring-integration-feed/src/test/java/org/springframework/integration/feed/atom.xml diff --git a/spring-integration-feed/src/main/java/org/springframework/integration/feed/inbound/FeedEntryMessageSource.java b/spring-integration-feed/src/main/java/org/springframework/integration/feed/inbound/FeedEntryMessageSource.java index 9e39d23718..f818fccbb0 100644 --- a/spring-integration-feed/src/main/java/org/springframework/integration/feed/inbound/FeedEntryMessageSource.java +++ b/spring-integration-feed/src/main/java/org/springframework/integration/feed/inbound/FeedEntryMessageSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 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. @@ -53,6 +53,7 @@ import com.sun.syndication.fetcher.impl.HttpURLFeedFetcher; * @author Mario Gray * @author Oleg Zhurakousky * @author Artem Bilan + * @author Aaron Loes * @since 2.0 */ public class FeedEntryMessageSource extends IntegrationObjectSupport implements MessageSource { @@ -159,8 +160,10 @@ public class FeedEntryMessageSource extends IntegrationObjectSupport implements if (next == null) { return null; } - if (next.getPublishedDate() != null) { - this.lastTime = next.getPublishedDate().getTime(); + + Date lastModifiedDate = FeedEntryMessageSource.getLastModifiedDate(next); + if (lastModifiedDate != null) { + this.lastTime = lastModifiedDate.getTime(); } else { this.lastTime += 1; diff --git a/spring-integration-feed/src/test/java/org/springframework/integration/feed/atom.xml b/spring-integration-feed/src/test/java/org/springframework/integration/feed/atom.xml new file mode 100644 index 0000000000..7f543dddfa --- /dev/null +++ b/spring-integration-feed/src/test/java/org/springframework/integration/feed/atom.xml @@ -0,0 +1,45 @@ + + + + dive into mark + + A <em>lot</em> of effort + went into making this effortless + + 2005-07-31T12:29:29Z + tag:example.org,2003:3 + + + Copyright (c) 2003, Mark Pilgrim + + Example Toolkit + + + Atom draft-07 snapshot + + + tag:example.org,2003:3.2397 + 2005-07-31T12:29:29Z + 2003-12-13T08:29:29-04:00 + + Mark Pilgrim + http://example.org/ + f8dy@example.com + + + Sam Ruby + + + Joe Gregorio + + +
+

+ [Update: The Atom draft is finished.] +

+
+
+
+
diff --git a/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedInboundChannelAdapterParserTests-file-context.xml b/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedInboundChannelAdapterParserTests-file-context.xml index eff5ef842a..e0ff440427 100644 --- a/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedInboundChannelAdapterParserTests-file-context.xml +++ b/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedInboundChannelAdapterParserTests-file-context.xml @@ -6,12 +6,12 @@ http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd http://www.springframework.org/schema/integration/feed http://www.springframework.org/schema/integration/feed/spring-integration-feed.xsd"> - + url="classpath:org/springframework/integration/feed/sample.rss"> @@ -23,4 +23,4 @@ - \ No newline at end of file + diff --git a/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedInboundChannelAdapterParserTests-file-usage-context.xml b/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedInboundChannelAdapterParserTests-file-usage-context.xml index 05b8997914..a9461b2d49 100644 --- a/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedInboundChannelAdapterParserTests-file-usage-context.xml +++ b/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedInboundChannelAdapterParserTests-file-usage-context.xml @@ -10,7 +10,7 @@ diff --git a/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedInboundChannelAdapterParserTests.java b/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedInboundChannelAdapterParserTests.java index 0e6ee90862..601badf921 100644 --- a/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedInboundChannelAdapterParserTests.java +++ b/spring-integration-feed/src/test/java/org/springframework/integration/feed/config/FeedInboundChannelAdapterParserTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 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. @@ -117,7 +117,7 @@ public class FeedInboundChannelAdapterParserTests { latch = spy(new CountDownLatch(3)); context = new ClassPathXmlApplicationContext( "FeedInboundChannelAdapterParserTests-file-usage-context.xml", this.getClass()); - latch.await(5, TimeUnit.SECONDS); + latch.await(500, TimeUnit.MILLISECONDS); verify(latch, times(0)).countDown(); context.destroy(); } diff --git a/spring-integration-feed/src/test/java/org/springframework/integration/feed/inbound/FeedEntryMessageSourceTests.java b/spring-integration-feed/src/test/java/org/springframework/integration/feed/inbound/FeedEntryMessageSourceTests.java index d7aad3f25c..9098969015 100644 --- a/spring-integration-feed/src/test/java/org/springframework/integration/feed/inbound/FeedEntryMessageSourceTests.java +++ b/spring-integration-feed/src/test/java/org/springframework/integration/feed/inbound/FeedEntryMessageSourceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 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. @@ -25,7 +25,8 @@ import java.net.URL; import org.junit.Before; import org.junit.Test; -import org.springframework.integration.Message; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.core.io.ClassPathResource; import org.springframework.integration.metadata.PropertiesPersistingMetadataStore; import com.sun.syndication.feed.synd.SyndEntry; @@ -34,13 +35,13 @@ import com.sun.syndication.fetcher.FeedFetcher; /** * @author Oleg Zhurakousky * @author Mark Fisher + * @author Aaron Loes * @since 2.0 */ public class FeedEntryMessageSourceTests { private final FeedFetcher feedFetcher = new FileUrlFeedFetcher(); - @Before public void prepare() { File metadataStoreFile = new File(System.getProperty("java.io.tmpdir") + "/spring-integration/", "metadata-store.properties"); @@ -51,14 +52,14 @@ public class FeedEntryMessageSourceTests { @Test(expected=IllegalArgumentException.class) public void testFailureWhenNotInitialized() throws Exception { - URL url = new URL("file:src/test/java/org/springframework/integration/feed/sample.rss"); + URL url = new ClassPathResource("org/springframework/integration/feed/sample.rss").getURL(); FeedEntryMessageSource feedEntrySource = new FeedEntryMessageSource(url, "foo"); feedEntrySource.receive(); } @Test public void testReceiveFeedWithNoEntries() throws Exception { - URL url = new URL("file:src/test/java/org/springframework/integration/feed/empty.rss"); + URL url = new ClassPathResource("org/springframework/integration/feed/empty.rss").getURL(); FeedEntryMessageSource feedEntrySource = new FeedEntryMessageSource(url, "foo", this.feedFetcher); feedEntrySource.setBeanName("feedReader"); feedEntrySource.afterPropertiesSet(); @@ -67,7 +68,7 @@ public class FeedEntryMessageSourceTests { @Test public void testReceiveFeedWithEntriesSorted() throws Exception { - URL url = new URL("file:src/test/java/org/springframework/integration/feed/sample.rss"); + URL url = new ClassPathResource("org/springframework/integration/feed/sample.rss").getURL(); FeedEntryMessageSource source = new FeedEntryMessageSource(url, "foo", this.feedFetcher); source.setComponentName("feedReader"); source.afterPropertiesSet(); @@ -82,11 +83,45 @@ public class FeedEntryMessageSourceTests { assertNull(source.receive()); } + // verifies that when entry has been updated since publish, that is taken into + // account when determining if the feed entry has been seen before + @Test + public void testEntryHavingBeenUpdatedAfterPublishAndRepeat() throws Exception { + URL url = new ClassPathResource("org/springframework/integration/feed/atom.xml").getURL(); + FeedEntryMessageSource feedEntrySource = new FeedEntryMessageSource(url, "foo", this.feedFetcher); + feedEntrySource.setBeanName("feedReader"); + PropertiesPersistingMetadataStore metadataStore = new PropertiesPersistingMetadataStore(); + metadataStore.afterPropertiesSet(); + feedEntrySource.setMetadataStore(metadataStore); + feedEntrySource.setBeanFactory(mock(BeanFactory.class)); + feedEntrySource.afterPropertiesSet(); + + SyndEntry entry1 = feedEntrySource.receive().getPayload(); + assertNull(feedEntrySource.receive()); // only 1 entries in the test feed + + assertEquals("Atom draft-07 snapshot", entry1.getTitle().trim()); + assertEquals(1071318569000L, entry1.getPublishedDate().getTime()); + assertEquals(1122812969000L, entry1.getUpdatedDate().getTime()); + + metadataStore.destroy(); + metadataStore.afterPropertiesSet(); + + // now test that what's been read is no longer retrieved + feedEntrySource = new FeedEntryMessageSource(url, "foo", this.feedFetcher); + feedEntrySource.setBeanName("feedReader"); + metadataStore = new PropertiesPersistingMetadataStore(); + metadataStore.afterPropertiesSet(); + feedEntrySource.setMetadataStore(metadataStore); + feedEntrySource.setBeanFactory(mock(BeanFactory.class)); + feedEntrySource.afterPropertiesSet(); + assertNull(feedEntrySource.receive()); + } + // will test that last feed entry is remembered between the sessions // and no duplicate entries are retrieved @Test public void testReceiveFeedWithRealEntriesAndRepeatWithPersistentMetadataStore() throws Exception { - URL url = new URL("file:src/test/java/org/springframework/integration/feed/sample.rss"); + URL url = new ClassPathResource("org/springframework/integration/feed/sample.rss").getURL(); FeedEntryMessageSource feedEntrySource = new FeedEntryMessageSource(url, "foo", this.feedFetcher); feedEntrySource.setBeanName("feedReader"); PropertiesPersistingMetadataStore metadataStore = new PropertiesPersistingMetadataStore(); @@ -126,7 +161,7 @@ public class FeedEntryMessageSourceTests { // no persistent MetadataStore is provided and the same entries are retrieved again @Test public void testReceiveFeedWithRealEntriesAndRepeatNoPersistentMetadataStore() throws Exception { - URL url = new URL("file:src/test/java/org/springframework/integration/feed/sample.rss"); + URL url = new ClassPathResource("org/springframework/integration/feed/sample.rss").getURL(); FeedEntryMessageSource feedEntrySource = new FeedEntryMessageSource(url, "foo", this.feedFetcher); feedEntrySource.setBeanName("feedReader"); feedEntrySource.afterPropertiesSet();