rolesQuery="select r.rolename, 'Role' from roles as r, accounts_roles as ar where ar.user_id=? and ar.role_id=r.csid"\r
tenantsQueryWithDisabled="select t.id, t.name, 'Tenants' from accounts_common as a, accounts_tenants as at, tenants as t where a.userid=? and a.csid = at.TENANTS_ACCOUNTSCOMMON_CSID and at.tenant_id = t.id"\r
tenantsQueryNoDisabled="select t.id, t.name, 'Tenants' from accounts_common as a, accounts_tenants as at, tenants as t where a.userid=? and a.csid = at.TENANTS_ACCOUNTSCOMMON_CSID and at.tenant_id = t.id and NOT t.disabled"\r
- maxRetrySeconds="5"\r
+ maxRetrySeconds="5000"\r
delayBetweenAttemptsMillis="200"\r
debug=true;\r
};\r
rolesQuery="select r.rolename, 'Role' from roles as r, accounts_roles as ar where ar.user_id=? and ar.role_id=r.csid"\r
tenantsQueryWithDisabled="select t.id, t.name, 'Tenants' from accounts_common as a, accounts_tenants as at, tenants as t where a.userid=? and a.csid = at.TENANTS_ACCOUNTSCOMMON_CSID and at.tenant_id = t.id"\r
tenantsQueryNoDisabled="select t.id, t.name, 'Tenants' from accounts_common as a, accounts_tenants as at, tenants as t where a.userid=? and a.csid = at.TENANTS_ACCOUNTSCOMMON_CSID and at.tenant_id = t.id and NOT t.disabled"\r
- maxRetrySeconds="5"\r
+ maxRetrySeconds="5000"\r
delayBetweenAttemptsMillis="200"\r
debug=true;\r
};\r
<filter-class>org.collectionspace.services.common.NetworkErrorRetryFilter</filter-class>\r
<init-param>\r
<param-name>maxRetrySeconds</param-name>\r
- <param-value>5</param-value>\r
+ <param-value>5000</param-value>\r
</init-param>\r
<init-param>\r
<param-name>delayBetweenAttemptsMillis</param-name>\r
import org.collectionspace.services.client.IQueryManager;
import org.collectionspace.services.client.PoxPayloadIn;
import org.collectionspace.services.client.PoxPayloadOut;
-
import org.collectionspace.services.common.UriTemplateRegistry;
import org.collectionspace.services.common.api.RefName;
import org.collectionspace.services.common.api.Tools;
import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema;
import org.collectionspace.services.common.vocabulary.AuthorityResource;
import org.collectionspace.services.common.vocabulary.RefNameServiceUtils;
-
import org.collectionspace.services.config.service.ListResultField;
import org.collectionspace.services.config.service.ObjectPartType;
-
import org.collectionspace.services.nuxeo.client.java.DocHandlerBase;
+import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentException;
import org.collectionspace.services.nuxeo.client.java.RepositoryJavaClientImpl;
import org.collectionspace.services.nuxeo.util.NuxeoUtils;
-
import org.collectionspace.services.relation.RelationsCommonList;
import org.collectionspace.services.relation.RelationsDocListItem;
-
import org.collectionspace.services.vocabulary.VocabularyItemJAXBSchema;
-
import org.nuxeo.ecm.core.api.ClientException;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.model.PropertyException;
import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Override
protected Object getListResultValue(DocumentModel docModel, // REM - CSPACE-5133
- String schema, ListResultField field) {
+ String schema, ListResultField field) throws DocumentException {
Object result = null;
result = NuxeoUtils.getXPathValue(docModel, schema, field.getXpath());
<version>6.0.33</version>\r
<scope>provided</scope>\r
</dependency>\r
+ <dependency>\r
+ <groupId>org.apache.tomcat</groupId>\r
+ <artifactId>catalina</artifactId>\r
+ <version>6.0.33</version>\r
+ <scope>provided</scope>\r
+ </dependency>\r
\r
<!-- javax -->\r
<dependency>\r
Throwable cause = exceptionChain;
while (cause != null) {
- if (isExceptionNetworkRelated(cause) == true) {
+ if (cause instanceof DocumentException) {
+ if (((DocumentException)cause).exceptionChainContainsNetworkError() == true) { // org.collectionspace.services.common.document.DocumentException (and subclasses) are a special case
+ result = true;
+ break;
+ }
+ } else if (isExceptionNetworkRelated(cause) == true) {
result = true;
break;
}
- Throwable nextCause = cause.getCause();
- if (nextCause == null) {
- // Since we reached the end of the exception chain, we can see if the last code
- // executed was network related.
- StackTraceElement[] finalStackTrace = cause.getStackTrace();
- }
+ cause = cause.getCause();
}
return result;
}
- private static boolean isStackTraceNetworkRelated(StackTraceElement[] stackTraceElementList) {
+ //
+ // We're using this method to try and figure out if the the exception is network related. Ideally,
+ // the exception's class name contains "java.net". Unfortunately, Nuxeo consumes some of these exceptions and
+ // returns a more general "java.sql" exception so we need to check for that as well.
+ //
+ public static boolean isExceptionNetworkRelated(String exceptionClassName) {
boolean result = false;
- for (StackTraceElement stackTraceElement : stackTraceElementList) {
- if (stackTraceElement.getClassName().contains("") == true) {
-
+ if (exceptionClassName != null) {
+ if (exceptionClassName.contains("java.net")) {
+ result = true;
+ } else if (exceptionClassName.contains("java.sql")) {
+ result = true;
}
}
return result;
}
-
+
/*
* Return 'true' if the exception is in the "java.net" package.
*/
- private static boolean isExceptionNetworkRelated(Throwable cause) {
+ public static boolean isExceptionNetworkRelated(Throwable exception) {
boolean result = false;
-
- if (cause != null) {
- String className = cause.getClass().getCanonicalName();
- if (cause instanceof DocumentException) {
- className = ((DocumentException) cause).getCausesClassName(); // Since Nuxeo wraps the real exception, we needed to create this special getCausesClassName() method -see NuxeoDocumentException for details
- }
- if (className != null && className.contains("java.net") == true) {
- result = true;
- }
+
+ if (exception != null) {
+ String className = exception.getClass().getCanonicalName();
+ result = isExceptionNetworkRelated(className);
}
return result;
package org.collectionspace.services.common;
import java.io.IOException;
+import java.lang.reflect.Field;
import java.net.ConnectException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
+import org.apache.catalina.connector.CoyoteInputStream;
+import org.apache.catalina.connector.InputBuffer;
import org.collectionspace.services.common.CSWebApplicationException;
import org.collectionspace.services.common.ServletTools;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
}
}
}
-
+
//
// This method will attempt to repeat the chain.doFilter() method if it fails because of a
// network related reason. It looks for failures in two ways:
/**
* Creates the CMIS query from the service context. Each document handler is responsible for returning a valid CMIS query using the
* information in the current service context -which includes things like the query parameters, etc.
+ * @throws DocumentException
*/
@Override
- public String getCMISQuery(QueryContext queryContext) {
+ public String getCMISQuery(QueryContext queryContext) throws DocumentException {
//
// By default, return nothing. Child classes can override if they want.
//
import javax.persistence.RollbackException;
+import org.collectionspace.services.common.CSWebApplicationException;
import org.collectionspace.services.common.ServiceException;
/**
public DocumentException(Throwable cause) {
super(cause);
}
-
- public String getCausesClassName() {
- String result = null;
+
+ public boolean exceptionChainContainsNetworkError() {
+ boolean result = false;
- Throwable cause = super.getCause();
- if (cause != null) {
- result = cause.getClass().getCanonicalName();
+ Throwable cause = this;
+ while (cause != null) {
+ if (CSWebApplicationException.isExceptionNetworkRelated(cause) == true) {
+ result = true;
+ break;
+ }
+
+ cause = cause.getCause();
}
-
+
return result;
}
-
}
/**
* Creates the CMIS query from the service context. Each document handler is responsible for returning a valid CMIS query using the
* information in the current service context -which includes things like the query parameters, etc.
+ * @throws DocumentException
*/
- public String getCMISQuery(QueryContext queryContext);
+ public String getCMISQuery(QueryContext queryContext) throws DocumentException;
/**
* Returns TRUE if a CMIS query should be used (instead of an NXQL query)
import org.collectionspace.services.common.authorityref.AuthorityRefList;
import org.collectionspace.services.common.context.ServiceContext;
import org.collectionspace.services.common.document.AbstractMultipartDocumentHandlerImpl;
+import org.collectionspace.services.common.document.DocumentException;
import org.collectionspace.services.common.document.DocumentFilter;
import org.collectionspace.services.common.document.DocumentWrapper;
import org.collectionspace.services.common.document.DocumentWrapperImpl;
import org.collectionspace.services.lifecycle.TransitionDef;
import org.collectionspace.services.lifecycle.TransitionDefList;
import org.collectionspace.services.lifecycle.TransitionList;
-
import org.nuxeo.ecm.core.NXCore;
import org.nuxeo.ecm.core.api.ClientException;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.model.PropertyException;
import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
import org.nuxeo.ecm.core.lifecycle.LifeCycleService;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
* 1. Document 'B' is the subject of the relationship
* 2. Document 'B' is the object of the relationship
* 3. Document 'B' is either the object or the subject of the relationship
+ * @throws DocumentException
*/
@Override
- public String getCMISQuery(QueryContext queryContext) {
+ public String getCMISQuery(QueryContext queryContext) throws DocumentException {
String result = null;
if (isCMISQuery() == true) {
package org.collectionspace.services.nuxeo.client.java;
+import org.collectionspace.services.common.CSWebApplicationException;
import org.collectionspace.services.common.document.DocumentException;
import org.nuxeo.ecm.core.api.WrappedException;
// TODO Auto-generated constructor stub
}
- @Override
- public String getCausesClassName() {
+ private static String getExceptionClassName(Throwable exception) {
String result = null;
- Throwable cause = super.getCause();
- if (cause != null && cause instanceof WrappedException) {
- WrappedException wrappedException = (WrappedException)cause;
- result = wrappedException.getClassName();
- } else {
- result = cause != null ? super.getCausesClassName() : null;
+ if (exception != null) {
+ result = exception.getClass().getCanonicalName();
+ if (exception instanceof WrappedException) {
+ result = ((WrappedException)exception).getClassName(); // Nuxeo wraps the original exception, so we need to get the name of it.
+ }
}
return result;
}
-
- protected boolean isNuxeoWrappedException(Throwable cause) {
+
+ @Override
+ public boolean exceptionChainContainsNetworkError() {
boolean result = false;
- String className = cause.getClass().getCanonicalName();
- if (className.contains("org.nuxeo.ecm.core.api.WrappedException") == true) {
- result = true;
+ Throwable cause = this;
+ while (cause != null) {
+ String exceptionClassName = getExceptionClassName(cause);
+ if (CSWebApplicationException.isExceptionNetworkRelated(exceptionClassName) == true) {
+ result = true;
+ break;
+ }
+
+ cause = cause.getCause();
}
-
+
return result;
}
* @param schema The name of the schema (part)
* @param xpath The XPath expression (without schema prefix)
* @return value the indicated property value as a String
+ * @throws DocumentException
*/
protected Object getListResultValue(DocumentModel docModel, // REM - CSPACE-5133
- String schema, ListResultField field) {
+ String schema, ListResultField field) throws DocumentException {
Object result = null;
result = NuxeoUtils.getXPathValue(docModel, schema, field.getXpath());
}
protected String getStringValue(DocumentModel docModel,
- String schema, ListResultField field) {
+ String schema, ListResultField field) throws DocumentException {
String result = null;
Object value = getListResultValue(docModel, schema, field);
import java.util.UUID;
import javax.sql.rowset.CachedRowSet;
-import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MultivaluedMap;
import org.collectionspace.services.client.CollectionSpaceClient;
/*
* See CSPACE-5036 - How to make CMISQL queries from Nuxeo
*/
- private IterableQueryResult makeCMISQLQuery(RepositoryInstance repoSession, String query, QueryContext queryContext) {
+ private IterableQueryResult makeCMISQLQuery(RepositoryInstance repoSession, String query, QueryContext queryContext) throws DocumentException {
IterableQueryResult result = null;
// the NuxeoRepository should be constructed only once, then cached
} catch (ClientException e) {
// TODO Auto-generated catch block
logger.error("Encounter trouble making the following CMIS query: " + query, e);
+ throw new NuxeoDocumentException(e);
}
return result;
Collections.sort(result, new Comparator<DocumentModel>() {
@Override
public int compare(DocumentModel doc1, DocumentModel doc2) {
- String termDisplayName1 = (String) NuxeoUtils.getXPathValue(doc1, COMMON_PART_SCHEMA, DISPLAY_NAME_XPATH);
- String termDisplayName2 = (String) NuxeoUtils.getXPathValue(doc2, COMMON_PART_SCHEMA, DISPLAY_NAME_XPATH);
+ String termDisplayName1 = null;
+ String termDisplayName2 = null;
+ try {
+ termDisplayName1 = (String) NuxeoUtils.getXPathValue(doc1, COMMON_PART_SCHEMA, DISPLAY_NAME_XPATH);
+ termDisplayName2 = (String) NuxeoUtils.getXPathValue(doc2, COMMON_PART_SCHEMA, DISPLAY_NAME_XPATH);
+ } catch (NuxeoDocumentException e) {
+ throw new RuntimeException(e); // We need to throw a RuntimeException because the compare() method of the Comparator interface does not support throwing an Exception
+ }
return termDisplayName1.compareToIgnoreCase(termDisplayName2);
}
});
import java.io.IOException;
import java.io.File;
import java.lang.reflect.Field;
-
-import java.util.GregorianCalendar;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import org.collectionspace.services.client.IQueryManager;
import org.collectionspace.services.client.PoxPayloadIn;
import org.collectionspace.services.client.PoxPayloadOut;
-import org.collectionspace.services.common.api.GregorianCalendarDateTimeUtils;
import org.collectionspace.services.common.api.Tools;
import org.collectionspace.services.common.context.ServiceBindingUtils;
import org.collectionspace.services.common.context.ServiceContext;
-import org.collectionspace.services.common.datetime.DateTimeFormatUtils;
import org.collectionspace.services.common.document.DocumentException;
import org.collectionspace.services.common.document.DocumentFilter;
import org.collectionspace.services.common.document.DocumentUtils;
import org.collectionspace.services.common.query.QueryContext;
+import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentException;
import org.dom4j.Document;
import org.dom4j.io.SAXReader;
import org.nuxeo.ecm.core.api.ClientException;
import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
import org.nuxeo.ecm.core.api.Blob;
+import org.nuxeo.ecm.core.api.ConnectionException;
import org.nuxeo.ecm.core.api.CoreSession;
import org.nuxeo.ecm.core.api.DocumentRef;
import org.nuxeo.ecm.core.api.IdRef;
import org.nuxeo.ecm.core.api.PathRef;
import org.nuxeo.ecm.core.api.model.PropertyException;
-
import org.nuxeo.ecm.core.io.DocumentPipe;
import org.nuxeo.ecm.core.io.DocumentReader;
import org.nuxeo.ecm.core.io.DocumentWriter;
import org.nuxeo.ecm.core.io.impl.DocumentPipeImpl;
import org.nuxeo.ecm.core.io.impl.plugins.SingleDocumentReader;
import org.nuxeo.ecm.core.io.impl.plugins.XMLDocumentWriter;
-
import org.nuxeo.ecm.core.schema.SchemaManager;
import org.nuxeo.ecm.core.search.api.client.querymodel.descriptor.QueryModelDescriptor;
import org.nuxeo.ecm.core.storage.sql.Binary;
import org.nuxeo.ecm.core.storage.sql.coremodel.SQLBlob;
import org.nuxeo.runtime.api.Framework;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
bais = new ByteArrayInputStream(baos.toByteArray());
SAXReader saxReader = new SAXReader();
doc = saxReader.read(bais);
+ } catch (ClientException ce) {
+ throw new NuxeoDocumentException(ce);
} catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.debug("Caught exception while processing document ", e);
DocumentRef documentRef = new IdRef(nuxeoId);
result = repoSession.getDocument(documentRef);
} catch (ClientException e) {
- e.printStackTrace();
+ throw new NuxeoDocumentException(e);
}
return result;
return result;
}
- public static String getTenantQualifiedDocType(ServiceContext ctx) {
+ public static String getTenantQualifiedDocType(ServiceContext ctx) throws NuxeoDocumentException {
String result = null;
+
try {
- String docType = ctx.getDocumentType();
- result = getTenantQualifiedDocType(ctx, docType);
+ String docType = ctx.getDocumentType();
+ result = getTenantQualifiedDocType(ctx, docType);
} catch (Exception e) {
- logger.error("Could not get tentant qualified doctype.", e);
+ throw new NuxeoDocumentException(e);
}
+
return result;
}
public static String getTenantQualifiedDocType(QueryContext queryCtx, String docType) throws Exception {
String result = docType;
- String tenantQualifiedDocType = queryCtx.getTenantQualifiedDoctype();
- if (docTypeExists(tenantQualifiedDocType) == true) {
- result = tenantQualifiedDocType;
- }
+ try {
+ String tenantQualifiedDocType = queryCtx.getTenantQualifiedDoctype();
+ if (docTypeExists(tenantQualifiedDocType) == true) {
+ result = tenantQualifiedDocType;
+ }
+ } catch (ClientException ce) {
+ throw new NuxeoDocumentException(ce);
+ }
return result;
}
SchemaManager schemaManager = null;
try {
schemaManager = Framework.getService(org.nuxeo.ecm.core.schema.SchemaManager.class);
+ } catch (ClientException ce) {
+ throw new NuxeoDocumentException(ce);
} catch (Exception e1) {
// TODO Auto-generated catch block
logger.error("Could not get Nuxeo SchemaManager instance.", e1);
throw e1;
}
+
Set<String> docTypes = schemaManager.getDocumentTypeNamesExtending(docType);
if (docTypes != null && docTypes.contains(docType)) {
result = true;
* @return value the indicated property value as a String
*/
public static Object getXPathValue(DocumentModel docModel,
- String schema, String xpath) {
+ String schema, String xpath) throws NuxeoDocumentException {
Object result = null;
xpath = schema + ":" + xpath;
returnVal = DocumentUtils.propertyValueAsString(value, docModel, xpath);
}
result = returnVal;
- } catch (PropertyException pe) {
- throw new RuntimeException("Problem retrieving property {" + xpath
- + "}. Bad XPath spec?" + pe.getLocalizedMessage());
+ } catch (ClientException ce) {
+ String msg = "Unknown Nuxeo client exception.";
+ if (ce instanceof PropertyException) {
+ msg = "Problem retrieving property {" + xpath + "}. Bad XPath spec?" + ce.getLocalizedMessage();
+ }
+ throw new NuxeoDocumentException(msg, ce); // We need to wrap this exception in order to retry failed requests caused by network errors
} catch (ClassCastException cce) {
- throw new RuntimeException("Problem retrieving property {" + xpath
+ throw new ClassCastException("Problem retrieving property {" + xpath
+ "} as String. Not a String property?"
+ cce.getLocalizedMessage());
} catch (IndexOutOfBoundsException ioobe) {
}
// Otherwise, e.g., for true OOB indices, propagate the exception.
if (result == null) {
- throw new RuntimeException("Problem retrieving property {" + xpath
+ throw new IndexOutOfBoundsException("Problem retrieving property {" + xpath
+ "}:" + ioobe.getLocalizedMessage());
}
- } catch (Exception e) {
- throw new RuntimeException("Unknown problem retrieving property {"
- + xpath + "}." + e.getLocalizedMessage());
}
return result;