Provides information about remote configuring of the FIM module. The Device Inventory API allows developers to access and remotely manage Functional Items registered on OSGi gateways connected to the Remote Manager. It lays on top of the Functional Items control unit representation and provides a more convenient Java management API.
Overview
In the Device Inventory API remotely managed items are represented by objects implementing the com.prosyst.mprm.admin.devices.inventory.FunctionalItemEx interface. This interface extends com.prosyst.mbs.services.fim.FunctionalItem, but in contrast to the functional items that are being registered on OSGi gateways – FunctionalItemEx objects do not implement (and therefore cannot be cast to) concrete object classes (like BinarySwitch, Alarm, etc). Instead generic methods for getting/setting property values and invoking operations are provided:
- Object getProperty(String property)
- setProperty(String property, Object value)
- Object invokeOperation(String operation, Object... parameters)
All values returned by these methods are represented in valid control unit types and all values passed as arguments to them should also be represented as valid control unit types.
The following conversions apply:
- Primitive types are represented as their boxed counterparts
- Objects implementing java.util.Collection are represented as arrays
- Objects implementing java.lang.Enum are represented with the corresponding java.lang.Enum.name() value
- Objects implementing java.util.Map are represented as java.util.Dictionary
- Beans are represented as java.util.Dictionary with entry for each field
- Objects implementing FunctionalItem interface are represented as a single-element java.util.Dictionary with property name FunctionalItem.UID and value – the UID of the functional item
To illustrate the specifics of using Device Inventory for FI Management compared to the OSGi Framework FI management, two examples are provided – Working with Functional Items on OSGi Framework and Working with Functional Items through Device Inventory.
The examples use the functional items provided by "Functional Item Management Demo Simple"'s Gateway Software package, which can be installed on the Gateway Software using the following command:
kitman.i "Functional Item Management Demo Simple"
Working with Functional Items on OSGi Framework:
import java.util.Arrays;import org.osgi.framework.BundleActivator;import org.osgi.framework.BundleContext;import org.osgi.framework.ServiceReference;import com.prosyst.mbs.fim.demo.MemberAdmin;import com.prosyst.mbs.fim.demo.MemberBean;... private BundleContext bc;... ServiceReference reference = bc.getServiceReference(MemberAdmin.class.getName()); MemberAdmin admin = (MemberAdmin)bc.getService(reference); MemberBean[] members = admin.getMembers(); System.out.println(Arrays.toString(members)); admin.addMember( new MemberBean( "Alice", 33));...Working with Functional Items through Device Inventory:
import java.util.Arrays;import java.util.Dictionary;import java.util.Hashtable;import com.prosyst.mbs.fim.demo.MemberAdmin;import com.prosyst.mprm.admin.devices.inventory.DeviceInventory;import com.prosyst.mprm.admin.devices.inventory.FunctionalItemEx;import com.prosyst.mprm.admin.devices.inventory.FunctionalItemGUID;import com.prosyst.mprm.admin.devices.inventory.Gateway;import com.prosyst.mprm.data.Enumerator;... private DeviceInventory di;... Gateway gw = di.getGateway(gatewayID); FunctionalItemEx memberAdmin = getFirstFunctionalItem(gw, MemberAdmin.class.getName()); @SuppressWarnings( "unchecked") Dictionary< String, Object>[] members = (Dictionary< String, Object>[])memberAdmin.getProperty( "members"); System.out.println(Arrays.toString(members)); Dictionary< String, Object> member = new Hashtable< String, Object>(); member.put( "name", "Bob"); member.put( "age", 23); memberAdmin.invokeOperation( "addMember", member);... /** * Returns the first found functional item with given object class. * * @param objectClass * object class * @ return functional item with the given object class or null if no such functional item is found * @ throws Exception */ private static FunctionalItemEx getFirstFunctionalItem(Gateway gw, String objectClass) throws Exception { Enumerator<FunctionalItemGUID, Exception> ids = gw.listFunctionalItems(objectClass, null); try { return ids.hasMoreElements() ? gw.getFunctionalItem(ids.nextElement().getUID()) : null; } finally { ids.close(); } }- The interface com.prosyst.mprm.admin.devices.inventory.Gateway abstracts a connected OSGi gateway with support for Remote Functional Items Management. It provides methods for – listing the installed functional items, subscribing for Functional Item events and for obtaining beans and functional items metadata.
- The com.prosyst.mprm.admin.devices.inventory.DeviceInventory interface provides methods for – listing all functional items accessible through RM, listening FIM events from all connected gateways and for listing all connected OSGi gateways with Remote FIM support. This interface is the entry point for Remote Functional Item management.
- The class com.prosyst.mprm.admin.devices.inventory.FunctionalItemGUID is used to uniquely identify functional items in the scope of RM. It holds the ID of the gateway on which the functional item resides and the UID of the functional item, which is unique in the scope of that particular gateway. The pair gateway ID and item UID is unique in the scope of RM. All device inventory methods for listing functional items return enumerations of FunctionalItemGUID objects.
Getting the Device Inventory
The Device Inventory interface is registered as a service on the back-end (CC, RAS and MS) OSGi frameworks (by packages/osgidm/m2m.di.ms.jar bundle).
Getting Device Inventory as OSGi service:
import org.osgi.framework.BundleActivator;import org.osgi.framework.BundleContext;import org.osgi.framework.ServiceReference;import com.prosyst.mprm.admin.devices.inventory.DeviceInventory;... private DeviceInventory deviceInventory; private ServiceReference reference; public void start(BundleContext bc) throws Exception { reference = bc.getServiceReference(DeviceInventory.class.getName()); deviceInventory = (DeviceInventory)bc.getService(reference);}
If you are developing a remote-to-backend application, get the Device Inventory service via a Remote Access Client (the service is provided by lib/rac/osgidm-rac.jar).
Getting Device Inventory as OSGi service:
import java.util.Hashtable;import com.prosyst.mprm.admin.devices.inventory.DeviceInventory;import com.prosyst.mprm.rac.RemoteAccessClient;... private static RemoteAccessClient rac; private static Hashtable credentials; private static String userName = "system"; private static String URI = "socket://localhost:11449" ; private static DeviceInventory deviceInventory; ... //Obtaining a connected RAC instance credentials = new Hashtable(); credentials.put(RemoteAccessClient.USER_PASSWORD, "system"); rac = RemoteAccessClient.connect(URI, userName, credentials, null); deviceInventory = (DeviceInventory)rac.getService(DeviceInventory.class.getName())During development lib/api/osgidm-api.jar can be used to compile applications using Device Inventory API.
Getting Device Inventory Gateways
Gateways with support for Remote FIM can be listed using the Enumerator<String, Exception> DeviceInventory.listGateways(String filter) method.
It takes an optional control unit filter argument for filtering the registered gateways. If the filter is omitted all registered gateways with Remote FIM support will be returned.
The method output is an enumerator of gateway IDs, which can be used with Gateway DeviceInventory.getGateway(String gatewayID) method. The Gateway object returned by this method can be used to manage functional items residing on the corresponding gateway.
Listing Functional Items
Functional items can be listed through the Enumerator<FunctionalItemGUID, Exception> DeviceInventory.listFunctionalItems(String objectClass, String filter) method. Which can be used to list all functional items accessible through RM.
Or Enumerator<FunctionalItemGUID, Exception> Gateway.listFunctionalItems(String objectClass, String ldapFilter) for listing functional items only in the scope of a given gateway.
Both methods have optional arguments for filtering functional items by object class and/or using LDAP filter.
List Functional Items:
import com.prosyst.mbs.fim.demo.BinarySwitch;import com.prosyst.mbs.services.fim.FunctionalItem;import com.prosyst.mprm.admin.devices.inventory.DeviceInventory;import com.prosyst.mprm.admin.devices.inventory.FunctionalItemEx;import com.prosyst.mprm.admin.devices.inventory.FunctionalItemGUID;import com.prosyst.mprm.data.Enumerator;... DeviceInventory deviceInventory;... Enumerator<FunctionalItemGUID, Exception> switches = di.listFunctionalItems(BinarySwitch.class.getName(), null); // list all binary switches Enumerator<FunctionalItemGUID, Exception> namedLamp = di.listFunctionalItems( null, "(" + FunctionalItem.NAME + "=lamp)"); // list all functional items with name "lamp" Enumerator<FunctionalItemGUID, Exception> switchesNamedLamp = di.listFunctionalItems(BinarySwitch.class.getName(), "(" + FunctionalItem.NAME + "=lamp)"); // list all binary switches with name "lamp"
These list methods return enumerators of FunctionalItemGUID objects which can be used for getting the corresponding FunctionalItemEx representation through FunctionalItemEx DeviceInventory.getFunctionalItem(FunctionalItemGUID guid).
FunctionalItemEx representation can be also obtained through FunctionalItemEx Gateway.getFunctionalItem(String uid) method, which takes as argument only the functional item UID (as it is unique in the scope of the given gateway).
Get a Functional Item:
... FunctionalItemEx itemA = deviceInventory.getFunctionalItem(guid); Gateway gateway = deviceInventory.getGateway(gatewayID); FunctionalItemEx itemB = gateway.getFunctionalItem(guid.getUID());Managing Functional Items
FunctionalItemEx extends com.prosyst.mbs.services.fim.FunctionalItem interface, so all its methods are accessible through the FunctionalItemEx representation (getName, setName, getItemMetadata, etc.). Additionally FunctionalItemEx has methods for reading/writing properties values and for invoking item operations.
Working with functional items:
FunctionalItemEx binarySwitchEx = ... //functional item of object class com.prosyst.mbs.fim.demo.BinarySwitchExt System.out.println( "Name:" + binarySwitchEx.getName()); Set< String> tags = new HashSet< String>(Arrays.asList( "switch ", "binary")); binarySwitchEx.setTags(tags); System.out.println(binarySwitchEx.getProperty( "caption")); binarySwitchEx.setProperty( "caption", "New Caption"); binarySwitchEx.invokeOperation( "operationInt", 0); int result = ( Integer)binarySwitchEx.invokeOperation( "incrementMyProperty");
FunctionalItemEx interface also provides a method for checking when a property was last synced from the gateway (long getLastPropertyUpdateTimestamp(String property)) and for triggering sync of the current item state from the gateway – void FunctionalItemEx.synchronizeState(). The later can be useful in cases when the item properties on the gateway change without the corresponding change events (com.prosyst.mbs.services.fim.FunctionalItemEventConstants.TOPIC_PROPERTY_CHANGED) being sent (i.e. "non-eventable" properties).
Events Handling
Device Inventory provides means for receiving notifications for functional item events, in similar way this is done on the OSGi Gateway – by registering object implementing org.osgi.service.event.EventHandler, which will receive org.osgi.service.event.Event with the event properties defined in the Functional Items documentation (FunctionalItem.UID, FunctionalItem.NAME, FunctionalItemEventConstants.PROPERTY_NAME, etc.). There is an additional property in events – FunctionalItemEx.GATEWAY_ID – which holds the ID of the gateway from which the event originated.
EventHandler can be registered through String DeviceInventory.addEventSubscription(String gatewayID, EventHandler handler, String[] topics, String filter) method.
The gatewayID argument specifies events from which gateway should be received.
The topics argument specifies a list of topics, from the ones listed in FunctionalItemEventConstants, for which events should be received.
The last argument, filter, is an LDAP filter over the event properties.
The method returns a subscription ID, which can be used in void DeviceInventory.removeEventSubscription(String subscriptionID) to remove the subscription.
The Gateway interface has similar methods – String addEventSubscription(EventHandler handler, String[] topics, String filter) and void removeEventSubscription(String subscriptionID) – which can be used to manage event subscriptions for events in the scope of a single gateway.
Event Subscription:
String subscriptionID = deviceInventory.addEventSubscription( null, event -> { for ( String name : event.getPropertyNames()) { System.out.println(name + ": " + event.getProperty(name)); }} , new String[] { FunctionalItemEventConstants.TOPIC_PROPERTY_CHANGED }, null); ...// do some work ...gw.removeEventSubscription(subscriptionID); //remove subscription when no longer neededUsing Functional Items in Task and Rules Scripts
Because Functional Items are represented as control units on the RM side they can be used as any other control units in Scripting and Rule-Based Management. Their alias is the simple name of the functional item interface prefixed with "FIM". For example the alias of com.prosyst.mbs.fim.demo.BinarySwitch will be "FIMBinarySwitch".
Working with functional items in scripts:
target.listFIMBinarySwitchs(null).each { println it.state}def binarySwitch = target.getFIMBinarySwitchExt( "fim:demo:BinarySwitchExt:1")binarySwitch.toggle()println binarySwitch.captiondef complex = [even:[2, 4, 6] as long[], odd:[1, 3, 5] as long[]]binarySwitch.setComplex(complex)binarySwitch.myOperationInt() { result -> println "Result:" + result}