]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
PAHMA-963-REM-A: Adding code to look into Nuxeo's wrapped exceptions for network...
authorRichard Millet <remillet@berkeley.edu>
Mon, 10 Feb 2014 18:05:21 +0000 (10:05 -0800)
committerRichard Millet <remillet@berkeley.edu>
Mon, 10 Feb 2014 18:05:21 +0000 (10:05 -0800)
22 files changed:
build.properties
services/JaxRsServiceProvider/src/main/java/org/collectionspace/services/jaxrs/CollectionSpaceJaxRsApplication.java
services/JaxRsServiceProvider/src/main/resources/log4j.properties
services/JaxRsServiceProvider/src/main/webapp/WEB-INF/login.conf
services/JaxRsServiceProvider/src/main/webapp/WEB-INF/web.xml
services/authentication/service/src/main/java/org/collectionspace/authentication/jaas/CSpaceJBossDBLoginModule.java
services/authentication/service/src/main/java/org/collectionspace/authentication/realm/db/CSpaceDbRealm.java
services/authentication/service/src/main/java/org/collectionspace/authentication/spring/CSpaceAuthorityGranter.java
services/authentication/service/src/main/resources/config/jboss-login-config.xml [deleted file]
services/authentication/service/src/main/resources/config/login-config.xml [deleted file]
services/authorization/service/src/main/java/org/collectionspace/services/authorization/spring/SpringPermissionEvaluator.java
services/common/src/main/java/org/collectionspace/services/common/CSWebApplicationException.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/NetworkErrorRetryFilter.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/document/DocumentException.java
services/common/src/main/java/org/collectionspace/services/common/profile/CSpaceFilter.java
services/common/src/main/java/org/collectionspace/services/common/query/QueryManager.java
services/common/src/main/java/org/collectionspace/services/common/query/nuxeo/QueryManagerNuxeoImpl.java
services/common/src/main/java/org/collectionspace/services/common/security/SecurityInterceptor.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoClientEmbedded.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoDocumentException.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java
services/query/service/src/main/java/org/collectionspace/services/query/QueryResource.java [deleted file]

index 245a592365d04cc3946794425c7a25f0d368b908..f50b08ab60b5e312a946213b4669faae0526a727 100644 (file)
@@ -123,6 +123,7 @@ db.cspace.user.password=${env.DB_PASSWORD_CSPACE}
 #db.host=dba-postgres-qa-21.ist.berkeley.edu\r
 #db.host=173.255.228.202\r
 db.host=169.229.248.106\r
+#db.host=localhost\r
 #db.host=169.229.199.44\r
 db.jdbc.baseurl=jdbc:${db}://${db.host}:${db.port}\r
 \r
index 956c52802806114560233dd0ac4a4a4c410432e0..f9a1c656f996c9a52b0389c9438bc98dd78dda6b 100644 (file)
@@ -51,8 +51,6 @@ import org.collectionspace.services.organization.OrgAuthorityResource;
 import org.collectionspace.services.person.PersonAuthorityResource;
 import org.collectionspace.services.citation.CitationAuthorityResource;
 
-//import org.collectionspace.services.query.QueryResource;
-
 import javax.servlet.ServletContext;
 import javax.ws.rs.core.Application;
 
@@ -130,7 +128,6 @@ public class CollectionSpaceJaxRsApplication extends Application
         /*
         singletons.add(new WorkflowResource());
         */
-//        singletons.add(new QueryResource());
 //        singletons.add(new DomainIdentifierResource());
 //        singletons.add(new PingResource());
     }
index 508a649030be0afca5b17b4583029ad3f80f088c..3677268c945655f162a7df801fc8d99e20ac6266 100644 (file)
@@ -55,6 +55,8 @@ log4j.additivity.perf.collectionspace=false
 log4j.logger.org.collectionspace=INFO\r
 log4j.logger.org.collectionspace.services.nuxeo.client.java=TRACE\r
 log4j.logger.org.collectionspace.services.common.storage.JDBCTools=ERROR\r
+log4j.logger.org.collectionspace.services.common.profile.CSpaceFilter=DEBUG\r
+\r
 #log4j.logger.org.collectionspace.services.common.vocabulary.nuxeo=TRACE\r
 \r
 #\r
index c8eddb09cf5a30011fd9ea376f26b6e249420371..bf28e215ec2c0496416891b5cf89788260dd1503 100644 (file)
@@ -8,9 +8,14 @@ CSpaceJBossDBLoginModule {
        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
+    delayBetweenAttemptsMillis="200"\r
        debug=true;\r
  };\r
  \r
