[java-identity-provider] branch main updated: IDP-1683 Plugins not all go into a common folder in dist

Rod Widdowson rdw at steadingsoftware.com
Sat Oct 10 15:59:38 UTC 2020


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=98f42b5bf05ec12c148ecce8a0f3610057b619fd

The following commit(s) were added to refs/heads/main by this push:
       new  98f42b5bf IDP-1683 Plugins not all go into a common folder in dist
98f42b5bf is described below

commit 98f42b5bf05ec12c148ecce8a0f3610057b619fd
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Sat Oct 10 16:57:10 2020 +0100

    IDP-1683 Plugins not all go into a common folder in dist
    
    We now install all plugins into dist\plugin-webapp.
    The installer knows to look there and the runclass scripts do too
    (unless they are told not to by the "plugin" command).
    
    Fix a hand full of bugs flished by this and further testing
    (notably some classpath issues when emitting the license).
---
 idp-distribution/src/main/resources/bin/plugin.bat |   2 +
 idp-distribution/src/main/resources/bin/plugin.sh  |   1 +
 .../src/main/resources/bin/runclass.bat            |   8 +-
 .../src/main/resources/bin/runclass.sh             |   4 +
 .../net/shibboleth/idp/installer/BuildWar.java     |  26 +----
 .../shibboleth/idp/installer/CopyDistribution.java |   2 +-
 .../idp/installer/plugin/impl/PluginInstaller.java | 108 ++++++++++-----------
 .../installer/plugin/impl/PluginInstallerCLI.java  |  26 ++---
 8 files changed, 83 insertions(+), 94 deletions(-)

diff --git a/idp-distribution/src/main/resources/bin/plugin.bat b/idp-distribution/src/main/resources/bin/plugin.bat
index 44b2dd51b..f9123bf54 100644
--- a/idp-distribution/src/main/resources/bin/plugin.bat
+++ b/idp-distribution/src/main/resources/bin/plugin.bat
@@ -1,4 +1,6 @@
 @echo off
 setlocal
 
+set NO_PLUGIN_WEBAPP="TRUE"
+
 "%~dp0\runclass.bat" net.shibboleth.idp.installer.plugin.impl.PluginInstallerCLI --home "%~dp0\.." %*
diff --git a/idp-distribution/src/main/resources/bin/plugin.sh b/idp-distribution/src/main/resources/bin/plugin.sh
index 38161f961..24abb99f9 100644
--- a/idp-distribution/src/main/resources/bin/plugin.sh
+++ b/idp-distribution/src/main/resources/bin/plugin.sh
@@ -3,5 +3,6 @@
 declare LOCATION
 
 LOCATION=$(dirname $0)
+NO_PLUGIN_WEBAPP="TRUE"
 
 $LOCATION/runclass.sh net.shibboleth.idp.installer.plugin.impl.PluginInstallerCLI --home "$LOCATION/.." "$@"
diff --git a/idp-distribution/src/main/resources/bin/runclass.bat b/idp-distribution/src/main/resources/bin/runclass.bat
index 400b8a044..6a561da9d 100644
--- a/idp-distribution/src/main/resources/bin/runclass.bat
+++ b/idp-distribution/src/main/resources/bin/runclass.bat
@@ -21,8 +21,14 @@ if not exist %JAVACMD% (
   exit /b
 )
 
+if defined NO_PLUGIN_WEBAPP (
+   set WEBAPPCP=%~dp0..\edit-webapp\WEB-INF\lib\*
+) else (
+   set WEBAPPCP=%~dp0..\edit-webapp\WEB-INF\lib\*;%~dp0..\plugin-webapp\WEB-INF\lib\*
+)
+
 REM add in the dependency .jar files
-set LOCALCLASSPATH=%~dp0lib\*;%~dp0..\edit-webapp\WEB-INF\lib\*;%~dp0..\dist\webapp\WEB-INF\lib\*;%JAVA_HOME%\lib\classes.zip;%CLASSPATH%
+set LOCALCLASSPATH=%~dp0lib\*;%WEBAPPCP%;%~dp0..\dist\webapp\WEB-INF\lib\*;%JAVA_HOME%\lib\classes.zip;%CLASSPATH%
 
 REM Go to it !
 
