Change blog descriptor format to include RSS feed flag

This now also handles the case where an RSS blog is deleted via the blog
deletion option and not the feed management.
This commit is contained in:
Torsten Grote
2017-04-10 18:57:14 -03:00
parent 58b9efb24c
commit d40a058ef5
12 changed files with 77 additions and 48 deletions

View File

@@ -68,8 +68,8 @@ import static org.briarproject.bramble.db.ExponentialBackoff.calculateExpiry;
@NotNullByDefault
abstract class JdbcDatabase implements Database<Connection> {
private static final int SCHEMA_VERSION = 29;
private static final int MIN_SCHEMA_VERSION = 29;
private static final int SCHEMA_VERSION = 30;
private static final int MIN_SCHEMA_VERSION = 30;
private static final String CREATE_SETTINGS =
"CREATE TABLE settings"

View File

@@ -13,16 +13,22 @@ import javax.annotation.concurrent.Immutable;
public class Blog extends BaseGroup implements Shareable {
private final Author author;
private final boolean rssFeed;
public Blog(Group group, Author author) {
public Blog(Group group, Author author, boolean rssFeed) {
super(group);
this.author = author;
this.rssFeed = rssFeed;
}
public Author getAuthor() {
return author;
}
public boolean isRssFeed() {
return rssFeed;
}
@Override
public boolean equals(Object o) {
return o instanceof Blog && super.equals(o);

View File

@@ -13,6 +13,11 @@ public interface BlogFactory {
*/
Blog createBlog(Author author);
/**
* Creates a RSS feed blog for a given author.
*/
Blog createFeedBlog(Author author);
/**
* Parses a blog with the given Group
*/

View File

@@ -93,21 +93,9 @@ public class Feed {
if (this == o) return true;
if (o instanceof Feed) {
Feed f = (Feed) o;
return url.equals(f.url) && blog.equals(f.blog) &&
equalsWithNull(title, f.title) &&
equalsWithNull(description, f.description) &&
equalsWithNull(author, f.author) &&
added == f.added &&
updated == f.updated &&
lastEntryTime == f.lastEntryTime;
return blog.equals(f.blog);
}
return false;
}
private boolean equalsWithNull(@Nullable Object a, @Nullable Object b) {
if (a == b) return true;
if (a == null || b == null) return false;
return a.equals(b);
}
}

View File

@@ -33,15 +33,25 @@ class BlogFactoryImpl implements BlogFactory {
@Override
public Blog createBlog(Author a) {
return createBlog(a, false);
}
@Override
public Blog createFeedBlog(Author a) {
return createBlog(a, true);
}
private Blog createBlog(Author a, boolean rssFeed) {
try {
BdfList blog = BdfList.of(
a.getName(),
a.getPublicKey()
a.getPublicKey(),
rssFeed
);
byte[] descriptor = clientHelper.toByteArray(blog);
Group g = groupFactory
.createGroup(BlogManagerImpl.CLIENT_ID, descriptor);
return new Blog(g, a);
return new Blog(g, a, rssFeed);
} catch (FormatException e) {
throw new RuntimeException(e);
}
@@ -54,7 +64,7 @@ class BlogFactoryImpl implements BlogFactory {
BdfList blog = clientHelper.toList(descriptor);
Author a =
authorFactory.createAuthor(blog.getString(0), blog.getRaw(1));
return new Blog(g, a);
return new Blog(g, a, blog.getBoolean(2));
}
}

View File

@@ -52,7 +52,7 @@ class FeedFactoryImpl implements FeedFactory {
.createLocalAuthor(syndFeed.getTitle(),
keyPair.getPublic().getEncoded(),
keyPair.getPrivate().getEncoded());
Blog blog = blogFactory.createBlog(localAuthor);
Blog blog = blogFactory.createFeedBlog(localAuthor);
long added = clock.currentTimeMillis();
return new Feed(url, blog, localAuthor, added);
@@ -75,7 +75,7 @@ class FeedFactoryImpl implements FeedFactory {
byte[] privateKey = d.getRaw(KEY_PRIVATE_KEY);
LocalAuthor localAuthor = authorFactory
.createLocalAuthor(blogTitle, publicKey, privateKey);
Blog blog = blogFactory.createBlog(localAuthor);
Blog blog = blogFactory.createFeedBlog(localAuthor);
String title = d.getOptionalString(KEY_FEED_TITLE);
String desc = d.getOptionalString(KEY_FEED_DESC);

View File

@@ -30,6 +30,7 @@ import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.Scheduler;
import org.briarproject.bramble.util.StringUtils;
import org.briarproject.briar.api.blog.Blog;
import org.briarproject.briar.api.blog.BlogManager;
import org.briarproject.briar.api.blog.BlogPost;
import org.briarproject.briar.api.blog.BlogPostFactory;
@@ -74,7 +75,8 @@ import static org.briarproject.briar.util.HtmlUtils.clean;
@ThreadSafe
@NotNullByDefault
class FeedManagerImpl implements FeedManager, Client, EventListener {
class FeedManagerImpl implements FeedManager, Client, EventListener,
BlogManager.RemoveBlogHook {
private static final Logger LOG =
Logger.getLogger(FeedManagerImpl.class.getName());
@@ -158,7 +160,6 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
@Override
public void addFeed(String url) throws DbException, IOException {
// TODO check for existing feed?
// fetch syndication feed to get its metadata
SyndFeed f;
try {
@@ -207,15 +208,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
LOG.info("Removing RSS feed...");
Transaction txn = db.startTransaction(false);
try {
List<Feed> feeds = getFeeds(txn);
for (Feed f : feeds) {
if (f.getBlogId().equals(feed.getBlogId())) {
feed = f;
feeds.remove(f);
break;
}
}
storeFeeds(txn, feeds);
// this will call removingBlog() where the feed itself gets removed
blogManager.removeBlog(txn, feed.getBlog());
db.commitTransaction(txn);
} finally {
@@ -223,6 +216,23 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
}
}
@Override
public void removingBlog(Transaction txn, Blog b) throws DbException {
if (!b.isRssFeed()) return;
// delete blog's RSS feed if we have it
boolean found = false;
List<Feed> feeds = getFeeds(txn);
for (Feed f : feeds) {
if (f.getBlogId().equals(b.getId())) {
found = true;
feeds.remove(f);
break;
}
}
if (found) storeFeeds(txn, feeds);
}
@Override
public List<Feed> getFeeds() throws DbException {
List<Feed> feeds;

View File

@@ -2,6 +2,7 @@ package org.briarproject.briar.feed;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.briar.api.blog.BlogManager;
import org.briarproject.briar.api.feed.FeedManager;
import javax.inject.Inject;
@@ -21,10 +22,12 @@ public class FeedModule {
@Provides
@Singleton
FeedManager provideFeedManager(FeedManagerImpl feedManager,
LifecycleManager lifecycleManager, EventBus eventBus) {
LifecycleManager lifecycleManager, EventBus eventBus,
BlogManager blogManager) {
lifecycleManager.registerClient(feedManager);
eventBus.addListener(feedManager);
blogManager.registerRemoveBlogHook(feedManager);
return feedManager;
}

View File

@@ -39,14 +39,20 @@ class BlogSharingValidator extends SharingValidator {
@Override
protected GroupId validateDescriptor(BdfList descriptor)
throws FormatException {
checkSize(descriptor, 2);
checkSize(descriptor, 3);
String name = descriptor.getString(0);
checkLength(name, 1, MAX_AUTHOR_NAME_LENGTH);
byte[] publicKey = descriptor.getRaw(1);
checkLength(publicKey, 1, MAX_PUBLIC_KEY_LENGTH);
boolean rssFeed = descriptor.getBoolean(2);
Author author = authorFactory.createAuthor(name, publicKey);
Blog blog = blogFactory.createBlog(author);
Blog blog;
if (rssFeed) {
blog = blogFactory.createFeedBlog(author);
} else {
blog = blogFactory.createBlog(author);
}
return blog.getId();
}

View File

@@ -297,7 +297,7 @@ public class BlogManagerImplTest extends BriarTestCase {
final LocalAuthor localAuthor =
new LocalAuthor(authorId, "Author", publicKey, privateKey,
created);
return new Blog(group, localAuthor);
return new Blog(group, localAuthor, false);
}
private BdfDictionary authorToBdfDictionary(Author a) {

View File

@@ -79,7 +79,7 @@ public class BlogPostValidatorTest extends BriarTestCase {
new BdfEntry(KEY_AUTHOR_NAME, author.getName()),
new BdfEntry(KEY_PUBLIC_KEY, author.getPublicKey())
);
blog = new Blog(group, author);
blog = new Blog(group, author, false);
MessageId messageId = new MessageId(TestUtils.getRandomId());
long timestamp = System.currentTimeMillis();

View File

@@ -23,8 +23,8 @@ public class BlogSharingValidatorTest extends SharingValidatorTest {
private final byte[] publicKey =
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
private final Author author = new Author(authorId, authorName, publicKey);
private final Blog blog = new Blog(group, author);
private final BdfList descriptor = BdfList.of(authorName, publicKey);
private final Blog blog = new Blog(group, author, false);
private final BdfList descriptor = BdfList.of(authorName, publicKey, false);
private final String content =
TestUtils.getRandomString(MAX_INVITATION_MESSAGE_LENGTH);
@@ -64,7 +64,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest {
@Test(expected = FormatException.class)
public void testRejectsNullBlogName() throws Exception {
BdfList invalidDescriptor = BdfList.of(null, publicKey);
BdfList invalidDescriptor = BdfList.of(null, publicKey, false);
v.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
@@ -72,7 +72,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest {
@Test(expected = FormatException.class)
public void testRejectsNonStringBlogName() throws Exception {
BdfList invalidDescriptor = BdfList.of(123, publicKey);
BdfList invalidDescriptor = BdfList.of(123, publicKey, false);
v.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
@@ -80,7 +80,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest {
@Test(expected = FormatException.class)
public void testRejectsTooShortBlogName() throws Exception {
BdfList invalidDescriptor = BdfList.of("", publicKey);
BdfList invalidDescriptor = BdfList.of("", publicKey, false);
v.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
@@ -89,7 +89,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest {
@Test
public void testAcceptsMinLengthBlogName() throws Exception {
String shortBlogName = TestUtils.getRandomString(1);
BdfList validDescriptor = BdfList.of(shortBlogName, publicKey);
BdfList validDescriptor = BdfList.of(shortBlogName, publicKey, false);
expectCreateBlog(shortBlogName, publicKey);
expectEncodeMetadata(INVITE);
BdfMessageContext messageContext = v.validateMessage(message, group,
@@ -102,7 +102,8 @@ public class BlogSharingValidatorTest extends SharingValidatorTest {
public void testRejectsTooLongBlogName() throws Exception {
String invalidBlogName =
TestUtils.getRandomString(MAX_BLOG_NAME_LENGTH + 1);
BdfList invalidDescriptor = BdfList.of(invalidBlogName, publicKey);
BdfList invalidDescriptor =
BdfList.of(invalidBlogName, publicKey, false);
v.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
@@ -110,7 +111,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest {
@Test(expected = FormatException.class)
public void testRejectsNullPublicKey() throws Exception {
BdfList invalidDescriptor = BdfList.of(authorName, null);
BdfList invalidDescriptor = BdfList.of(authorName, null, false);
v.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
@@ -118,7 +119,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest {
@Test(expected = FormatException.class)
public void testRejectsNonRawPublicKey() throws Exception {
BdfList invalidDescriptor = BdfList.of(authorName, 123);
BdfList invalidDescriptor = BdfList.of(authorName, 123, false);
v.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
@@ -127,7 +128,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest {
@Test(expected = FormatException.class)
public void testRejectsTooLongPublicKey() throws Exception {
byte[] invalidKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1);
BdfList invalidDescriptor = BdfList.of(authorName, invalidKey);
BdfList invalidDescriptor = BdfList.of(authorName, invalidKey, false);
v.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
null));
@@ -136,7 +137,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest {
@Test
public void testAcceptsMinLengthPublicKey() throws Exception {
byte[] key = TestUtils.getRandomBytes(1);
BdfList validDescriptor = BdfList.of(authorName, key);
BdfList validDescriptor = BdfList.of(authorName, key, false);
expectCreateBlog(authorName, key);
expectEncodeMetadata(INVITE);