Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
  <bean id="instantiatePostProcessor" class="com.cloud.utils.component.ComponentInstantiationPostProcessor">
    <property name="Interceptors">
        <list>
            <ref bean="transactionContextBuilder" />
            <ref bean="actionEventInterceptor" />
        </list>
    </property>
  </bean>

4.6 Pluggable adapters

5. Component lifecycle

Adapter components usually works under the management of its manager component, a same set of adapter components may be used by multiple managers, and sometimes, order of the adapters may also be significant. Whether or not an adapter component is in action depends not only the existence of its <bean> declaration, but also the references in manager components.

The reference configuration of adapters in fact represents the dynamic aspect of CloudStack and gives people the flexibility to tune and customize CloudStack, due to its dynamic nature, we put all of these configurations in componentContext.xml.in and/or nonossComponentContext.xml.in. Following example shows a same set of adapter components, but with a different order of these adapter components.

Code Block
 <!-- Security adapters -->
 <bean id="userAuthenticators" class="com.cloud.utils.component.AdapterList">
   <property name="Adapters">
     <list>
         <ref bean="SHA256SaltedUserAuthenticator"/>
         <ref bean="MD5UserAuthenticator"/>
         <ref bean="LDAPUserAuthenticator"/>
         <ref bean="PlainTextUserAuthenticator"/>
     </list>
   </property>
 </bean>
 <bean id="userPasswordEncoders" class="com.cloud.utils.component.AdapterList">
   <property name="Adapters">
     <list>
         <ref bean="SHA256SaltedUserAuthenticator"/>
         <ref bean="MD5UserAuthenticator"/>
         <ref bean="LDAPUserAuthenticator"/>
         <ref bean="PlainTextUserAuthenticator"/>
     </list>
   </property>
 </bean>

For network plugin developers, you probably need to visit following example often to add or remove your network element component. (baremetal support is disabled in following example)

Code Block

 <bean id="networkElements" class="com.cloud.utils.component.AdapterList">
   <property name="Adapters">
     <list>
         <ref bean="VirtualRouter"/>
         <ref bean="Ovs"/>
         <ref bean="SecurityGroupProvider"/>
         <ref bean="VpcVirtualRouter"/>
         <ref bean="NiciraNvp" />
         <ref bean="MidoNetElement"/>
!--
         <ref bean="BareMetalDhcp"/>
         <ref bean="BareMetalPxe"/>
         <ref bean="BareMetalUserdata"/>
->
     </list>
   </property>
 </bean>

4.7 Module & components

CloudStack contains a lot of software modules, for example, module for account management, module for networking etc, each module in turn can contain its own DAO, manager, adapter components, To help make the component configuration maintainable, please follow following two guidelines.

  • Make it become a component only if it is necessary

Due to historic reason, we have a number of tiny components, like OVA/ISO format "components", unless you see a need to take advantage of auto-wiring, avoid turning these classes into components

  • Put all component declarations that logically belong to the same module into one section.  

Because of the removal of component auto-scanning, all current component declaration in applicationContext.xml.in are primarily generated with a tool, and also the module boundaries of most of legacy components are blur, therefore organization of these legacy components does not strictly follow this rule. However, it is recommended for all new large independent modules to follow this rule. For example, baremetal feature module is organized in this way in applicationContext.xml.in 

Code Block
<!--=======================================================================================================-->
<!--                                                                                                       -->
<!--                           Module-basis OSS/non-OSS Common components                                  -->
<!--                                                                                                       -->
<!--=======================================================================================================-->

  <!--
    Baremetal components
  -->

<!--
  <bean id="BareMetalDhcp" class="com.cloud.baremetal.networkservice.BaremetalDhcpElement">
    <property name="name" value="BareMetalDhcp"/>
  </bean>
  <bean id="BareMetalPxe" class="com.cloud.baremetal.networkservice.BaremetalPxeElement">
    <property name="name" value="BareMetalPxe"/>
  </bean>
  <bean id="BareMetalUserdata" class="com.cloud.baremetal.networkservice.BaremetalUserdataElement">
      <property name="name" value="BareMetalUserdata"/>
  </bean>

  <bean id="BareMetalTemplateAdapter" class="com.cloud.baremetal.manager.BareMetalTemplateAdapter" />

  <bean id="BareMetalDiscoverer" class="com.cloud.baremetal.manager.BareMetalDiscoverer">
    <property name="name" value="Bare Metal Agent"/>
  </bean>

  <bean id="BareMetalPlanner" class="com.cloud.baremetal.manager.BareMetalPlanner">
    <property name="name" value="BareMetal Fit"/>
  </bean>

  <bean id="BaremetalGuru" class="com.cloud.baremetal.manager.BareMetalGuru">
    <property name="name" value="BaremetalGuru"/>
  </bean>

  <bean id="BaremetalPlannerSelector" class="com.cloud.baremetal.manager.BaremetalPlannerSelector">
    <property name="name" value="BaremetalPlannerSelector"/>
  </bean>

  <bean id="BaremetalManager" class="com.cloud.baremetal.manager.BaremetalManagerImpl"/>
  <bean id="BaremetalDhcpManager" class="com.cloud.baremetal.networkservice.BaremetalDhcpManagerImpl"/>
  <bean id="BaremetalKickStartPxeService" class="com.cloud.baremetal.networkservice.BaremetalKickStartServiceImpl"/>
  <bean id="BaremetalPingPxeService" class="com.cloud.baremetal.networkservice.BareMetalPingServiceImpl" />
  <bean id="BaremetalPxeManager" class="com.cloud.baremetal.networkservice.BaremetalPxeManagerImpl" />

  <bean id="BAREMETAL" class="org.apache.cloudstack.storage.image.format.BAREMETAL" />
  <bean id="baremetalDhcpDaoImpl" class="com.cloud.baremetal.database.BaremetalDhcpDaoImpl" />
  <bean id="baremetalPxeDaoImpl" class="com.cloud.baremetal.database.BaremetalPxeDaoImpl" />
-->

5. Component lifecycle

In CloudStack, some components are lifecyle sensitive, examples are those manager objects, adapter objects. To indicate the desire to be life-cycle management aware, a component needs to implement interface ComponentLifecycle. ComponentLifecycle currently defines 6 run-levels to represent system startup cycles.

Code Block
public interface ComponentLifecycle {
	public static final int RUN_LEVEL_SYSTEM_BOOTSTRAP = 0;			// for system level bootstrap components
	public static final int RUN_LEVEL_SYSTEM = 1;				// for system level service components (i.e., DAOs)
	public static final int RUN_LEVEL_FRAMEWORK_BOOTSTRAP = 2;		// for framework startup checkers (i.e., DB migration check)
	public static final int RUN_LEVEL_FRAMEWORK = 3;			// for framework bootstrap components(i.e., clustering management components)
	public static final int RUN_LEVEL_COMPONENT_BOOTSTRAP = 4;		// general manager components
	public static final int RUN_LEVEL_COMPONENT = 5;			// regular adapters, plugin components
	public static final int RUN_LEVEL_APPLICATION_MAINLOOP = 6;
	public static final int MAX_RUN_LEVELS = 7;


	// ...
}

You usually don't need to implement such interface of your own, GenericDaoBase, AdapterBase, ManagerBase give you a start point. It covers major flavors of the components inside CloudStackIn CloudStack, some components are lifecyle sensitive, examples are those manager objects, adapter objects, to make lifecyle management more general and flexible, there are some TODO works to make component life-cycle management easier. We'll keep this topic updated in the community.