[java-identity-provider] 01/04: IDP-1595 Add -cl (--List-contents) to the plugin verb

Rod Widdowson rdw at steadingsoftware.com
Wed Oct 7 15:19:44 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=659d4c01e077b98b653ab831a704e898b7c14efc

commit 659d4c01e077b98b653ab831a704e898b7c14efc
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Tue Oct 6 13:41:43 2020 +0100

    IDP-1595 Add -cl (--List-contents) to the plugin verb
    
    https://issues.shibboleth.net/jira/browse/IDP-1595
---
 .../net/shibboleth/idp/plugin/PluginVersion.java   | 12 +++++
 .../idp/installer/plugin/impl/PluginInstaller.java | 61 ++++++++++++++++++++--
 .../plugin/impl/PluginInstallerArguments.java      | 16 +++++-
 .../installer/plugin/impl/PluginInstallerCLI.java  | 51 +++++++++++++++++-
 .../idp/installer/plugin/impl/PluginState.java     |  3 +-
 .../idp/installer/plugin/impl/PluginCLITest.java   |  2 +-
 6 files changed, 134 insertions(+), 11 deletions(-)

diff --git a/idp-admin-api/src/main/java/net/shibboleth/idp/plugin/PluginVersion.java b/idp-admin-api/src/main/java/net/shibboleth/idp/plugin/PluginVersion.java
index 4edcfa07e..1d35dd4c7 100644
--- a/idp-admin-api/src/main/java/net/shibboleth/idp/plugin/PluginVersion.java
+++ b/idp-admin-api/src/main/java/net/shibboleth/idp/plugin/PluginVersion.java
@@ -17,6 +17,8 @@
 
 package net.shibboleth.idp.plugin;
 
+import javax.annotation.Nonnull;
+
 import net.shibboleth.utilities.java.support.primitive.StringSupport;
 
 /**
@@ -62,6 +64,16 @@ public final class PluginVersion implements Comparable<PluginVersion>{
         }
     }
     
+    /**
+     * Constructor.
+     *
+     * @param plugin what to get the version of.
+     * @throws NumberFormatException if the values are out of range
+     */
+    public PluginVersion(@Nonnull final IdPPlugin plugin) throws NumberFormatException {
+        this(plugin.getMajorVersion(), plugin.getMinorVersion(), plugin.getPatchVersion());
+    }
+
     /**
      * Constructor.
      *
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 466417c15..9a27797ff 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
@@ -56,6 +56,7 @@ import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
 import org.apache.commons.compress.utils.IOUtils;
 import org.apache.http.client.HttpClient;
 import org.apache.tools.ant.BuildException;
+import org.jetbrains.annotations.NotNull;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -122,6 +123,12 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
     /** Files that were copied - to handle rollback. */
     @Nonnull private List<Path> copiedFiles = new ArrayList<>();
 
+    /** What was installed - this is setup by {@link #loadCopiedFiles()}. */
+    @Nullable private List<String> installedContents;
+
+    /** The version from the contents file, or null if it isn't loaded. */
+    @Nullable private String installedVersionFromContents;
+
     /** Set IdP Home.
      * @param home Where we are working from
      */
@@ -276,7 +283,24 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
             throw new BuildException(e);
         }
     }
