[java-identity-provider] 03/06: IDP-1595 Add a class to capture the current Plugin state

Rod Widdowson rdw at steadingsoftware.com
Wed May 20 16:04:59 UTC 2020


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

rdw pushed a commit to branch dev/IDP-1595
in repository java-identity-provider.

View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=d5af891085f42c45e30c07c9c8ddc2a469d5a4e0

commit d5af891085f42c45e30c07c9c8ddc2a469d5a4e0
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Mon May 11 16:25:20 2020 +0100

    IDP-1595 Add a class to capture the current Plugin state
    
    https://issues.shibboleth.net/jira/browse/IDP-1595
    
    and tests
---
 .../idp/installer/plugin/PluginSupport.java        |  68 ++++
 .../idp/installer/plugin/impl/PluginState.java     | 358 +++++++++++++++++++++
 .../idp/installer/plugin/impl/package-info.java    |  21 ++
 .../idp/installer/plugin/impl/PluginStateTest.java |  98 ++++++
 .../idp/installer/plugin/impl/TestPlugin.java      |  66 ++++
 .../1.2.3/version.details.properties               |   3 +
 .../1.2.4/version.details.properties               |   3 +
 .../2.0.0/version.details.properties               |   3 +
 .../net.shibboleth.plugin.test/versions.properties |   1 +
 9 files changed, 621 insertions(+)

diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/PluginSupport.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/PluginSupport.java
new file mode 100644
index 000000000..e68827978
--- /dev/null
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/PluginSupport.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.installer.plugin;
+
+import javax.annotation.Nonnull;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.shibboleth.idp.Version;
+
+/** Useful methods for supporting plugins. 
+ *
+ */
+public final class PluginSupport {
+    
+    /** Where (relatively) to find available versions. */
+    @Nonnull public static final String AVAILABLE_VERSIONS_PATH = "versions.properties";
+
+    /** Where (relatively) to find available versions. */
+    @Nonnull public static final String VERSION_INFO_PATH = "version.details.properties";
+
+    /** Property Name for available versions inside {@link #AVAILABLE_VERSIONS_PATH}. */
+    @Nonnull public static final String AVAILABLE_VERSIONS_PROPERTY_SUFFIX = ".versions";
+
+    /** Property Name for max supported IdP version inside {@link #VERSION_INFO_PATH}. */
+    @Nonnull public static final String MAX_IDP_VERSION = "idp.version.max";
+    
+    /** Property Name for minimum supported IdP version inside {@link #VERSION_INFO_PATH}. */
+    @Nonnull public static final String MIN_IDP_VERSION = "idp.version.min";
+
+    /** Property Name for support level inside {@link #VERSION_INFO_PATH}. */
+    @Nonnull public static final String SUPPORT_LEVEL = "support.level";
+    
+    /** Class logger. */
+    @Nonnull private static Logger log = LoggerFactory.getLogger(PluginSupport.class);
+    
+    /** Constructor. */
+    private PluginSupport() {
+    }
+
+    /** Get parse IdP Version (with fallback for testing).
+     * @return a {@link PluginVersion} of the version.
+     */
+    public static PluginVersion getIdPVersion() {
+        final String idpVersion = Version.getVersion();
+        if (idpVersion!=null) {
+            return new PluginVersion(idpVersion);
+        }
+        log.error("Could not locate IdP Version, assuming 4.1.0");
+        return new PluginVersion(4,1,0);
+    }
+}
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginState.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginState.java
new file mode 100644
index 000000000..0b1143093
--- /dev/null
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginState.java
@@ -0,0 +1,358 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.installer.plugin.impl;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.regex.Pattern;
+
+import javax.annotation.Nonnull;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.shibboleth.idp.installer.plugin.PluginSupport;
+import net.shibboleth.idp.installer.plugin.PluginVersion;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.plugin.PluginDescription;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.utilities.java.support.resource.Resource;
+
+/**
+ * A class which will answer questions about a plugin state as of now
+ * (by querying the information Resources for the current published state). 
+ */
+public final class PluginState extends AbstractInitializableComponent {
+
+    /** regexp for spaces. */
+    private static final Pattern SPACE_CONTAINING = Pattern.compile("\\s+");
+
+    /** The plug in in question. */
+    @Nonnull private final PluginDescription plugin;
+    
+    /** The version of this plugin. */
+    @Nonnull private final PluginVersion myPluginVersion;
+    
+    /** The support information. */
+    @Nonnull private final Map<PluginVersion, VersionInfo> versionInfo = new HashMap<>();
+    
+    /** My support information. */
+    @NonnullAfterInit private VersionInfo myVersionInfo;
+    
+    /** Class logger. */
+    @Nonnull private final Logger log = LoggerFactory.getLogger(PluginState.class);
+    
+    /**
+     * Constructor.
+     *
+     * @param description what we are talking about.
+     */
+    public PluginState(@Nonnull final PluginDescription description) {
+        plugin = Constraint.isNotNull(description, "Plugin must not be null");
+        myPluginVersion = new PluginVersion(plugin.getMajorVersion(), 
+                plugin.getMinorVersion(), plugin.getPatchVersion());
+    }
+    
+    /** Given a version find out more.
+     * @param parentResource the root we are looking at
+     * @param version the version in question.
+     * @return true if we processed everything OK.
+     */
+    // Checkstyle: CyclomaticComplexity OFF
+    private boolean handleAvailableVersion(final Resource parentResource, final String version) {
+        final Properties detailsProps = new Properties(3);
+        final PluginVersion theVersion = new PluginVersion(version);
+        if (theVersion.getMajor() == 0 && theVersion.getMinor() == 0 && theVersion.getPatch() == 0) {
+            log.warn("Plugin {}: improbable version {}", plugin.getPluginId(), version);
+        }
+        if (versionInfo.containsKey(theVersion)) {
+            log.warn("Plugin {}: Duplicate version {}", plugin.getPluginId(), version);
+        }
+        
+        try {
+            final Resource details = parentResource.createRelativeResource(version + "/")
+                    .createRelativeResource(PluginSupport.VERSION_INFO_PATH);
+            detailsProps.load(details.getInputStream());
+        } catch (final IOException e) {
+            log.warn("Could not find details description {}, version {} ", plugin.getPluginId(), version, e);
+            return false;
+        }
+        log.debug("Plugin {}: Version details : {}", plugin.getPluginId(), detailsProps);
+        final String maxVersionInfo = StringSupport.trimOrNull(detailsProps.getProperty(PluginSupport.MAX_IDP_VERSION));
+        if (maxVersionInfo == null) {
+            log.warn("Plugin {}: Could not find max idp version for version {} ", plugin.getPluginId(), version);
+            return false;
+        }
+        final String minVersionInfo = StringSupport.trimOrNull(detailsProps.getProperty(PluginSupport.MIN_IDP_VERSION));
+        if (minVersionInfo == null) {
+            log.warn("Plugin {}: Could not find min idp version for version {} ", plugin.getPluginId(), version);
+            return false;
+        }
+        final String supportLevel = StringSupport.trimOrNull(detailsProps.getProperty(PluginSupport.SUPPORT_LEVEL));
+        if (supportLevel == null) {
+            log.warn("Plugin {}: Could not find support level for {}, version {} ", plugin.getPluginId(), version);
+            return false;
+        }
+        log.debug("Plugin {}: MaxIdP {}, MinIdP {}, Support Level {}", 
+                plugin.getPluginId(), maxVersionInfo, minVersionInfo, supportLevel);
+        final VersionInfo info; 
+        try {
+            info = new VersionInfo(
+                new PluginVersion(maxVersionInfo),
+                new PluginVersion(minVersionInfo),
+                Integer.parseInt(supportLevel));
+        } catch (final NumberFormatException e) {
+            log.warn("Plugin {}: version {}: Could not parse version info",
+                    plugin.getPluginId(), version, e);
+            return false;
+        }
+        versionInfo.put(theVersion, info);
+        if (myPluginVersion.equals(theVersion)) {
+            myVersionInfo = info;
+        }
+        return true;
+    }
+    // Checkstyle: CyclomaticComplexity ON
+
+    /** Given a list of versions find out more.
+     * @param parentResource the root we are looking at
+     * @param availableVersions a space delimited array of versions
+     * @return true if we processed everything OK.
+     */
+    private boolean handleAvailableVersions(final Resource parentResource, final String availableVersions) {
+        final String[] versions = SPACE_CONTAINING.split(availableVersions, 0);
+
+        log.debug("Plugin {}: available versions : {} ", plugin.getPluginId(), availableVersions);
+        for (final String version:versions) {
+            log.debug("Plugin {} : considering {}", plugin.getPluginId(), version);
+            if (!handleAvailableVersion(parentResource, version)) {
+                return false;
+           }
+        }
+        return true;
+    }
+    
+    /** (try to) populate the information about this plugin.
+     * @param parentResource where to start looking
+     * @return whether it worked
+     */
+    protected boolean populate(@Nonnull final Resource parentResource) {
+        
+        final Resource pluginIdResource;
+        try {
+            pluginIdResource = 
+                    parentResource.createRelativeResource(plugin.getPluginId() + "/");
+            if (!pluginIdResource.exists()) {
+                log.debug("Plugin {}: directory at {} could not be found",
+                        plugin.getPluginId(), parentResource.getDescription());
+                return false;
+            }
+        } catch (final IOException e) {
+            log.info("Plugin{}: problems open directory at {}",
+                        plugin.getPluginId(), parentResource.getDescription(), e);
+            return false;
+        }
+        try {
+            final Resource versionsResource =
+                    pluginIdResource.createRelativeResource(PluginSupport.AVAILABLE_VERSIONS_PATH);
+            final Properties versionsProps = new Properties(1);
+            versionsProps.load(versionsResource.getInputStream());
+            final String name = plugin.getPluginId() + PluginSupport.AVAILABLE_VERSIONS_PROPERTY_SUFFIX;
+            final String availableVersions = StringSupport.trim(versionsProps.getProperty(name));
+            if (availableVersions.length() == 0) {
+                log.warn("Plugin {}: Could not find {} property in {}", 
+                        plugin.getPluginId(), name, parentResource.getDescription());
+                return false;
+            }
+            return handleAvailableVersions(pluginIdResource, availableVersions);
+        } catch (final IOException e) {
+            // INFO - not being there is not a failure
+            log.info("Plugin {}: Could not find description {}", 
+                    plugin.getPluginId(), parentResource.getDescription(), e);
+            return false;
+        }
+    }
+        
+    /** {@inheritDoc} */
+    protected void doInitialize() throws ComponentInitializationException {
+        
+        for (final Resource parent:plugin.getUpdateResources()) {
+           
+            log.debug("Plugin {}: Looking for update at {}", plugin.getPluginId(), parent.getDescription());
+            if (!parent.exists()) {
+                log.info("Plugin {}: {} could not be located", plugin.getPluginId(), parent.getDescription());
+                continue;
+            }
+            
+            if (populate(parent)) { 
+                log.debug("Plugin {}: PluginState populated from {}", plugin.getPluginId(), parent.getDescription());
+                if (myVersionInfo == null) {
+                    log.error("Plugin {} : Could not find version {} in descriptions at {}",
+                            plugin.getPluginId(), myPluginVersion, parent.getDescription());
+                }
+                return;
+            }
+        }
+        log.warn("Plugin {}: No available servers found.");
+        throw new ComponentInitializationException("Could not locate information for " + plugin.getPluginId());
+    }
+    
+    /** Get the current support level for this version.
+     * @return the level
+     */
+    public int getSupportLevel() {
+        ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this);
+        return myVersionInfo.getSupportLevel();
+    }
+
+    /** Is this plugin supported with the current IdP?
+     * @return whether it is supported.
+     */
+    public boolean isSupportedWithIdPVersion() {
+        return isSupportedWithIdPVersion(PluginSupport.getIdPVersion());
+    }
+    
+    /** Is this plugin supported with this IdP version.
+     * @param idPVersion the version as a {@link String}
+     * @return whether it is supported.
+     */
+    public boolean isSupportedWithIdPVersion(final String idPVersion) {
+        return isSupportedWithIdPVersion(new PluginVersion(idPVersion));
+    }
+    
+    /** Is this plugin supported with this IdP version.
+     * @param idPVersion the version as a {@link PluginVersion}
+     * @return whether it is supported.
+     */
+    public boolean isSupportedWithIdPVersion(final PluginVersion idPVersion) {
+        return isSupportedWithIdPVersion(myVersionInfo, idPVersion);
+    }
+    
+    /** Is the specified plugin supported with this IdP version.
+     * @param pluginVersion the version if the plugin as a {@link PluginVersion}
+     * @param idPVersion the version if the IDP as a {@link PluginVersion}
+     * @return whether it is supported.
+     */
+    public boolean isSupportedWithIdPVersion(final PluginVersion pluginVersion, final PluginVersion idPVersion) {
+        final VersionInfo info = versionInfo.get(pluginVersion);
+        
+        if (info == null) {
+            log.error("Plugin: {} Non existant version {} supplied.", plugin.getPluginId(), pluginVersion);
+            log.debug("Plugin: {} available {}", plugin.getPluginId(), versionInfo.keySet());
+            return false;
+        }
+        
+        return isSupportedWithIdPVersion(info, idPVersion);
+    }
+    
+    /** Is the specified plugin supported with this IdP version.
+     * @param pluginVersion the version if the plugin as a {@link PluginVersion}
+     * @param idPVersion the version if the IDP as a {@link String}
+     * @return whether it is supported.
+     */
+    public boolean isSupportedWithIdPVersion(final PluginVersion pluginVersion, final String idPVersion) {
+        return isSupportedWithIdPVersion(pluginVersion, new PluginVersion(idPVersion));
+    }
+        
+    /** Is the specified plugin supported with this IdP version.
+     * Worker method for all 'isSupportedWith' classes.
+     * @param pluginVersionInfo the version info to consider
+     * @param idPVersion the version as a {@link PluginVersion}
+     * @return whether it is supported.
+     */
+    protected boolean isSupportedWithIdPVersion(final VersionInfo pluginVersionInfo, final PluginVersion idPVersion) {
+        ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this);
+        final int maxCompare = idPVersion.compareTo(pluginVersionInfo.getMaxSupported()); 
+        
+        if (maxCompare >= 0) {
+            // Exclusive:
+            // IdP (test against) Version is GREATER THAN OR EQUAL to our Max
+            return false;
+        }
+        final int minCompare = idPVersion.compareTo(pluginVersionInfo.getMinSupported());
+        if (minCompare >= 0) {
+            // Inclusive:
+            // IdP (test against) version is GREATER THAN OR EQUAL to our Min
+            return true;
+        }
+        return false;
+    }
+    
+    /** Return all announced versions.
+     * @return the versions.
+     */
+    @Nonnull @NotEmpty public Collection<PluginVersion> getAvailableVersions() {
+        ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this);
+        return versionInfo.keySet();
+    }
+    
+    /** Encapsulation of the information about a given IdP version. */
+    protected static class VersionInfo {
+        
+        /** Maximum version - this version is NOT SUPPORTED. */ 
+        private final PluginVersion maxSupported; 
+
+        /** Minimum version - this version IS supported. */ 
+        private final PluginVersion minSupported; 
+        
+        /** support level. */
+        private final int supportLevel;
+        
+        /**
+         * Constructor.
+         *
+         * @param max support level
+         * @param min support level
+         * @param support support level
+         */
+        VersionInfo(final PluginVersion max, final PluginVersion min, final int support) {
+            maxSupported = max;
+            minSupported = min;
+            supportLevel = support;
+        }
+
+        /** get Maximum version - this version is NOT SUPPORTED.
+         * @return Returns the maxSupported.
+         */
+        public PluginVersion getMaxSupported() {
+            return maxSupported;
+        }
+
+        /** get Minimum (IdP) version - this version IS supported.
+         * @return Returns the minSupported.
+         */
+        public PluginVersion getMinSupported() {
+            return minSupported;
+        }
+
+        /** get support level.
+         * @return Returns the supportLevel.
+         */
+        public int getSupportLevel() {
+            return supportLevel;
+        }
+    }
+}
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/package-info.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/package-info.java
new file mode 100644
index 000000000..219482d7f
--- /dev/null
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Classes for handling plugins.
+ */
+
+package net.shibboleth.idp.installer.plugin.impl;
\ No newline at end of file
diff --git a/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/PluginStateTest.java b/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/PluginStateTest.java
new file mode 100644
index 000000000..a083c11c4
--- /dev/null
+++ b/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/PluginStateTest.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.installer.plugin.impl;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.testng.annotations.Test;
+
+import net.shibboleth.ext.spring.resource.HTTPResource;
+import net.shibboleth.idp.installer.plugin.PluginVersion;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.httpclient.HttpClientBuilder;
+import net.shibboleth.utilities.java.support.plugin.PluginDescription;
+import net.shibboleth.utilities.java.support.resource.Resource;
+
+/**
+ * Tests for {@link PluginState}.
+ */
+ at SuppressWarnings("javadoc")
+public class PluginStateTest {
+
+    @Test
+    public void testSimple() throws ComponentInitializationException {
+
+        final PluginDescription simple = new TestPlugin();
+        
+        final PluginState state = new PluginState(simple);
+        
+        state.initialize();
+        
+        assertEquals(state.getAvailableVersions().size(), 3);
+        assertTrue(state.getAvailableVersions().contains(new PluginVersion(1, 2, 3)));
+        assertTrue(state.getAvailableVersions().contains(new PluginVersion(1, 2, 4)));
+        assertTrue(state.getAvailableVersions().contains(new PluginVersion(2,0,0)));
+        assertFalse(state.getAvailableVersions().contains(new PluginVersion(3, 2, 3)));
+
+        assertTrue(state.isSupportedWithIdPVersion("4.2.0"));
+        assertTrue(state.isSupportedWithIdPVersion("4.99.9"));
+        assertFalse(state.isSupportedWithIdPVersion("5.0.0"));
+        assertFalse(state.isSupportedWithIdPVersion("4.1.0"));
+
+        final PluginVersion v124 = new PluginVersion(1,2,3);        
+        assertTrue(state.isSupportedWithIdPVersion(v124, "4.1.0"));
+        assertTrue(state.isSupportedWithIdPVersion(v124, "4.99.9"));
+        assertFalse(state.isSupportedWithIdPVersion(v124, "5.0.0"));
+        assertFalse(state.isSupportedWithIdPVersion(v124, "4.0.0"));
+
+        final PluginVersion v2 = new PluginVersion(2,0,0);
+        assertTrue(state.isSupportedWithIdPVersion(v2, "4.99.1"));
+        assertTrue(state.isSupportedWithIdPVersion(v2, "4.99.999"));
+        assertFalse(state.isSupportedWithIdPVersion(v2, "4.99.0"));
+        assertFalse(state.isSupportedWithIdPVersion(v2, "4.98.999"));
+        assertTrue(state.isSupportedWithIdPVersion(v2, "5.0.0"));
+        assertTrue(state.isSupportedWithIdPVersion(v2, "6.0.0"));
+        assertTrue(state.isSupportedWithIdPVersion(v2, "7.0.0"));
+        assertFalse(state.isSupportedWithIdPVersion(v2, "8"));
+        
+    }
+    
+    @Test
+    public void testMulti() throws IOException, Exception {
+
+        Resource res = new HTTPResource(new HttpClientBuilder().buildClient(), "http://example.org/dir");
+        
+        final PluginDescription simple = new TestPlugin() {
+            /** {@inheritDoc} */
+            public List<Resource> getUpdateResources() {
+                return List.of(res, super.getUpdateResources().get(0));
+            }
+        };
+        
+        final PluginState state = new PluginState(simple);
+        state.initialize();
+        
+        assertEquals(state.getAvailableVersions().size(), 3);
+        assertEquals(state.getSupportLevel(),1);
+    }
+}
diff --git a/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/TestPlugin.java b/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/TestPlugin.java
new file mode 100644
index 000000000..caf612170
--- /dev/null
+++ b/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/TestPlugin.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.installer.plugin.impl;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.springframework.core.io.ClassPathResource;
+
+import net.shibboleth.ext.spring.resource.ResourceHelper;
+import net.shibboleth.utilities.java.support.plugin.PluginDescription;
+import net.shibboleth.utilities.java.support.resource.Resource;
+
+/**
+ *
+ */
+public class TestPlugin extends PluginDescription {
+
+    /** {@inheritDoc} */
+    @Override
+    public String getPluginId() {
+        // TODO Auto-generated method stub
+        return "net.shibboleth.plugin.test";
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public List<Resource> getUpdateResources() {
+        ClassPathResource resource = new ClassPathResource("/net/shibboleth/idp/installer/plugin/");
+        return Collections.singletonList(ResourceHelper.of(resource));
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getMajorVersion() {
+        return 1;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getMinorVersion() {
+        return 2;
+    }
+    
+
+    /** {@inheritDoc} */
+    @Override
+    public int getPatchVersion() {
+        return 3;
+    }
+}
diff --git a/idp-installer/src/test/resources/net/shibboleth/idp/installer/plugin/net.shibboleth.plugin.test/1.2.3/version.details.properties b/idp-installer/src/test/resources/net/shibboleth/idp/installer/plugin/net.shibboleth.plugin.test/1.2.3/version.details.properties
new file mode 100644
index 000000000..ccce079b9
--- /dev/null
+++ b/idp-installer/src/test/resources/net/shibboleth/idp/installer/plugin/net.shibboleth.plugin.test/1.2.3/version.details.properties
@@ -0,0 +1,3 @@
+idp.version.max=5.0.0
+idp.version.min=4.1.0
+support.level = 2
diff --git a/idp-installer/src/test/resources/net/shibboleth/idp/installer/plugin/net.shibboleth.plugin.test/1.2.4/version.details.properties b/idp-installer/src/test/resources/net/shibboleth/idp/installer/plugin/net.shibboleth.plugin.test/1.2.4/version.details.properties
new file mode 100644
index 000000000..79f7b8621
--- /dev/null
+++ b/idp-installer/src/test/resources/net/shibboleth/idp/installer/plugin/net.shibboleth.plugin.test/1.2.4/version.details.properties
@@ -0,0 +1,3 @@
+idp.version.max=5.0.0
+idp.version.min=4.2.0
+support.level = 1
diff --git a/idp-installer/src/test/resources/net/shibboleth/idp/installer/plugin/net.shibboleth.plugin.test/2.0.0/version.details.properties b/idp-installer/src/test/resources/net/shibboleth/idp/installer/plugin/net.shibboleth.plugin.test/2.0.0/version.details.properties
new file mode 100644
index 000000000..1eab454b5
--- /dev/null
+++ b/idp-installer/src/test/resources/net/shibboleth/idp/installer/plugin/net.shibboleth.plugin.test/2.0.0/version.details.properties
@@ -0,0 +1,3 @@
+idp.version.max=8.0.0
+idp.version.min=4.99.1
+support.level = 2
diff --git a/idp-installer/src/test/resources/net/shibboleth/idp/installer/plugin/net.shibboleth.plugin.test/versions.properties b/idp-installer/src/test/resources/net/shibboleth/idp/installer/plugin/net.shibboleth.plugin.test/versions.properties
new file mode 100644
index 000000000..8577686cf
--- /dev/null
+++ b/idp-installer/src/test/resources/net/shibboleth/idp/installer/plugin/net.shibboleth.plugin.test/versions.properties
@@ -0,0 +1 @@
+net.shibboleth.plugin.test.versions=1.2.3 1.2.4 2.0.0
\ No newline at end of file

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


More information about the commits mailing list