Index: icepush/core/src/main/java/org/icepush/servlet/AddNotifyBackURI.java =================================================================== --- icepush/core/src/main/java/org/icepush/servlet/AddNotifyBackURI.java (revision 0) +++ icepush/core/src/main/java/org/icepush/servlet/AddNotifyBackURI.java (working copy) @@ -0,0 +1,46 @@ +package org.icepush.servlet; + +import java.net.URI; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.icepush.Browser; +import org.icepush.PushContext; + +public class AddNotifyBackURI +extends AbstractPseudoServlet +implements PseudoServlet { + private static final Logger LOGGER = Logger.getLogger(AddNotifyBackURI.class.getName()); + + private final PushContext pushContext; + + public AddNotifyBackURI(final PushContext pushContext) { + this.pushContext = pushContext; + } + + public void service(final HttpServletRequest request, final HttpServletResponse response) + throws Exception { + String _browserID = Browser.getBrowserID(request); + URI _notifyBackURI = new URI(request.getParameter("notifyBackURI")); + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log( + Level.FINE, + "Adding Notify-Back-URI '" + _notifyBackURI + "' to Browser '" + _browserID + "'." + ); + } + addNotifyBackURI(_browserID, _notifyBackURI); + response.setContentType("text/plain"); + response.setContentLength(0); + } + + protected void addNotifyBackURI(final String browserID, final URI notifyBackURI) { + getPushContext().addNotifyBackURI(browserID, notifyBackURI); + } + + protected final PushContext getPushContext() { + return pushContext; + } +} Index: icepush/core/src/main/java/org/icepush/servlet/HasNotifyBackURI.java =================================================================== --- icepush/core/src/main/java/org/icepush/servlet/HasNotifyBackURI.java (revision 0) +++ icepush/core/src/main/java/org/icepush/servlet/HasNotifyBackURI.java (working copy) @@ -0,0 +1,47 @@ +package org.icepush.servlet; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.icepush.Browser; +import org.icepush.PushContext; + +public class HasNotifyBackURI +extends AbstractPseudoServlet +implements PseudoServlet { + private static final Logger LOGGER = Logger.getLogger(HasNotifyBackURI.class.getName()); + + private final PushContext pushContext; + + public HasNotifyBackURI(final PushContext pushContext) { + this.pushContext = pushContext; + } + + public void service(final HttpServletRequest request, final HttpServletResponse response) + throws Exception { + String _browserID = Browser.getBrowserID(request); + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log( + Level.FINE, + "Removing Notify-Back-URI from Browser '" + _browserID + "'." + ); + } + if (hasNotifyBackURI(_browserID)) { + response.setContentType("text/plain"); + response.setContentLength(0); + } else { + response.sendError(404); // Not Found + } + } + + protected final PushContext getPushContext() { + return pushContext; + } + + protected boolean hasNotifyBackURI(final String browserID) { + return getPushContext().hasNotifyBackURI(browserID); + } +} Index: icepush/core/src/main/java/org/icepush/servlet/RemoveNotifyBackURI.java =================================================================== --- icepush/core/src/main/java/org/icepush/servlet/RemoveNotifyBackURI.java (revision 0) +++ icepush/core/src/main/java/org/icepush/servlet/RemoveNotifyBackURI.java (working copy) @@ -0,0 +1,44 @@ +package org.icepush.servlet; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.icepush.Browser; +import org.icepush.PushContext; + +public class RemoveNotifyBackURI +extends AbstractPseudoServlet +implements PseudoServlet { + private static final Logger LOGGER = Logger.getLogger(RemoveNotifyBackURI.class.getName()); + + private final PushContext pushContext; + + public RemoveNotifyBackURI(final PushContext pushContext) { + this.pushContext = pushContext; + } + + public void service(final HttpServletRequest request, final HttpServletResponse response) + throws Exception { + String _browserID = Browser.getBrowserID(request); + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log( + Level.FINE, + "Removing Notify-Back-URI from Browser '" + _browserID + "'." + ); + } + removeNotifyBackURI(_browserID); + response.setContentType("text/plain"); + response.setContentLength(0); + } + + protected final PushContext getPushContext() { + return pushContext; + } + + protected void removeNotifyBackURI(final String browserID) { + getPushContext().removeNotifyBackURI(browserID); + } +} Index: icepush/core/src/main/java/org/icepush/servlet/BrowserBoundServlet.java =================================================================== --- icepush/core/src/main/java/org/icepush/servlet/BrowserBoundServlet.java (revision 48585) +++ icepush/core/src/main/java/org/icepush/servlet/BrowserBoundServlet.java (working copy) @@ -16,6 +16,7 @@ package org.icepush.servlet; import java.util.Timer; +import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletContext; @@ -36,13 +37,13 @@ implements PseudoServlet { private final static Logger LOGGER = Logger.getLogger(BrowserBoundServlet.class.getName()); - protected final String browserID; - protected final Configuration configuration; - protected final Slot heartbeatInterval; - protected final Timer monitoringScheduler; - protected final PushContext pushContext; - protected final ServletContext servletContext; - protected final boolean terminateBlockingConnectionOnShutdown; + private final String browserID; + private final Configuration configuration; + private final Slot heartbeatInterval; + private final Timer monitoringScheduler; + private final PushContext pushContext; + private final ServletContext servletContext; + private final boolean terminateBlockingConnectionOnShutdown; protected boolean setUp = false; @@ -59,7 +60,8 @@ this.terminateBlockingConnectionOnShutdown = terminateBlockingConnectionOnShutdown; this.heartbeatInterval = new Slot( - configuration.getAttributeAsLong("heartbeatTimeout", ConfigurationServer.DefaultHeartbeatTimeout)); + configuration.getAttributeAsLong("heartbeatTimeout", ConfigurationServer.DefaultHeartbeatTimeout) + ); } @Override @@ -74,6 +76,9 @@ dispatchOn(".*create-push-id\\.icepush", newCreatePushID()); dispatchOn(".*add-group-member\\.icepush", newAddGroupMember()); dispatchOn(".*remove-group-member\\.icepush", newRemoveGroupMember()); + dispatchOn(".*add-notify-back-uri\\.icepush", newAddNotifyBackURI()); + dispatchOn(".*has-notify-back-uri\\.icepush", newHasNotifyBackURI()); + dispatchOn(".*remove-notify-back-uri\\.icepush", newRemoveNotifyBackURI()); setUp = true; } @@ -95,41 +100,88 @@ Slot sequenceNo = new Slot(0L); return new ConfigurationServer( - heartbeatInterval, - servletContext, - configuration, + getHeartbeatInterval(), + getServletContext(), + getConfiguration(), new PushStormDetectionServer( new SequenceTaggingServer( sequenceNo, newBlockingConnectionServer() ), - configuration + getConfiguration() ) ); } + protected final String getBrowserID() { + return browserID; + } + + protected final Configuration getConfiguration() { + return configuration; + } + + protected final Slot getHeartbeatInterval() { + return heartbeatInterval; + } + + protected final Timer getMonitoringScheduler() { + return monitoringScheduler; + } + + protected final PushContext getPushContext() { + return pushContext; + } + + protected final ServletContext getServletContext() { + return servletContext; + } + + protected final boolean getTerminateBlockingConnectionOnShutdown() { + return terminateBlockingConnectionOnShutdown; + } + protected PseudoServlet newAddGroupMember() { - return new AddGroupMember(pushContext); + return new AddGroupMember(getPushContext()); } + protected PseudoServlet newAddNotifyBackURI() { + return new AddNotifyBackURI(getPushContext()); + } + protected BlockingConnectionServer newBlockingConnectionServer() { BlockingConnectionServer _blockBlockingConnectionServer = new BlockingConnectionServer( - browserID, monitoringScheduler, heartbeatInterval, terminateBlockingConnectionOnShutdown, configuration + getBrowserID(), + getMonitoringScheduler(), + getHeartbeatInterval(), + getTerminateBlockingConnectionOnShutdown(), + getConfiguration() ); _blockBlockingConnectionServer.setUp(); return _blockBlockingConnectionServer; } protected PseudoServlet newCreatePushID() { - return new CreatePushID(pushContext); + return new CreatePushID(getPushContext()); } + protected PseudoServlet newHasNotifyBackURI() { + return new HasNotifyBackURI(getPushContext()); + } + protected PseudoServlet newListen() { - return new EnvironmentAdaptingServlet(createBlockingConnectionServer(), heartbeatInterval, configuration); + return + new EnvironmentAdaptingServlet( + createBlockingConnectionServer(), getHeartbeatInterval(), getConfiguration() + ); } protected PseudoServlet newRemoveGroupMember() { - return new RemoveGroupMember(pushContext); + return new RemoveGroupMember(getPushContext()); } + + protected PseudoServlet newRemoveNotifyBackURI() { + return new RemoveNotifyBackURI(getPushContext()); + } } Index: icepush/core/src/main/java/org/icepush/Browser.java =================================================================== --- icepush/core/src/main/java/org/icepush/Browser.java (revision 48585) +++ icepush/core/src/main/java/org/icepush/Browser.java (working copy) @@ -16,6 +16,8 @@ package org.icepush; +import static org.icesoft.util.StringUtilities.isNotNullAndIsNotEmpty; + import java.io.Serializable; import java.util.Collection; import java.util.Collections; @@ -221,6 +223,10 @@ } } + public boolean hasNotifyBackURI() { + return isNotNullAndIsNotEmpty(getNotifyBackURI()); + } + public boolean isCloudPushEnabled() { InternalPushGroupManager _internalPushGroupManager = getInternalPushGroupManager(); for (final String _pushIDString : pushIDSet) { Index: icepush/core/src/main/java/org/icepush/PushContext.java =================================================================== --- icepush/core/src/main/java/org/icepush/PushContext.java (revision 48586) +++ icepush/core/src/main/java/org/icepush/PushContext.java (working copy) @@ -19,6 +19,7 @@ import static org.icesoft.util.PreCondition.checkArgument; import static org.icesoft.util.StringUtilities.isNotNullAndIsNotEmpty; +import java.net.URI; import java.util.logging.Level; import java.util.logging.Logger; @@ -56,14 +57,13 @@ public void addGroupMember(final String groupName, final String pushID) { checkArgument( isNotNullAndIsNotEmpty(groupName), - "Illegal argument groupName: '" + groupName + "'. Argument groupName cannot be null or empty." + "Illegal argument groupName: '" + groupName + "'. Argument cannot be null or empty." ); checkArgument( isNotNullAndIsNotEmpty(pushID), - "Illegal argument pushID: '" + pushID + "'. Argument pushID cannot be null or empty." + "Illegal argument pushID: '" + pushID + "'. Argument cannot be null or empty." ); - ((PushGroupManager)PushInternalContext.getInstance().getAttribute(PushGroupManager.class.getName())). - addMember(groupName, pushID); + getPushGroupManager().addMember(groupName, pushID); } /** @@ -84,16 +84,27 @@ public void addGroupMember(final String groupName, final String pushID, final PushConfiguration pushConfiguration) { checkArgument( isNotNullAndIsNotEmpty(groupName), - "Illegal argument groupName: '" + groupName + "'. Argument groupName cannot be null or empty." + "Illegal argument groupName: '" + groupName + "'. Argument cannot be null or empty." ); checkArgument( isNotNullAndIsNotEmpty(pushID), - "Illegal argument pushID: '" + pushID + "'. Argument pushID cannot be null or empty." + "Illegal argument pushID: '" + pushID + "'. Argument cannot be null or empty." ); - ((PushGroupManager)PushInternalContext.getInstance().getAttribute(PushGroupManager.class.getName())). - addMember(groupName, pushID, pushConfiguration); + getPushGroupManager().addMember(groupName, pushID, pushConfiguration); } + public void addNotifyBackURI(final String browserID, final URI notifyBackURI) { + checkArgument( + isNotNullAndIsNotEmpty(browserID), + "Illegal argument browserID: '" + browserID + "'. Argument cannot be null or empty." + ); + checkArgument( + isNotNull(notifyBackURI), + "Illegal argument notifyBackURI: '" + notifyBackURI + "'. Argument cannot be null." + ); + getPushGroupManager().addNotifyBackURI(browserID, notifyBackURI); + } + /** *
* Instructs the specified browser to back off from ajax push listen for the specified number of milliseconds. @@ -110,14 +121,13 @@ public void backOff(final String browserID, final long delay) { checkArgument( isNotNullAndIsNotEmpty(browserID), - "Illegal argument browserID: '" + browserID + "'. Argument browserID cannot be null or empty." + "Illegal argument browserID: '" + browserID + "'. Argument cannot be null or empty." ); checkArgument( delay >= 0, - "Illegal argument delay: " + delay + ". Argument delay cannot be less than 0." + "Illegal argument delay: " + delay + ". Argument cannot be less than 0." ); - ((PushGroupManager)PushInternalContext.getInstance().getAttribute(PushGroupManager.class.getName())). - backOff(browserID, delay); + getPushGroupManager().backOff(browserID, delay); } /** @@ -138,12 +148,12 @@ public synchronized String createPushId(final HttpServletRequest request, final HttpServletResponse response) { checkArgument( - request != null, - "Illegal argument request: '" + request + "'. Argument request cannot be null." + isNotNull(request), + "Illegal argument request: '" + request + "'. Argument cannot be null." ); checkArgument( - response != null, - "Illegal argument response: '" + response + "'. Argument response cannot be null." + isNotNull(response), + "Illegal argument response: '" + response + "'. Argument cannot be null." ); String browserID = Browser.getBrowserID(request); if (browserID == null) { @@ -158,7 +168,6 @@ browserID = currentBrowserID; } } - String id = browserID + ":" + generateSubID(); if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.finest("Created new pushId '" + id + "'."); @@ -166,6 +175,14 @@ return id; } + public boolean hasNotifyBackURI(final String browserID) { + checkArgument( + isNotNullAndIsNotEmpty(browserID), + "Illegal argument browserID: '" + browserID + "'. Argument cannot be null or empty." + ); + return getPushGroupManager().hasNotifyBackURI(browserID); + } + /** *
* Initiate a Server Push to the members of the group specified by the groupName
.
@@ -180,10 +197,9 @@
public void push(final String groupName) {
checkArgument(
isNotNullAndIsNotEmpty(groupName),
- "Illegal argument groupName: '" + groupName + "'. Argument groupName cannot be null or empty."
+ "Illegal argument groupName: '" + groupName + "'. Argument cannot be null or empty."
);
- ((PushGroupManager)PushInternalContext.getInstance().getAttribute(PushGroupManager.class.getName())).
- push(groupName);
+ getPushGroupManager().push(groupName);
}
/**
@@ -203,10 +219,9 @@
public void push(final String groupName, final String payload) {
checkArgument(
isNotNullAndIsNotEmpty(groupName),
- "Illegal argument groupName: '" + groupName + "'. Argument groupName cannot be null or empty."
+ "Illegal argument groupName: '" + groupName + "'. Argument cannot be null or empty."
);
- ((PushGroupManager)PushInternalContext.getInstance().getAttribute(PushGroupManager.class.getName())).
- push(groupName, payload);
+ getPushGroupManager().push(groupName, payload);
}
/**
@@ -227,7 +242,7 @@
public void push(final String groupName, final PushConfiguration pushConfiguration) {
checkArgument(
isNotNullAndIsNotEmpty(groupName),
- "Illegal argument groupName: '" + groupName + "'. Argument groupName cannot be null or empty."
+ "Illegal argument groupName: '" + groupName + "'. Argument cannot be null or empty."
);
checkArgument(
isNull(pushConfiguration) ||
@@ -236,8 +251,7 @@
"Illegal argument pushConfiguration: '" + pushConfiguration + "'. " +
"Argument must contain attribute 'targetURI' when it contains attribute 'subject'."
);
- ((PushGroupManager)PushInternalContext.getInstance().getAttribute(PushGroupManager.class.getName())).
- push(groupName, pushConfiguration);
+ getPushGroupManager().push(groupName, pushConfiguration);
}
/**
@@ -261,7 +275,7 @@
public void push(final String groupName, final String payload, final PushConfiguration pushConfiguration) {
checkArgument(
isNotNullAndIsNotEmpty(groupName),
- "Illegal argument groupName: '" + groupName + "'. Argument groupName cannot be null or empty."
+ "Illegal argument groupName: '" + groupName + "'. Argument cannot be null or empty."
);
checkArgument(
isNull(pushConfiguration) ||
@@ -270,8 +284,7 @@
"Illegal argument pushConfiguration: '" + pushConfiguration + "'. " +
"Argument must contain attribute 'targetURI' when it contains attribute 'subject'."
);
- ((PushGroupManager)PushInternalContext.getInstance().getAttribute(PushGroupManager.class.getName())).
- push(groupName, payload, pushConfiguration);
+ getPushGroupManager().push(groupName, payload, pushConfiguration);
}
/**
@@ -290,16 +303,23 @@
public void removeGroupMember(final String groupName, final String pushID) {
checkArgument(
isNotNullAndIsNotEmpty(groupName),
- "Illegal argument groupName: '" + groupName + "'. Argument groupName cannot be null or empty."
+ "Illegal argument groupName: '" + groupName + "'. Argument cannot be null or empty."
);
checkArgument(
isNotNullAndIsNotEmpty(pushID),
- "Illegal argument pushID: '" + pushID + "'. Argument pushID cannot be null or empty."
+ "Illegal argument pushID: '" + pushID + "'. Argument cannot be null or empty."
);
- ((PushGroupManager)PushInternalContext.getInstance().getAttribute(PushGroupManager.class.getName())).
- removeMember(groupName, pushID);
+ getPushGroupManager().removeMember(groupName, pushID);
}
+ public void removeNotifyBackURI(final String browserID) {
+ checkArgument(
+ isNotNullAndIsNotEmpty(browserID),
+ "Illegal argument browserID: '" + browserID + "'. Argument cannot be null or empty."
+ );
+ getPushGroupManager().removeNotifyBackURI(browserID);
+ }
+
/**
*
* Gets the PushContext instance associated with the specified servletContext
.
@@ -314,7 +334,7 @@
public static synchronized PushContext getInstance(final ServletContext servletContext) {
checkArgument(
servletContext != null,
- "Illegal argument servletContext: '" + servletContext + "'. Argument servletContext cannot be null."
+ "Illegal argument servletContext: '" + servletContext + "'. Argument cannot be null."
);
PushContext pushContext = (PushContext)servletContext.getAttribute(PushContext.class.getName());
if (pushContext == null) {
@@ -323,6 +343,10 @@
return pushContext;
}
+ protected PushGroupManager getPushGroupManager() {
+ return (PushGroupManager)PushInternalContext.getInstance().getAttribute(PushGroupManager.class.getName());
+ }
+
private synchronized String generateSubID() {
return Integer.toString((++subCounter) + (hashCode() / 10000), 36);
}
Index: icepush/core/src/main/java/org/icepush/LocalPushGroupManager.java
===================================================================
--- icepush/core/src/main/java/org/icepush/LocalPushGroupManager.java (revision 48585)
+++ icepush/core/src/main/java/org/icepush/LocalPushGroupManager.java (working copy)
@@ -17,6 +17,7 @@
import static org.icesoft.util.StringUtilities.isNotNullAndIsNotEmpty;
+import java.net.URI;
import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.Collection;
@@ -226,6 +227,10 @@
return addNotifyBackURI(getModifiableNotifyBackURIMap(), notifyBackURI);
}
+ public boolean addNotifyBackURI(final String browserID, final URI notifyBackURI) {
+ return addNotifyBackURI(getModifiableBrowserMap(), getModifiableNotifyBackURIMap(), browserID, notifyBackURI);
+ }
+
public void backOff(final String browserID, final long delay) {
BlockingConnectionServer server = blockingConnectionServerMap.get(browserID);
if (server != null) {
@@ -369,6 +374,10 @@
return Collections.unmodifiableMap(getModifiablePushIDMap());
}
+ public boolean hasNotifyBackURI(final String browserID) {
+ return hasNotifyBackURI(getBrowserMap(), browserID);
+ }
+
public boolean isParked(final String pushID) {
return parkedPushIDs.containsKey(pushID);
}
@@ -451,6 +460,10 @@
outboundNotifier.removeReceiver(observer);
}
+ public boolean removeNotifyBackURI(final String browserID) {
+ return removeNotifyBackURI(getModifiableBrowserMap(), getModifiableNotifyBackURIMap(), browserID);
+ }
+
public void removePendingNotification(final String pushID) {
getPendingNotifiedPushIDSetLock().lock();
try {
@@ -708,6 +721,25 @@
return _modified;
}
+ protected boolean addNotifyBackURI(
+ final ConcurrentMap