-    
+
+    /** What files were installed to webapp for this plugin?
+     * @return a list of the installed contents, may be empty if
+     * nothing is installed or the plugin didn't install anything.
+     */
+    @NotNull public List<String> getInstalledContents() {
+        loadCopiedFiles();
+        return installedContents;
+    }
+
+    /** return the version that the contents page thinks is installed.
+     * @return the version, or null if it is not found.
+     */
+    @Nullable public String getVersionFromContents() {
+        loadCopiedFiles();
+        return installedVersionFromContents;
+    }
+
     /**
      * Police that required modules for plugin installation are enabled.
      * 
@@ -340,9 +364,7 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
             Files.createDirectories(parent);
             final Properties props = new Properties(1+copiedFiles.size());
             props.setProperty("idp.plugin.version",
-                    new PluginVersion(description.getMajorVersion(),
-                            description.getMinorVersion(),
-                            description.getPatchVersion()).toString());
+                    new PluginVersion(description).toString());
             int count = 1;
             for (final Path p: copiedFiles) {
                 props.setProperty("idp.plugin.file."+Integer.toString(count++),
@@ -359,6 +381,37 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
         }
     }
 
+    /** Load the contents for this plugin from the properties file used during
+     * installation.
+     * @throws BuildException if the load fails
+     */
+    private void loadCopiedFiles() throws BuildException {
+        if (installedContents != null) {
+            return;
+        }
+        final Path parent = idpHome.resolve("dist").resolve("plugin-contents");
+        final Properties props = new Properties();
+        final File inFile = parent.resolve(pluginId).toFile();
+        if (!inFile.exists()) {
+            LOG.error("Contents file for plugin {} ({}) does not exist", pluginId, inFile.getAbsolutePath());
+            return;
+        }
+        try (final BufferedInputStream inStream = new BufferedInputStream(new FileInputStream(inFile))) {
+            props.load(inStream);
+        } catch (final IOException e) {
+            LOG.error("Error loading list of copied files from {}.", inFile, e);
+            throw new BuildException(e);
+        }
+        installedContents = new ArrayList<>(props.size());
+        installedVersionFromContents = StringSupport.trimOrNull(props.getProperty("idp.plugin.version"));
+        int count = 1;
+        String val = props.getProperty("idp.plugin.file."+Integer.toString(count++));
+        while (val != null) {
+            installedContents.add(val);
+            val = props.getProperty("idp.plugin.file."+Integer.toString(count++));
+        }
+    }
+
     /** Method to download a zip file to the {{@link #downloadDirectory}.
      * @param baseURL Where the zip/tgz and signature file is
      * @param fileName the name.
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginInstallerArguments.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginInstallerArguments.java
index 407637098..8cd1dd2bc 100644
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginInstallerArguments.java
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginInstallerArguments.java
@@ -83,6 +83,10 @@ public class PluginInstallerArguments extends AbstractIdPHomeAwareCommandLineArg
     @Parameter(names= {"-r", "--remove-jars"})
     @Nullable private String removeId;
 
+    /** Contents to list. */
+    @Parameter(names= {"-cl", "--contents-list"})
+    @Nullable private String contentsList;
+
     /** The {@link #forceUpdateVersion} as a {@link PluginVersion}. */
     @Nullable private PluginVersion updateVersion;
 
@@ -109,6 +113,8 @@ public class PluginInstallerArguments extends AbstractIdPHomeAwareCommandLineArg
         REMOVEJARS,
         /** Print the license file to System.out. */
         OUTPUTLICENSE,
+        /** List the contents for the plugin. */
+        LISTCONTENTS,
         /** Unknown. */
         UNKNOWN
     };
@@ -260,8 +266,11 @@ public class PluginInstallerArguments extends AbstractIdPHomeAwareCommandLineArg
         } else if (license != null) {
             pluginId = license;
             operation = OperationType.OUTPUTLICENSE;
+        } else if (contentsList != null){
+            pluginId = contentsList;
+            operation = OperationType.LISTCONTENTS;
         } else {
-            getLog().error("Missing qualifier. Options are : -l, -fl, -i, -u");
+            getLog().error("Missing qualifier. Options are : -l, -fl, -cl, -i, -u, -r, --license");
             throw new IllegalArgumentException("Missing qualifier");
         }
     }
@@ -308,6 +317,7 @@ public class PluginInstallerArguments extends AbstractIdPHomeAwareCommandLineArg
         out.println();
         out.println(String.format("  %-22s %s", "-l, --list", "Brief Information of all installed plugins"));
         out.println(String.format("  %-22s %s", "-fl, --full-list", "Full details of all installed plugins"));
+        out.println(String.format("  %-22s %s", "-cl, --contents-list", "Details of what was installed"));
         out.println(String.format("  %-22s %s", "-i, --input <what>", "Install (file name or web address)"));
         out.println(String.format("  %-22s %s", "-u, --update <PluginId>", "update"));
         out.println(String.format("  %-22s %s", "-fu, --force-update <version>",
@@ -315,9 +325,11 @@ public class PluginInstallerArguments extends AbstractIdPHomeAwareCommandLineArg
         out.println(String.format("  %-22s %s", "-r, --remove-jars <PluginId>",
                 "remove any installed jars (and other resources) from the war file. \n" + 
                 "\t\t\tDOES NOT UNDO any other installation"));
+        out.println(String.format("  %-22s %s", "--license <pluginid>",
+                "Output all licenses for this plugin"));
         out.println(String.format("  %-22s %s", "--noPrompt", "Unattended Install"));
         out.println(String.format("  %-22s %s", "--truststore <path>",
-                "Explicit location to look for keys (should exist but may be empty"));
+                "Explicit location to look for keys (should exist but may be an empty file)"));
         out.println();
     }
 
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 7b4462919..667bf9726 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
@@ -33,6 +33,7 @@ import javax.annotation.Nullable;
 
 import org.apache.tools.ant.BuildException;
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.jetbrains.annotations.NotNull;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeansException;
@@ -147,6 +148,11 @@ public final class PluginInstallerCLI extends AbstractIdPHomeAwareCommandLine<Pl
                     outputLicense(args.getPluginId());
                     break;
 
