Author: taylor
Date: Thu Jan 25 15:31:22 2007
New Revision: 500054

URL: http://svn.apache.org/viewvc?view=rev&rev=500054
Log:
https://issues.apache.org/jira/browse/JS2-647
Cluster Deployment
contribution from Hajo Birthelmer

Added:
    
portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/cluster/
    
portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/cluster/NodeInformationImpl.java
    
portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/cluster/NodeManagerImpl.java
    
portals/jetspeed-2/trunk/components/portal/src/test/org/apache/jetspeed/cluster/
    
portals/jetspeed-2/trunk/components/portal/src/test/org/apache/jetspeed/cluster/TestCluster.java
    portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cluster/
    
portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cluster/NodeInformation.java
    
portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cluster/NodeManager.java
    portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/cluster-node.xml
Modified:
    
portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/tools/pamanager/PortletApplicationManager.java
    portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/deployment.xml

Added: 
portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/cluster/NodeInformationImpl.java
URL: 
http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/cluster/NodeInformationImpl.java?view=auto&rev=500054
==============================================================================
--- 
portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/cluster/NodeInformationImpl.java
 (added)
+++ 
portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/cluster/NodeInformationImpl.java
 Thu Jan 25 15:31:22 2007
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.cluster;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.text.DateFormat;
+import java.util.Date;
+
+import org.apache.pluto.om.common.ObjectID;
+
+/**
+ * Node Information
+ * 
+ * @author <a href="mailto:[EMAIL PROTECTED]">Hajo Birthelmer</a>
+ * @version
+ */
+public class NodeInformationImpl implements NodeInformation, Serializable 
+{
+       static final long serialVersionUID = -598265530537353219L;
+
+       private Long id;
+       private String contextName;
+       private Date lastDeployDate = null;
+       private static final int CompressVersion = 1;
+
+       /**
+        * default class construtor required for bean management
+        *
+        */
+       public NodeInformationImpl()
+       {}
+       
+       /**
+        * extensible serialization routine - indicates the version written to 
allow for later structural updates
+        *
+        */
+       private void writeObject(ObjectOutputStream out) throws IOException
+       {
+               out.writeByte(CompressVersion);
+               out.writeLong(id.longValue());
+               out.writeUTF(contextName);
+               if (lastDeployDate == null)
+                       out.writeByte(0);
+               else
+               {
+                       out.writeByte(1);
+                       out.writeLong(lastDeployDate.getTime());
+               }
+       }
+       /**
+        * extensible serialization routine 
+        * using the version byte code can identify older versions and handle 
updates correctly
+        *
+        */
+       private void readObject(ObjectInputStream in) throws IOException,
+                       ClassNotFoundException
+       {
+               int version = in.readByte();
+               // do changes here if version dependant
+
+               id = new Long(in.readLong());
+               contextName = in.readUTF();
+               int dateSet = in.readByte();
+               
+               if (dateSet == 1)
+                       lastDeployDate = new Date(in.readLong());
+               else
+                       lastDeployDate = null;
+       }
+
+       public boolean equals(Object object)
+       {
+               if (object == this)
+                       return true;
+               if (!(object instanceof NodeInformation))
+                       return false;
+               return equals((NodeInformation) object);
+       }
+
+       public int compareTo(Object object)
+       {
+               if (object == null)
+                       return 1;
+               if (object == this)
+                       return 0;
+               if (!(object instanceof NodeInformation))
+                       return 1;
+               return compareTo((NodeInformation) object);
+       }
+
+       public final boolean equals(NodeInformation object)
+       {
+               if (object == null)
+                       return false;
+               return object.getContextName().equalsIgnoreCase(contextName);
+       }
+
+       public final int compareTo(NodeInformation object)
+       {
+               return getContextName().compareToIgnoreCase(contextName);
+       }
+
+       public String toString()
+       {
+               StringBuffer buffer = new StringBuffer();
+               buffer.append("id= " + this.id.longValue());
+               buffer.append("; contextName= " + this.getContextName());
+               buffer.append("; lastDeployDate= " + this.getContextName());
+               if (this.lastDeployDate != null)
+               {
+                       DateFormat format = 
DateFormat.getTimeInstance(DateFormat.SHORT);
+                       try
+                       {
+                               
buffer.append(format.format(this.lastDeployDate));
+                       } catch (Exception e)
+                       {
+                               buffer.append("<invalidDate>");
+                       }
+               } else
+                       buffer.append("<empty>");
+
+               return buffer.toString();
+       }
+
+       public String getContextName()
+       {
+               return contextName;
+       }
+
+       public void setContextName(String contextName)
+       {
+               this.contextName = contextName;
+       }
+
+       public Long getId()
+       {
+               return id;
+       }
+
+       public void setId(ObjectID id)
+       {
+               this.id = new Long(id.toString());
+       }
+
+       public void setId(Long id)
+       {
+               this.id = id;
+       }
+
+       public void setId(long id)
+       {
+               this.id = new Long(id);
+       }
+
+       public Date getLastDeployDate()
+       {
+               return lastDeployDate;
+       }
+
+       public void setLastDeployDate(Date lastDeployDate)
+       {
+               this.lastDeployDate = lastDeployDate;
+       }
+
+}

