[java-shib-profile] 01/02: IDP-2297 Explore extending the Plugin and Module Infrastructure to allow Jetty installation
Rod Widdowson
rdw at steadingsoftware.com
Tue Jul 30 19:03:37 UTC 2024
This is an automated email from the git hooks/post-receive script.
rdw pushed a commit to branch dev/IDP-2297
in repository java-shib-profile.
View the commit online:
http://git.shibboleth.net/view/?p=java-shib-profile.git;a=commit;h=cfddf6886a59b88952f000a5d85cb7dc39a192ac
commit cfddf6886a59b88952f000a5d85cb7dc39a192ac
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Thu Jul 25 10:32:21 2024 +0100
IDP-2297 Explore extending the Plugin and Module Infrastructure to allow Jetty installation
https://shibboleth.atlassian.net/browse/IDP-2297
Teach Plugins about "Packages"
---
.../shibboleth/profile/plugin/AbstractPlugin.java | 24 ++-
.../java/net/shibboleth/profile/plugin/Plugin.java | 34 ++++
.../profile/plugin/PropertyDrivenPlugin.java | 172 +++++++++++++++++----
3 files changed, 199 insertions(+), 31 deletions(-)
diff --git a/shib-profile-api/src/main/java/net/shibboleth/profile/plugin/AbstractPlugin.java b/shib-profile-api/src/main/java/net/shibboleth/profile/plugin/AbstractPlugin.java
index ee6ba09..bb242df 100644
--- a/shib-profile-api/src/main/java/net/shibboleth/profile/plugin/AbstractPlugin.java
+++ b/shib-profile-api/src/main/java/net/shibboleth/profile/plugin/AbstractPlugin.java
@@ -14,6 +14,8 @@
package net.shibboleth.profile.plugin;
+import java.util.Collection;
+import java.util.List;
import java.util.Set;
import javax.annotation.Nonnegative;
@@ -39,6 +41,9 @@ public abstract class AbstractPlugin<T extends Module> implements Plugin<T> {
/** Modules to disable on removal. */
@Nonnull private Set<T> disableModules;
+ /** Packages to unpack. */
+ @Nonnull private List<Package> packages = CollectionSupport.emptyList();
+
/** Constructor. */
public AbstractPlugin() {
enableModules = CollectionSupport.emptySet();
@@ -97,10 +102,23 @@ public abstract class AbstractPlugin<T extends Module> implements Plugin<T> {
/** {@inheritDoc} */
@Override
- public boolean equals(final Object obj) {
- return obj instanceof Plugin && getPluginId().equals(((Plugin<?>) obj).getPluginId());
+ @Nonnull
+ public Collection<Package> getPackages() {
+ return packages;
+ }
+
+ /** Set the packages to transfer
+ * @param input what to set
+ */
+ public void setPackages(@Nonnull Collection<Package> input) {
+ packages = CollectionSupport.copyToList(input);
}
+ /** {@inheritDoc} */
+ @Override
+ public boolean equals(final Object obj) {
+ return obj instanceof Plugin && getPluginId().equals(((Plugin<?>) obj).getPluginId());
+ }
/** {@inheritDoc} */
@Override
@@ -113,5 +131,5 @@ public abstract class AbstractPlugin<T extends Module> implements Plugin<T> {
public String toString() {
return "Plugin " + getPluginId();
}
-
+
}
\ No newline at end of file
diff --git a/shib-profile-api/src/main/java/net/shibboleth/profile/plugin/Plugin.java b/shib-profile-api/src/main/java/net/shibboleth/profile/plugin/Plugin.java
index 543ef65..4bc697d 100644
--- a/shib-profile-api/src/main/java/net/shibboleth/profile/plugin/Plugin.java
+++ b/shib-profile-api/src/main/java/net/shibboleth/profile/plugin/Plugin.java
@@ -16,6 +16,7 @@ package net.shibboleth.profile.plugin;
import java.io.IOException;
import java.net.URL;
+import java.util.Collection;
import java.util.List;
import java.util.Set;
@@ -27,6 +28,7 @@ import net.shibboleth.profile.module.Module;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.annotation.constraint.NotLive;
import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+import net.shibboleth.shared.collection.CollectionSupport;
/**
* The base interface for plugins into the IdP and SP.
@@ -104,4 +106,36 @@ public interface Plugin<T extends Module> {
*/
@Nonnull @Unmodifiable @NotLive Set<T> getDisableOnRemoval();
+ /**
+ * Get the things to explicitly install.
+ *
+ * @return what to install
+ */
+ default @Nonnull @Unmodifiable @NotLive Collection<Package> getPackages() {
+ return CollectionSupport.emptySet();
+ }
+
+ /** An abstraction for "a thing that we want to unpack into idp home (outside webapps)". */
+ interface Package {
+
+ /** Where in the zip file is the file.
+ * @return the location.
+ */
+ @Nonnull @Unmodifiable @NotLive String getSourceName();
+
+ /** Where the file/string has to be unpacked to (relative to idp.home).
+ * @return the location
+ */
+ @Nonnull @Unmodifiable @NotLive String getDestinationName();
+
+ /** Is this package for Windows Only?
+ * @return true if it is
+ */
+ boolean isWindows();
+
+ /** Is this package for non-windows Only?
+ * @return
+ */
+ boolean isNonWindows();
+ }
}
\ No newline at end of file
diff --git a/shib-profile-api/src/main/java/net/shibboleth/profile/plugin/PropertyDrivenPlugin.java b/shib-profile-api/src/main/java/net/shibboleth/profile/plugin/PropertyDrivenPlugin.java
index 0991ad3..a783d81 100644
--- a/shib-profile-api/src/main/java/net/shibboleth/profile/plugin/PropertyDrivenPlugin.java
+++ b/shib-profile-api/src/main/java/net/shibboleth/profile/plugin/PropertyDrivenPlugin.java
@@ -19,6 +19,7 @@ import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
@@ -41,9 +42,9 @@ import net.shibboleth.shared.primitive.StringSupport;
/**
* Implementation of {@link Plugin} relying on Java {@link Properties}.
- *
+ *
* @param <T> module type
- *
+ *
* @since 4.1.0
*/
public abstract class PropertyDrivenPlugin<T extends Module> extends AbstractPlugin<T> implements Plugin<T> {
@@ -66,6 +67,21 @@ public abstract class PropertyDrivenPlugin<T extends Module> extends AbstractPlu
/** Property for plugin's required modules. */
@Nonnull @NotEmpty public static final String PLUGIN_REQ_MODULES_PROPERTY = "plugin.modules.required";
+ /** Prefix for the properties for plugin's packages. */
+ @Nonnull @NotEmpty public static final String PLUGIN_PACKAGE_PROPERTY = "plugin.package.";
+
+ /** Postfix for the source package properties. */
+ @Nonnull @NotEmpty public static final String PLUGIN_PACKAGE_SOURCE_PROPERTY = ".source";
+
+ /** Postfix for the destination package properties. */
+ @Nonnull @NotEmpty public static final String PLUGIN_PACKAGE_DESTNATION_PROPERTY = ".destination";
+
+ /** Postfix for the windows package properties. */
+ @Nonnull @NotEmpty public static final String PLUGIN_PACKAGE_WINDOWS_PROPERTY = ".windows";
+
+ /** Postfix for the non-windows package properties. */
+ @Nonnull @NotEmpty public static final String PLUGIN_PACKAGE_NONWINDOWS_PROPERTY = ".nonwindows";
+
/** Class logger. */
@Nonnull private Logger log = LoggerFactory.getLogger(PropertyDrivenPlugin.class);
@@ -74,13 +90,13 @@ public abstract class PropertyDrivenPlugin<T extends Module> extends AbstractPlu
/** Non-defaulted plugin ID. */
@Nullable private String pluginId;
-
+
/** Handles parsing of plugin version. */
@Nullable private InstallableComponentVersion pluginVersion;
-
+
/** Plugin update URLs. */
@Nonnull private List<URL> updateURLs = CollectionSupport.emptyList();
-
+
/** Required modules. */
@Nonnull private Set<String> requiredModules = CollectionSupport.emptySet();
@@ -88,19 +104,19 @@ public abstract class PropertyDrivenPlugin<T extends Module> extends AbstractPlu
* Constructor.
*
* @param claz type of object used to locate default module.properties resource
- *
+ *
* @throws IOException if unable to read file
* @throws PluginException if the plugin is not in a valid state
*/
public PropertyDrivenPlugin(@Nonnull final Class<? extends Plugin<T>> claz) throws IOException, PluginException {
this(Constraint.isNotNull(claz.getResourceAsStream(DEFAULT_RESOURCE), "never get: null resource stream"));
}
-
+
/**
* Constructor.
*
* @param inputStream property stream
- *
+ *
* @throws IOException if unable to read file
* @throws PluginException if the plugin is not in a valid state
*/
@@ -114,23 +130,23 @@ public abstract class PropertyDrivenPlugin<T extends Module> extends AbstractPlu
* Constructor.
*
* @param properties property set
- *
+ *
* @throws PluginException if the plugin is not in a valid state
*/
public PropertyDrivenPlugin(@Nonnull final Properties properties) throws PluginException {
pluginProperties = Constraint.isNotNull(properties, "Properties cannot be null");
load();
}
-
+
/**
* Load plugin information from properties.
- *
+ *
* @throws PluginException on errors
*/
protected void load() throws PluginException {
-
+
pluginId = StringSupport.trimOrNull(pluginProperties.getProperty(PLUGIN_ID_PROPERTY));
-
+
String version = getClass().getPackage().getImplementationVersion();
if (version == null) {
version = StringSupport.trimOrNull(pluginProperties.getProperty(PLUGIN_VERSION_PROPERTY));
@@ -139,7 +155,7 @@ public abstract class PropertyDrivenPlugin<T extends Module> extends AbstractPlu
}
log.debug("Using plugin '{}' version property in favor of absent package manifest", pluginId);
}
-
+
try {
pluginVersion = new InstallableComponentVersion(version);
} catch (final NumberFormatException e) {
@@ -147,33 +163,58 @@ public abstract class PropertyDrivenPlugin<T extends Module> extends AbstractPlu
}
final List<URL> urls = new ArrayList<>();
-
+
for (Integer urlnum = 1; ; ++urlnum) {
-
+
final String urlstr = pluginProperties.getProperty(PLUGIN_URL_PROPERTY + urlnum.toString());
if (urlstr == null) {
break;
}
-
+
try {
urls.add(new URL(urlstr));
} catch (final MalformedURLException e) {
log.error("Unable to convert property value '{}' to URL", urlstr, e);
}
}
-
urls.addAll(getDefaultUpdateURLs());
-
+
updateURLs = CollectionSupport.copyToList(urls);
-
- final String propVals = pluginProperties.getProperty(PLUGIN_REQ_MODULES_PROPERTY, "");
- assert propVals != null;
+
+ final String propVals = pluginProperties.getProperty(PLUGIN_REQ_MODULES_PROPERTY, "");
+ assert propVals != null;
requiredModules = CollectionSupport.copyToSet(StringSupport.normalizeStringCollection(StringSupport.stringToList(propVals, ",")));
+ final HashSet<Plugin.Package> packages = new HashSet<Plugin.Package>();
+
+ for (Integer packageNum = 1; ; ++packageNum) {
+ final String packageNumStr = packageNum.toString();
+ final String srcStr = pluginProperties.getProperty(PLUGIN_PACKAGE_PROPERTY + packageNumStr + PLUGIN_PACKAGE_SOURCE_PROPERTY);
+ if (srcStr == null) {
+ break;
+ }
+ final String destStr = pluginProperties.getProperty(PLUGIN_PACKAGE_PROPERTY + packageNumStr + PLUGIN_PACKAGE_DESTNATION_PROPERTY);
+ if (destStr == null) {
+ log.error("Plugin {} no destination index {} (source = {}", pluginId, packageNum, srcStr);
+ break;
+ }
+ final boolean nonWin = Boolean.valueOf(
+ pluginProperties.getProperty(PLUGIN_PACKAGE_PROPERTY + packageNumStr + PLUGIN_PACKAGE_NONWINDOWS_PROPERTY, "false"));
+ final boolean win = Boolean.valueOf(
+ pluginProperties.getProperty(PLUGIN_PACKAGE_PROPERTY + packageNumStr + PLUGIN_PACKAGE_WINDOWS_PROPERTY, "false"));
+
+ packages.add(new PackageDescriptor(srcStr, destStr, nonWin, win));
+ }
+ setPackages(packages);
+
+ final String reqModules = pluginProperties.getProperty(PLUGIN_REQ_MODULES_PROPERTY, "");
+ assert reqModules != null;
+ requiredModules = CollectionSupport.copyToSet(
+ StringSupport.normalizeStringCollection(StringSupport.stringToList(reqModules , ",")));
log.debug("Plugin {} loaded", getPluginId());
}
-
+
/** {@inheritDoc} */
@Override
@Nonnull @NotEmpty public String getPluginId() {
@@ -182,7 +223,7 @@ public abstract class PropertyDrivenPlugin<T extends Module> extends AbstractPlu
}
return super.getPluginId();
}
-
+
/** {@inheritDoc} */
@Nonnull @Unmodifiable @NotLive public List<URL> getUpdateURLs() {
return updateURLs;
@@ -217,15 +258,90 @@ public abstract class PropertyDrivenPlugin<T extends Module> extends AbstractPlu
assert pluginVersion != null;
return pluginVersion.getPatch();
}
-
+
/**
* Provides default update locations to use.
- *
+ *
* @return default update locations
* @throws PluginException if a derived class throws it (see derived classes)
*/
@Nonnull @Unmodifiable @NotLive protected List<URL> getDefaultUpdateURLs() throws PluginException {
return CollectionSupport.emptyList();
}
-
-}
\ No newline at end of file
+
+ /** Implementation of {@link Plugin.Package} for our use. */
+ private static class PackageDescriptor implements Package {
+
+ /** What to return to {@link Plugin.Package#getSourceName()}. */
+ @Nonnull private final String source;
+
+ /** What to return to {@link Plugin.Package#getDestinationName()}. */
+ @Nonnull private final String destination;
+
+ /** What to return to {@link Plugin.Package#isNonWindows()}. */
+ private final boolean nonWindows;
+
+ /** What to return to {@link Plugin.Package#isWindows()}. */
+ private final boolean windows;
+
+ /**
+ * Constructor.
+ *
+ * @param src for {@link #getSourceName()}
+ * @param dest for {@link #getDestinationName()}
+ * @param nonWin for{@link #isNonWindows()}
+ * @param win for {@link #isWindows()}
+ */
+ private PackageDescriptor(@Nonnull final String src, @Nonnull final String dest, final boolean nonWin, final boolean win) {
+ source = src;
+ destination = dest;
+ nonWindows = nonWin;
+ windows = win;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nonnull
+ public String getSourceName() {
+ return source;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nonnull
+ public String getDestinationName() {
+ return destination;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean isWindows() {
+ return windows;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean isNonWindows() {
+ return nonWindows;
+ }
+
+ /** {@inheritDoc}. Hashing and equality os slightly weird because we want to deduplicate on {{@link #destination} only */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (obj instanceof PackageDescriptor desc) {
+ return desc.destination.equals(destination);
+ }
+ return false;
+ }
+
+ /** {@inheritDoc}. Hashing and equality os slightly weird because we want to deduplicate on {{@link #destination} only */
+ @Override
+ public int hashCode() {
+ return destination.hashCode();
+ }
+
+ }
+}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list