What is CXWS?
A Java-based CIMOM technology with:• Clean conceptual basis• Lightweight instances• Simplified provider development
Clean Conceptualization
• Object-oriented framework (meta-objects actually do things)
• Properties really get and set values• Instances and classes are always
fully functional, even if lazily realized
Lightweight Instances
• CIM class definitions impose structure on CIM instances
• CXWS leverages this structure as meta-data for instances
• A CxInstance is little more than a CxClass reference and an array of object values
• CxProperty objects know just which value to get or set (no overhead, no searching)
• Provision for lazily-populated instances, built directly from an object path
Superior Provider Interface
• Java WBEM Services (WBEMSolutions), OpenWBEM, Pegasus all have isomorphic provider interfaceso Merely “pass through” the original client
request, without adding value
• CXWS’ basic provider interface is one method, two argumentso The surprise: it’s not just simpler, it’s also
more powerful!
JWS Providers
• references, referenceNames• createInstance, setInstance,
deleteInstance• execQuery
• enumerateInstances• enumerateInstanceNames• getInstance• associations, associationNames
CXWS Providers
• Typical “observational” providers implement just one method.
• An interface allowing manipulation of objects adds three methods (create, update, delete), but implementation is optional.
• Support for “lazy” instances is also optional; adds one additional method.
Fewer Execution Paths
for (Iterator paths = enumerateInstanceNames(…);
paths.hasNext(); )
{
CIMInstance inst =
getInstance((CIMObjectPath) paths.next(), …);
. . .
}
Fewer Execution Paths
for (Iterator insts = enumerateInstances(…);
insts.hasNext(); )
{
CIMInstance inst = (CIMInstance) insts.next();
. . .
}
Code stops working!
Client exercises a new code path
Basic Provider Interface
void enumerateDirectInstances(CxCondition cond, InstanceReceiver r) throws Exception
• A single all-purpose enumeration method with a simple signature.
• The condition argument tells what instances the caller wants.
• Candidate instances are passed to InstanceReceiver callback.
A Simple Provider
public void enumerateDirectInstances(CxCondition cond, InstanceReceiver r)throws Exception
{for (int ii = 0; ii < getHbaCount(); ++ii){ r.test(makeHbaInstance(ii));}
}
private CxClass cc = …;private CxProperty hbaIndex = cc.getExpectedProperty(“HbaIndex”);private CxClass hbaName = cc.getExpectedProperty(“HbaName”);
private CxInstance makeHbaInstance(int ii){
Object[] values = cc.getDefaultValues();hbaIndex.set(values, new Integer(ii));hbaName.set(values, getHbaName(ii));// . . .return new CxInstance(cc, values);
}
Conditions
• A generalization of object path• Like a WHERE clause in a query, but
only refers to one class (the condition’s domain)
• No parsing required• Support simple but powerful forms of
reasoning
Instance Receivers
• Originally conceived to avoid constantly concatenating Vectors
• Serendipitously, opens the door to:o Streaming resultso Asynchronyo Reporting partial operation failure
Typical Conditions
• For enumerateInstances: condition = CxCondition.ALWAYS
• For getInstance: condition encodes object path
• For references, associators: condition expresses a constraint on the “role” property (inferred if necessary)
• Providers should not make assumptions about the nature of the condition
Provider Structure
• Step one: nested loops• Step two: each loop body becomes a
separate method; “select or search” control strategy
• Step three (unusual): alternative selection strategies
Provider Example (Step 1)
public void enumerateDirectInstances(CxCondition cond, InstanceReceiver r)
throws Exception
{
for (Iterator systems = getAllSystems(); systems.hasNext(); )
{
System system = (System) systems.next();
for (Iterator devices = system.getAllDevices(); devices.hasNext(); )
r.test(makeInstance((Device) devices.next()));
}
}
Provider Example (Step 2)
public void enumerateDirectInstances(CxCondition cond, InstanceReceiver r)
throws Exception
{
if (cond.hasRestriction(systemName))
enumeratePerSystem(getSystem((String) cond.getRestriction(systemName)),
cond, r);
else
for (Iterator systems = getAllSystems(); systems.hasNext(); )
enumeratePerSystem((System) systems.next(), cond, r);
}
private void enumeratePerSystem(System system, CxCondition cond, InstanceReceiver r)
{
if (cond.hasRestriction(deviceId))
r.test(makeInstance (system.getDevice((String) cond.getRestriction(deviceId))));
else
for (Iterator devices = system.getAllDevices(); devices.hasNext(); )
r.test(makeInstance((Device) devices.next()));
}
Association Providers
• Can be written like any other provider• Or… use AssociationProvider abstract
class, based on “relations”• Relations describe how to compute
the Antecedent from the Dependent, or vice-versa.
• CIM_SystemDevice: trivial to identify the CIM_System associated with a CIM_Device
Implementing CIM Methods
• CXWS dispatches CIM methods using Java reflection
• Provider just implements a Java method whose name and type signature matches that of the CIM method
• Providers don’t have to dispatch methods, in the style of invokeMethod()
Provider Interface Extensions
• LifecycleProvider adds createInstance, setProperties, deleteInstance.
• PartialInstanceProvider allows an object path to be used as an instance.If and when access to non-key properties is
required, the provider’s retrieveValues method will be called.
• DispatchingMethodProvider allows a provider to take more active control over dispatching a CIM method call.
Query Processing
• The WHERE clause can be processed into a necessary condition for any variable
• Providers already know how to optimize their search based on conditions, without additional work
• The condition tends to be more specific if other variables’ values can be assumed, so…
• The query engine tries to be clever in ordering query variables
• Query engine recursively processes query variables to achieve effect of nested loops
select hba.index, port.index
from AixHbaPort port,
AixHostBusAdapter hba,
AixHbaControlledBy cb
where hba.manufacturer = “QLogic”
and port = cb.dependent
and hba = cb.antecedent
Query Processing
Pseudo-code for execution plan:foreach (hba such that
manufacturer = “Qlogic”){
foreach (cb such that antecedent = hba){
// port is uniquely// determinedlet port =
cb.dependent;
produce(hba.index, port.index);
}}
select hba.index, port.index
from AixHbaPort port,
AixHostBusAdapter hba,
AixHbaControlledBy cb
where hba.manufacturer = “QLogic”
and port = cb.dependent
and hba = cb.antecedent
The CXWS Eco-System
• CXWS framework• CIM-XML over HTTP
servlet (DSP0200, DSP0201)
• CIM-RMI interface (JSR-47)
• Streaming RMI interface for CIMOM
• RMI interface for host agents
• MOF compiler• Query engine
• Simple instance repository
• JwsProviderConverter adapts Java WBEM Services (JWS) providers to CXWS
• Reflective CIM model for controlling the CIMOM
• Interface generator for constructing Java interfaces from CIM class definitions
Cxws_ClassToProvider
Management of CXWS is performed by operating on a CIM model of CXWS itself, in the root/reflection namespace:
• All CIM classes modeled as instances of the CIM class CXWS_Class.
• All Java provider instances exposed by CXWS_Provider CIM class.
• Creating an instance of CXWS_ClassToProvider association actually binds a CIM class to its provider.
• Separates provider from CIM class definition
CXWS_ClassToProvider Example
#pragma namespace("root/reflection")
instance of CXWS_ClassToProvider
{
Antecedent = "root/reflection:CXWS_Provider." "JavaName=\"com.appiq.cimom.aix.AixComputerSystemProvider\"";
Dependent = "root/reflection:CXWS_Class."
"NamespaceName=\"root/cimv2\","
"Name=\"APPIQ_AixComputerSystem\"";
};
Generated Provider Interface
• Automated tool generates Java symbolic constants from CIM namespace:o Class nameso Property nameso ValueMap values
• Also generates static members for the class and property objects, not just names.
Generated Interface
/**** Interface file generated from CIM class definition
for APPIQ_AixComputerSystem ****/
public interface AixComputerSystemProviderInterface extends Provider
{
public static final String APPIQ_AIX_COMPUTER_SYSTEM = "APPIQ_AixComputerSystem";
. . .
public static final String CREATION_CLASS_NAME = "CreationClassName";
public static final String DEDICATED = "Dedicated";
public static final UnsignedInt16 DEDICATED_ACCESS_SERVER = new UnsignedInt16(9);
. . .
public static final String _CLASS = "APPIQ_AixComputerSystem";
public static final String _NAMESPACE = "root/cimv2";
public static final String _SUPER = "APPIQ_ComputerSystem";
public static final CxNamespace _namespace =
CxNamespace.getExistingNamespaceOrNull(_NAMESPACE);
public static final CxClass _class = _namespace.getExpectedClass(_CLASS);
public static final CxProperty caption = _class.getExpectedProperty(CAPTION);
public static final CxProperty description = _class.getExpectedProperty(DESCRIPTION);
. . .
}