Added: 
portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/cluster/NodeManagerImpl.java
URL: 
http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/cluster/NodeManagerImpl.java?view=auto&rev=500054
==============================================================================
--- 
portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/cluster/NodeManagerImpl.java
 (added)
+++ 
portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/cluster/NodeManagerImpl.java
 Thu Jan 25 15:31:22 2007
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.cluster;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.HashMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jetspeed.om.common.portlet.MutablePortletApplication;
+import org.apache.pluto.om.common.ObjectID;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
+
+/**
+ * Node Manager 
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Hajo Birthelmer</a>
+ * @version 
+ */
+public class NodeManagerImpl implements NodeManager,BeanFactoryAware
+{
+       protected final static Log log = 
LogFactory.getLog(NodeManagerImpl.class);
+
+    /**
+     * added support for bean factory to create profile rules
+     */
+    private BeanFactory beanFactory;
+
+       private HashMap nodes = null; 
+       private File rootIndexDir = null;
+           
+    /** the default criterion bean name */
+    private String nodeInformationBean = "NodeInformation";
+
+       
+       public NodeManagerImpl(String indexRoot, String nodeInformationBean)
+    throws Exception
+    {
+       
+        //assume it's full path for now
+        rootIndexDir = new File(indexRoot);
+        this.nodeInformationBean = nodeInformationBean;
+
+        if (!(rootIndexDir.exists()))
+               rootIndexDir.mkdirs();
+        load();
+    }
+
+       
+       protected void save()
+       {
+               try {
+                     FileOutputStream fout = new 
FileOutputStream(rootIndexDir.getAbsolutePath()+ "/nodeInfo.ser");
+                     ObjectOutputStream oos = new ObjectOutputStream(fout);
+                     oos.writeObject(nodes);
+                     oos.close();
+                     }
+                  catch (Exception e) 
+                  {
+                   log.error("Failed to write nodes data file to  " + 
rootIndexDir.getAbsolutePath()+ "/nodeInfo.ser" + " - error : " + 
e.getLocalizedMessage());
+                          e.printStackTrace(); 
+                       }
+       }
+    
+       protected void load()
+       {
+                       File data = new File( rootIndexDir.getAbsolutePath()+ 
"/nodeInfo.ser");
+                       if (data.exists())
+                       {
+                               try {
+                                   FileInputStream fin = new 
FileInputStream(data.getAbsolutePath());
+                                   ObjectInputStream ois = new 
ObjectInputStream(fin);
+                                   nodes = (HashMap) ois.readObject();
+                                   ois.close();
+                                   }
+                                  catch (Exception e) 
+                                  { 
+                                   log.error("Failed to read nodes data file 
from " + data.getAbsolutePath() + " - error : " + e.getLocalizedMessage());
+                                          nodes = new HashMap();
+                                  }
+                       }
+                       else
+                       {
+                               try
+                               {
+                                       data.createNewFile();
+                               }
+                               catch (Exception e)
+                               {
+                           log.error("Failed to create new nodes data file 
error : " + e.getLocalizedMessage());
+                                       e.printStackTrace();
+                               }
+                               nodes = new HashMap();
+                       }
+                       
+//                     NodeInformationImpl temp = new NodeInformationImpl();
+//                     temp.setContextName("tttt");
+       }
+       public int checkNode(Long id, String contextName)
+       {
+               if ((contextName == null) || (id == null))
+                       return NodeManager.INVALID_NODE_REQUEST;
+               NodeInformation info = (NodeInformation)nodes.get(contextName);
+               if (info == null)
+                       return NodeManager.NODE_NEW;
+               if (info.getId().longValue() < id.longValue())
+                       return NodeManager.NODE_OUTDATED;
+               return NodeManager.NODE_SAVED;
+       }
+       
+       public void addNode(Long id, String contextName) throws Exception
+       {
+               if ((contextName == null) || (id == null))
+                       return;
+               NodeInformation info = (NodeInformation)nodes.get(contextName);
+               if (info == null)
+               {
+                       info = createNodeInformation();
+                       info.setContextName(contextName);
+               }
+               info.setId(id);
+               nodes.put(contextName, info);
+               save();
+       }
+
+       public void removeNode(String contextName) throws Exception
+       {
+               if (contextName == null)
+                       return;
+               NodeInformation info = (NodeInformation)nodes.get(contextName);
+               if (info == null)
+                       return;
+               nodes.remove(contextName);
+               save();
+       }
+
+       
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.jetspeed.profiler.Profiler#createRuleCriterion()
+     */
+    protected NodeInformation createNodeInformation() throws 
ClassNotFoundException
+    {
+        try
+        {
+            NodeInformation nodeInformation = (NodeInformation) 
beanFactory.getBean(
+                    this.nodeInformationBean, NodeInformation.class);
+            return nodeInformation;
+        } catch (Exception e)
+        {
+            log.error("Failed to create nodeInformation for " + 
nodeInformationBean
+                    + " error : " + e.getLocalizedMessage());
+            throw new ClassNotFoundException("Spring failed to create the "
+                    + " nodeInformation bean.", e);
+        }
+
+    }
+
+    /*
+     * Method called automatically by Spring container upon initialization
+     * 
+     * @param beanFactory automatically provided by framework @throws
+     * BeansException
+     */
+    public void setBeanFactory(BeanFactory beanFactory) throws BeansException
+    {
+        this.beanFactory = beanFactory;
+    }
+
+       public int getNumberOfNodes()
+       {
+               return nodes.size();
+       }
+
+    
+    
+    
+}

Modified: 
portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/tools/pamanager/PortletApplicationManager.java
URL: 
http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/tools/pamanager/PortletApplicationManager.java?view=diff&rev=500054&r1=500053&r2=500054
==============================================================================
--- 
portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/tools/pamanager/PortletApplicationManager.java
 (original)
+++ 
portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/tools/pamanager/PortletApplicationManager.java
 Thu Jan 25 15:31:22 2007
@@ -15,9 +15,17 @@
  */
 package org.apache.jetspeed.tools.pamanager;
 
+import java.io.File;
+import java.io.IOException;
+import java.security.Permission;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-
+import org.apache.jetspeed.cluster.NodeManager;
 import 
org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent;
 import 
org.apache.jetspeed.components.portletentity.PortletEntityNotDeletedException;
 import org.apache.jetspeed.components.portletregistry.PortletRegistry;
@@ -31,25 +39,16 @@
 import org.apache.jetspeed.security.PortletPermission;
 import org.apache.jetspeed.security.Role;
 import org.apache.jetspeed.security.RoleManager;
+import org.apache.jetspeed.security.SecurityException;
 import org.apache.jetspeed.util.DirectoryHelper;
 import org.apache.jetspeed.util.FileSystemHelper;
 import org.apache.jetspeed.util.MultiFileChecksumHelper;
 import org.apache.jetspeed.util.descriptor.PortletApplicationWar;
-import org.apache.jetspeed.security.SecurityException;
 import org.apache.pluto.om.common.SecurityRole;
 import org.apache.pluto.om.entity.PortletEntity;
 import org.apache.pluto.om.entity.PortletEntityCtrl;
 import org.apache.pluto.om.portlet.PortletDefinition;
 
-import java.io.File;
-import java.io.IOException;
-
-import java.security.Permission;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
 /**
  * PortletApplicationManager
  *
@@ -74,13 +73,15 @@
     protected DescriptorChangeMonitor monitor;
     protected boolean started;
 
+    protected NodeManager nodeManager;
+    
     /**
         * Creates a new PortletApplicationManager object.
         */
        public PortletApplicationManager(PortletFactory portletFactory, 
PortletRegistry registry,
                PortletEntityAccessComponent entityAccess, 
PortletWindowAccessor windowAccess,
         PermissionManager permissionManager, SearchEngine searchEngine,
-        RoleManager roleManager, List permissionRoles)
+        RoleManager roleManager, List permissionRoles, NodeManager nodeManager)
        {
                this.portletFactory     = portletFactory;
                this.registry               = registry;
@@ -90,6 +91,7 @@
         this.searchEngine       = searchEngine;
         this.roleManager        = roleManager;        
         this.permissionRoles    = permissionRoles;
+        this.nodeManager               = nodeManager;
        }
     
     public void start()
@@ -217,6 +219,7 @@
                 // ignore errors during portal shutdown
             }
 
