[java-identity-provider] 01/13: IDP-1699 Warn if updating an IdP with an unsupported plugin

Rod Widdowson rdw at steadingsoftware.com
Sun Jun 6 11:40:41 UTC 2021


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

rdw pushed a commit to branch main
in repository java-identity-provider.

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

commit aee6246bfbff3634138f8bd6e9bf9c13a65985ea
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Tue Apr 27 16:06:25 2021 +0100

    IDP-1699 Warn if updating an IdP with an unsupported plugin
    
    https://issues.shibboleth.net/jira/browse/IDP-1699
---
 .../idp/installer/CurrentInstallState.java         |  7 +++
 .../net/shibboleth/idp/installer/V4Install.java    | 19 ++++++++
 .../installer/impl/CurrentInstallStateImpl.java    | 57 ++++++++++++++++++++++
 .../idp/installer/plugin/impl/PluginInstaller.java |  3 +-
 .../java/net/shibboleth/idp/installer/Test.java    |  6 +--
 5 files changed, 88 insertions(+), 4 deletions(-)

diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/CurrentInstallState.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/CurrentInstallState.java
index 8c54b2358..f73455adf 100644
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/CurrentInstallState.java
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/CurrentInstallState.java
@@ -83,4 +83,11 @@ public interface CurrentInstallState extends InitializableComponent {
     default @Nonnull Collection<String> getEnabledModules() {
         return Collections.emptySet();
     }
+
+    /** Build a classpath loader which adds all the plugins in.
+     * @return a classloader
+     */
+    default ClassLoader getInstalledPluginsLoader() {
+        return this.getClass().getClassLoader();
+    }
 }
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/V4Install.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/V4Install.java
index 941f28fd4..38899abeb 100644
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/V4Install.java
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/V4Install.java
@@ -48,9 +48,12 @@ import org.springframework.core.io.Resource;
 
 import net.shibboleth.ext.spring.util.ApplicationContextBuilder;
 import net.shibboleth.idp.Version;
+import net.shibboleth.idp.installer.plugin.impl.PluginState;
 import net.shibboleth.idp.module.IdPModule;
 import net.shibboleth.idp.module.ModuleContext;
 import net.shibboleth.idp.module.ModuleException;
+import net.shibboleth.idp.plugin.IdPPlugin;
+import net.shibboleth.idp.plugin.PluginVersion;
 import net.shibboleth.idp.spring.IdPPropertiesApplicationContextInitializer;
 import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
 import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
@@ -142,6 +145,22 @@ public class V4Install extends AbstractInitializableComponent {
                 throw new BuildException("Install failed: system will not work after V4 upgrade");
             }
         }
+        final PluginVersion idpVersion = new PluginVersion(Version.getVersion());
+        for (final IdPPlugin plugin: ServiceLoader.load(IdPPlugin.class, currentState.getInstalledPluginsLoader())) {
+            final String pluginId = plugin.getPluginId();
+            final PluginVersion pluginVersion = new PluginVersion(plugin);
+            try {
+                log.debug("Considering Plugin {}, version {}", pluginId,  pluginVersion);
+                final PluginState state = new PluginState(plugin, Collections.emptyList());
+                state.initialize();
+                if (!state.isSupportedWithIdPVersion(pluginVersion, idpVersion)) {
+                    log.warn("Installed Plugin {} version {} is not supported with IdP Version {}, continuing.",
+                            pluginId, pluginVersion, idpVersion);
+                }
+            } catch (final ComponentInitializationException e) {
+                log.error("Could not process plugin {}, continuing", plugin.getPluginId(),e);
+            }
+        }
     }
 
     /** Report the to be installed and (if there is one) current versions. 
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/CurrentInstallStateImpl.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/CurrentInstallStateImpl.java
index d7111c4ca..df3d77021 100644
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/CurrentInstallStateImpl.java
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/CurrentInstallStateImpl.java
@@ -21,8 +21,16 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -37,6 +45,7 @@ import java.util.Set;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
+import org.apache.tools.ant.BuildException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -83,6 +92,9 @@ public final class CurrentInstallStateImpl extends AbstractInitializableComponen
     /** The files to delete after an upgrade. */
     @NonnullAfterInit private List<Path> pathsToDelete;
 
+    /** The classloader for "us plus the plugins in the target". */
+    @Nullable private ClassLoader installedPluginsLoader;
+
     /** Constructor.
      * @param installerProps the installer situation.
      */
@@ -250,4 +262,49 @@ public final class CurrentInstallStateImpl extends AbstractInitializableComponen
     @Nonnull public Collection<String> getEnabledModules() {
         return enabledModules;
     }
