dflorey 2004/08/09 04:51:53
Modified: src/share/org/apache/slide/cluster
ClusterCacheRefresher.java
Log:
Removed threading as notificationListener now supports connection timeout
Revision Changes Path
1.2 +198 -216
jakarta-slide/src/share/org/apache/slide/cluster/ClusterCacheRefresher.java
Index: ClusterCacheRefresher.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/src/share/org/apache/slide/cluster/ClusterCacheRefresher.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ClusterCacheRefresher.java 9 Aug 2004 05:03:09 -0000 1.1
+++ ClusterCacheRefresher.java 9 Aug 2004 11:51:53 -0000 1.2
@@ -23,13 +23,11 @@
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
-import org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory;
import org.apache.commons.httpclient.protocol.Protocol;
-import org.apache.commons.httpclient.protocol.SSLProtocolSocketFactory;
import org.apache.slide.authenticate.CredentialsToken;
+import org.apache.slide.authenticate.SecurityToken;
import org.apache.slide.common.Domain;
import org.apache.slide.common.NamespaceAccessToken;
-import org.apache.slide.common.SlideToken;
import org.apache.slide.common.SlideTokenImpl;
import org.apache.slide.common.Uri;
import org.apache.slide.store.ExtendedStore;
@@ -40,7 +38,6 @@
import org.apache.slide.util.logger.Logger;
import org.apache.webdav.lib.NotificationListener;
import org.apache.webdav.lib.Subscriber;
-import org.apache.webdav.lib.methods.DepthSupport;
/**
* <h3>Description</h3>
@@ -54,225 +51,210 @@
* <p>
* Add the following to your Domain.xml inside the <events> node.
* </p>
+ *
* <pre>
- * <listener classname="org.apache.slide.cluster.ClusterCacheRefresher">
- * <configuration>
- * <node local-host="local.host.domain"
- * local-port="4444"
- * repository-host="remote.host.domain"
- * repository-port="8080"
- * repository-protocol="http"
- * username="root"
- * password="root"
- * />
- * </configuration>
- * </listener>
- * </pre>
+ *
+ *
+ * <listener
classname="org.apache.slide.cluster.ClusterCacheRefresher">
+ * <configuration>
+ * <node local-host="local.host.domain"
+ * local-port="4444"
+ * repository-host="remote.host.domain"
+ * repository-port="8080"
+ * repository-protocol="http"
+ * username="root"
+ * password="root"
+ * />
+ * </configuration>
+ * </listener>
+ *
+ *
+ * </pre>
+ *
* <p>
* There should be one <node> element for each node in the cluster,
- * <b>except</b> for the current node. ClusterCacheRefresher should not be
+ * <b>except </b> for the current node. ClusterCacheRefresher should not be
* configured to listen to itself except for testing purposes.
* </p>
* <h3><node> attributes</h3>
* <table>
- * <tr>
- * <th>Attribute Name</th>
- * <th>Required?</th>
- * <th>Default Value</th>
- * <th>Description</th>
- * </tr>
- * <tr>
- * <td>local-host</td>
- * <td>yes</td>
- * <td>none</td>
- * <td>A network-accessible name or ip-address where the remote Slide
instance can reach <b>this server.</b></td>
- * </tr>
- * <tr>
- * <td>local-port</td>
- * <td>yes</td>
- * <td>none</td>
- * <td>A port number ClusterCacheRefresher can use to listen for
notifications. <b>Must be unique.</b></td>
- * </tr>
- * <tr>
- * <td>repository-host</td>
- * <td>yes</td>
- * <td>none</td>
- * <td>A network-accessible name or ip-address of the remote Slide
instance to monitor.</td>
- * </tr>
- * <tr>
- * <td>repository-port</td>
- * <td>yes</td>
- * <td>none</td>
- * <td>The port the remote Slide instance is running on.</td>
- * </tr>
- * <tr>
- * <td>repository-protocol</td>
- * <td>no</td>
- * <td>http</td>
- * <td>The protocol the remote Slide instance is using. Must be one of
"http" or "https".</td>
- * </tr>
- * <tr>
- * <td>username</td>
- * <td>no</td>
- * <td>none</td>
- * <td>The username to use to connect to the remote Slide instance.</td>
- * </tr>
- * <tr>
- * <td>password</td>
- * <td>no</td>
- * <td>none</td>
- * <td>The password that goes with the username.</td>
- * </tr>
- * <tr>
- * <td>repository-domain</td>
- * <td>no</td>
- * <td>/slide</td>
- * <td>The context path of the remote Slide instance.</td>
- * </tr>
- * <tr>
- * <td>poll-interval</td>
- * <td>no</td>
- * <td>60000</td>
- * <td>The number of milliseconds to wait between polling the remote
Slide instance for any changes. Polling for changes is a backup only, so this value
can be set fairly high.</td>
- * </tr>
- * <tr>
- * <td>udp</td>
- * <td>no</td>
- * <td>true</td>
- * <td>Must be "true" or "false". Indicates whether to use udp or tcp to
listen for notifications.</td>
- * </tr>
- * <tr>
- * <td>base-uri</td>
- * <td>no</td>
- * <td>/</td>
- * <td>The base path to monitor for changes. Will be appended to the
repository-domain.</td>
- * </tr>
- * <tr>
- * <td>subscription-lifetime</td>
- * <td>no</td>
- * <td>3600</td>
- * <td>The number of seconds a subscription should last. Subscriptions
are automatically refreshed. Do not set this value too high.</td>
- * </tr>
- * <tr>
- * <td>notification-delay</td>
- * <td>no</td>
- * <td>0</td>
- * <td>Number of seconds the remote Slide instance should wait before
sending a notification of a change.</td>
- * </tr>
+ * <tr>
+ * <th>Attribute Name</th>
+ * <th>Required?</th>
+ * <th>Default Value</th>
+ * <th>Description</th>
+ * </tr>
+ * <tr>
+ * <td>local-host</td>
+ * <td>yes</td>
+ * <td>none</td>
+ * <td>A network-accessible name or ip-address where the remote Slide instance
+ * can reach <b>this server. </b></td>
+ * </tr>
+ * <tr>
+ * <td>local-port</td>
+ * <td>yes</td>
+ * <td>none</td>
+ * <td>A port number ClusterCacheRefresher can use to listen for notifications.
+ * <b>Must be unique. </b></td>
+ * </tr>
+ * <tr>
+ * <td>repository-host</td>
+ * <td>yes</td>
+ * <td>none</td>
+ * <td>A network-accessible name or ip-address of the remote Slide instance to
+ * monitor.</td>
+ * </tr>
+ * <tr>
+ * <td>repository-port</td>
+ * <td>yes</td>
+ * <td>none</td>
+ * <td>The port the remote Slide instance is running on.</td>
+ * </tr>
+ * <tr>
+ * <td>repository-protocol</td>
+ * <td>no</td>
+ * <td>http</td>
+ * <td>The protocol the remote Slide instance is using. Must be one of "http"
+ * or "https".</td>
+ * </tr>
+ * <tr>
+ * <td>username</td>
+ * <td>no</td>
+ * <td>none</td>
+ * <td>The username to use to connect to the remote Slide instance.</td>
+ * </tr>
+ * <tr>
+ * <td>password</td>
+ * <td>no</td>
+ * <td>none</td>
+ * <td>The password that goes with the username.</td>
+ * </tr>
+ * <tr>
+ * <td>repository-domain</td>
+ * <td>no</td>
+ * <td>/slide</td>
+ * <td>The context path of the remote Slide instance.</td>
+ * </tr>
+ * <tr>
+ * <td>poll-interval</td>
+ * <td>no</td>
+ * <td>60000</td>
+ * <td>The number of milliseconds to wait between polling the remote Slide
+ * instance for any changes. Polling for changes is a backup only, so this value
+ * can be set fairly high.</td>
+ * </tr>
+ * <tr>
+ * <td>udp</td>
+ * <td>no</td>
+ * <td>true</td>
+ * <td>Must be "true" or "false". Indicates whether to use udp or tcp to listen
+ * for notifications.</td>
+ * </tr>
+ * <tr>
+ * <td>base-uri</td>
+ * <td>no</td>
+ * <td>/</td>
+ * <td>The base path to monitor for changes. Will be appended to the
+ * repository-domain.</td>
+ * </tr>
+ * <tr>
+ * <td>subscription-lifetime</td>
+ * <td>no</td>
+ * <td>3600</td>
+ * <td>The number of seconds a subscription should last. Subscriptions are
+ * automatically refreshed. Do not set this value too high.</td>
+ * </tr>
+ * <tr>
+ * <td>notification-delay</td>
+ * <td>no</td>
+ * <td>0</td>
+ * <td>Number of seconds the remote Slide instance should wait before sending a
+ * notification of a change.</td>
+ * </tr>
* </table>
*/
-public class ClusterCacheRefresher implements Subscriber, EventListener,
Configurable {
- protected static final String LOG_CHANNEL =
ClusterCacheRefresher.class.getName();
-
- protected NotificationListener listener;
-
- public ClusterCacheRefresher() {
- Domain.log("Creating ClusterCacheRefresher", LOG_CHANNEL, Logger.INFO);
- }
-
- public void notify(String uri, Map information) {
- // FIXME: need a better way to get the right namespace
- NamespaceAccessToken nat = Domain.accessNamespace( new
org.apache.slide.authenticate.SecurityToken(this), "slide" );
- Iterator keys = information.keySet().iterator();
- while ( keys.hasNext() ) {
- String key = keys.next().toString();
- if ( "uri".equals( key ) ) {
- Uri theUri = nat.getUri( new SlideTokenImpl(new
CredentialsToken("")),information.get(key).toString());
- Store store = theUri.getStore();
- if ( store instanceof ExtendedStore ) {
- Domain.log( "Resetting cache for " + theUri,
LOG_CHANNEL, Logger.INFO );
-
((ExtendedStore)store).removeObjectFromCache(theUri);
- }
- store = theUri.getParentUri().getStore();
- if ( store instanceof ExtendedStore ) {
- Domain.log( "Resetting cache for " +
theUri.getParentUri(), LOG_CHANNEL, Logger.INFO );
-
((ExtendedStore)store).removeObjectFromCache(theUri.getParentUri());
- }
- }
- }
- }
-
- public void configure(Configuration configuration) throws
ConfigurationException {
-
- Domain.log("Configuring ClusterCacheRefresher", LOG_CHANNEL,
Logger.INFO);
-
- Enumeration nodes = configuration.getConfigurations("node");
- while ( nodes.hasMoreElements() ) {
- Configuration node = (Configuration)nodes.nextElement();
-
- final String host = node.getAttribute("local-host");
- final int port = node.getAttributeAsInt("local-port");
- final String repositoryHost =
node.getAttribute("repository-host");
- final int repositoryPort =
node.getAttributeAsInt("repository-port");
- String repositoryProtocolString =
node.getAttribute("repository-protocol", "http");
- final Protocol protocol;
- if ( "http".equals(repositoryProtocolString) ) {
- protocol = new Protocol( "http", new
DefaultProtocolSocketFactory(), 80 );
- } else if ( "https".equals(repositoryProtocolString) ) {
- protocol = new Protocol( "https", new
SSLProtocolSocketFactory(), 443 );
- } else {
- throw new ConfigurationException("Unknown
repository-protocol: " + repositoryProtocolString + ". Must be \"http\" or
\"https\".", configuration);
- }
- String username = node.getAttribute("username", "");
- String password = node.getAttribute("password", "");
- final Credentials credentials = new
UsernamePasswordCredentials( username, password );
- final String repositoryDomain =
node.getAttribute("repository-domain", "/slide");
- final int pollInterval =
node.getAttributeAsInt("poll-interval", 60000);
- final boolean udp = node.getAttributeAsBoolean("udp", true);
- final String uri = node.getAttribute("base-uri", "/");
-// int depth = DepthSupport.DEPTH_INFINITY;
- final int depth = 1;
- final int lifetime =
node.getAttributeAsInt("subscription-lifetime", 3600);
- final int notificationDelay =
node.getAttributeAsInt("notification-delay", 0);
- final Subscriber subscriber = this;
-
-// System.out.println( "\n## Creating NotificationListener" );
-
- listener = new NotificationListener( host, port,
repositoryHost, repositoryPort, protocol, credentials, repositoryDomain, pollInterval,
udp);
-
-// System.out.println( "listener created" );
-
- Thread t = new Thread( new Runnable() {
-
- private boolean first = true;
-
- public void run() {
-
- try {
- if ( first ) {
- // Delay on startup to let
server finish starting.
- // FIXME: This should not be
necessary when NotificationListener stops freezing
- first = false;
- Thread.sleep(3000);
- Domain.log( "Registering
cluster subscriptions", LOG_CHANNEL, Logger.INFO );
- } else {
- Thread.sleep(lifetime*1000-60);
- }
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
-// System.out.println( "creating update
subscriber");
-
-
listener.subscribe("Update",uri,depth,lifetime,notificationDelay,subscriber,credentials);
-
-// System.out.println( "creating update/newmember
subscriber" );
-
-
listener.subscribe("Update/newmember",uri,depth,lifetime,notificationDelay,subscriber,credentials);
-
-// System.out.println("creating delete
subscriber");
-
-
listener.subscribe("Delete",uri,depth,lifetime,notificationDelay,subscriber,credentials);
-
-// System.out.println( "creating move subscriber"
);
-
-
listener.subscribe("Move",uri,depth,lifetime,notificationDelay,subscriber,credentials);
- }
- });
- t.setDaemon(true);
- t.start();
- }
- }
+public class ClusterCacheRefresher implements EventListener, Configurable {
+ protected static final String LOG_CHANNEL =
ClusterCacheRefresher.class.getName();
-}
+ protected NotificationListener listener;
+
+ public ClusterCacheRefresher() {
+ Domain.log("Creating ClusterCacheRefresher", LOG_CHANNEL, Logger.INFO);
+ }
+
+ public void configure(Configuration configuration) throws
ConfigurationException {
+ Domain.log("Configuring ClusterCacheRefresher", LOG_CHANNEL, Logger.INFO);
+
+ Enumeration nodes = configuration.getConfigurations("node");
+ while (nodes.hasMoreElements()) {
+ Configuration node = (Configuration) nodes.nextElement();
+ final String host = node.getAttribute("local-host");
+ final int port = node.getAttributeAsInt("local-port");
+ final String repositoryHost = node.getAttribute("repository-host");
+ final int repositoryPort = node.getAttributeAsInt("repository-port");
+ String repositoryProtocolString =
node.getAttribute("repository-protocol", "http");
+ final Protocol protocol;
+ try {
+ protocol = Protocol.getProtocol(repositoryProtocolString);
+ } catch (IllegalStateException exception) {
+ throw new ConfigurationException("Unknown repository-protocol: " +
repositoryProtocolString
+ + ". Must be \"http\" or \"https\".", configuration);
+ }
+ String username = node.getAttribute("username", "");
+ String password = node.getAttribute("password", "");
+ final Credentials credentials = new
UsernamePasswordCredentials(username, password);
+ final String repositoryDomain = node.getAttribute("repository-domain",
"/slide");
+ final int pollInterval = node.getAttributeAsInt("poll-interval", 60000);
+ final boolean udp = node.getAttributeAsBoolean("udp", true);
+ final String uri = node.getAttribute("base-uri", "/");
+ final int depth = Integer.MAX_VALUE;
+ final int lifetime = node.getAttributeAsInt("subscription-lifetime",
3600);
+ final int notificationDelay =
node.getAttributeAsInt("notification-delay", 0);
+
+ final Subscriber contentSubscriber = new Subscriber() {
+ public void notify(String uri, Map information) {
+ NamespaceAccessToken nat = Domain.accessNamespace(new
SecurityToken(this), Domain.getDefaultNamespace());
+ Iterator keys = information.keySet().iterator();
+ while (keys.hasNext()) {
+ String key = keys.next().toString();
+ if ("uri".equals(key)) {
+ Uri theUri = nat.getUri(new SlideTokenImpl(new
CredentialsToken("")), information.get(key).toString());
+ Store store = theUri.getStore();
+ if (store instanceof ExtendedStore) {
+ Domain.log("Resetting cache for " + theUri,
LOG_CHANNEL, Logger.INFO);
+ ((ExtendedStore)
store).removeObjectFromCache(theUri);
+ }
+ }
+ }
+ }
+ };
+
+ final Subscriber structureSubscriber = new Subscriber() {
+ public void notify(String uri, Map information) {
+ NamespaceAccessToken nat = Domain.accessNamespace(new
SecurityToken(this), Domain.getDefaultNamespace());
+ Iterator keys = information.keySet().iterator();
+ while (keys.hasNext()) {
+ String key = keys.next().toString();
+ if ("uri".equals(key)) {
+ Uri theUri = nat.getUri(new SlideTokenImpl(new
CredentialsToken("")), information.get(key).toString());
+ Store store = theUri.getParentUri().getStore();
+ if (store instanceof ExtendedStore) {
+ Domain.log("Resetting cache for " +
theUri.getParentUri(), LOG_CHANNEL, Logger.INFO);
+ ((ExtendedStore)
store).removeObjectFromCache(theUri.getParentUri());
+ }
+ }
+ }
+ }
+ };
+
+ listener = new NotificationListener(host, port, repositoryHost,
repositoryPort, protocol, credentials,
+ repositoryDomain, pollInterval, udp);
+
+ listener.subscribe("Update", uri, depth, lifetime, notificationDelay,
contentSubscriber, credentials);
+ listener.subscribe("Update/newmember", uri, depth, lifetime,
notificationDelay, structureSubscriber, credentials);
+ listener.subscribe("Delete", uri, depth, lifetime, notificationDelay,
structureSubscriber, credentials);
+ listener.subscribe("Move", uri, depth, lifetime, notificationDelay,
structureSubscriber, credentials);
+ }
+ }
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]