[java-identity-provider] branch main updated: IDP-2073 Consider enabling the installer to download new versions
Rod Widdowson
rdw at steadingsoftware.com
Sat Jun 3 14:57:47 UTC 2023
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=608ef6e80d12d61c55352e56fc9bdcb327679b82
The following commit(s) were added to refs/heads/main by this push:
new 608ef6e80 IDP-2073 Consider enabling the installer to download new versions
608ef6e80 is described below
commit 608ef6e80d12d61c55352e56fc9bdcb327679b82
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Sat Jun 3 15:54:37 2023 +0100
IDP-2073 Consider enabling the installer to download new versions
https://shibboleth.atlassian.net/browse/IDP-2073
Major refactor of the Plugin handling
1) Move some version handling things inside the IdP (prior
to onward transfer to shib-profile). This will allow the IdP
to make enquries about plugins (and eventually itself).
2) Collapse a lot of specific Plugin Installer helper code up into the
IdP helper code.
---
.../idp/plugin/InstallableComponentInfo.java | 334 +++++++++++++++++
...rsion.java => InstallableComponentVersion.java} | 14 +-
.../net/shibboleth/idp/plugin/PluginSupport.java | 128 ++++++-
.../net/shibboleth/idp/plugin/PluginVersion.java | 158 +-------
.../idp/plugin/PropertyDrivenIdPPlugin.java | 4 +-
.../shibboleth/idp/plugin/PluginVersionTest.java | 26 +-
.../shibboleth/idp/installer/InstallerSupport.java | 205 ++++++++++-
.../shibboleth/idp/installer/impl/V5Install.java | 6 +-
.../idp/installer/plugin/impl/PluginInfo.java | 247 ++-----------
.../idp/installer/plugin/impl/PluginInstaller.java | 35 +-
.../plugin/impl/PluginInstallerArguments.java | 10 +-
.../installer/plugin/impl/PluginInstallerCLI.java | 56 +--
.../plugin/impl/PluginInstallerSupport.java | 397 ---------------------
.../idp/installer/plugin/impl/PluginState.java | 59 +--
.../idp/installer/plugin/impl/BasePluginTest.java | 2 +-
.../idp/installer/plugin/impl/PluginCLITest.java | 3 +-
.../idp/installer/plugin/impl/PluginStateTest.java | 28 +-
.../idp/installer/plugin/impl/RollbackTester.java | 3 +-
18 files changed, 799 insertions(+), 916 deletions(-)
diff --git a/idp-admin-api/src/main/java/net/shibboleth/idp/plugin/InstallableComponentInfo.java b/idp-admin-api/src/main/java/net/shibboleth/idp/plugin/InstallableComponentInfo.java
new file mode 100644
index 000000000..5fae44edf
--- /dev/null
+++ b/idp-admin-api/src/main/java/net/shibboleth/idp/plugin/InstallableComponentInfo.java
@@ -0,0 +1,334 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.plugin;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.regex.Pattern;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import net.shibboleth.idp.plugin.PluginSupport.SupportLevel;
+import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.primitive.StringSupport;
+
+/**
+ * Class which encapsulates the information about a given Installable Component as downloaded
+ * from the appropriate location (as a Properties file).
+ * Different variants deal with the max and min supported versions (Plugins get them from a file
+ * Non plugins derive them from the version under consideration.
+ */
+public abstract class InstallableComponentInfo {
+
+ /** regexp for spaces. */
+ private static final Pattern SPACE_CONTAINING = Pattern.compile("\\s+");
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(InstallableComponentInfo.class);
+
+ /** The support information. */
+ @Nonnull private final Map<InstallableComponentVersion, InstallableComponentInfo.VersionInfo> versionInfo = new HashMap<>();
+
+ /** The Download information. */
+ @Nonnull private final Map<InstallableComponentVersion, Pair<URL,String>> downloadInfo = new HashMap<>();
+
+ /** The Id. */
+ @Nonnull private final String componentId;
+
+ /** Whether the information was sufficient. */
+ private boolean allInfoPresent = true;
+
+ /**
+ * Constructor.
+ *
+ * @param id the id we care about
+ * @param props all the properties.
+ */
+ public InstallableComponentInfo(@Nonnull final String id, @Nonnull final Properties props) {
+ componentId = id;
+ parse(props);
+ }
+
+ /** Did the property file have enough information?
+ * @return true if something was missing.
+ */
+ public boolean isInfoComplete() {
+ return allInfoPresent;
+ }
+
+ /** Get the base URL for this version.
+ * @param version which version
+ * @return the base URL
+ */
+ @Nullable public URL getUpdateURL(@Nonnull final InstallableComponentVersion version) {
+ final Pair<URL, String> p = downloadInfo.get(version);
+ if (p == null) {
+ return null;
+ }
+ return p.getFirst();
+ }
+
+ /** Get the base Name for this version.
+ * @param version which version
+ * @return the base name
+ */
+ @Nullable public String getUpdateBaseName(@Nonnull final InstallableComponentVersion version) {
+ final Pair<URL, String> p = downloadInfo.get(version);
+ if (p == null) {
+ return null;
+ }
+ return p.getSecond();
+ }
+
+ /** Get the raw version info for this component.
+ * @return the info.
+ */
+ @Nonnull public Map<InstallableComponentVersion, InstallableComponentInfo.VersionInfo> getAvailableVersions() {
+ return versionInfo;
+ }
+
+ /** Get the Installable Component Id under consideration
+ * @return Returns the componentId.
+ */
+ @Nonnull protected String getComponentId() {
+ return componentId;
+ }
+
+ /** (try to) populate the information about this component.
+ * @param props what to load.
+ */
+ private void parse(@Nonnull final Properties props) {
+ final String name = componentId + PluginSupport.AVAILABLE_VERSIONS_PROPERTY_SUFFIX;
+ final String availableVersions = StringSupport.trim(props.getProperty(name));
+ if (availableVersions == null) {
+ log.warn("Component {}: Could not find {} property.", componentId, name);
+ allInfoPresent = false;
+ } else {
+ handleAvailableVersions(props, availableVersions);
+ }
+ }
+
+ /** Given a version find out more.
+ * @param props the property files for this component we are looking at
+ * @param version the version in question.
+ */
+ private void handleAvailableVersion(@Nonnull final Properties props, @Nonnull final String version) {
+ final InstallableComponentVersion theVersion = new InstallableComponentVersion(version);
+ if (theVersion.getMajor() == 0 && theVersion.getMinor() == 0 && theVersion.getPatch() == 0) {
+ log.warn("Component {}: Improbable version {}", componentId, version);
+ }
+ if (versionInfo.containsKey(theVersion)) {
+ log.warn("Component {}: Duplicate version {}", componentId, version);
+ }
+
+ final InstallableComponentVersion maxVersionInfo = getMaxVersion(props, version);
+ if (maxVersionInfo == null) {
+ log.warn("Component {}, Version {}: Could not find max idp version.", componentId, version);
+ allInfoPresent = false;
+ return;
+ }
+
+ final InstallableComponentVersion minVersionInfo = getMinVersion(props, version);
+ if (minVersionInfo == null) {
+ log.warn("Component {}, Version {}: Could not find min idp version.", componentId, version);
+ allInfoPresent = false;
+ return;
+ }
+
+ final String supportLevelString = StringSupport.trimOrNull(
+ props.getProperty(componentId + PluginSupport.SUPPORT_LEVEL_INTERFIX + version));
+ PluginSupport.SupportLevel supportLevel;
+ if (supportLevelString == null) {
+ log.debug("Component {}, Version {}: Could not find support level for {}.", componentId, version);
+ supportLevel = SupportLevel.Unknown;
+ } else {
+ try {
+ supportLevel = Enum.valueOf(SupportLevel.class, supportLevelString);
+ } catch (final IllegalArgumentException e) {
+ log.warn("Component {}, Version {}: Invalid support level {}.", componentId, version, supportLevelString);
+ supportLevel = SupportLevel.Unknown;
+ }
+ }
+
+ log.debug("Component {}: MaxIdP {}, MinIdP {}, Support Level {}",
+ componentId, maxVersionInfo, minVersionInfo, supportLevel);
+ final InstallableComponentInfo.VersionInfo info;
+ info = new InstallableComponentInfo.VersionInfo(maxVersionInfo, minVersionInfo, supportLevel);
+ versionInfo.put(theVersion, info);
+ String downloadURL = StringSupport.trimOrNull(
+ getDefaultedValue(props, PluginSupport.DOWNLOAD_URL_INTERFIX, version));
+ final String baseName = StringSupport.trimOrNull(
+ getDefaultedValue(props, PluginSupport.BASE_NAME_INTERFIX, version));
+ if (baseName != null && downloadURL != null) {
+ try {
+ if (!downloadURL.endsWith("/")) {
+ downloadURL += "/";
+ }
+ final URL url = new URL(downloadURL);
+ downloadInfo.put(theVersion, new Pair<>(url, baseName));
+ log.trace("Component {}, version {}: Added download URL {} baseName {} for {}",
+ componentId, theVersion, url, baseName);
+ } catch (final MalformedURLException e) {
+ log.warn("Component {}, version {}: Download URL '{}' could not be constructed",
+ componentId, theVersion, downloadURL, e);
+ }
+ } else {
+ log.info("Component {}, version {}: no download information present", componentId, theVersion);
+ }
+ }
+
+ /** Find the max supported version version we can be installed into.
+ * @param props the properties to look at
+ * @param version the component version we are enquiring about
+ * @return the version null if not found.
+ */
+ @Nullable abstract protected InstallableComponentVersion getMaxVersion(@Nonnull final Properties props, @Nonnull final String version);
+
+ /** Find the min supported version we can be installed into.
+ * @param props the properties to look at
+ * @param version the component version we are enquiring about
+ * @return the version null if not found.
+ */
+ @Nullable abstract protected InstallableComponentVersion getMinVersion(@Nonnull final Properties props, @Nonnull final String version);
+
+ /** Given a list of versions find out more.
+ * @param props the property files for the component we are looking at
+ * @param availableVersions a space delimited array of versions
+ */
+ private void handleAvailableVersions(@Nonnull final Properties props, @Nonnull final String availableVersions) {
+ final String[] versions = SPACE_CONTAINING.split(availableVersions, 0);
+
+ log.debug("Component {}: Available versions : {} ", componentId, availableVersions);
+ for (final String version:versions) {
+ assert version != null;
+ log.debug("Component {}: Considering {}", componentId, version);
+ handleAvailableVersion(props, version);
+ }
+ }
+
+ /** Look up the key derived from the component, the interfix and the version, but if that
+ * fails look for a templated definition.
+ * @param props what to look in
+ * @param interfix the interface (between the ID and the version)
+ * @param version the version.
+ * @return the suitable value
+ */
+ @Nullable private String getDefaultedValue(@Nonnull final Properties props, @Nonnull final String interfix, @Nonnull final String version) {
+ String result = props.getProperty(componentId + interfix + version);
+ if (result != null) {
+ return result;
+ }
+ result = props.getProperty(componentId + interfix + PluginSupport.VERSION_PATTERN);
+ if (result == null) {
+ return result;
+ }
+ return result.replaceAll(PluginSupport.VERSION_PATTERN_REGEX, version);
+ }
+
+ /** Can the specified component be installed into this version?
+ * @param componentVersion the version if the component as a {@link InstallableComponentVersion}
+ * @param intsallIntoVersion the version if the IDP as a {@link InstallableComponentVersion}
+ * @return whether it is supported.
+ */
+ public boolean isSupportedWithIdPVersion(@Nonnull final InstallableComponentVersion componentVersion, @Nonnull final InstallableComponentVersion intsallIntoVersion) {
+ final InstallableComponentInfo.VersionInfo info = versionInfo.get(componentVersion);
+ if (info == null) {
+ log.error("Component {}: Unknown version {} supplied.", componentId, componentVersion);
+ log.debug("Component {}: Available {}", componentId, versionInfo.keySet());
+ return false;
+ }
+ return InstallableComponentInfo.isSupportedWithIdPVersion(info, intsallIntoVersion);
+ }
+
+ /** Can the specified component be installed into this version?
+ * Worker method for all 'isSupportedWith' classes.
+ * @param componentVersionInfo the version info to consider
+ * @param installIntoVersion the version as a {@link InstallableComponentVersion}
+ * @return whether it is supported.
+ */
+ public static boolean isSupportedWithIdPVersion(@Nonnull final VersionInfo componentVersionInfo,
+ @Nonnull final InstallableComponentVersion installIntoVersion) {
+ final int maxCompare = installIntoVersion.compareTo(componentVersionInfo.getMaxSupported());
+ if (maxCompare >= 0) {
+ // Exclusive:
+ // IdP (test against) Version is GREATER THAN OR EQUAL to our Max
+ return false;
+ }
+ final int minCompare = installIntoVersion.compareTo(componentVersionInfo.getMinSupported());
+ if (minCompare >= 0) {
+ // Inclusive:
+ // IdP (test against) version is GREATER THAN OR EQUAL to our Min
+ return true;
+ }
+ return false;
+ }
+
+ /** Encapsulation of the information about a given IdP version. */
+ public static class VersionInfo {
+
+ /** Maximum version - this version is NOT SUPPORTED. */
+ private final InstallableComponentVersion maxSupported;
+
+ /** Minimum version - this version IS supported. */
+ private final InstallableComponentVersion minSupported;
+
+ /** support level. */
+ private final SupportLevel supportLevel;
+
+ /**
+ * Constructor.
+ *
+ * @param max support level
+ * @param min support level
+ * @param support support level
+ */
+ public VersionInfo(final InstallableComponentVersion max, final InstallableComponentVersion min, final SupportLevel support) {
+ maxSupported = max;
+ minSupported = min;
+ supportLevel = support;
+ }
+
+ /** get Maximum version - this version is NOT SUPPORTED.
+ * @return Returns the maxSupported.
+ */
+ public InstallableComponentVersion getMaxSupported() {
+ return maxSupported;
+ }
+
+ /** get Minimum (IdP) version - this version IS supported.
+ * @return Returns the minSupported.
+ */
+ public InstallableComponentVersion getMinSupported() {
+ return minSupported;
+ }
+
+ /** get support level.
+ * @return Returns the supportLevel.
+ */
+ public SupportLevel getSupportLevel() {
+ return supportLevel;
+ }
+ }
+}
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/InstallableComponentVersion.java
similarity index 89%
copy from idp-admin-api/src/main/java/net/shibboleth/idp/plugin/PluginVersion.java
copy to idp-admin-api/src/main/java/net/shibboleth/idp/plugin/InstallableComponentVersion.java
index 2c0ae97fd..f0bd5d4bd 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/InstallableComponentVersion.java
@@ -24,7 +24,7 @@ import net.shibboleth.shared.primitive.StringSupport;
/**
* A version string (Major.minor.patch) as a handy class.
*/
-public final class PluginVersion implements Comparable<PluginVersion>{
+public class InstallableComponentVersion implements Comparable<InstallableComponentVersion>{
/** arbitrary maximum (to help hashing and sanity). */
private static final int MAX_VNO = 10000;
@@ -45,7 +45,7 @@ public final class PluginVersion implements Comparable<PluginVersion>{
* @throws NumberFormatException if it doesn't fit a 1.2.3 format or if the values are
* out of range
*/
- public PluginVersion(final String version) throws NumberFormatException {
+ public InstallableComponentVersion(final String version) throws NumberFormatException {
final String versionStr = StringSupport.trimOrNull(version);
if (null == versionStr) {
@@ -70,7 +70,7 @@ public final class PluginVersion implements Comparable<PluginVersion>{
* @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 {
+ public InstallableComponentVersion(@Nonnull final IdPPlugin plugin) throws NumberFormatException {
this(plugin.getMajorVersion(), plugin.getMinorVersion(), plugin.getPatchVersion());
}
@@ -82,7 +82,7 @@ public final class PluginVersion implements Comparable<PluginVersion>{
* @param pat Patch Version
* @throws NumberFormatException if the values are out of range
*/
- public PluginVersion(final int maj, final int min, final int pat) throws NumberFormatException {
+ public InstallableComponentVersion(final int maj, final int min, final int pat) throws NumberFormatException {
major = maj;
if (maj < 0 || maj >= MAX_VNO) {
throw new NumberFormatException("Improbable major version number : " + maj);
@@ -142,8 +142,8 @@ public final class PluginVersion implements Comparable<PluginVersion>{
/** {@inheritDoc} */
public boolean equals(final Object obj) {
- if (obj instanceof PluginVersion) {
- final PluginVersion other= (PluginVersion)obj;
+ if (obj instanceof InstallableComponentVersion) {
+ final InstallableComponentVersion other= (InstallableComponentVersion)obj;
return other.major == major && other.minor == minor && other.patch == patch;
}
return false;
@@ -162,7 +162,7 @@ public final class PluginVersion implements Comparable<PluginVersion>{
* negative integer, zero, or a positive integer as this object is less
* than, equal to, or greater than the specified object.
* {@inheritDoc} */
- public int compareTo(final PluginVersion other) {
+ public int compareTo(final InstallableComponentVersion other) {
if (major == other.major) {
if (minor == other.minor) {
return patch - other.patch;
diff --git a/idp-admin-api/src/main/java/net/shibboleth/idp/plugin/PluginSupport.java b/idp-admin-api/src/main/java/net/shibboleth/idp/plugin/PluginSupport.java
index bc5a8daf6..4b1232f3b 100644
--- a/idp-admin-api/src/main/java/net/shibboleth/idp/plugin/PluginSupport.java
+++ b/idp-admin-api/src/main/java/net/shibboleth/idp/plugin/PluginSupport.java
@@ -17,12 +17,27 @@
package net.shibboleth.idp.plugin;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.apache.hc.client5.http.classic.HttpClient;
+import org.opensaml.security.httpclient.HttpClientSecurityContextHandler;
+import org.opensaml.security.httpclient.HttpClientSecurityParameters;
import org.slf4j.Logger;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.core.io.Resource;
import net.shibboleth.idp.Version;
+import net.shibboleth.idp.plugin.InstallableComponentInfo.VersionInfo;
+import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.spring.httpclient.resource.HTTPResource;
/** Useful methods for supporting plugins.
*
@@ -77,14 +92,119 @@ public final class PluginSupport {
}
/** Get parse IdP Version (with fallback for testing).
- * @return a {@link PluginVersion} of the version.
+ * @return a {@link InstallableComponentVersion} of the version.
*/
- public static PluginVersion getIdPVersion() {
+ public static InstallableComponentVersion getIdPVersion() {
final String idpVersion = Version.getVersion();
if (idpVersion!=null) {
- return new PluginVersion(idpVersion);
+ return new InstallableComponentVersion(idpVersion);
}
log.error("Could not locate IdP Version, assuming 5.0.0");
- return new PluginVersion(5,0,0);
+ return new InstallableComponentVersion(5,0,0);
+ }
+
+ /** Find the best update version (plugin or IdP).
+ * @param installIntoVersion The IdP version to check.
+ * @param pluginVersion The Plugin version
+ * @param pluginInfo all about the plugin
+ * @return the best version (or null)
+ */
+ @Nullable static public InstallableComponentVersion getBestVersion(
+ @Nonnull final InstallableComponentVersion installIntoVersion,
+ @Nonnull final InstallableComponentVersion pluginVersion,
+ @Nonnull final InstallableComponentInfo pluginInfo) {
+ final List<InstallableComponentVersion> availableVersions = new ArrayList<>(pluginInfo.getAvailableVersions().keySet());
+ availableVersions.sort(null);
+ log.debug("Considering versions: {}", availableVersions);
+
+ for (int i = availableVersions.size()-1; i >= 0; i--) {
+ final InstallableComponentVersion version = availableVersions.get(i);
+ if (version.compareTo(pluginVersion) <= 0) {
+ log.debug("Version {} is less than or the same as {}. All done", version, pluginVersion);
+ return null;
+ }
+ final VersionInfo versionInfo = pluginInfo.getAvailableVersions().get(version);
+ if (versionInfo.getSupportLevel() != SupportLevel.Current) {
+ log.debug("Version {} has support level {}, ignoring", version, versionInfo.getSupportLevel());
+ continue;
+ }
+ if (!pluginInfo.isSupportedWithIdPVersion(version, installIntoVersion)) {
+ log.debug("Version {} is not supported with idpVersion {}", version, installIntoVersion);
+ continue;
+ }
+ log.debug("Version {} is supported with idpVersion {}", version, installIntoVersion);
+ if (pluginInfo.getUpdateURL(version) == null || pluginInfo.getUpdateBaseName(version) == null) {
+ log.debug("Version {} is does not have update information", version);
+ continue;
+ }
+ return version;
+ }
+ return null;
+ }
+
+ /** Find the best update version (plugin or IdP).
+ * @param pluginVersion The Plugin version
+ * @param pluginInfo all about the plugin
+ * @return the best version (or null)
+ */
+ @Nullable static public InstallableComponentVersion getBestVersion(
+ @Nonnull final InstallableComponentVersion pluginVersion, @Nonnull final InstallableComponentInfo pluginInfo) {
+ return getBestVersion(getIdPVersion(), pluginVersion, pluginInfo);
+ }
+
+ /** Load the property file describing all the plugin we know about from a known location.
+ * @param updateURLs where to look
+ * @param client the http client to use
+ * @param securityParameters the HttpClientSecurityParameters, if any
+ * @return the property files for the component.
+ */
+ @Nullable public static Properties loadPluginInfo(@Nonnull final List<URL> updateURLs, @Nonnull final HttpClient client,
+ @Nullable final HttpClientSecurityParameters securityParameters) {
+ final List<URL> urls;
+ final Properties props = new Properties();
+ try {
+ if (updateURLs.isEmpty()) {
+ urls = List.of(
+ new URL("https://shibboleth.net/downloads/identity-provider/plugins/plugins.properties"),
+ new URL("http://plugins.shibboleth.net/plugins.properties"));
+ } else {
+ urls = updateURLs;
+ }
+ } catch (final IOException e) {
+ log.error("Could not load update URLs", e);
+ return null;
+ }
+ for (final URL url: urls) {
+ final Resource propertyResource;
+ try {
+ if ("file".equals(url.getProtocol())) {
+ final String path =url.getPath();
+ assert path != null;
+ propertyResource = new FileSystemResource(path);
+ } else if ("http".equals(url.getProtocol()) || "https".equals(url.getProtocol())) {
+ final HTTPResource httpResource;
+ propertyResource = httpResource = new HTTPResource(client , url);
+ final HttpClientSecurityContextHandler handler = new HttpClientSecurityContextHandler();
+ handler.setHttpClientSecurityParameters(securityParameters);
+ handler.initialize();
+ httpResource.setHttpClientContextHandler(handler);
+ } else {
+ log.error("Only file and http[s] URLs are allowed");
+ continue;
+ }
+ log.debug("Plugin Listing: Looking for update at {}", propertyResource.getDescription());
+ if (!propertyResource.exists()) {
+ log.info("{} could not be located", propertyResource.getDescription());
+ continue;
+ }
+ props.load(propertyResource.getInputStream());
+ return props;
+ } catch (final IOException | ComponentInitializationException e) {
+ log.error("Could not open Update URL {} :", url, e);
+ continue;
+ }
+ }
+ log.error("Could not locate any active update servers");
+ return null;
}
}
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 2c0ae97fd..baa3f1644 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
@@ -19,165 +19,35 @@ package net.shibboleth.idp.plugin;
import javax.annotation.Nonnull;
-import net.shibboleth.shared.primitive.StringSupport;
+import net.shibboleth.shared.primitive.DeprecationSupport;
+import net.shibboleth.shared.primitive.DeprecationSupport.ObjectType;
/**
- * A version string (Major.minor.patch) as a handy class.
+ * @deprecated class.
*/
-public final class PluginVersion implements Comparable<PluginVersion>{
+ at Deprecated(forRemoval = true, since = "5.0.0") public class PluginVersion extends InstallableComponentVersion {
- /** arbitrary maximum (to help hashing and sanity). */
- private static final int MAX_VNO = 10000;
-
- /** Major version. */
- private int major;
-
- /** Minor version. */
- private int minor;
-
- /** Patch version. */
- private int patch;
-
- /**
- * Constructor.
- *
- * @param version what to build from
- * @throws NumberFormatException if it doesn't fit a 1.2.3 format or if the values are
- * out of range
- */
- public PluginVersion(final String version) throws NumberFormatException {
-
- final String versionStr = StringSupport.trimOrNull(version);
- if (null == versionStr) {
- throw new NumberFormatException("Empty Version not allowed");
- }
-
- final String[] components = versionStr.split("\\.|\\+|-");
- if (components.length >= 1) {
- major = parseValue(components[0]);
- }
- if (components.length >= 2) {
- minor = parseValue(components[1]);
- }
- if (components.length >= 3) {
- patch = parseValue(components[2]);
- }
- }
-
/**
* 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());
+ public PluginVersion(@Nonnull IdPPlugin plugin) throws NumberFormatException {
+ super(plugin);
+ DeprecationSupport.warnOnce(ObjectType.CLASS, PluginVersion.class.toString(), null, InstallableComponentVersion.class.toString());
}
+
/**
* Constructor.
*
- * @param maj Major Version
- * @param min Minor Version
- * @param pat Patch Version
- * @throws NumberFormatException if the values are out of range
- */
- public PluginVersion(final int maj, final int min, final int pat) throws NumberFormatException {
- major = maj;
- if (maj < 0 || maj >= MAX_VNO) {
- throw new NumberFormatException("Improbable major version number : " + maj);
- }
- minor = min;
- if (min < 0 || min >= MAX_VNO) {
- throw new NumberFormatException("Improbable minor version number : " + min);
- }
- patch = pat;
- if (pat < 0 || pat >= MAX_VNO) {
- throw new NumberFormatException("Improbable patch version number : " + pat);
- }
- }
-
- /** Get the major version.
- * @return Returns the major version.
- */
- public int getMajor() {
- return major;
- }
-
- /** Get the minor version.
- * @return Returns the minor version.
- */
- public int getMinor() {
- return minor;
- }
-
- /** Get the patch version.
- * @return Returns the patch version.
- */
- public int getPatch() {
- return patch;
- }
-
- /** Is this version all zeros (usually as a result of a parsing issue.
- * @return if all nulls */
- public boolean isNull() {
- return major == 0 && minor ==0 && patch == 0;
- }
-
- /** Helper function for the constructor.
- *
- * Parse a string into an int with a range check.
- * @param valueAsString what to parse
- * @return the value as an int
- * @throws NumberFormatException if {@link Integer#parseInt(String, int)} does
- * or if the value is less than 0 or > {@link #MAX_VNO}.
+ * @param version what to build from
+ * @throws NumberFormatException if it doesn't fit a 1.2.3 format or if the values are
+ * out of range
*/
- private int parseValue(final String valueAsString) throws NumberFormatException{
- final int value = Integer.parseInt(valueAsString);
- if (value < 0 || value >= MAX_VNO) {
- throw new NumberFormatException("Improbable version number : " + value);
- }
- return value;
- }
-
- /** {@inheritDoc} */
- public boolean equals(final Object obj) {
- if (obj instanceof PluginVersion) {
- final PluginVersion other= (PluginVersion)obj;
- return other.major == major && other.minor == minor && other.patch == patch;
- }
- return false;
- }
-
- /** {@inheritDoc} */
- public int hashCode() {
- long l = major*MAX_VNO*MAX_VNO;
- l += minor * MAX_VNO;
- l += patch;
- return Long.hashCode(l);
- }
-
- /**
- * Compares this object with the specified object for order. Returns a
- * negative integer, zero, or a positive integer as this object is less
- * than, equal to, or greater than the specified object.
- * {@inheritDoc} */
- public int compareTo(final PluginVersion other) {
- if (major == other.major) {
- if (minor == other.minor) {
- return patch - other.patch;
- }
- return minor - other.minor;
- }
- return major - other.major;
- }
-
- /** {@inheritDoc} */
- public String toString() {
- return new StringBuffer(8).append(Integer.toString(major))
- .append('.')
- .append(Integer.toString(minor))
- .append('.')
- .append(Integer.toString(patch)).toString();
+ public PluginVersion(final String version) throws NumberFormatException {
+ super(version);
+ DeprecationSupport.warnOnce(ObjectType.CLASS, PluginVersion.class.toString(), null, InstallableComponentVersion.class.toString());
}
}
diff --git a/idp-admin-api/src/main/java/net/shibboleth/idp/plugin/PropertyDrivenIdPPlugin.java b/idp-admin-api/src/main/java/net/shibboleth/idp/plugin/PropertyDrivenIdPPlugin.java
index e0d232ad4..abad86e09 100644
--- a/idp-admin-api/src/main/java/net/shibboleth/idp/plugin/PropertyDrivenIdPPlugin.java
+++ b/idp-admin-api/src/main/java/net/shibboleth/idp/plugin/PropertyDrivenIdPPlugin.java
@@ -77,7 +77,7 @@ public abstract class PropertyDrivenIdPPlugin extends AbstractIdPPlugin {
@Nullable private String pluginId;
/** Handles parsing of plugin version. */
- @Nullable private PluginVersion pluginVersion;
+ @Nullable private InstallableComponentVersion pluginVersion;
/** Plugin update URLs. */
@Nonnull @NonnullElements private List<URL> updateURLs = CollectionSupport.emptyList();
@@ -144,7 +144,7 @@ public abstract class PropertyDrivenIdPPlugin extends AbstractIdPPlugin {
}
try {
- pluginVersion = new PluginVersion(version);
+ pluginVersion = new InstallableComponentVersion(version);
} catch (final NumberFormatException e) {
throw new PluginException(e);
}
diff --git a/idp-admin-api/src/test/java/net/shibboleth/idp/plugin/PluginVersionTest.java b/idp-admin-api/src/test/java/net/shibboleth/idp/plugin/PluginVersionTest.java
index 0cbd666f3..79066c8cf 100644
--- a/idp-admin-api/src/test/java/net/shibboleth/idp/plugin/PluginVersionTest.java
+++ b/idp-admin-api/src/test/java/net/shibboleth/idp/plugin/PluginVersionTest.java
@@ -24,14 +24,14 @@ import static org.testng.Assert.fail;
import org.testng.annotations.Test;
/**
- * Tests for {@link PluginVersion}
+ * Tests for {@link InstallableComponentVersion}
*/
@SuppressWarnings("javadoc")
public final class PluginVersionTest {
private void failParse(final String what) {
try {
- new PluginVersion(what);
+ new InstallableComponentVersion(what);
fail("Invalid version parsed OK");
} catch (final NumberFormatException e) {
return;
@@ -39,23 +39,23 @@ public final class PluginVersionTest {
}
@Test public void parseTest() {
- PluginVersion ver = new PluginVersion("4.2.1");
+ InstallableComponentVersion ver = new InstallableComponentVersion("4.2.1");
assertEquals(ver.getMajor(), 4);
assertEquals(ver.getMinor(), 2);
assertEquals(ver.getPatch(), 1);
- ver = new PluginVersion("3.4");
+ ver = new InstallableComponentVersion("3.4");
assertEquals(ver.getMajor(), 3);
assertEquals(ver.getMinor(), 4);
assertEquals(ver.getPatch(), 0);
- ver = new PluginVersion("2");
+ ver = new InstallableComponentVersion("2");
assertEquals(ver.getMajor(), 2);
assertEquals(ver.getMinor(), 0);
assertEquals(ver.getPatch(), 0);
// Edge cases
- ver = new PluginVersion("2.-.");
+ ver = new InstallableComponentVersion("2.-.");
assertEquals(ver.getMajor(), 2);
assertEquals(ver.getMinor(), 0);
assertEquals(ver.getPatch(), 0);
@@ -72,19 +72,19 @@ public final class PluginVersionTest {
failParse("10001.99.0");
try {
- new PluginVersion(1,2,-1);
+ new InstallableComponentVersion(1,2,-1);
fail("Bad version not caught");
} catch (NumberFormatException ex) {
// OK
}
try {
- new PluginVersion(10000,2,0);
+ new InstallableComponentVersion(10000,2,0);
fail("Bad version not caught");
} catch (NumberFormatException ex) {
// OK
}
try {
- new PluginVersion(1, 10000,2);
+ new InstallableComponentVersion(1, 10000,2);
fail("Bad version not caught");
} catch (NumberFormatException ex) {
// OK
@@ -95,9 +95,9 @@ public final class PluginVersionTest {
// check direction
assertTrue(Integer.valueOf(-1).compareTo(Integer.valueOf(0)) < 0);
- assertTrue(new PluginVersion("4.5.6").compareTo(new PluginVersion(4,5,6)) == 0);
- assertTrue(new PluginVersion(4,0,0).compareTo(new PluginVersion(3,9,9)) > 0);
- assertTrue(new PluginVersion(4,1,0).compareTo(new PluginVersion(4,2,1)) < 0);
- assertTrue(new PluginVersion(4,1,0).compareTo(new PluginVersion(4,1,1)) < 0);
+ assertTrue(new InstallableComponentVersion("4.5.6").compareTo(new InstallableComponentVersion(4,5,6)) == 0);
+ assertTrue(new InstallableComponentVersion(4,0,0).compareTo(new InstallableComponentVersion(3,9,9)) > 0);
+ assertTrue(new InstallableComponentVersion(4,1,0).compareTo(new InstallableComponentVersion(4,2,1)) < 0);
+ assertTrue(new InstallableComponentVersion(4,1,0).compareTo(new InstallableComponentVersion(4,1,1)) < 0);
}
}
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/InstallerSupport.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/InstallerSupport.java
index e9b8f814e..5f5bb9021 100644
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/InstallerSupport.java
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/InstallerSupport.java
@@ -17,11 +17,21 @@
package net.shibboleth.idp.installer;
+import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.OutputStream;
+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.List;
+import java.util.function.Predicate;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
@@ -35,11 +45,18 @@ import org.apache.tools.ant.taskdefs.optional.unix.Chgrp;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.selectors.PresentSelector;
import org.apache.tools.ant.types.selectors.PresentSelector.FilePresence;
+import org.opensaml.security.httpclient.HttpClientSecurityContextHandler;
import org.slf4j.Logger;
+import net.shibboleth.idp.installer.plugin.impl.LoggingVisitor;
+import net.shibboleth.shared.annotation.constraint.Live;
+import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.primitive.StringSupport;
+import net.shibboleth.shared.spring.httpclient.resource.HTTPResource;
-/** General common names and helper functions for the Installer.
+/** General common names and helper functions for the IdP & Plugin Installers.
* This is not intended for general use.
*/
public final class InstallerSupport {
@@ -270,7 +287,7 @@ public final class InstallerSupport {
* @param where where
* @throws BuildException if badness occurs
*/
- public static void deleteTree(final Path where) throws BuildException {
+ public static void deleteTree(@Nullable final Path where) throws BuildException {
deleteTree(where, null);
}
@@ -279,8 +296,11 @@ public final class InstallerSupport {
* @param excludes wildcards to exclude
* @throws BuildException if badness occurs
*/
- public static void deleteTree(final Path where, final String excludes) throws BuildException {
- if (!Files.exists(where)) {
+ public static void deleteTree(@Nullable final Path where, @Nullable final String excludes) throws BuildException {
+ if (where == null) {
+ return;
+ }
+ if (where == null || !Files.exists(where)) {
log.debug("Directory {} does not exist. Skipping delete.", where);
return;
}
@@ -307,7 +327,7 @@ public final class InstallerSupport {
delete.setVerbose(!log.isDebugEnabled());
delete.execute();
}
-
+
/** Return a {@link Jar} task.
* @param baseDir where from
* @param destFile where to
@@ -320,4 +340,179 @@ public final class InstallerSupport {
jarTask.setProject(InstallerSupport.ANT_PROJECT);
return jarTask;
}
+
+ /** Download helper method.
+ * @param baseResource where to go for the file
+ * @param handler HttpClientSecurityContextHandler to use
+ * @param downloadDirectory where to download to
+ * @param fileName the file name
+ * @throws IOException as required
+ */
+ public static void download(@Nonnull final HTTPResource baseResource,
+ @Nonnull final HttpClientSecurityContextHandler handler,
+ @Nonnull final Path downloadDirectory,
+ @Nonnull final String fileName) throws IOException {
+ final HTTPResource httpResource = baseResource.createRelative(fileName, handler);
+ final Path filePath = downloadDirectory.resolve(fileName);
+ log.info("Downloading from {}", httpResource.getDescription());
+ log.debug("Downloading to {}", filePath);
+ try (final OutputStream fileOut = new ProgressReportingOutputStream(new FileOutputStream(filePath.toFile()))) {
+ httpResource.getInputStream().transferTo(fileOut);
+ }
+ }
+
+ /** Return the canonical path.
+ * @param from the path we get given
+ * @return the canonicalized one
+ * @throws IOException as from {@link File#getCanonicalFile()}
+ */
+ @SuppressWarnings("null")
+ @Nonnull
+ public static Path canonicalPath(@Nonnull final Path from) throws IOException {
+ return from.toFile().getCanonicalFile().toPath();
+ }
+
+ /** Rename Files into the provided tree.
+ * @param fromBase The root directory of the from files
+ * @param toBase The root directory to rename to
+ * @param fromFiles The list of files (inside fromBase) to rename
+ * @param renames All the work as it is done
+ * @throws IOException If any of the file operations fail
+ */
+ public static void renameToTree(@Nonnull final Path fromBase,
+ @Nonnull final Path toBase,
+ @Nonnull final List<Path> fromFiles,
+ @Nonnull @Live final List<Pair<Path, Path>> renames) throws IOException {
+ if (!Files.exists(toBase)) {
+ Files.createDirectories(toBase);
+ }
+ for (final Path path : fromFiles) {
+ if (!Files.exists(path)) {
+ log.info("File {} was not renamed away because it does not exist", path);
+ continue;
+ }
+ final Path relName = fromBase.relativize(path);
+ log.trace("Relative name {}", relName);
+ final Path to = toBase.resolve(relName);
+ Files.createDirectories(to.getParent());
+ Files.move(path,to);
+ renames.add(new Pair<>(path, to));
+ }
+ }
+
+ /** Traverse "from" looking to see if any of the files are already in "to".
+ * @param from source directory
+ * @param to target directory
+ * @return true if there was a match
+ * @throws BuildException if anything threw and {@link IOException}
+ */
+ public static boolean detectDuplicates(@Nonnull final Path from, @Nullable final Path to) throws BuildException {
+
+ if (to == null || !Files.exists(to)) {
+ return false;
+ }
+ final NameClashVisitor detector = new NameClashVisitor(from, to);
+ log.debug("Walking {}, looking for a name clash in {}", from, to);
+ try {
+ Files.walkFileTree(from, detector);
+ } catch (final IOException e) {
+ log.error("Failed during duplicate detection:", e);
+ throw new BuildException(e);
+ }
+ return detector.wasNameClash();
+ }
+
+ /** Copy a directory tree and keep a log of what has changed.
+ * @param from source directory
+ * @param to target directory
+ * @param pathsCopied the list of files copied up (including if there was a failure)
+ * @throws BuildException from the copy
+ */
+ public static void copyWithLogging(@Nullable final Path from,
+ @Nonnull final Path to, @Nonnull @Live final List<Path> pathsCopied) throws BuildException {
+ if (from == null || !Files.exists(from)) {
+ return;
+ }
+ log.debug("Copying from {} to {}", from, to);
+ final LoggingVisitor visitor = new LoggingVisitor(from, to);
+ try {
+ Files.walkFileTree(from, visitor);
+ } catch (final IOException e) {
+ pathsCopied.addAll(visitor.getCopiedList());
+ log.error("Error copying files from {} to {}", from, to, e);
+ throw new BuildException(e);
+ }
+ pathsCopied.addAll(visitor.getCopiedList());
+ }
+
+ /**
+ * A @{link {@link FileVisitor} which detects (and logs) whether a copy would overwrite.
+ */
+ private static final class NameClashVisitor extends SimpleFileVisitor<Path> {
+ /** did we find a duplicate. */
+ private boolean nameClash;
+
+ /** Path we are traversing. */
+ private final Path from;
+
+ /** Path where we check for Duplicates. */
+ private final Path to;
+
+ /**
+ * Constructor.
+ *
+ * @param fromDir Path we are traversing
+ * @param toDir Path where we check for Duplicates
+ */
+ public NameClashVisitor(@Nonnull final Path fromDir, @Nonnull final Path toDir) {
+ from = fromDir;
+ to = toDir;
+ }
+
+ @Override
+ public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
+ final Path relFile = from.relativize(file);
+ final Path toFile = to.resolve(relFile);
+ if (Files.exists(toFile)) {
+ nameClash = true;
+ log.warn("{} already exists", toFile);
+ }
+ return FileVisitResult.CONTINUE;
+ }
+
+ /** did we find a name clash?
+ * @return whether we found a name clash.
+ */
+ public boolean wasNameClash() {
+ return nameClash;
+ }
+ }
+
+ /** Predicate to ask the user if they want to install the trust store provided. */
+ public static class InstallerQuery implements Predicate<String> {
+
+ /** What to say. */
+ @Nonnull
+ private final String promptText;
+
+ /**
+ * Constructor.
+ * @param text What to say before the prompt information
+ */
+ public InstallerQuery(@Nonnull final String text) {
+ promptText = Constraint.isNotNull(text, "Text should not be null");
+ }
+
+ /** {@inheritDoc} */
+ public boolean test(final String keyString) {
+ if (System.console() == null) {
+ log.error("No Console Attached to installer");
+ return false;
+ }
+ System.console().printf("%s:\n%s [yN] ", promptText, keyString);
+ System.console().flush();
+ final String result = StringSupport.trimOrNull(System.console().readLine());
+ return result != null && "y".equalsIgnoreCase(result.substring(0, 1));
+ }
+ }
}
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/V5Install.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/V5Install.java
index 231efbcb7..d63d0e043 100644
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/V5Install.java
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/V5Install.java
@@ -59,7 +59,7 @@ 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.plugin.InstallableComponentVersion;
import net.shibboleth.idp.spring.IdPPropertiesApplicationContextInitializer;
import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.component.ComponentInitializationException;
@@ -136,10 +136,10 @@ public class V5Install {
*/
protected void checkPreConditions() throws BuildException {
final String versionAsString = Version.getVersion();
- final PluginVersion idpVersion = new PluginVersion(versionAsString!=null?versionAsString:"5.0.0");
+ final InstallableComponentVersion idpVersion = new InstallableComponentVersion(versionAsString!=null?versionAsString:"5.0.0");
for (final IdPPlugin plugin: ServiceLoader.load(IdPPlugin.class, currentState.getInstalledPluginsLoader())) {
final String pluginId = plugin.getPluginId();
- final PluginVersion pluginVersion = new PluginVersion(plugin);
+ final InstallableComponentVersion pluginVersion = new InstallableComponentVersion(plugin);
try {
log.debug("Considering Plugin {}, version {}", pluginId, pluginVersion);
final PluginState state = new PluginState(plugin, CollectionSupport.emptyList());
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginInfo.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginInfo.java
index 11df4cfad..7613e0677 100644
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginInfo.java
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginInfo.java
@@ -17,255 +17,52 @@
package net.shibboleth.idp.installer.plugin.impl;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.Map;
import java.util.Properties;
-import java.util.regex.Pattern;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import org.slf4j.Logger;
-
-import net.shibboleth.idp.installer.plugin.impl.PluginState.VersionInfo;
+import net.shibboleth.idp.plugin.InstallableComponentInfo;
+import net.shibboleth.idp.plugin.InstallableComponentVersion;
import net.shibboleth.idp.plugin.PluginSupport;
-import net.shibboleth.idp.plugin.PluginSupport.SupportLevel;
-import net.shibboleth.idp.plugin.PluginVersion;
-import net.shibboleth.shared.collection.Pair;
-import net.shibboleth.shared.logic.Constraint;
-import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.primitive.StringSupport;
/**
- * Class which encapsulates the information about a given plugin as downloaded
- * fro the plugin URL (or file).
+ * Information about a Plugin
*/
-public class PluginInfo {
-
- /** regexp for spaces. */
- private static final Pattern SPACE_CONTAINING = Pattern.compile("\\s+");
-
- /** Class logger. */
- @Nonnull private final Logger log = LoggerFactory.getLogger(PluginInfo.class);
-
- /** The support information. */
- @Nonnull private final Map<PluginVersion, VersionInfo> versionInfo = new HashMap<>();
-
- /** The Download information. */
- @Nonnull private final Map<PluginVersion, Pair<URL,String>> downloadInfo = new HashMap<>();
-
- /** The pluginId. */
- @Nonnull private final String pluginId;
-
- /** Whether the information was sufficient. */
- private boolean allInfoPresent = true;
+public class PluginInfo extends InstallableComponentInfo {
/**
* Constructor.
*
- * @param id the id we care about
- * @param props all the properties.
- */
- public PluginInfo(final String id, @Nonnull final Properties props) {
- pluginId = Constraint.isNotNull(StringSupport.trimOrNull(id), "pluginID must be non-null");
- parse(props);
- }
-
- /** Did the property file have enough information?
- * @return true if something was missing.
- */
- public boolean isInfoComplete() {
- return allInfoPresent;
- }
-
- /** Get the base URL for this version.
- * @param version which version
- * @return the base URL
- */
- @Nullable public URL getUpdateURL(final PluginVersion version) {
- final Pair<URL, String> p = downloadInfo.get(version);
- if (p == null) {
- return null;
- }
- return p.getFirst();
- }
-
- /** Get the base Name for this version.
- * @param version which version
- * @return the base name
- */
- @Nullable public String getUpdateBaseName(final PluginVersion version) {
- final Pair<URL, String> p = downloadInfo.get(version);
- if (p == null) {
- return null;
- }
- return p.getSecond();
- }
-
- /** Get the raw version imfo for this plugin.
- * @return the info.
+ * @param id the plugin Id to ask about.
+ * @param props the properties file to load from
*/
- public Map<PluginVersion, VersionInfo> getAvailableVersions() {
- return versionInfo;
+ public PluginInfo(@Nonnull String id, @Nonnull Properties props) {
+ super(id, props);
}
- /** (try to) populate the information about this plugin.
- * @param props what to load.
- */
- private void parse(@Nonnull final Properties props) {
- final String name = pluginId + PluginSupport.AVAILABLE_VERSIONS_PROPERTY_SUFFIX;
- final String availableVersions = StringSupport.trim(props.getProperty(name));
- if (availableVersions == null) {
- log.warn("Plugin {}: Could not find {} property.", pluginId, name);
- allInfoPresent = false;
- } else {
- handleAvailableVersions(props, availableVersions);
- }
- }
-
- /** Given a version find out more.
- * @param props the property files for this plugin we are looking at
- * @param version the version in question.
- */
- // Checkstyle: CyclomaticComplexity OFF
- private void handleAvailableVersion(final Properties props, final String version) {
- final PluginVersion theVersion = new PluginVersion(version);
- if (theVersion.getMajor() == 0 && theVersion.getMinor() == 0 && theVersion.getPatch() == 0) {
- log.warn("Plugin {}: Improbable version {}", pluginId, version);
- }
- if (versionInfo.containsKey(theVersion)) {
- log.warn("Plugin {}: Duplicate version {}", pluginId, version);
- }
-
+ /** {@inheritDoc} */
+ @Override
+ protected @Nullable InstallableComponentVersion getMaxVersion(@Nonnull Properties props, @Nonnull String version) {
final String maxVersionInfo = StringSupport.trimOrNull(
- props.getProperty(pluginId + PluginSupport.MAX_IDP_VERSION_INTERFIX + version));
+ props.getProperty(getComponentId() + PluginSupport.MAX_IDP_VERSION_INTERFIX + version));
if (maxVersionInfo == null) {
- log.warn("Plugin {}, Version {}: Could not find max idp version.", pluginId, version);
- allInfoPresent = false;
- return;
+ return null;
}
+ return new InstallableComponentVersion(maxVersionInfo);
+ }
+ /** {@inheritDoc} */
+ @Override
+ @Nullable
+ protected InstallableComponentVersion getMinVersion(@Nonnull Properties props, @Nonnull String version) {
final String minVersionInfo = StringSupport.trimOrNull(
- props.getProperty(pluginId + PluginSupport.MIN_IDP_VERSION_INTERFIX + version));
+ props.getProperty(getComponentId() + PluginSupport.MIN_IDP_VERSION_INTERFIX + version));
if (minVersionInfo == null) {
- log.warn("Plugin {}, Version {}: Could not find min idp version.", pluginId, version);
- allInfoPresent = false;
- return;
- }
-
- final String supportLevelString = StringSupport.trimOrNull(
- props.getProperty(pluginId + PluginSupport.SUPPORT_LEVEL_INTERFIX + version));
- PluginSupport.SupportLevel supportLevel;
- if (supportLevelString == null) {
- log.debug("Plugin {}, Version {}: Could not find support level for {}.", pluginId, version);
- supportLevel = SupportLevel.Unknown;
- } else {
- try {
- supportLevel = Enum.valueOf(SupportLevel.class, supportLevelString);
- } catch (final IllegalArgumentException e) {
- log.warn("Plugin {}, Version {}: Invalid support level {}.", pluginId, version, supportLevelString);
- supportLevel = SupportLevel.Unknown;
- }
- }
-
- log.debug("Plugin {}: MaxIdP {}, MinIdP {}, Support Level {}",
- pluginId, maxVersionInfo, minVersionInfo, supportLevel);
- final VersionInfo info;
- info = new VersionInfo(new PluginVersion(maxVersionInfo), new PluginVersion(minVersionInfo), supportLevel);
- versionInfo.put(theVersion, info);
- String downloadURL = StringSupport.trimOrNull(
- getDefaultedValue(props, PluginSupport.DOWNLOAD_URL_INTERFIX, version));
- final String baseName = StringSupport.trimOrNull(
- getDefaultedValue(props, PluginSupport.BASE_NAME_INTERFIX, version));
- if (baseName != null && downloadURL != null) {
- try {
- if (!downloadURL.endsWith("/")) {
- downloadURL += "/";
- }
- final URL url = new URL(downloadURL);
- downloadInfo.put(theVersion, new Pair<>(url, baseName));
- log.trace("Plugin {}, version {}: Added download URL {} baseName {} for {}",
- pluginId, theVersion, url, baseName);
- } catch (final MalformedURLException e) {
- log.warn("Plugin {}, version {}: Download URL '{}' could not be constructed",
- pluginId, theVersion, downloadURL, e);
- }
- } else {
- log.info("Plugin {}, version {}: no download information present", pluginId, theVersion);
- }
- }
- // Checkstyle: CyclomaticComplexity ON
-
- /** Given a list of versions find out more.
- * @param props the property files for this plugin we are looking at
- * @param availableVersions a space delimited array of versions
- */
- private void handleAvailableVersions(final Properties props, final String availableVersions) {
- final String[] versions = SPACE_CONTAINING.split(availableVersions, 0);
-
- log.debug("Plugin {}: Available versions : {} ", pluginId, availableVersions);
- for (final String version:versions) {
- log.debug("Plugin {}: Considering {}", pluginId, version);
- handleAvailableVersion(props, version);
- }
- }
-
- /** Look up the key derived from the pluginId, the interfix and the version, but if that
- * fails look for a templated definition.
- * @param props what to look in
- * @param interfix the interface (between the ID and the version)
- * @param version the version.
- * @return the suitable value
- */
- @Nullable private String getDefaultedValue(final Properties props, final String interfix, final String version) {
- String result = props.getProperty(pluginId + interfix + version);
- if (result != null) {
- return result;
- }
- result = props.getProperty(pluginId + interfix + PluginSupport.VERSION_PATTERN);
- if (result == null) {
- return result;
- }
- return result.replaceAll(PluginSupport.VERSION_PATTERN_REGEX, version);
- }
-
- /** Is the specified plugin supported with this IdP version.
- * @param pluginVersion the version if the plugin as a {@link PluginVersion}
- * @param idPVersion the version if the IDP as a {@link PluginVersion}
- * @return whether it is supported.
- */
- public boolean isSupportedWithIdPVersion(final PluginVersion pluginVersion, final PluginVersion idPVersion) {
- final VersionInfo info = versionInfo.get(pluginVersion);
- if (info == null) {
- log.error("Plugin {}: Unknown version {} supplied.", pluginId, pluginVersion);
- log.debug("Plugin {}: Available {}", pluginId, versionInfo.keySet());
- return false;
+ return null;
}
- return PluginInfo.isSupportedWithIdPVersion(info, idPVersion);
+ return new InstallableComponentVersion(minVersionInfo);
}
- /** Is the specified plugin supported with this IdP version.
- * Worker method for all 'isSupportedWith' classes.
- * @param pluginVersionInfo the version info to consider
- * @param idPVersion the version as a {@link PluginVersion}
- * @return whether it is supported.
- */
- public static boolean isSupportedWithIdPVersion(final PluginState.VersionInfo pluginVersionInfo,
- final PluginVersion idPVersion) {
- final int maxCompare = idPVersion.compareTo(pluginVersionInfo.getMaxSupported());
- if (maxCompare >= 0) {
- // Exclusive:
- // IdP (test against) Version is GREATER THAN OR EQUAL to our Max
- return false;
- }
- final int minCompare = idPVersion.compareTo(pluginVersionInfo.getMinSupported());
- if (minCompare >= 0) {
- // Inclusive:
- // IdP (test against) version is GREATER THAN OR EQUAL to our Min
- return true;
- }
- return false;
- }
}
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 520785f09..3865dd9ac 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
@@ -75,7 +75,7 @@ import net.shibboleth.idp.module.IdPModule.ResourceResult;
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.plugin.InstallableComponentVersion;
import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.collection.CollectionSupport;
@@ -296,8 +296,8 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
} catch (final ComponentInitializationException e) {
throw new BuildException(e);
}
- final PluginVersion pluginVersion = new PluginVersion(getDescription());
- final PluginVersion idpVersion = getIdPVersion();
+ final InstallableComponentVersion pluginVersion = new InstallableComponentVersion(getDescription());
+ final InstallableComponentVersion idpVersion = getIdPVersion();
if (!state.getPluginInfo().isSupportedWithIdPVersion(pluginVersion, idpVersion)) {
LOG.error("Plugin {} version {} is not supported with IdP Version {}",
pluginId, pluginVersion, idpVersion);
@@ -513,10 +513,11 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
*/
private void installNew(final RollbackPluginInstall rollBack) throws BuildException {
final Path from = distribution.resolve("webapp");
- if (PluginInstallerSupport.detectDuplicates(from, getPluginsWebapp())) {
+ assert from != null;
+ if (InstallerSupport.detectDuplicates(from, getPluginsWebapp())) {
throw new BuildException("Install would overwrite files");
}
- PluginInstallerSupport.copyWithLogging(from, getPluginsWebapp(), rollBack.getFilesCopied());
+ InstallerSupport.copyWithLogging(from, getPluginsWebapp(), rollBack.getFilesCopied());
String moduleId = null;
try {
@@ -546,7 +547,7 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
final Path rollbackDir = workspacePath.resolve("rollback");
assert rollbackDir != null;
LOG.debug("Uninstalling version {} of {}", oldVersion, pluginId);
- PluginInstallerSupport.renameToTree(getPluginsWebapp(),
+ InstallerSupport.renameToTree(getPluginsWebapp(),
rollbackDir,
getInstalledContents(),
rollback.getFilesRenamedAway());
@@ -565,7 +566,7 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
try {
Files.createDirectories(pluginsContents);
final Properties props = new Properties(1+copiedFiles.size());
- props.setProperty(PLUGIN_VERSION_PROPERTY, new PluginVersion(getDescription()).toString());
+ props.setProperty(PLUGIN_VERSION_PROPERTY, new InstallableComponentVersion(getDescription()).toString());
props.setProperty(PLUGIN_RELATIVE_PATHS_PROPERTY, "true");
int count = 1;
for (final Path p: copiedFiles) {
@@ -679,8 +680,8 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
handler.setHttpClientSecurityParameters(securityParams);
handler.initialize();
baseResource.setHttpClientContextHandler(handler);
- PluginInstallerSupport.download(baseResource, handler, dir, fileName);
- PluginInstallerSupport.download(baseResource, handler, dir, fileName + ".asc");
+ InstallerSupport.download(baseResource, handler, dir, fileName);
+ InstallerSupport.download(baseResource, handler, dir, fileName + ".asc");
} catch (final IOException | ComponentInitializationException e) {
LOG.error("Error in download", e);
throw new BuildException(e);
@@ -787,7 +788,7 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
}
final Path next = contents.next();
assert next != null;
- distribution = PluginInstallerSupport.canonicalPath(next);
+ distribution = InstallerSupport.canonicalPath(next);
if (contents.hasNext()) {
LOG.error("Too many packages in distributions {}", fullName);
throw new BuildException("Too many packages in distributions");
@@ -913,7 +914,7 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
throw new ComponentInitializationException("idp.home property must be set");
}
try {
- idpHome = myIdpHome = PluginInstallerSupport.canonicalPath(myIdpHome);
+ idpHome = myIdpHome = InstallerSupport.canonicalPath(myIdpHome);
} catch (final IOException e) {
LOG.error("Could not canonicalize idp home", e);
throw new ComponentInitializationException(e);
@@ -1050,24 +1051,24 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
public void close() {
closeSilently(installedPluginsLoader);
closeSilently(installingPluginLoader);
- PluginInstallerSupport.deleteTree(downloadDirectory);
- PluginInstallerSupport.deleteTree(unpackDirectory);
- PluginInstallerSupport.deleteTree(workspacePath);
+ InstallerSupport.deleteTree(downloadDirectory);
+ InstallerSupport.deleteTree(unpackDirectory);
+ InstallerSupport.deleteTree(workspacePath);
InstallerSupport.setReadOnly(distPath, true);
}
/** Return a version we can use in a test proof manner.
* @return the IdP version or a fixed value
*/
- @Nonnull protected static PluginVersion getIdPVersion() {
+ @Nonnull protected static InstallableComponentVersion getIdPVersion() {
final String version = Version.getVersion();
if (version == null) {
LOG.error("Could not determine IdP Version. Assuming 4.2.0");
LOG.error("You should never see this outside a test environment");
- return new PluginVersion(4,2,0);
+ return new InstallableComponentVersion(4,2,0);
}
- return new PluginVersion(version);
+ return new InstallableComponentVersion(version);
}
}
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 665d7e1d4..3fb49d5c8 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
@@ -31,7 +31,7 @@ import org.slf4j.Logger;
import com.beust.jcommander.Parameter;
import net.shibboleth.idp.cli.AbstractIdPHomeAwareCommandLineArguments;
-import net.shibboleth.idp.plugin.PluginVersion;
+import net.shibboleth.idp.plugin.InstallableComponentVersion;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.primitive.StringSupport;
@@ -108,8 +108,8 @@ public class PluginInstallerArguments extends AbstractIdPHomeAwareCommandLineArg
@Parameter(names= {"--noRebuild", "--no-rebuild"})
private boolean noRebuild;
- /** The {@link #forceUpdateVersion} as a {@link PluginVersion}. */
- @Nullable private PluginVersion updateVersion;
+ /** The {@link #forceUpdateVersion} as a {@link InstallableComponentVersion}. */
+ @Nullable private InstallableComponentVersion updateVersion;
/** Decomposed input - name. */
@Nullable private String inputName;
@@ -260,7 +260,7 @@ public class PluginInstallerArguments extends AbstractIdPHomeAwareCommandLineArg
/** Return the version to update to or null.
* @return the version or null
*/
- @Nullable public PluginVersion getUpdateVersion() {
+ @Nullable public InstallableComponentVersion getUpdateVersion() {
return updateVersion;
}
@@ -318,7 +318,7 @@ public class PluginInstallerArguments extends AbstractIdPHomeAwareCommandLineArg
pluginId = updatePluginId;
operation = OperationType.UPDATE;
if (forceUpdateVersion != null) {
- updateVersion = new PluginVersion(forceUpdateVersion);
+ updateVersion = new InstallableComponentVersion(forceUpdateVersion);
}
} else if (uninstallId != null) {
pluginId = uninstallId;
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 9f5f7eddf..951c71560 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
@@ -46,9 +46,11 @@ import org.springframework.core.io.Resource;
import net.shibboleth.idp.Version;
import net.shibboleth.idp.cli.AbstractIdPHomeAwareCommandLine;
-import net.shibboleth.idp.installer.plugin.impl.PluginState.VersionInfo;
+import net.shibboleth.idp.installer.InstallerSupport;
import net.shibboleth.idp.plugin.IdPPlugin;
-import net.shibboleth.idp.plugin.PluginVersion;
+import net.shibboleth.idp.plugin.InstallableComponentInfo;
+import net.shibboleth.idp.plugin.InstallableComponentVersion;
+import net.shibboleth.idp.plugin.PluginSupport;
import net.shibboleth.shared.annotation.constraint.NonnullElements;
import net.shibboleth.shared.cli.AbstractCommandLine;
import net.shibboleth.shared.collection.CollectionSupport;
@@ -216,7 +218,7 @@ public final class PluginInstallerCLI extends AbstractIdPHomeAwareCommandLine<Pl
assert idpHome != null;
inst.setIdpHome(idpHome);
if (!args.isUnattended()) {
- inst.setAcceptKey(new PluginInstallerSupport.InstallerQuery("Accept this key"));
+ inst.setAcceptKey(new InstallerSupport.InstallerQuery("Accept this key"));
}
inst.setTrustore(args.getTruststore());
final HttpClient client = getHttpClient();
@@ -261,19 +263,20 @@ public final class PluginInstallerCLI extends AbstractIdPHomeAwareCommandLine<Pl
log.error("Could not interrogate plugin {}", plugin.getPluginId(), e);
return;
}
- final Map<PluginVersion, VersionInfo> versionMap = state.getPluginInfo().getAvailableVersions();
- final List<PluginVersion> versionList = new ArrayList<>(versionMap.keySet());
+ final Map<InstallableComponentVersion, InstallableComponentInfo.VersionInfo> versionMap = state.getPluginInfo().getAvailableVersions();
+ final List<InstallableComponentVersion> versionList = new ArrayList<>(versionMap.keySet());
versionList.sort(null);
outOrLog("\tVersions ");
- for (final PluginVersion version:versionList) {
+ for (final InstallableComponentVersion version:versionList) {
final String downLoadDetails;
+ assert version != null;
if (state.getPluginInfo().getUpdateBaseName(version) == null ||
state.getPluginInfo().getUpdateURL(version)==null ) {
downLoadDetails = " - No download available";
} else {
downLoadDetails = "";
}
- final VersionInfo info = versionMap.get(version);
+ final InstallableComponentInfo.VersionInfo info = versionMap.get(version);
outOrLog(String.format("\t%s:\tMin=%s\tMax=%s\tSupport level: %s%s",
version,
info.getMinSupported(),
@@ -367,7 +370,7 @@ public final class PluginInstallerCLI extends AbstractIdPHomeAwareCommandLine<Pl
log.error("Plugin {} found, but no contents listed", pluginId);
return;
}
- final String installedVersion = new PluginVersion(thePlugin).toString();
+ final String installedVersion = new InstallableComponentVersion(thePlugin).toString();
if (!fromContentsVersion.equals(installedVersion)) {
log.error("Installed version of Plugin {} ({}) does not match contents ({})",
pluginId, installedVersion, fromContentsVersion);
@@ -386,41 +389,44 @@ public final class PluginInstallerCLI extends AbstractIdPHomeAwareCommandLine<Pl
* @return whether it worked
*/
private int doListAvailable() {
- final Properties props = PluginInstallerSupport.loadPluginInfo(updateURLs, this);
+ final HttpClient client = getHttpClient();
+ assert client != null;
+ final Properties props = PluginSupport.loadPluginInfo(updateURLs, client, getHttpClientSecurityParameters());
if (props == null) {
return RC_IO;
}
- final Map<String, PluginInfo> plugins = new HashMap<>();
+ final Map<String, InstallableComponentInfo> plugins = new HashMap<>();
final Enumeration<Object> en = props.keys();
while (en.hasMoreElements()) {
final String key = (String)en.nextElement();
if (key.endsWith(".versions")) {
final String pluginId = key.substring(0, key.length()-9);
- final PluginInfo info = new PluginInfo(pluginId, props);
+ assert pluginId != null;
+ final InstallableComponentInfo info = new PluginInfo(pluginId, props);
if (info.isInfoComplete()) {
plugins.put(pluginId, info);
}
}
}
- for (final Entry<String, PluginInfo> entry: plugins.entrySet()) {
- final PluginVersion nullVersion = new PluginVersion(0, 0, 0);
+ for (final Entry<String, InstallableComponentInfo> entry: plugins.entrySet()) {
+ final InstallableComponentVersion nullVersion = new InstallableComponentVersion(0, 0, 0);
final String key = entry.getKey();
- final PluginInfo value = entry.getValue();
+ final InstallableComponentInfo value = entry.getValue();
assert key!=null && value !=null;
assert installer != null;
final IdPPlugin existingPlugin = installer.getInstalledPlugin(key);
if (existingPlugin == null) {
- final PluginVersion version = PluginInstallerSupport.getBestVersion(nullVersion, value);
+ final InstallableComponentVersion version = PluginSupport.getBestVersion(nullVersion, value);
if (version == null) {
log.debug("Plugin {} has no version available", entry.getKey());
} else {
outOrLog(String.format("Plugin %s: version %s available for install", entry.getKey(), version));
}
} else {
- final PluginVersion existingVersion = new PluginVersion(existingPlugin);
- final PluginVersion version = PluginInstallerSupport.getBestVersion(existingVersion, value);
+ final InstallableComponentVersion existingVersion = new InstallableComponentVersion(existingPlugin);
+ final InstallableComponentVersion version = PluginSupport.getBestVersion(existingVersion, value);
if (version == null) {
outOrLog(String.format("Plugin %s: Installed version %s: No update available",
entry.getKey(),
@@ -451,17 +457,19 @@ public final class PluginInstallerCLI extends AbstractIdPHomeAwareCommandLine<Pl
log.error("Plugin {} is already installed", pluginId);
return RC_INIT;
}
- final Properties props = PluginInstallerSupport.loadPluginInfo(updateURLs, this);
+ final HttpClient client = getHttpClient();
+ assert client != null;
+ final Properties props = PluginSupport.loadPluginInfo(updateURLs, client, getHttpClientSecurityParameters());
if (props == null) {
log.error("AutoInstall not possible");
return RC_INIT;
}
- final PluginInfo info = new PluginInfo(pluginId, props);
+ final InstallableComponentInfo info = new PluginInfo(pluginId, props);
if (!info.isInfoComplete()) {
log.error("Plugin {}: Information not found", pluginId);
return RC_INIT;
}
- final PluginVersion versionToInstall = PluginInstallerSupport.getBestVersion(new PluginVersion(0,0,0), info);
+ final InstallableComponentVersion versionToInstall = PluginSupport.getBestVersion(new InstallableComponentVersion(0,0,0), info);
if (versionToInstall == null) {
log.error("Plugin {}: No version available to install", pluginId);
return RC_INIT;
@@ -480,7 +488,7 @@ public final class PluginInstallerCLI extends AbstractIdPHomeAwareCommandLine<Pl
* @param checkVersion are we checking the version.
*/
private void doUpdate(@Nonnull final String pluginId,
- @Nullable final PluginVersion pluginVersion,
+ @Nullable final InstallableComponentVersion pluginVersion,
final boolean checkVersion) {
final PluginInstaller inst = installer;
@@ -503,16 +511,16 @@ public final class PluginInstallerCLI extends AbstractIdPHomeAwareCommandLine<Pl
log.error("Could not interrogate plugin {}", plugin.getPluginId(), e);
return;
}
- final PluginVersion installVersion;
+ final InstallableComponentVersion installVersion;
if (pluginVersion == null) {
- installVersion = PluginInstallerSupport.getBestVersion(new PluginVersion(plugin), state.getPluginInfo());
+ installVersion = PluginSupport.getBestVersion(new InstallableComponentVersion(plugin), state.getPluginInfo());
if (installVersion == null) {
log.info("No suitable update version available");
return;
}
} else {
installVersion = pluginVersion;
- final Map<PluginVersion, VersionInfo> versions = state.getPluginInfo().getAvailableVersions();
+ final Map<InstallableComponentVersion, InstallableComponentInfo.VersionInfo> versions = state.getPluginInfo().getAvailableVersions();
if (!versions.containsKey(installVersion)) {
log.error("Specified version {} could not be found. Available versions: {}",
installVersion, versions.keySet());
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginInstallerSupport.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginInstallerSupport.java
deleted file mode 100644
index f3fc533f7..000000000
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/plugin/impl/PluginInstallerSupport.java
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Licensed to the University Corporation for Advanced Internet Development,
- * Inc. (UCAID) under one or more contributor license agreements. See the
- * NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The UCAID licenses this file to You under the Apache
- * License, Version 2.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.installer.plugin.impl;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.net.URL;
-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.List;
-import java.util.Properties;
-import java.util.function.Predicate;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.apache.hc.client5.http.classic.HttpClient;
-import org.apache.tools.ant.BuildException;
-import org.opensaml.security.httpclient.HttpClientSecurityContextHandler;
-import org.slf4j.Logger;
-import org.springframework.core.io.FileSystemResource;
-import org.springframework.core.io.Resource;
-
-import net.shibboleth.idp.cli.AbstractIdPHomeAwareCommandLine;
-import net.shibboleth.idp.installer.InstallerSupport;
-import net.shibboleth.idp.installer.ProgressReportingOutputStream;
-import net.shibboleth.idp.installer.plugin.impl.PluginState.VersionInfo;
-import net.shibboleth.idp.plugin.PluginSupport.SupportLevel;
-import net.shibboleth.idp.plugin.PluginVersion;
-import net.shibboleth.shared.annotation.constraint.Live;
-import net.shibboleth.shared.collection.Pair;
-import net.shibboleth.shared.component.ComponentInitializationException;
-import net.shibboleth.shared.logic.Constraint;
-import net.shibboleth.shared.primitive.LoggerFactory;
-import net.shibboleth.shared.primitive.StringSupport;
-import net.shibboleth.shared.spring.httpclient.resource.HTTPResource;
-
-/**
- * Support for copying files during plugin manipulation.
- */
-public final class PluginInstallerSupport {
-
- /** Class logger. */
- @Nonnull
- private static final Logger LOG = LoggerFactory.getLogger(PluginInstallerSupport.class);
-
- /** Constructor. */
- private PluginInstallerSupport() {
- }
-
- /** Return the canonical path.
- * @param from the path we get given
- * @return the canonicalized one
- * @throws IOException as from {@link File#getCanonicalFile()}
- */
- @SuppressWarnings("null")
- @Nonnull static Path canonicalPath(@Nonnull final Path from) throws IOException {
- return from.toFile().getCanonicalFile().toPath();
- }
-
- /** Delete a directory tree.
- * @param directory what to delete
- */
- public static void deleteTree(@Nullable final Path directory) {
- if (directory == null || !Files.exists(directory)) {
- return;
- }
- LOG.debug("Deleting directory {}", directory);
- InstallerSupport.setReadOnly(directory, false);
- try {
- Files.walkFileTree(directory, new DeletingVisitor());
- } catch (final IOException e) {
- LOG.error("Couldn't delete {}", directory, e);
- }
- }
-
- /** Traverse "from" looking to see if any of the files are already in "to".
- * @param from source directory
- * @param to target directory
- * @return true if there was a match
- * @throws BuildException if anything threw and {@link IOException}
- */
- public static boolean detectDuplicates(final Path from, final Path to) throws BuildException {
-
- if (to == null || !Files.exists(to)) {
- return false;
- }
- final NameClashVisitor detector = new NameClashVisitor(from, to);
- LOG.debug("Walking {}, looking for a name clash in {}", from, to);
- try {
- Files.walkFileTree(from, detector);
- } catch (final IOException e) {
- LOG.error("Failed during duplicate detection:", e);
- throw new BuildException(e);
- }
- return detector.wasNameClash();
- }
-
- /** Copy a directory tree and keep a log of what has changed.
- * @param from source directory
- * @param to target directory
- * @param pathsCopied the list of files copied up (including if there was a failure)
- * @throws BuildException from the copy
- */
- public static void copyWithLogging(final Path from,
- final Path to, @Live final List<Path> pathsCopied) throws BuildException {
- if (from == null || !Files.exists(from)) {
- return;
- }
- LOG.debug("Copying from {} to {}", from, to);
- final LoggingVisitor visitor = new LoggingVisitor(from, to);
- try {
- Files.walkFileTree(from, visitor);
- } catch (final IOException e) {
- pathsCopied.addAll(visitor.getCopiedList());
- LOG.error("Error copying files from {} to {}", from, to, e);
- throw new BuildException(e);
- }
- pathsCopied.addAll(visitor.getCopiedList());
- }
-
- /** Rename Files into the provided tree.
- * @param fromBase The root directory of the from files
- * @param toBase The root directory to rename to
- * @param fromFiles The list of files (inside fromBase) to rename
- * @param renames All the work as it is done
- * @throws IOException If any of the file operations fail
- */
- public static void renameToTree(@Nonnull final Path fromBase,
- @Nonnull final Path toBase,
- @Nonnull final List<Path> fromFiles,
- @Nonnull @Live final List<Pair<Path, Path>> renames) throws IOException {
- if (!Files.exists(toBase)) {
- Files.createDirectories(toBase);
- }
- for (final Path path : fromFiles) {
- if (!Files.exists(path)) {
- LOG.info("File {} was not renamed away because it does not exist", path);
- continue;
- }
- final Path relName = fromBase.relativize(path);
- LOG.trace("Relative name {}", relName);
- final Path to = toBase.resolve(relName);
- Files.createDirectories(to.getParent());
- Files.move(path,to);
- renames.add(new Pair<>(path, to));
- }
- }
-
- /**
- * A @{link {@link FileVisitor} which detects (and logs) whether a copy would overwrite.
- */
- private static final class NameClashVisitor extends SimpleFileVisitor<Path> {
- /** did we find a duplicate. */
- private boolean nameClash;
-
- /** Path we are traversing. */
- private final Path from;
-
- /** Path where we check for Duplicates. */
- private final Path to;
- /**
- * Constructor.
- *
- * @param fromDir Path we are traversing
- * @param toDir Path where we check for Duplicates
- */
- public NameClashVisitor(final Path fromDir, final Path toDir) {
- from = fromDir;
- to = toDir;
- }
-
- @Override
- public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
- final Path relFile = from.relativize(file);
- final Path toFile = to.resolve(relFile);
- if (Files.exists(toFile)) {
- nameClash = true;
- LOG.warn("{} already exists", toFile);
- }
- return FileVisitResult.CONTINUE;
- }
-
- /** did we find a name clash?
- * @return whether we found a name clash.
- */
- public boolean wasNameClash() {
- return nameClash;
- }
- }
-
- /**
- * A @{link {@link FileVisitor} which deletes files.
- */
- private static final class DeletingVisitor extends SimpleFileVisitor<Path> {
- @Override
- public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
- try {
- Files.delete(file);
- } catch (final IOException e) {
- LOG.error("Could not delete {}", file.toAbsolutePath(), e);
- file.toFile().deleteOnExit();
- // and carry on
- }
- return FileVisitResult.CONTINUE;
- }
- @Override
- public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) throws IOException {
- if (exc != null) {
- throw exc;
- }
- try {
- Files.delete(dir);
- } catch (final IOException e) {
- LOG.error("Could not delete {}", dir.toAbsolutePath(), e);
- dir.toFile().deleteOnExit();
- // and carry on
- }
- return FileVisitResult.CONTINUE;
- }
- }
-
- /** Find the best update version (plugin or IdP).
- * @param pluginVersion The Plugin version
- * @param pluginInfo all about the plugin
- * @return the best version (or null)
- */
- @Nullable static public PluginVersion getBestVersion(@Nonnull final PluginVersion pluginVersion, @Nonnull final PluginInfo pluginInfo) {
- return getBestVersion(PluginInstaller.getIdPVersion(), pluginVersion, pluginInfo);
- }
-
- /** Find the best update version (plugin or IdP).
- * @param idPVersion The IdP version to check.
- * @param pluginVersion The Plugin version
- * @param pluginInfo all about the plugin
- * @return the best version (or null)
- */
- @Nullable static public PluginVersion getBestVersion(@Nonnull final PluginVersion idPVersion,
- @Nonnull final PluginVersion pluginVersion, @Nonnull final PluginInfo pluginInfo) {
-
- final List<PluginVersion> availableVersions = new ArrayList<>(pluginInfo.getAvailableVersions().keySet());
- availableVersions.sort(null);
- LOG.debug("Considering versions: {}", availableVersions);
-
- for (int i = availableVersions.size()-1; i >= 0; i--) {
- final PluginVersion version = availableVersions.get(i);
- if (version.compareTo(pluginVersion) <= 0) {
- LOG.debug("Version {} is less than or the same as {}. All done", version, pluginVersion);
- return null;
- }
- final VersionInfo versionInfo = pluginInfo.getAvailableVersions().get(version);
- if (versionInfo.getSupportLevel() != SupportLevel.Current) {
- LOG.debug("Version {} has support level {}, ignoring", version, versionInfo.getSupportLevel());
- continue;
- }
- if (!pluginInfo.isSupportedWithIdPVersion(version, idPVersion)) {
- LOG.debug("Version {} is not supported with idpVersion {}", version, idPVersion);
- continue;
- }
- LOG.debug("Version {} is supported with idpVersion {}", version, idPVersion);
- if (pluginInfo.getUpdateURL(version) == null || pluginInfo.getUpdateBaseName(version) == null) {
- LOG.debug("Version {} is does not have update information", version);
- continue;
- }
- return version;
- }
- return null;
- }
-
- /** Load the property file describing all the plugin we know about from a known location.
- * @param updateURLs where to look
- * @param commandLine the programming calling us.
- * @return the property files plugins.
- */
- @Nullable public static Properties loadPluginInfo(@Nonnull final List<URL> updateURLs,
- @Nonnull final AbstractIdPHomeAwareCommandLine<?> commandLine) {
- final List<URL> urls;
- final Properties props = new Properties();
- try {
- if (updateURLs.isEmpty()) {
- urls = List.of(
- new URL("https://shibboleth.net/downloads/identity-provider/plugins/plugins.properties"),
- new URL("http://plugins.shibboleth.net/plugins.properties"));
- } else {
- urls = updateURLs;
- }
- } catch (final IOException e) {
- LOG.error("Could not load update URLs", e);
- return null;
- }
- for (final URL url: urls) {
- final Resource propertyResource;
- try {
- if ("file".equals(url.getProtocol())) {
- final String path =url.getPath();
- assert path != null;
- propertyResource = new FileSystemResource(path);
- } else if ("http".equals(url.getProtocol()) || "https".equals(url.getProtocol())) {
- final HttpClient client = commandLine.getHttpClient();
- assert client != null;
- final HTTPResource httpResource;
- propertyResource = httpResource = new HTTPResource(client , url);
- final HttpClientSecurityContextHandler handler = new HttpClientSecurityContextHandler();
- handler.setHttpClientSecurityParameters(commandLine.getHttpClientSecurityParameters());
- handler.initialize();
- httpResource.setHttpClientContextHandler(handler);
- } else {
- LOG.error("Only file and http[s] URLs are allowed");
- continue;
- }
- LOG.debug("Plugin Listing: Looking for update at {}", propertyResource.getDescription());
- if (!propertyResource.exists()) {
- LOG.info("{} could not be located", propertyResource.getDescription());
- continue;
- }
- props.load(propertyResource.getInputStream());
- return props;
- } catch (final IOException | ComponentInitializationException e) {
- LOG.error("Could not open Update URL {} :", url, e);
- continue;
- }
- }
- LOG.error("Could not locate any active update servers");
- return null;
- }
-
- /** Download helper method.
- * @param baseResource where to go for the file
- * @param handler HttpClientSecurityContextHandler to use
- * @param downloadDirectory where to download to
- * @param fileName the file name
- * @throws IOException as required
- */
- public static void download(@Nonnull final HTTPResource baseResource,
- @Nonnull final HttpClientSecurityContextHandler handler,
- @Nonnull final Path downloadDirectory,
- @Nonnull final String fileName) throws IOException {
- final HTTPResource httpResource = baseResource.createRelative(fileName, handler);
- final Path filePath = downloadDirectory.resolve(fileName);
- LOG.info("Downloading from {}", httpResource.getDescription());
- LOG.debug("Downloading to {}", filePath);
- try (final OutputStream fileOut = new ProgressReportingOutputStream(new FileOutputStream(filePath.toFile()))) {
- httpResource.getInputStream().transferTo(fileOut);
- }
- }
-
-/** Predicate to ask the user if they want to install the trust store provided. */
- public static class InstallerQuery implements Predicate<String> {
-
- /** What to say. */
- @Nonnull
- private final String promptText;
-
- /**
- * Constructor.
- * @param text What to say before the prompt information
- */
- public InstallerQuery(@Nonnull final String text) {
- promptText = Constraint.isNotNull(text, "Text should not be null");
- }
-
- /** {@inheritDoc} */
- public boolean test(final String keyString) {
- if (System.console() == null) {
- LOG.error("No Console Attached to installer");
- return false;
- }
- System.console().printf("%s:\n%s [yN] ", promptText, keyString);
- System.console().flush();
- final String result = StringSupport.trimOrNull(System.console().readLine());
- return result != null && "y".equalsIgnoreCase(result.substring(0, 1));
- }
- }
-}
-
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 93e960562..a4d94df2a 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
@@ -33,8 +33,8 @@ import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import net.shibboleth.idp.plugin.IdPPlugin;
-import net.shibboleth.idp.plugin.PluginSupport.SupportLevel;
-import net.shibboleth.idp.plugin.PluginVersion;
+import net.shibboleth.idp.plugin.InstallableComponentInfo;
+import net.shibboleth.idp.plugin.InstallableComponentVersion;
import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
import net.shibboleth.shared.component.AbstractInitializableComponent;
import net.shibboleth.shared.component.ComponentInitializationException;
@@ -53,10 +53,10 @@ public class PluginState extends AbstractInitializableComponent {
@Nonnull private final IdPPlugin plugin;
/** My Plugin Info. */
- @NonnullAfterInit private PluginInfo myPluginInfo;
+ @NonnullAfterInit private InstallableComponentInfo myPluginInfo;
/** The version of this plugin. */
- @Nonnull private final PluginVersion myPluginVersion;
+ @Nonnull private final InstallableComponentVersion myPluginVersion;
/** Class logger. */
@Nonnull private final Logger log = LoggerFactory.getLogger(PluginState.class);
@@ -79,13 +79,13 @@ public class PluginState extends AbstractInitializableComponent {
public PluginState(@Nonnull final IdPPlugin description, final List<URL> updateOverrides) {
updateOverrideURLs = Constraint.isNotNull(updateOverrides, "updated Locations must not be null");
plugin = Constraint.isNotNull(description, "Plugin must not be null");
- myPluginVersion = new PluginVersion(plugin);
+ myPluginVersion = new InstallableComponentVersion(plugin);
}
/** get our PluginInfo.
* @return our PluginInfo.
*/
- @Nonnull public PluginInfo getPluginInfo() {
+ @Nonnull public InstallableComponentInfo getPluginInfo() {
checkComponentActive();
assert myPluginInfo!=null;
return myPluginInfo;
@@ -212,51 +212,4 @@ public class PluginState extends AbstractInitializableComponent {
}
}
// CheckStyle: CyclomaticComplexity ON
-
- /** Encapsulation of the information about a given IdP version. */
- public static class VersionInfo {
-
- /** Maximum version - this version is NOT SUPPORTED. */
- private final PluginVersion maxSupported;
-
- /** Minimum version - this version IS supported. */
- private final PluginVersion minSupported;
-
- /** support level. */
- private final SupportLevel supportLevel;
-
- /**
- * Constructor.
- *
- * @param max support level
- * @param min support level
- * @param support support level
- */
- VersionInfo(final PluginVersion max, final PluginVersion min, final SupportLevel support) {
- maxSupported = max;
- minSupported = min;
- supportLevel = support;
- }
-
- /** get Maximum version - this version is NOT SUPPORTED.
- * @return Returns the maxSupported.
- */
- public PluginVersion getMaxSupported() {
- return maxSupported;
- }
-
- /** get Minimum (IdP) version - this version IS supported.
- * @return Returns the minSupported.
- */
- public PluginVersion getMinSupported() {
- return minSupported;
- }
-
- /** get support level.
- * @return Returns the supportLevel.
- */
- public SupportLevel getSupportLevel() {
- return supportLevel;
- }
- }
}
diff --git a/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/BasePluginTest.java b/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/BasePluginTest.java
index 268f20a18..e4ad9959d 100644
--- a/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/BasePluginTest.java
+++ b/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/BasePluginTest.java
@@ -71,7 +71,7 @@ public class BasePluginTest {
return;
}
InstallerSupport.setReadOnly(idpHome, false);
- PluginInstallerSupport.deleteTree(idpHome);
+ InstallerSupport.deleteTree(idpHome);
}
protected Path getIdpHome() {
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 0958ddeb3..a83f3f867 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
@@ -32,6 +32,7 @@ import org.springframework.core.io.Resource;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;
+import net.shibboleth.idp.installer.InstallerSupport;
import net.shibboleth.idp.installer.ProgressReportingOutputStream;
import net.shibboleth.shared.cli.AbstractCommandLine;
import net.shibboleth.shared.httpclient.HttpClientBuilder;
@@ -156,7 +157,7 @@ public class PluginCLITest extends BasePluginTest {
AbstractCommandLine.RC_OK);
} finally {
if (unpack != null) {
- PluginInstallerSupport.deleteTree(unpack);
+ InstallerSupport.deleteTree(unpack);
}
}
}
diff --git a/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/PluginStateTest.java b/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/PluginStateTest.java
index 021f01569..1d46ed9a9 100644
--- a/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/PluginStateTest.java
+++ b/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/PluginStateTest.java
@@ -31,7 +31,7 @@ import javax.annotation.Nonnull;
import org.testng.annotations.Test;
import net.shibboleth.idp.plugin.IdPPlugin;
-import net.shibboleth.idp.plugin.PluginVersion;
+import net.shibboleth.idp.plugin.InstallableComponentVersion;
import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.component.ComponentInitializationException;
@@ -41,8 +41,8 @@ import net.shibboleth.shared.component.ComponentInitializationException;
@SuppressWarnings("javadoc")
public class PluginStateTest {
- private boolean testSupportState(final PluginVersion pluginVersion, final PluginState state, final String IdpVersion) {
- final PluginVersion idPVersion = new PluginVersion(IdpVersion);
+ private boolean testSupportState(@Nonnull final InstallableComponentVersion pluginVersion, final PluginState state, final String IdpVersion) {
+ final InstallableComponentVersion idPVersion = new InstallableComponentVersion(IdpVersion);
return state.getPluginInfo().isSupportedWithIdPVersion(pluginVersion, idPVersion);
}
@@ -55,27 +55,27 @@ public class PluginStateTest {
state.initialize();
- final PluginVersion pluginVersion = new PluginVersion(simple.getMajorVersion(), simple.getMinorVersion(), simple.getPatchVersion());
+ final InstallableComponentVersion pluginVersion = new InstallableComponentVersion(simple.getMajorVersion(), simple.getMinorVersion(), simple.getPatchVersion());
- assertEquals(pluginVersion, new PluginVersion("1.2.3"));
+ assertEquals(pluginVersion, new InstallableComponentVersion("1.2.3"));
assertEquals(state.getPluginInfo().getAvailableVersions().size(), 3);
- assertTrue(state.getPluginInfo().getAvailableVersions().containsKey(new PluginVersion(1, 2, 3)));
- assertTrue(state.getPluginInfo().getAvailableVersions().containsKey(new PluginVersion(1, 2, 4)));
- assertTrue(state.getPluginInfo().getAvailableVersions().containsKey(new PluginVersion(2,0,0)));
- assertFalse(state.getPluginInfo().getAvailableVersions().containsKey(new PluginVersion(3, 2, 3)));
+ assertTrue(state.getPluginInfo().getAvailableVersions().containsKey(new InstallableComponentVersion(1, 2, 3)));
+ assertTrue(state.getPluginInfo().getAvailableVersions().containsKey(new InstallableComponentVersion(1, 2, 4)));
+ assertTrue(state.getPluginInfo().getAvailableVersions().containsKey(new InstallableComponentVersion(2,0,0)));
+ assertFalse(state.getPluginInfo().getAvailableVersions().containsKey(new InstallableComponentVersion(3, 2, 3)));
assertTrue(testSupportState(pluginVersion, state, "4.1.0"));
assertTrue(testSupportState(pluginVersion, state, "4.2.0"));
assertTrue(testSupportState(pluginVersion, state, "4.99.9"));
assertFalse(testSupportState(pluginVersion, state, "5.0.0"));
- final PluginVersion v124 = new PluginVersion(1,2,3);
+ final InstallableComponentVersion v124 = new InstallableComponentVersion(1,2,3);
assertTrue(testSupportState(v124, state,"4.1.0"));
assertTrue(testSupportState(v124, state, "4.99.9"));
assertFalse(testSupportState(v124, state, "5.0.0"));
assertFalse(testSupportState(v124, state, "4.0.0"));
- final PluginVersion v2 = new PluginVersion(2,0,0);
+ final InstallableComponentVersion v2 = new InstallableComponentVersion(2,0,0);
assertTrue(testSupportState(v2, state, "4.99.1"));
assertTrue(testSupportState(v2, state, "4.99.999"));
assertFalse(testSupportState(v2, state, "4.99.0"));
@@ -91,9 +91,9 @@ public class PluginStateTest {
final TestPlugin tp = new TestPlugin();
final PluginState state = new PluginState(tp, tp.getUpdateURLs());
state.initialize();
- final PluginVersion v123 = new PluginVersion(1,2,3);
- final PluginVersion v124 = new PluginVersion(1,2,4);
- final PluginVersion v2 = new PluginVersion(2,0,0);
+ final InstallableComponentVersion v123 = new InstallableComponentVersion(1,2,3);
+ final InstallableComponentVersion v124 = new InstallableComponentVersion(1,2,4);
+ final InstallableComponentVersion v2 = new InstallableComponentVersion(2,0,0);
assertEquals(state.getPluginInfo().getUpdateURL(v123), new URL("https://example.org/plugins/"));
assertEquals(state.getPluginInfo().getUpdateURL(v124), new URL("https://example.org/plugins4/"));
diff --git a/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/RollbackTester.java b/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/RollbackTester.java
index c4461faef..3fcb6c9bf 100644
--- a/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/RollbackTester.java
+++ b/idp-installer/src/test/java/net/shibboleth/idp/installer/plugin/impl/RollbackTester.java
@@ -29,6 +29,7 @@ import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
+import net.shibboleth.idp.installer.InstallerSupport;
import net.shibboleth.idp.module.IdPModule;
import net.shibboleth.idp.module.ModuleContext;
import net.shibboleth.idp.module.ModuleException;
@@ -45,7 +46,7 @@ public class RollbackTester {
}
@AfterClass public void teardown() {
- PluginInstallerSupport.deleteTree(parent);
+ InstallerSupport.deleteTree(parent);
}
@Test public void rollbackTest() throws IOException, ModuleException {
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list