incubator-connectors-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kwri...@apache.org
Subject svn commit: r1005096 - in /incubator/lcf/trunk/modules/framework: agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ agents/src/main/java/org/apache/manifoldcf/agents/outputconnection/ crawler-ui/src/main/webapp/ pull-agent/src/main/java/org...
Date Wed, 06 Oct 2010 16:06:42 GMT
Author: kwright
Date: Wed Oct  6 16:06:41 2010
New Revision: 1005096

URL: http://svn.apache.org/viewvc?rev=1005096&view=rev
Log:
Fix for CONNECTORS-112.  Introduce isnew as part of every connection object, to allow the
code to prevent unintentional overwrite of a connection.

Modified:
    incubator/lcf/trunk/modules/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/IOutputConnection.java
    incubator/lcf/trunk/modules/framework/agents/src/main/java/org/apache/manifoldcf/agents/outputconnection/OutputConnection.java
    incubator/lcf/trunk/modules/framework/agents/src/main/java/org/apache/manifoldcf/agents/outputconnection/OutputConnectionManager.java
    incubator/lcf/trunk/modules/framework/crawler-ui/src/main/webapp/editauthority.jsp
    incubator/lcf/trunk/modules/framework/crawler-ui/src/main/webapp/editconnection.jsp
    incubator/lcf/trunk/modules/framework/crawler-ui/src/main/webapp/editoutput.jsp
    incubator/lcf/trunk/modules/framework/crawler-ui/src/main/webapp/execute.jsp
    incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/authorities/authority/AuthorityConnection.java
    incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/authorities/authority/AuthorityConnectionManager.java
    incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/authorities/interfaces/IAuthorityConnection.java
    incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/interfaces/IRepositoryConnection.java
    incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/repository/RepositoryConnection.java
    incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/repository/RepositoryConnectionManager.java
    incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/ManifoldCF.java

