Jump to: navigation, search

COSMOS Bug Design 209248

Comments are on the Talk page


The Muse programming model is a composition-oriented model, where capabilities can be imposed on a resource implementation externally. In the annotations, the composition model can be supported programatically by creating a single facade over multiple capability implementations, but the annotations don't provide any support to make this easier.

The annotations should provide support for this model in order to enforce/encourage alignment with the existing Muse programming model.

/**
 * Annotation used to indicate an interface which to be exposed as a distinct 
 * management capability. 
 */
@Target(TYPE)
@Retention(RUNTIME)
public @interface ManagedResourceCapability {
	
	/**
	 * A text description of the capability. 
	 * This attribute is intended for tooling support. 
	 * 
	 */
	String description() default "";
	/**
	 * The namespace of the capability. This namespace will be used for all
	 * operations and properties exposed by this capability (unless overridden) 
	 * and will uniquely identify the capability when introspecting its resource.  
	 */
	String namespace();
	
	/**
	 * Indicates that the annotated implementation may be used in conjunction
	 * with the ComposableManagedCapabilitySet annotation to implement a 
	 * composite managed resource  
	 */
	boolean composable() default true;
}

/**
 * Annotation used to decorate a ManagedResource with externally implemented capabilities 
 */
@Target(TYPE)
@Retention(RUNTIME)
public @interface ComposableManagedCapabilitySet {

	/**
	 * The set of capability classes to decorate the targeted 
	 * ManagedResource instance with. This annotation works
	 * in conjunction with the ManagedFrameworkAutowire, 
	 * ManagedResourceCapability, and ManagedResourceFactory  
	 * annotations to enable the framework to replicate the
	 * delcarative programming model exposed by Muse.xml  
	 */
	Class[] set() default {};
	
}

/**
 * Annotation used to support autowiring of 
 * Components within the management framework.
 */
@Target(FIELD)
@Retention(RUNTIME)
public @interface ManagedFrameworkAutowire {
	/**
	 * Name of the desired Component
	 */
	String name() default "";
	
	/**
	 * Class of the desired Capability. This attribute works 
	 * in conjunction with the ComposableManagedCapabilitySet
	 *  annotation
	 */
	Class capability() default Void.class;
}

The following annotations (proposed as a way to support the Singleton requirement for CMDBf) can be used for this purpose as well.

/**
 * Annotation used to indicate a factory method to construct a framework component. 
 */
@Target(METHOD)
@Retention(RUNTIME)
public @interface ManagedResourceFactory {
	
	/**
	 * If true, indicates that the resource is a singleton, and only the default 
	 * instance may be registered. All other instances attempting to register will
	 * be rejected   
	 */
	boolean singleton() default false;
	
}

Binding rules:

For composable capability set values:

  • check that each set element is annotated as a capability
  • check that each set element is composable
  • construct the composed capability instances
    • if the capability has a designated factory method, use that method to construct the instance
    • if the capability does not have a factory method, use the capability's namespace to see if a factory has been registered with the contribution manager (Minor change required to ContributionManager interface). If yes, use that factory to construct the capaiblity instance. Ensure that the instance matches the capability class. If no factory exists, or if the instance is not assignable, fail the bind request.
  • Perform any requested autowires. Wiring requests based on class are taken from the composed capability set. Wiring requests based on names are taken from the ContributionManager.
  • Ensure that all duplicated capabilities (between composed and interface implementation) share a satisfied wiring target. If a capability is duplicated, but no wiring target exists, fail the binding. The assumption is that the intent is to use the POJO interface to proxy to the delegated implementation. We don't want the POJO invocation and the bound invocation to take different paths through the resource.
  • Bind the result to the appropriate managagement binding. The binding needs to ensure that composed capabilities and capabilities based on implemented interfaces are not represented twice (No duplicated Port types!). Bindings should ensure that all calls route to the interface call first, based on the assumption that the interface call will delegate to the autowire target.