GH-3735: Don't mutate FeedEntryMS metadataKey

Fixes https://github.com/spring-projects/spring-integration/issues/3735

The `FeedEntryMessageSource` adds an url to the provided `metadataKey`
making it incompatible when we provide a `Resource`-based configuration.

* Remove adding of the url to the `metadataKey` making it rely only
on the provided value
* Remove internal `Comparator` for entries in favor of `Comparator.comparing()`
feature
* Improve some internal logic of the `PropertiesPersistingMetadataStore`
when it emits a false warning: cannot create dirs, but they are present
* Improve `feed.adoc`
This commit is contained in:
Artem Bilan
2022-03-18 15:52:55 -04:00
committed by Gary Russell
parent 67e0599a26
commit bba83c7231
6 changed files with 71 additions and 124 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@@ -17,7 +17,6 @@
package org.springframework.integration.feed.inbound;
import java.io.Reader;
import java.io.Serializable;
import java.net.URL;
import java.util.Comparator;
import java.util.Date;
@@ -66,7 +65,9 @@ public class FeedEntryMessageSource extends AbstractMessageSource<SyndEntry> {
private final Object monitor = new Object();
private final Comparator<SyndEntry> syndEntryComparator = new SyndEntryPublishedDateComparator();
private final Comparator<SyndEntry> syndEntryComparator =
Comparator.comparing(FeedEntryMessageSource::getLastModifiedDate,
Comparator.nullsFirst(Comparator.naturalOrder()));
private final Object feedMonitor = new Object();
@@ -90,9 +91,9 @@ public class FeedEntryMessageSource extends AbstractMessageSource<SyndEntry> {
*/
public FeedEntryMessageSource(URL feedUrl, String metadataKey) {
Assert.notNull(feedUrl, "'feedUrl' must not be null");
Assert.notNull(metadataKey, "'metadataKey' must not be null");
Assert.hasText(metadataKey, "'metadataKey' must not be empty");
this.feedUrl = feedUrl;
this.metadataKey = metadataKey + "." + feedUrl;
this.metadataKey = metadataKey;
this.feedResource = null;
}
@@ -104,7 +105,7 @@ public class FeedEntryMessageSource extends AbstractMessageSource<SyndEntry> {
*/
public FeedEntryMessageSource(Resource feedResource, String metadataKey) {
Assert.notNull(feedResource, "'feedResource' must not be null");
Assert.notNull(metadataKey, "'metadataKey' must not be null");
Assert.hasText(metadataKey, "'metadataKey' must not be empty");
this.feedResource = feedResource;
this.metadataKey = metadataKey;
this.feedUrl = null;
@@ -223,7 +224,7 @@ public class FeedEntryMessageSource extends AbstractMessageSource<SyndEntry> {
? new XmlReader(this.feedUrl)
: new XmlReader(this.feedResource.getInputStream());
SyndFeed feed = this.syndFeedInput.build(reader);
logger.debug(() -> "Retrieved feed for [" + this + "]");
logger.debug(() -> "Retrieved feed for [" + this + "]");
if (feed == null) {
logger.debug(() -> "No feeds updated for [" + this + "], returning null");
}
@@ -249,26 +250,4 @@ public class FeedEntryMessageSource extends AbstractMessageSource<SyndEntry> {
return (entry.getUpdatedDate() != null) ? entry.getUpdatedDate() : entry.getPublishedDate();
}
@SuppressWarnings("serial")
private static final class SyndEntryPublishedDateComparator implements Comparator<SyndEntry>, Serializable {
SyndEntryPublishedDateComparator() {
}
@Override
public int compare(SyndEntry entry1, SyndEntry entry2) {
Date date1 = getLastModifiedDate(entry1);
Date date2 = getLastModifiedDate(entry2);
if (date1 != null && date2 != null) {
return date1.compareTo(date2);
}
if (date1 == null && date2 == null) {
return 0;
}
return date2 == null ? -1 : 1;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -69,6 +69,7 @@ public class FeedInboundChannelAdapterParserTests {
"FeedInboundChannelAdapterParserTests-file-context.xml", this.getClass());
SourcePollingChannelAdapter adapter = context.getBean("feedAdapter", SourcePollingChannelAdapter.class);
FeedEntryMessageSource source = (FeedEntryMessageSource) TestUtils.getPropertyValue(adapter, "source");
assertThat(TestUtils.getPropertyValue(source, "metadataKey")).isEqualTo("feedAdapter");
assertThat(TestUtils.getPropertyValue(source, "metadataStore")).isSameAs(context.getBean(MetadataStore.class));
SyndFeedInput syndFeedInput = TestUtils.getPropertyValue(source, "syndFeedInput", SyndFeedInput.class);
assertThat(syndFeedInput).isSameAs(context.getBean(SyndFeedInput.class));

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2019 the original author or authors.
* Copyright 2016-2022 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.
@@ -18,13 +18,12 @@ package org.springframework.integration.feed.dsl;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.File;
import java.io.FileReader;
import java.util.Properties;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -39,7 +38,7 @@ import org.springframework.integration.metadata.PropertiesPersistingMetadataStor
import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import com.rometools.rome.feed.synd.SyndEntry;
@@ -48,12 +47,12 @@ import com.rometools.rome.feed.synd.SyndEntry;
*
* @since 5.0
*/
@RunWith(SpringRunner.class)
@SpringJUnitConfig
@DirtiesContext
public class FeedDslTests {
@ClassRule
public static final TemporaryFolder tempFolder = new TemporaryFolder();
@TempDir
public static File tempFolder;
@Autowired
private PollableChannel entries;
@@ -80,12 +79,14 @@ public class FeedDslTests {
this.metadataStore.flush();
FileReader metadataStoreFile =
new FileReader(tempFolder.getRoot().getAbsolutePath() + "/metadata-store.properties");
new FileReader(tempFolder.getAbsolutePath() + "/metadata-store.properties");
Properties metadataStoreProperties = new Properties();
metadataStoreProperties.load(metadataStoreFile);
assertThat(metadataStoreProperties.isEmpty()).isFalse();
assertThat(metadataStoreProperties.size()).isEqualTo(1);
assertThat(metadataStoreProperties.containsKey("feedTest")).isTrue();
metadataStoreFile.close();
}
@Configuration
@@ -98,7 +99,7 @@ public class FeedDslTests {
@Bean
public MetadataStore metadataStore() {
PropertiesPersistingMetadataStore metadataStore = new PropertiesPersistingMetadataStore();
metadataStore.setBaseDirectory(tempFolder.getRoot().getAbsolutePath());
metadataStore.setBaseDirectory(tempFolder.getAbsolutePath());
return metadataStore;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.