+
+    /** {@inheritDoc} */
+    public synchronized ClassLoader getInstalledPluginsLoader() {
+
+        if (installedPluginsLoader != null) {
+            return installedPluginsLoader;
+        }
+        final Path libs = targetDir.resolve("dist").resolve("plugin-webapp").resolve("WEB-INF").resolve("lib");
+        final URL[] urls;
+        if (Files.exists(libs)) {
+            try {
+                final List<Path> copiedFiles = new ArrayList<>();
+                final FileVisitor<Path> visitor = new SimpleFileVisitor<>() {
+                    public FileVisitResult visitFile(final Path file,
+                            final BasicFileAttributes attrs) throws IOException {
+                        copiedFiles.add(file);
+                        return FileVisitResult.CONTINUE;
+                    }
+                };
+                try (final DirectoryStream<Path> webInfLibs = Files.newDirectoryStream(libs)) {
+                    for (final Path jar : webInfLibs) {
+                        visitor.visitFile(jar, null);
+                    }
+                }
+                urls = copiedFiles.
+                        stream().
+                        map( path -> {
+                            try {
+                                return path.toUri().toURL();
+                            } catch (final MalformedURLException e1) {
+                                throw new BuildException(e1);
+                            }
+                        }).
+                        toArray(URL[]::new);
+            } catch (final IOException e) {
+                log.error("Error finding Plugins' classpath", e);
+                installedPluginsLoader = this.getClass().getClassLoader();
+                return installedPluginsLoader;
+            }
+        } else {
+            urls = new URL[0];
+        }
+        installedPluginsLoader = new URLClassLoader(urls);
+        return installedPluginsLoader;
+    }
 }
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginInstaller.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginInstaller.java
index 59b84ace0..61dd267ea 100644
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginInstaller.java
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginInstaller.java
@@ -404,7 +404,7 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
     private void checkRequiredModules(final Set<String> loadedModules) throws BuildException  {
         for (final String moduleId: description.getRequiredModules()) {
             if (!loadedModules.contains(moduleId)) {
-                LOG.warn("Required modules {} is missing on not enabled ", moduleId);
+                LOG.warn("Required module {} is missing or not enabled ", moduleId);
                 throw new BuildException("One or more required modules are not enabled");
             }
         }
@@ -774,6 +774,7 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
 
     /** Generate a {@link URLClassLoader} which looks at the
      * installed WEB-INF/lib in addition to the dist webapp and bin/lib directories.
+     * As a side effect, it also copies the libs (since they may well be overwritten)
      * @return an appropriate loader
      * @throws BuildException if a directory traversal fails.
      */
diff --git a/idp-installer/src/test/java/net/shibboleth/idp/installer/Test.java b/idp-installer/src/test/java/net/shibboleth/idp/installer/Test.java
index 6deac8a3d..18309b0ea 100644
--- a/idp-installer/src/test/java/net/shibboleth/idp/installer/Test.java
+++ b/idp-installer/src/test/java/net/shibboleth/idp/installer/Test.java
@@ -44,11 +44,11 @@ public class Test {
      */
     public static void main(String[] args) throws IOException, ComponentInitializationException {
 
-        System.setProperty(InstallerPropertiesImpl.TARGET_DIR,"H:\\Downloads\\v4install");
+        System.setProperty(InstallerPropertiesImpl.TARGET_DIR,"H:\\Downloads\\idp");
         System.setProperty(InstallerPropertiesImpl.SOURCE_DIR,
-                "h:\\Perforce\\Juno\\New\\java-identity-provider\\idp-distribution\\target\\shibboleth-identity-provider-4.1.0-SNAPSHOT");
+                "h:\\Perforce\\Juno\\New\\java-identity-provider\\idp-distribution\\target\\shibboleth-identity-provider-4.1.1-SNAPSHOT");
         System.setProperty(InstallerPropertiesImpl.ANT_BASE_DIR,
-                "h:\\Perforce\\Juno\\New\\java-identity-provider\\idp-distribution\\target\\shibboleth-identity-provider-4.1.0-SNAPSHOT\\bin");
+                "h:\\Perforce\\Juno\\New\\java-identity-provider\\idp-distribution\\target\\shibboleth-identity-provider-4.1.1-SNAPSHOT\\bin");
         System.setProperty(InstallerPropertiesImpl.KEY_STORE_PASSWORD, "p1");
         System.setProperty(InstallerPropertiesImpl.SEALER_PASSWORD, "p1");
         System.setProperty(InstallerPropertiesImpl.HOST_NAME, "machine.org.uk");

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


More information about the commits mailing list