Factored out BaseDataConnector class
authorcantor <cantor@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Thu, 18 Sep 2003 19:07:35 +0000 (19:07 +0000)
committercantor <cantor@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Thu, 18 Sep 2003 19:07:35 +0000 (19:07 +0000)
Added option to mask errors in a PlugIn from parents.

git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/trunk@760 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

src/edu/internet2/middleware/shibboleth/aa/attrresolv/AttributeResolver.java
src/edu/internet2/middleware/shibboleth/aa/attrresolv/ResolutionPlugIn.java
src/edu/internet2/middleware/shibboleth/aa/attrresolv/provider/BaseDataConnector.java [new file with mode: 0644]
src/edu/internet2/middleware/shibboleth/aa/attrresolv/provider/BaseResolutionPlugIn.java
src/edu/internet2/middleware/shibboleth/aa/attrresolv/provider/JDBCDataConnector.java
src/edu/internet2/middleware/shibboleth/aa/attrresolv/provider/JNDIDirectoryDataConnector.java
tests/edu/internet2/middleware/shibboleth/aa/attrresolv/ScopeTestConnector.java

index a7f95f7..21a478b 100644 (file)
@@ -62,6 +62,7 @@ import java.util.Properties;
 import java.util.Set;
 
 import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttributes;
 
 import org.apache.log4j.Logger;
 import org.apache.xerces.parsers.DOMParser;
@@ -519,12 +520,10 @@ public class AttributeResolver {
         }
 
         //Resolve the connector
+        Attributes resolvedAttributes = null;
         try {
-            Attributes resolvedAttributes = currentDefinition.resolve(principal, requester, depends);
+            resolvedAttributes = currentDefinition.resolve(principal, requester, depends);
 
-            //Cache for this request
-            requestCache.put(currentDefinition.getId(), resolvedAttributes);
-    
             //Add attribute resolution to cache
             if (currentDefinition.getTTL() > 0) {
                 resolverCache.cacheConnectorResolution(
@@ -533,8 +532,6 @@ public class AttributeResolver {
                     currentDefinition.getTTL(),
                     resolvedAttributes);
             }
-            
-            return resolvedAttributes;
         }
         catch (ResolutionPlugInException e) {
             // Something went wrong, so check for a fail-over...
@@ -543,8 +540,19 @@ public class AttributeResolver {
                     currentDefinition.getFailoverDependencyId(), principal, requester, requestCache, requestedAttributes
                     );
             }
-            throw e;
+            
+            if (currentDefinition.getPropagateErrors()) {
+                throw e;
+            } else {
+                log.warn(
+                    "Connector (" + currentDefinition.getId() + ") returning empty attribute set instead of propagating error: " + e);
+                resolvedAttributes = new BasicAttributes();
+            }
         }
+
+        //Cache for this request
+        requestCache.put(currentDefinition.getId(), resolvedAttributes);
+        return resolvedAttributes;
     }
 
        private void resolveAttribute(
@@ -619,22 +627,32 @@ public class AttributeResolver {
                                resolveConnector(connectorDependencies[i], principal, requester, requestCache, requestedAttributes));
                }
 
-               //Resolve the attribute
-               currentDefinition.resolve(attribute, principal, requester, depends);
+        //Resolve the attribute
+        try {
+            currentDefinition.resolve(attribute, principal, requester, depends);
+
+            //Add attribute resolution to cache
+            if (currentDefinition.getTTL() > 0) {
+                resolverCache.cacheAttributeResolution(
+                    principal,
+                    attribute.getName(),
+                    currentDefinition.getTTL(),
+                    attribute);
+            }
+        }
+        catch (ResolutionPlugInException e) {
+            if (currentDefinition.getPropagateErrors()) {
+                throw e;
+            } else {
+                log.warn(
+                    "Attribute (" + currentDefinition.getId() + ") returning no values instead of propagating error: " + e);
+            }
+        }
 
                //If necessary, cache for this request
                if (dependancyOnly || !attribute.hasValues()) {
                        requestCache.put(currentDefinition.getId(), attribute);
                }
