You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by df...@apache.org on 2004/08/09 13:51:53 UTC

cvs commit: jakarta-slide/src/share/org/apache/slide/cluster ClusterCacheRefresher.java

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 &lt;events&gt; node.
    * </p>
  + * 
    * <pre>
  - *	&lt;listener classname="org.apache.slide.cluster.ClusterCacheRefresher"&gt;
  - *		&lt;configuration&gt;
  - *			&lt;node local-host="local.host.domain"
  - *			      local-port="4444"
  - *				  repository-host="remote.host.domain"
  - *				  repository-port="8080"
  - *				  repository-protocol="http"
  - *				  username="root"
  - *				  password="root"
  - *			/&gt;
  - *		&lt;/configuration&gt;
  - *	&lt;/listener&gt;
  - *  </pre>
  + * 
  + *  
  + *  	&lt;listener classname=&quot;org.apache.slide.cluster.ClusterCacheRefresher&quot;&gt;
  + *  		&lt;configuration&gt;
  + *  			&lt;node local-host=&quot;local.host.domain&quot;
  + *  			      local-port=&quot;4444&quot;
  + *  				  repository-host=&quot;remote.host.domain&quot;
  + *  				  repository-port=&quot;8080&quot;
  + *  				  repository-protocol=&quot;http&quot;
  + *  				  username=&quot;root&quot;
  + *  				  password=&quot;root&quot;
  + *  			/&gt;
  + *  		&lt;/configuration&gt;
  + *  	&lt;/listener&gt;
  + *    
  + *  
  + * </pre>
  + * 
    * <p>
    * There should be one &lt;node&gt; 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>&lt;node&gt; 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: slide-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: slide-dev-help@jakarta.apache.org


Re: cvs commit: jakarta-slide/src/share/org/apache/slide/cluster ClusterCacheRefresher.java

Posted by Daniel Florey <df...@apache.org>.
Hi James,
sorry for accidantely reformatting the javadocs...

James Mason schrieb:

> Thanks for doing this, Daniel. I like the changes you made. Much 
> cleaner :). With the threading gone I think the lifetime value needs 
> to be higher, otherwise subscription will die after an hour. Is this 
> correct? What's a good value for infinite lifetime?

Integer.MAX_VALUE  :-)
Don't know really, I will have a look at this tomorrow
Daniel

>
> -James
>
> dflorey@apache.org wrote:
>
>> 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 &lt;events&gt; 
>> node.
>>     * </p>
>>   + *     * <pre>
>>   - *    &lt;listener 
>> classname="org.apache.slide.cluster.ClusterCacheRefresher"&gt;
>>   - *        &lt;configuration&gt;
>>   - *            &lt;node local-host="local.host.domain"
>>   - *                  local-port="4444"
>>   - *                  repository-host="remote.host.domain"
>>   - *                  repository-port="8080"
>>   - *                  repository-protocol="http"
>>   - *                  username="root"
>>   - *                  password="root"
>>   - *            /&gt;
>>   - *        &lt;/configuration&gt;
>>   - *    &lt;/listener&gt;
>>   - *  </pre>
>>   + *   + *    + *      &lt;listener 
>> classname=&quot;org.apache.slide.cluster.ClusterCacheRefresher&quot;&gt;
>>   + *          &lt;configuration&gt;
>>   + *              &lt;node local-host=&quot;local.host.domain&quot;
>>   + *                    local-port=&quot;4444&quot;
>>   + *                    repository-host=&quot;remote.host.domain&quot;
>>   + *                    repository-port=&quot;8080&quot;
>>   + *                    repository-protocol=&quot;http&quot;
>>   + *                    username=&quot;root&quot;
>>   + *                    password=&quot;root&quot;
>>   + *              /&gt;
>>   + *          &lt;/configuration&gt;
>>   + *      &lt;/listener&gt;
>>   + *      + *    + * </pre>
>>   + *     * <p>
>>     * There should be one &lt;node&gt; 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>&lt;node&gt; 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: slide-dev-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: slide-dev-help@jakarta.apache.org
>>
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: slide-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: slide-dev-help@jakarta.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: slide-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: slide-dev-help@jakarta.apache.org


Re: cvs commit: jakarta-slide/src/share/org/apache/slide/cluster ClusterCacheRefresher.java

Posted by James Mason <ma...@apache.org>.
Thanks for doing this, Daniel. I like the changes you made. Much cleaner 
:). With the threading gone I think the lifetime value needs to be 
higher, otherwise subscription will die after an hour. Is this correct? 
What's a good value for infinite lifetime?

-James

dflorey@apache.org wrote:
> 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 &lt;events&gt; node.
>     * </p>
>   + * 
>     * <pre>
>   - *	&lt;listener classname="org.apache.slide.cluster.ClusterCacheRefresher"&gt;
>   - *		&lt;configuration&gt;
>   - *			&lt;node local-host="local.host.domain"
>   - *			      local-port="4444"
>   - *				  repository-host="remote.host.domain"
>   - *				  repository-port="8080"
>   - *				  repository-protocol="http"
>   - *				  username="root"
>   - *				  password="root"
>   - *			/&gt;
>   - *		&lt;/configuration&gt;
>   - *	&lt;/listener&gt;
>   - *  </pre>
>   + * 
>   + *  
>   + *  	&lt;listener classname=&quot;org.apache.slide.cluster.ClusterCacheRefresher&quot;&gt;
>   + *  		&lt;configuration&gt;
>   + *  			&lt;node local-host=&quot;local.host.domain&quot;
>   + *  			      local-port=&quot;4444&quot;
>   + *  				  repository-host=&quot;remote.host.domain&quot;
>   + *  				  repository-port=&quot;8080&quot;
>   + *  				  repository-protocol=&quot;http&quot;
>   + *  				  username=&quot;root&quot;
>   + *  				  password=&quot;root&quot;
>   + *  			/&gt;
>   + *  		&lt;/configuration&gt;
>   + *  	&lt;/listener&gt;
>   + *    
>   + *  
>   + * </pre>
>   + * 
>     * <p>
>     * There should be one &lt;node&gt; 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>&lt;node&gt; 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: slide-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: slide-dev-help@jakarta.apache.org
> 
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: slide-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: slide-dev-help@jakarta.apache.org