Formatted and cleaned up code
Fixed Java warnings
This commit is contained in:
parent
d100aca9bb
commit
372e2581ce
40 changed files with 244 additions and 168 deletions
|
@ -24,6 +24,8 @@ package org.rometools.certiorem;
|
||||||
*/
|
*/
|
||||||
public class HttpStatusCodeException extends RuntimeException {
|
public class HttpStatusCodeException extends RuntimeException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final int status;
|
private final int status;
|
||||||
|
|
||||||
public HttpStatusCodeException(final int status, final String message, final Throwable cause) {
|
public HttpStatusCodeException(final int status, final String message, final Throwable cause) {
|
||||||
|
|
|
@ -10,7 +10,8 @@ import org.rometools.fetcher.impl.FeedFetcherCache;
|
||||||
import org.rometools.fetcher.impl.SyndFeedInfo;
|
import org.rometools.fetcher.impl.SyndFeedInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper FeedFetcherCache that wraps a backing FeedFetcherCache and makes sure that any SyndFeedInfo used within it are replaced with a DeltaSyndFeedInfo
|
* Wrapper FeedFetcherCache that wraps a backing FeedFetcherCache and makes sure
|
||||||
|
* that any SyndFeedInfo used within it are replaced with a DeltaSyndFeedInfo
|
||||||
* which is capable of tracking changes to entries in the underlying feed.
|
* which is capable of tracking changes to entries in the underlying feed.
|
||||||
*
|
*
|
||||||
* @author najmi
|
* @author najmi
|
||||||
|
|
|
@ -18,18 +18,21 @@ import com.sun.syndication.feed.synd.SyndEntry;
|
||||||
import com.sun.syndication.feed.synd.SyndFeed;
|
import com.sun.syndication.feed.synd.SyndFeed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extends SyndFeedInfo to also track etags for individual entries. This may be used with DeltaFeedInfoCache to only return feed with a subset of entries that
|
* Extends SyndFeedInfo to also track etags for individual entries. This may be
|
||||||
* have changed since last fetch.
|
* used with DeltaFeedInfoCache to only return feed with a subset of entries
|
||||||
|
* that have changed since last fetch.
|
||||||
*
|
*
|
||||||
* @author najmi
|
* @author najmi
|
||||||
*/
|
*/
|
||||||
public class DeltaSyndFeedInfo extends SyndFeedInfo {
|
public class DeltaSyndFeedInfo extends SyndFeedInfo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
Map<String, String> entryTagsMap = new HashMap<String, String>();
|
Map<String, String> entryTagsMap = new HashMap<String, String>();
|
||||||
Map<String, Boolean> changedMap = new HashMap<String, Boolean>();
|
Map<String, Boolean> changedMap = new HashMap<String, Boolean>();
|
||||||
|
|
||||||
private DeltaSyndFeedInfo() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public DeltaSyndFeedInfo(final SyndFeedInfo backingFeedInfo) {
|
public DeltaSyndFeedInfo(final SyndFeedInfo backingFeedInfo) {
|
||||||
setETag(backingFeedInfo.getETag());
|
setETag(backingFeedInfo.getETag());
|
||||||
setId(backingFeedInfo.getId());
|
setId(backingFeedInfo.getId());
|
||||||
|
@ -38,7 +41,8 @@ public class DeltaSyndFeedInfo extends SyndFeedInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a filtered version of the SyndFeed that only has entries that were changed in the last setSyndFeed() call.
|
* Gets a filtered version of the SyndFeed that only has entries that were
|
||||||
|
* changed in the last setSyndFeed() call.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@ -65,7 +69,8 @@ public class DeltaSyndFeedInfo extends SyndFeedInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides super class method to update changedMap and entryTagsMap for tracking changed entries.
|
* Overrides super class method to update changedMap and entryTagsMap for
|
||||||
|
* tracking changed entries.
|
||||||
*
|
*
|
||||||
* @param feed
|
* @param feed
|
||||||
*/
|
*/
|
||||||
|
@ -89,9 +94,12 @@ public class DeltaSyndFeedInfo extends SyndFeedInfo {
|
||||||
|
|
||||||
private String computeEntryTag(final SyndEntry entry) {
|
private String computeEntryTag(final SyndEntry entry) {
|
||||||
|
|
||||||
// Following hash algorithm suggested by Robert Cooper needs to be evaluated in future.
|
// Following hash algorithm suggested by Robert Cooper needs to be
|
||||||
// int hash = ( entry.getUri() != null ? entry.getUri().hashCode() : entry.getLink().hashCode() ) ^
|
// evaluated in future.
|
||||||
// (entry.getUpdatedDate() != null ? entry.getUpdatedDate().hashCode() : entry.getPublishedDate().hashCode()) ^
|
// int hash = ( entry.getUri() != null ? entry.getUri().hashCode() :
|
||||||
|
// entry.getLink().hashCode() ) ^
|
||||||
|
// (entry.getUpdatedDate() != null ? entry.getUpdatedDate().hashCode() :
|
||||||
|
// entry.getPublishedDate().hashCode()) ^
|
||||||
// entry.getTitle().hashCode() ^
|
// entry.getTitle().hashCode() ^
|
||||||
// entry.getDescription().hashCode();
|
// entry.getDescription().hashCode();
|
||||||
|
|
||||||
|
@ -102,7 +110,9 @@ public class DeltaSyndFeedInfo extends SyndFeedInfo {
|
||||||
if (publishedDate != null) {
|
if (publishedDate != null) {
|
||||||
updateDate = publishedDate;
|
updateDate = publishedDate;
|
||||||
} else {
|
} else {
|
||||||
// For misbehaving feeds that do not set updateDate or publishedDate we use current tiem which pretty mucg assures that it will be viewed as
|
// For misbehaving feeds that do not set updateDate or
|
||||||
|
// publishedDate we use current tiem which pretty mucg assures
|
||||||
|
// that it will be viewed as
|
||||||
// changed even when it is not
|
// changed even when it is not
|
||||||
updateDate = new Date();
|
updateDate = new Date();
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,8 @@ import org.rometools.fetcher.FeedFetcher;
|
||||||
import com.sun.syndication.feed.synd.SyndFeed;
|
import com.sun.syndication.feed.synd.SyndFeed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The basic business logic controller for the Hub implementation. It is intended to be usable under a very thin servlet wrapper, or other, non-HTTP
|
* The basic business logic controller for the Hub implementation. It is
|
||||||
|
* intended to be usable under a very thin servlet wrapper, or other, non-HTTP
|
||||||
* notification methods you might want to use.
|
* notification methods you might want to use.
|
||||||
*
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
|
@ -72,8 +73,8 @@ public class Hub {
|
||||||
this.notifier = notifier;
|
this.notifier = notifier;
|
||||||
this.fetcher = fetcher;
|
this.fetcher = fetcher;
|
||||||
validSchemes = STANDARD_SCHEMES;
|
validSchemes = STANDARD_SCHEMES;
|
||||||
validPorts = Collections.EMPTY_SET;
|
validPorts = Collections.emptySet();
|
||||||
validTopics = Collections.EMPTY_SET;
|
validTopics = Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,9 +82,12 @@ public class Hub {
|
||||||
*
|
*
|
||||||
* @param dao The persistence HubDAO to use
|
* @param dao The persistence HubDAO to use
|
||||||
* @param verifier The verification strategy to use
|
* @param verifier The verification strategy to use
|
||||||
* @param validSchemes A list of valid URI schemes for callbacks (default: http, https)
|
* @param validSchemes A list of valid URI schemes for callbacks (default:
|
||||||
* @param validPorts A list of valid port numbers for callbacks (default: any)
|
* http, https)
|
||||||
* @param validTopics A set of valid topic URIs which can be subscribed to (default: any)
|
* @param validPorts A list of valid port numbers for callbacks (default:
|
||||||
|
* any)
|
||||||
|
* @param validTopics A set of valid topic URIs which can be subscribed to
|
||||||
|
* (default: any)
|
||||||
*/
|
*/
|
||||||
public Hub(final HubDAO dao, final Verifier verifier, final Notifier notifier, final FeedFetcher fetcher, final Set<String> validSchemes,
|
public Hub(final HubDAO dao, final Verifier verifier, final Notifier notifier, final FeedFetcher fetcher, final Set<String> validSchemes,
|
||||||
final Set<Integer> validPorts, final Set<String> validTopics) {
|
final Set<Integer> validPorts, final Set<String> validTopics) {
|
||||||
|
@ -96,18 +100,29 @@ public class Hub {
|
||||||
this.validSchemes = readOnlySchemes == null ? STANDARD_SCHEMES : readOnlySchemes;
|
this.validSchemes = readOnlySchemes == null ? STANDARD_SCHEMES : readOnlySchemes;
|
||||||
|
|
||||||
final Set<Integer> readOnlyPorts = Collections.unmodifiableSet(validPorts);
|
final Set<Integer> readOnlyPorts = Collections.unmodifiableSet(validPorts);
|
||||||
this.validPorts = readOnlyPorts == null ? Collections.EMPTY_SET : readOnlyPorts;
|
if (readOnlyPorts == null) {
|
||||||
|
this.validPorts = Collections.emptySet();
|
||||||
|
} else {
|
||||||
|
this.validPorts = readOnlyPorts;
|
||||||
|
}
|
||||||
|
|
||||||
final Set<String> readOnlyTopics = Collections.unmodifiableSet(validTopics);
|
final Set<String> readOnlyTopics = Collections.unmodifiableSet(validTopics);
|
||||||
this.validTopics = readOnlyTopics == null ? Collections.EMPTY_SET : readOnlyTopics;
|
if (validTopics == null) {
|
||||||
|
this.validTopics = Collections.emptySet();
|
||||||
|
} else {
|
||||||
|
this.validTopics = readOnlyTopics;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a notification to the subscribers
|
* Sends a notification to the subscribers
|
||||||
*
|
*
|
||||||
* @param requestHost the host name the hub is running on. (Used for the user agent)
|
* @param requestHost the host name the hub is running on. (Used for the
|
||||||
|
* user agent)
|
||||||
* @param topic the URL of the topic that was updated.
|
* @param topic the URL of the topic that was updated.
|
||||||
* @throws HttpStatusCodeException a wrapper exception with a recommended status code for the request.
|
* @throws HttpStatusCodeException a wrapper exception with a recommended
|
||||||
|
* status code for the request.
|
||||||
*/
|
*/
|
||||||
public void sendNotification(final String requestHost, final String topic) {
|
public void sendNotification(final String requestHost, final String topic) {
|
||||||
assert validTopics.isEmpty() || validTopics.contains(topic) : "That topic is not supported by this hub. " + topic;
|
assert validTopics.isEmpty() || validTopics.contains(topic) : "That topic is not supported by this hub. " + topic;
|
||||||
|
@ -120,7 +135,7 @@ public class Hub {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<SubscriptionSummary> summaries = (List<SubscriptionSummary>) dao.summariesForTopic(topic);
|
final List<? extends SubscriptionSummary> summaries = dao.summariesForTopic(topic);
|
||||||
int total = 0;
|
int total = 0;
|
||||||
final StringBuilder hosts = new StringBuilder();
|
final StringBuilder hosts = new StringBuilder();
|
||||||
|
|
||||||
|
@ -135,7 +150,7 @@ public class Hub {
|
||||||
.append(" subscribers)").append(hosts);
|
.append(" subscribers)").append(hosts);
|
||||||
final SyndFeed feed = fetcher.retrieveFeed(userAgent.toString(), new URL(topic));
|
final SyndFeed feed = fetcher.retrieveFeed(userAgent.toString(), new URL(topic));
|
||||||
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "Got feed for {0} Sending to {1} subscribers.", new Object[] { topic, subscribers.size() });
|
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "Got feed for {0} Sending to {1} subscribers.", new Object[] { topic, subscribers.size() });
|
||||||
notifier.notifySubscribers((List<Subscriber>) subscribers, feed, new SubscriptionSummaryCallback() {
|
notifier.notifySubscribers(subscribers, feed, new SubscriptionSummaryCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onSummaryInfo(final SubscriptionSummary summary) {
|
public void onSummaryInfo(final SubscriptionSummary summary) {
|
||||||
dao.handleSummary(topic, summary);
|
dao.handleSummary(topic, summary);
|
||||||
|
@ -156,9 +171,11 @@ public class Hub {
|
||||||
* @param lease_seconds Duration of the lease
|
* @param lease_seconds Duration of the lease
|
||||||
* @param secret Secret value
|
* @param secret Secret value
|
||||||
* @param verify_token verify_token;
|
* @param verify_token verify_token;
|
||||||
* @return Boolean.TRUE if the subscription succeeded synchronously, Boolean.FALSE if the subscription failed synchronously, or null if the request is
|
* @return Boolean.TRUE if the subscription succeeded synchronously,
|
||||||
* asynchronous.
|
* Boolean.FALSE if the subscription failed synchronously, or null
|
||||||
* @throws HttpStatusCodeException a wrapper exception with a recommended status code for the request.
|
* if the request is asynchronous.
|
||||||
|
* @throws HttpStatusCodeException a wrapper exception with a recommended
|
||||||
|
* status code for the request.
|
||||||
*/
|
*/
|
||||||
public Boolean subscribe(final String callback, final String topic, final String verify, final long lease_seconds, final String secret,
|
public Boolean subscribe(final String callback, final String topic, final String verify, final long lease_seconds, final String secret,
|
||||||
final String verify_token) {
|
final String verify_token) {
|
||||||
|
|
|
@ -31,13 +31,15 @@ import com.sun.syndication.feed.synd.SyndFeed;
|
||||||
*/
|
*/
|
||||||
public interface Notifier {
|
public interface Notifier {
|
||||||
/**
|
/**
|
||||||
* Instructs the notifier to begin sending notifications to the list of subscribers
|
* Instructs the notifier to begin sending notifications to the list of
|
||||||
|
* subscribers
|
||||||
*
|
*
|
||||||
* @param subscribers Subscribers to notify
|
* @param subscribers Subscribers to notify
|
||||||
* @param value The SyndFeed to send them
|
* @param value The SyndFeed to send them
|
||||||
* @param callback A callback that is invoked each time a subscriber is notified.
|
* @param callback A callback that is invoked each time a subscriber is
|
||||||
|
* notified.
|
||||||
*/
|
*/
|
||||||
public void notifySubscribers(List<Subscriber> subscribers, SyndFeed value, SubscriptionSummaryCallback callback);
|
public void notifySubscribers(List<? extends Subscriber> subscribers, SyndFeed value, SubscriptionSummaryCallback callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A callback that is invoked each time a subscriber is notified.
|
* A callback that is invoked each time a subscriber is notified.
|
||||||
|
|
|
@ -69,7 +69,8 @@ public interface Verifier {
|
||||||
public boolean verifyUnsubcribeSyncronously(Subscriber subscriber);
|
public boolean verifyUnsubcribeSyncronously(Subscriber subscriber);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface for capturing the result of a verification (subscribe or unsubscribe)
|
* An interface for capturing the result of a verification (subscribe or
|
||||||
|
* unsubscribe)
|
||||||
*/
|
*/
|
||||||
public static interface VerificationCallback {
|
public static interface VerificationCallback {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -25,6 +25,10 @@ import java.io.Serializable;
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
public class Subscriber implements Serializable {
|
public class Subscriber implements Serializable {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
public static final String VERIFY_SYNC = "sync";
|
public static final String VERIFY_SYNC = "sync";
|
||||||
public static final String VERIFY_ASYNC = "async";
|
public static final String VERIFY_ASYNC = "async";
|
||||||
private String callback;
|
private String callback;
|
||||||
|
|
|
@ -25,6 +25,10 @@ import java.io.Serializable;
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
public class SubscriptionSummary implements Serializable {
|
public class SubscriptionSummary implements Serializable {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
private String host;
|
private String host;
|
||||||
private boolean lastPublishSuccessful = true;
|
private boolean lastPublishSuccessful = true;
|
||||||
private int subscribers = 0;
|
private int subscribers = 0;
|
||||||
|
|
|
@ -57,7 +57,9 @@ public class JPADAO implements HubDAO {
|
||||||
query.setParameter("topic", topic);
|
query.setParameter("topic", topic);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (final JPASubscriber subscriber : (List<JPASubscriber>) query.getResultList()) {
|
@SuppressWarnings("unchecked")
|
||||||
|
final List<JPASubscriber> subscribers = query.getResultList();
|
||||||
|
for (final JPASubscriber subscriber : subscribers) {
|
||||||
if (subscriber.getLeaseSeconds() == -1) {
|
if (subscriber.getLeaseSeconds() == -1) {
|
||||||
result.add(subscriber);
|
result.add(subscriber);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -37,6 +37,10 @@ import org.rometools.certiorem.hub.data.Subscriber;
|
||||||
@Entity
|
@Entity
|
||||||
@NamedQueries({ @NamedQuery(name = "Subcriber.forTopic", query = "SELECT o FROM JPASubscriber o WHERE o.topic = :topic AND o.expired = false ORDER BY o.subscribedAt") })
|
@NamedQueries({ @NamedQuery(name = "Subcriber.forTopic", query = "SELECT o FROM JPASubscriber o WHERE o.topic = :topic AND o.expired = false ORDER BY o.subscribedAt") })
|
||||||
public class JPASubscriber extends Subscriber implements Serializable {
|
public class JPASubscriber extends Subscriber implements Serializable {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
private Date subscribedAt = new Date();
|
private Date subscribedAt = new Date();
|
||||||
private String id;
|
private String id;
|
||||||
private boolean expired = false;
|
private boolean expired = false;
|
||||||
|
|
|
@ -89,7 +89,7 @@ public class InMemoryHubDAO implements HubDAO {
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
return Collections.EMPTY_LIST;
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,17 +43,19 @@ import com.sun.syndication.io.SyndFeedOutput;
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractNotifier implements Notifier {
|
public abstract class AbstractNotifier implements Notifier {
|
||||||
/**
|
/**
|
||||||
* This method will serialize the synd feed and build Notifications for the implementation class to handle.
|
* This method will serialize the synd feed and build Notifications for the
|
||||||
|
* implementation class to handle.
|
||||||
*
|
*
|
||||||
* @see enqueueNotification
|
* @see enqueueNotification
|
||||||
*
|
*
|
||||||
* @param subscribers List of subscribers to notify
|
* @param subscribers List of subscribers to notify
|
||||||
* @param value The SyndFeed object to send
|
* @param value The SyndFeed object to send
|
||||||
* @param callback A callback that will be invoked each time a subscriber is notified.
|
* @param callback A callback that will be invoked each time a subscriber is
|
||||||
|
* notified.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void notifySubscribers(final List<Subscriber> subscribers, final SyndFeed value, final SubscriptionSummaryCallback callback) {
|
public void notifySubscribers(final List<? extends Subscriber> subscribers, final SyndFeed value, final SubscriptionSummaryCallback callback) {
|
||||||
String mimeType = null;
|
String mimeType = null;
|
||||||
|
|
||||||
if (value.getFeedType().startsWith("rss")) {
|
if (value.getFeedType().startsWith("rss")) {
|
||||||
|
@ -98,8 +100,9 @@ public abstract class AbstractNotifier implements Notifier {
|
||||||
protected abstract void enqueueNotification(Notification not);
|
protected abstract void enqueueNotification(Notification not);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* POSTs the payload to the subscriber's callback and returns a SubscriptionSummary with subscriber counts (where possible) and the success state of the
|
* POSTs the payload to the subscriber's callback and returns a
|
||||||
* notification.
|
* SubscriptionSummary with subscriber counts (where possible) and the
|
||||||
|
* success state of the notification.
|
||||||
*
|
*
|
||||||
* @param subscriber subscriber data.
|
* @param subscriber subscriber data.
|
||||||
* @param mimeType MIME type for the request
|
* @param mimeType MIME type for the request
|
||||||
|
|
|
@ -28,7 +28,8 @@ import java.util.concurrent.TimeUnit;
|
||||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A notifier implementation that uses a thread pool to deliver notifications to subscribers
|
* A notifier implementation that uses a thread pool to deliver notifications to
|
||||||
|
* subscribers
|
||||||
*
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
|
@ -51,8 +52,9 @@ public class ThreadPoolNotifier extends AbstractNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enqueues a notification to run. If the notification fails, it will be retried every two minutes until 5 attempts are completed. Notifications to the same
|
* Enqueues a notification to run. If the notification fails, it will be
|
||||||
* callback should be delivered successfully in order.
|
* retried every two minutes until 5 attempts are completed. Notifications
|
||||||
|
* to the same callback should be delivered successfully in order.
|
||||||
*
|
*
|
||||||
* @param not
|
* @param not
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
|
|
||||||
package org.rometools.certiorem.hub.notify.standard;
|
package org.rometools.certiorem.hub.notify.standard;
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentSkipListSet;
|
|
||||||
|
|
||||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,20 +26,19 @@ import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
public class UnthreadedNotifier extends AbstractNotifier {
|
public class UnthreadedNotifier extends AbstractNotifier {
|
||||||
private final ConcurrentSkipListSet<Notification> retries = new ConcurrentSkipListSet<Notification>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A blocking call that performs a notification. If there are pending retries that are older than two minutes old, they will be retried before the method
|
* A blocking call that performs a notification. If there are pending
|
||||||
* returns.
|
* retries that are older than two minutes old, they will be retried before
|
||||||
|
* the method returns.
|
||||||
*
|
*
|
||||||
* @param not
|
* @param not
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void enqueueNotification(final Notification not) {
|
protected void enqueueNotification(final Notification not) {
|
||||||
not.lastRun = System.currentTimeMillis();
|
not.lastRun = System.currentTimeMillis();
|
||||||
|
|
||||||
final SubscriptionSummary summary = postNotification(not.subscriber, not.mimeType, not.payload);
|
final SubscriptionSummary summary = postNotification(not.subscriber, not.mimeType, not.payload);
|
||||||
|
|
||||||
not.callback.onSummaryInfo(summary);
|
not.callback.onSummaryInfo(summary);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,8 @@ import org.rometools.certiorem.hub.Verifier;
|
||||||
import org.rometools.certiorem.hub.data.Subscriber;
|
import org.rometools.certiorem.hub.data.Subscriber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstract verifier based on the java.net HTTP classes. This implements only synchronous operations, and expects a child class to do Async ops.
|
* An abstract verifier based on the java.net HTTP classes. This implements only
|
||||||
|
* synchronous operations, and expects a child class to do Async ops.
|
||||||
*
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
|
@ -68,7 +69,8 @@ public abstract class AbstractVerifier implements Verifier {
|
||||||
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||||
connection.setDoInput(true);
|
connection.setDoInput(true);
|
||||||
// connection.setRequestProperty("Host", url.getHost());
|
// connection.setRequestProperty("Host", url.getHost());
|
||||||
// connection.setRequestProperty("Port", Integer.toString(url.getPort()));
|
// connection.setRequestProperty("Port",
|
||||||
|
// Integer.toString(url.getPort()));
|
||||||
connection.setRequestProperty("User-Agent", "ROME-Certiorem");
|
connection.setRequestProperty("User-Agent", "ROME-Certiorem");
|
||||||
connection.connect();
|
connection.connect();
|
||||||
final int rc = connection.getResponseCode();
|
final int rc = connection.getResponseCode();
|
||||||
|
|
|
@ -24,6 +24,11 @@ package org.rometools.certiorem.pub;
|
||||||
*/
|
*/
|
||||||
public class NotificationException extends Exception {
|
public class NotificationException extends Exception {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public NotificationException(final String message) {
|
public NotificationException(final String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,13 +40,15 @@ public class Publisher {
|
||||||
private ThreadPoolExecutor executor;
|
private ThreadPoolExecutor executor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new publisher. This publisher will spawn a new thread for each async send.
|
* Constructs a new publisher. This publisher will spawn a new thread for
|
||||||
|
* each async send.
|
||||||
*/
|
*/
|
||||||
public Publisher() {
|
public Publisher() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new publisher with an optional ThreadPoolExector for sending updates.
|
* Constructs a new publisher with an optional ThreadPoolExector for sending
|
||||||
|
* updates.
|
||||||
*/
|
*/
|
||||||
public Publisher(final ThreadPoolExecutor executor) {
|
public Publisher(final ThreadPoolExecutor executor) {
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
|
@ -91,7 +93,8 @@ public class Publisher {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a notification for a feed located at "topic". The feed MUST contain rel="hub".
|
* Sends a notification for a feed located at "topic". The feed MUST contain
|
||||||
|
* rel="hub".
|
||||||
*
|
*
|
||||||
* @param topic URL for the feed
|
* @param topic URL for the feed
|
||||||
* @param feed The feed itself
|
* @param feed The feed itself
|
||||||
|
@ -109,7 +112,8 @@ public class Publisher {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a notification for a feed. The feed MUST contain rel="hub" and rel="self" links.
|
* Sends a notification for a feed. The feed MUST contain rel="hub" and
|
||||||
|
* rel="self" links.
|
||||||
*
|
*
|
||||||
* @param feed The feed to notify
|
* @param feed The feed to notify
|
||||||
* @throws NotificationException Any failure
|
* @throws NotificationException Any failure
|
||||||
|
@ -172,7 +176,8 @@ public class Publisher {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asynchronously sends a notification for a feed located at "topic". The feed MUST contain rel="hub".
|
* Asynchronously sends a notification for a feed located at "topic". The
|
||||||
|
* feed MUST contain rel="hub".
|
||||||
*
|
*
|
||||||
* @param topic URL for the feed
|
* @param topic URL for the feed
|
||||||
* @param feed The feed itself
|
* @param feed The feed itself
|
||||||
|
@ -200,7 +205,8 @@ public class Publisher {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asyncronously sends a notification for a feed. The feed MUST contain rel="hub" and rel="self" links.
|
* Asyncronously sends a notification for a feed. The feed MUST contain
|
||||||
|
* rel="hub" and rel="self" links.
|
||||||
*
|
*
|
||||||
* @param feed The feed to notify
|
* @param feed The feed to notify
|
||||||
* @param callback A callback invoked when the notification completes.
|
* @param callback A callback invoked when the notification completes.
|
||||||
|
|
|
@ -25,6 +25,10 @@ import java.io.Serializable;
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
public class Subscription implements Serializable {
|
public class Subscription implements Serializable {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
private String id;
|
private String id;
|
||||||
private String sourceUrl;
|
private String sourceUrl;
|
||||||
private String verifyToken;
|
private String verifyToken;
|
||||||
|
|
|
@ -34,6 +34,10 @@ import org.rometools.certiorem.hub.Hub;
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractHubServlet extends HttpServlet {
|
public abstract class AbstractHubServlet extends HttpServlet {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
public static final String HUBMODE = "hub.mode";
|
public static final String HUBMODE = "hub.mode";
|
||||||
private final Hub hub;
|
private final Hub hub;
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,10 @@ import org.rometools.certiorem.sub.Subscriptions;
|
||||||
*/
|
*/
|
||||||
public class AbstractSubServlet extends HttpServlet {
|
public class AbstractSubServlet extends HttpServlet {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
private final Subscriptions subscriptions;
|
private final Subscriptions subscriptions;
|
||||||
|
|
||||||
protected AbstractSubServlet(final Subscriptions subscriptions) {
|
protected AbstractSubServlet(final Subscriptions subscriptions) {
|
||||||
|
|
|
@ -44,7 +44,8 @@ public class DeltaSyndFeedInfoTest {
|
||||||
List<SyndEntry> entries = feed.getEntries();
|
List<SyndEntry> entries = feed.getEntries();
|
||||||
assertTrue(!entries.isEmpty());
|
assertTrue(!entries.isEmpty());
|
||||||
|
|
||||||
// Fetch again and this time the entries should be empty as none have changed.
|
// Fetch again and this time the entries should be empty as none have
|
||||||
|
// changed.
|
||||||
feed = feedFetcher.retrieveFeed(getFeedUrl());
|
feed = feedFetcher.retrieveFeed(getFeedUrl());
|
||||||
entries = feed.getEntries();
|
entries = feed.getEntries();
|
||||||
assertTrue(entries.isEmpty());
|
assertTrue(entries.isEmpty());
|
||||||
|
@ -52,7 +53,8 @@ public class DeltaSyndFeedInfoTest {
|
||||||
|
|
||||||
private URL getFeedUrl() throws IOException {
|
private URL getFeedUrl() throws IOException {
|
||||||
final URL feedUrl = new URL("http://news.google.com/news?pz=1&cf=all&ned=us&hl=en&output=rss");
|
final URL feedUrl = new URL("http://news.google.com/news?pz=1&cf=all&ned=us&hl=en&output=rss");
|
||||||
// URL feedUrl = new URL("http://newsrss.bbc.co.uk/rss/newsonline_world_edition/front_page/rss.xml");
|
// URL feedUrl = new
|
||||||
|
// URL("http://newsrss.bbc.co.uk/rss/newsonline_world_edition/front_page/rss.xml");
|
||||||
return feedUrl;
|
return feedUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ public abstract class AbstractDAOTest {
|
||||||
|
|
||||||
assert result.equals(subscriber) : "Subscriber not equal.";
|
assert result.equals(subscriber) : "Subscriber not equal.";
|
||||||
|
|
||||||
final List<Subscriber> subscribers = (List<Subscriber>) instance.subscribersForTopic(subscriber.getTopic());
|
final List<? extends Subscriber> subscribers = instance.subscribersForTopic(subscriber.getTopic());
|
||||||
|
|
||||||
assert subscribers.contains(result) : "Subscriber not in result.";
|
assert subscribers.contains(result) : "Subscriber not in result.";
|
||||||
}
|
}
|
||||||
|
@ -65,11 +65,11 @@ public abstract class AbstractDAOTest {
|
||||||
|
|
||||||
assert subscriber.equals(result) : "Subscriber not equal.";
|
assert subscriber.equals(result) : "Subscriber not equal.";
|
||||||
// quick test for store.
|
// quick test for store.
|
||||||
List<Subscriber> subscribers = (List<Subscriber>) instance.subscribersForTopic(subscriber.getTopic());
|
List<? extends Subscriber> subscribers = instance.subscribersForTopic(subscriber.getTopic());
|
||||||
assert subscribers.contains(result) : "Subscriber not in result.";
|
assert subscribers.contains(result) : "Subscriber not in result.";
|
||||||
// sleep past expiration
|
// sleep past expiration
|
||||||
Thread.sleep(1100);
|
Thread.sleep(1100);
|
||||||
subscribers = (List<Subscriber>) instance.subscribersForTopic(subscriber.getTopic());
|
subscribers = instance.subscribersForTopic(subscriber.getTopic());
|
||||||
assert !subscribers.contains(result) : "Subscriber should have expired";
|
assert !subscribers.contains(result) : "Subscriber should have expired";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,8 +83,8 @@ public abstract class AbstractDAOTest {
|
||||||
subscriber.setLeaseSeconds(1);
|
subscriber.setLeaseSeconds(1);
|
||||||
subscriber.setVerify("VerifyMe");
|
subscriber.setVerify("VerifyMe");
|
||||||
|
|
||||||
final Subscriber result = instance.addSubscriber(subscriber);
|
|
||||||
// TODO
|
// TODO
|
||||||
|
// final Subscriber result = instance.addSubscriber(subscriber);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue