[java-identity-provider] branch main updated: IDP-1682 Modules managemebnt during Plugin installation
Rod Widdowson
rdw at steadingsoftware.com
Sat Oct 17 14:23:06 UTC 2020
This is an automated email from the git hooks/post-receive script.
rdw pushed a commit to branch main
in repository java-identity-provider.
View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=906bc99e1ff803666fbcf7a15f3ef2e70e3cd941
The following commit(s) were added to refs/heads/main by this push:
new 906bc99e1 IDP-1682 Modules managemebnt during Plugin installation
906bc99e1 is described below
commit 906bc99e1ff803666fbcf7a15f3ef2e70e3cd941
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Sat Oct 17 15:14:54 2020 +0100
IDP-1682 Modules managemebnt during Plugin installation
https://issues.shibboleth.net/jira/browse/IDP-1682
During an update (or indeed an install) we call Module.enable
on any modules provided by the "just installed" plugin which
we already enabled when the installation was started.
This allows a plugin upgrade to insert extra
configuration files.
---
.../idp/installer/plugin/impl/PluginInstaller.java | 93 +++++++++++++++-------
1 file changed, 63 insertions(+), 30 deletions(-)
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 0bda648b6..3176d507e 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
@@ -239,11 +239,13 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
LOG.info("Installing Plugin {} version {}.{}.{}", pluginId,
description.getMajorVersion(),description.getMinorVersion(), description.getPatchVersion());
+ final Set<String> loadedModules = getLoadedModules();
try (final RollbackPluginInstall rollBack = new RollbackPluginInstall(moduleContext)) {
uninstallOld(rollBack);
- checkRequiredModules();
+ checkRequiredModules(loadedModules);
installNew(rollBack);
+ reEnableModules(loadedModules);
saveCopiedFiles(rollBack.getFilesCopied());
rollBack.completed();
@@ -314,12 +316,7 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
*/
private void setupDescriptionFromDistribution() throws BuildException {
final ServiceLoader<IdPPlugin> plugins;
- try {
plugins = ServiceLoader.load(IdPPlugin.class, getDistributionLoader());
- } catch (final IOException e) {
- LOG.error("Error loading descritpion");
- throw new BuildException(e);
- }
final Optional<IdPPlugin> first = plugins.findFirst();
if (first.isEmpty()) {
LOG.error("No Plugin services found in plugin distribution");
@@ -355,30 +352,60 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
return installedVersionFromContents;
}
- /**
- * Police that required modules for plugin installation are enabled.
- *
- * @throws BuildException if any required modules are missing or disabled or loading the module fails
+ /** What modules (on the installed plugins Classpath) are currently loaded?
+ * @return a set of the names of the currently enabled Modules.
+ * @throws BuildException on loading a module
*/
- private void checkRequiredModules() throws BuildException {
- final Set<String> requiredModules = new HashSet<>(description.getRequiredModules());
+ private Set<String> getLoadedModules() throws BuildException {
+ final Set<String> enablededModules = new HashSet<>();
final Iterator<IdPModule> modules = ServiceLoader.load(IdPModule.class, getInstalledPluginsLoader()).iterator();
- while (modules.hasNext() && !requiredModules.isEmpty()) {
+ while (modules.hasNext()) {
try {
final IdPModule module = modules.next();
- if (requiredModules.contains(module.getId())) {
- if (module.isEnabled(moduleContext)) {
- requiredModules.remove(module.getId());
- }
+ if (module.isEnabled(moduleContext)) {
+ enablededModules.add(module.getId());
}
} catch (final ServiceConfigurationError e) {
LOG.error("Unable to instantiate IdPModule", e);
+ throw new BuildException(e);
}
}
-
- if (!requiredModules.isEmpty()) {
- LOG.warn("Required modules are missing or disabled: {}", requiredModules);
- throw new BuildException("One or more required modules are not enabled");
+ return enablededModules;
+ }
+
+ /**
+ * Police that required modules for plugin installation are enabled.
+ * @param loadedModules the modules we know to be enabled
+ * @throws BuildException if any required modules are missing or disabled
+ */
+ private void checkRequiredModules(final Set<String> loadedModules) throws BuildException {
+ for (final String moduleId: description.getRequiredModules()) {
+ if (!loadedModules.contains(moduleId)) {
+ LOG.warn("Required modules {} is missing on not enabled ", moduleId);
+ throw new BuildException("One or more required modules are not enabled");
+ }
+ }
+ }
+
+ /** Re-enabled the listed modules iff then are implemented by the plugin we just installed.
+ * @param loadedModules the modules to enable
+ * @throws BuildException on errors finding or enabling the modules
+ */
+ private void reEnableModules(final Set<String> loadedModules) throws BuildException {
+ try {
+ final Iterator<IdPModule> modules = ServiceLoader.load(IdPModule.class, getDistributionLoader()).iterator();
+ while (modules.hasNext()) {
+ final IdPModule module = modules.next();
+ if (pluginId.equals(module.getOwnerId()) && loadedModules.contains(module.getId())) {
+ LOG.debug("Re-enabling module {}", module.getId());
+ module.enable(moduleContext);
+ } else {
+ LOG.debug("Not re-enabling module {}, not provided by this plugin", module.getId());
+ }
+ }
+ } catch (final ServiceConfigurationError | ModuleException e) {
+ LOG.error("Unable to instantiate IdPModule", e);
+ throw new BuildException(e);
}
}
@@ -786,21 +813,27 @@ public final class PluginInstaller extends AbstractInitializableComponent implem
/** Generate a {@link URLClassLoader} which looks at the
* installing WEB-INF.
* @return an appropriate loader
- * @throws IOException if a directory traversal fails.
+ * @throws BuildException if a directory traversal fails.
*/
- private synchronized URLClassLoader getDistributionLoader() throws IOException {
+ private synchronized URLClassLoader getDistributionLoader() throws BuildException {
if (installingPluginLoader!= null) {
return installingPluginLoader;
}
- final List<URL> urls = new ArrayList<>();
- final Path libDir = distribution.resolve("webapp").resolve("WEB-INF").resolve("lib");
- try (final DirectoryStream<Path> libDirPaths = Files.newDirectoryStream(libDir)){
- for (final Path jar : libDirPaths) {
- urls.add(jar.toUri().toURL());
+ try {
+ final List<URL> urls = new ArrayList<>();
+ final Path libDir = distribution.resolve("webapp").resolve("WEB-INF").resolve("lib");
+ try (final DirectoryStream<Path> libDirPaths = Files.newDirectoryStream(libDir)){
+ for (final Path jar : libDirPaths) {
+ urls.add(jar.toUri().toURL());
+ }
+ installingPluginLoader = new URLClassLoader(urls.toArray(URL[]::new));
+ return installingPluginLoader;
}
- installingPluginLoader = new URLClassLoader(urls.toArray(URL[]::new));
- return installingPluginLoader;
+ } catch (final IOException e) {
+ LOG.error("Error building Plugin Installation ClassPathLoader");
+ throw new BuildException(e);
}
+
}
/**
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list