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);
|