diff --git a/idp-distribution/src/main/resources/bin/runclass.sh b/idp-distribution/src/main/resources/bin/runclass.sh
index ad3826f52..011d7eee3 100755
--- a/idp-distribution/src/main/resources/bin/runclass.sh
+++ b/idp-distribution/src/main/resources/bin/runclass.sh
@@ -36,7 +36,11 @@ if [ -z "$IDP_BASE_URL" ] ; then
 fi
 
 # add in the dependency .jar files
+
 LOCALCLASSPATH="$LOCATION/../dist/webapp/WEB-INF/lib/*":$LOCALCLASSPATH
+if [ -z "$NO_PLUGIN_WEBAPP" ] ; then
+  LOCALCLASSPATH="$LOCATION/../plugin-webapp/WEB-INF/lib/*":$LOCALCLASSPATH
+fi
 LOCALCLASSPATH="$LOCATION/../edit-webapp/WEB-INF/lib/*":$LOCALCLASSPATH
 LOCALCLASSPATH="$LOCATION/lib/*":$LOCALCLASSPATH
 
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/BuildWar.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/BuildWar.java
index c72c89c43..398881dfc 100644
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/BuildWar.java
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/BuildWar.java
@@ -18,12 +18,8 @@
 package net.shibboleth.idp.installer;
 
 import java.io.File;
-import java.io.IOException;
-import java.nio.file.FileSystem;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.PathMatcher;
-import java.util.stream.Stream;
 
 import javax.annotation.Nonnull;
 
