[java-metadata-aggregator] branch master updated: MDA-153 add generic validator framework

Ian Young ian at iay.org.uk
Tue Dec 15 14:46:13 EST 2015


This is an automated email from the git hooks/post-receive script.

iay pushed a commit to branch master
in repository java-metadata-aggregator.

The following commit(s) were added to refs/heads/master by this push:
       new  8256dc2   MDA-153 add generic validator framework
8256dc2 is described below

commit 8256dc20a42f8cc0b21d48fd466bb78e02281f2b
Author: Ian Young <ian at iay.org.uk>
AuthorDate: Tue Dec 15 19:46:40 2015 +0000

    MDA-153 add generic validator framework
    
    Use chain of control and strategy patterns for validators. Pulled in
    from the other branch of the ukf-mda project.
---
 .../metadata/dom/AbstractDOMValidationStage.java   |  7 +-
 .../shibboleth/metadata/validate/Validator.java    | 20 ++++-
 .../validate/x509/AbstractX509Validator.java       | 28 +++++++
 .../validate/x509/X509RSAExponentValidator.java    |  2 +-
 .../validate/x509/X509RSAKeyLengthValidator.java   |  2 +-
 .../x509/X509RSAOpenSSLBlacklistValidator.java     |  2 +-
 .../dom/AbstractDOMValidationStageTest.java        | 87 ++++++++++++++++++++++
 .../net/shibboleth/metadata/dom/BaseDOMTest.java   | 27 ++++++-
 .../x509/X509RSAExponentValidatorTest.java         |  3 +-
 .../x509/X509RSAKeyLengthValidatorTest.java        |  7 +-
 .../x509/X509RSAOpenSSLBlacklistValidatorTest.java | 19 ++---
 .../dom/AbstractDOMValidationStage-early.xml       |  5 ++
 12 files changed, 189 insertions(+), 20 deletions(-)

diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AbstractDOMValidationStage.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AbstractDOMValidationStage.java
index 0bfd9ca..fec083d 100644
--- a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AbstractDOMValidationStage.java
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AbstractDOMValidationStage.java
@@ -73,8 +73,11 @@ public abstract class AbstractDOMValidationStage<V> extends AbstractDOMTraversal
      */
     protected void applyValidators(@Nonnull final V obj, @Nonnull final TraversalContext context)
             throws StageProcessingException {
-        for (Validator<V> validator: validators) {
-            validator.validate(obj, context.getItem(), getId());
+        for (final Validator<V> validator: validators) {
+            final Validator.Action action = validator.validate(obj, context.getItem(), getId());
+            if (action == Validator.Action.DONE) {
+                return;
+            }
         }
     }
     
diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/validate/Validator.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/validate/Validator.java
index 21d61cb..65fe9a9 100644
--- a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/validate/Validator.java
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/validate/Validator.java
@@ -34,6 +34,23 @@ public interface Validator<V> extends DestructableComponent, IdentifiableCompone
     InitializableComponent {
     
     /**
+     * {@link Validator} instances are normally applied in sequence in a
+     * chain of responsibility pattern orchestrated by the caller.
+     * 
+     * The sequence is regarded as completed when all validators have been called,
+     * or when the first returns a {@link #DONE} value. This can be used to
+     * short-circuit evaluation in the case where the problem detected would
+     * invalidate subsequent tests.
+     */
+    public enum Action {
+        /** Evaluation of other {@link Validator}s may proceed. */
+        CONTINUE,
+        
+        /** Evaluation of other {@link Validator}s should not proceed. */
+        DONE
+    }
+
+    /**
      * Apply the validator to the object in the given {@link Item} context.
      * 
      * The validator influences future processing by adding item metadata to the {@link Item}.
@@ -42,9 +59,10 @@ public interface Validator<V> extends DestructableComponent, IdentifiableCompone
      * @param item the {@link Item} context for the validation
      * @param stageId the identifier for the stage that is requesting the validation, for
      *      inclusion in status metadata
+     * @return an indication of whether to process additional validators
      * @throws StageProcessingException if an error occurs during validation
      */
-    public void validate(@Nonnull V e, @Nonnull Item<?> item, @Nonnull String stageId)
+    public Action validate(@Nonnull V e, @Nonnull Item<?> item, @Nonnull String stageId)
         throws StageProcessingException;
     
 }
diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/validate/x509/AbstractX509Validator.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/validate/x509/AbstractX509Validator.java
index 8017de6..8f2eb97 100644
--- a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/validate/x509/AbstractX509Validator.java
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/validate/x509/AbstractX509Validator.java
@@ -19,12 +19,40 @@ package net.shibboleth.metadata.validate.x509;
 
 import java.security.cert.X509Certificate;
 
+import javax.annotation.Nonnull;
+
+import net.shibboleth.metadata.Item;
+import net.shibboleth.metadata.pipeline.StageProcessingException;
 import net.shibboleth.metadata.validate.BaseValidator;
 import net.shibboleth.metadata.validate.Validator;
 
 /**
  * Abstract class implementing validation on {@link X509Certificate} objects.
+ *
+ * X.509 certificate issues are almost always independent, so simplify the validator interface
+ * by delegation.
  */
 public abstract class AbstractX509Validator extends BaseValidator implements Validator<X509Certificate> {
 
+    /**
+     * Apply the validator to the object in the given {@link Item} context.
+     * 
+     * The validator influences future processing by adding item metadata to the {@link Item}.
+     * 
+     * @param cert the certificate to be validated
+     * @param item the {@link Item} context for the validation
+     * @param stageId the identifier for the stage that is requesting the validation, for
+     *      inclusion in status metadata
+     * @throws StageProcessingException if an error occurs during validation
+     */
+    protected abstract void doValidate(@Nonnull final X509Certificate cert, @Nonnull final Item<?> item,
+            @Nonnull final String stageId) throws StageProcessingException;
+
+    @Override
+    public Action validate(@Nonnull final X509Certificate cert, @Nonnull final Item<?> item,
+            @Nonnull final String stageId) throws StageProcessingException {
+        doValidate(cert, item, stageId);
+        return Action.CONTINUE;
+    }
+
 }
diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/validate/x509/X509RSAExponentValidator.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/validate/x509/X509RSAExponentValidator.java
index d855645..17b11bf 100644
--- a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/validate/x509/X509RSAExponentValidator.java
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/validate/x509/X509RSAExponentValidator.java
@@ -94,7 +94,7 @@ public class X509RSAExponentValidator extends AbstractX509Validator {
     }
     
     @Override
-    public void validate(@Nonnull final X509Certificate cert, @Nonnull final Item<?> item,
+    public void doValidate(@Nonnull final X509Certificate cert, @Nonnull final Item<?> item,
             @Nonnull final String stageId) {
         final PublicKey key = cert.getPublicKey();
         if ("RSA".equals(key.getAlgorithm())) {
diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/validate/x509/X509RSAKeyLengthValidator.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/validate/x509/X509RSAKeyLengthValidator.java
index 2a17b5b..a0d1284 100644
--- a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/validate/x509/X509RSAKeyLengthValidator.java
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/validate/x509/X509RSAKeyLengthValidator.java
@@ -91,7 +91,7 @@ public class X509RSAKeyLengthValidator extends AbstractX509Validator {
     
     /** {@inheritDoc} */
     @Override
-    public void validate(@Nonnull final X509Certificate cert, @Nonnull final Item<?> item,
+    public void doValidate(@Nonnull final X509Certificate cert, @Nonnull final Item<?> item,
             @Nonnull final String stageId) {
         final PublicKey key = cert.getPublicKey();
         if ("RSA".equals(key.getAlgorithm())) {
diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/validate/x509/X509RSAOpenSSLBlacklistValidator.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/validate/x509/X509RSAOpenSSLBlacklistValidator.java
index 757ccd4..5398f24 100644
--- a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/validate/x509/X509RSAOpenSSLBlacklistValidator.java
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/validate/x509/X509RSAOpenSSLBlacklistValidator.java
@@ -165,7 +165,7 @@ public class X509RSAOpenSSLBlacklistValidator extends AbstractX509Validator {
     
     /** {@inheritDoc} */
     @Override
-    public void validate(@Nonnull final X509Certificate cert, @Nonnull final Item<?> item,
+    public void doValidate(@Nonnull final X509Certificate cert, @Nonnull final Item<?> item,
             @Nonnull final String stageId) throws StageProcessingException {
         ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this);
         final PublicKey key = cert.getPublicKey();
diff --git a/aggregator-pipeline/src/test/java/net/shibboleth/metadata/dom/AbstractDOMValidationStageTest.java b/aggregator-pipeline/src/test/java/net/shibboleth/metadata/dom/AbstractDOMValidationStageTest.java
new file mode 100644
index 0000000..08f12af
--- /dev/null
+++ b/aggregator-pipeline/src/test/java/net/shibboleth/metadata/dom/AbstractDOMValidationStageTest.java
@@ -0,0 +1,87 @@
+
+package net.shibboleth.metadata.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+import org.w3c.dom.Element;
+
+import net.shibboleth.metadata.ErrorStatus;
+import net.shibboleth.metadata.Item;
+import net.shibboleth.metadata.pipeline.StageProcessingException;
+import net.shibboleth.metadata.validate.BaseValidator;
+import net.shibboleth.metadata.validate.Validator;
+
+public class AbstractDOMValidationStageTest extends BaseDOMTest {
+
+    protected AbstractDOMValidationStageTest() {
+        super(AbstractDOMValidationStage.class);
+    }
+
+    private static class StringValidationStage extends AbstractDOMValidationStage<String> {
+
+        @Override
+        protected boolean applicable(Element element) {
+            return "checkedElement".equals(element.getLocalName());
+        }
+
+        @Override
+        protected void visit(Element element, TraversalContext context) throws StageProcessingException {
+            applyValidators(element.getTextContent(), context);
+        }
+        
+    }
+
+    private static class FirstStringValidator extends BaseValidator implements Validator<String> {
+
+        @Override
+        public Action validate(String e, Item<?> item, String stageId)
+                throws StageProcessingException {
+            addError("element contains " + e, item, stageId);
+            return Action.DONE; // once per value checked
+        }
+        
+    }
+
+    private static class UnexecutedStringValidator extends BaseValidator implements Validator<String> {
+
+        @Override
+        public Action validate(String e, Item<?> item, String stageId)
+                throws StageProcessingException {
+            Assert.fail("should not execute this");
+            return Action.CONTINUE;
+        }
+
+    }
+
+    @Test
+    public void testEarlyCompletion() throws Exception {
+        final FirstStringValidator v1 = new FirstStringValidator();
+        v1.setId("v1");
+        v1.initialize();
+        final UnexecutedStringValidator v2 = new UnexecutedStringValidator();
+        v2.setId("v2");
+        v2.initialize();
+        final List<Validator<String>> validators = new ArrayList<>();
+        validators.add(v1);
+        validators.add(v2);
+        
+        final StringValidationStage s1 = new StringValidationStage();
+        s1.setId("s1");
+        s1.setValidators(validators);
+        s1.initialize();
+
+        final Item<Element> i1 = readDOMItem("early.xml");
+        final List<Item<Element>> items = new ArrayList<>();
+        items.add(i1);
+        
+        s1.execute(items);
+        Assert.assertEquals(2, countErrors(i1));
+        final List<ErrorStatus> errors = i1.getItemMetadata().get(ErrorStatus.class);
+        Assert.assertEquals(errors.get(0).getStatusMessage(), "element contains one");
+        Assert.assertEquals(errors.get(1).getStatusMessage(), "element contains two");
+    }
+
+}
diff --git a/aggregator-pipeline/src/test/java/net/shibboleth/metadata/dom/BaseDOMTest.java b/aggregator-pipeline/src/test/java/net/shibboleth/metadata/dom/BaseDOMTest.java
index c99e122..bc9c951 100644
--- a/aggregator-pipeline/src/test/java/net/shibboleth/metadata/dom/BaseDOMTest.java
+++ b/aggregator-pipeline/src/test/java/net/shibboleth/metadata/dom/BaseDOMTest.java
@@ -18,8 +18,13 @@
 package net.shibboleth.metadata.dom;
 
 import java.io.InputStream;
+import java.util.List;
 
 import net.shibboleth.metadata.BaseTest;
+import net.shibboleth.metadata.ErrorStatus;
+import net.shibboleth.metadata.Item;
+import net.shibboleth.metadata.ItemMetadata;
+import net.shibboleth.utilities.java.support.collection.ClassToInstanceMultiMap;
 import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
 import net.shibboleth.utilities.java.support.logic.Constraint;
 import net.shibboleth.utilities.java.support.primitive.StringSupport;
@@ -74,7 +79,7 @@ public abstract class BaseDOMTest extends BaseTest {
      * 
      * @return the document root of the data file, never null
      * 
-     * @throws XMLParserException thrown if the file does not exists or there is a problem parsing it
+     * @throws XMLParserException thrown if the file does not exist or there is a problem parsing it
      */
     public Element readXMLData(final String path) throws XMLParserException {
         String trimmedPath = StringSupport.trimOrNull(path);
@@ -93,6 +98,20 @@ public abstract class BaseDOMTest extends BaseTest {
     }
 
     /**
+     * Reads in an XML file and returns it as a new {@link DOMElementItem}.
+     * 
+     * @param path classpath path to the data file, never null
+     * 
+     * @return an {@link Item} wrapping the document representing the data file, never null
+     * 
+     * @throws XMLParserExceptionthrown if the file does not exist or there is a problem parsing it
+     */
+    public Item<Element> readDOMItem(final String path) throws XMLParserException {
+        final Element e = readXMLData(path);
+        return new DOMElementItem(e);
+    }
+
+    /**
      * Checks whether two nodes are identical based on {@link Diff#identical()}.
      * 
      * @param expected the expected node against which the actual node will be tested, never null
@@ -108,4 +127,10 @@ public abstract class BaseDOMTest extends BaseTest {
         }
     }
     
+    protected int countErrors(final Item<Element> item) {
+        final ClassToInstanceMultiMap<ItemMetadata> metadata = item.getItemMetadata();
+        final List<ErrorStatus> errors = metadata.get(ErrorStatus.class);
+        return errors.size();
+    }
+    
 }
diff --git a/aggregator-pipeline/src/test/java/net/shibboleth/metadata/validate/x509/X509RSAExponentValidatorTest.java b/aggregator-pipeline/src/test/java/net/shibboleth/metadata/validate/x509/X509RSAExponentValidatorTest.java
index 83463e4..b76d45d 100644
--- a/aggregator-pipeline/src/test/java/net/shibboleth/metadata/validate/x509/X509RSAExponentValidatorTest.java
+++ b/aggregator-pipeline/src/test/java/net/shibboleth/metadata/validate/x509/X509RSAExponentValidatorTest.java
@@ -7,6 +7,7 @@ import net.shibboleth.metadata.Item;
 import net.shibboleth.metadata.MockItem;
 import net.shibboleth.metadata.validate.Validator;
 
+import org.testng.Assert;
 import org.testng.annotations.Test;
 
 public class X509RSAExponentValidatorTest extends BaseX509ValidatorTest {
@@ -21,7 +22,7 @@ public class X509RSAExponentValidatorTest extends BaseX509ValidatorTest {
             final int expectedErrors, final int expectedWarnings) throws Exception {
         final Item<String> item = new MockItem("foo");
         final X509Certificate cert = getCertificate(certName);
-        val.validate(cert, item, "stage");
+        Assert.assertEquals(val.validate(cert, item, "stage"), Validator.Action.CONTINUE);
         errorsAndWarnings(item, expectedErrors, expectedWarnings);
     }
 
diff --git a/aggregator-pipeline/src/test/java/net/shibboleth/metadata/validate/x509/X509RSAKeyLengthValidatorTest.java b/aggregator-pipeline/src/test/java/net/shibboleth/metadata/validate/x509/X509RSAKeyLengthValidatorTest.java
index 056ce14..7d9f701 100644
--- a/aggregator-pipeline/src/test/java/net/shibboleth/metadata/validate/x509/X509RSAKeyLengthValidatorTest.java
+++ b/aggregator-pipeline/src/test/java/net/shibboleth/metadata/validate/x509/X509RSAKeyLengthValidatorTest.java
@@ -7,6 +7,7 @@ import net.shibboleth.metadata.Item;
 import net.shibboleth.metadata.MockItem;
 import net.shibboleth.metadata.validate.Validator;
 
+import org.testng.Assert;
 import org.testng.annotations.Test;
 
 public class X509RSAKeyLengthValidatorTest extends BaseX509ValidatorTest {
@@ -21,7 +22,7 @@ public class X509RSAKeyLengthValidatorTest extends BaseX509ValidatorTest {
         final Item<String> item = new MockItem("foo");
         final Validator<X509Certificate> val = new X509RSAKeyLengthValidator();
         final X509Certificate cert = getCertificate("2048.pem");
-        val.validate(cert, item, "stage");
+        Assert.assertEquals(val.validate(cert, item, "stage"), Validator.Action.CONTINUE);
         errorsAndWarnings(item, 0, 0);
     }
 
@@ -30,7 +31,7 @@ public class X509RSAKeyLengthValidatorTest extends BaseX509ValidatorTest {
         final Item<String> item = new MockItem("foo");
         final Validator<X509Certificate> val = new X509RSAKeyLengthValidator();
         final X509Certificate cert = getCertificate("1024.pem");
-        val.validate(cert, item, "stage");
+        Assert.assertEquals(val.validate(cert, item, "stage"), Validator.Action.CONTINUE);
         errorsAndWarnings(item, 1, 0);
     }
 
@@ -41,7 +42,7 @@ public class X509RSAKeyLengthValidatorTest extends BaseX509ValidatorTest {
         val.setErrorBoundary(1024);
         val.setWarningBoundary(2048);
         final X509Certificate cert = getCertificate("1024.pem");
-        val.validate(cert, item, "stage");
+        Assert.assertEquals(val.validate(cert, item, "stage"), Validator.Action.CONTINUE);
         errorsAndWarnings(item, 0, 1);
     }
 
diff --git a/aggregator-pipeline/src/test/java/net/shibboleth/metadata/validate/x509/X509RSAOpenSSLBlacklistValidatorTest.java b/aggregator-pipeline/src/test/java/net/shibboleth/metadata/validate/x509/X509RSAOpenSSLBlacklistValidatorTest.java
index b0d198c..94bd213 100644
--- a/aggregator-pipeline/src/test/java/net/shibboleth/metadata/validate/x509/X509RSAOpenSSLBlacklistValidatorTest.java
+++ b/aggregator-pipeline/src/test/java/net/shibboleth/metadata/validate/x509/X509RSAOpenSSLBlacklistValidatorTest.java
@@ -9,6 +9,7 @@ import org.testng.annotations.Test;
 
 import net.shibboleth.metadata.Item;
 import net.shibboleth.metadata.MockItem;
+import net.shibboleth.metadata.validate.Validator;
 
 public class X509RSAOpenSSLBlacklistValidatorTest extends BaseX509ValidatorTest {
     
@@ -26,7 +27,7 @@ public class X509RSAOpenSSLBlacklistValidatorTest extends BaseX509ValidatorTest
         
         final Item<String> item = new MockItem("foo");
         final X509Certificate cert = getCertificate("ok.pem");
-        val.validate(cert, item, "stage");
+        Assert.assertEquals(val.validate(cert, item, "stage"), Validator.Action.CONTINUE);
         errorsAndWarnings(item, 0, 0);
     }
 
@@ -39,7 +40,7 @@ public class X509RSAOpenSSLBlacklistValidatorTest extends BaseX509ValidatorTest
         
         final Item<String> item = new MockItem("foo");
         final X509Certificate cert = getCertificate("1024.pem");
-        val.validate(cert, item, "stage");
+        Assert.assertEquals(val.validate(cert, item, "stage"), Validator.Action.CONTINUE);
         errorsAndWarnings(item, 1, 0);
     }
 
@@ -52,7 +53,7 @@ public class X509RSAOpenSSLBlacklistValidatorTest extends BaseX509ValidatorTest
         
         final Item<String> item = new MockItem("foo");
         final X509Certificate cert = getCertificate("1024.pem");
-        val.validate(cert, item, "stage");
+        Assert.assertEquals(val.validate(cert, item, "stage"), Validator.Action.CONTINUE);
         errorsAndWarnings(item, 1, 0);
     }
 
@@ -65,7 +66,7 @@ public class X509RSAOpenSSLBlacklistValidatorTest extends BaseX509ValidatorTest
         
         final Item<String> item = new MockItem("foo");
         final X509Certificate cert = getCertificate("1024.pem");
-        val.validate(cert, item, "stage");
+        Assert.assertEquals(val.validate(cert, item, "stage"), Validator.Action.CONTINUE);
         errorsAndWarnings(item, 0, 0);
     }
 
@@ -79,7 +80,7 @@ public class X509RSAOpenSSLBlacklistValidatorTest extends BaseX509ValidatorTest
         final Item<String> item = new MockItem("foo");
         final X509Certificate cert = getCertificate("2048.pem");
         val.validate(cert, item, "stage");
-        errorsAndWarnings(item, 0, 0);
+        Assert.assertEquals(val.validate(cert, item, "stage"), Validator.Action.CONTINUE);
     }
 
     @Test
@@ -92,7 +93,7 @@ public class X509RSAOpenSSLBlacklistValidatorTest extends BaseX509ValidatorTest
         final Item<String> item = new MockItem("foo");
         final X509Certificate cert = getCertificate("2048.pem");
         val.validate(cert, item, "stage");
-        errorsAndWarnings(item, 1, 0);
+        Assert.assertEquals(val.validate(cert, item, "stage"), Validator.Action.CONTINUE);
     }
 
     @Test
@@ -105,7 +106,7 @@ public class X509RSAOpenSSLBlacklistValidatorTest extends BaseX509ValidatorTest
         final Item<String> item = new MockItem("foo");
         final X509Certificate cert = getCertificate("2048.pem");
         val.validate(cert, item, "stage");
-        errorsAndWarnings(item, 1, 0);
+        Assert.assertEquals(val.validate(cert, item, "stage"), Validator.Action.CONTINUE);
     }
 
     @Test
@@ -117,7 +118,7 @@ public class X509RSAOpenSSLBlacklistValidatorTest extends BaseX509ValidatorTest
         
         final Item<String> item = new MockItem("foo");
         final X509Certificate cert = getCertificate("2048.pem");
-        val.validate(cert, item, "stage");
+        Assert.assertEquals(val.validate(cert, item, "stage"), Validator.Action.CONTINUE);
         errorsAndWarnings(item, 0, 0);
     }
 
@@ -137,7 +138,7 @@ public class X509RSAOpenSSLBlacklistValidatorTest extends BaseX509ValidatorTest
         
         final Item<String> item = new MockItem("foo");
         final X509Certificate cert = getCertificate("2048.pem");
-        val.validate(cert, item, "stage");
+        Assert.assertEquals(val.validate(cert, item, "stage"), Validator.Action.CONTINUE);
         errorsAndWarnings(item, 1, 0);
     }
     
diff --git a/aggregator-pipeline/src/test/resources/net/shibboleth/metadata/dom/AbstractDOMValidationStage-early.xml b/aggregator-pipeline/src/test/resources/net/shibboleth/metadata/dom/AbstractDOMValidationStage-early.xml
new file mode 100644
index 0000000..289c3e1
--- /dev/null
+++ b/aggregator-pipeline/src/test/resources/net/shibboleth/metadata/dom/AbstractDOMValidationStage-early.xml
@@ -0,0 +1,5 @@
+<root>
+    <checkedElement>one</checkedElement>
+    <checkedElement>two</checkedElement>
+    <uncheckedElement>three</uncheckedElement>
+</root>

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list