Alon Bar-Lev has uploaded a new change for review. Change subject: aaa: extension-manager: prepare to multiple binding support ......................................................................
aaa: extension-manager: prepare to multiple binding support Change-Id: Iab0b2efa0ac95c05a3e682bdf51e528a32b3f84a Signed-off-by: Alon Bar-Lev <[email protected]> --- M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/InitBackendServicesOnStartupBean.java M backend/manager/modules/extensions-api-root/extensions-api/src/main/java/org/ovirt/engine/api/extensions/Base.java M backend/manager/modules/extensions-manager/src/main/java/org/ovirt/engine/core/extensions/mgr/ExtensionsManager.java 3 files changed, 150 insertions(+), 56 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/80/27280/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/InitBackendServicesOnStartupBean.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/InitBackendServicesOnStartupBean.java index c6f39a1..2e5e18e 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/InitBackendServicesOnStartupBean.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/InitBackendServicesOnStartupBean.java @@ -118,8 +118,9 @@ Properties authConfig = new Properties(); authConfig.put(Base.ConfigKeys.NAME, "builtin-authn-internal"); authConfig.put(Base.ConfigKeys.PROVIDES, Authn.class.getName()); - authConfig.put(Base.ConfigKeys.MODULE, "org.ovirt.engine.extensions.builtin"); - authConfig.put(Base.ConfigKeys.CLASS, "org.ovirt.engine.extensions.aaa.builtin.internal.InternalAuthn"); + authConfig.put(Base.ConfigKeys.BINDINGS_METHOD, Base.ConfigBindingsMethods.JBOSSMODULE); + authConfig.put(Base.ConfigKeys.BINDINGS_JBOSSMODULE_MODULE, "org.ovirt.engine.extensions.builtin"); + authConfig.put(Base.ConfigKeys.BINDINGS_JBOSSMODULE_CLASS, "org.ovirt.engine.extensions.aaa.builtin.internal.InternalAuthn"); authConfig.put("ovirt.engine.aaa.authn.profile.name", "internal"); authConfig.put("ovirt.engine.aaa.authn.authz.plugin", "internal"); authConfig.put("config.authn.user.name", Config.<String> getValue(ConfigValues.AdminUser)); @@ -130,8 +131,9 @@ Properties dirConfig = new Properties(); dirConfig.put(Base.ConfigKeys.NAME, "internal"); dirConfig.put(Base.ConfigKeys.PROVIDES, Authz.class.getName()); - dirConfig.put(Base.ConfigKeys.MODULE, "org.ovirt.engine.extensions.builtin"); - dirConfig.put(Base.ConfigKeys.CLASS, "org.ovirt.engine.extensions.aaa.builtin.internal.InternalAuthz"); + dirConfig.put(Base.ConfigKeys.BINDINGS_METHOD, Base.ConfigBindingsMethods.JBOSSMODULE); + dirConfig.put(Base.ConfigKeys.BINDINGS_JBOSSMODULE_MODULE, "org.ovirt.engine.extensions.builtin"); + dirConfig.put(Base.ConfigKeys.BINDINGS_JBOSSMODULE_CLASS, "org.ovirt.engine.extensions.aaa.builtin.internal.InternalAuthz"); dirConfig.put("config.authz.user.name", Config.<String> getValue(ConfigValues.AdminUser)); dirConfig.put("config.authz.user.id", "fdfc627c-d875-11e0-90f0-83df133b58cc"); dirConfig.put("config.query.filter.size", @@ -167,8 +169,9 @@ authConfig.put(Base.ConfigKeys.NAME, String.format("builtin-authn-%1$s", domain)); authConfig.put(Base.ConfigKeys.PROVIDES, Authn.class.getName()); authConfig.put(Base.ConfigKeys.ENABLED, "true"); - authConfig.put(Base.ConfigKeys.MODULE, "org.ovirt.engine.extensions.builtin"); - authConfig.put(Base.ConfigKeys.CLASS, + authConfig.put(Base.ConfigKeys.BINDINGS_METHOD, Base.ConfigBindingsMethods.JBOSSMODULE); + authConfig.put(Base.ConfigKeys.BINDINGS_JBOSSMODULE_MODULE, "org.ovirt.engine.extensions.builtin"); + authConfig.put(Base.ConfigKeys.BINDINGS_JBOSSMODULE_CLASS, "org.ovirt.engine.extensions.aaa.builtin.kerberosldap.KerberosLdapAuthn"); authConfig.put("ovirt.engine.aaa.authn.profile.name", domain); authConfig.put("ovirt.engine.aaa.authn.authz.plugin", domain); @@ -179,8 +182,9 @@ Properties dirConfig = new Properties(); dirConfig.put(Base.ConfigKeys.NAME, domain); dirConfig.put(Base.ConfigKeys.PROVIDES, Authz.class.getName()); - dirConfig.put(Base.ConfigKeys.MODULE, "org.ovirt.engine.extensions.builtin"); - dirConfig.put(Base.ConfigKeys.CLASS, + dirConfig.put(Base.ConfigKeys.BINDINGS_METHOD, Base.ConfigBindingsMethods.JBOSSMODULE); + dirConfig.put(Base.ConfigKeys.BINDINGS_JBOSSMODULE_MODULE, "org.ovirt.engine.extensions.builtin"); + dirConfig.put(Base.ConfigKeys.BINDINGS_JBOSSMODULE_CLASS, "org.ovirt.engine.extensions.aaa.builtin.kerberosldap.KerberosLdapAuthz"); dirConfig.put("config.query.filter.size", Config.<Integer> getValue(ConfigValues.MaxLDAPQueryPartsNumber)); diff --git a/backend/manager/modules/extensions-api-root/extensions-api/src/main/java/org/ovirt/engine/api/extensions/Base.java b/backend/manager/modules/extensions-api-root/extensions-api/src/main/java/org/ovirt/engine/api/extensions/Base.java index 1c2cc0c..f5b2763 100644 --- a/backend/manager/modules/extensions-api-root/extensions-api/src/main/java/org/ovirt/engine/api/extensions/Base.java +++ b/backend/manager/modules/extensions-api-root/extensions-api/src/main/java/org/ovirt/engine/api/extensions/Base.java @@ -42,19 +42,28 @@ */ public static final String ENABLED = "ovirt.engine.extension.enabled"; /** - * Extension module name. - * Jboss module to load. + * Extension binding method. + * Bindings method to use. + * <ul> + * <li>{@link ConfigBindingsMethods#JBOSSMODULE}</li> + * </ul> + * Mandatory if binding method is Jboss module. + * @see ConfigBindingsMethods + */ + public static final String BINDINGS_METHOD = "ovirt.engine.extension.bindings.method"; + /** + * Jboss module binding method jboss module name. * <br> * Mandatory. */ - public static final String MODULE = "ovirt.engine.extension.module"; + public static final String BINDINGS_JBOSSMODULE_MODULE = "ovirt.engine.extension.binding.jbossmodule.module"; /** - * Extension class name within module. + * Jboss module binding method class name. * Used to locate the service at META-INF/services/<class>.Extension. * <br> - * Mandatory. + * Mandatory if binding method is Jboss module. */ - public static final String CLASS = "ovirt.engine.extension.class"; + public static final String BINDINGS_JBOSSMODULE_CLASS = "ovirt.engine.extension.binding.jbossmodule.class"; /** * Sensitive keys of configuration. * These will should not appear in debugging. @@ -63,6 +72,60 @@ } /** + * Binding methods. + */ + public static class ConfigBindingsMethods { + /** + * Jboss module binding method. + * Use Jboss module loading method and Java bindings. + * <pre> + * public class MyExtension implements Extension { + * {@code + * private void doInit(ExtMap input, ExtMap output) { + * input.<ExtMap> get(Base.InvokeKeys.CONTEXT).mput( + * Base.ContextKeys.AUTHOR, + * "The oVirt Project" + * ).mput( + * Base.ContextKeys.EXTENSION_NAME, + * "Extension Java Example" + * ).mput( + * Base.ContextKeys.LICENSE, + * "ASL 2.0" + * ).mput( + * Base.ContextKeys.HOME_URL, + * "http://www.ovirt.org" + * ).mput( + * Base.ContextKeys.VERSION, + * "0.0.0" + * ); + * } + * + * \@Override + * public void invoke(ExtMap input, ExtMap output) { + * try { + * if (input.get(Base.InvokeKeys.COMMAND).equals(Base.InvokeCommands.INITIALIZE)) { + * doInit(input, output); + * } else { + * output.put(Base.InvokeKeys.RESULT, Base.InvokeResult.UNSUPPORTED); + * } + * output.putIfAbsent(Base.InvokeKeys.RESULT, Base.InvokeResult.SUCCESS); + * } catch (Exception e) { + * output.mput( + * Base.InvokeKeys.RESULT, + * Base.InvokeResult.FAILED + * ).mput( + * Base.InvokeKeys.MESSAGE, + * e.getMessage() + * ); + * } + * } + * } + * }</pre> + */ + public static final String JBOSSMODULE = "jbossmodule"; + } + + /** * Global context key. */ public static class GlobalContextKeys { diff --git a/backend/manager/modules/extensions-manager/src/main/java/org/ovirt/engine/core/extensions/mgr/ExtensionsManager.java b/backend/manager/modules/extensions-manager/src/main/java/org/ovirt/engine/core/extensions/mgr/ExtensionsManager.java index 0c9906c..1558134 100644 --- a/backend/manager/modules/extensions-manager/src/main/java/org/ovirt/engine/core/extensions/mgr/ExtensionsManager.java +++ b/backend/manager/modules/extensions-manager/src/main/java/org/ovirt/engine/core/extensions/mgr/ExtensionsManager.java @@ -36,9 +36,64 @@ public static final ExtKey TRACE_LOG_CONTEXT_KEY = new ExtKey("EXTENSION_MANAGER_TRACE_LOG", Logger.class, "863db666-3ea7-4751-9695-918a3197ad83"); public static final ExtKey CAUSE_OUTPUT_KEY = new ExtKey("EXTENSION_MANAGER_CAUSE_OUTPUT_KEY", Throwable.class, "894e1c86-518b-40a2-a92b-29ea1eb0403d"); - private static int extensionNameIndex = 0; + private static interface BindingsLoader { + Extension load(Properties props) throws Exception; + } + + private static class JBossBindingsLoader implements BindingsLoader { + private Map<String, Module> loadedModules = new HashMap<>(); + + private Module loadModule(String moduleSpec) { + // If the module was not already loaded, load it + try { + Module module = loadedModules.get(moduleSpec); + if (module == null) { + ModuleLoader loader = ModuleLoader.forClass(this.getClass()); + if (loader == null) { + throw new ConfigurationException(String.format("The module '%1$s' cannot be loaded as the module system isn't enabled.", + moduleSpec)); + } + module = loader.loadModule(ModuleIdentifier.fromString(moduleSpec)); + loadedModules.put(moduleSpec, module); + } + return module; + } catch (ModuleLoadException exception) { + throw new ConfigurationException(String.format("The module '%1$s' cannot be loaded.", moduleSpec), + exception); + } + } + + private Class<?> lookupService(Class<?> serviceInterface, String serviceClassName, String moduleName) { + // Iterate over the service classes, and find the one that should + // be instantiated and initialized. + Module module = loadModule(moduleName); + Class<?> serviceClass = null; + for (Object service : ServiceLoader.load(serviceInterface, module.getClassLoader())) { + if (service.getClass().getName().equals(serviceClassName)) { + serviceClass = service.getClass(); + break; + } + } + if (serviceClass == null) { + throw new ConfigurationException(String.format("The module '%1$s' does not contain the service '%2$s'.", + module.getIdentifier().getName(), + serviceClassName)); + } + return serviceClass; + } + + public Extension load(Properties props) throws Exception { + return (Extension) lookupService( + Extension.class, + props.getProperty(Base.ConfigKeys.BINDINGS_JBOSSMODULE_CLASS), + props.getProperty(Base.ConfigKeys.BINDINGS_JBOSSMODULE_MODULE) + ).newInstance(); + } + } private static class ExtensionEntry { + + private static int extensionNameIndex = 0; private String name; private File file; @@ -63,8 +118,8 @@ private static final Logger log = LoggerFactory.getLogger(ExtensionsManager.class); private static final Logger traceLog = LoggerFactory.getLogger(ExtensionsManager.class.getName() + ".trace"); private static volatile ExtensionsManager instance = null; + private Map<String, BindingsLoader> bindingsLoaders = new HashMap<>(); private Map<String, ExtensionEntry> loadedEntries = new HashMap<>(); - private Map<String, Module> loadedModules = new HashMap<>(); private ExtMap globalContext = new ExtMap().mput(Base.GlobalContextKeys.EXTENSIONS, new ArrayList<ExtMap>()); public static ExtensionsManager getInstance() { @@ -98,6 +153,9 @@ } private ExtensionsManager() { + + bindingsLoaders.put(Base.ConfigBindingsMethods.JBOSSMODULE, new JBossBindingsLoader()); + for (File directory : EngineLocalConfig.getInstance().getExtensionsDirectories()) { if (!directory.exists()) { log.warn(String.format("The directory '%1$s' cotaning configuration files does not exist.", @@ -177,11 +235,7 @@ if (entry.enabled && entry.extension == null) { try { entry.extension = new ExtensionProxy( - (Extension) lookupService( - Extension.class, - props.getProperty(Base.ConfigKeys.CLASS), - props.getProperty(Base.ConfigKeys.MODULE) - ).newInstance(), + loadExtension(props), ( new ExtMap().mput( Base.ContextKeys.GLOBAL_CONTEXT, @@ -266,43 +320,16 @@ } } - private Module loadModule(String moduleSpec) { - // If the module was not already loaded, load it - try { - Module module = loadedModules.get(moduleSpec); - if (module == null) { - ModuleLoader loader = ModuleLoader.forClass(this.getClass()); - if (loader == null) { - throw new ConfigurationException(String.format("The module '%1$s' cannot be loaded as the module system isn't enabled.", - moduleSpec)); - } - module = loader.loadModule(ModuleIdentifier.fromString(moduleSpec)); - loadedModules.put(moduleSpec, module); - } - return module; - } catch (ModuleLoadException exception) { - throw new ConfigurationException(String.format("The module '%1$s' cannot be loaded.", moduleSpec), - exception); - } - } + private Extension loadExtension(Properties props) throws Exception { + Extension extension; - private Class<?> lookupService(Class<?> serviceInterface, String serviceClassName, String moduleName) { - // Iterate over the service classes, and find the one that should - // be instantiated and initialized. - Module module = loadModule(moduleName); - Class<?> serviceClass = null; - for (Object service : ServiceLoader.load(serviceInterface, module.getClassLoader())) { - if (service.getClass().getName().equals(serviceClassName)) { - serviceClass = service.getClass(); - break; - } + BindingsLoader loader = bindingsLoaders.get(props.getProperty(Base.ConfigKeys.BINDINGS_METHOD)); + if (loader == null) { + throw new ConfigurationException(String.format("Invalid binding method '%1$s'.", + props.getProperty(Base.ConfigKeys.BINDINGS_METHOD))); } - if (serviceClass == null) { - throw new ConfigurationException(String.format("The module '%1$s' does not contain the service '%2$s'.", - module.getIdentifier().getName(), - serviceClassName)); - } - return serviceClass; + + return loader.load(props); } public void dump() { -- To view, visit http://gerrit.ovirt.org/27280 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iab0b2efa0ac95c05a3e682bdf51e528a32b3f84a Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Alon Bar-Lev <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
