[java-identity-provider] 02/06: IDP-1595 Plugin Command line: List installed clients
Rod Widdowson
rdw at steadingsoftware.com
Tue Aug 4 13:06:42 UTC 2020
This is an automated email from the git hooks/post-receive script.
rdw pushed a commit to branch master
in repository java-identity-provider.
View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=851b4003cc251c491140c04660c4687e7579c680
commit 851b4003cc251c491140c04660c4687e7579c680
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Sun Aug 2 14:50:03 2020 +0100
IDP-1595 Plugin Command line: List installed clients
https://issues.shibboleth.net/jira/browse/IDP-1595
-li/--list, -fl/--full-list
Output is to System.out which has bizarre logging side effects.
---
idp-installer/pom.xml | 7 ++
.../installer/plugin/PluginInstallerArguments.java | 92 +++++++++++++++
.../idp/installer/plugin/PluginInstallerCLI.java | 127 ++++++++++++++++++---
.../idp/installer/plugin/PluginCLITest.java | 6 +-
.../installer/plugin/impl/PluginInstallerTest.java | 3 +-
.../net.shibboleth.idp.plugin.PluginDescription | 1 +
.../idphome-test/conf/admin/{gitkeep => .gitkeep} | 0
7 files changed, 213 insertions(+), 23 deletions(-)
diff --git a/idp-installer/pom.xml b/idp-installer/pom.xml
index cb0e5da29..d5073e131 100644
--- a/idp-installer/pom.xml
+++ b/idp-installer/pom.xml
@@ -159,6 +159,13 @@
<artifactId>bcpkix-jdk15on</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>idp-admin-impl</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
</dependencies>
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/PluginInstallerArguments.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/PluginInstallerArguments.java
index 8c81e1e3b..41a07228f 100644
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/PluginInstallerArguments.java
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/PluginInstallerArguments.java
@@ -17,6 +17,12 @@
package net.shibboleth.idp.installer.plugin;
+import java.io.PrintStream;
+
+import javax.annotation.Nullable;
+
+import com.beust.jcommander.Parameter;
+
import net.shibboleth.ext.spring.cli.AbstractCommandLineArguments;
/**
@@ -24,4 +30,90 @@ import net.shibboleth.ext.spring.cli.AbstractCommandLineArguments;
*/
public class PluginInstallerArguments extends AbstractCommandLineArguments {
+ /** The PluginId - usually used to drive the update. */
+ @Parameter(names= {"-p", "--pluginId"})
+ @Nullable private String pluginId;
+
+ /** Brief info about installed plugins. */
+ @Parameter(names= {"-l", "--list"})
+ @Nullable private boolean list;
+
+ /** Detailed info about installed plugins. */
+ @Parameter(names= {"-fl", "--full-list"})
+ @Nullable private boolean fullList;
+
+ /** Operation enum. */
+ public enum OperationType {
+ /** Update a known install. */
+ UPDATE,
+ /** List all installs. */
+ LIST,
+ /** Install from a local copy. */
+ INSTALLDIR,
+ /** Install from the web. */
+ INSTALLREMOTE,
+ /** Unknown. */
+ UNKNOWN
+ };
+
+ /** What to do. */
+ private OperationType operation = OperationType.UNKNOWN;
+
+ /** Plugin Id (if specified).
+ * @return {@link #pluginId}
+ */
+ @Nullable public String getPluginId() {
+ return pluginId;
+ }
+
+ /** Are we doing a full List?
+ * @return {@link #fullList}
+ */
+ public boolean getFullList() {
+ return fullList;
+ }
+
+ /** Are we doing a List?
+ * @return {@link #list}
+ */
+ public boolean getList() {
+ return list;
+ }
+
+ /**
+ * Get operation to perform.
+ *
+ * @return operation
+ */
+ @Nullable public OperationType getOperation() {
+ return operation;
+ }
+
+ /** {@inheritDoc} */
+ public void validate() throws IllegalArgumentException {
+ super.validate();
+
+ if (getOtherArgs().size() > 2) {
+ throw new IllegalArgumentException("????");
+ }
+ if (list || fullList) {
+ operation = OperationType.LIST;
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void printHelp(final PrintStream out) {
+ out.println("Plugin");
+ out.println("Provides a command line interface for plugin management operations.");
+ out.println();
+ out.println(" Plugn [options] springConfiguration [FullName]");
+ out.println();
+ out.println(" springConfiguration name of Spring configuration resource to use");
+ super.printHelp(out);
+ 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();
+ }
+
}
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/PluginInstallerCLI.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/PluginInstallerCLI.java
index 3e944b1e7..5f1e50fd8 100644
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/PluginInstallerCLI.java
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/PluginInstallerCLI.java
@@ -17,25 +17,32 @@
package net.shibboleth.idp.installer.plugin;
-import java.io.IOException;
-import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import org.apache.http.client.HttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeansException;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import net.shibboleth.ext.spring.cli.AbstractCommandLine;
import net.shibboleth.idp.Version;
+import net.shibboleth.idp.installer.plugin.impl.PluginInstaller;
+import net.shibboleth.idp.plugin.PluginDescription;
+import net.shibboleth.idp.plugin.PluginVersion;
+import net.shibboleth.idp.plugin.impl.PluginState;
+import net.shibboleth.idp.plugin.impl.PluginState.VersionInfo;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.primitive.StringSupport;
/**
@@ -48,7 +55,13 @@ public final class PluginInstallerCLI extends AbstractCommandLine<PluginInstalle
/** Where the IdP is installed to. */
@Nullable private Path idpHome;
+
+ /** A Plugin Installer to use. */
+ private PluginInstaller installer;
+ /** The injected HttpClient. */
+ private HttpClient httpClient;
+
/**
* Constrained Constructor.
*/
@@ -113,27 +126,103 @@ public final class PluginInstallerCLI extends AbstractCommandLine<PluginInstalle
if (ret != RC_OK) {
return ret;
}
+ final Set<Entry<String, HttpClient>> clients =
+ getApplicationContext().getBeansOfType(HttpClient.class).entrySet();
+ if (clients.isEmpty()) {
+ log.debug("No HttpClient definitions found.");
+ } else {
+ final Entry<String, HttpClient> entry = clients.iterator().next();
+ httpClient = entry.getValue();
+ if (clients.size() > 1) {
+ log.warn("Multiple HttpClient beans found; Taking {}", entry.getKey());
+ } else {
+ log.debug("Selecting HttpClient: {}", entry.getKey());
+ }
+ }
+
try {
- Files.walkFileTree(getIdpHome().resolve("conf"), new SimpleFileVisitor<Path>() {
- @Override
- public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
- getLogger().warn("File {}",file);
- return FileVisitResult.CONTINUE;
- }
- @Override
- public FileVisitResult preVisitDirectory(final Path dir,
- final BasicFileAttributes attrs) throws IOException {
- getLogger().warn("Dire {}",dir);
- return FileVisitResult.CONTINUE;
- }
- });
- } catch (final IOException e) {
- getLogger().error("oops", e);
+ constructPluginInstaller();
+ switch (args.getOperation()) {
+ case LIST:
+ doList(args.getFullList(), args.getPluginId());
+ break;
+
+ default:
+ getLogger().error("Invalid operation");
+ return RC_IO;
+ }
+
+ } catch (final ComponentInitializationException | BeansException e) {
+ getLogger().error("Plugin failed", e);
return RC_IO;
}
return ret;
}
+ /** Build the installer.
+ * @throws ComponentInitializationException as required*/
+ private void constructPluginInstaller() throws ComponentInitializationException {
+ installer= new PluginInstaller();
+ installer.setIdpHome(idpHome);
+ if (httpClient!= null) {
+ installer.setHttpClient(httpClient);
+ }
+ installer.initialize();
+ }
+
+ /** List all installed plugins (or just one if provided).
+ * @param fullList whether to do full deatils
+ * @param pluginId the pluginId or null.
+ */
+ private void doList(final boolean fullList, @Nullable final String pluginId) {
+ boolean list = false;
+ final List<PluginDescription> plugins = installer.getInstalledPlugins();
+ for (final PluginDescription plugin: plugins) {
+ if (pluginId == null || pluginId.equals(plugin.getPluginId())) {
+ list = true;
+ System.out.println(String.format("Plugin: %-22s\tCurrent Version: %d.%d.%d",
+ plugin.getPluginId(),
+ plugin.getMajorVersion(),plugin.getMinorVersion(), plugin.getPatchVersion()));
+ if (fullList) {
+ printDetails(plugin);
+ }
+ }
+ }
+ if (!list) {
+ if (pluginId == null) {
+ System.out.println("No plugins installed");
+ } else {
+ System.out.println("Plugin " + pluginId + " not installed");
+ }
+ }
+ }
+
+ /** Print our more information about a plugin.
+ * @param plugin what we are interested in.
+ */
+ private void printDetails(final PluginDescription plugin) {
+ log.debug("Interrogating {} ", plugin.getPluginId());
+ final PluginState state = new PluginState(plugin);
+ if (httpClient != null) {
+ state.setHttpClient(httpClient);
+ }
+ try {
+ state.initialize();
+ } catch (final ComponentInitializationException e) {
+ log.error("Could not interrogate plugin {}", plugin.getPluginId(), e);
+ return;
+ }
+ final Map<PluginVersion, VersionInfo> versions = state.getAvailableVersions();
+ System.out.println("\tVersions ");
+ for (final Entry<PluginVersion, VersionInfo> entry : versions.entrySet()) {
+ System.out.println(String.format("\t%s:\tMin=%s\tMax=%s\tSupport level: %s",
+ entry.getKey(),
+ entry.getValue().getMinSupported(),
+ entry.getValue().getMaxSupported(),
+ entry.getValue().getSupportLevel()));
+ }
+ }
+
/** Shim for CLI entry point: Allows the code to be run from a test.
*
* @return one of the predefines {@link AbstractCommandLine#RC_INIT},
diff --git a/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/PluginCLITest.java b/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/PluginCLITest.java
index 1f567f3ab..f2d87ff99 100644
--- a/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/PluginCLITest.java
+++ b/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/PluginCLITest.java
@@ -34,7 +34,7 @@ import net.shibboleth.ext.spring.cli.AbstractCommandLine;
@SuppressWarnings("javadoc")
public class PluginCLITest extends BasePluginTest {
- @Test(enabled = true) public void TestCli() throws IOException {
+ @Test(enabled = true) public void testList() throws IOException {
System.setProperty("net.shibboleth.idp.cli.idp.home",getIdpHome().toString());
final Resource pluginInstaller = new ClassPathResource("conf/admin/plugin-installer.xml");
final File plugin = getIdpHome().resolve("conf").resolve("admin").resolve("plugin-installer.xml").toFile();
@@ -45,7 +45,7 @@ public class PluginCLITest extends BasePluginTest {
is.transferTo(os);
}
- assertEquals(PluginInstallerCLI.runMain(new String[] { plugin.getAbsolutePath(), "--verbose"}),
- AbstractCommandLine.RC_OK);
+ assertEquals(PluginInstallerCLI.runMain(new String[] { plugin.getAbsolutePath(), "-fl"}),
+ AbstractCommandLine.RC_OK);
}
}
diff --git a/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/PluginInstallerTest.java b/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/PluginInstallerTest.java
index c6f5ca425..ae087f472 100644
--- a/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/PluginInstallerTest.java
+++ b/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/PluginInstallerTest.java
@@ -23,6 +23,7 @@ import java.io.IOException;
import java.net.URL;
import java.nio.file.Path;
import java.security.Security;
+import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
@@ -119,7 +120,7 @@ public class PluginInstallerTest extends BasePluginTest {
/** {@inheritDoc} */
public List<URL> getUpdateURLs() throws IOException {
- return null;
+ return Collections.emptyList();
}
/** {@inheritDoc} */
diff --git a/idp-installer/src/test/resources/META-INF/services/net.shibboleth.idp.plugin.PluginDescription b/idp-installer/src/test/resources/META-INF/services/net.shibboleth.idp.plugin.PluginDescription
new file mode 100644
index 000000000..abc52d47f
--- /dev/null
+++ b/idp-installer/src/test/resources/META-INF/services/net.shibboleth.idp.plugin.PluginDescription
@@ -0,0 +1 @@
+net.shibboleth.idp.plugin.TestPlugin
diff --git a/idp-installer/src/test/resources/idphome-test/conf/admin/gitkeep b/idp-installer/src/test/resources/idphome-test/conf/admin/.gitkeep
similarity index 100%
rename from idp-installer/src/test/resources/idphome-test/conf/admin/gitkeep
rename to idp-installer/src/test/resources/idphome-test/conf/admin/.gitkeep
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list