Modified: incubator/lcf/trunk/modules/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/IOutputConnection.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/IOutputConnection.java?rev=1005096&r1=1005095&r2=1005096&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/IOutputConnection.java
(original)
+++ incubator/lcf/trunk/modules/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/IOutputConnection.java
Wed Oct  6 16:06:41 2010
@@ -27,6 +27,16 @@ public interface IOutputConnection
 {
   public static final String _rcsid = "@(#)$Id: IOutputConnection.java 988245 2010-08-23
18:39:35Z kwright $";
 
+  /** Set 'isnew' condition.
+  *@param isnew true if this is a new instance.
+  */
+  public void setIsNew(boolean isnew);
+  
+  /** Get 'isnew' condition.
+  *@return true if this is a new connection, false otherwise.
+  */
+  public boolean getIsNew();
+  
   /** Set name.
   *@param name is the name.
   */

Modified: incubator/lcf/trunk/modules/framework/agents/src/main/java/org/apache/manifoldcf/agents/outputconnection/OutputConnection.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/agents/src/main/java/org/apache/manifoldcf/agents/outputconnection/OutputConnection.java?rev=1005096&r1=1005095&r2=1005096&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/agents/src/main/java/org/apache/manifoldcf/agents/outputconnection/OutputConnection.java
(original)
+++ incubator/lcf/trunk/modules/framework/agents/src/main/java/org/apache/manifoldcf/agents/outputconnection/OutputConnection.java
Wed Oct  6 16:06:41 2010
@@ -30,6 +30,7 @@ public class OutputConnection implements
   public static final String _rcsid = "@(#)$Id: OutputConnection.java 988245 2010-08-23 18:39:35Z
kwright $";
 
   // data
+  protected boolean isNew = true;
   protected String name = null;
   protected String description = null;
   protected String className = null;
@@ -48,6 +49,7 @@ public class OutputConnection implements
   public OutputConnection duplicate()
   {
     OutputConnection rval = new OutputConnection();
+    rval.isNew = isNew;
     rval.name = name;
     rval.description = description;
     rval.className = className;
@@ -56,6 +58,22 @@ public class OutputConnection implements
     return rval;
   }
 
+  /** Set 'isnew' condition.
+  *@param isnew true if this is a new instance.
+  */
+  public void setIsNew(boolean isnew)
+  {
+    this.isNew = isnew;
+  }
+  
+  /** Get 'isnew' condition.
+  *@return true if this is a new connection, false otherwise.
+  */
+  public boolean getIsNew()
+  {
+    return isNew;
+  }
+  
   /** Set name.
   *@param name is the name.
   */

Modified: incubator/lcf/trunk/modules/framework/agents/src/main/java/org/apache/manifoldcf/agents/outputconnection/OutputConnectionManager.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/agents/src/main/java/org/apache/manifoldcf/agents/outputconnection/OutputConnectionManager.java?rev=1005096&r1=1005095&r2=1005096&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/agents/src/main/java/org/apache/manifoldcf/agents/outputconnection/OutputConnectionManager.java
(original)
+++ incubator/lcf/trunk/modules/framework/agents/src/main/java/org/apache/manifoldcf/agents/outputconnection/OutputConnectionManager.java
Wed Oct  6 16:06:41 2010
@@ -44,6 +44,8 @@ public class OutputConnectionManager ext
   protected final static String maxCountField = "maxcount";
   protected final static String configField = "configxml";
 
+  protected static Random random = new Random();
+
   // Cache manager
   ICacheManager cacheManager;
   // Thread context
@@ -242,77 +244,105 @@ public class OutputConnectionManager ext
     ssb.add(getOutputConnectionsKey());
     ssb.add(getOutputConnectionKey(object.getName()));
     StringSet cacheKeys = new StringSet(ssb);
-    ICacheHandle ch = cacheManager.enterCache(null,cacheKeys,getTransactionID());
-    try
+    while (true)
     {
-      beginTransaction();
+      // Catch deadlock condition
       try
       {
-        performLock();
-        // Notify of a change to the configuration
-        ManifoldCF.noteConfigurationChange();
-        // See whether the instance exists
-        ArrayList params = new ArrayList();
-        params.add(object.getName());
-        IResultSet set = performQuery("SELECT * FROM "+getTableName()+" WHERE "+
-          nameField+"=? FOR UPDATE",params,null,null);
-        HashMap values = new HashMap();
-        values.put(descriptionField,object.getDescription());
-        values.put(classNameField,object.getClassName());
-        values.put(maxCountField,new Long((long)object.getMaxConnections()));
-        String configXML = object.getConfigParams().toXML();
-        values.put(configField,configXML);
-        boolean notificationNeeded = false;
-        boolean isCreated;
-        
-        if (set.getRowCount() > 0)
+        ICacheHandle ch = cacheManager.enterCache(null,cacheKeys,getTransactionID());
+        try
         {
-          isCreated = false;
-          IResultRow row = set.getRow(0);
-          String oldXML = (String)row.getValue(configField);
-          if (oldXML == null || !oldXML.equals(configXML))
-            notificationNeeded = true;
-
-          // Update
-          params.clear();
-          params.add(object.getName());
-          performUpdate(values," WHERE "+nameField+"=?",params,null);
+          beginTransaction();
+          try
+          {
+            performLock();
+            // Notify of a change to the configuration
+            ManifoldCF.noteConfigurationChange();
+            boolean isNew = object.getIsNew();
+            // See whether the instance exists
+            ArrayList params = new ArrayList();
+            params.add(object.getName());
+            IResultSet set = performQuery("SELECT * FROM "+getTableName()+" WHERE "+
+              nameField+"=? FOR UPDATE",params,null,null);
+            HashMap values = new HashMap();
+            values.put(descriptionField,object.getDescription());
+            values.put(classNameField,object.getClassName());
+            values.put(maxCountField,new Long((long)object.getMaxConnections()));
+            String configXML = object.getConfigParams().toXML();
+            values.put(configField,configXML);
+            boolean notificationNeeded = false;
+            boolean isCreated;
+            
+            if (set.getRowCount() > 0)
+            {
+              // If the object is supposedly new, it is bad that we found one that already
exists.
+              if (isNew)
+                throw new ManifoldCFException("Output connection '"+object.getName()+"' already
exists");
+              isCreated = false;
+              IResultRow row = set.getRow(0);
+              String oldXML = (String)row.getValue(configField);
+              if (oldXML == null || !oldXML.equals(configXML))
+                notificationNeeded = true;
+
+              // Update
+              params.clear();
+              params.add(object.getName());
+              performUpdate(values," WHERE "+nameField+"=?",params,null);
+            }
+            else
+            {
+              // If the object is not supposed to be new, it is bad that we did not find
one.
+              if (!isNew)
+                throw new ManifoldCFException("Output connection '"+object.getName()+"' no
longer exists");
+              isCreated = true;
+              // Insert
+              values.put(nameField,object.getName());
+              // We only need the general key because this is new.
+              performInsert(values,null);
+            }
+            
+            // If notification required, do it.
+            if (notificationNeeded)
+              AgentManagerFactory.noteOutputConnectionChange(threadContext,object.getName());
+
+            cacheManager.invalidateKeys(ch);
+            return isCreated;
+          }
+          catch (ManifoldCFException e)
+          {
+            signalRollback();
+            throw e;
+          }
+          catch (Error e)
+          {
+            signalRollback();
+            throw e;
+          }
+          finally
+          {
+            endTransaction();
+          }
         }
-        else
+        finally
         {
-          isCreated = true;
-          // Insert
-          values.put(nameField,object.getName());
-          // We only need the general key because this is new.
-          performInsert(values,null);
+          cacheManager.leaveCache(ch);
         }
-        
-        // If notification required, do it.
-        if (notificationNeeded)
-          AgentManagerFactory.noteOutputConnectionChange(threadContext,object.getName());
-
-        cacheManager.invalidateKeys(ch);
-        return isCreated;
       }
       catch (ManifoldCFException e)
       {
-        signalRollback();
-        throw e;
-      }
-      catch (Error e)
-      {
-        signalRollback();
-        throw e;
-      }
-      finally
-      {
-        endTransaction();
+        // Is this a deadlock exception?  If so, we want to try again.
+        if (e.getErrorCode() != ManifoldCFException.DATABASE_TRANSACTION_ABORT)
+          throw e;
+        try
+        {
+          ManifoldCF.sleep((long)(random.nextDouble() * 60000.0 + 500.0));
+        }
+        catch (InterruptedException e2)
+        {
+          throw new ManifoldCFException(e2.getMessage(),e2,ManifoldCFException.INTERRUPTED);
+        }
       }
     }
-    finally
-    {
-      cacheManager.leaveCache(ch);
-    }
   }
 
   /** Delete an output connection.
@@ -539,6 +569,7 @@ public class OutputConnectionManager ext
       String name = row.getValue(nameField).toString();
       int index = ((Integer)returnIndex.get(name)).intValue();
       OutputConnection rc = new OutputConnection();
+      rc.setIsNew(false);
       rc.setName(name);
       rc.setDescription((String)row.getValue(descriptionField));
       rc.setClassName((String)row.getValue(classNameField));

Modified: incubator/lcf/trunk/modules/framework/crawler-ui/src/main/webapp/editauthority.jsp
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/crawler-ui/src/main/webapp/editauthority.jsp?rev=1005096&r1=1005095&r2=1005096&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/crawler-ui/src/main/webapp/editauthority.jsp (original)
+++ incubator/lcf/trunk/modules/framework/crawler-ui/src/main/webapp/editauthority.jsp Wed
Oct  6 16:06:41 2010
@@ -53,6 +53,7 @@
 	}
 
 	// Setup default fields
+	boolean isNew = true;
 	String description = "";
 	String className = "";
 	int maxConnections = 10;
@@ -61,6 +62,7 @@
 	if (connection != null)
 	{
 		// Set up values
+		isNew = connection.getIsNew();
 		connectionName = connection.getName();
 		description = connection.getDescription();
 		className = connection.getClassName();
@@ -241,6 +243,7 @@
 	  <input type="hidden" name="op" value="Continue"/>
 	  <input type="hidden" name="type" value="authority"/>
 	  <input type="hidden" name="tabname" value='<%=org.apache.manifoldcf.ui.util.Encoder.attributeEscape(tabName)%>'/>
+	  <input type="hidden" name="isnewconnection" value='<%=(isNew?"true":"false")%>'/>
 	    <table class="tabtable">
 	      <tr class="tabrow">
 <%

Modified: incubator/lcf/trunk/modules/framework/crawler-ui/src/main/webapp/editconnection.jsp
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/crawler-ui/src/main/webapp/editconnection.jsp?rev=1005096&r1=1005095&r2=1005096&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/crawler-ui/src/main/webapp/editconnection.jsp (original)
+++ incubator/lcf/trunk/modules/framework/crawler-ui/src/main/webapp/editconnection.jsp Wed
Oct  6 16:06:41 2010
@@ -54,6 +54,7 @@
 	}
 	
 	// Set up default fields.
+	boolean isNew = true;
 	String description = "";
 	String className = "";
 	String authorityName = null;
@@ -66,6 +67,7 @@
 	if (connection != null)
 	{
 		// Set up values
+		isNew = connection.getIsNew();
 		connectionName = connection.getName();
 		description = connection.getDescription();
 		className = connection.getClassName();
@@ -281,6 +283,7 @@
 	  <input type="hidden" name="op" value="Continue"/>
 	  <input type="hidden" name="type" value="connection"/>
 	  <input type="hidden" name="tabname" value='<%=org.apache.manifoldcf.ui.util.Encoder.attributeEscape(tabName)%>'/>
+	  <input type="hidden" name="isnewconnection" value='<%=(isNew?"true":"false")%>'/>
 	    <table class="tabtable">
 	      <tr class="tabrow">
 <%

Modified: incubator/lcf/trunk/modules/framework/crawler-ui/src/main/webapp/editoutput.jsp
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/crawler-ui/src/main/webapp/editoutput.jsp?rev=1005096&r1=1005095&r2=1005096&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/crawler-ui/src/main/webapp/editoutput.jsp (original)
+++ incubator/lcf/trunk/modules/framework/crawler-ui/src/main/webapp/editoutput.jsp Wed Oct
 6 16:06:41 2010
@@ -53,6 +53,7 @@
 	}
 
 	// Set up default fields.
+	boolean isNew = true;
 	String description = "";
 	String className = "";
 	int maxConnections = 10;
@@ -62,6 +63,7 @@
 	if (connection != null)
 	{
 		// Set up values
+		isNew = connection.getIsNew();
 		connectionName = connection.getName();
 		description = connection.getDescription();
 		className = connection.getClassName();
@@ -240,6 +242,7 @@
 	  <input type="hidden" name="op" value="Continue"/>
 	  <input type="hidden" name="type" value="output"/>
 	  <input type="hidden" name="tabname" value='<%=org.apache.manifoldcf.ui.util.Encoder.attributeEscape(tabName)%>'/>
+	  <input type="hidden" name="isnewconnection" value='<%=(isNew?"true":"false")%>'/>
 	    <table class="tabtable">
 	      <tr class="tabrow">
 <%

Modified: incubator/lcf/trunk/modules/framework/crawler-ui/src/main/webapp/execute.jsp
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/crawler-ui/src/main/webapp/execute.jsp?rev=1005096&r1=1005095&r2=1005096&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/crawler-ui/src/main/webapp/execute.jsp (original)
+++ incubator/lcf/trunk/modules/framework/crawler-ui/src/main/webapp/execute.jsp Wed Oct 
6 16:06:41 2010
@@ -60,9 +60,14 @@
 				{
 					// Set up a connection object that is a merge of an existing connection object plus
what was posted.
 					IRepositoryConnection connection = null;
+					boolean isNew = true;
+					String x = variableContext.getParameter("isnewconnection");
+					if (x != null)
+						isNew = x.equals("true");
+
 					String connectionName = variableContext.getParameter("connname");
 					// If the connectionname is not null, load the connection description and prepopulate
everything with what comes from it.
-					if (connectionName != null && connectionName.length() > 0)
+					if (connectionName != null && connectionName.length() > 0 && !isNew)
 					{
 						connection = connManager.load(connectionName);
 					}
@@ -75,7 +80,8 @@
 					}
 					
 					// Fill in connection object from posted data
-					String x = variableContext.getParameter("description");
+					connection.setIsNew(isNew);
+					x = variableContext.getParameter("description");
 					if (x != null)
 						connection.setDescription(x);
 					x = variableContext.getParameter("classname");
@@ -214,9 +220,14 @@
 				{
 					// Set up a connection object that is a merge of an existing connection object plus
what was posted.
 					IAuthorityConnection connection = null;
+					boolean isNew = true;
+					String x = variableContext.getParameter("isnewconnection");
+					if (x != null)
+						isNew = x.equals("true");
+
 					String connectionName = variableContext.getParameter("connname");
 					// If the connectionname is not null, load the connection description and prepopulate
everything with what comes from it.
-					if (connectionName != null && connectionName.length() > 0)
+					if (connectionName != null && connectionName.length() > 0 && !isNew)
 					{
 						connection = authConnManager.load(connectionName);
 					}
@@ -229,7 +240,8 @@
 					}
 
 					// Gather all the data from the form.
-					String x = variableContext.getParameter("description");
+					connection.setIsNew(isNew);
+					x = variableContext.getParameter("description");
 					if (x != null)
 						connection.setDescription(x);
 					x = variableContext.getParameter("classname");
@@ -323,9 +335,14 @@
 				{
 					// Set up a connection object that is a merge of an existing connection object plus
what was posted.
 					IOutputConnection connection = null;
+					boolean isNew = true;
+					String x = variableContext.getParameter("isnewconnection");
+					if (x != null)
+						isNew = x.equals("true");
+
 					String connectionName = variableContext.getParameter("connname");
 					// If the connectionname is not null, load the connection description and prepopulate
everything with what comes from it.
-					if (connectionName != null && connectionName.length() > 0)
+					if (connectionName != null && connectionName.length() > 0 && !isNew)
 					{
 						connection = outputManager.load(connectionName);
 					}
@@ -338,7 +355,8 @@
 					}
 
 					// Gather all the data from the form.
-					String x = variableContext.getParameter("description");
+					connection.setIsNew(isNew);
+					x = variableContext.getParameter("description");
 					if (x != null)
 						connection.setDescription(x);
 					x = variableContext.getParameter("classname");

Modified: incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/authorities/authority/AuthorityConnection.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/authorities/authority/AuthorityConnection.java?rev=1005096&r1=1005095&r2=1005096&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/authorities/authority/AuthorityConnection.java
(original)
+++ incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/authorities/authority/AuthorityConnection.java
Wed Oct  6 16:06:41 2010
@@ -30,6 +30,7 @@ public class AuthorityConnection impleme
   public static final String _rcsid = "@(#)$Id: AuthorityConnection.java 988245 2010-08-23
18:39:35Z kwright $";
 
   // data
+  protected boolean isNew = true;
   protected String name = null;
   protected String description = null;
   protected String className = null;
@@ -48,6 +49,7 @@ public class AuthorityConnection impleme
   public AuthorityConnection duplicate()
   {
     AuthorityConnection rval = new AuthorityConnection();
+    rval.isNew = isNew;
     rval.name = name;
     rval.description = description;
     rval.className = className;
@@ -56,6 +58,22 @@ public class AuthorityConnection impleme
     return rval;
   }
 
+  /** Set 'isnew' condition.
+  *@param isnew true if this is a new instance.
+  */
+  public void setIsNew(boolean isnew)
+  {
+    this.isNew = isnew;
+  }
+  
+  /** Get 'isnew' condition.
+  *@return true if this is a new connection, false otherwise.
+  */
+  public boolean getIsNew()
+  {
+    return isNew;
+  }
+
   /** Set name.
   *@param name is the name.
   */

Modified: incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/authorities/authority/AuthorityConnectionManager.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/authorities/authority/AuthorityConnectionManager.java?rev=1005096&r1=1005095&r2=1005096&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/authorities/authority/AuthorityConnectionManager.java
(original)
+++ incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/authorities/authority/AuthorityConnectionManager.java
Wed Oct  6 16:06:41 2010
@@ -42,6 +42,8 @@ public class AuthorityConnectionManager 
   protected final static String maxCountField = "maxcount";
   protected final static String configField = "configxml";
 
+  protected static Random random = new Random();
+
   // Cache manager
   ICacheManager cacheManager;
   // Thread context
@@ -240,66 +242,93 @@ public class AuthorityConnectionManager 
     ssb.add(getAuthorityConnectionsKey());
     ssb.add(getAuthorityConnectionKey(object.getName()));
     StringSet cacheKeys = new StringSet(ssb);
-    ICacheHandle ch = cacheManager.enterCache(null,cacheKeys,getTransactionID());
-    try
+    while (true)
     {
-      beginTransaction();
       try
       {
-        performLock();
-        ManifoldCF.noteConfigurationChange();
-        // See whether the instance exists
-        ArrayList params = new ArrayList();
-        params.add(object.getName());
-        IResultSet set = performQuery("SELECT * FROM "+getTableName()+" WHERE "+
-          nameField+"=? FOR UPDATE",params,null,null);
-        HashMap values = new HashMap();
-        values.put(descriptionField,object.getDescription());
-        values.put(classNameField,object.getClassName());
-        values.put(maxCountField,new Long((long)object.getMaxConnections()));
-        values.put(configField,object.getConfigParams().toXML());
-
-        boolean isCreated;
-        
-        if (set.getRowCount() > 0)
+        ICacheHandle ch = cacheManager.enterCache(null,cacheKeys,getTransactionID());
+        try
         {
-          isCreated = false;
-          // Update
-          params.clear();
-          params.add(object.getName());
-          performUpdate(values," WHERE "+nameField+"=?",params,null);
+          beginTransaction();
+          try
+          {
+            performLock();
+            ManifoldCF.noteConfigurationChange();
+            boolean isNew = object.getIsNew();
+            // See whether the instance exists
+            ArrayList params = new ArrayList();
+            params.add(object.getName());
+            IResultSet set = performQuery("SELECT * FROM "+getTableName()+" WHERE "+
+              nameField+"=? FOR UPDATE",params,null,null);
+            HashMap values = new HashMap();
+            values.put(descriptionField,object.getDescription());
+            values.put(classNameField,object.getClassName());
+            values.put(maxCountField,new Long((long)object.getMaxConnections()));
+            values.put(configField,object.getConfigParams().toXML());
+
+            boolean isCreated;
+            
+            if (set.getRowCount() > 0)
+            {
+              // If the object is supposedly new, it is bad that we found one that already
exists.
+              if (isNew)
+                throw new ManifoldCFException("Authority connection '"+object.getName()+"'
already exists");
+              isCreated = false;
+              // Update
+              params.clear();
+              params.add(object.getName());
+              performUpdate(values," WHERE "+nameField+"=?",params,null);
+            }
+            else
+            {
+              // If the object is not supposed to be new, it is bad that we did not find
one.
+              if (!isNew)
+                throw new ManifoldCFException("Authority connection '"+object.getName()+"'
no longer exists");
+              isCreated = true;
+              // Insert
+              values.put(nameField,object.getName());
+              // We only need the general key because this is new.
+              performInsert(values,null);
+            }
+
+            cacheManager.invalidateKeys(ch);
+            return isCreated;
+          }
+          catch (ManifoldCFException e)
+          {
+            signalRollback();
+            throw e;
+          }
+          catch (Error e)
+          {
+            signalRollback();
+            throw e;
+          }
+          finally
+          {
+            endTransaction();
+          }
         }
-        else
+        finally
         {
-          isCreated = true;
-          // Insert
-          values.put(nameField,object.getName());
-          // We only need the general key because this is new.
-          performInsert(values,null);
+          cacheManager.leaveCache(ch);
         }
-
-        cacheManager.invalidateKeys(ch);
-        return isCreated;
       }
       catch (ManifoldCFException e)
       {
-        signalRollback();
-        throw e;
-      }
-      catch (Error e)
-      {
-        signalRollback();
-        throw e;
-      }
-      finally
-      {
-        endTransaction();
+        // Is this a deadlock exception?  If so, we want to try again.
+        if (e.getErrorCode() != ManifoldCFException.DATABASE_TRANSACTION_ABORT)
+          throw e;
+        try
+        {
+          ManifoldCF.sleep((long)(random.nextDouble() * 60000.0 + 500.0));
+        }
+        catch (InterruptedException e2)
+        {
+          throw new ManifoldCFException(e2.getMessage(),e2,ManifoldCFException.INTERRUPTED);
+        }
       }
     }
-    finally
-    {
-      cacheManager.leaveCache(ch);
-    }
   }
 
   /** Delete a repository connection.
@@ -443,7 +472,7 @@ public class AuthorityConnectionManager 
     }
   }
 
-  /** Read a chunk of repository connections.
+  /** Read a chunk of authority connections.
   *@param rval is the place to put the read policies.
   *@param returnIndex is a map from the object id (resource id) and the rval index.
   *@param idList is the list of id's.
@@ -462,6 +491,7 @@ public class AuthorityConnectionManager 
       String name = row.getValue(nameField).toString();
       int index = ((Integer)returnIndex.get(name)).intValue();
       AuthorityConnection rc = new AuthorityConnection();
+      rc.setIsNew(false);
       rc.setName(name);
       rc.setDescription((String)row.getValue(descriptionField));
       rc.setClassName((String)row.getValue(classNameField));

Modified: incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/authorities/interfaces/IAuthorityConnection.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/authorities/interfaces/IAuthorityConnection.java?rev=1005096&r1=1005095&r2=1005096&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/authorities/interfaces/IAuthorityConnection.java
(original)
+++ incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/authorities/interfaces/IAuthorityConnection.java
Wed Oct  6 16:06:41 2010
@@ -25,6 +25,16 @@ import java.util.*;
 */
 public interface IAuthorityConnection
 {
+  /** Set 'isnew' condition.
+  *@param isnew true if this is a new instance.
+  */
+  public void setIsNew(boolean isnew);
+  
+  /** Get 'isnew' condition.
+  *@return true if this is a new connection, false otherwise.
+  */
+  public boolean getIsNew();
+
   /** Set name.
   *@param name is the name.
   */

Modified: incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/interfaces/IRepositoryConnection.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/interfaces/IRepositoryConnection.java?rev=1005096&r1=1005095&r2=1005096&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/interfaces/IRepositoryConnection.java
(original)
+++ incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/interfaces/IRepositoryConnection.java
Wed Oct  6 16:06:41 2010
@@ -28,6 +28,16 @@ public interface IRepositoryConnection
 {
   public static final String _rcsid = "@(#)$Id: IRepositoryConnection.java 988245 2010-08-23
18:39:35Z kwright $";
 
+  /** Set 'isnew' condition.
+  *@param isnew true if this is a new instance.
+  */
+  public void setIsNew(boolean isnew);
+  
+  /** Get 'isnew' condition.
+  *@return true if this is a new connection, false otherwise.
+  */
+  public boolean getIsNew();
+
   /** Set name.
   *@param name is the name.
   */

Modified: incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/repository/RepositoryConnection.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/repository/RepositoryConnection.java?rev=1005096&r1=1005095&r2=1005096&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/repository/RepositoryConnection.java
(original)
+++ incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/repository/RepositoryConnection.java
Wed Oct  6 16:06:41 2010
@@ -30,6 +30,7 @@ public class RepositoryConnection implem
   public static final String _rcsid = "@(#)$Id: RepositoryConnection.java 988245 2010-08-23
18:39:35Z kwright $";
 
   // data
+  protected boolean isNew = true;
   protected String name = null;
   protected String description = null;
   protected String className = null;
@@ -52,6 +53,7 @@ public class RepositoryConnection implem
   public RepositoryConnection duplicate()
   {
     RepositoryConnection rval = new RepositoryConnection();
+    rval.isNew = isNew;
     rval.name = name;
     rval.description = description;
     rval.className = className;
@@ -68,6 +70,22 @@ public class RepositoryConnection implem
     return rval;
   }
 
+  /** Set 'isnew' condition.
+  *@param isnew true if this is a new instance.
+  */
+  public void setIsNew(boolean isnew)
+  {
+    this.isNew = isnew;
+  }
+  
+  /** Get 'isnew' condition.
+  *@return true if this is a new connection, false otherwise.
+  */
+  public boolean getIsNew()
+  {
+    return isNew;
+  }
+
   /** Set name.
   *@param name is the name.
   */

Modified: incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/repository/RepositoryConnectionManager.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/repository/RepositoryConnectionManager.java?rev=1005096&r1=1005095&r2=1005096&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/repository/RepositoryConnectionManager.java
(original)
+++ incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/repository/RepositoryConnectionManager.java
Wed Oct  6 16:06:41 2010
@@ -46,6 +46,8 @@ public class RepositoryConnectionManager
   protected final static String maxCountField = "maxcount";
   protected final static String configField = "configxml";
 
+  protected static Random random = new Random();
+
   // Handle for repository history manager
   protected RepositoryHistoryManager historyManager;
   // Handle for throttle spec storage
@@ -300,85 +302,113 @@ public class RepositoryConnectionManager
     ssb.add(getRepositoryConnectionsKey());
     ssb.add(getRepositoryConnectionKey(object.getName()));
     StringSet cacheKeys = new StringSet(ssb);
-    ICacheHandle ch = cacheManager.enterCache(null,cacheKeys,getTransactionID());
-    try
+    while (true)
     {
-      beginTransaction();
+      // Catch deadlock condition
       try
       {
-        performLock();
-        // Notify of a change to the configuration
-        ManifoldCF.noteConfigurationChange();
-        // See whether the instance exists
-        ArrayList params = new ArrayList();
-        params.add(object.getName());
-        IResultSet set = performQuery("SELECT * FROM "+getTableName()+" WHERE "+
-          nameField+"=? FOR UPDATE",params,null,null);
-        HashMap values = new HashMap();
-        values.put(descriptionField,object.getDescription());
-        values.put(classNameField,object.getClassName());
-        values.put(authorityNameField,object.getACLAuthority());
-        values.put(maxCountField,new Long((long)object.getMaxConnections()));
-        String configXML = object.getConfigParams().toXML();
-        values.put(configField,configXML);
-        boolean notificationNeeded = false;
-        boolean isCreated;
-        
-        if (set.getRowCount() > 0)
+        ICacheHandle ch = cacheManager.enterCache(null,cacheKeys,getTransactionID());
+        try
         {
-          isCreated = false;
-          IResultRow row = set.getRow(0);
-          String oldXML = (String)row.getValue(configField);
-          if (oldXML == null || !oldXML.equals(configXML))
-            notificationNeeded = true;
-          
-          // Update
-          params.clear();
-          params.add(object.getName());
-          performUpdate(values," WHERE "+nameField+"=?",params,null);
-          throttleSpecManager.deleteRows(object.getName());
+          beginTransaction();
+          try
+          {
+            performLock();
+            // Notify of a change to the configuration
+            ManifoldCF.noteConfigurationChange();
+            boolean isNew = object.getIsNew();
+            // See whether the instance exists
+            ArrayList params = new ArrayList();
+            params.add(object.getName());
+            IResultSet set = performQuery("SELECT * FROM "+getTableName()+" WHERE "+
+              nameField+"=? FOR UPDATE",params,null,null);
+            HashMap values = new HashMap();
+            values.put(descriptionField,object.getDescription());
+            values.put(classNameField,object.getClassName());
+            values.put(authorityNameField,object.getACLAuthority());
+            values.put(maxCountField,new Long((long)object.getMaxConnections()));
+            String configXML = object.getConfigParams().toXML();
+            values.put(configField,configXML);
+            boolean notificationNeeded = false;
+            boolean isCreated;
+            
+            if (set.getRowCount() > 0)
+            {
+              // If the object is supposedly new, it is bad that we found one that already
exists.
+              if (isNew)
+                throw new ManifoldCFException("Repository connection '"+object.getName()+"'
already exists");
+              isCreated = false;
+              IResultRow row = set.getRow(0);
+              String oldXML = (String)row.getValue(configField);
+              if (oldXML == null || !oldXML.equals(configXML))
+                notificationNeeded = true;
+              
+              // Update
+              params.clear();
+              params.add(object.getName());
+              performUpdate(values," WHERE "+nameField+"=?",params,null);
+              throttleSpecManager.deleteRows(object.getName());
+            }
+            else
+            {
+              // If the object is not supposed to be new, it is bad that we did not find
one.
+              if (!isNew)
+                throw new ManifoldCFException("Repository connection '"+object.getName()+"'
no longer exists");
+              isCreated = true;
+              // Insert
+              values.put(nameField,object.getName());
+              // We only need the general key because this is new.
+              performInsert(values,null);
+            }
+
+            // Write secondary table stuff
+            throttleSpecManager.writeRows(object.getName(),object);
+
+            // If notification required, do it.
+            if (notificationNeeded)
+            {
+              IJobManager jobManager = JobManagerFactory.make(threadContext);
+              jobManager.noteConnectionChange(object.getName());
+            }
+
+            cacheManager.invalidateKeys(ch);
+            return isCreated;
+          }
+          catch (ManifoldCFException e)
+          {
+            signalRollback();
+            throw e;
+          }
+          catch (Error e)
+          {
+            signalRollback();
+            throw e;
+          }
+          finally
+          {
+            endTransaction();
+          }
         }
-        else
+        finally
         {
-          isCreated = true;
-          // Insert
-          values.put(nameField,object.getName());
-          // We only need the general key because this is new.
-          performInsert(values,null);
+          cacheManager.leaveCache(ch);
         }
-
-        // Write secondary table stuff
-        throttleSpecManager.writeRows(object.getName(),object);
-
-        // If notification required, do it.
-        if (notificationNeeded)
-        {
-          IJobManager jobManager = JobManagerFactory.make(threadContext);
-          jobManager.noteConnectionChange(object.getName());
-        }
-
-        cacheManager.invalidateKeys(ch);
-        return isCreated;
       }
       catch (ManifoldCFException e)
       {
-        signalRollback();
-        throw e;
-      }
-      catch (Error e)
-      {
-        signalRollback();
-        throw e;
-      }
-      finally
-      {
-        endTransaction();
+        // Is this a deadlock exception?  If so, we want to try again.
+        if (e.getErrorCode() != ManifoldCFException.DATABASE_TRANSACTION_ABORT)
+          throw e;
+        try
+        {
+          ManifoldCF.sleep((long)(random.nextDouble() * 60000.0 + 500.0));
+        }
+        catch (InterruptedException e2)
+        {
+          throw new ManifoldCFException(e2.getMessage(),e2,ManifoldCFException.INTERRUPTED);
+        }
       }
     }
-    finally
-    {
-      cacheManager.leaveCache(ch);
-    }
   }
 
   /** Delete a repository connection.
@@ -775,6 +805,7 @@ public class RepositoryConnectionManager
       String name = row.getValue(nameField).toString();
       int index = ((Integer)returnIndex.get(name)).intValue();
       RepositoryConnection rc = new RepositoryConnection();
+      rc.setIsNew(false);
       rc.setName(name);
       rc.setDescription((String)row.getValue(descriptionField));
       rc.setClassName((String)row.getValue(classNameField));

Modified: incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/ManifoldCF.java
URL: http://svn.apache.org/viewvc/incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/ManifoldCF.java?rev=1005096&r1=1005095&r2=1005096&view=diff
==============================================================================
--- incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/ManifoldCF.java
(original)
+++ incubator/lcf/trunk/modules/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/ManifoldCF.java
Wed Oct  6 16:06:41 2010
@@ -2573,6 +2573,7 @@ public class ManifoldCF extends org.apac
   
   // Connection API
   
+  protected static final String CONNECTIONNODE_ISNEW = "isnew";
   protected static final String CONNECTIONNODE_NAME = "name";
   protected static final String CONNECTIONNODE_CLASSNAME = "class_name";
   protected static final String CONNECTIONNODE_MAXCONNECTIONS = "max_connections";
@@ -2597,7 +2598,13 @@ public class ManifoldCF extends org.apac
     {
       ConfigurationNode child = connectionNode.findChild(i++);
       String childType = child.getType();
-      if (childType.equals(CONNECTIONNODE_NAME))
+      if (childType.equals(CONNECTIONNODE_ISNEW))
+      {
+        if (child.getValue() == null)
+          throw new ManifoldCFException("Connection isnew node requires a value");
+        connection.setIsNew(child.getValue().equals("true"));
+      }
+      else if (childType.equals(CONNECTIONNODE_NAME))
       {
         if (child.getValue() == null)
           throw new ManifoldCFException("Connection name node requires a value");
@@ -2656,7 +2663,11 @@ public class ManifoldCF extends org.apac
   {
     ConfigurationNode child;
     int j;
-    
+
+    child = new ConfigurationNode(CONNECTIONNODE_ISNEW);
+    child.setValue(connection.getIsNew()?"true":"false");
+    connectionNode.addChild(connectionNode.getChildCount(),child);
+
     child = new ConfigurationNode(CONNECTIONNODE_NAME);
     child.setValue(connection.getName());
     connectionNode.addChild(connectionNode.getChildCount(),child);
@@ -2701,7 +2712,13 @@ public class ManifoldCF extends org.apac
     {
       ConfigurationNode child = connectionNode.findChild(i++);
       String childType = child.getType();
-      if (childType.equals(CONNECTIONNODE_NAME))
+      if (childType.equals(CONNECTIONNODE_ISNEW))
+      {
+        if (child.getValue() == null)
+          throw new ManifoldCFException("Connection isnew node requires a value");
+        connection.setIsNew(child.getValue().equals("true"));
+      }
+      else if (childType.equals(CONNECTIONNODE_NAME))
       {
         if (child.getValue() == null)
           throw new ManifoldCFException("Connection name node requires a value");
@@ -2761,6 +2778,10 @@ public class ManifoldCF extends org.apac
     ConfigurationNode child;
     int j;
     
+    child = new ConfigurationNode(CONNECTIONNODE_ISNEW);
+    child.setValue(connection.getIsNew()?"true":"false");
+    connectionNode.addChild(connectionNode.getChildCount(),child);
+
     child = new ConfigurationNode(CONNECTIONNODE_NAME);
     child.setValue(connection.getName());
     connectionNode.addChild(connectionNode.getChildCount(),child);
@@ -2805,7 +2826,13 @@ public class ManifoldCF extends org.apac
     {
       ConfigurationNode child = connectionNode.findChild(i++);
       String childType = child.getType();
-      if (childType.equals(CONNECTIONNODE_NAME))
+      if (childType.equals(CONNECTIONNODE_ISNEW))
+      {
+        if (child.getValue() == null)
+          throw new ManifoldCFException("Connection isnew node requires a value");
+        connection.setIsNew(child.getValue().equals("true"));
+      }
+      else if (childType.equals(CONNECTIONNODE_NAME))
       {
         if (child.getValue() == null)
           throw new ManifoldCFException("Connection name node requires a value");
@@ -2902,7 +2929,11 @@ public class ManifoldCF extends org.apac
   {
     ConfigurationNode child;
     int j;
-    
+
+    child = new ConfigurationNode(CONNECTIONNODE_ISNEW);
+    child.setValue(connection.getIsNew()?"true":"false");
+    connectionNode.addChild(connectionNode.getChildCount(),child);
+
     child = new ConfigurationNode(CONNECTIONNODE_NAME);
     child.setValue(connection.getName());
     connectionNode.addChild(connectionNode.getChildCount(),child);



Mime
View raw message