mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
fix formatting
This commit is contained in:
@@ -21,36 +21,36 @@ import lombok.Getter;
|
||||
@Getter
|
||||
public class CommaFeedConfiguration extends Configuration {
|
||||
|
||||
public static enum CacheType {
|
||||
public enum CacheType {
|
||||
NOOP, REDIS
|
||||
}
|
||||
|
||||
private ResourceBundle bundle;
|
||||
|
||||
public CommaFeedConfiguration() {
|
||||
bundle = ResourceBundle.getBundle("application");
|
||||
}
|
||||
|
||||
@Valid
|
||||
@NotNull
|
||||
@JsonProperty("database")
|
||||
private DataSourceFactory dataSourceFactory = new DataSourceFactory();
|
||||
private final DataSourceFactory dataSourceFactory = new DataSourceFactory();
|
||||
|
||||
@Valid
|
||||
@NotNull
|
||||
@JsonProperty("redis")
|
||||
private RedisPoolFactory redisPoolFactory = new RedisPoolFactory();
|
||||
private final RedisPoolFactory redisPoolFactory = new RedisPoolFactory();
|
||||
|
||||
@Valid
|
||||
@NotNull
|
||||
@JsonProperty("session")
|
||||
private SessionHandlerFactory SessionHandlerFactory = new SessionHandlerFactory();
|
||||
private final SessionHandlerFactory sessionHandlerFactory = new SessionHandlerFactory();
|
||||
|
||||
@Valid
|
||||
@NotNull
|
||||
@JsonProperty("app")
|
||||
private ApplicationSettings applicationSettings;
|
||||
|
||||
private final ResourceBundle bundle;
|
||||
|
||||
public CommaFeedConfiguration() {
|
||||
bundle = ResourceBundle.getBundle("application");
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return bundle.getString("version");
|
||||
}
|
||||
|
||||
@@ -2,16 +2,13 @@ package com.commafeed;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
import com.codahale.metrics.MetricFilter;
|
||||
import com.codahale.metrics.MetricRegistry;
|
||||
import com.codahale.metrics.graphite.Graphite;
|
||||
import com.codahale.metrics.graphite.GraphiteReporter;
|
||||
import com.codahale.metrics.MetricFilter;
|
||||
import com.commafeed.CommaFeedConfiguration.ApplicationSettings;
|
||||
import com.commafeed.CommaFeedConfiguration.CacheType;
|
||||
import com.commafeed.backend.cache.CacheService;
|
||||
@@ -33,6 +30,10 @@ import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.multibindings.Multibinder;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class CommaFeedModule extends AbstractModule {
|
||||
@@ -76,15 +77,16 @@ public class CommaFeedModule extends AbstractModule {
|
||||
final int graphitePort = settings.getGraphitePort();
|
||||
final int graphiteInterval = settings.getGraphiteInterval();
|
||||
|
||||
log.info("Graphite Metrics will be sent to host={}, port={}, prefix={}, interval={}sec", graphiteHost, graphitePort, graphitePrefix, graphiteInterval);
|
||||
log.info("Graphite Metrics will be sent to host={}, port={}, prefix={}, interval={}sec", graphiteHost, graphitePort,
|
||||
graphitePrefix, graphiteInterval);
|
||||
|
||||
final Graphite graphite = new Graphite(new InetSocketAddress(graphiteHost, graphitePort));
|
||||
final GraphiteReporter reporter = GraphiteReporter.forRegistry(metrics)
|
||||
.prefixedWith(graphitePrefix)
|
||||
.convertRatesTo(TimeUnit.SECONDS)
|
||||
.convertDurationsTo(TimeUnit.MILLISECONDS)
|
||||
.filter(MetricFilter.ALL)
|
||||
.build(graphite);
|
||||
.prefixedWith(graphitePrefix)
|
||||
.convertRatesTo(TimeUnit.SECONDS)
|
||||
.convertDurationsTo(TimeUnit.MILLISECONDS)
|
||||
.filter(MetricFilter.ALL)
|
||||
.build(graphite);
|
||||
reporter.start(graphiteInterval, TimeUnit.SECONDS);
|
||||
} else {
|
||||
log.info("Graphite Metrics Disabled. Metrics will not be sent.");
|
||||
|
||||
@@ -5,12 +5,6 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.Pipeline;
|
||||
|
||||
import com.commafeed.backend.model.Feed;
|
||||
import com.commafeed.backend.model.FeedSubscription;
|
||||
import com.commafeed.backend.model.Models;
|
||||
@@ -20,11 +14,17 @@ import com.commafeed.frontend.model.UnreadCount;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.Pipeline;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class RedisCacheService extends CacheService {
|
||||
|
||||
private static ObjectMapper MAPPER = new ObjectMapper();
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
|
||||
private final JedisPool pool;
|
||||
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
package com.commafeed.backend.cache;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import lombok.Getter;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.JedisPoolConfig;
|
||||
import redis.clients.jedis.Protocol;
|
||||
|
||||
@Getter
|
||||
public class RedisPoolFactory {
|
||||
private String host = "localhost";
|
||||
private int port = Protocol.DEFAULT_PORT;
|
||||
private String password = null;
|
||||
private int timeout = Protocol.DEFAULT_TIMEOUT;
|
||||
private int database = Protocol.DEFAULT_DATABASE;
|
||||
private final String host = "localhost";
|
||||
private final int port = Protocol.DEFAULT_PORT;
|
||||
private String password;
|
||||
private final int timeout = Protocol.DEFAULT_TIMEOUT;
|
||||
private final int database = Protocol.DEFAULT_DATABASE;
|
||||
|
||||
private int maxTotal = 500;
|
||||
private final int maxTotal = 500;
|
||||
|
||||
public JedisPool build() {
|
||||
JedisPoolConfig config = new JedisPoolConfig();
|
||||
|
||||
@@ -38,6 +38,18 @@ import com.querydsl.jpa.impl.JPAQuery;
|
||||
@Singleton
|
||||
public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
||||
|
||||
private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_DESC = new Comparator<FeedEntryStatus>() {
|
||||
@Override
|
||||
public int compare(FeedEntryStatus o1, FeedEntryStatus o2) {
|
||||
CompareToBuilder builder = new CompareToBuilder();
|
||||
builder.append(o2.getEntryUpdated(), o1.getEntryUpdated());
|
||||
builder.append(o2.getId(), o1.getId());
|
||||
return builder.toComparison();
|
||||
}
|
||||
};
|
||||
|
||||
private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_ASC = Ordering.from(STATUS_COMPARATOR_DESC).reverse();
|
||||
|
||||
private final FeedEntryDAO feedEntryDAO;
|
||||
private final FeedEntryTagDAO feedEntryTagDAO;
|
||||
private final CommaFeedConfiguration config;
|
||||
@@ -56,18 +68,6 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_DESC = new Comparator<FeedEntryStatus>() {
|
||||
@Override
|
||||
public int compare(FeedEntryStatus o1, FeedEntryStatus o2) {
|
||||
CompareToBuilder builder = new CompareToBuilder();
|
||||
builder.append(o2.getEntryUpdated(), o1.getEntryUpdated());
|
||||
builder.append(o2.getId(), o1.getId());
|
||||
return builder.toComparison();
|
||||
}
|
||||
};
|
||||
|
||||
private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_ASC = Ordering.from(STATUS_COMPARATOR_DESC).reverse();
|
||||
|
||||
public FeedEntryStatus getStatus(User user, FeedSubscription sub, FeedEntry entry) {
|
||||
List<FeedEntryStatus> statuses = query().selectFrom(status).where(status.entry.eq(entry), status.subscription.eq(sub)).fetch();
|
||||
FeedEntryStatus status = Iterables.getFirst(statuses, null);
|
||||
|
||||
@@ -7,16 +7,6 @@ import org.hibernate.context.internal.ManagedSessionContext;
|
||||
|
||||
public class UnitOfWork {
|
||||
|
||||
@FunctionalInterface
|
||||
public static interface SessionRunner {
|
||||
public void runInSession();
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public static interface SessionRunnerReturningValue<T> {
|
||||
public T runInSession();
|
||||
}
|
||||
|
||||
public static void run(SessionFactory sessionFactory, SessionRunner sessionRunner) {
|
||||
call(sessionFactory, () -> {
|
||||
sessionRunner.runInSession();
|
||||
@@ -66,4 +56,14 @@ public class UnitOfWork {
|
||||
throw (E) e;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SessionRunner {
|
||||
void runInSession();
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SessionRunnerReturningValue<T> {
|
||||
T runInSession();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,22 +3,22 @@ package com.commafeed.backend.favicon;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.commafeed.backend.model.Feed;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public abstract class AbstractFaviconFetcher {
|
||||
|
||||
private static List<String> ICON_MIMETYPE_BLACKLIST = Arrays.asList("application/xml", "text/html");
|
||||
private static long MIN_ICON_LENGTH = 100;
|
||||
private static long MAX_ICON_LENGTH = 100000;
|
||||
protected static final int TIMEOUT = 4000;
|
||||
|
||||
protected static int TIMEOUT = 4000;
|
||||
private static final List<String> ICON_MIMETYPE_BLACKLIST = Arrays.asList("application/xml", "text/html");
|
||||
private static final long MIN_ICON_LENGTH = 100;
|
||||
private static final long MAX_ICON_LENGTH = 100000;
|
||||
|
||||
public abstract Favicon fetch(Feed feed);
|
||||
|
||||
|
||||
@@ -3,9 +3,6 @@ package com.commafeed.backend.favicon;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
@@ -16,6 +13,9 @@ import com.commafeed.backend.HttpGetter.HttpResult;
|
||||
import com.commafeed.backend.feed.FeedUtils;
|
||||
import com.commafeed.backend.model.Feed;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Inspired/Ported from https://github.com/potatolondon/getfavicon
|
||||
*
|
||||
|
||||
@@ -8,9 +8,6 @@ import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.utils.URLEncodedUtils;
|
||||
|
||||
@@ -18,6 +15,9 @@ import com.commafeed.backend.HttpGetter;
|
||||
import com.commafeed.backend.HttpGetter.HttpResult;
|
||||
import com.commafeed.backend.model.Feed;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
|
||||
@@ -28,7 +28,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }) )
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
public class YoutubeFaviconFetcher extends AbstractFaviconFetcher {
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@ package com.commafeed.backend.feed;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* A keyword used in a search query
|
||||
*/
|
||||
@@ -15,7 +15,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
@RequiredArgsConstructor
|
||||
public class FeedEntryKeyword {
|
||||
|
||||
public static enum Mode {
|
||||
public enum Mode {
|
||||
INCLUDE, EXCLUDE;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,8 +86,9 @@ public class FeedFetcher {
|
||||
private static String extractFeedUrl(Set<FeedURLProvider> urlProviders, String url, String urlContent) {
|
||||
for (FeedURLProvider urlProvider : urlProviders) {
|
||||
String feedUrl = urlProvider.get(url, urlContent);
|
||||
if (feedUrl != null)
|
||||
if (feedUrl != null) {
|
||||
return feedUrl;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -48,7 +48,7 @@ public class FeedParser {
|
||||
private static final Namespace ATOM_10_NS = Namespace.getNamespace(ATOM_10_URI);
|
||||
|
||||
private static final Date START = new Date(86400000);
|
||||
private static final Date END = new Date(1000l * Integer.MAX_VALUE - 86400000);
|
||||
private static final Date END = new Date(1000L * Integer.MAX_VALUE - 86400000);
|
||||
|
||||
public FetchedFeed parse(String feedUrl, byte[] xml) throws FeedException {
|
||||
FetchedFeed fetchedFeed = new FetchedFeed();
|
||||
|
||||
@@ -2,12 +2,12 @@ package com.commafeed.backend.feed;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import com.commafeed.backend.model.Feed;
|
||||
import com.commafeed.backend.model.FeedEntry;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class FeedRefreshContext {
|
||||
|
||||
@@ -81,10 +81,6 @@ public class FeedRefreshExecutor {
|
||||
pool.execute(task);
|
||||
}
|
||||
|
||||
public static interface Task extends Runnable {
|
||||
boolean isUrgent();
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
pool.shutdownNow();
|
||||
while (!pool.isTerminated()) {
|
||||
@@ -95,4 +91,9 @@ public class FeedRefreshExecutor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface Task extends Runnable {
|
||||
boolean isUrgent();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
package com.commafeed.backend.feed;
|
||||
|
||||
import io.dropwizard.lifecycle.Managed;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import com.codahale.metrics.Meter;
|
||||
import com.codahale.metrics.MetricRegistry;
|
||||
import com.commafeed.CommaFeedConfiguration;
|
||||
import com.commafeed.backend.dao.FeedDAO;
|
||||
|
||||
import io.dropwizard.lifecycle.Managed;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Infinite loop fetching feeds from @FeedQueues and queuing them to the {@link FeedRefreshWorker} pool.
|
||||
*
|
||||
@@ -26,10 +25,10 @@ public class FeedRefreshTaskGiver implements Managed {
|
||||
private final FeedQueues queues;
|
||||
private final FeedRefreshWorker worker;
|
||||
|
||||
private ExecutorService executor;
|
||||
private final ExecutorService executor;
|
||||
|
||||
private Meter feedRefreshed;
|
||||
private Meter threadWaited;
|
||||
private final Meter feedRefreshed;
|
||||
private final Meter threadWaited;
|
||||
|
||||
@Inject
|
||||
public FeedRefreshTaskGiver(FeedQueues queues, FeedDAO feedDAO, FeedRefreshWorker worker, CommaFeedConfiguration config,
|
||||
|
||||
@@ -49,13 +49,13 @@ public class FeedRefreshUpdater implements Managed {
|
||||
private final FeedSubscriptionDAO feedSubscriptionDAO;
|
||||
private final CacheService cache;
|
||||
|
||||
private FeedRefreshExecutor pool;
|
||||
private Striped<Lock> locks;
|
||||
private final FeedRefreshExecutor pool;
|
||||
private final Striped<Lock> locks;
|
||||
|
||||
private Meter entryCacheMiss;
|
||||
private Meter entryCacheHit;
|
||||
private Meter feedUpdated;
|
||||
private Meter entryInserted;
|
||||
private final Meter entryCacheMiss;
|
||||
private final Meter entryCacheHit;
|
||||
private final Meter feedUpdated;
|
||||
private final Meter entryInserted;
|
||||
|
||||
@Inject
|
||||
public FeedRefreshUpdater(SessionFactory sessionFactory, FeedUpdateService feedUpdateService, PubSubService pubSubService,
|
||||
@@ -94,70 +94,6 @@ public class FeedRefreshUpdater implements Managed {
|
||||
pool.execute(new EntryTask(context));
|
||||
}
|
||||
|
||||
private class EntryTask implements Task {
|
||||
|
||||
private FeedRefreshContext context;
|
||||
|
||||
public EntryTask(FeedRefreshContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
boolean ok = true;
|
||||
final Feed feed = context.getFeed();
|
||||
List<FeedEntry> entries = context.getEntries();
|
||||
if (entries.isEmpty()) {
|
||||
feed.setMessage("Feed has no entries");
|
||||
} else {
|
||||
List<String> lastEntries = cache.getLastEntries(feed);
|
||||
List<String> currentEntries = new ArrayList<>();
|
||||
|
||||
List<FeedSubscription> subscriptions = null;
|
||||
for (FeedEntry entry : entries) {
|
||||
String cacheKey = cache.buildUniqueEntryKey(feed, entry);
|
||||
if (!lastEntries.contains(cacheKey)) {
|
||||
log.debug("cache miss for {}", entry.getUrl());
|
||||
if (subscriptions == null) {
|
||||
subscriptions = UnitOfWork.call(sessionFactory, () -> feedSubscriptionDAO.findByFeed(feed));
|
||||
}
|
||||
ok &= addEntry(feed, entry, subscriptions);
|
||||
entryCacheMiss.mark();
|
||||
} else {
|
||||
log.debug("cache hit for {}", entry.getUrl());
|
||||
entryCacheHit.mark();
|
||||
}
|
||||
|
||||
currentEntries.add(cacheKey);
|
||||
}
|
||||
cache.setLastEntries(feed, currentEntries);
|
||||
|
||||
if (subscriptions == null) {
|
||||
feed.setMessage("No new entries found");
|
||||
} else if (!subscriptions.isEmpty()) {
|
||||
List<User> users = subscriptions.stream().map(s -> s.getUser()).collect(Collectors.toList());
|
||||
cache.invalidateUnreadCount(subscriptions.toArray(new FeedSubscription[0]));
|
||||
cache.invalidateUserRootCategory(users.toArray(new User[0]));
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getApplicationSettings().getPubsubhubbub()) {
|
||||
handlePubSub(feed);
|
||||
}
|
||||
if (!ok) {
|
||||
// requeue asap
|
||||
feed.setDisabledUntil(new Date(0));
|
||||
}
|
||||
feedUpdated.mark();
|
||||
queues.giveBack(feed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUrgent() {
|
||||
return context.isUrgent();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean addEntry(final Feed feed, final FeedEntry entry, final List<FeedSubscription> subscriptions) {
|
||||
boolean success = false;
|
||||
|
||||
@@ -223,4 +159,68 @@ public class FeedRefreshUpdater implements Managed {
|
||||
}
|
||||
}
|
||||
|
||||
private class EntryTask implements Task {
|
||||
|
||||
private final FeedRefreshContext context;
|
||||
|
||||
public EntryTask(FeedRefreshContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
boolean ok = true;
|
||||
final Feed feed = context.getFeed();
|
||||
List<FeedEntry> entries = context.getEntries();
|
||||
if (entries.isEmpty()) {
|
||||
feed.setMessage("Feed has no entries");
|
||||
} else {
|
||||
List<String> lastEntries = cache.getLastEntries(feed);
|
||||
List<String> currentEntries = new ArrayList<>();
|
||||
|
||||
List<FeedSubscription> subscriptions = null;
|
||||
for (FeedEntry entry : entries) {
|
||||
String cacheKey = cache.buildUniqueEntryKey(feed, entry);
|
||||
if (!lastEntries.contains(cacheKey)) {
|
||||
log.debug("cache miss for {}", entry.getUrl());
|
||||
if (subscriptions == null) {
|
||||
subscriptions = UnitOfWork.call(sessionFactory, () -> feedSubscriptionDAO.findByFeed(feed));
|
||||
}
|
||||
ok &= addEntry(feed, entry, subscriptions);
|
||||
entryCacheMiss.mark();
|
||||
} else {
|
||||
log.debug("cache hit for {}", entry.getUrl());
|
||||
entryCacheHit.mark();
|
||||
}
|
||||
|
||||
currentEntries.add(cacheKey);
|
||||
}
|
||||
cache.setLastEntries(feed, currentEntries);
|
||||
|
||||
if (subscriptions == null) {
|
||||
feed.setMessage("No new entries found");
|
||||
} else if (!subscriptions.isEmpty()) {
|
||||
List<User> users = subscriptions.stream().map(FeedSubscription::getUser).collect(Collectors.toList());
|
||||
cache.invalidateUnreadCount(subscriptions.toArray(new FeedSubscription[0]));
|
||||
cache.invalidateUserRootCategory(users.toArray(new User[0]));
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getApplicationSettings().getPubsubhubbub()) {
|
||||
handlePubSub(feed);
|
||||
}
|
||||
if (!ok) {
|
||||
// requeue asap
|
||||
feed.setDisabledUntil(new Date(0));
|
||||
}
|
||||
feedUpdated.mark();
|
||||
queues.giveBack(feed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUrgent() {
|
||||
return context.isUrgent();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.commafeed.backend.feed;
|
||||
|
||||
import io.dropwizard.lifecycle.Managed;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -10,8 +8,6 @@ import java.util.stream.Collectors;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
@@ -23,6 +19,9 @@ import com.commafeed.backend.feed.FeedRefreshExecutor.Task;
|
||||
import com.commafeed.backend.model.Feed;
|
||||
import com.commafeed.backend.model.FeedEntry;
|
||||
|
||||
import io.dropwizard.lifecycle.Managed;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Calls {@link FeedFetcher} and handles its outcome
|
||||
*
|
||||
@@ -61,25 +60,6 @@ public class FeedRefreshWorker implements Managed {
|
||||
pool.execute(new FeedTask(context));
|
||||
}
|
||||
|
||||
private class FeedTask implements Task {
|
||||
|
||||
private FeedRefreshContext context;
|
||||
|
||||
public FeedTask(FeedRefreshContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
update(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUrgent() {
|
||||
return context.isUrgent();
|
||||
}
|
||||
}
|
||||
|
||||
private void update(FeedRefreshContext context) {
|
||||
Feed feed = context.getFeed();
|
||||
int refreshInterval = config.getApplicationSettings().getRefreshIntervalMinutes();
|
||||
@@ -97,8 +77,8 @@ public class FeedRefreshWorker implements Managed {
|
||||
}
|
||||
|
||||
if (config.getApplicationSettings().getHeavyLoad()) {
|
||||
disabledUntil = FeedUtils.buildDisabledUntil(fetchedFeed.getFeed().getLastEntryDate(), fetchedFeed.getFeed()
|
||||
.getAverageEntryInterval(), disabledUntil);
|
||||
disabledUntil = FeedUtils.buildDisabledUntil(fetchedFeed.getFeed().getLastEntryDate(),
|
||||
fetchedFeed.getFeed().getAverageEntryInterval(), disabledUntil);
|
||||
}
|
||||
String urlAfterRedirect = fetchedFeed.getUrlAfterRedirect();
|
||||
if (StringUtils.equals(url, urlAfterRedirect)) {
|
||||
@@ -156,7 +136,7 @@ public class FeedRefreshWorker implements Managed {
|
||||
topic = "http://" + topic;
|
||||
} else if (topic.startsWith("feed://")) {
|
||||
topic = "http://" + topic.substring(7);
|
||||
} else if (topic.startsWith("http") == false) {
|
||||
} else if (!topic.startsWith("http")) {
|
||||
topic = "http://" + topic;
|
||||
}
|
||||
log.debug("feed {} has pubsub info: {}", feed.getUrl(), topic);
|
||||
@@ -165,4 +145,23 @@ public class FeedRefreshWorker implements Managed {
|
||||
feed.setPushTopicHash(DigestUtils.sha1Hex(topic));
|
||||
}
|
||||
}
|
||||
|
||||
private class FeedTask implements Task {
|
||||
|
||||
private final FeedRefreshContext context;
|
||||
|
||||
public FeedTask(FeedRefreshContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
update(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUrgent() {
|
||||
return context.isUrgent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ public class FeedUtils {
|
||||
public static Charset guessEncoding(byte[] bytes) {
|
||||
String extracted = extractDeclaredEncoding(bytes);
|
||||
if (StringUtils.startsWithIgnoreCase(extracted, "iso-8859-")) {
|
||||
if (StringUtils.endsWith(extracted, "1") == false) {
|
||||
if (!StringUtils.endsWith(extracted, "1")) {
|
||||
return Charset.forName(extracted);
|
||||
}
|
||||
} else if (StringUtils.startsWithIgnoreCase(extracted, "windows-")) {
|
||||
|
||||
@@ -3,12 +3,12 @@ package com.commafeed.backend.feed;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import com.commafeed.backend.model.Feed;
|
||||
import com.commafeed.backend.model.FeedEntry;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class FetchedFeed {
|
||||
|
||||
@@ -8,11 +8,11 @@ import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
|
||||
@Entity
|
||||
@Table(name = "USERS")
|
||||
@SuppressWarnings("serial")
|
||||
@@ -55,7 +55,7 @@ public class User extends AbstractModel {
|
||||
private Date lastFullRefresh;
|
||||
|
||||
public boolean shouldRefreshFeedsAt(Date when) {
|
||||
return (lastFullRefresh == null || lastFullRefreshMoreThan30MinutesBefore(when));
|
||||
return lastFullRefresh == null || lastFullRefreshMoreThan30MinutesBefore(when);
|
||||
}
|
||||
|
||||
private boolean lastFullRefreshMoreThan30MinutesBefore(Date when) {
|
||||
|
||||
@@ -19,7 +19,7 @@ import lombok.Setter;
|
||||
@Setter
|
||||
public class UserRole extends AbstractModel {
|
||||
|
||||
public static enum Role {
|
||||
public enum Role {
|
||||
USER, ADMIN
|
||||
}
|
||||
|
||||
|
||||
@@ -6,9 +6,6 @@ import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@@ -23,6 +20,9 @@ import com.rometools.opml.feed.opml.Opml;
|
||||
import com.rometools.opml.feed.opml.Outline;
|
||||
import com.rometools.rome.io.WireFeedInput;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
|
||||
@@ -24,7 +24,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
*
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }) )
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
public class DatabaseCleaningService {
|
||||
|
||||
|
||||
@@ -12,8 +12,6 @@ import java.util.concurrent.TimeoutException;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.apache.commons.jexl2.JexlContext;
|
||||
import org.apache.commons.jexl2.JexlEngine;
|
||||
import org.apache.commons.jexl2.JexlException;
|
||||
@@ -30,12 +28,16 @@ import org.jsoup.Jsoup;
|
||||
|
||||
import com.commafeed.backend.model.FeedEntry;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
public class FeedEntryFilteringService {
|
||||
|
||||
private static final JexlEngine ENGINE = initEngine();
|
||||
|
||||
private final ExecutorService executor = Executors.newCachedThreadPool();
|
||||
|
||||
private static JexlEngine initEngine() {
|
||||
// classloader that prevents object creation
|
||||
ClassLoader cl = new ClassLoader() {
|
||||
@@ -70,8 +72,6 @@ public class FeedEntryFilteringService {
|
||||
return engine;
|
||||
}
|
||||
|
||||
private ExecutorService executor = Executors.newCachedThreadPool();
|
||||
|
||||
public boolean filterMatchesEntry(String filter, FeedEntry entry) throws FeedEntryFilterException {
|
||||
if (StringUtils.isBlank(filter)) {
|
||||
return true;
|
||||
@@ -87,8 +87,8 @@ public class FeedEntryFilteringService {
|
||||
JexlContext context = new MapContext();
|
||||
context.set("title", entry.getContent().getTitle() == null ? "" : Jsoup.parse(entry.getContent().getTitle()).text().toLowerCase());
|
||||
context.set("author", entry.getContent().getAuthor() == null ? "" : entry.getContent().getAuthor().toLowerCase());
|
||||
context.set("content", entry.getContent().getContent() == null ? "" : Jsoup.parse(entry.getContent().getContent()).text()
|
||||
.toLowerCase());
|
||||
context.set("content",
|
||||
entry.getContent().getContent() == null ? "" : Jsoup.parse(entry.getContent().getContent()).text().toLowerCase());
|
||||
context.set("url", entry.getUrl() == null ? "" : entry.getUrl().toLowerCase());
|
||||
context.set("categories", entry.getContent().getCategories() == null ? "" : entry.getContent().getCategories().toLowerCase());
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@ import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import com.commafeed.backend.cache.CacheService;
|
||||
import com.commafeed.backend.dao.FeedEntryDAO;
|
||||
import com.commafeed.backend.dao.FeedEntryStatusDAO;
|
||||
@@ -19,6 +17,8 @@ import com.commafeed.backend.model.FeedEntryStatus;
|
||||
import com.commafeed.backend.model.FeedSubscription;
|
||||
import com.commafeed.backend.model.User;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
public class FeedEntryService {
|
||||
|
||||
@@ -7,14 +7,14 @@ import java.util.stream.Collectors;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import com.commafeed.backend.dao.FeedEntryDAO;
|
||||
import com.commafeed.backend.dao.FeedEntryTagDAO;
|
||||
import com.commafeed.backend.model.FeedEntry;
|
||||
import com.commafeed.backend.model.FeedEntryTag;
|
||||
import com.commafeed.backend.model.User;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
public class FeedEntryTagService {
|
||||
@@ -29,10 +29,12 @@ public class FeedEntryTagService {
|
||||
}
|
||||
|
||||
List<FeedEntryTag> existingTags = feedEntryTagDAO.findByEntry(user, entry);
|
||||
Set<String> existingTagNames = existingTags.stream().map(t -> t.getName()).collect(Collectors.toSet());
|
||||
Set<String> existingTagNames = existingTags.stream().map(FeedEntryTag::getName).collect(Collectors.toSet());
|
||||
|
||||
List<FeedEntryTag> addList = tagNames.stream().filter(name -> !existingTagNames.contains(name))
|
||||
.map(name -> new FeedEntryTag(user, entry, name)).collect(Collectors.toList());
|
||||
List<FeedEntryTag> addList = tagNames.stream()
|
||||
.filter(name -> !existingTagNames.contains(name))
|
||||
.map(name -> new FeedEntryTag(user, entry, name))
|
||||
.collect(Collectors.toList());
|
||||
List<FeedEntryTag> removeList = existingTags.stream().filter(tag -> !tagNames.contains(tag.getName())).collect(Collectors.toList());
|
||||
|
||||
feedEntryTagDAO.saveOrUpdate(addList);
|
||||
|
||||
@@ -7,9 +7,6 @@ import java.util.stream.Collectors;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.commafeed.CommaFeedConfiguration;
|
||||
@@ -26,18 +23,14 @@ import com.commafeed.backend.model.Models;
|
||||
import com.commafeed.backend.model.User;
|
||||
import com.commafeed.frontend.model.UnreadCount;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
public class FeedSubscriptionService {
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public static class FeedSubscriptionException extends RuntimeException {
|
||||
private FeedSubscriptionException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private final FeedDAO feedDAO;
|
||||
private final FeedEntryStatusDAO feedEntryStatusDAO;
|
||||
private final FeedSubscriptionDAO feedSubscriptionDAO;
|
||||
@@ -108,7 +101,7 @@ public class FeedSubscriptionService {
|
||||
}
|
||||
|
||||
public Map<Long, UnreadCount> getUnreadCount(User user) {
|
||||
return feedSubscriptionDAO.findAll(user).stream().collect(Collectors.toMap(s -> s.getId(), s -> getUnreadCount(user, s)));
|
||||
return feedSubscriptionDAO.findAll(user).stream().collect(Collectors.toMap(FeedSubscription::getId, s -> getUnreadCount(user, s)));
|
||||
}
|
||||
|
||||
private UnreadCount getUnreadCount(User user, FeedSubscription sub) {
|
||||
@@ -121,4 +114,11 @@ public class FeedSubscriptionService {
|
||||
return count;
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public static class FeedSubscriptionException extends RuntimeException {
|
||||
private FeedSubscriptionException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,9 +6,6 @@ import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
||||
import com.commafeed.backend.dao.FeedEntryDAO;
|
||||
@@ -20,6 +17,9 @@ import com.commafeed.backend.model.FeedEntryStatus;
|
||||
import com.commafeed.backend.model.FeedSubscription;
|
||||
import com.commafeed.backend.service.FeedEntryFilteringService.FeedEntryFilterException;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
|
||||
@@ -13,12 +13,12 @@ import javax.mail.Transport;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import com.commafeed.CommaFeedConfiguration;
|
||||
import com.commafeed.CommaFeedConfiguration.ApplicationSettings;
|
||||
import com.commafeed.backend.model.User;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
* Mailing service
|
||||
*
|
||||
|
||||
@@ -12,11 +12,11 @@ import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
// taken from http://www.javacodegeeks.com/2012/05/secure-password-storage-donts-dos-and.html
|
||||
@SuppressWarnings("serial")
|
||||
@Slf4j
|
||||
|
||||
@@ -7,9 +7,6 @@ import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.HttpHeaders;
|
||||
@@ -28,6 +25,9 @@ import com.commafeed.backend.feed.FeedUtils;
|
||||
import com.commafeed.backend.model.Feed;
|
||||
import com.commafeed.frontend.resource.PubSubHubbubCallbackREST;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Sends push subscription requests. Callback is handled by {@link PubSubHubbubCallbackREST}
|
||||
*
|
||||
@@ -76,8 +76,8 @@ public class PubSubService {
|
||||
queues.giveBack(feed);
|
||||
log.debug("handled pushpress subfeed {} : {}", topic, feed.getPushTopic());
|
||||
} else {
|
||||
throw new Exception("Unexpected response code: " + code + " " + response.getStatusLine().getReasonPhrase() + " - "
|
||||
+ message);
|
||||
throw new Exception(
|
||||
"Unexpected response code: " + code + " " + response.getStatusLine().getReasonPhrase() + " - " + message);
|
||||
}
|
||||
}
|
||||
log.debug("subscribed to {} for {}", hub, topic);
|
||||
|
||||
@@ -9,8 +9,6 @@ import java.util.UUID;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@@ -26,6 +24,8 @@ import com.commafeed.backend.model.UserRole.Role;
|
||||
import com.commafeed.backend.service.internal.PostLoginActivities;
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
public class UserService {
|
||||
@@ -102,8 +102,8 @@ public class UserService {
|
||||
|
||||
Preconditions.checkNotNull(email);
|
||||
Preconditions.checkArgument(StringUtils.length(name) >= 3, "Name too short (3 characters minimum)");
|
||||
Preconditions
|
||||
.checkArgument(forceRegistration || StringUtils.length(password) >= 6, "Password too short (6 characters maximum)");
|
||||
Preconditions.checkArgument(forceRegistration || StringUtils.length(password) >= 6,
|
||||
"Password too short (6 characters maximum)");
|
||||
Preconditions.checkArgument(StringUtils.contains(email, "@"), "Invalid email address");
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@ import java.util.Date;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
|
||||
import com.commafeed.CommaFeedConfiguration;
|
||||
@@ -14,6 +12,8 @@ import com.commafeed.backend.dao.UserDAO;
|
||||
import com.commafeed.backend.model.User;
|
||||
import com.commafeed.backend.service.FeedSubscriptionService;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
public class PostLoginActivities {
|
||||
|
||||
@@ -5,11 +5,11 @@ import java.util.concurrent.TimeUnit;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import com.commafeed.CommaFeedConfiguration;
|
||||
import com.commafeed.backend.service.DatabaseCleaningService;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
public class OldEntriesCleanupTask extends ScheduledTask {
|
||||
|
||||
@@ -6,11 +6,11 @@ import java.util.concurrent.TimeUnit;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import com.commafeed.CommaFeedConfiguration;
|
||||
import com.commafeed.backend.service.DatabaseCleaningService;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
public class OldStatusesCleanupTask extends ScheduledTask {
|
||||
|
||||
@@ -5,10 +5,10 @@ import java.util.concurrent.TimeUnit;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import com.commafeed.backend.service.DatabaseCleaningService;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
public class OrphanedContentsCleanupTask extends ScheduledTask {
|
||||
|
||||
@@ -5,10 +5,10 @@ import java.util.concurrent.TimeUnit;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import com.commafeed.backend.service.DatabaseCleaningService;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
public class OrphanedFeedsCleanupTask extends ScheduledTask {
|
||||
|
||||
@@ -11,8 +11,6 @@ import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.eclipse.jetty.util.B64Code;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.glassfish.jersey.server.internal.inject.AbstractContainerRequestValueFactory;
|
||||
@@ -22,6 +20,8 @@ import com.commafeed.backend.model.UserRole.Role;
|
||||
import com.commafeed.backend.service.UserService;
|
||||
import com.commafeed.frontend.session.SessionHelper;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class SecurityCheckFactory extends AbstractContainerRequestValueFactory<User> {
|
||||
|
||||
@@ -52,11 +52,15 @@ public class SecurityCheckFactory extends AbstractContainerRequestValueFactory<U
|
||||
return user.get();
|
||||
} else {
|
||||
throw new WebApplicationException(Response.status(Response.Status.FORBIDDEN)
|
||||
.entity("You don't have the required role to access this resource.").type(MediaType.TEXT_PLAIN_TYPE).build());
|
||||
.entity("You don't have the required role to access this resource.")
|
||||
.type(MediaType.TEXT_PLAIN_TYPE)
|
||||
.build());
|
||||
}
|
||||
} else {
|
||||
throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED)
|
||||
.entity("Credentials are required to access this resource.").type(MediaType.TEXT_PLAIN_TYPE).build());
|
||||
.entity("Credentials are required to access this resource.")
|
||||
.type(MediaType.TEXT_PLAIN_TYPE)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ package com.commafeed.frontend.auth;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.glassfish.hk2.api.Factory;
|
||||
import org.glassfish.hk2.api.InjectionResolver;
|
||||
import org.glassfish.hk2.api.ServiceLocator;
|
||||
@@ -19,6 +17,8 @@ import org.glassfish.jersey.server.spi.internal.ValueFactoryProvider;
|
||||
import com.commafeed.backend.model.User;
|
||||
import com.commafeed.backend.service.UserService;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Singleton
|
||||
public class SecurityCheckFactoryProvider extends AbstractValueFactoryProvider {
|
||||
|
||||
@@ -32,8 +32,9 @@ public class SecurityCheckFactoryProvider extends AbstractValueFactoryProvider {
|
||||
final Class<?> classType = parameter.getRawType();
|
||||
|
||||
SecurityCheck securityCheck = parameter.getAnnotation(SecurityCheck.class);
|
||||
if (securityCheck == null)
|
||||
if (securityCheck == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (classType.isAssignableFrom(User.class)) {
|
||||
return new SecurityCheckFactory(securityCheck.value(), securityCheck.apiKeyAllowed());
|
||||
|
||||
@@ -30,74 +30,6 @@ import lombok.Data;
|
||||
@Data
|
||||
public class Entry implements Serializable {
|
||||
|
||||
public static Entry build(FeedEntryStatus status, String publicUrl, boolean proxyImages) {
|
||||
Entry entry = new Entry();
|
||||
|
||||
FeedEntry feedEntry = status.getEntry();
|
||||
FeedSubscription sub = status.getSubscription();
|
||||
FeedEntryContent content = feedEntry.getContent();
|
||||
|
||||
entry.setId(String.valueOf(feedEntry.getId()));
|
||||
entry.setGuid(feedEntry.getGuid());
|
||||
entry.setRead(status.isRead());
|
||||
entry.setStarred(status.isStarred());
|
||||
entry.setMarkable(status.isMarkable());
|
||||
entry.setDate(feedEntry.getUpdated());
|
||||
entry.setInsertedDate(feedEntry.getInserted());
|
||||
entry.setUrl(feedEntry.getUrl());
|
||||
entry.setFeedName(sub.getTitle());
|
||||
entry.setFeedId(String.valueOf(sub.getId()));
|
||||
entry.setFeedUrl(sub.getFeed().getUrl());
|
||||
entry.setFeedLink(sub.getFeed().getLink());
|
||||
entry.setIconUrl(FeedUtils.getFaviconUrl(sub, publicUrl));
|
||||
entry.setTags(status.getTags().stream().map(FeedEntryTag::getName).collect(Collectors.toList()));
|
||||
|
||||
if (content != null) {
|
||||
entry.setRtl(FeedUtils.isRTL(feedEntry));
|
||||
entry.setTitle(content.getTitle());
|
||||
entry.setContent(proxyImages ? FeedUtils.proxyImages(content.getContent(), publicUrl) : content.getContent());
|
||||
entry.setAuthor(content.getAuthor());
|
||||
|
||||
entry.setEnclosureType(content.getEnclosureType());
|
||||
entry.setEnclosureUrl(proxyImages && StringUtils.contains(content.getEnclosureType(), "image")
|
||||
? FeedUtils.proxyImage(content.getEnclosureUrl(), publicUrl)
|
||||
: content.getEnclosureUrl());
|
||||
|
||||
entry.setMediaDescription(content.getMediaDescription());
|
||||
entry.setMediaThumbnailUrl(
|
||||
proxyImages ? FeedUtils.proxyImage(content.getMediaThumbnailUrl(), publicUrl) : content.getMediaThumbnailUrl());
|
||||
entry.setMediaThumbnailWidth(content.getMediaThumbnailWidth());
|
||||
entry.setMediaThumbnailHeight(content.getMediaThumbnailHeight());
|
||||
|
||||
entry.setCategories(content.getCategories());
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
public SyndEntry asRss() {
|
||||
SyndEntry entry = new SyndEntryImpl();
|
||||
|
||||
entry.setUri(getGuid());
|
||||
entry.setTitle(getTitle());
|
||||
entry.setAuthor(getAuthor());
|
||||
|
||||
SyndContentImpl content = new SyndContentImpl();
|
||||
content.setValue(getContent());
|
||||
entry.setContents(Arrays.<SyndContent> asList(content));
|
||||
|
||||
if (getEnclosureUrl() != null) {
|
||||
SyndEnclosureImpl enclosure = new SyndEnclosureImpl();
|
||||
enclosure.setType(getEnclosureType());
|
||||
enclosure.setUrl(getEnclosureUrl());
|
||||
entry.setEnclosures(Arrays.<SyndEnclosure> asList(enclosure));
|
||||
}
|
||||
|
||||
entry.setLink(getUrl());
|
||||
entry.setPublishedDate(getDate());
|
||||
return entry;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "entry id", required = true)
|
||||
private String id;
|
||||
|
||||
@@ -172,4 +104,72 @@ public class Entry implements Serializable {
|
||||
|
||||
@ApiModelProperty(value = "tags", required = true)
|
||||
private List<String> tags;
|
||||
|
||||
public static Entry build(FeedEntryStatus status, String publicUrl, boolean proxyImages) {
|
||||
Entry entry = new Entry();
|
||||
|
||||
FeedEntry feedEntry = status.getEntry();
|
||||
FeedSubscription sub = status.getSubscription();
|
||||
FeedEntryContent content = feedEntry.getContent();
|
||||
|
||||
entry.setId(String.valueOf(feedEntry.getId()));
|
||||
entry.setGuid(feedEntry.getGuid());
|
||||
entry.setRead(status.isRead());
|
||||
entry.setStarred(status.isStarred());
|
||||
entry.setMarkable(status.isMarkable());
|
||||
entry.setDate(feedEntry.getUpdated());
|
||||
entry.setInsertedDate(feedEntry.getInserted());
|
||||
entry.setUrl(feedEntry.getUrl());
|
||||
entry.setFeedName(sub.getTitle());
|
||||
entry.setFeedId(String.valueOf(sub.getId()));
|
||||
entry.setFeedUrl(sub.getFeed().getUrl());
|
||||
entry.setFeedLink(sub.getFeed().getLink());
|
||||
entry.setIconUrl(FeedUtils.getFaviconUrl(sub, publicUrl));
|
||||
entry.setTags(status.getTags().stream().map(FeedEntryTag::getName).collect(Collectors.toList()));
|
||||
|
||||
if (content != null) {
|
||||
entry.setRtl(FeedUtils.isRTL(feedEntry));
|
||||
entry.setTitle(content.getTitle());
|
||||
entry.setContent(proxyImages ? FeedUtils.proxyImages(content.getContent(), publicUrl) : content.getContent());
|
||||
entry.setAuthor(content.getAuthor());
|
||||
|
||||
entry.setEnclosureType(content.getEnclosureType());
|
||||
entry.setEnclosureUrl(proxyImages && StringUtils.contains(content.getEnclosureType(), "image")
|
||||
? FeedUtils.proxyImage(content.getEnclosureUrl(), publicUrl)
|
||||
: content.getEnclosureUrl());
|
||||
|
||||
entry.setMediaDescription(content.getMediaDescription());
|
||||
entry.setMediaThumbnailUrl(
|
||||
proxyImages ? FeedUtils.proxyImage(content.getMediaThumbnailUrl(), publicUrl) : content.getMediaThumbnailUrl());
|
||||
entry.setMediaThumbnailWidth(content.getMediaThumbnailWidth());
|
||||
entry.setMediaThumbnailHeight(content.getMediaThumbnailHeight());
|
||||
|
||||
entry.setCategories(content.getCategories());
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
public SyndEntry asRss() {
|
||||
SyndEntry entry = new SyndEntryImpl();
|
||||
|
||||
entry.setUri(getGuid());
|
||||
entry.setTitle(getTitle());
|
||||
entry.setAuthor(getAuthor());
|
||||
|
||||
SyndContentImpl content = new SyndContentImpl();
|
||||
content.setValue(getContent());
|
||||
entry.setContents(Arrays.<SyndContent> asList(content));
|
||||
|
||||
if (getEnclosureUrl() != null) {
|
||||
SyndEnclosureImpl enclosure = new SyndEnclosureImpl();
|
||||
enclosure.setType(getEnclosureType());
|
||||
enclosure.setUrl(getEnclosureUrl());
|
||||
entry.setEnclosures(Arrays.<SyndEnclosure> asList(enclosure));
|
||||
}
|
||||
|
||||
entry.setLink(getUrl());
|
||||
entry.setPublishedDate(getDate());
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,28 +17,6 @@ import lombok.Data;
|
||||
@Data
|
||||
public class Subscription implements Serializable {
|
||||
|
||||
public static Subscription build(FeedSubscription subscription, String publicUrl, UnreadCount unreadCount) {
|
||||
Date now = new Date();
|
||||
FeedCategory category = subscription.getCategory();
|
||||
Feed feed = subscription.getFeed();
|
||||
Subscription sub = new Subscription();
|
||||
sub.setId(subscription.getId());
|
||||
sub.setName(subscription.getTitle());
|
||||
sub.setPosition(subscription.getPosition());
|
||||
sub.setMessage(feed.getMessage());
|
||||
sub.setErrorCount(feed.getErrorCount());
|
||||
sub.setFeedUrl(feed.getUrl());
|
||||
sub.setFeedLink(feed.getLink());
|
||||
sub.setIconUrl(FeedUtils.getFaviconUrl(subscription, publicUrl));
|
||||
sub.setLastRefresh(feed.getLastUpdated());
|
||||
sub.setNextRefresh((feed.getDisabledUntil() != null && feed.getDisabledUntil().before(now)) ? null : feed.getDisabledUntil());
|
||||
sub.setUnread(unreadCount.getUnreadCount());
|
||||
sub.setNewestItemTime(unreadCount.getNewestItemTime());
|
||||
sub.setCategoryId(category == null ? null : String.valueOf(category.getId()));
|
||||
sub.setFilter(subscription.getFilter());
|
||||
return sub;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "subscription id", required = true)
|
||||
private Long id;
|
||||
|
||||
@@ -84,4 +62,26 @@ public class Subscription implements Serializable {
|
||||
@ApiModelProperty(value = "JEXL string evaluated on new entries to mark them as read if they do not match")
|
||||
private String filter;
|
||||
|
||||
public static Subscription build(FeedSubscription subscription, String publicUrl, UnreadCount unreadCount) {
|
||||
Date now = new Date();
|
||||
FeedCategory category = subscription.getCategory();
|
||||
Feed feed = subscription.getFeed();
|
||||
Subscription sub = new Subscription();
|
||||
sub.setId(subscription.getId());
|
||||
sub.setName(subscription.getTitle());
|
||||
sub.setPosition(subscription.getPosition());
|
||||
sub.setMessage(feed.getMessage());
|
||||
sub.setErrorCount(feed.getErrorCount());
|
||||
sub.setFeedUrl(feed.getUrl());
|
||||
sub.setFeedLink(feed.getLink());
|
||||
sub.setIconUrl(FeedUtils.getFaviconUrl(subscription, publicUrl));
|
||||
sub.setLastRefresh(feed.getLastUpdated());
|
||||
sub.setNextRefresh((feed.getDisabledUntil() != null && feed.getDisabledUntil().before(now)) ? null : feed.getDisabledUntil());
|
||||
sub.setUnread(unreadCount.getUnreadCount());
|
||||
sub.setNewestItemTime(unreadCount.getNewestItemTime());
|
||||
sub.setCategoryId(category == null ? null : String.valueOf(category.getId()));
|
||||
sub.setFilter(subscription.getFilter());
|
||||
return sub;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -100,18 +100,6 @@ public class FeedREST {
|
||||
|
||||
private static final FeedEntry TEST_ENTRY = initTestEntry();
|
||||
|
||||
private static FeedEntry initTestEntry() {
|
||||
FeedEntry entry = new FeedEntry();
|
||||
entry.setUrl("https://github.com/Athou/commafeed");
|
||||
|
||||
FeedEntryContent content = new FeedEntryContent();
|
||||
content.setAuthor("Athou");
|
||||
content.setTitle("Merge pull request #662 from Athou/dw8");
|
||||
content.setContent("Merge pull request #662 from Athou/dw8");
|
||||
entry.setContent(content);
|
||||
return entry;
|
||||
}
|
||||
|
||||
private final FeedSubscriptionDAO feedSubscriptionDAO;
|
||||
private final FeedCategoryDAO feedCategoryDAO;
|
||||
private final FeedEntryStatusDAO feedEntryStatusDAO;
|
||||
@@ -126,6 +114,18 @@ public class FeedREST {
|
||||
private final CacheService cache;
|
||||
private final CommaFeedConfiguration config;
|
||||
|
||||
private static FeedEntry initTestEntry() {
|
||||
FeedEntry entry = new FeedEntry();
|
||||
entry.setUrl("https://github.com/Athou/commafeed");
|
||||
|
||||
FeedEntryContent content = new FeedEntryContent();
|
||||
content.setAuthor("Athou");
|
||||
content.setTitle("Merge pull request #662 from Athou/dw8");
|
||||
content.setContent("Merge pull request #662 from Athou/dw8");
|
||||
entry.setContent(content);
|
||||
return entry;
|
||||
}
|
||||
|
||||
@Path("/entries")
|
||||
@GET
|
||||
@UnitOfWork
|
||||
@@ -176,8 +176,9 @@ public class FeedREST {
|
||||
entryKeywords, newerThanDate, offset, limit + 1, order, true, onlyIds, null);
|
||||
|
||||
for (FeedEntryStatus status : list) {
|
||||
entries.getEntries().add(Entry.build(status, config.getApplicationSettings().getPublicUrl(),
|
||||
config.getApplicationSettings().getImageProxyEnabled()));
|
||||
entries.getEntries()
|
||||
.add(Entry.build(status, config.getApplicationSettings().getPublicUrl(),
|
||||
config.getApplicationSettings().getImageProxyEnabled()));
|
||||
}
|
||||
|
||||
boolean hasMore = entries.getEntries().size() > limit;
|
||||
@@ -226,7 +227,7 @@ public class FeedREST {
|
||||
feed.setTitle("CommaFeed - " + entries.getName());
|
||||
feed.setDescription("CommaFeed - " + entries.getName());
|
||||
feed.setLink(config.getApplicationSettings().getPublicUrl());
|
||||
feed.setEntries(entries.getEntries().stream().map(e -> e.asRss()).collect(Collectors.toList()));
|
||||
feed.setEntries(entries.getEntries().stream().map(Entry::asRss).collect(Collectors.toList()));
|
||||
|
||||
SyndFeedOutput output = new SyndFeedOutput();
|
||||
StringWriter writer = new StringWriter();
|
||||
@@ -270,8 +271,10 @@ public class FeedREST {
|
||||
try {
|
||||
info = fetchFeedInternal(req.getUrl());
|
||||
} catch (Exception e) {
|
||||
return Response.status(Status.INTERNAL_SERVER_ERROR).entity(Throwables.getStackTraceAsString(Throwables.getRootCause(e)))
|
||||
.type(MediaType.TEXT_PLAIN).build();
|
||||
return Response.status(Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Throwables.getStackTraceAsString(Throwables.getRootCause(e)))
|
||||
.type(MediaType.TEXT_PLAIN)
|
||||
.build();
|
||||
}
|
||||
return Response.ok(info).build();
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Path("/push")
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }) )
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
public class PubSubHubbubCallbackREST {
|
||||
|
||||
@@ -69,7 +69,7 @@ public class PubSubHubbubCallbackREST {
|
||||
|
||||
List<Feed> feeds = feedDAO.findByTopic(topic);
|
||||
|
||||
if (feeds.isEmpty() == false) {
|
||||
if (!feeds.isEmpty()) {
|
||||
for (Feed feed : feeds) {
|
||||
log.debug("activated push notifications for {}", feed.getPushTopic());
|
||||
feed.setPushLastPing(new Date());
|
||||
|
||||
@@ -21,7 +21,7 @@ import com.commafeed.frontend.session.SessionHelper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }) )
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
public class CustomCssServlet extends HttpServlet {
|
||||
|
||||
|
||||
@@ -9,10 +9,10 @@ import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import com.commafeed.CommaFeedConfiguration;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
|
||||
@@ -5,10 +5,10 @@ import java.util.Optional;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import com.commafeed.backend.model.User;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor()
|
||||
public class SessionHelper {
|
||||
|
||||
|
||||
@@ -28,8 +28,9 @@ public class SessionHelperFactoryProvider extends AbstractValueFactoryProvider {
|
||||
final Class<?> classType = parameter.getRawType();
|
||||
|
||||
Context context = parameter.getAnnotation(Context.class);
|
||||
if (context == null)
|
||||
if (context == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (classType.isAssignableFrom(SessionHelper.class)) {
|
||||
return new SessionHelperFactory();
|
||||
|
||||
@@ -9,17 +9,18 @@ import org.junit.Test;
|
||||
|
||||
public class FixedSizeSortedSetTest {
|
||||
|
||||
private FixedSizeSortedSet<String> set;
|
||||
private static Comparator<String> COMP = new Comparator<String>() {
|
||||
private static final Comparator<String> COMP = new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
return ObjectUtils.compare(o1, o2);
|
||||
}
|
||||
};
|
||||
|
||||
private FixedSizeSortedSet<String> set;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
set = new FixedSizeSortedSet<String>(3, COMP);
|
||||
set = new FixedSizeSortedSet<>(3, COMP);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -87,7 +87,7 @@ public class FeedUtilsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveTrailingSlash_lastSlashOnly() {
|
||||
public void testRemoveTrailingSlashLastSlashOnly() {
|
||||
final String url = "http://localhost//";
|
||||
final String result = FeedUtils.removeTrailingSlash(url);
|
||||
Assert.assertEquals("http://localhost/", result);
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
package com.commafeed.backend.opml;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import com.commafeed.backend.dao.FeedCategoryDAO;
|
||||
@@ -29,31 +27,31 @@ public class OPMLExporterTest {
|
||||
@Mock
|
||||
private FeedSubscriptionDAO feedSubscriptionDAO;
|
||||
|
||||
private User user = new User();
|
||||
private final User user = new User();
|
||||
|
||||
private FeedCategory cat1 = new FeedCategory();
|
||||
private FeedCategory cat2 = new FeedCategory();
|
||||
private final FeedCategory cat1 = new FeedCategory();
|
||||
private final FeedCategory cat2 = new FeedCategory();
|
||||
|
||||
private FeedSubscription rootFeed = newFeedSubscription("rootFeed", "rootFeed.com");
|
||||
private FeedSubscription cat1Feed = newFeedSubscription("cat1Feed", "cat1Feed.com");
|
||||
private FeedSubscription cat2Feed = newFeedSubscription("cat2Feed", "cat2Feed.com");
|
||||
private final FeedSubscription rootFeed = newFeedSubscription("rootFeed", "rootFeed.com");
|
||||
private final FeedSubscription cat1Feed = newFeedSubscription("cat1Feed", "cat1Feed.com");
|
||||
private final FeedSubscription cat2Feed = newFeedSubscription("cat2Feed", "cat2Feed.com");
|
||||
|
||||
private List<FeedCategory> categories = new ArrayList<>();
|
||||
private List<FeedSubscription> subscriptions = new ArrayList<>();
|
||||
private final List<FeedCategory> categories = new ArrayList<>();
|
||||
private final List<FeedSubscription> subscriptions = new ArrayList<>();
|
||||
|
||||
@Before
|
||||
public void before_each_test() {
|
||||
public void init() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
user.setName("John Doe");
|
||||
|
||||
cat1.setId(1l);
|
||||
cat1.setId(1L);
|
||||
cat1.setName("cat1");
|
||||
cat1.setParent(null);
|
||||
cat1.setChildren(new HashSet<FeedCategory>());
|
||||
cat1.setSubscriptions(new HashSet<FeedSubscription>());
|
||||
|
||||
cat2.setId(2l);
|
||||
cat2.setId(2L);
|
||||
cat2.setName("cat2");
|
||||
cat2.setParent(cat1);
|
||||
cat2.setChildren(new HashSet<FeedCategory>());
|
||||
@@ -90,51 +88,59 @@ public class OPMLExporterTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void generates_OPML_correctly() {
|
||||
when(feedCategoryDAO.findAll(user)).thenReturn(categories);
|
||||
when(feedSubscriptionDAO.findAll(user)).thenReturn(subscriptions);
|
||||
public void generatesOpmlCorrectly() {
|
||||
Mockito.when(feedCategoryDAO.findAll(user)).thenReturn(categories);
|
||||
Mockito.when(feedSubscriptionDAO.findAll(user)).thenReturn(subscriptions);
|
||||
|
||||
Opml opml = new OPMLExporter(feedCategoryDAO, feedSubscriptionDAO).export(user);
|
||||
|
||||
List<Outline> rootOutlines = opml.getOutlines();
|
||||
assertEquals(2, rootOutlines.size());
|
||||
assertTrue(containsCategory(rootOutlines, "cat1"));
|
||||
assertTrue(containsFeed(rootOutlines, "rootFeed", "rootFeed.com"));
|
||||
Assert.assertEquals(2, rootOutlines.size());
|
||||
Assert.assertTrue(containsCategory(rootOutlines, "cat1"));
|
||||
Assert.assertTrue(containsFeed(rootOutlines, "rootFeed", "rootFeed.com"));
|
||||
|
||||
Outline cat1Outline = getCategoryOutline(rootOutlines, "cat1");
|
||||
List<Outline> cat1Children = cat1Outline.getChildren();
|
||||
assertEquals(2, cat1Children.size());
|
||||
assertTrue(containsCategory(cat1Children, "cat2"));
|
||||
assertTrue(containsFeed(cat1Children, "cat1Feed", "cat1Feed.com"));
|
||||
Assert.assertEquals(2, cat1Children.size());
|
||||
Assert.assertTrue(containsCategory(cat1Children, "cat2"));
|
||||
Assert.assertTrue(containsFeed(cat1Children, "cat1Feed", "cat1Feed.com"));
|
||||
|
||||
Outline cat2Outline = getCategoryOutline(cat1Children, "cat2");
|
||||
List<Outline> cat2Children = cat2Outline.getChildren();
|
||||
assertEquals(1, cat2Children.size());
|
||||
assertTrue(containsFeed(cat2Children, "cat2Feed", "cat2Feed.com"));
|
||||
Assert.assertEquals(1, cat2Children.size());
|
||||
Assert.assertTrue(containsFeed(cat2Children, "cat2Feed", "cat2Feed.com"));
|
||||
}
|
||||
|
||||
private boolean containsCategory(List<Outline> outlines, String category) {
|
||||
for (Outline o : outlines)
|
||||
if (!"rss".equals(o.getType()))
|
||||
if (category.equals(o.getTitle()))
|
||||
for (Outline o : outlines) {
|
||||
if (!"rss".equals(o.getType())) {
|
||||
if (category.equals(o.getTitle())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean containsFeed(List<Outline> outlines, String title, String url) {
|
||||
for (Outline o : outlines)
|
||||
if ("rss".equals(o.getType()))
|
||||
if (title.equals(o.getTitle()) && o.getAttributeValue("xmlUrl").equals(url))
|
||||
for (Outline o : outlines) {
|
||||
if ("rss".equals(o.getType())) {
|
||||
if (title.equals(o.getTitle()) && o.getAttributeValue("xmlUrl").equals(url)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private Outline getCategoryOutline(List<Outline> outlines, String title) {
|
||||
for (Outline o : outlines)
|
||||
if (o.getTitle().equals(title))
|
||||
for (Outline o : outlines) {
|
||||
if (o.getTitle().equals(title)) {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
package com.commafeed.backend.service;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockserver.model.HttpRequest.request;
|
||||
import static org.mockserver.model.HttpResponse.response;
|
||||
|
||||
import org.apache.http.HttpHeaders;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
@@ -16,9 +7,12 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockserver.client.MockServerClient;
|
||||
import org.mockserver.junit.MockServerRule;
|
||||
import org.mockserver.model.HttpRequest;
|
||||
import org.mockserver.model.HttpResponse;
|
||||
import org.mockserver.model.MediaType;
|
||||
|
||||
import com.commafeed.CommaFeedConfiguration;
|
||||
@@ -28,76 +22,78 @@ import com.commafeed.backend.model.Feed;
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class PubSubServiceTest {
|
||||
|
||||
PubSubService underTest;
|
||||
private PubSubService underTest;
|
||||
|
||||
@Rule
|
||||
public MockServerRule mockServerRule = new MockServerRule(this, 22441);
|
||||
public MockServerClient mockServerClient;
|
||||
private final MockServerRule mockServerRule = new MockServerRule(this, 22441);
|
||||
|
||||
private MockServerClient mockServerClient;
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
CommaFeedConfiguration config;
|
||||
private CommaFeedConfiguration config;
|
||||
|
||||
@Mock
|
||||
FeedQueues queues;
|
||||
private FeedQueues queues;
|
||||
|
||||
@Mock
|
||||
Feed feed;
|
||||
private Feed feed;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
underTest = new PubSubService(config, queues);
|
||||
|
||||
// setup feed
|
||||
feed = mock(Feed.class);
|
||||
when(feed.getPushHub()).thenReturn("http://localhost:22441/hub");
|
||||
when(feed.getPushTopic()).thenReturn("foo");
|
||||
feed = Mockito.mock(Feed.class);
|
||||
Mockito.when(feed.getPushHub()).thenReturn("http://localhost:22441/hub");
|
||||
Mockito.when(feed.getPushTopic()).thenReturn("foo");
|
||||
|
||||
// setup config
|
||||
when(config.getApplicationSettings().getPublicUrl()).thenReturn("http://localhost:22441/hub");
|
||||
Mockito.when(config.getApplicationSettings().getPublicUrl()).thenReturn("http://localhost:22441/hub");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subscribe_200() {
|
||||
public void subscribe200() {
|
||||
// Arrange
|
||||
mockServerClient.when(request().withMethod("POST")).respond(response().withStatusCode(200));
|
||||
mockServerClient.when(HttpRequest.request().withMethod("POST")).respond(HttpResponse.response().withStatusCode(200));
|
||||
|
||||
// Act
|
||||
underTest.subscribe(feed);
|
||||
|
||||
// Assert
|
||||
mockServerClient.verify(request().withContentType(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
mockServerClient.verify(HttpRequest.request()
|
||||
.withContentType(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
.withHeader(HttpHeaders.USER_AGENT, "CommaFeed")
|
||||
.withMethod("POST")
|
||||
.withPath("/hub"));
|
||||
verify(feed, never()).setPushTopic(anyString());
|
||||
verifyZeroInteractions(queues);
|
||||
Mockito.verify(feed, Mockito.never()).setPushTopic(Mockito.anyString());
|
||||
Mockito.verifyZeroInteractions(queues);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subscribe_400_withPushpressError() {
|
||||
public void subscribe400WithPushpressError() {
|
||||
// Arrange
|
||||
mockServerClient.when(request().withMethod("POST"))
|
||||
.respond(response().withStatusCode(400).withBody(" is value is not allowed. You may only subscribe to"));
|
||||
mockServerClient.when(HttpRequest.request().withMethod("POST"))
|
||||
.respond(HttpResponse.response().withStatusCode(400).withBody(" is value is not allowed. You may only subscribe to"));
|
||||
|
||||
// Act
|
||||
underTest.subscribe(feed);
|
||||
|
||||
// Assert
|
||||
verify(feed).setPushTopic(anyString());
|
||||
verify(queues).giveBack(feed);
|
||||
Mockito.verify(feed).setPushTopic(Mockito.anyString());
|
||||
Mockito.verify(queues).giveBack(feed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subscribe_400_withoutPushpressError() {
|
||||
public void subscribe400WithoutPushpressError() {
|
||||
// Arrange
|
||||
mockServerClient.when(request().withMethod("POST")).respond(response().withStatusCode(400));
|
||||
mockServerClient.when(HttpRequest.request().withMethod("POST")).respond(HttpResponse.response().withStatusCode(400));
|
||||
|
||||
// Act
|
||||
underTest.subscribe(feed);
|
||||
|
||||
// Assert
|
||||
verify(feed, never()).setPushTopic(anyString());
|
||||
verifyZeroInteractions(queues);
|
||||
Mockito.verify(feed, Mockito.never()).setPushTopic(Mockito.anyString());
|
||||
Mockito.verifyZeroInteractions(queues);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,19 +1,12 @@
|
||||
package com.commafeed.backend.service;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import com.commafeed.CommaFeedConfiguration;
|
||||
@@ -53,7 +46,7 @@ public class UserServiceTest {
|
||||
private UserService userService;
|
||||
|
||||
@Before
|
||||
public void before_each_test() {
|
||||
public void init() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
userService = new UserService(feedCategoryDAO, feedSubscriptionDAO, userDAO, userRoleDAO, userSettingsDAO,
|
||||
@@ -69,129 +62,133 @@ public class UserServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void calling_login_should_not_return_user_object_when_given_null_nameOrEmail() {
|
||||
public void callingLoginShouldNotReturnUserObjectWhenGivenNullNameOrEmail() {
|
||||
Optional<User> user = userService.login(null, "password");
|
||||
assertFalse(user.isPresent());
|
||||
Assert.assertFalse(user.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void calling_login_should_not_return_user_object_when_given_null_password() {
|
||||
public void callingLoginShouldNotReturnUserObjectWhenGivenNullPassword() {
|
||||
Optional<User> user = userService.login("testusername", null);
|
||||
assertFalse(user.isPresent());
|
||||
Assert.assertFalse(user.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void calling_login_should_lookup_user_by_name() {
|
||||
public void callingLoginShouldLookupUserByName() {
|
||||
userService.login("test", "password");
|
||||
verify(userDAO).findByName("test");
|
||||
Mockito.verify(userDAO).findByName("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void calling_login_should_lookup_user_by_email_if_lookup_by_name_failed() {
|
||||
when(userDAO.findByName("test@test.com")).thenReturn(null);
|
||||
public void callingLoginShouldLookupUserByEmailIfLookupByNameFailed() {
|
||||
Mockito.when(userDAO.findByName("test@test.com")).thenReturn(null);
|
||||
userService.login("test@test.com", "password");
|
||||
verify(userDAO).findByEmail("test@test.com");
|
||||
Mockito.verify(userDAO).findByEmail("test@test.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void calling_login_should_not_return_user_object_if_could_not_find_user_by_name_or_email() {
|
||||
when(userDAO.findByName("test@test.com")).thenReturn(null);
|
||||
when(userDAO.findByEmail("test@test.com")).thenReturn(null);
|
||||
public void callingLoginShouldNotReturnUserObjectIfCouldNotFindUserByNameOrEmail() {
|
||||
Mockito.when(userDAO.findByName("test@test.com")).thenReturn(null);
|
||||
Mockito.when(userDAO.findByEmail("test@test.com")).thenReturn(null);
|
||||
|
||||
Optional<User> user = userService.login("test@test.com", "password");
|
||||
|
||||
assertFalse(user.isPresent());
|
||||
Assert.assertFalse(user.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void calling_login_should_not_return_user_object_if_user_is_disabled() {
|
||||
when(userDAO.findByName("test")).thenReturn(disabledUser);
|
||||
public void callingLoginShouldNotReturnUserObjectIfUserIsDisabled() {
|
||||
Mockito.when(userDAO.findByName("test")).thenReturn(disabledUser);
|
||||
Optional<User> user = userService.login("test", "password");
|
||||
assertFalse(user.isPresent());
|
||||
Assert.assertFalse(user.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void calling_login_should_try_to_authenticate_user_who_is_not_disabled() {
|
||||
when(userDAO.findByName("test")).thenReturn(normalUser);
|
||||
when(passwordEncryptionService.authenticate(anyString(), any(byte[].class), any(byte[].class))).thenReturn(false);
|
||||
public void callingLoginShouldTryToAuthenticateUserWhoIsNotDisabled() {
|
||||
Mockito.when(userDAO.findByName("test")).thenReturn(normalUser);
|
||||
Mockito.when(passwordEncryptionService.authenticate(Mockito.anyString(), Mockito.any(byte[].class), Mockito.any(byte[].class)))
|
||||
.thenReturn(false);
|
||||
|
||||
userService.login("test", "password");
|
||||
|
||||
verify(passwordEncryptionService).authenticate("password", ENCRYPTED_PASSWORD, SALT);
|
||||
Mockito.verify(passwordEncryptionService).authenticate("password", ENCRYPTED_PASSWORD, SALT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void calling_login_should_not_return_user_object_on_unsuccessful_authentication() {
|
||||
when(userDAO.findByName("test")).thenReturn(normalUser);
|
||||
when(passwordEncryptionService.authenticate(anyString(), any(byte[].class), any(byte[].class))).thenReturn(false);
|
||||
public void callingLoginShouldNotReturnUserObjectOnUnsuccessfulAuthentication() {
|
||||
Mockito.when(userDAO.findByName("test")).thenReturn(normalUser);
|
||||
Mockito.when(passwordEncryptionService.authenticate(Mockito.anyString(), Mockito.any(byte[].class), Mockito.any(byte[].class)))
|
||||
.thenReturn(false);
|
||||
|
||||
Optional<User> authenticatedUser = userService.login("test", "password");
|
||||
|
||||
assertFalse(authenticatedUser.isPresent());
|
||||
Assert.assertFalse(authenticatedUser.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void calling_login_should_execute_post_login_activities_for_user_on_successful_authentication() {
|
||||
when(userDAO.findByName("test")).thenReturn(normalUser);
|
||||
when(passwordEncryptionService.authenticate(anyString(), any(byte[].class), any(byte[].class))).thenReturn(true);
|
||||
doNothing().when(postLoginActivities).executeFor(any(User.class));
|
||||
public void callingLoginShouldExecutePostLoginActivitiesForUserOnSuccessfulAuthentication() {
|
||||
Mockito.when(userDAO.findByName("test")).thenReturn(normalUser);
|
||||
Mockito.when(passwordEncryptionService.authenticate(Mockito.anyString(), Mockito.any(byte[].class), Mockito.any(byte[].class)))
|
||||
.thenReturn(true);
|
||||
Mockito.doNothing().when(postLoginActivities).executeFor(Mockito.any(User.class));
|
||||
|
||||
userService.login("test", "password");
|
||||
|
||||
verify(postLoginActivities).executeFor(normalUser);
|
||||
Mockito.verify(postLoginActivities).executeFor(normalUser);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void calling_login_should_return_user_object_on_successful_authentication() {
|
||||
when(userDAO.findByName("test")).thenReturn(normalUser);
|
||||
when(passwordEncryptionService.authenticate(anyString(), any(byte[].class), any(byte[].class))).thenReturn(true);
|
||||
doNothing().when(postLoginActivities).executeFor(any(User.class));
|
||||
public void callingLoginShouldReturnUserObjectOnSuccessfulAuthentication() {
|
||||
Mockito.when(userDAO.findByName("test")).thenReturn(normalUser);
|
||||
Mockito.when(passwordEncryptionService.authenticate(Mockito.anyString(), Mockito.any(byte[].class), Mockito.any(byte[].class)))
|
||||
.thenReturn(true);
|
||||
Mockito.doNothing().when(postLoginActivities).executeFor(Mockito.any(User.class));
|
||||
|
||||
Optional<User> authenticatedUser = userService.login("test", "password");
|
||||
|
||||
assertTrue(authenticatedUser.isPresent());
|
||||
assertEquals(normalUser, authenticatedUser.get());
|
||||
Assert.assertTrue(authenticatedUser.isPresent());
|
||||
Assert.assertEquals(normalUser, authenticatedUser.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void api_login_should_not_return_user_if_apikey_null() {
|
||||
public void apiLoginShouldNotReturnUserIfApikeyNull() {
|
||||
Optional<User> user = userService.login(null);
|
||||
assertFalse(user.isPresent());
|
||||
Assert.assertFalse(user.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void api_login_should_lookup_user_by_apikey() {
|
||||
when(userDAO.findByApiKey("apikey")).thenReturn(null);
|
||||
public void apiLoginShouldLookupUserByApikey() {
|
||||
Mockito.when(userDAO.findByApiKey("apikey")).thenReturn(null);
|
||||
userService.login("apikey");
|
||||
verify(userDAO).findByApiKey("apikey");
|
||||
Mockito.verify(userDAO).findByApiKey("apikey");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void api_login_should_not_return_user_if_user_not_found_from_lookup_by_apikey() {
|
||||
when(userDAO.findByApiKey("apikey")).thenReturn(null);
|
||||
public void apiLoginShouldNotReturnUserIfUserNotFoundFromLookupByApikey() {
|
||||
Mockito.when(userDAO.findByApiKey("apikey")).thenReturn(null);
|
||||
Optional<User> user = userService.login("apikey");
|
||||
assertFalse(user.isPresent());
|
||||
Assert.assertFalse(user.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void api_login_should_not_return_user_if_user_found_from_apikey_lookup_is_disabled() {
|
||||
when(userDAO.findByApiKey("apikey")).thenReturn(disabledUser);
|
||||
public void apiLoginShouldNotReturnUserIfUserFoundFromApikeyLookupIsDisabled() {
|
||||
Mockito.when(userDAO.findByApiKey("apikey")).thenReturn(disabledUser);
|
||||
Optional<User> user = userService.login("apikey");
|
||||
assertFalse(user.isPresent());
|
||||
Assert.assertFalse(user.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void api_login_should_perform_post_login_activities_if_user_found_from_apikey_lookup_not_disabled() {
|
||||
when(userDAO.findByApiKey("apikey")).thenReturn(normalUser);
|
||||
public void apiLoginShouldPerformPostLoginActivitiesIfUserFoundFromApikeyLookupNotDisabled() {
|
||||
Mockito.when(userDAO.findByApiKey("apikey")).thenReturn(normalUser);
|
||||
userService.login("apikey");
|
||||
verify(postLoginActivities).executeFor(normalUser);
|
||||
Mockito.verify(postLoginActivities).executeFor(normalUser);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void api_login_should_return_user_if_user_found_from_apikey_lookup_not_disabled() {
|
||||
when(userDAO.findByApiKey("apikey")).thenReturn(normalUser);
|
||||
public void apiLoginShouldReturnUserIfUserFoundFromApikeyLookupNotDisabled() {
|
||||
Mockito.when(userDAO.findByApiKey("apikey")).thenReturn(normalUser);
|
||||
Optional<User> returnedUser = userService.login("apikey");
|
||||
assertEquals(normalUser, returnedUser.get());
|
||||
Assert.assertEquals(normalUser, returnedUser.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
package com.commafeed.frontend.auth;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import com.commafeed.backend.model.User;
|
||||
import com.commafeed.backend.service.UserService;
|
||||
@@ -16,13 +13,13 @@ import com.commafeed.frontend.session.SessionHelper;
|
||||
public class SecurityCheckFactoryTest {
|
||||
|
||||
@Test
|
||||
public void cookie_login_should_perform_post_login_activities_if_user_is_logged_in() {
|
||||
public void cookieLoginShouldPerformPostLoginActivities() {
|
||||
User userInSession = new User();
|
||||
|
||||
SessionHelper sessionHelper = mock(SessionHelper.class);
|
||||
when(sessionHelper.getLoggedInUser()).thenReturn(Optional.of(userInSession));
|
||||
SessionHelper sessionHelper = Mockito.mock(SessionHelper.class);
|
||||
Mockito.when(sessionHelper.getLoggedInUser()).thenReturn(Optional.of(userInSession));
|
||||
|
||||
PostLoginActivities postLoginActivities = mock(PostLoginActivities.class);
|
||||
PostLoginActivities postLoginActivities = Mockito.mock(PostLoginActivities.class);
|
||||
|
||||
UserService service = new UserService(null, null, null, null, null, null, null, postLoginActivities);
|
||||
|
||||
@@ -30,7 +27,7 @@ public class SecurityCheckFactoryTest {
|
||||
factory.userService = service;
|
||||
factory.cookieSessionLogin(sessionHelper);
|
||||
|
||||
verify(postLoginActivities).executeFor(userInSession);
|
||||
Mockito.verify(postLoginActivities).executeFor(userInSession);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
package com.commafeed.frontend.resource;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import com.commafeed.backend.model.User;
|
||||
import com.commafeed.backend.model.UserRole.Role;
|
||||
@@ -24,16 +18,16 @@ import com.commafeed.frontend.session.SessionHelper;
|
||||
public class UserRestTest {
|
||||
|
||||
@Test
|
||||
public void login_should_not_populate_http_session_if_unsuccessfull() {
|
||||
public void loginShouldNotPopulateHttpSessionIfUnsuccessfull() {
|
||||
// Absent user
|
||||
Optional<User> absentUser = Optional.empty();
|
||||
|
||||
// Create UserService partial mock
|
||||
UserService service = mock(UserService.class);
|
||||
when(service.login("user", "password")).thenReturn(absentUser);
|
||||
UserService service = Mockito.mock(UserService.class);
|
||||
Mockito.when(service.login("user", "password")).thenReturn(absentUser);
|
||||
|
||||
UserREST userREST = new UserREST(null, null, null, service, null, null, null);
|
||||
SessionHelper sessionHelper = mock(SessionHelper.class);
|
||||
SessionHelper sessionHelper = Mockito.mock(SessionHelper.class);
|
||||
|
||||
LoginRequest req = new LoginRequest();
|
||||
req.setName("user");
|
||||
@@ -41,43 +35,43 @@ public class UserRestTest {
|
||||
|
||||
userREST.login(req, sessionHelper);
|
||||
|
||||
verify(sessionHelper, never()).setLoggedInUser(any(User.class));
|
||||
Mockito.verify(sessionHelper, Mockito.never()).setLoggedInUser(Mockito.any(User.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void login_should_populate_http_session_if_successfull() {
|
||||
public void loginShouldPopulateHttpSessionIfSuccessfull() {
|
||||
// Create a user
|
||||
User user = new User();
|
||||
|
||||
// Create UserService mock
|
||||
UserService service = mock(UserService.class);
|
||||
when(service.login("user", "password")).thenReturn(Optional.of(user));
|
||||
UserService service = Mockito.mock(UserService.class);
|
||||
Mockito.when(service.login("user", "password")).thenReturn(Optional.of(user));
|
||||
|
||||
LoginRequest req = new LoginRequest();
|
||||
req.setName("user");
|
||||
req.setPassword("password");
|
||||
|
||||
UserREST userREST = new UserREST(null, null, null, service, null, null, null);
|
||||
SessionHelper sessionHelper = mock(SessionHelper.class);
|
||||
SessionHelper sessionHelper = Mockito.mock(SessionHelper.class);
|
||||
|
||||
userREST.login(req, sessionHelper);
|
||||
|
||||
verify(sessionHelper).setLoggedInUser(user);
|
||||
Mockito.verify(sessionHelper).setLoggedInUser(user);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void register_should_register_and_then_login() {
|
||||
public void registerShouldRegisterAndThenLogin() {
|
||||
// Create UserService mock
|
||||
UserService service = mock(UserService.class);
|
||||
UserService service = Mockito.mock(UserService.class);
|
||||
|
||||
RegistrationRequest req = new RegistrationRequest();
|
||||
req.setName("user");
|
||||
req.setPassword("password");
|
||||
req.setEmail("test@test.com");
|
||||
|
||||
InOrder inOrder = inOrder(service);
|
||||
InOrder inOrder = Mockito.inOrder(service);
|
||||
|
||||
SessionHelper sessionHelper = mock(SessionHelper.class);
|
||||
SessionHelper sessionHelper = Mockito.mock(SessionHelper.class);
|
||||
UserREST userREST = new UserREST(null, null, null, service, null, null, null);
|
||||
|
||||
userREST.registerUser(req, sessionHelper);
|
||||
@@ -87,26 +81,27 @@ public class UserRestTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void register_should_populate_http_session() {
|
||||
public void registerShouldPopulateHttpSession() {
|
||||
// Create a user
|
||||
User user = new User();
|
||||
|
||||
// Create UserService mock
|
||||
UserService service = mock(UserService.class);
|
||||
when(service.register(any(String.class), any(String.class), any(String.class), Matchers.anyListOf(Role.class))).thenReturn(user);
|
||||
when(service.login(any(String.class), any(String.class))).thenReturn(Optional.of(user));
|
||||
UserService service = Mockito.mock(UserService.class);
|
||||
Mockito.when(service.register(Mockito.any(String.class), Mockito.any(String.class), Mockito.any(String.class),
|
||||
ArgumentMatchers.anyList())).thenReturn(user);
|
||||
Mockito.when(service.login(Mockito.any(String.class), Mockito.any(String.class))).thenReturn(Optional.of(user));
|
||||
|
||||
RegistrationRequest req = new RegistrationRequest();
|
||||
req.setName("user");
|
||||
req.setPassword("password");
|
||||
req.setEmail("test@test.com");
|
||||
|
||||
SessionHelper sessionHelper = mock(SessionHelper.class);
|
||||
SessionHelper sessionHelper = Mockito.mock(SessionHelper.class);
|
||||
UserREST userREST = new UserREST(null, null, null, service, null, null, null);
|
||||
|
||||
userREST.registerUser(req, sessionHelper);
|
||||
|
||||
verify(sessionHelper).setLoggedInUser(user);
|
||||
Mockito.verify(sessionHelper).setLoggedInUser(user);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
package com.commafeed.frontend.session;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -11,27 +7,28 @@ import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import com.commafeed.backend.model.User;
|
||||
|
||||
public class SessionHelperTest {
|
||||
|
||||
private static String SESSION_KEY_USER = "user";
|
||||
private static final String SESSION_KEY_USER = "user";
|
||||
|
||||
@Test
|
||||
public void getting_user_does_not_create_a_session_if_not_present() {
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
public void gettingUserDoesNotCreateSession() {
|
||||
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
|
||||
|
||||
SessionHelper sessionHelper = new SessionHelper(request);
|
||||
sessionHelper.getLoggedInUser();
|
||||
|
||||
verify(request).getSession(false);
|
||||
Mockito.verify(request).getSession(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getting_user_should_not_return_user_if_there_is_no_preexisting_http_session() {
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
when(request.getSession(false)).thenReturn(null);
|
||||
public void gettingUserShouldNotReturnUserIfThereIsNoPreexistingHttpSession() {
|
||||
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
|
||||
Mockito.when(request.getSession(false)).thenReturn(null);
|
||||
|
||||
SessionHelper sessionHelper = new SessionHelper(request);
|
||||
Optional<User> user = sessionHelper.getLoggedInUser();
|
||||
@@ -40,12 +37,12 @@ public class SessionHelperTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getting_user_should_not_return_user_if_user_not_present_in_http_session() {
|
||||
HttpSession session = mock(HttpSession.class);
|
||||
when(session.getAttribute(SESSION_KEY_USER)).thenReturn(null);
|
||||
public void gettingUserShouldNotReturnUserIfUserNotPresentInHttpSession() {
|
||||
HttpSession session = Mockito.mock(HttpSession.class);
|
||||
Mockito.when(session.getAttribute(SESSION_KEY_USER)).thenReturn(null);
|
||||
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
when(request.getSession(false)).thenReturn(session);
|
||||
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
|
||||
Mockito.when(request.getSession(false)).thenReturn(session);
|
||||
|
||||
SessionHelper sessionHelper = new SessionHelper(request);
|
||||
Optional<User> user = sessionHelper.getLoggedInUser();
|
||||
@@ -54,14 +51,14 @@ public class SessionHelperTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getting_user_should_return_user_if_user_present_in_http_session() {
|
||||
public void gettingUserShouldReturnUserIfUserPresentInHttpSession() {
|
||||
User userInSession = new User();
|
||||
|
||||
HttpSession session = mock(HttpSession.class);
|
||||
when(session.getAttribute(SESSION_KEY_USER)).thenReturn(userInSession);
|
||||
HttpSession session = Mockito.mock(HttpSession.class);
|
||||
Mockito.when(session.getAttribute(SESSION_KEY_USER)).thenReturn(userInSession);
|
||||
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
when(request.getSession(false)).thenReturn(session);
|
||||
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
|
||||
Mockito.when(request.getSession(false)).thenReturn(session);
|
||||
|
||||
SessionHelper sessionHelper = new SessionHelper(request);
|
||||
Optional<User> user = sessionHelper.getLoggedInUser();
|
||||
|
||||
Reference in New Issue
Block a user