Skip to content
Snippets Groups Projects
Verified Commit de29fbc3 authored by Torsten Grote's avatar Torsten Grote
Browse files

Fix bug where RSS feeds got lost when a fetching error occured

parent 35aad409
No related branches found
No related tags found
No related merge requests found
...@@ -291,8 +291,12 @@ class FeedManagerImpl implements FeedManager, Client, EventListener, ...@@ -291,8 +291,12 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
* This method is called periodically from a background service. * This method is called periodically from a background service.
* It fetches all available feeds and posts new entries to the respective * It fetches all available feeds and posts new entries to the respective
* blog. * blog.
*
* We can not do this within one database {@link Transaction},
* because fetching can take a long time
* and we can not block the database that long.
*/ */
private void fetchFeeds() { void fetchFeeds() {
LOG.info("Updating RSS feeds..."); LOG.info("Updating RSS feeds...");
// Get current feeds // Get current feeds
...@@ -313,12 +317,15 @@ class FeedManagerImpl implements FeedManager, Client, EventListener, ...@@ -313,12 +317,15 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
} catch (FeedException e) { } catch (FeedException e) {
if (LOG.isLoggable(WARNING)) if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e); LOG.log(WARNING, e.toString(), e);
newFeeds.add(feed);
} catch (IOException e) { } catch (IOException e) {
if (LOG.isLoggable(WARNING)) if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e); LOG.log(WARNING, e.toString(), e);
newFeeds.add(feed);
} catch (DbException e) { } catch (DbException e) {
if (LOG.isLoggable(WARNING)) if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e); LOG.log(WARNING, e.toString(), e);
newFeeds.add(feed);
} }
} }
......
package org.briarproject.briar.feed;
import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.client.ContactGroupFactory;
import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfEntry;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.test.BrambleMockTestCase;
import org.briarproject.bramble.test.ImmediateExecutor;
import org.briarproject.briar.api.blog.Blog;
import org.briarproject.briar.api.blog.BlogManager;
import org.briarproject.briar.api.blog.BlogPostFactory;
import org.briarproject.briar.api.feed.Feed;
import org.jmock.Expectations;
import org.junit.Test;
import java.net.UnknownHostException;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import javax.net.SocketFactory;
import okhttp3.Dns;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEEDS;
import static org.briarproject.briar.api.feed.FeedManager.CLIENT_ID;
public class FeedManagerImplTest extends BrambleMockTestCase {
private final ScheduledExecutorService scheduler =
context.mock(ScheduledExecutorService.class);
private final Executor ioExecutor = new ImmediateExecutor();
private final DatabaseComponent db = context.mock(DatabaseComponent.class);
private final ContactGroupFactory contactGroupFactory =
context.mock(ContactGroupFactory.class);
private final ClientHelper clientHelper = context.mock(ClientHelper.class);
private final BlogManager blogManager = context.mock(BlogManager.class);
private final BlogPostFactory blogPostFactory =
context.mock(BlogPostFactory.class);
private final FeedFactory feedFactory = context.mock(FeedFactory.class);
private final Clock clock = context.mock(Clock.class);
private final Dns noDnsLookups = context.mock(Dns.class);
private final GroupId localGroupId = new GroupId(getRandomId());
private final Group localGroup =
new Group(localGroupId, CLIENT_ID, getRandomBytes(42));
private final GroupId blogGroupId = new GroupId(getRandomId());
private final Group blogGroup =
new Group(blogGroupId, BlogManager.CLIENT_ID, getRandomBytes(42));
private final AuthorId authorId = new AuthorId(getRandomId());
private final LocalAuthor localAuthor =
new LocalAuthor(authorId, "author", getRandomBytes(2),
getRandomBytes(2), 0);
private final Blog blog = new Blog(blogGroup, localAuthor, true);
private final Feed feed =
new Feed("http://example.org", blog, localAuthor, 0);
private final BdfDictionary feedDict = new BdfDictionary();
private final FeedManagerImpl feedManager =
new FeedManagerImpl(scheduler, ioExecutor, db, contactGroupFactory,
clientHelper, blogManager, blogPostFactory, feedFactory,
SocketFactory.getDefault(), clock, noDnsLookups);
@Test
public void testEmptyFetchFeed() throws Exception {
BdfList feedList = new BdfList();
expectGetFeeds(feedList);
expectStoreFeed(feedList);
feedManager.fetchFeeds();
}
@Test
public void testFetchFeedIoException() throws Exception {
final BdfDictionary feedDict= new BdfDictionary();
BdfList feedList = BdfList.of(feedDict);
expectGetFeeds(feedList);
context.checking(new Expectations() {{
oneOf(noDnsLookups).lookup("example.org");
will(throwException(new UnknownHostException()));
}});
expectStoreFeed(feedList);
feedManager.fetchFeeds();
}
private void expectGetLocalGroup() {
context.checking(new Expectations() {{
oneOf(contactGroupFactory).createLocalGroup(CLIENT_ID);
will(returnValue(localGroup));
}});
}
private void expectGetFeeds(final BdfList feedList) throws Exception {
final Transaction txn = new Transaction(null, true);
final BdfDictionary feedsDict =
BdfDictionary.of(new BdfEntry(KEY_FEEDS, feedList));
expectGetLocalGroup();
context.checking(new Expectations() {{
oneOf(db).startTransaction(true);
will(returnValue(txn));
oneOf(clientHelper).getGroupMetadataAsDictionary(txn, localGroupId);
will(returnValue(feedsDict));
if (feedList.size() == 1) {
oneOf(feedFactory).createFeed(feedDict);
will(returnValue(feed));
}
oneOf(db).commitTransaction(txn);
oneOf(db).endTransaction(txn);
}});
}
private void expectStoreFeed(final BdfList feedList) throws Exception {
final BdfDictionary feedDict =
BdfDictionary.of(new BdfEntry(KEY_FEEDS, feedList));
expectGetLocalGroup();
context.checking(new Expectations() {{
oneOf(clientHelper).mergeGroupMetadata(localGroupId, feedDict);
if (feedList.size() == 1) {
oneOf(feedFactory).feedToBdfDictionary(feed);
will(returnValue(feedList.getDictionary(0)));
}
}});
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment