Overview

This document describes the system-scoped model for management of devices (i.e. device root control units) and their components (i.e. component control units) within the scope of the entire RM system.

The common principles and concepts of RM device management are described in Conceptual Guide and in the Device Management Overview document from the Developer Guide.

Getting the Device Manager

The main component of the Device Manager API is the com.prosyst.mprm.admin.devices.DeviceManager, whose methods should be called by applications using the system-scoped management model. A reference to DeviceManager can be requested by a backend bundle residing on a RAS framework or on the CC OSGi framework or by an application running a RAC. Refer to "Getting the Device Manager"section from Common Management Principles for more details on accessing the Generic Device Manager.

Managing the Structure of the Management Tree

The DeviceManager provides convenient methods for managing the structure of the device management tree.

Nodes

The nodes of the device management tree are represented as Node objects. Basically, a Node object allows you to retrieve the path, type (group or node), properties, parent, etc. of the node in the device management tree.

  • Node type – For device nodes the node type is equal to the type of the relevant device root control unit. Device group nodes have type equal to null.

  • Node path – The node path represents the unique location of the node in the management tree. The path to the root node is equal to "ROOT".

  • Display name – The display name stands for the user-friendly name of the node, which might be shown to the user by administration applications such as the console. If needed, you can change a node's display name by using the setDisplayName(String displayName) method.

  • Node properties – Node properties are key-value pairs representing parameters used by the device provider and/or manager applications. Node properties are inheritable, that is, if a property is not defined for a node, its value is taken from its parent.

    If you are interested not only in a property's value but also if this value is inherited or is set specifically for the node, you can use the InheritableProperty instance returned by the getInteritableProperty method called on the relevant node. Otherwise, simply use the getNodeProperties or getProperty method.

    If you want to modify the properties of a node, use the setNodeProperties or setNodeProperty method. For device groups, you can also specify node properties at group creation.

Getting Notified of Tree Changes

If needed, you can implement a com.prosyst.mprm.admin.devices.event.NodeListener to receive notifications of changes in a node. The changes are carried by NodeEvent objects passed to the nodeEvent method of your Node Listener. As event source, the NodeEvent object will have the Node which is changed.

The mapping between the NodeEvents that you will receive in the Node Listener and modifications on the node of interest:

  • If the set of node properties is changed, the listener will receive an event of type NodeEvent.NODE_CHANGED.

  • If the node is removed, the listener will receive an event of type NodeEvent.NODE_REMOVED.

  • If a child node is created, the listener will receive an event of type NodeEvent.SUB_NODE_CREATED.

  • If the set of properties of a child node is modified, the listener will receive an event of type NodeEvent.SUB_NODE_CHANGED.

  • If a child node is removed, the listener will receive an event of type NodeEvent.SUB_NODE_REMOVED.

Handling Device Groups

The groups in the tree are represented as DeviceGroup objects. By using a DeviceGroup instance, you can retrieve and search for specific control units (device roots or components) within the descendants of the group. In addition, by using the methods of the super interface NodeOperations, you can launch management operations on filtered control units from the group. Regarding the tree structure, you can use the DeviceGroup instance to get, create or delete member groups.

Initially, from the Device Manager you have access only to the root by calling the getRoot method. All registered devices are direct or indirect members of the root group.

Rule Script Usage

The Script service is available in mprm/modules/m2m/groups/m2m.groups.rules.service.

Getting Control Units and Their Metadata

This section describes how to access devices and their resources as control units.

Getting Control Units

By using the Device Manager you can get control units available to the RM system by unique ID. This is done via the getControlUnit(ControlUnitID controlUnitID) method, which returns a DeviceControlUnit object.

The DeviceControlUnit object identifies a particular control unit in the RM system. It is associated with type, ID, device ID and the device type. For device root control units the type and ID are the same as, respectively, the device type and device ID.

A DeviceControlUnit extends the org.mbs.services.cu.ControlUnit interface (part of the base Control Unit Admin API) by adding features specific for the context of RM.

In addition, for device roots, which are represented as device nodes in the device management tree, the getControlUnit method returns DeviceNode objects, extending DeviceControlUnit with features related to tree nodes and to device capabilities.

You can also get the control unit types and versions stored in RM, as well as all relations among available control unit types (device-component, parent-sub and super-extending).

You can retrieve the control units available under a specific node of the device management tree by using the corresponding Node object. Most methods for getting control units return ControlUnitID objects which can be provided to the Device Manager to retrieve the actual control units (as DeviceControlUnit instances).


To get a reference to a particular device, you must first acquire reference to the root group. Once you have the root DeviceGroup object, you may search through its members for concrete control units.

Getting Control Unit Metadata

Knowing the control unit's type and its version, you can retrieve the metatype associated with it by using the getControlUnitMetadata method of Device Manager. Having a control unit metatype, your application will know a control unit's actions and state variables and will be able to correctly refer them. More information on the structure of control unit metatypes is available in the Control Unit Metatyping document.

Example of Getting Control Unit Information

The listing below illustrates getting all control units from the device management tree by using the capabilities of the tree root group. Then, the example retrieves the metatype of each control unit type and lists its state variables and actions.

  
  import java.util.Hashtable;
 
  import org.mbs.services.metatype.ObjectClassDefinitionEx;
  import org.osgi.service.metatype.AttributeDefinition;
  import org.osgi.service.metatype.MetaTypeProvider;
  import org.osgi.service.metatype.ObjectClassDefinition;
 
  import com.prosyst.mprm.admin.devices.ControlUnitID;
  import com.prosyst.mprm.admin.devices.DeviceGroup;
  import com.prosyst.mprm.admin.devices.DeviceManager;
  import com.prosyst.mprm.common.ManagementException;
  import com.prosyst.mprm.data.Enumerator;
  import com.prosyst.mprm.rac.RemoteAccessClient;
 
public class DeviceManagementTest {
  private static final String CC_URL = "socket://172.22.104.17:11449";
  private static final String USER_NAME = "system";
  private static final String USER_PASS = "system";
  RemoteAccessClient rac = null;
  DeviceManager deviceMngr = null;  
 
DeviceManagementTest(RemoteAccessClient rac) {
    this.rac = rac;
    getDeviceManager();
    listDeviceControlUnits();
  }  
 
private void getDeviceManager() {
    try {
      deviceMngr = (DeviceManager) rac.getService(DeviceManager.class.getName());
    } catch (ManagementException e) {
      e.printStackTrace();
    }  
  }  
 
private void listDeviceControlUnits() {
    String[] deviceTypes;
    try {
      //
        Retrieving all device types currently available in
        RM
      deviceTypes = deviceMngr.getDeviceTypes();
      for (int i = 0; i < deviceTypes.length; i++) {
        String[] versions = deviceMngr.getVersions(deviceTypes[i]);
        for (int j = 0; j < versions.length; j++) {
      
        // Printing the metadata of each device
        type
          printMetadata(deviceTypes[i], versions[j]);        }      }
      //
        Listing the IDs of the devices currently available in the tree
      listDeviceIds(deviceTypes);
    } catch (ManagementException e) {  
      e.printStackTrace();
    }  
}
    /**    
        * Lists the devices currently registered in the RM device management tree.
        * This method goes to the root group and launches the search there.    
        */
          private void listDeviceIds(String[] deviceTypes) {
    try {
      DeviceGroup root = deviceMngr.getRoot();
      for (int i = 0; i < deviceTypes.length; i++) {
        // Getting the devices of each supported device type
        Enumerator cus = root.getControlUnits(deviceTypes[i], null, true);
        while (cus.hasMoreElements()) {
          ControlUnitID device = (ControlUnitID) cus.nextElement();
          String id = device.getControlUnitId();
          System.out.println("[ControlUnitTest] Located device " + id);
        }
      }    
    } catch (ManagementException e) {
      e.printStackTrace();
    } catch (Exception e) {
      e.printStackTrace();
    }  
  }  /**    
       * Prints the metadata, saved in RM,      
       * for the specified control unit
        type and version.  
       */
         private void printMetadata(String cuType, String cuVersion) {
    MetaTypeProvider mtp;
    try {
      mtp = deviceMngr.getControlUnitMetadata(cuType, cuVersion);
      if (mtp == null) return;
      // Getting the control unit type definition
      ObjectClassDefinition ocd =        
      ObjectClassDefinition) mtp.getObjectClassDefinition(cuType, null);
      // Getting state variable
        AttributeDefinitions
      AttributeDefinition[] ads =        
      ocd.getAttributeDefinitions(ObjectClassDefinition.ALL);
      for (int k = 0; (ads != null) && (k < ads.length); k++) {
        System.out.println("[ControlUnitTest] variable " + ads[k].getID());
      }    
      if (ocd != null && (ocd instanceof ObjectClassDefinitionEx)) {
 
        // Getting the action ObjectClassDefinitions        
        ObjectClassDefinition[] actions =          
          ((ObjectClassDefinitionEx) ocd).getObjectClassDefinitions();
        for (int i = 0; (actions != null) && (i < actions.length); i++) {
          System.out.println("[ControlUnitTest] action " + actions[i].getID());      
         }
      }  
   } catch (ManagementException e) {
      e.printStackTrace();
    }  
   }  
  
  public static void main(String[] args) {
    Hashtable credentials = new Hashtable();
    credentials.put(RemoteAccessClient.USER_PASSWORD, USER_PASS);    
    Hashtable connProps = new Hashtable();
    connProps.put(RemoteAccessClient.CONNECT_TO_CC, "true");    
    try {
      RemoteAccessClient rac1 = RemoteAccessClient.connect(CC_URL, USER_NAME,
                                                           credentials, connProps);
      DeviceManagementTest start = new DeviceManagementTest(rac1);
    } catch (ManagementException e) {
      e.printStackTrace();    
     }  
   }
}  