@@ -85,6 +81,9 @@ public final class BuildWar extends AbstractInitializableComponent {
      * @throws BuildException if unexpected badness occurs.
      */
     private void overlayWebapp(final Path from, final Path webAppTo) throws BuildException {
+        if (!Files.exists(from)) {
+            return;
+        }
         final Copy overlay = InstallerSupport.getCopyTask(from, webAppTo);
         overlay.setOverwrite(true);
         overlay.setPreserveLastModified(true);
@@ -94,23 +93,6 @@ public final class BuildWar extends AbstractInitializableComponent {
         overlay.execute();
     }
 
-    /** Enumerate all the plugin webapps and deal with them.
-     * @param parent the 'dist' folder
-     * @param to target
-     * @throws BuildException as badness occurrs
-     */
-    private void overlayPluginWebapps(final Path parent, final Path to) throws BuildException {
-        final FileSystem fs = parent.getFileSystem();
-        final PathMatcher folderMatcher = fs.getPathMatcher("glob:edit-webapp-*");
-        try (final Stream<Path> list = Files.list(parent)){
-            list.filter(Files::isDirectory).
-                filter(e -> folderMatcher.matches(e.getFileName())).
-                forEach(e -> overlayWebapp(e, to));
-        } catch (final IOException e) {
-            throw new BuildException(e);
-        }
-    }
-
     /** Method to do the work of building the war.
      * @throws BuildException if unexpected badness occurs.
      */
@@ -131,7 +113,7 @@ public final class BuildWar extends AbstractInitializableComponent {
         log.info("Initial populate from {} to {}", distWebApp, webAppTmp);
         initial.execute();
 
-        overlayPluginWebapps(dist, webAppTmp);
+        overlayWebapp(targetDir.resolve("dist").resolve("plugin-webapp"), webAppTmp);
         overlayWebapp(targetDir.resolve("edit-webapp"), webAppTmp);
 
         final File warFileFile = warFile.toFile();
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/CopyDistribution.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/CopyDistribution.java
index 34688209f..7d3a1d5b5 100644
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/CopyDistribution.java
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/CopyDistribution.java
@@ -91,7 +91,7 @@ public final class CopyDistribution extends AbstractInitializableComponent {
      */
     protected void deleteOld() {
         delete(installerProps.getTargetDir().resolve("bin").resolve("lib"), null);
-        delete(installerProps.getTargetDir().resolve("dist"), "edit-webapp-*/** plugin-contents/**");
+        delete(installerProps.getTargetDir().resolve("dist"), "plugin-webapp/** plugin-contents/**");
         delete(installerProps.getTargetDir().resolve("doc"), null);
         final Path system = installerProps.getTargetDir().resolve("system");
         if (Files.exists(system)) {
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 651d118a2..b494961fe 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
@@ -121,9 +121,15 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
 
     /** What to use to download things. */
     private HttpClient httpClient;
- 
+
     /** Dumping space for renamed files. */
-    @Nonnull private Path renamePath;
+    @NonnullAfterInit private Path renamePath;
+
+    /** DistDir. */
+    @NonnullAfterInit private Path distPath;
+
+    /** Pluginss webapp. */
+    @NonnullAfterInit private Path pluginsWebapp;
 
     /** What was installed - this is setup by {@link #loadCopiedFiles()}. */
     @Nullable private List<String> installedContents;
@@ -232,13 +238,11 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
         LOG.info("Installing Plugin {} version {}.{}.{}", pluginId,
                 description.getMajorVersion(),description.getMinorVersion(), description.getPatchVersion());
 
-        final Path myWebApp = idpHome.resolve("dist").resolve("edit-webapp-" + pluginId);
-
         try (final RollbackPluginInstall rollBack = new RollbackPluginInstall(moduleContext)) {
-            uninstallOld(rollBack, myWebApp);
+            uninstallOld(rollBack);
 
             checkRequiredModules();
-            installNew(rollBack, myWebApp);
+            installNew(rollBack);
 
             saveCopiedFiles(rollBack.getFilesCopied());
             rollBack.completed();
@@ -352,28 +356,22 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
     /**
      * Police that required modules for plugin installation are enabled.
      * 
-     * @throws BuildException if any required modules are missing or disabled
+     * @throws BuildException if any required modules are missing or disabled or loading the module fails
      */
     private void checkRequiredModules() throws BuildException {
         final Set<String> requiredModules = new HashSet<>(description.getRequiredModules());
-        
-        try (final URLClassLoader loader = getInstalledPluginLoader()) {
-            final Iterator<IdPModule> modules = ServiceLoader.load(IdPModule.class).iterator();
-            while (modules.hasNext() && !requiredModules.isEmpty()) {
-                try {
-                    final IdPModule module = modules.next();
-                    if (requiredModules.contains(module.getId())) {
-                        if (module.isEnabled(moduleContext)) {
-                            requiredModules.remove(module.getId());
-                        }
+        final Iterator<IdPModule> modules = ServiceLoader.load(IdPModule.class, getInstalledPluginLoader()).iterator();
+        while (modules.hasNext() && !requiredModules.isEmpty()) {
+            try {
+                final IdPModule module = modules.next();
+                if (requiredModules.contains(module.getId())) {
+                    if (module.isEnabled(moduleContext)) {
+                        requiredModules.remove(module.getId());
                     }
-                } catch (final ServiceConfigurationError e) {
-                    LOG.error("Unable to instantiate IdPModule", e);
                 }
+            } catch (final ServiceConfigurationError e) {
+                LOG.error("Unable to instantiate IdPModule", e);
             }
-        } catch (final IOException e) {
-            LOG.error("Error looking for required modules");
-            throw new BuildException(e);
         }
         
         if (!requiredModules.isEmpty()) {
@@ -385,16 +383,14 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
     /** Copy the webapp folder from the distribution to the per plugin
      * location inside dist.
      * @param rollBack Roll Back Context
-     * @param myWebApp Where to put it.
      * @throws BuildException if badness is detected.
      */
-    private void installNew(final RollbackPluginInstall rollBack, final Path myWebApp) throws BuildException {
-        final Path from = distribution.resolve("edit-webapp");
-        if (PluginInstallerSupport.detectDuplicates(from, myWebApp)) {
+    private void installNew(final RollbackPluginInstall rollBack) throws BuildException {
+        final Path from = distribution.resolve("webapp");
+        if (PluginInstallerSupport.detectDuplicates(from, pluginsWebapp)) {
             throw new BuildException("Install would overwrite filess");
         }
-        PluginInstallerSupport.copyWithLogging(from, myWebApp, rollBack.getFilesCopied());
-        InstallerSupport.setReadOnly(myWebApp, true);
+        PluginInstallerSupport.copyWithLogging(from, pluginsWebapp, rollBack.getFilesCopied());
 
         String moduleId = null;
         try {
@@ -413,9 +409,8 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
 
     /** Uninstall the old version of the plugin.
      * @param rollback Rollback Context
-     * @param myWebApp where to delete 
      * @throws BuildException on IO or module errors */
-    private void uninstallOld(final RollbackPluginInstall rollback, final Path myWebApp) throws BuildException {
+    private void uninstallOld(final RollbackPluginInstall rollback) throws BuildException {
         final IdPPlugin oldPlugin = getInstalledPlugin(pluginId);
         if (oldPlugin == null) {
             LOG.debug("{} not installed. No modules disabled", pluginId);
@@ -438,9 +433,8 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
         if (getVersionFromContents() == null) {
             LOG.debug("{} not installed. files renamed", pluginId);
         } else {
-            InstallerSupport.setReadOnly(myWebApp, false);
             try {
-                PluginInstallerSupport.renameToTree(myWebApp, renamePath,
+                PluginInstallerSupport.renameToTree(pluginsWebapp, renamePath,
                         getInstalledContents(),
                         rollback.getFilesRenamedAway());
             } catch (final IOException e) {
@@ -456,7 +450,7 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
      */
     private void saveCopiedFiles(final List<Path> copiedFiles) throws BuildException {
         try {
-            final Path parent = idpHome.resolve("dist").resolve("plugin-contents");
+            final Path parent = distPath.resolve("plugin-contents");
             Files.createDirectories(parent);
             final Properties props = new Properties(1+copiedFiles.size());
             props.setProperty("idp.plugin.version",
@@ -484,7 +478,7 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
         if (installedContents != null) {
             return;
         }
-        final Path parent = idpHome.resolve("dist").resolve("plugin-contents");
+        final Path parent = distPath.resolve("plugin-contents");
         final Properties props = new Properties();
         final File inFile = parent.resolve(pluginId).toFile();
         if (!inFile.exists()) {
@@ -653,7 +647,7 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
         final File propertyFile = distribution.resolve("bootstrap").resolve("plugin.properties").toFile();
         if (!propertyFile.exists()) {
             LOG.error("Could not locate identity of plugin. "
-                    + "Identity file 'bootstrap/id.property' not present in plugin distribution.");
+                    + "Identity file 'bootstrap/plugin.properties' not present in plugin distribution.");
             throw new BuildException("Could not locate identity of plugin");
         }
         try (final InputStream inStream = new BufferedInputStream(new FileInputStream(propertyFile))) {
@@ -734,28 +728,31 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
         moduleContext = new ModuleContext(idpHome);
         moduleContext.setHttpClientSecurityParameters(securityParams);
         moduleContext.setHttpClient(httpClient);
-        renamePath = idpHome.resolve("dist").resolve("plugin-rollback");
+        distPath = idpHome.resolve("dist");
+        renamePath = distPath.resolve("plugin-rollback");
+        pluginsWebapp = distPath.resolve("plugin-webapp");
+        InstallerSupport.setReadOnly(distPath, false);
     }
 
     /** Generate a {@link URLClassLoader} which looks at the
      * installed WEB-INF/lib in addition to the dist webapp and bin/lib directories.
      * @return an appropriate loader
-     * @throws IOException if a directory traversal fails.
+     * @throws BuildException if a directory traversal fails.
      */
-    private synchronized URLClassLoader getInstalledPluginLoader() throws IOException {
+    private synchronized URLClassLoader getInstalledPluginLoader() throws BuildException {
         if (installedPluginLoader != null) {
             return installedPluginLoader;
         }
         final List<URL> urls = new ArrayList<>();
-        try (final DirectoryStream<Path> webAppList =
-                Files.newDirectoryStream(idpHome.resolve("dist"), "edit-webapp-*")) {
-            for (final Path webApp : webAppList) {
-                try (final DirectoryStream<Path> webInfLibs =
-                        Files.newDirectoryStream(webApp.resolve("WEB-INF").resolve("lib"))) {
-                    for (final Path jar : webInfLibs) {
-                        urls.add(jar.toUri().toURL());
-                    }
+        final Path libs = pluginsWebapp.resolve("WEB-INF").resolve("lib");
+        if (Files.exists(libs)) {
+            try (final DirectoryStream<Path> webInfLibs = Files.newDirectoryStream(libs)) {
+                for (final Path jar : webInfLibs) {
+                    urls.add(jar.toUri().toURL());
                 }
+            } catch (final IOException e) {
+                LOG.error("Error finding Plugins' classpath");
+                throw new BuildException(e);
             }
         }
         installedPluginLoader = new URLClassLoader(urls.toArray(URL[]::new));
@@ -773,7 +770,7 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
             return installingPluginLoader;
         }
         final List<URL> urls = new ArrayList<>();
-        final Path libDir = distribution.resolve("edit-webapp").resolve("WEB-INF").resolve("lib");
+        final Path libDir = distribution.resolve("webapp").resolve("WEB-INF").resolve("lib");
         try (final DirectoryStream<Path> libDirPaths = Files.newDirectoryStream(libDir)){
             for (final Path jar : libDirPaths) {
                 urls.add(jar.toUri().toURL());
@@ -786,18 +783,12 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
     /**
      * Return a list of the installed plugins.
      * @return All the plugins.
+     * @throws BuildException if loafing the classpath fails.
      */
-    public List<IdPPlugin> getInstalledPlugins() {
-        try {
-            try (final URLClassLoader loader = getInstalledPluginLoader()){
-               try (final Stream<Provider<IdPPlugin>> loaderStream =
-                       ServiceLoader.load(IdPPlugin.class, loader).stream()) {
-                   return loaderStream.map(ServiceLoader.Provider::get).collect(Collectors.toList());
-               }
-           }
-        } catch (final IOException e) {
-            throw new BuildException(e);
-        }
+    public List<IdPPlugin> getInstalledPlugins() throws BuildException {
+       final Stream<Provider<IdPPlugin>> loaderStream =
+               ServiceLoader.load(IdPPlugin.class, getInstalledPluginLoader()).stream();
+       return loaderStream.map(ServiceLoader.Provider::get).collect(Collectors.toList());
     }
 
     /** Find the {@link IdPPlugin} with the provided Id.
@@ -836,6 +827,7 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
         PluginInstallerSupport.deleteTree(downloadDirectory);
         PluginInstallerSupport.deleteTree(unpackDirectory);
         PluginInstallerSupport.deleteTree(renamePath);
+        InstallerSupport.setReadOnly(distPath, true);
     }
     
 }
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginInstallerCLI.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginInstallerCLI.java
index 4e6d908fb..b6516dc18 100644
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginInstallerCLI.java
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginInstallerCLI.java
@@ -19,6 +19,7 @@ package net.shibboleth.idp.installer.plugin.impl;
 
 import java.io.BufferedReader;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.nio.file.Path;
 import java.security.Security;
@@ -245,20 +246,21 @@ public final class PluginInstallerCLI extends AbstractIdPHomeAwareCommandLine<Pl
         }
         final String location = plugin.getLicenseFileLocation();
         if (location == null) {
-            log.error("Plugin {} has no license", pluginId);
+            log.info("Plugin {} has no license", pluginId);
             return;
         }
-        final Resource loc = new ClassPathResource(location);
-        if (!loc.exists()) {
-            log.error("Plugin {} license could not be found at {}", pluginId, location);
-            return;
-        }
-        outOrLog(String.format("License for %s", plugin));
-        try (final BufferedReader reader = new BufferedReader(new InputStreamReader(loc.getInputStream()))) {
-            String line = reader.readLine();
-            while (line != null) {
-                outOrLog(line);
-                line = reader.readLine();
+        try (final InputStream is = plugin.getClass().getResourceAsStream(location)) {
+            if (is == null) {
+                log.error("Plugin {} license could not be found at {}", pluginId, location);
+                return;
+            }
+            outOrLog(String.format("License for %s", plugin));
+            try (final BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
+                String line = reader.readLine();
+                while (line != null) {
+                    outOrLog(line);
+                    line = reader.readLine();
+                }
             }
         } catch (final IOException e) {
             log.error("Failed to output license", e);

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


More information about the commits mailing list