+            
             if (pa != null)
             {
                 if (portletFactory.isPortletApplicationRegistered(pa))
@@ -225,6 +228,14 @@
                 }
 
                 unregisterPortletApplication(pa, true);
+                try
+                {
+                       nodeManager.removeNode(paName);
+                }
+                catch (Exception ee)
+                {
+                       // we actually do not care about an exception in the 
remove operation...
+                }
             }
         }
         finally
@@ -337,12 +348,10 @@
                        log.info("Registered the portlet application " + 
paName);
 
                        // add to search engine result
-                       if (searchEngine != null)
-                       {
-                               searchEngine.add(pa);
-                               searchEngine.add(pa.getPortletDefinitions());
-                               log.info("Registered the portlet application in 
the search engine... " + paName);
-                       }
+                       this.updateSearchEngine(false, pa);
+                       
+                       // and add to the current node info
+                       nodeManager.addNode(new Long(pa.getId().toString()), 
pa.getName());
             
             // grant default permissions to portlet application
                        grantDefaultPermissions(paName);
@@ -451,17 +460,85 @@
                 }
                 portletFactory.unregisterPortletApplication(pa);               
         
             }
-            if (register && (pa == null || checksum != pa.getChecksum()))
+//            if (register && (pa == null || checksum != pa.getChecksum()))
+            if (register)
             {
-                try
-                {
-                    pa = registerPortletApplication(paWar, pa, local, 
paClassLoader);
-                }
-                catch (Exception e)
-                {
-                    // don't register the pa
-                    register = false;
-                }
+               if (pa == null)
+               { 
+                       // new
+                       try
+                       {
+                           pa = registerPortletApplication(paWar, pa, local, 
paClassLoader);
+                       }
+                       catch (Exception e)
+                       {
+                           // don't register the pa
+                           register = false;
+                       }
+               }
+               else
+               {
+                       int status = nodeManager.checkNode(new 
Long(pa.getId().toString()), pa.getName());
+                               boolean reregister = false;
+                               boolean deploy = false;
+                               switch (status)
+                               {
+                                       case  NodeManager.NODE_NEW:
+                                       {
+                                       //only reason is that the file got 
somehow corrupted 
+                                       // so we really do not know what is 
going on here...
+                                       // the best chance at this point is to 
reregister (which might be the absolute wrong choice)
+                                       log.warn("The portlet application " + 
pa.getName() + " is registered in the database but not locally .... we will 
reregister");
+                                       reregister = true;
+                                               if (checksum != 
pa.getChecksum())
+                                               {
+                                               log.warn("The provided portlet 
application " + pa.getName() + " is a different version than in the database 
(db-checksum=" + pa.getChecksum() + ", local-checksum=: " + checksum + ") .... 
we will redeploy (also to the database)");
+                                                       deploy = true;
+                                               }
+                                               break;
+                                       }
+                                       case  NodeManager.NODE_SAVED:
+                                       {
+                                               if (checksum != 
pa.getChecksum())
+                               {       
+                                               log.warn("The provided portlet 
application " + pa.getName() + " is a different version than in the local node 
info and the database (db-checksum=" + pa.getChecksum() + ", local-checksum=: " 
+ checksum + ") .... we will reregister AND redeploy (also to the database)");
+                                                       //database and local 
node info are in synch, so we assume that this is a brand new
+                                                       // war .... let's deploy
+                                                       reregister = true;
+                                                       deploy = true;
+                               }
+                                               break;
+                                       }
+                                       case  NodeManager.NODE_OUTDATED:
+                                       {
+                                       //database version is older (determined 
by id) than the database 
+                                               //let's deploy and reregister
+                                               if (checksum != 
pa.getChecksum())
+                                               log.error("The portlet 
application " + pa.getName() + " provided for the upgrade IS WRONG. The 
database checksum= " + pa.getChecksum() + ", but the local=" + checksum + 
"....THIS NEEDS TO BE CORRECTED");
+                                                       reregister = true;
+                                               break;
+                                       }
+                               }
+                               if (deploy)
+                           pa = registerPortletApplication(paWar, pa, local, 
paClassLoader);
+                               else
+                                       if (reregister)
+                                       {
+                                               // add to search engine result
+                                               this.updateSearchEngine(false, 
pa);
+                                               
+                                               // and add to the current node 
info
+                                               try
+                                               {
+                                                       nodeManager.addNode(new 
Long(pa.getId().toString()), pa.getName());
+                                               } catch (Exception e)
+                                               {
+                                                       log.error("Adding node 
for portlet application " + pa.getName() + " caused exception" , e);
+                                               }
+                                       }
+                                       
+               
+               }
             }
             if (register)
             {
@@ -525,16 +602,32 @@
                }
        }
 
-       protected void unregisterPortletApplication(MutablePortletApplication 
pa,
-               boolean purgeEntityInfo)
-               throws RegistryException
+       
+       protected void updateSearchEngine(boolean 
remove,MutablePortletApplication pa )
        {
                if (searchEngine != null)
                {
-                       searchEngine.remove(pa);
-                       searchEngine.remove(pa.getPortletDefinitions());
+                       if (remove)
+                       {
+                               searchEngine.remove(pa);
+                               searchEngine.remove(pa.getPortletDefinitions());
+                                       log.info("Un-Registered the portlet 
application in the search engine... " + pa.getName());
+                       }
+                       else
+                       {
+                                       searchEngine.add(pa);
+                                       
searchEngine.add(pa.getPortletDefinitions());
+                                       log.info("Registered the portlet 
application in the search engine... " + pa.getName());
+                       }
                }
+               
+       }
+       protected void unregisterPortletApplication(MutablePortletApplication 
pa,
+               boolean purgeEntityInfo)
+               throws RegistryException
+       {
 
+               updateSearchEngine(true,pa);
                log.info("Remove all registry entries defined for portlet 
application " + pa.getName());
 
                Iterator portlets = pa.getPortletDefinitions().iterator();

Added: 
portals/jetspeed-2/trunk/components/portal/src/test/org/apache/jetspeed/cluster/TestCluster.java
URL: 
http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/components/portal/src/test/org/apache/jetspeed/cluster/TestCluster.java?view=auto&rev=500054
==============================================================================
--- 
portals/jetspeed-2/trunk/components/portal/src/test/org/apache/jetspeed/cluster/TestCluster.java
 (added)
+++ 
portals/jetspeed-2/trunk/components/portal/src/test/org/apache/jetspeed/cluster/TestCluster.java
 Thu Jan 25 15:31:22 2007
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.cluster;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.apache.jetspeed.components.util.DatasourceEnabledSpringTestCase;
+
+/**
+ * <p>
+ * TestCluster
+ * </p>
+ * 
+ * @author <a href="mailto:[EMAIL PROTECTED]">Scott T. Weaver </a>
+ * @version $Id: TestCluster.java 463270 2006-10-12 15:19:29Z taylor $
+ *  
+ */
+public class TestCluster extends DatasourceEnabledSpringTestCase
+{
+ 
+          /** The node manager. */
+    private NodeManager single;
+
+    /**
+     * @see junit.framework.TestCase#setUp()
+     */
+    public void setUp() throws Exception
+    {
+       System.setProperty("applicationRoot","target/jetspeed");
+        super.setUp();
+
+        single = (NodeManager) 
ctx.getBean("org.apache.jetspeed.cluster.NodeManager");
+    }
+  
+    public static Test suite()
+    {
+        // All methods starting with "test" will be executed in the test suite.
+        return new TestSuite(TestCluster.class);
+    }
+
+    /** Test set user info map. * */
+    public void testCluser() throws Exception
+    {
+       String contextName = "SOME_NEW_PORTLET_APPLICATION";
+       Long id = new Long(10);
+       
+        assertNotNull("Manager should be instantiated", single);
+        
+        int numExistingApps = single.getNumberOfNodes();
+        
+        //create a new node
+        int status = single.checkNode(id, contextName);
+        if (status != NodeManager.NODE_NEW)
+        {
+               single.removeNode(contextName); //previous run didn't clean up
+               status = single.checkNode(id, contextName);
+            assertEquals("Should be a new node",NodeManager.NODE_NEW,status);
+        }
+        
+        // ok - create a new node
+        single.addNode(id, contextName);
+        int newApps = single.getNumberOfNodes();
+
+        assertEquals("Should have added new node",newApps, numExistingApps+1);
+        
+        status = single.checkNode(id, contextName);
+        assertEquals("Should be a current (saved) 
node",NodeManager.NODE_SAVED,status);
+        
+       id = new Long(20);
+        status = single.checkNode(id, contextName);
+        assertEquals("Should be an outdated 
node",NodeManager.NODE_OUTDATED,status);
+
+        single.addNode(id, contextName);
+        status = single.checkNode(id, contextName);
+        assertEquals("Should be again a current (saved) 
node",NodeManager.NODE_SAVED,status);
+
+       id = new Long(10);
+        status = single.checkNode(id, contextName);
+        assertEquals("Should still be a current (saved) 
node",NodeManager.NODE_SAVED,status);
+
+       single.removeNode(contextName); //previous run didn't clean up
+        status = single.checkNode(id, contextName);
+        assertEquals("Node should be gone....",NodeManager.NODE_NEW,status);
+    }
+    protected String[] getConfigurations()
+    {
+        return new String[]
+        { "cluster-node.xml"};
+    }
+
+}

Added: 
portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cluster/NodeInformation.java
URL: 
http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cluster/NodeInformation.java?view=auto&rev=500054
==============================================================================
--- 
portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cluster/NodeInformation.java
 (added)
+++ 
portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cluster/NodeInformation.java
 Thu Jan 25 15:31:22 2007
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.cluster;
+
+import java.util.Date;
+import org.apache.pluto.om.common.ObjectID;
+
+/**
+ * Node Information Interface
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Hajo Birthelmer</a>
+ * @version 
+ */
+
+public interface NodeInformation
+{
+
+       /**
+        * Getter for ContextName
+        * @return
+        */
+       public String getContextName();
+       /**
+        * setter for context name
+        * 
+        * @param id
+        */     
+       public void setContextName(String contextName);
+
+       
+       /**
+        * Getter for ObjectID 
+        * @return
+        */
+       public Long getId();
+
+       /**
+        * setter for ObjectID 
+        * 
+        * @param id
+        */     
+       public void setId(ObjectID id);
+
+       /**
+        * setter for ObjectID 
+        * 
+        * @param id
+        */     
+       public void setId(Long id);
+       /**
+        * setter for ObjectID 
+        * 
+        * @param id
+        */     
+       public void setId(long id);
+
+       /**
+        * Getter for Last Deploy Date
+        * @return
+        */
+       public Date getLastDeployDate();
+
+
+       /**
+        * setter for last deploy date 
+        * 
+        * @param id
+        */     
+       public void setLastDeployDate(Date lastDeployDate);
+       
+       public String toString ();
+}
\ No newline at end of file

Added: 
portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cluster/NodeManager.java
URL: 
http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cluster/NodeManager.java?view=auto&rev=500054
==============================================================================
--- 
portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cluster/NodeManager.java
 (added)
+++ 
portals/jetspeed-2/trunk/jetspeed-api/src/java/org/apache/jetspeed/cluster/NodeManager.java
 Thu Jan 25 15:31:22 2007
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.cluster;
+
+/**
+ * Node Manager Interface
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Hajo Birthelmer</a>
+ * @version 
+ */
+public interface NodeManager
+{
+
+       public static final int INVALID_NODE_REQUEST = -1;
+       public static final int NODE_SAVED = 0;
+       public static final int NODE_OUTDATED = 1;
+       public static final int NODE_NEW = 2;
+
+       /**
+        * Returns the current "knowledge" about a given node (i.e. the portlet 
application).
+        * If the contextName doesn't exist NODE_NEW is returned.
+        * An id requested newer than what is stored is indicated by 
NODE_OUTDATED. 
+        * @param id
+        * @param contextName
+        * @return
+        */
+       public int checkNode(Long id, String contextName);
+
+       /**
+        * Add a new node or update the id of an existing one...(i.e. the 
portlet application) to the local info
+        * @param id
+        * @param contextName
+        * @throws Exception
+        */
+       public void addNode(Long id, String contextName) throws Exception;
+
+       /**
+        * return the number of currently stored nodes
+        * @return
+        */
+       public int getNumberOfNodes();
+
+       /**
+        * Remove a node
+        * @param id
+        * @param contextName
+        * @throws Exception
+        */
+       public void removeNode(String contextName) throws Exception;
+
+}

Added: portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/cluster-node.xml
URL: 
http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/cluster-node.xml?view=auto&rev=500054
==============================================================================
--- portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/cluster-node.xml 
(added)
+++ portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/cluster-node.xml Thu 
Jan 25 15:31:22 2007
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
"http://www.springframework.org/dtd/spring-beans.dtd";>
+<!--
+Copyright 2004 The Apache Software Foundation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<beans>
+
+  <!--CLUSTER NODE COMPONENT-->
+  <bean id="org.apache.jetspeed.cluster.NodeManager"
+       class="org.apache.jetspeed.cluster.NodeManagerImpl"
+  >
+       <constructor-arg index="0">
+       <value>${applicationRoot}/WEB-INF/cluster_node</value> 
+<!--                                   
<value>target/jetspeed/WEB-INF/cluster_node</value> -->
+               </constructor-arg>
+       <!--  pass reference to NodeInformation -->
+               <constructor-arg index="1">
+                       <value>NodeInformation</value>
+               </constructor-arg>
+       
+  </bean>
+  
+       <!-- Rule Criterion -->
+       <bean id="NodeInformation" 
class="org.apache.jetspeed.cluster.NodeInformationImpl" 
singleton="false"></bean>
+  
+</beans>

Modified: portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/deployment.xml
URL: 
http://svn.apache.org/viewvc/portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/deployment.xml?view=diff&rev=500054&r1=500053&r2=500054
==============================================================================
--- portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/deployment.xml 
(original)
+++ portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/deployment.xml Thu Jan 
25 15:31:22 2007
@@ -51,6 +51,7 @@
             <value>user</value>
          </list>
        </constructor-arg>
+          <constructor-arg><ref 
bean="org.apache.jetspeed.cluster.NodeManager"/></constructor-arg>              
       
 
    <!-- optional configuration for automatic creation of not yet existing 
roles as defined in the deployed web.xml:
        <property name="autoCreateRoles"><value>true</value></property>



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to