+                case LISTCONTENTS:
+                    installer.setPluginId(args.getPluginId());
+                    doContentList(args.getPluginId());
+                    break;
+
                 default:
                     getLogger().error("Invalid operation");
                     return RC_INIT;
@@ -287,6 +293,48 @@ public final class PluginInstallerCLI extends AbstractIdPHomeAwareCommandLine<Pl
             }
         }
     }
+    
+    /** List the contents for the detailed plugin.
+     * @param pluginId the pluginId
+     */
+    private void doContentList(@NotNull final String pluginId) {
+        final List<IdPPlugin> plugins = installer.getInstalledPlugins();
+        IdPPlugin thePlugin = null;
+        for (final IdPPlugin plugin: plugins) {
+            if (pluginId.equals(plugin.getPluginId())) {
+                thePlugin = plugin;
+                break;
+            }
+        }
+
+        final String fromContentsVersion =  installer.getVersionFromContents();
+        final List<String> contents = installer.getInstalledContents();
+        if (thePlugin == null) {
+            log.warn("Plugin was not installed {}", pluginId);
+            if (fromContentsVersion != null) {
+                log.error("Plugin {} not installed, but contents found.", pluginId);
+                log.debug("{}", contents);
+            } else {
+                return;
+            }
+        } else if (fromContentsVersion == null) {
+            log.error("Plugin {} found, but no contents listed", pluginId);
+            return;
+        }
+        final String installedVersion = new PluginVersion(thePlugin).toString();
+        if (!fromContentsVersion.equals(installedVersion)) {
+            log.error("Installed version of Plugin {} ({}) does not match contents ({})", 
+                    pluginId, installedVersion, fromContentsVersion);
+        }
+        if (contents.isEmpty()) {
+            log.info("No Contents");
+        } else {
+            for (final String s: contents) {
+                outOrLog(String.format("%s", s));
+            }
+        }
+    }
+
 
     /** Find the best update version.  Helper function for {@linkplain #doUpdate(String, PluginVersion)}.
      * @param plugin The Plugin
@@ -296,8 +344,7 @@ public final class PluginInstallerCLI extends AbstractIdPHomeAwareCommandLine<Pl
     @Nullable private PluginVersion getBestVersion(final IdPPlugin plugin, final PluginState state) {
 
         final String idpVersionString = net.shibboleth.idp.Version.getVersion();
-        final PluginVersion myVersion = new PluginVersion(plugin.getMajorVersion(),
-                plugin.getMinorVersion(), plugin.getPatchVersion());
+        final PluginVersion myVersion = new PluginVersion(plugin);
 
         final PluginVersion idPVersion;
         if (idpVersionString == null) {
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
index 7723fc3c0..0abd246f9 100644
--- 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
@@ -87,8 +87,7 @@ public class PluginState extends AbstractInitializableComponent {
      */
     public PluginState(@Nonnull final IdPPlugin description) {
         plugin = Constraint.isNotNull(description, "Plugin must not be null");
-        myPluginVersion = new PluginVersion(plugin.getMajorVersion(), 
-                plugin.getMinorVersion(), plugin.getPatchVersion());
+        myPluginVersion = new PluginVersion(plugin);
     }
     
     /** Get the base URL for this version.
diff --git a/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/PluginCLITest.java b/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/PluginCLITest.java
index a9b9ef2f4..2d39bb3bf 100644
--- a/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/PluginCLITest.java
+++ b/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/PluginCLITest.java
@@ -50,7 +50,7 @@ public class PluginCLITest extends BasePluginTest {
     @Test(enabled = true) public void testLicense() {
         assertEquals(PluginInstallerCLI.runMain(new String[] { "--license", "net.shibboleth.plugin.test"} ), AbstractCommandLine.RC_OK);
     }
-    
+
     @Test(enabled = false) public void testList() throws IOException {
         assertEquals(PluginInstallerCLI.runMain(new String[] { "-fl", } ), AbstractCommandLine.RC_OK);
     }

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


More information about the commits mailing list