Synchronizing a Control Unit's State

You can use the Device Manager to force synchronization of a control unit's state (formed by the state variable values) with the actual state of the underlying managed resource. Call the synchronizeState method of the Device Manager by specifying the ID of the target control unit.

Invoking Actions and Querying State Variables

By using the Device Manager you can invoke actions of the target control unit and query it for the current values of its state variables.

To invoke an action:

  • Call the invokeAction (ControlUnitID cuId, String actionId, Object arguments) method of DeviceManager. The method's parameters are the ID of the control unit, the action ID according to the unit's metadata and the action's input arguments.

  • Call the invokeAction method of the DeviceControlUnit instance for the target control unit. It then invokes the Device Manager's invokeAction(ControlUnitID, String, Object) method.


Querying a unit's state variables can be done by using the queryStateVariable method of DeviceControlUnit instance for the control unit.

Listening for Control Unit Events

You can add three types of listeners in the org.mbs.services.devices.event package – MPRMControlUnitListener, MPRMHierarchyListener and MPRMStateVariableListener.

Control Unit Listeners

Control unit listeners listen for newly registered or destroyed control units as well as appeared and disappeared control unit types. MPRMControlUnitListener has a single method, controlUnitEvent(ControlUnitEvent cuEvent), called by the Device Manager when a new event is available. Received events can related to control unit types and to control unit instances.

Handling Type Events

Control unit events related to types are ControlUnitEvent.CONTROL_UNIT_TYPE_APPEARED and ControlUnitEvent.CONTROL_UNIT_TYPE_DISAPPEARED.

There are two kinds of events for newly-appeared (and disappeared) types:

  • There is a new type generally in the RM system – In this case, events contain data only for the relevant type:

    • In the case of a component type – The event contains information only for the control unit type. The device type, device ID and control unit ID are null.

    • In the case of a device root type – The same as the previous case, except for the device type which is set to the value of the control unit type. This could be used by the listener to check whether the new type is a device type or a component type.

  • There is a new component type available in the scope of a specific device – This kind of events is useful in cases when a component type is registered in RM, but it is available only for specific devices. Such events contain information about the device type, device ID and control unit type, the control unit ID is null. The device type and device ID indicate the device in whose scope the new type is registered.

Handling Instance Events

Control unit events related to instances are ControlUnitEvent.CONTROL_UNIT_ADDED and ControlUnitEvent.CONTROL_UNIT_REMOVED.

Listener Registration

A control unit listener is registered using the registerControlUnitListener(String nodePath, MPRMControlUnitListener listener, Dictionary cuListenerProps) method of DeviceManager. The method takes the following arguments:

  • nodePath – The device management tree node to watch for events

  • MPRMControlUnitListener – The instance of your MPRMControlUnitListener implementation that will receive control unit events

  • cuListenerProps – Properties for filtering the control units to receive events for . cuListenerProps can have the following keys:

    • org.mbs.services.cu.ControlConstants.EVENT_FILTER – A String representation of an LDAP filter for specifying control unit types and IDs to receive events from. Filtering is done on the basis of the org.mbs.services.cu.ControlConstants.TYPE, org.mbs.services.cu.ControlConstants.ID,  and org.mbs.services.cu.ControlConstants.VERSION and org.mbs.services.cu.ControlConstants.EVENT_TYPE search attributes.

      For example:

      String LISTENER_FILTER = "(&(" + ControlConstants.TYPE + "=my.device.cu)(" + ControlConstants.EVENT_TYPE + "=" + ControlUnitEvent.CONTROL_UNIT_ADDED + "))"; Hashtable cuListenerProps = new Hashtable(); cuListenerProps.put(ControlConstants.EVENT_FILTER, LISTENER_FILTER);

      A control unit listener with no filter specified receives all types of events for all control units.

