Work in progress. Does not reflect reality, purely the thoughts of a mad man



Deployment Models

Single JVM

Redundant JVM

Externalized System Services

Fully Distributed

Or some other combination

Architecture

Overview

Module System

CloudStack is arrange into a series module that are in a hierarchical arrangement.  Depending on which modules are selected to load determines what role the JVM will take on.  This is forms the basis of how different deployment models can be achieved.  If all modules are selected, then this would be a the "Single JVM" or "Redundant JVM" approach.  The above picture is used an example of modules but does not reflect the actual module hierarchy in CloudStack.

Implementation

Spring

The implementation of the modules is based on assembling a hierarchy of Spring application contexts.  With Spring each application context can have a parent.  Each module defines its own Spring XML configuration that will be loaded in its own application context.  Each module also specifies what is it's parent context.  From a Spring perspective, this means each module is isolated from its siblings.  This means that network element A can not pollute the application context of network element B.  Additionally this means that "plugins" will be isolated from core application contexts of CloudStack.  Thus if CloudStack core defines a bean "MyPoorlyNamedBean" and network element A defines a bean of the same name, network element A will not mess up the rest of the CloudStack by overriding that bean.  It could of course mess up itself though.

Module Life Cycle

The life cycle of the modules follows the Spring managed life cycle. Parent contexts are always initiated before the child contexts. Child contexts are destroyed before parent contexts are. All beans respect the standard JSR-250 life cycle annotations, @PreDestroy and @PostConstruct. While dynamic module loading is not in the initial scope of the first implementation, such a thing will be possible. If you wish to unload network element A, the Spring context for network element A will be stopped, initiating a context shutdown. Refer to "Plugin Discovery" for more information on how plugins are discovered and (un)registered.

Module Discovery

Modules are discovered and loaded based on classpath scanning. If a file META-INF/cloudstack/*/module.properties is found it is treated as a module. It will then find the rest of the configuration for that module. It will be automatically loaded if 1) it hasn't been configured specifically to not be loaded and 2) all of its ancestors have been selected to be loaded. For example, network element A will only be loaded if its parent context (let's just call that cloudstack-network for now) is selected to be loaded. So if I'm in a JVM that is designated to be an API only JVM, then the cloudstack-network module will not be selected and thus network elements will not be loaded and started in that JVM.

Since module discovery is based on classpath scanning (basically looking up and finding URL's) this means modules could really be loaded from anywhere. So, for example, you could create CloudStack as a Java Web Start application, or even embedded in OSGi, or whatever.

Class Loader Management

Ideally each module should be loaded in its own class loader. This is completely feasible. The ModuleDefinitionLocator is responsible for discovering the modules and their respective class loaders. For the first implementation, we may focus on a simple strategy of assuming a single classloader. That is TBD.

Plugin, Adapter, or Extension Management

Currently plugins, adapters, gurus, widgets, or "whatever vague term you want" is registered through either modifying Spring XML or programmatic registration as part of the configure method. In the new module system this will all be consolidated to one mechanism that is truly decoupled and extensible. As modules are loaded the modules will be scanned for beans of pluggable types, like NetworkElement or Investigator. That bean will then be registered in a fashion that makes it available to the consumers of the pluggable types. This is a bit hand wavy as a bit of analysis needs to be done to determine all the different extension points.

When a context is shutdown, the pluggable types will be shutdown and deregistered.

Sample Configuration
META-INF/cloudstack/mycomponent/module.properties

This is the main file that defines a module. The contents should be

name=mycomponent
parent=myparent

The name should match the directory it is in. It would be nice to discover the module name based on the directory, but unfortunately that isn't really possible if you truly want to respect the opaque nature of URLs in Java. The parent parameter is obviously the parent context

META-INF/cloudstack/mycomponet/*context.xml

Spring XML files for the component named "mycomponent" are expected to be found at META-INF/cloudstack/mycomponet/*context.xml. A module can define as many XML files as it chooses.

META-INF/cloudstack/mycomponent/*defaults.properties

These files define defaults to be added to the Configuration subsystem. That subsystem is also a new idea and isn't documented yet.

Communication to SystemVM

Components

Configuration

Locking

Eventing

  • No labels