mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Added support for component libraries in plugins
This commit is contained in:
parent
75184d33ea
commit
1d3a443237
@ -71,9 +71,42 @@ import com.cloud.utils.mgmt.JmxUtil;
|
||||
import com.cloud.utils.mgmt.ManagementBean;
|
||||
|
||||
/**
|
||||
* ComponentLocator manages all of the adapters within a system. It operates on
|
||||
* top of an components.xml and uses reflection to instantiate all of the
|
||||
* adapters. It also supports rereading of all of the adapters.
|
||||
* ComponentLocator ties together several different concepts. First, it
|
||||
* deals with how a system should be put together. It manages different
|
||||
* types of components:
|
||||
* - Manager: Singleton implementation of a certain process.
|
||||
* - Adapter: Different singleton implementations for the same functions.
|
||||
* - SystemIntegrityChecker: Singletons that are called at the load time.
|
||||
* - Dao: Data Access Objects.
|
||||
*
|
||||
* These components can be declared in several ways:
|
||||
* - ComponentLibrary - A Java class that declares the above components. The
|
||||
* advantage of declaring components here is they change automatically
|
||||
* with any refactoring.
|
||||
* - components specification - An xml file that overrides the
|
||||
* ComponentLibrary. The advantage of declaring components here is
|
||||
* they can change by hand on every deployment.
|
||||
*
|
||||
* The two are NOT mutually exclusive. ComponentLocator basically locates
|
||||
* the components specification, which specifies the ComponentLibrary within.
|
||||
* Components found in the ComponentLibrary are overridden by components
|
||||
* found in components specification.
|
||||
*
|
||||
* Components specification can also be nested. One components specification
|
||||
* can point to another components specification and, therefore, "inherits"
|
||||
* those components but still override one or more components. ComponentLocator
|
||||
* reads the child components specification first and follow the chain up.
|
||||
* the child's components overrides the ones in the parent.
|
||||
*
|
||||
* ComponentLocator looks for the components specification as follows:
|
||||
* 1. By following the path specified by "cloud-stack-components-specification"
|
||||
* within the environment.properties file.
|
||||
* 2. Look for components.xml in the class path.
|
||||
*
|
||||
* ComponentLocator also ties in component injection. Components can specify
|
||||
* an @Inject annotation to components ComponentLocator knows. When
|
||||
* instantiating components, ComponentLocator attempts to inject these
|
||||
* components.
|
||||
*
|
||||
**/
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -98,7 +131,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
||||
protected String _serverName;
|
||||
protected Object _component;
|
||||
protected HashMap<Class<?>, Class<?>> _factories;
|
||||
protected HashMap<String, ComponentInfo<PluggableService>> _pluggableServicesMap;
|
||||
protected HashMap<String, ComponentInfo<PluggableService>> _pluginsMap;
|
||||
|
||||
static {
|
||||
if (s_janitor == null) {
|
||||
@ -133,7 +166,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
||||
_checkerMap = new LinkedHashMap<String, ComponentInfo<SystemIntegrityChecker>>();
|
||||
_adapterMap = new HashMap<String, Adapters<? extends Adapter>>();
|
||||
_factories = new HashMap<Class<?>, Class<?>>();
|
||||
_pluggableServicesMap = new LinkedHashMap<String, ComponentInfo<PluggableService>>();
|
||||
_pluginsMap = new LinkedHashMap<String, ComponentInfo<PluggableService>>();
|
||||
File file = PropertiesUtil.findConfigFile(filename);
|
||||
if (file == null) {
|
||||
s_logger.info("Unable to find " + filename);
|
||||
@ -157,7 +190,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
||||
_daoMap.putAll(parentLocator._daoMap);
|
||||
_managerMap.putAll(parentLocator._managerMap);
|
||||
_factories.putAll(parentLocator._factories);
|
||||
_pluggableServicesMap.putAll(parentLocator._pluggableServicesMap);
|
||||
_pluginsMap.putAll(parentLocator._pluginsMap);
|
||||
}
|
||||
|
||||
ComponentLibrary library = null;
|
||||
@ -168,14 +201,14 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
||||
_managerMap.putAll(library.getManagers());
|
||||
adapters.putAll(library.getAdapters());
|
||||
_factories.putAll(library.getFactories());
|
||||
_pluggableServicesMap.putAll(library.getPluggableServices());
|
||||
_pluginsMap.putAll(library.getPluggableServices());
|
||||
}
|
||||
|
||||
_daoMap.putAll(handler.daos);
|
||||
_managerMap.putAll(handler.managers);
|
||||
_checkerMap.putAll(handler.checkers);
|
||||
adapters.putAll(handler.adapters);
|
||||
_pluggableServicesMap.putAll(handler.pluggableServices);
|
||||
_pluginsMap.putAll(handler.pluggableServices);
|
||||
|
||||
return new Pair<XmlHandler, HashMap<String, List<ComponentInfo<Adapter>>>>(handler, adapters);
|
||||
} catch (ParserConfigurationException e) {
|
||||
@ -204,6 +237,8 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
||||
return;
|
||||
}
|
||||
|
||||
instantiatePluggableServices();
|
||||
|
||||
XmlHandler handler = result.first();
|
||||
HashMap<String, List<ComponentInfo<Adapter>>> adapters = result.second();
|
||||
try {
|
||||
@ -220,7 +255,6 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
||||
startAdapters();
|
||||
//TODO do we need to follow the instantiate -> inject -> configure -> start -> stop flow of singletons like managers/adapters?
|
||||
//TODO do we need to expose pluggableServices to MBean (provide getNames?)
|
||||
instantiatePluggableServices();
|
||||
} catch (CloudRuntimeException e) {
|
||||
s_logger.error("Unable to load configuration for " + _serverName + " from " + filename, e);
|
||||
System.exit(1);
|
||||
@ -641,18 +675,26 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
||||
}
|
||||
|
||||
protected void instantiatePluggableServices() {
|
||||
Set<Map.Entry<String, ComponentInfo<PluggableService>>> entries = _pluggableServicesMap.entrySet();
|
||||
Set<Map.Entry<String, ComponentInfo<PluggableService>>> entries = _pluginsMap.entrySet();
|
||||
for (Map.Entry<String, ComponentInfo<PluggableService>> entry : entries) {
|
||||
ComponentInfo<PluggableService> info = entry.getValue();
|
||||
if (info.instance == null) {
|
||||
s_logger.info("Instantiating PluggableService: " + info.name);
|
||||
info.instance = (PluggableService)createInstance(info.clazz, false, info.singleton);
|
||||
|
||||
if (info.instance instanceof Plugin) {
|
||||
Plugin plugin = (Plugin)info.instance;
|
||||
|
||||
ComponentLibrary lib = plugin.getComponentLibrary();
|
||||
_managerMap.putAll(lib.getManagers());
|
||||
_daoMap.putAll(lib.getDaos());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ComponentInfo<PluggableService> getPluggableService(String name) {
|
||||
ComponentInfo<PluggableService> mgr = _pluggableServicesMap.get(name);
|
||||
ComponentInfo<PluggableService> mgr = _pluginsMap.get(name);
|
||||
return mgr;
|
||||
}
|
||||
|
||||
@ -669,7 +711,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
||||
|
||||
public <T> List<T> getAllPluggableServices() {
|
||||
List<T> services = new ArrayList<T>();
|
||||
Set<Map.Entry<String, ComponentInfo<PluggableService>>> entries = _pluggableServicesMap.entrySet();
|
||||
Set<Map.Entry<String, ComponentInfo<PluggableService>>> entries = _pluginsMap.entrySet();
|
||||
for (Map.Entry<String, ComponentInfo<PluggableService>> entry : entries) {
|
||||
ComponentInfo<PluggableService> info = entry.getValue();
|
||||
if (info.instance == null) {
|
||||
@ -1041,7 +1083,7 @@ public class ComponentLocator implements ComponentLocatorMBean {
|
||||
checkers.put(info.name, info);
|
||||
s_logger.info("Adding system integrity checker: " + info.name);
|
||||
currentInfo = info;
|
||||
} else if (qName.equals("pluggableservice")) {
|
||||
} else if (qName.equals("pluggableservice") || qName.equals("plugin")) {
|
||||
ComponentInfo<PluggableService> info = new ComponentInfo<PluggableService>();
|
||||
fillInfo(atts, PluggableService.class, info);
|
||||
s_logger.info("Adding PluggableService: " + info.name);
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
package com.cloud.utils.component;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This interface defines methods for pluggable code within the Cloud Stack.
|
||||
*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user