State Variable Listeners

State variable listeners listen for changes in the values of the state variables of control units. Such a listener can be registered by using the registerStateVariableListener(String nodePath, MPRMStateVariableListener listener, Dictionary svListenerProps) method of DeviceManager.

  • The nodePath parameter defines the location in the device management tree which the listener will receive events from.

  • The listener parameter represents the instance of the your MPRMStateVariableListener implementation that will process received state variable events.

  • The svListenerProps parameter contains the listener's properties for filtering and synchronous receipt, which are similar to the ones of the control unit listener discussed above. In addition to these common filter attributes, a state variable listener can also specify the IDs of state variables of interest by including the org.mbs.services.cu.ControlConstants.STATE_VARIABLE_ID search attribute in the ControlConstants.EVENT_FILTER filter property.


The MPRMStateVariableListener has a single method: stateVariableChanged(StateVariableEvent svEvent), called by the Device Manager when a new event suitable for this listener becomes available.

Hierarchy Listeners

Hierarchy listeners receive events for changes in the hierarchy of specific control units.

There are no hierarchy events at the registration of a new control unit although there is a change in the overall control unit hierarchy of the device. Hierarchy events are fired when there is a new hierarchy relation for an existing control unit.

You can register a hierarchy listener by calling the registerHierarchyListener method of the Device Manager. Similarly to the methods for registration of control unit listeners and state variable listeners you should provide as arguments the device tree node of interest, the MPRMHierarchyListener instance that will receive the events and registration properties. Besides the control unit type, ID and version, the LDAP filter of the ControlConstants.EVENT_FILTER registration property can contain the following search attributes:

  • org.mbs.services.cu.ControlConstants.EVENT_TYPE – Specifies whether to receive events for attached or detached parents of a control unit, or for both. This attribute can be related to com.prosyst.mprm.admin.devices.event.HierarchyEvent.ATTACHED or com.prosyst.mprm.admin.devices.event.HierarchyEvent.DETACHED.

  • org.mbs.services.cu.ControlConstants.PARENT_TYPE and org.mbs.services.cu.ControlConstants.PARENT_ID – Specifies the type and ID of parent control units for whose subcomponents to receive events.


The MPRMHierarchyListener owns a single method, hierarchyChanged, which the Device Manager calls when there are changes in the hierarchy of the watched control units.

Creating, Destroying and Searching for Control Units

If a Control Unit Provider, associated with a specific control unit type, has defined constructor or destructor actions, you can call them from RM through the Device Manager. Depending on the provider type, these actions may result in registering or unregistering a device or in simply creating or destroying a device resource.

Invocation of such predefined actions is done by calling specific method in Device Manager:


Provider Action

Method in Control Unit Manager

Description

Constructor

createControlUnit(String nodePath, String controlUnitType, String constructorId, Object arguments)

Creates a control unit of the specified type, by using the specified constructor and arguments and within a specific node (group or device) of the device management tree.

Destructor

destroyControlUnit(ControlUnitID cuId)

Destroys a control unit instance, specified as a ControlUnitID.

Using Dynamic Device Groups

Dynamic device groups are special nodes in the device management tree whose members are not fixed – members might be dynamically added or removed as a result from applying a control unit filter on the devices within certain device groups.

Dynamic device groups provide a flexible and convenient way for managing registered devices. They allow you to select devices on criteria other than the path one, without having to write a script rule. The members of a dynamic group are those which fully match the applied search filter and are placed in the group's base path from the device management tree.

In the Device Manager API, dynamic device groups are represented as com.prosyst.mprm.admin.devices.DynamicDeviceGroup objects which are associated with name, base node holding the relevant dynamic group and a search filter following the syntax of the "RM Management Script".

To create a dynamic device group call the createDynamicDeviceGroup method of the Device Manager. As a result, a new DynamicDeviceGroup will be created with no filter and no base node, that is, all devices under the root of the device tree will participate in the new dynamic group.

You can specify a filter and a base node by using respectively the setControlUnitsFilter method and the setBaseNode one.

To retrieve information about the control units (device roots or components) of a certain type available on the devices members of a dynamic group by calling the getCurrentMemberControlUnits method of the DynamicDeviceGroup. The method will return a com.prosyst.mprm.data.Enumerator of ControlUnitID objects.

To get the dynamic device groups defined in RM use the listDynamicDeviceGroups and getDynamicDeviceGroup methods of the Device Manager.