-
-               //Add attribute resolution to cache
-               if (currentDefinition.getTTL() > 0) {
-                       resolverCache.cacheAttributeResolution(
-                               principal,
-                               attribute.getName(),
-                               currentDefinition.getTTL(),
-                               attribute);
-               }
        }
 
        private class DuplicatePlugInException extends Exception {
index 2149f62..e91c7bf 100644 (file)
@@ -58,8 +58,27 @@ package edu.internet2.middleware.shibboleth.aa.attrresolv;
  */
 public interface ResolutionPlugIn {
        
-       public String getId();
-       public long getTTL();
+    /**
+     * Returns the name of the plugin.
+     * 
+     * @return String a plugin name
+     */
+    public String getId();
+       
+    /**
+     * Returns the time in seconds to cache the results of the plugin's resolution.
+     * 
+     * @return long time in seconds 
+     */
+    public long getTTL();
+    
+    /**
+     * Returns whether to trap and log resolution errors and return nothing,
+     * or propagate errors up as exceptions. 
+     * 
+     * @return boolean whether to propagate errors 
+     */
+    public boolean getPropagateErrors();
 
     /**
      * Returns an array containing the names of the attribute
diff --git a/src/edu/internet2/middleware/shibboleth/aa/attrresolv/provider/BaseDataConnector.java b/src/edu/internet2/middleware/shibboleth/aa/attrresolv/provider/BaseDataConnector.java
new file mode 100644 (file)
index 0000000..97f7034
--- /dev/null
@@ -0,0 +1,88 @@
+/* 
+ * The Shibboleth License, Version 1. 
+ * Copyright (c) 2002 
+ * University Corporation for Advanced Internet Development, Inc. 
+ * All rights reserved
+ * 
+ * 
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * Redistributions of source code must retain the above copyright notice, this 
+ * list of conditions and the following disclaimer.
+ * 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation 
+ * and/or other materials provided with the distribution, if any, must include 
+ * the following acknowledgment: "This product includes software developed by 
+ * the University Corporation for Advanced Internet Development 
+ * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement 
+ * may appear in the software itself, if and wherever such third-party 
+ * acknowledgments normally appear.
+ * 
+ * Neither the name of Shibboleth nor the names of its contributors, nor 
+ * Internet2, nor the University Corporation for Advanced Internet Development, 
+ * Inc., nor UCAID may be used to endorse or promote products derived from this 
+ * software without specific prior written permission. For written permission, 
+ * please contact shibboleth@shibboleth.org
+ * 
+ * Products derived from this software may not be called Shibboleth, Internet2, 
+ * UCAID, or the University Corporation for Advanced Internet Development, nor 
+ * may Shibboleth appear in their name, without prior written permission of the 
+ * University Corporation for Advanced Internet Development.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK 
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE. 
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY 
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT, 
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package edu.internet2.middleware.shibboleth.aa.attrresolv.provider;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import edu.internet2.middleware.shibboleth.aa.attrresolv.AttributeResolver;
+import edu.internet2.middleware.shibboleth.aa.attrresolv.DataConnectorPlugIn;
+import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugInException;
+
+/**
+ * Base class for Data Connector PlugIns.  Provides basic functionality such as 
+ * failover tracking.  Subclasses must provide resolution logic.
+ * 
+ * @author Scott Cantor (cantor.2@osu.edu)
+ */
+
+public abstract class BaseDataConnector extends BaseResolutionPlugIn implements DataConnectorPlugIn {
+       
+       /** A backup connector to use if this one fails. */
+    protected String failover = null;
+       
+       protected BaseDataConnector(Element e) throws ResolutionPlugInException {
+
+               super(e);
+
+        NodeList failoverNodes = e.getElementsByTagNameNS(AttributeResolver.resolverNamespace, "FailoverDependency");
+        if (failoverNodes.getLength() > 0) {
+            failover = ((Element)failoverNodes.item(0)).getAttribute("requires");
+        }
+       }
+
+    /**
+     * @see edu.internet2.middleware.shibboleth.aa.attrresolv.DataConnectorPlugIn#getFailoverDependencyId()
+     */
+    public String getFailoverDependencyId() {
+        return failover;
+    }
+
+}
index f67f767..0e2ee8b 100644 (file)
@@ -57,6 +57,7 @@ import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 
 import edu.internet2.middleware.shibboleth.aa.attrresolv.AttributeResolver;
+import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugIn;
 import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugInException;
 
 /**
@@ -65,7 +66,7 @@ import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugInExcepti
  * @author Walter Hoehn (wassa@columbia.edu)
  */
 
-public abstract class BaseResolutionPlugIn {
+public abstract class BaseResolutionPlugIn implements ResolutionPlugIn {
 
        private static Logger log = Logger.getLogger(BaseResolutionPlugIn.class.getName());
        
@@ -74,6 +75,9 @@ public abstract class BaseResolutionPlugIn {
 
        /** Time, in seconds, for which the Attribute Resolver should cache resolutions of this PlugIn. */
        protected long ttl = 0;
+    
+    /** Whether to propagate errors out of the PlugIn as exceptions. */
+    protected boolean propagateErrors = true;
 
     /** Dependencies. */
     protected Set connectorDependencyIds = new HashSet();
@@ -96,6 +100,11 @@ public abstract class BaseResolutionPlugIn {
                                throw new ResolutionPlugInException("Failed to initialize Resolution PlugIn.");
                        }
                }
+        
+        String propagateFlag = e.getAttribute("propagateErrors");
+        if (propagateFlag != null && (propagateFlag.equals("false") || propagateFlag.equals("0"))) {
+            propagateErrors = false;
+        }
 
         NodeList connectorNodes = e.getElementsByTagNameNS(AttributeResolver.resolverNamespace, "DataConnectorDependency");
 
@@ -133,6 +142,14 @@ public abstract class BaseResolutionPlugIn {
                return ttl;
        }
 
+    /**
+     * @see edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugIn#getPropagateErrors()
+     */
+    public boolean getPropagateErrors() {
+        return propagateErrors;
+    }
+
+
     protected void addDataConnectorDependencyId(String id) {
         connectorDependencyIds.add(id);
     }
index 5b8b6a2..9cf0986 100644 (file)
@@ -84,23 +84,18 @@ import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolverAttribute;
  * @author Scott Cantor
  */
 
-public class JDBCDataConnector extends BaseResolutionPlugIn implements DataConnectorPlugIn {
+public class JDBCDataConnector extends BaseDataConnector implements DataConnectorPlugIn {
 
        private static Logger log = Logger.getLogger(JDBCDataConnector.class.getName());
        protected String searchVal;
        protected DataSource dataSource;
        protected JDBCAttributeExtractor extractor;
        protected JDBCStatementCreator statementCreator;
-    protected String failover = null;
 
        public JDBCDataConnector(Element e) throws ResolutionPlugInException {
 
                super(e);
 
-        NodeList failoverNodes = e.getElementsByTagNameNS(AttributeResolver.resolverNamespace, "FailoverDependency");
-        if (failoverNodes.getLength() > 0) {
-            failover = ((Element)failoverNodes.item(0)).getAttribute("requires");
-        }
                //Get the query string
                NodeList queryNodes = e.getElementsByTagNameNS(AttributeResolver.resolverNamespace, "Query");
                Node tnode = queryNodes.item(0).getFirstChild();
@@ -375,13 +370,6 @@ public class JDBCDataConnector extends BaseResolutionPlugIn implements DataConne
                log.debug("Driver loaded.");
        }
 
-    /**
-     * @see edu.internet2.middleware.shibboleth.aa.attrresolv.DataConnectorPlugIn#getFailoverDependencyId()
-     */
-    public String getFailoverDependencyId() {
-        return failover;
-    }
-
        private class Log4jPrintWriter extends PrintWriter {
 
                private Priority level;
index 5279f29..d911027 100644 (file)
@@ -76,7 +76,7 @@ import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolutionPlugInExcepti
  * @author Walter Hoehn (wassa@columbia.edu)
  *
  */
-public class JNDIDirectoryDataConnector extends BaseResolutionPlugIn implements DataConnectorPlugIn {
+public class JNDIDirectoryDataConnector extends BaseDataConnector implements DataConnectorPlugIn {
 
        private static Logger log = Logger.getLogger(JNDIDirectoryDataConnector.class.getName());
        protected String searchFilter;
@@ -96,11 +96,6 @@ public class JNDIDirectoryDataConnector extends BaseResolutionPlugIn implements
 
                super(e);
         
-        NodeList failoverNodes = e.getElementsByTagNameNS(AttributeResolver.resolverNamespace, "FailoverDependency");
-        if (failoverNodes.getLength() > 0) {
-            failover = ((Element)failoverNodes.item(0)).getAttribute("requires");
-        }
-        
                NodeList searchNodes = e.getElementsByTagNameNS(AttributeResolver.resolverNamespace, "Search");
                if (searchNodes.getLength() != 1) {
                        log.error("JNDI Directory Data Connector requires a \"Search\" specification.");
@@ -283,11 +278,4 @@ public class JNDIDirectoryDataConnector extends BaseResolutionPlugIn implements
                        }
                }
        }
-
-    /**
-     * @see edu.internet2.middleware.shibboleth.aa.attrresolv.DataConnectorPlugIn#getFailoverDependencyId()
-     */
-    public String getFailoverDependencyId() {
-        return failover;
-    }
 }
index 57bbd07..ae5418d 100644 (file)
@@ -58,7 +58,7 @@ import javax.naming.directory.BasicAttributes;
 import org.apache.log4j.Logger;
 import org.w3c.dom.Element;
 
-import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.BaseResolutionPlugIn;
+import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.BaseDataConnector;
 
 /**
  * <code>DataConnectorPlugIn</code> implementation for use in unit testing.
@@ -66,7 +66,7 @@ import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.BaseResolution
  * @author Walter Hoehn
  *
  */
-public class ScopeTestConnector extends BaseResolutionPlugIn implements DataConnectorPlugIn {
+public class ScopeTestConnector extends BaseDataConnector implements DataConnectorPlugIn {
 
        private static Logger log = Logger.getLogger(ScopeTestConnector.class.getName());
 
@@ -87,12 +87,4 @@ public class ScopeTestConnector extends BaseResolutionPlugIn implements DataConn
                attributes.put(new BasicAttribute("foo", "bar@example.com"));
                return attributes;
        }
-
-    /**
-     * @see edu.internet2.middleware.shibboleth.aa.attrresolv.DataConnectorPlugIn#getFailoverDependencyId()
-     */
-    public String getFailoverDependencyId() {
-        return null;
-    }
-
 }