+ /**\r
+ * The JAAS login configuration.\r
+ */\r
  cspace {\r
    org.collectionspace.authentication.jaas.CSpaceJBossDBLoginModule required\r
        dsJndiName="CspaceDS"\r
@@ -21,5 +26,7 @@ CSpaceJBossDBLoginModule {
        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
+    delayBetweenAttemptsMillis="200"\r
        debug=true;\r
  };\r
index e633882ce2baeafc7a57334d78e3e2acab69752f..e329897dd4805e64cf4b57ff50776315e8221092 100644 (file)
@@ -45,6 +45,9 @@
         </param-value>\r
     </context-param>\r
 \r
+    <!--\r
+       Spring Security Filter\r
+    -->\r
     <filter>\r
         <filter-name>springSecurityFilterChain</filter-name>\r
         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>\r
         <url-pattern>/*</url-pattern>\r
     </filter-mapping>\r
 \r
+       <!--\r
+       - A filter that will attempt to retry requests that fail due to network errors.\r
+       -\r
+       -               maxRetrySeconds - How long to keep retrying a request.\r
+       -               delayBetweenAttemptsMillis - How long to wait between retries.\r
+       -\r
+       -->\r
+       <filter>\r
+               <filter-name>networkErrorRetryFilter</filter-name>\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
+               </init-param>\r
+               <init-param>\r
+               <param-name>delayBetweenAttemptsMillis</param-name>\r
+               <param-value>200</param-value>\r
+               </init-param>\r
+       </filter>\r
+       \r
+       <filter-mapping>\r
+               <filter-name>networkErrorRetryFilter</filter-name>\r
+               <url-pattern>/*</url-pattern>\r
+       </filter-mapping>\r
+    \r
+       <!--\r
+               A filter that logs profiling information.\r
+        -->\r
     <filter>\r
                <filter-name>CSpaceFilter</filter-name>\r
         <filter-class>org.collectionspace.services.common.profile.CSpaceFilter</filter-class>\r
index 4a2dec8b3d25eaf2ef5ad462bef6c8a3591343a8..bc585755b1edcf185aae29d4eb461a8237e80fdf 100644 (file)
@@ -27,15 +27,14 @@ import java.util.ArrayList;
 import java.util.Collection;\r
 import java.util.List;\r
 import java.util.Map;\r
-\r
 import java.security.acl.Group;\r
+\r
 import javax.security.auth.Subject;\r
 import javax.security.auth.callback.CallbackHandler;\r
 import javax.security.auth.login.LoginException;\r
 \r
 import org.collectionspace.authentication.realm.db.CSpaceDbRealm;\r
 import org.jboss.security.auth.spi.UsernamePasswordLoginModule;\r
-\r
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
 \r
@@ -68,10 +67,26 @@ public class CSpaceJBossDBLoginModule extends UsernamePasswordLoginModule {
         realm = new CSpaceDbRealm(options);\r
     }\r
 \r
+    @Override\r
+    protected String createPasswordHash(String username, String password,\r
+            String digestOption)\r
+            throws LoginException {\r
+       String result = super.createPasswordHash(username, password, digestOption);\r
+       \r
+       if (result == null) {\r
+               String message = "Could not create a password hash for the supplied password.  Check your login.conf configuration's hash algorithm setting.";\r
+               log.error(message);\r
+               throw new LoginException(message);\r
+       }\r
+       \r
+       return result;\r
+    }\r
+    \r
     protected String getUsersPassword() throws LoginException {\r
 \r
         String username = getUsername();\r
         String password = null;\r
+        \r
         try {\r
             password = realm.getUsersPassword(username);\r
             password = convertRawPassword(password);\r
@@ -79,12 +94,15 @@ public class CSpaceJBossDBLoginModule extends UsernamePasswordLoginModule {
                logger.debug("Obtained user password for: " + username);\r
             }\r
         } catch (LoginException lex) {\r
+               log.error("Could not retrieve user password for: " + username, lex);\r
             throw lex;\r
         } catch (Exception ex) {\r
+               log.error("Could not retrieve user password for: " + username, ex);\r
             LoginException le = new LoginException("Unknown Exception");\r
             le.initCause(ex);\r
             throw le;\r
         }\r
+        \r
         return password;\r
     }\r
     \r
index aa67924f390ca432158b717e38e45944b682e13d..342ab215941045153600fc64d721916f920b3e7c 100644 (file)
@@ -50,6 +50,7 @@
 package org.collectionspace.authentication.realm.db;
 
 import java.lang.reflect.Constructor;
+import java.net.ConnectException;
 import java.security.Principal;
 import java.security.acl.Group;
 import java.sql.Connection;
@@ -70,10 +71,13 @@ import javax.sql.DataSource;
 //import org.apache.commons.logging.Log;
 //import org.apache.commons.logging.LogFactory;
 
+
+
+
+
 import org.collectionspace.authentication.AuthN;
 import org.collectionspace.authentication.CSpaceTenant;
 import org.collectionspace.authentication.realm.CSpaceRealm;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -82,8 +86,7 @@ import org.slf4j.LoggerFactory;
  * @author 
  */
 public class CSpaceDbRealm implements CSpaceRealm {
-
-    private Logger logger = LoggerFactory.getLogger(CSpaceDbRealm.class);
+       private Logger logger = LoggerFactory.getLogger(CSpaceDbRealm.class);
     
     private String datasourceName;
     private String principalsQuery;
@@ -92,6 +95,48 @@ public class CSpaceDbRealm implements CSpaceRealm {
     private String tenantsQueryWithDisabled;
     private boolean suspendResume;
 
+       private long maxRetrySeconds = MAX_RETRY_SECONDS;
+       private static final int MAX_RETRY_SECONDS = 5;
+    private static final String MAX_RETRY_SECONDS_STR = "maxRetrySeconds";
+
+       private long delayBetweenAttemptsMillis = DELAY_BETWEEN_ATTEMPTS_MILLISECONDS;
+    private static final String DELAY_BETWEEN_ATTEMPTS_MILLISECONDS_STR = "delayBetweenAttemptsMillis";
+       private static final long DELAY_BETWEEN_ATTEMPTS_MILLISECONDS = 200;
+       
+       protected void setMaxRetrySeconds(Map options) {
+               Object optionsObj = options.get(MAX_RETRY_SECONDS_STR);
+               if (optionsObj != null) {
+                       String paramValue = optionsObj.toString();
+                       try {
+                               maxRetrySeconds = Long.parseLong(paramValue);
+                       } catch (NumberFormatException e) {
+                               logger.warn(String.format("The Spring Security login authentication parameter '%s' with value '%s' could not be parsed to a long value.  The default value of '%d' will be used instead.",
+                                               MAX_RETRY_SECONDS_STR, paramValue, maxRetrySeconds));
+                       }
+               }
+       }
+       
+       protected long getMaxRetrySeconds() {
+               return this.maxRetrySeconds;
+       }
+       
+       protected void setDelayBetweenAttemptsMillis(Map options) {
+               Object optionsObj = options.get(DELAY_BETWEEN_ATTEMPTS_MILLISECONDS_STR);
+               if (optionsObj != null) {
+                       String paramValue = optionsObj.toString();
+                       try {
+                               delayBetweenAttemptsMillis = Long.parseLong(paramValue);
+                       } catch (NumberFormatException e) {
+                               logger.warn(String.format("The Spring Security login authentication parameter '%s' with value '%s' could not be parsed to a long value.  The default value of '%d' will be used instead.",
+                                               MAX_RETRY_SECONDS_STR, paramValue, delayBetweenAttemptsMillis));
+                       }
+               }
+       }
+       
+       protected long getDelayBetweenAttemptsMillis() {
+               return this.delayBetweenAttemptsMillis;
+       }
+    
     /**
      * CSpace Database Realm
      * @param datasourceName datasource name
@@ -121,6 +166,10 @@ public class CSpaceDbRealm implements CSpaceRealm {
         if (tmp != null) {
             suspendResume = Boolean.valueOf(tmp.toString()).booleanValue();
         }
+        
+        this.setMaxRetrySeconds(options);
+        this.setDelayBetweenAttemptsMillis(options);
+        
         if (logger.isTraceEnabled()) {
             logger.trace("DatabaseServerLoginModule, dsJndiName=" + datasourceName);
             logger.trace("principalsQuery=" + principalsQuery);
@@ -475,11 +524,71 @@ public class CSpaceDbRealm implements CSpaceRealm {
         return p;
     }
 
-    private Connection getConnection() throws LoginException, SQLException {
+    /*
+     * This method will attempt to get a connection.  If a network error prevents it from getting a connection on the first try
+     * it will retry for the next 'getMaxRetrySeconds()' seconds.  If it is unable to get the connection then it will timeout and
+     * throw an exception.
+     */
+    private Connection getConnection() throws Exception {
+        Connection result = null;
+               boolean failed = true;
+               Exception lastException = null;
+               int requestAttempts = 0;
+
+               long quittingTime = System.currentTimeMillis() + getMaxRetrySeconds() * 1000; // This is how long we attempt retries
+               do {
+                       if (requestAttempts > 0) {
+                               Thread.sleep(getDelayBetweenAttemptsMillis()); // Wait a little time between reattempts.
+                       }
+                       
+                       try {
+                               // proceed to the original request by calling doFilter()
+                               result = this.getConnection(getDataSourceName());
+                               if (result != null) {
+                                       failed = false;
+                                       break; // the request was successfully executed, so we can break out of this retry loop
+                               } else {
+                                       failed = true;
+                                       throw new ConnectException(); // The 'response' argument indicated a network related failure, so let's throw a generic connection exception
+                               }
+                       } catch (Exception e) {
+                               lastException = e;
+                               if (exceptionChainContainsNetworkError(lastException) == false) {
+                                       // Break if the exception chain does not contain a
+                                       // network related exception because we don't want to retry if it's not a network related failure
+                                       break;
+                               }
+                               requestAttempts++; // keep track of how many times we've tried the request
+                       }
+               } while (System.currentTimeMillis() < quittingTime);  // keep trying until we run out of time
+               
+               //
+               // Add a warning to the logs if we encountered *any* failures on our re-attempts.  Only add the warning
+               // if we were eventually successful.
+               //
+               if (requestAttempts > 0 && failed == false) {
+                       logger.warn(String.format("Request to get a connection from data source '%s' failed with exception '%s' at attempt number '%d' before finally succeeding on the next attempt.",
+                                       getDataSourceName(),
+                                       lastException.getClass().getName(),
+                                       requestAttempts));
+               }
+
+               if (failed == true) {
+                       // If we get here, it means all of our attempts to get a successful call to chain.doFilter() have failed.
+                       throw lastException;
+               }
+               
+               return result;
+       }
+    
+       /*
+        * Don't call this method directly.  Instead, use the getConnection() method that take no arguments.
+        */
+       private Connection getConnection(String dataSourceName) throws LoginException, SQLException {
         InitialContext ctx = null;
         Connection conn = null;
-        String dataSourceName = getDataSourceName();
         DataSource ds = null;
+        
         try {
             ctx = new InitialContext();
             try {
@@ -522,7 +631,9 @@ public class CSpaceDbRealm implements CSpaceRealm {
             if (conn == null) {
                conn = AuthN.getDataSource().getConnection();  //FIXME:REM - This is the result of some type of JNDI mess.  Should try to solve this problem and clean up this code.
             }
+            
             return conn;
+            
         } catch (NamingException ex) {
             LoginException le = new LoginException("Error looking up DataSource from: " + dataSourceName);
             le.initCause(ex);
@@ -532,7 +643,7 @@ public class CSpaceDbRealm implements CSpaceRealm {
                 try {
                     ctx.close();
                 } catch (Exception e) {
-                       e.printStackTrace();
+                       e.printStackTrace();  // We should be using a logger here instead.
                 }
             }
         }
@@ -587,4 +698,39 @@ public class CSpaceDbRealm implements CSpaceRealm {
         this.tenantsQueryNoDisabled = tenantQuery;
     }
      */
+    
+    /*
+     * This method crawls the exception chain looking for network related exceptions and
+     * returns 'true' if it finds one.
+     */
+       public static boolean exceptionChainContainsNetworkError(Throwable exceptionChain) {
+               boolean result = false;
+               Throwable cause = exceptionChain;
+
+               while (cause != null) {
+                       if (isExceptionNetworkRelated(cause) == true) {
+                               result = true;
+                               break;
+                       }
+                       
+                       cause = cause.getCause();
+               }
+
+               return result;
+       }
+       
+       /*
+        * Return 'true' if the exception is in the "java.net" package.
+        */
+       private static boolean isExceptionNetworkRelated(Throwable cause) {
+               boolean result = false;
+
+               String className = cause.getClass().getCanonicalName();
+               if (className.contains("java.net") == true) {
+                       result = true;
+               }
+
+               return result;
+       }
+    
 }
index 66355bf78edb66aad9ef128e38f270916def32ec..85ec97db733df5a121489d8cbd3e25d7d1e8c200 100644 (file)
@@ -54,6 +54,7 @@ import java.security.acl.Group;
 import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Set;
+
 import org.springframework.security.authentication.jaas.AuthorityGranter;
 
 /**
@@ -66,7 +67,7 @@ public class CSpaceAuthorityGranter implements AuthorityGranter {
         Set<String> authorities = new HashSet<String>();
         if (principal instanceof Group) {
             Group g = (Group) principal;
-            Enumeration members = g.members();
+            Enumeration<? extends Principal> members = g.members();
             while (members.hasMoreElements()) {
                 Principal p = (Principal) members.nextElement();
                 authorities.add(p.getName());
diff --git a/services/authentication/service/src/main/resources/config/jboss-login-config.xml b/services/authentication/service/src/main/resources/config/jboss-login-config.xml
deleted file mode 100644 (file)
index ee67001..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-    Copyright 2009 University of California at Berkeley
-    Licensed under the Educational Community License (ECL), Version 2.0.
-    You may not use this file except in compliance with this License.
-
-    Document   : jboss-login-config.xml
-    Created on : June 19, 2009, 9:58 AM
-    Author     :
-    Description:
-        jboss config for JAAS DatabaseServerLoginModule
--->
-<!--
-copy the following snippet into $JBOSS_HOME/server/cspace/conf/login-config.xml
-copy before the "other" application-policy
--->
-
-<application-policy name="cspace">
-    <authentication>
-        <login-module code="org.collectionspace.authentication.jaas.CSpaceJBossDBLoginModule"
-                      flag="required">
-            <module-option name="dsJndiName">CspaceDS</module-option>
-            <module-option name="hashAlgorithm">SHA-256</module-option>
-            <module-option name="ignorePasswordCase">false</module-option>
-            <module-option name = "principalClass">org.collectionspace.authentication.CSpacePrincipal</module-option>
-            <module-option name="principalsQuery">
-                select passwd from users where username=?
-            </module-option>
-            <module-option name="rolesQuery">
-                select r.rolename, 'Role' from roles as r, accounts_roles as ar where ar.user_id=? and ar.role_id=r.csid
-            </module-option>
-            <module-option name="tenantsQuery">
-                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
-            </module-option>
-        </login-module>
-    </authentication>
-</application-policy>
diff --git a/services/authentication/service/src/main/resources/config/login-config.xml b/services/authentication/service/src/main/resources/config/login-config.xml
deleted file mode 100644 (file)
index 9481453..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-<?xml version='1.0'?>
-<!DOCTYPE policy PUBLIC
-      "-//JBoss//DTD JBOSS Security Config 3.0//EN"
-      "http://www.jboss.org/j2ee/dtd/security_config.dtd">
-<!-- The XML based JAAS login configuration read by the
-org.jboss.security.auth.login.XMLLoginConfig mbean. Add
-an application-policy element for each security domain.
-
-The outline of the application-policy is:
-<application-policy name="security-domain-name">
-  <authentication>
-    <login-module code="login.module1.class.name" flag="control_flag">
-      <module-option name = "option1-name">option1-value</module-option>
-      <module-option name = "option2-name">option2-value</module-option>
-      ...
-    </login-module>
-
-    <login-module code="login.module2.class.name" flag="control_flag">
-      ...
-    </login-module>
-    ...
-  </authentication>
-</application-policy>
-
-$Revision: 64598 $
--->
-
-<policy>
-    <!-- Used by clients within the application server VM such as
-    mbeans and servlets that access EJBs.
-    -->
-    <application-policy name = "client-login">
-       <authentication>
-          <login-module code = "org.jboss.security.ClientLoginModule"
-             flag = "required">
-             <!-- Any existing security context will be restored on logout -->
-             <module-option name="restore-login-identity">true</module-option>
-          </login-module>
-       </authentication>
-    </application-policy>
-
-    <!-- Security domain for JBossMQ -->
-    <application-policy name = "jbossmq">
-       <authentication>
-          <login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule"
-             flag = "required">
-             <module-option name = "unauthenticatedIdentity">guest</module-option>
-             <module-option name = "dsJndiName">java:/DefaultDS</module-option>
-             <module-option name = "principalsQuery">SELECT PASSWD FROM JMS_USERS WHERE USERID=?</module-option>
-             <module-option name = "rolesQuery">SELECT ROLEID, 'Roles' FROM JMS_ROLES WHERE USERID=?</module-option>
-          </login-module>
-       </authentication>
-    </application-policy>
-
-    <!-- Security domain for JBossMQ when using file-state-service.xml
-    <application-policy name = "jbossmq">
-       <authentication>
-          <login-module code = "org.jboss.mq.sm.file.DynamicLoginModule"
-             flag = "required">
-             <module-option name = "unauthenticatedIdentity">guest</module-option>
-             <module-option name = "sm.objectname">jboss.mq:service=StateManager</module-option>
-          </login-module>
-       </authentication>
-    </application-policy>
-    -->
-
-    <!-- Security domains for testing new jca framework -->
-    <application-policy name = "HsqlDbRealm">
-       <authentication>
-          <login-module code = "org.jboss.resource.security.ConfiguredIdentityLoginModule"
-             flag = "required">
-             <module-option name = "principal">sa</module-option>
-             <module-option name = "userName">sa</module-option>
-             <module-option name = "password"></module-option>
-             <module-option name = "managedConnectionFactoryName">jboss.jca:service=LocalTxCM,name=DefaultDS</module-option>
-          </login-module>
-       </authentication>
-    </application-policy>
-
-    <application-policy name = "JmsXARealm">
-       <authentication>
-          <login-module code = "org.jboss.resource.security.ConfiguredIdentityLoginModule"
-             flag = "required">
-             <module-option name = "principal">guest</module-option>
-             <module-option name = "userName">guest</module-option>
-             <module-option name = "password">guest</module-option>
-             <module-option name = "managedConnectionFactoryName">jboss.jca:service=TxCM,name=JmsXA</module-option>
-          </login-module>
-       </authentication>
-    </application-policy>
-
-    <!-- A template configuration for the jmx-console web application. This
-      defaults to the UsersRolesLoginModule the same as other and should be
-      changed to a stronger authentication mechanism as required.
-    -->
-    <application-policy name = "jmx-console">
-       <authentication>
-          <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
-             flag = "required">
-           <module-option name="usersProperties">props/jmx-console-users.properties</module-option>
-           <module-option name="rolesProperties">props/jmx-console-roles.properties</module-option>
-          </login-module>
-       </authentication>
-    </application-policy>
-
-    <!-- A template configuration for the web-console web application. This
-      defaults to the UsersRolesLoginModule the same as other and should be
-      changed to a stronger authentication mechanism as required.
-    -->
-    <application-policy name = "web-console">
-       <authentication>
-          <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
-             flag = "required">
-             <module-option name="usersProperties">web-console-users.properties</module-option>
-             <module-option name="rolesProperties">web-console-roles.properties</module-option>
-          </login-module>
-       </authentication>
-    </application-policy>
-
-    <!--
-      A template configuration for the JBossWS security domain.
-      This defaults to the UsersRolesLoginModule the same as other and should be
-      changed to a stronger authentication mechanism as required.
-    -->
-    <application-policy name="JBossWS">
-      <authentication>
-        <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
-          flag="required">
-          <module-option name="usersProperties">props/jbossws-users.properties</module-option>
-          <module-option name="rolesProperties">props/jbossws-roles.properties</module-option>
-          <module-option name="unauthenticatedIdentity">anonymous</module-option>
-        </login-module>
-      </authentication>
-    </application-policy>
-
-<application-policy name="cspace">
-    <authentication>
-        <login-module code="org.collectionspace.authentication.jaas.CSpaceJBossDBLoginModule"
-                      flag="required">
-            <module-option name="dsJndiName">CspaceDS</module-option>
-            <module-option name="hashAlgorithm">SHA-256</module-option>
-            <module-option name="ignorePasswordCase">false</module-option>
-            <module-option name = "principalClass">org.collectionspace.authentication.CSpacePrincipal</module-option>
-            <module-option name="principalsQuery">
-                select passwd from users where username=?
-            </module-option>
-            <module-option name="rolesQuery">
-                select r.rolename, 'Role' from roles as r, accounts_roles as ar where ar.user_id=? and ar.role_id=r.csid
-            </module-option>
-            <module-option name="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
-            </module-option>
-            <module-option name="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
-            </module-option>
-        </login-module>
-    </authentication>
-</application-policy>
-
-    <!-- The default login configuration used by any security domain that
-    does not have a application-policy entry with a matching name
-    -->
-    <application-policy name = "other">
-       <!-- A simple server login module, which can be used when the number
-       of users is relatively small. It uses two properties files:
-       users.properties, which holds users (key) and their password (value).
-       roles.properties, which holds users (key) and a comma-separated list of
-       their roles (value).
-       The unauthenticatedIdentity property defines the name of the principal
-       that will be used when a null username and password are presented as is
-       the case for an unuathenticated web client or MDB. If you want to
-       allow such users to be authenticated add the property, e.g.,
-       unauthenticatedIdentity="nobody"
-       -->
-       <authentication>
-          <login-module code = "org.jboss.security.auth.spi.UsersRolesLoginModule"
-             flag = "required" />
-       </authentication>
-    </application-policy>
-
-</policy>
-
index bdb1e80cd7ed181b49445e6992bfe7275e496b71..c04449e0e009f9cacea8d0491491d319ece4169c 100644 (file)
@@ -25,11 +25,11 @@ package org.collectionspace.services.authorization.spring;
 
 import java.util.List;
 import java.io.Serializable;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.collectionspace.services.authorization.CSpaceAction;
 import org.collectionspace.services.authorization.spi.CSpacePermissionEvaluator;
-
 import org.collectionspace.services.authorization.CSpaceResource;
 import org.springframework.security.access.PermissionEvaluator;
 import org.springframework.security.acls.model.Permission;
@@ -64,10 +64,13 @@ public class SpringPermissionEvaluator implements CSpacePermissionEvaluator {
                debug(res, authToken, objectIdId, objectIdType, perm);
                result = eval.hasPermission(authToken,
                        objectIdId, objectIdType, perm);
-       } catch (Exception e) {
-               //
-               // If this exception is caused by a network timeout, we may want to reattempt
-               //
+       } catch (Throwable e) {
+               if (exceptionChainContainsNetworkError(e) == true) {
+                       //
+                       // If this exception is caused by a network timeout, we want to re-attempt
+                       //
+                       throw e;
+               }
                log.error("Unexpected exception encountered while evaluating permissions.", e);
        }
         
@@ -92,4 +95,32 @@ public class SpringPermissionEvaluator implements CSpacePermissionEvaluator {
                System.out.println("");
        }
     }
+    
+       public static boolean exceptionChainContainsNetworkError(Throwable exceptionChain) {
+               boolean result = false;
+               Throwable cause = exceptionChain;
+
+               while (cause != null) {
+                       if (isCauseNetworkRelated(cause) == true) {
+                               result = true;
+                               break;
+                       }
+                       
+                       cause = cause.getCause();
+               }
+
+               return result;
+       }
+       
+       private static boolean isCauseNetworkRelated(Throwable cause) {
+               boolean result = false;
+
+               String className = cause.getClass().getCanonicalName();
+               if (className.contains("java.net") || className.contains("java.io")) {
+                       result = true;
+               }
+
+               return result;
+       }
+    
 }
diff --git a/services/common/src/main/java/org/collectionspace/services/common/CSWebApplicationException.java b/services/common/src/main/java/org/collectionspace/services/common/CSWebApplicationException.java
new file mode 100644 (file)
index 0000000..6c4ee70
--- /dev/null
@@ -0,0 +1,148 @@
+package org.collectionspace.services.common;
+
+import java.net.SocketException;
+import java.util.Random;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+import org.collectionspace.services.common.document.DocumentException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CSWebApplicationException extends WebApplicationException {
+    static final Logger logger = LoggerFactory.getLogger(CSWebApplicationException.class);
+    public final static String NETWORK_ERROR_TYPE = "text/neterr";
+    public final static String TEXT_MIME_TYPE = "text/plain";
+       /**
+        * 
+        */
+       private static final long serialVersionUID = 1L;
+       private Response response;
+
+       //
+       // Override of constructors
+       //
+       public CSWebApplicationException(Response response) {
+               super(response); // this set's our parent's private response member
+               this.response = response; // we need to set our copy since we override the getResponse() method.
+               logger.warn("CSWebApplicationException instance created without an underlying 'cause' exception.");
+       }
+
+       public CSWebApplicationException(Throwable cause) {
+               super(cause);
+               this.response = getFinalResponse(cause, null);
+       }
+
+       public CSWebApplicationException(Throwable cause, Response response) {
+               super(cause);
+               this.response = getFinalResponse(cause, response);
+       }
+
+       //
+       // Overrides and custom methods
+       //
+       
+       @Override
+       public Response getResponse() {
+               return response;
+       }
+
+       private Response getFinalResponse(Throwable cause, Response response) {
+               Response finalResponse = response;
+
+               if (exceptionChainContainsNetworkError(cause) == true) {
+                       if (response != null) {
+                               finalResponse = Response.fromResponse(response).entity(cause.getMessage()).type(NETWORK_ERROR_TYPE).build();
+                       } else {
+                               finalResponse = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
+                                               cause.getMessage()).type(NETWORK_ERROR_TYPE).build();
+
+                       }
+                       if (logger.isTraceEnabled() == true) {
+                               logger.trace(cause.getMessage(), cause);
+                       }
+               }
+               
+               if (finalResponse == null) {
+                       finalResponse = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
+                                       cause.getMessage()).type(TEXT_MIME_TYPE).build();
+               }
+
+               return finalResponse;
+       }
+
+       /*
+        * This method crawls the exception chain looking for network related exceptions and
+        * returns 'true' if it finds one.
+        */
+       public static boolean exceptionChainContainsNetworkError(Throwable exceptionChain) {
+               boolean result = false;
+               
+               Throwable cause = exceptionChain;
+               while (cause != null) {
+                       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();
+                       }
+               }
+
+               return result;
+       }
+       
+       private static boolean isStackTraceNetworkRelated(StackTraceElement[] stackTraceElementList) {
+               boolean result = false;
+               
+               for (StackTraceElement stackTraceElement : stackTraceElementList) {
+                       if (stackTraceElement.getClassName().contains("") == true) {
+                               
+                       }
+               }
+               
+               return result;
+       }
+       
+       /*
+        * Return 'true' if the exception is in the "java.net" package.
+        */
+       private static boolean isExceptionNetworkRelated(Throwable cause) {
+               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;
+                       }
+               }
+               
+               return result;
+       }
+       
+       /*
+        * This Method is intended only for testing the robustness of our network exception handling
+        * and retry code.  You can place a call to this method is various locations throughout the code
+        * and it will randomly throw an exception.
+        */
+       public static void throwAnException(int chance) throws SocketException {
+               Random generator = new Random(System.currentTimeMillis());
+               int roll = generator.nextInt(chance) + 1;
+               if (roll != 1) {
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("Throwing a SocketException at random to test our network robustness.");
+                       }
+                       throw new SocketException();
+               }
+       }
+
+}
diff --git a/services/common/src/main/java/org/collectionspace/services/common/NetworkErrorRetryFilter.java b/services/common/src/main/java/org/collectionspace/services/common/NetworkErrorRetryFilter.java
new file mode 100644 (file)
index 0000000..ab05ee0
--- /dev/null
@@ -0,0 +1,207 @@
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+ *
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+ *
+ * Copyright Â© 2009 {Contributing Institution}
+ *
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+ *
+ * You may obtain a copy of the ECL 2.0 License at
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+ */
+package org.collectionspace.services.common;
+
+import java.io.IOException;
+import java.net.ConnectException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import org.collectionspace.services.common.CSWebApplicationException;
+import org.collectionspace.services.common.ServletTools;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * CSpaceFilter.java
+ *
+ * A filter that performs specified actions at the time
+ * each new request is received by the servlet container.
+ *
+ * This filter is currently used for recording performance
+ * metrics for requests to the CollectionSpace services.
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ *
+ */
+public class NetworkErrorRetryFilter implements Filter {
+    final Logger logger = LoggerFactory.getLogger(NetworkErrorRetryFilter.class);
+
+    /** The filter config. */
+    FilterConfig filterConfig = null;
+    private final String CLASS_NAME = this.getClass().getSimpleName();
+    
+       private long maxRetrySeconds = MAX_RETRY_SECONDS;
+       private static final int MAX_RETRY_SECONDS = 5;
+    private static final String MAX_RETRY_SECONDS_STR = "maxRetrySeconds";
+
+       private long delayBetweenAttemptsMillis = DELAY_BETWEEN_ATTEMPTS_MILLISECONDS;
+    private static final String DELAY_BETWEEN_ATTEMPTS_MILLISECONDS_STR = "delayBetweenAttemptsMillis";
+       private static final long DELAY_BETWEEN_ATTEMPTS_MILLISECONDS = 200;
+       
+       protected void setMaxRetrySeconds(FilterConfig filterConfig) {
+               String paramValue = filterConfig.getInitParameter(MAX_RETRY_SECONDS_STR);
+               if (paramValue != null) {
+                       try {
+                               maxRetrySeconds = Long.parseLong(paramValue);
+                       } catch (NumberFormatException e) {
+                               logger.warn(String.format("The init parameter '%s' with value '%s' of the servlet filter '%s' could not be parsed to a long value.  The default value of '%d' will be used instead.",
+                                               MAX_RETRY_SECONDS_STR, paramValue, CLASS_NAME, maxRetrySeconds));
+                       }
+               }
+       }
+       
+       protected long getMaxRetrySeconds() {
+               return this.maxRetrySeconds;
+       }
+       
+       protected void setDelayBetweenAttemptsMillis(FilterConfig filterConfig) {
+               String paramValue = filterConfig.getInitParameter(DELAY_BETWEEN_ATTEMPTS_MILLISECONDS_STR);
+               if (paramValue != null) {
+                       try {
+                               delayBetweenAttemptsMillis = Long.parseLong(paramValue);
+                       } catch (NumberFormatException e) {
+                               logger.warn(String.format("The init parameter '%s' with value '%s' of the servlet filter '%s' could not be parsed to a long value.  The default value of '%d' will be used instead.",
+                                               MAX_RETRY_SECONDS_STR, paramValue, CLASS_NAME, delayBetweenAttemptsMillis));
+                       }
+               }
+       }
+       
+       protected long getDelayBetweenAttemptsMillis() {
+               return this.delayBetweenAttemptsMillis;
+       }
+       
+    /* (non-Javadoc)
+     * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
+     */
+    @Override
+    public void init(FilterConfig theFilterConfig) throws ServletException {
+        filterConfig = theFilterConfig;
+        
+        if (filterConfig != null) {
+            setMaxRetrySeconds(theFilterConfig);
+            setDelayBetweenAttemptsMillis(theFilterConfig);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.Filter#destroy()
+     */
+    @Override
+    public void destroy() {
+        // Empty method.
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
+     */
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response,
+            FilterChain chain) throws IOException, ServletException {
+        if (request != null) {
+                       try {
+                               doWrappedFilter(request, response, chain);
+                       } catch (Throwable e) {
+                               if (logger.isDebugEnabled() == true) {
+                                       logger.debug(CLASS_NAME, e);
+                               }
+                               throw new ServletException(e);
+                       }
+        }
+    }
+    
+    //
+    // 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:
+    //
+    //                 1. It looks at the response content type for a special string that we set in the CSWebApplicationException class.
+    //         2. If we catch an exception, we look at the exception chain for network related exceptions.
+    //
+       public void doWrappedFilter(ServletRequest request, ServletResponse response,
+            FilterChain chain) throws Throwable {
+               boolean failed = true;
+               Throwable lastException = null;
+               int requestAttempts = 0;
+
+               long quittingTime = System.currentTimeMillis() + getMaxRetrySeconds() * 1000; // This is how long we attempt retries
+               do {
+                       if (requestAttempts > 0) {
+                               response.reset();  // This will reset the response instance from the last failed attempt -i.e., we're retrying the request so we don't care about the last response
+                               Thread.sleep(getDelayBetweenAttemptsMillis()); // Wait a little time between reattempts.
+                       }
+                                               
+                       try {
+                               // proceed to the original request by calling doFilter()
+                               chain.doFilter(request, response);
+                               // check the response for network related errors
+                               if (hasNetworkRelatedError(response) == false) {
+                                       failed = false;
+                                       break; // the request was successfully executed, so we can break out of this retry loop
+                               } else {
+                                       throw new ConnectException(); // The 'response' argument indicated a network related failure, so let's throw a generic connection exception
+                               }
+                       } catch (Exception e) {
+                               lastException = e;
+                               if (CSWebApplicationException.exceptionChainContainsNetworkError(lastException) == false) {
+                                       // Break if the exception chain does not contain a
+                                       // SocketException because we don't want to retry if it's not a network related failure
+                                       break;
+                               }
+                               requestAttempts++; // keep track of how many times we've tried the request
+                       }
+               } while (System.currentTimeMillis() < quittingTime);  // keep trying until we run out of time
+               
+               //
+               // Add a warning to the logs if we encountered *any* failures on our re-attempts.  Only add the warning
+               // if we were eventually successful.
+               //
+               if (requestAttempts > 0 && failed == false) {
+                       logger.warn(String.format("Request to '%s' URL failed with exception '%s' at attempt number '%d' before finally succeeding on the next attempt.",
+                                       ServletTools.getURL((HttpServletRequest) request),
+                                       lastException.getClass().getName(),
+                                       requestAttempts));
+               }
+
+               if (failed == true) {
+                       // If we get here, it means all of our attempts to get a successful call to chain.doFilter() have failed.
+                       throw lastException;
+               }
+       }
+       
+       private boolean hasNetworkRelatedError(ServletResponse response) {
+               boolean result = false;
+               
+               String contentType = response.getContentType();
+               if (contentType != null && contentType.equalsIgnoreCase(CSWebApplicationException.NETWORK_ERROR_TYPE) == true) {
+                       result = true;
+               }
+               
+               if (contentType == null) {
+                       logger.debug("Response had no content type specified.  Probably just a successful POST which will have content type.");
+               }
+               
+               return result;
+       }
+}
index 953641911a13b334e1c8fa92a3dc78afa0425148..0060e8683fc8eaaa2acdb9d16769aad7b46711e0 100644 (file)
@@ -114,5 +114,16 @@ public class DocumentException extends ServiceException {
     public DocumentException(Throwable cause) {
         super(cause);
     }
+    
+       public String getCausesClassName() {
+               String result = null;
+               
+               Throwable cause = super.getCause();
+               if (cause != null) {
+                       result = cause.getClass().getCanonicalName();
+               }
+               
+               return result;
+       }
 
 }
index 459cb4193d0adb6d6a8c06a63842dcc607489e53..fad825f920f2c284bfd3ff571c998e3a19bc4f5d 100644 (file)
@@ -17,7 +17,6 @@
 package org.collectionspace.services.common.profile;\r
 \r
 import java.io.IOException;\r
-import java.net.SocketException;\r
 \r
 import javax.servlet.Filter;\r
 import javax.servlet.FilterChain;\r
@@ -26,11 +25,10 @@ import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;\r
 import javax.servlet.ServletResponse;\r
 import javax.servlet.http.HttpServletRequest;\r
-//import javax.servlet.ServletContext;\r
-\r
 \r
 import org.collectionspace.services.client.Profiler;\r
 import org.collectionspace.services.common.ServletTools;\r
+\r
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
 \r
@@ -48,13 +46,11 @@ import org.slf4j.LoggerFactory;
  *\r
  */\r
 public class CSpaceFilter implements Filter {\r
+    final Logger logger = LoggerFactory.getLogger(CSpaceFilter.class);\r
 \r
     /** The filter config. */\r
     FilterConfig filterConfig = null;\r
-\r
     private final String CLASS_NAME = this.getClass().getSimpleName();\r
-       private static final int MAX_RETRY_SECONDS = 5;\r
-\r
 \r
     /* (non-Javadoc)\r
      * @see javax.servlet.Filter#destroy()\r
@@ -100,13 +96,7 @@ public class CSpaceFilter implements Filter {
            profiler.log(csvMsg, FORMAT_LOG_MESSAGE);\r
 \r
             // Process the request.\r
-            //chain.doFilter(request, response);\r
-                       try {\r
-                               invoke(request, response, chain);\r
-                       } catch (Throwable e) {\r
-                               // TODO Auto-generated catch block\r
-                               e.printStackTrace();\r
-                       }\r
+            chain.doFilter(request, response);\r
 \r
             // Stop timing and log performance-related metrics.\r
             profiler.stop();\r
@@ -127,61 +117,6 @@ public class CSpaceFilter implements Filter {
         }\r
     }\r
     \r
-       public void invoke(ServletRequest request, ServletResponse response,\r
-            FilterChain chain) throws Throwable {\r
-               Throwable lastException = null;\r
-               int attempt = 0;\r
-\r
-               long quittingTime = System.currentTimeMillis() + MAX_RETRY_SECONDS * 1000;\r
-               do {\r
-                       try {\r
-                               // proceed to original method call\r
-                               chain.doFilter(request, response);\r
-                               String contentType = response.getContentType();\r
-                               lastException = null;\r
-                               break;\r
-                       } catch (Exception e) {\r
-                               lastException = e;\r
-                               if (exceptionChainContains(lastException, SocketException.class) == false) {\r
-                                       // Break if the exception chain does not contain a\r
-                                       // SocketException.\r
-                                       break;\r
-                               }\r
-                               attempt++;\r
-                               System.out\r
-                                               .println(String\r
-                                                               .format("'%s' URL request failed with exception '%s' at attemp '%d'",\r
-                                                                               ServletTools.getURL((HttpServletRequest) request),\r
-                                                                               lastException.getClass().getName(),\r
-                                                                               attempt));\r
-                       }\r
-               } while (System.currentTimeMillis() < quittingTime);\r
-\r
-               if (lastException != null) {\r
-                       throw lastException;\r
-               }\r
-\r
-               System.out.println("Success!");\r
-       }\r
-       \r
-       private boolean exceptionChainContains(Throwable exceptionChain,\r
-                       Class<?> target) {\r
-               boolean result = false;\r
-               Throwable top = exceptionChain;\r
-\r
-               while (top != null) {\r
-                       System.out.println(top.getClass().getCanonicalName());\r
-                       if (target.isInstance(top) == true) {\r
-                               result = true;\r
-                               break;\r
-                       }\r
-                       top = top.getCause();\r
-               }\r
-\r
-               return result;\r
-       }\r
-    \r
-\r
     /* (non-Javadoc)\r
      * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)\r
      */\r
index 8863aaeb757dd0761a61871cc2ab25af516f404c..6e330883b127035d1b7608d3c23c2e4a66051d06 100644 (file)
@@ -28,7 +28,6 @@ package org.collectionspace.services.common.query;
 \r
 import org.collectionspace.services.client.IQueryManager;\r
 import org.collectionspace.services.common.ServiceMain;\r
-import org.collectionspace.services.common.api.Tools;\r
 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;\r
 import org.collectionspace.services.common.config.TenantBindingUtils;\r
 import org.collectionspace.services.common.context.ServiceContext;\r
@@ -38,10 +37,6 @@ import org.collectionspace.services.config.tenant.TenantBindingType;
 public class QueryManager {\r
        static private final IQueryManager queryManager = new QueryManagerNuxeoImpl();\r
        \r
-       static public void execQuery(String queryString) {\r
-               queryManager.execQuery(queryString);\r
-       }\r
-       \r
        /**\r
         * Creates the where clause from keywords.\r
         * \r
index 744e998b3bdb6d9c7f2bbc55e5d780a2fcad1a73..a8c4734edad7b007db4196fd26ea24cccf3adeea 100644 (file)
@@ -32,16 +32,11 @@ import org.slf4j.LoggerFactory;
 import java.util.regex.Matcher;\r
 import java.util.regex.Pattern;\r
 \r
-import org.nuxeo.ecm.core.api.DocumentModel;\r
-import org.nuxeo.ecm.core.api.DocumentModelList;\r
-import org.nuxeo.ecm.core.api.repository.RepositoryInstance;\r
 //import org.nuxeo.ecm.core.client.NuxeoClient;\r
 \r
 import org.collectionspace.services.jaxb.InvocableJAXBSchema;\r
 //import org.collectionspace.services.nuxeo.client.java.NuxeoConnector;\r
 //import org.collectionspace.services.nuxeo.client.java.NxConnect;\r
-import org.collectionspace.services.nuxeo.client.java.NuxeoClientEmbedded;\r
-import org.collectionspace.services.nuxeo.client.java.NuxeoConnectorEmbedded;\r
 \r
 import org.collectionspace.services.client.IQueryManager;\r
 import org.collectionspace.services.common.invocable.InvocableUtils;\r
@@ -105,32 +100,7 @@ public class QueryManagerNuxeoImpl implements IQueryManager {
        @Override\r
        @Deprecated\r
        public void execQuery(String queryString) {\r
-               NuxeoClientEmbedded client = null;\r
-               try {\r
-                       client = NuxeoConnectorEmbedded.getInstance().getClient();\r
-                       RepositoryInstance repoSession = client.openRepository();\r
-\r
-                       DocumentModelList docModelList = repoSession\r
-                                       .query("SELECT * FROM Relation WHERE relations_common:subjectCsid='updated-Subject-1'");\r
-                       // DocumentModelList docModelList =\r
-                       // repoSession.query("SELECT * FROM Relation");\r
-                       // DocumentModelList docModelList =\r
-                       // repoSession.query("SELECT * FROM CollectionObject WHERE collectionobject:objectNumber='objectNumber-1251305545865'");\r
-                       for (DocumentModel docModel : docModelList) {\r
-                               System.out\r
-                                               .println("--------------------------------------------");\r
-                               System.out.println(docModel.getPathAsString());\r
-                               System.out.println(docModel.getName());\r
-                               System.out.println(docModel.getPropertyValue("dc:title"));\r
-                               // System.out.println("subjectCsid=" +\r
-                               // docModel.getProperty("relations_common",\r
-                               // "subjectCsid").toString());\r
-                       }\r
-\r
-               } catch (Exception e) {\r
-                       // TODO Auto-generated catch block\r
-                       e.printStackTrace();\r
-               }\r
+               // Intentionally left blank\r
        }\r
 \r
        @Override\r
index ce5189c65937a10847b5ad386110a4083cb26129..0b634de81f3a46bcde1f46a63278c8b195ac156e 100644 (file)
@@ -39,12 +39,12 @@ import org.jboss.resteasy.annotations.interception.SecurityPrecedence;
 import org.jboss.resteasy.annotations.interception.ServerInterceptor;
 import org.jboss.resteasy.spi.Failure;
 import org.jboss.resteasy.spi.HttpRequest;
+
 import org.nuxeo.runtime.api.Framework;
 
 import javax.security.auth.Subject;
 import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
-import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.ext.Provider;
 
@@ -58,6 +58,7 @@ import org.collectionspace.services.common.CollectionSpaceResource;
 import org.collectionspace.services.common.document.JaxbUtils;
 import org.collectionspace.services.common.storage.jpa.JpaStorageUtils;
 import org.collectionspace.services.common.security.SecurityUtils;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -87,21 +88,7 @@ public class SecurityInterceptor implements PreProcessInterceptor, PostProcessIn
     //
     private static final String ERROR_NUXEO_LOGOUT = "Attempt to logout when Nuxeo login context was null";
     private static final String ERROR_UNBALANCED_LOGINS = "The number of Logins vs Logouts to the Nuxeo framework was unbalanced.";    
-       
-    private boolean implementsInterface(Class<?> clazz, Class<?> interfaze) {
-       boolean result = false;
-       
-       Class<?>[] interfaces = clazz.getInterfaces();
-       for (Class<?> interfaceItem : interfaces) {
-               if (interfaceItem.equals(interfaze)) {
-                       result = true;
-                       break;
-               }
-       }
-       
-       return result;
-    }
-    
+           
     private boolean isAnonymousRequest(HttpRequest request, ResourceMethod resourceMethod) {
        boolean result = false;
        
@@ -126,85 +113,92 @@ public class SecurityInterceptor implements PreProcessInterceptor, PostProcessIn
                        throws Failure, CSWebApplicationException {
                ServerResponse result = null; // A null value essentially means success for this method
                
-               if (isAnonymousRequest(request, resourceMethod) == true) {
-                       // We don't need to check credentials for anonymous requests.  Just login to Nuxeo and
-                       // exit
-                       nuxeoPreProcess(request, resourceMethod);
-
-                       return result;
-               }
-               
-               final String servicesResource = "/cspace-services/"; // HACK - this is configured in war
-               final int servicesResourceLen = servicesResource.length();
-               String httpMethod = request.getHttpMethod();
-               String uriPath = request.getUri().getPath();
-               
-               if (logger.isDebugEnabled()) {
-                       String fullRequest = request.getUri().getRequestUri().toString();
-                       int servicesResourceIdx = fullRequest.indexOf(servicesResource);
-                       String relativeRequest = (servicesResourceIdx<=0)? fullRequest
-                                                                                               : fullRequest.substring(servicesResourceIdx+servicesResourceLen);
-                       logger.debug("received " + httpMethod + " on " + relativeRequest);
-               }
-               
-               String resName = SecurityUtils.getResourceName(request.getUri());
-               String resEntity = SecurityUtils.getResourceEntity(resName);
-               
-               //
-               // If the resource entity is acting as a proxy then all sub-resource will map to the resource itself.
-               // This essentially means that the sub-resource inherit all the authz permissions of the entity.
-               //
-               if (SecurityUtils.isEntityProxy() == true && !resName.equalsIgnoreCase(ACCOUNT_PERMISSIONS)) {
-                       resName = resEntity;
-               }
-               //
-               // Make sure the account is current and active
-               //
-               checkActive();
-               
-               //
-               // All active users are allowed to the *their* (we enforce this) current list of permissions.  If this is not
-               // the request, then we'll do a full AuthZ check.
-               //
-               if (resName.equalsIgnoreCase(ACCOUNT_PERMISSIONS) != true) { //see comment immediately above
-                       AuthZ authZ = AuthZ.get();
-                       CSpaceResource res = new URIResourceImpl(AuthN.get().getCurrentTenantId(), resName, httpMethod);
-                       if (authZ.isAccessAllowed(res) == false) {
-                                       logger.error("Access to " + res.getId() + " is NOT allowed to "
-                                                       + " user=" + AuthN.get().getUserId());
-                                       Response response = Response.status(
-                                                       Response.Status.FORBIDDEN).entity(uriPath + " " + httpMethod).type("text/plain").build();
-                                       throw new CSWebApplicationException(response);
-                       } else {
-                               //
-                               // They passed the first round of security checks, so now let's check to see if they're trying
-                               // to perform a workflow state change and make sure they are allowed to to this.
-                               //
-                               if (uriPath.contains(WorkflowClient.SERVICE_PATH) == true) {
-                                       String workflowProxyResource = SecurityUtils.getWorkflowResourceName(request);
-                                       res = new URIResourceImpl(AuthN.get().getCurrentTenantId(), workflowProxyResource, httpMethod);
-                                       if (authZ.isAccessAllowed(res) == false) {
-                                               logger.error("Access to " + resName + ":" + res.getId() + " is NOT allowed to "
+               try {
+                       if (isAnonymousRequest(request, resourceMethod) == true) {
+                               // We don't need to check credentials for anonymous requests.  Just login to Nuxeo and
+                               // exit
+                               nuxeoPreProcess(request, resourceMethod);
+       
+                               return result;
+                       }
+                       
+                       final String servicesResource = "/cspace-services/"; // HACK - this is configured in war
+                       final int servicesResourceLen = servicesResource.length();
+                       String httpMethod = request.getHttpMethod();
+                       String uriPath = request.getUri().getPath();
+                       
+                       if (logger.isDebugEnabled()) {
+                               String fullRequest = request.getUri().getRequestUri().toString();
+                               int servicesResourceIdx = fullRequest.indexOf(servicesResource);
+                               String relativeRequest = (servicesResourceIdx<=0)? fullRequest
+                                                                                                       : fullRequest.substring(servicesResourceIdx+servicesResourceLen);
+                               logger.debug("received " + httpMethod + " on " + relativeRequest);
+                       }
+                       
+                       String resName = SecurityUtils.getResourceName(request.getUri());
+                       String resEntity = SecurityUtils.getResourceEntity(resName);
+                       
+                       //
+                       // If the resource entity is acting as a proxy then all sub-resource will map to the resource itself.
+                       // This essentially means that the sub-resource inherit all the authz permissions of the entity.
+                       //
+                       if (SecurityUtils.isEntityProxy() == true && !resName.equalsIgnoreCase(ACCOUNT_PERMISSIONS)) {
+                               resName = resEntity;
+                       }
+                       //
+                       // Make sure the account is current and active
+                       //
+                       checkActive();
+                       
+                       //
+                       // All active users are allowed to the *their* (we enforce this) current list of permissions.  If this is not
+                       // the request, then we'll do a full AuthZ check.
+                       //
+                       if (resName.equalsIgnoreCase(ACCOUNT_PERMISSIONS) != true) { //see comment immediately above
+                               AuthZ authZ = AuthZ.get();
+                               CSpaceResource res = new URIResourceImpl(AuthN.get().getCurrentTenantId(), resName, httpMethod);
+                               if (authZ.isAccessAllowed(res) == false) {
+                                               logger.error("Access to " + res.getId() + " is NOT allowed to "
                                                                + " user=" + AuthN.get().getUserId());
                                                Response response = Response.status(
                                                                Response.Status.FORBIDDEN).entity(uriPath + " " + httpMethod).type("text/plain").build();
                                                throw new CSWebApplicationException(response);
+                               } else {
+                                       //
+                                       // They passed the first round of security checks, so now let's check to see if they're trying
+                                       // to perform a workflow state change and make sure they are allowed to to this.
+                                       //
+                                       if (uriPath.contains(WorkflowClient.SERVICE_PATH) == true) {
+                                               String workflowProxyResource = SecurityUtils.getWorkflowResourceName(request);
+                                               res = new URIResourceImpl(AuthN.get().getCurrentTenantId(), workflowProxyResource, httpMethod);
+                                               if (authZ.isAccessAllowed(res) == false) {
+                                                       logger.error("Access to " + resName + ":" + res.getId() + " is NOT allowed to "
+                                                                       + " user=" + AuthN.get().getUserId());
+                                                       Response response = Response.status(
+                                                                       Response.Status.FORBIDDEN).entity(uriPath + " " + httpMethod).type("text/plain").build();
+                                                       throw new CSWebApplicationException(response);
+                                               }
                                        }
                                }
+                               //
+                               // Login to Nuxeo
+                               //
+                               nuxeoPreProcess(request, resourceMethod);
+                               
+                               //
+                               // We've passed all the checks.  Now just log the results
+                               //
+                               if (logger.isTraceEnabled()) {
+                                       logger.trace("Access to " + res.getId() + " is allowed to " +
+                                                       " user=" + AuthN.get().getUserId() +
+                                                       " for tenant id=" + AuthN.get().getCurrentTenantName());
+                               }
                        }
-                       //
-                       // Login to Nuxeo
-                       //
-                       nuxeoPreProcess(request, resourceMethod);
-                       
-                       //
-                       // We've passed all the checks.  Now just log the results
-                       //
-                       if (logger.isTraceEnabled()) {
-                               logger.trace("Access to " + res.getId() + " is allowed to " +
-                                               " user=" + AuthN.get().getUserId() +
-                                               " for tenant id=" + AuthN.get().getCurrentTenantName());
+               } catch (Throwable t) {
+                       if (logger.isTraceEnabled() == true) {
+                               t.printStackTrace();
                        }
+                       throw t;
                }
                
                return result;
@@ -220,14 +214,11 @@ public class SecurityInterceptor implements PreProcessInterceptor, PostProcessIn
 
        /**
         * checkActive check if account is active
-        * @throws CSWebApplicationException
+        * @throws CSWebApplicationException 
         */
        private void checkActive() throws CSWebApplicationException {
                String userId = AuthN.get().getUserId();
-               
-               if (true)
-                       throw new CSWebApplicationException(new java.net.SocketException("An faux exception thrown for testing."));
-               
+                               
                try {
                        // Need to ensure that user is associated to a tenant
                        String tenantId = AuthN.get().getCurrentTenantId();
@@ -335,7 +326,9 @@ public class SecurityInterceptor implements PreProcessInterceptor, PostProcessIn
                                + threadLocalLoginContext.get());
                }
        }
+       
        LoginContext loginContext = threadLocalLoginContext.get();
+       
        if (loginContext == null) {
                loginContext = Framework.loginAs(user);
                frameworkLogins++;
index c9d6ed6dae476f7f757c32305c9a496acb3621cd..f7aeb66ef053d23eec2fb4e46df596be3ffbcc9d 100644 (file)
@@ -155,22 +155,6 @@ public final class NuxeoClientEmbedded {
         return openRepository(repoName, -1);\r
     }    \r
 \r
-    /*\r
-     * Open a Nuxeo repo session using the default repo with the specified (passed in) tx timeout period\r
-     */\r
-    @Deprecated\r
-    public RepositoryInstance openRepository(int timeoutSeconds) throws Exception {\r
-        return openRepository(null, timeoutSeconds);\r
-    }\r
-\r
-    /*\r
-     * Open a Nuxeo repo session using the default repo with the default tx timeout period\r
-     */\r
-    @Deprecated\r
-    public RepositoryInstance openRepository() throws Exception {\r
-        return openRepository(null, -1 /*default timeout period*/);\r
-    }\r
-\r
     public RepositoryInstance openRepository(String repoName, int timeoutSeconds) throws Exception {\r
        RepositoryInstance result = null;\r
        \r
diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoDocumentException.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoDocumentException.java
new file mode 100644 (file)
index 0000000..1931857
--- /dev/null
@@ -0,0 +1,68 @@
+package org.collectionspace.services.nuxeo.client.java;
+
+import org.collectionspace.services.common.document.DocumentException;
+import org.nuxeo.ecm.core.api.WrappedException;
+
+public class NuxeoDocumentException extends DocumentException {
+
+       /**
+        * 
+        */
+       private static final long serialVersionUID = 1L;
+
+       public NuxeoDocumentException() {
+               super();
+       }
+
+       public NuxeoDocumentException(String msg) {
+               super(msg);
+               // TODO Auto-generated constructor stub
+       }
+
+       public NuxeoDocumentException(int errorCode) {
+               super(errorCode);
+               // TODO Auto-generated constructor stub
+       }
+
+       public NuxeoDocumentException(int errorCode, String errorReason) {
+               super(errorCode, errorReason);
+               // TODO Auto-generated constructor stub
+       }
+
+       public NuxeoDocumentException(String message, Throwable cause) {
+               super(message, cause);
+               // TODO Auto-generated constructor stub
+       }
+
+       public NuxeoDocumentException(Throwable cause) {
+               super(cause);
+               // TODO Auto-generated constructor stub
+       }
+       
+       @Override
+       public String getCausesClassName() {
+               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;
+               }
+               
+               return result;
+       }
+               
+       protected boolean isNuxeoWrappedException(Throwable cause) {
+               boolean result = false;
+               
+               String className = cause.getClass().getCanonicalName();
+               if (className.contains("org.nuxeo.ecm.core.api.WrappedException") == true) {
+                       result = true;
+               }
+               
+               return result;
+       }
+       
+}
index e44ad6ee03dfd861a34bb19061d3aed5bb9a1458..2b562fe0ecb5e5e17f12157ab58097a529d1b2a5 100644 (file)
@@ -207,7 +207,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             throw bre;
         } catch (Exception e) {
             logger.error("Caught exception ", e);
-            throw new DocumentException(e);
+            throw new NuxeoDocumentException(e);
         } finally {
             if (repoSession != null) {
                 releaseRepositorySession(ctx, repoSession);
@@ -265,7 +265,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             if (logger.isDebugEnabled()) {
                 logger.debug("Caught exception ", e);
             }
-            throw new DocumentException(e);
+            throw new NuxeoDocumentException(e);
         } finally {
             if (repoSession != null) {
                 releaseRepositorySession(ctx, repoSession);
@@ -320,7 +320,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             if (logger.isDebugEnabled()) {
                 logger.debug("Caught exception ", e);
             }
-            throw new DocumentException(e);
+            throw new NuxeoDocumentException(e);
         } finally {
             if (repoSession != null) {
                 releaseRepositorySession(ctx, repoSession);
@@ -383,7 +383,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             if (logger.isDebugEnabled()) {
                 logger.debug("Caught exception ", e);
             }
-            throw new DocumentException(e);
+            throw new NuxeoDocumentException(e);
         } finally {
             if (repoSession != null) {
                 releaseRepositorySession(ctx, repoSession);
@@ -430,7 +430,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             if (logger.isDebugEnabled()) {
                 logger.debug("Caught exception ", e);
             }
-            throw new DocumentException(e);
+            throw new NuxeoDocumentException(e);
         }
 
         return wrapDoc;
@@ -458,7 +458,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             repoSession = getRepositorySession(ctx);
             wrapDoc = findDoc(repoSession, ctx, whereClause);
         } catch (Exception e) {
-            throw new DocumentException("Unable to create a Nuxeo repository session.", e);
+            throw new NuxeoDocumentException("Unable to create a Nuxeo repository session.", e);
         } finally {
             if (repoSession != null) {
                 releaseRepositorySession(ctx, repoSession);
@@ -507,7 +507,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             if (logger.isDebugEnabled()) {
                 logger.debug("Caught exception ", e);
             }
-            throw new DocumentException(e);
+            throw new NuxeoDocumentException(e);
         } finally {
             if (releaseSession && (repoSession != null)) {
                 this.releaseRepositorySession(ctx, repoSession);
@@ -547,7 +547,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             if (logger.isDebugEnabled()) {
                 logger.debug("Caught exception ", e);
             }
-            throw new DocumentException(e);
+            throw new NuxeoDocumentException(e);
         }
 
         return wrapDoc;
@@ -610,7 +610,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             if (logger.isDebugEnabled()) {
                 logger.debug("Caught exception ", e);
             }
-            throw new DocumentException(e);
+            throw new NuxeoDocumentException(e);
         }
 
         return wrapDoc;
@@ -646,7 +646,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             if (logger.isDebugEnabled()) {
                 logger.debug("Caught exception ", e);
             }
-            throw new DocumentException(e);
+            throw new NuxeoDocumentException(e);
         } finally {
             if (repoSession != null) {
                 releaseRepositorySession(ctx, repoSession);
@@ -694,7 +694,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             if (logger.isDebugEnabled()) {
                 logger.debug("Caught exception ", e);
             }
-            throw new DocumentException(e);
+            throw new NuxeoDocumentException(e);
         } finally {
             if (repoSession != null) {
                 releaseRepositorySession(ctx, repoSession);
@@ -745,7 +745,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             if (logger.isDebugEnabled()) {
                 logger.debug("Caught exception ", e);
             }
-            throw new DocumentException(e);
+            throw new NuxeoDocumentException(e);
         } finally {
             if (repoSession != null) {
                 releaseRepositorySession(ctx, repoSession);
@@ -910,7 +910,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             if (logger.isDebugEnabled()) {
                 logger.debug("Caught exception ", e); // REM - 1/17/2014: Check for org.nuxeo.ecm.core.api.ClientException and re-attempt
             }
-            throw new DocumentException(e);
+            throw new NuxeoDocumentException(e);
         } finally {
             if (repoSession != null) {
                 releaseRepositorySession(ctx, repoSession);
@@ -1248,7 +1248,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             if (logger.isDebugEnabled()) {
                 logger.debug("Caught exception ", e);
             }
-            throw new DocumentException(e);
+            throw new NuxeoDocumentException(e);
         }
 
         //
@@ -1323,7 +1323,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
                 /* Once we advance to 5.5 or later, we can add this. 
                  * See also https://jira.nuxeo.com/browse/NXP-8506
                  if(!doc.isVersionable()) {
-                 throw new DocumentException("Configuration for: "
+                 throw new NuxeoDocumentException("Configuration for: "
                  +handler.getServiceContextPath()+" supports versioning, but Nuxeo config does not!");
                  }
                  */
@@ -1358,7 +1358,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             if (logger.isDebugEnabled()) {
                 logger.debug("Caught exception ", e);
             }
-            throw new DocumentException(e);
+            throw new NuxeoDocumentException(e);
         } finally {
             if (repoSession != null) {
                 releaseRepositorySession(ctx, repoSession);
@@ -1395,7 +1395,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             if (logger.isDebugEnabled()) {
                 logger.debug("Caught exception ", e);
             }
-            throw new DocumentException(e);
+            throw new NuxeoDocumentException(e);
         }
     }
 
@@ -1426,7 +1426,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             throw ce;
         } catch (Exception e) {
             logger.error("Caught exception ", e);
-            throw new DocumentException(e);
+            throw new NuxeoDocumentException(e);
         }
     }
 
@@ -1474,7 +1474,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             if (logger.isDebugEnabled()) {
                 logger.debug("Caught exception ", e);
             }
-            throw new DocumentException(e);
+            throw new NuxeoDocumentException(e);
         } finally {
             if (repoSession != null) {
                 releaseRepositorySession(ctx, repoSession);
@@ -1681,7 +1681,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             if (logger.isDebugEnabled()) {
                 logger.debug("Caught exception ", e);
             }
-            throw new DocumentException(e);
+            throw new NuxeoDocumentException(e);
         } finally {
             if (repoSession != null) {
                 releaseRepositorySession(null, repoSession);
diff --git a/services/query/service/src/main/java/org/collectionspace/services/query/QueryResource.java b/services/query/service/src/main/java/org/collectionspace/services/query/QueryResource.java
deleted file mode 100644 (file)
index 9c575b8..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/**\r
- *  This document is a part of the source code and related artifacts\r
- *  for CollectionSpace, an open source collections management system\r
- *  for museums and related institutions:\r
-\r
- *  http://www.collectionspace.org\r
- *  http://wiki.collectionspace.org\r
-\r
- *  Copyright 2009 University of California at Berkeley\r
-\r
- *  Licensed under the Educational Community License (ECL), Version 2.0.\r
- *  You may not use this file except in compliance with this License.\r
-\r
- *  You may obtain a copy of the ECL 2.0 License at\r
-\r
- *  https://source.collectionspace.org/collection-space/LICENSE.txt\r
-\r
- *  Unless required by applicable law or agreed to in writing, software\r
- *  distributed under the License is distributed on an "AS IS" BASIS,\r
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- *  See the License for the specific language governing permissions and\r
- *  limitations under the License.\r
- */\r
-package org.collectionspace.services.query;\r
-\r
-import javax.ws.rs.Consumes;\r
-import javax.ws.rs.GET;\r
-import javax.ws.rs.Path;\r
-import javax.ws.rs.Produces;\r
-import javax.ws.rs.PathParam;\r
-import javax.ws.rs.WebApplicationException;\r
-import javax.ws.rs.core.Response;\r
-//import javax.xml.bind.JAXBContext;\r
-//import javax.xml.bind.Marshaller;\r
-\r
-\r
-import org.collectionspace.services.common.CSWebApplicationException;\r
-import org.collectionspace.services.common.query.QueryManager;\r
-//import org.collectionspace.services.common.NuxeoClientType;\r
-/*import org.collectionspace.services.common.ServiceMain;\r
-import org.collectionspace.services.common.document.DocumentNotFoundException;\r
-import org.collectionspace.services.common.document.DocumentHandler;\r
-import org.collectionspace.services.common.repository.RepositoryClient;\r
-import org.collectionspace.services.common.repository.RepositoryClientFactory;\r
-import org.jboss.resteasy.util.HttpResponseCodes;\r
-*/\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-@Path("/query")\r
-@Consumes("application/xml")\r
-@Produces("application/xml")\r
-public class QueryResource {\r
-\r
-    public final static String SERVICE_NAME = "query";\r
-    final Logger logger = LoggerFactory.getLogger(QueryResource.class);\r
-    //FIXME retrieve client type from configuration\r
-    //final static NuxeoClientType CLIENT_TYPE = ServiceMain.getInstance().getNuxeoClientType();\r
-\r
-    public QueryResource() {\r
-        // do nothing\r
-    }\r
-\r
-    @GET\r
-    @Path("{csid}")\r
-    public void getQuery(\r
-            @PathParam("csid") String csid) {\r
-        if(logger.isDebugEnabled()){\r
-            verbose("getQuery with csid=" + csid);\r
-        }\r
-        if (csid == null || "".equals(csid)){\r
-            logger.error("getQuery: missing csid!");\r
-            Response response = Response.status(Response.Status.BAD_REQUEST).entity(\r
-                    "get failed on getQuery csid=" + csid).type(\r
-                    "text/plain").build();\r
-            throw new CSWebApplicationException(response);\r
-        }\r
-\r
-        try {\r
-               QueryManager.execQuery(csid);\r
-        } catch(Exception e){\r
-            if(logger.isDebugEnabled()){\r
-                logger.debug("getQuery", e);\r
-            }\r
-            Response response = Response.status(Response.Status.NOT_FOUND).entity(\r
-                    "Get failed on query csid=" + csid).type(\r
-                    "text/plain").build();\r
-            throw new CSWebApplicationException(e, response);\r
-        }\r
-\r
-        if (false) {  // REM - 1/29/2014 : Huh? Why is this essentially commented out?  Should probably clean up.\r
-            Response response = Response.status(Response.Status.NOT_FOUND).entity(\r
-                    "Get failed, the requested CSID:" + csid + ": was not found.").type(\r
-                    "text/plain").build();\r
-            throw new CSWebApplicationException(response);\r
-        }\r
-\r
-//        return intakeObject;\r
-    }\r
-\r
-//    private void verbose(String msg, Intake intakeObject) {\r
-//        try{\r
-//            verbose(msg);\r
-//            JAXBContext jc = JAXBContext.newInstance(\r
-//                    Intake.class);\r
-//\r
-//            Marshaller m = jc.createMarshaller();\r
-//            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);\r
-//            m.marshal(intakeObject, System.out);\r
-//        }catch(Exception e){\r
-//            e.printStackTrace();\r
-//        }\r
-//\r
-//    }\r
-\r
-    private void verbose(String msg) {\r
-        System.out.println("QueryResource. " + msg);\r
-    }\r
-}\r