Extended instances

In the old Common Data Model, the large chunks of data had to be split into the key-value pairs and stored as extended attributes. Now you can use extended instances for storing large content, thanks to which you do not need to create a large number of extended attributes. You can store low-level objects as extended instances and attach them to top-level objects, which are CIs, as raw or preprocessed data.

Data model type

The structure of the XD attribute is a simple sequence of XML elements. Every model object type has the XD attribute of a new Java ExtendedInstanceData type. This type allows for storing any type of content, for example plain text, like command output, XML, CSV, or CDATA.

You can group extended instances by type, the default type is General.

Viewing extended instances

After you run a discovery of a sensor, for which you specified the XD attribute, you can view extended instances in Data Management Portal. Open the Details pane of a discovered object. Each extended instance type is displayed on a separate tab.

Example of usage in a sensor

The following example shows the ExtendedInstanceData type that is used to store raw content. The lsofOutput and ifconfigOutput variables are the string variables that store command outputs. In this example, the outputs are not processed, but they can be formatted as an XML or JSON.
        SComputerSystem scs = ModelFactory.newInstance(SComputerSystem.class);
        scs.setHierarchyDomain("sys.unix.linux");
        scs.setHierarchyType("RedHat");
        scs.setManufacturer("RedHat");
        scs.setModel("Linux");
        scs.setSerialNumber("as00123012");

        ExtendedInstanceData xd = new ExtendedInstanceData();
        xd.addInstance("lsof", lsofOutput);
        xd.addInstance("ipInterfaces", ifconfigOutput);
        xd.addInstance(null, "Linux vmw009128109120 2.6.32-220.el6.x86_64 #1 SMP Wed Nov 9 08:03:13 EST 2011 x86_64 x86_64 x86_64 GNU/Linux");
        scs.setXD(xd);
As a result, the following map of attributes with the XD attribute filled with correct XML is stored. The XML creates elements for the instance type with the elements of raw data of the same type inside, enclosed by <instance>. The instance that is created with the null type is placed in the default type <general>.
manufacturer -> RedHat
hierarchyType -> RedHat
XD -> <xml>
	<general>
		<instance>Linux vmw009128109120 2.6.32-220.el6.x86_64 #1 SMP Wed Nov 9 08:03:13 EST 2011 x86_64 x86_64 x86_64 GNU/Linux</instance>
	</general>
	<ipInterfaces>
		<instance>eth4      Link encap:Ethernet  HWaddr 00:50:56:00:72:92
          inet addr:9.128.109.120  Bcast:9.128.109.255  Mask:255.255.255.0
          inet6 addr: fe80::250:56ff:fe00:7292/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:805298636 errors:0 dropped:0 overruns:0 frame:0
          TX packets:665767802 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:590819760949 (550.2 GiB)  TX bytes:272393336858 (253.6 GiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:833223633 errors:0 dropped:0 overruns:0 frame:0
          TX packets:833223633 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:594042898379 (553.2 GiB)  TX bytes:594042898379 (553.2 GiB)

		</instance>
	</ipInterfaces>
	<lsof>
		<instance>pickup    31017   postfix  mem       REG                8,2  1580928    1066619 /usr/lib64/mysql/libmysqlclient.so.16.0.0
              pickup    31017   postfix  mem       REG                8,2   184088     139800 /lib64/libpcre.so.0.0.1
              pickup    31017   postfix  mem       REG                8,2    63304     139295 /lib64/liblber-2.4.so.2.5.6
              pickup    31017   postfix  mem       REG                8,2   308912     130952 /lib64/libldap-2.4.so.2.5.6
              pickup    31017   postfix  mem       REG                8,2   156872     130819 /lib64/ld-2.12.so
              pickup    31017   postfix    0u      CHR                1,3      0t0       3640 /dev/null
              pickup    31017   postfix    1u      CHR                1,3      0t0       3640 /dev/null
              pickup    31017   postfix    2u      CHR                1,3      0t0       3640 /dev/null
              pickup    31017   postfix    3r     FIFO                0,8      0t0      10751 pipe
              pickup    31017   postfix    5u     unix 0xffff8802350d9c80      0t0      10659 socket
              pickup    31017   postfix    6u     FIFO                8,2      0t0     392456 /var/spool/postfix/public/pickup
              pickup    31017   postfix    7u     unix 0xffff8802378e8680      0t0   49305400 socket
              pickup    31017   postfix    8u      REG                0,9        0       3638 anon_inode
              loop0     31473      root  cwd       DIR                8,2     4096          2 /
              loop0     31473      root  rtd       DIR                8,2     4096          2 /
              loop0     31473      root  txt   unknown                                       /proc/31473/exe
		</instance>
	</lsof>
</xml>
serialNumber -> as00123012
isPlaceholder -> false
hierarchyDomain -> sys.unix.linux
model -> Linux

The preceding example uses the simplest addInstance methods. It is advised to use the addInstance(String type, INSTANCE_FORMAT format, boolean isVisible, String content) method that enables the control of two XML attributes of the <instance> element.

The first XML attribute is format, which is used to interpret the content. INSTANCE_FORMAT is a Java enum with the following possible values: plain, XML, CSV, JSON, CDATA.

The second XML attribute is visible, which is used when some instances are not displayed in the UI.

Example:
<general><instance format="plain" visible="false">Linux vmw009128109120 2.6.32-220.el6.x86_64 #1 SMP Wed Nov 9 08:03:13 EST 2011 x86_64 x86_64 x86_64 GNU/Linux</instance></general>

Partial update

A CI can be stored with the same naming rules values from different data sources, and as a result the values are merged into one object. To prevent that, partial update mechanism is used to merge two different XML-formatted XD attributes. For example, if one source is stored with object 1, and another source is stored with object 2, a CI that holds the merged attribute is created.
Object 1
        SComputerSystem xd1 = ModelFactory.newInstance(SComputerSystem.class);
        xd1 = ModelFactory.newInstance(SComputerSystem.class);
        xd1.setHierarchyDomain("sys.unix.linux");
        xd1.setHierarchyType("RedHat");
        xd1.setManufacturer("RedHat");
        xd1.setModel("Linux");
        xd1.setSerialNumber("as00123012xd");

        ExtendedInstanceData xdone = new ExtendedInstanceData();
        xdone.addInstance("lsof", "content from CI1");
        xdone.addInstance(null, "content from CI1");
        xd1.setXD(xdone);
Object 2
        SComputerSystem xd2 = ModelFactory.newInstance(SComputerSystem.class);
        xd2 = ModelFactory.newInstance(SComputerSystem.class);
        xd2.setHierarchyDomain("sys.unix.linux");
        xd2.setHierarchyType("RedHat");
        xd2.setManufacturer("RedHat");
        xd2.setModel("Linux");
        xd2.setSerialNumber("as00123012xd");

        ExtendedInstanceData xdtwo = new ExtendedInstanceData();
        xdtwo.addInstance("ips", "content from CI2");
        xdtwo.addInstance(null, "content from CI2");
        xd2.setXD(xdtwo);
Merged attribute
manufacturer -> RedHat
hierarchyType -> RedHat
XD -> <xml>
	<general>
		<instance>content from CI2</instance>
	</general>
	<lsof>
		<instance>content from CI1</instance>
	</lsof>
	<ips>
		<instance>content from CI2</instance>
	</ips>
</xml>
serialNumber -> as00123012xd
isPlaceholder -> false
hierarchyDomain -> sys.unix.linux
model -> Linux
All not overlapping attributes from the first object and the second object are present with their values in the merged attribute and the general type has the instances from the object that was stored as last. The partial update for the XD attribute of every model object is made with respect to an instance type.

MQL queries with EVAL operator (XA and XD attributes only)

Many CDM attributes are moved into XML content of the XA or XD attributes. Therefore, MQL syntax supports a new operator eval, which can be added in the where clause. The eval operator enables querying CIs by the values of extended attributes or extended instances.

Note: All MQL queries examples contain escaped quotation marks (\"value\") because it is assumed that the queries are run in the following manner:
./api.sh -u username -p password find "MQL query"
For example, the following query was run to find a computer system with the productID attribute set to 'prod1':
SELECT * FROM ComputerSystem WHERE productID == 'prod1'
The following equivalent query uses the eval operator:
SELECT * FROM ComputerSystem WHERE XA eval '/xml[attribute[@category=\"taddm_global\" and @name=\"productID\"]=\"prod1\"]'
The eval operator can be followed by any valid XPath expression that returns Boolean true or false value to enable the performance of correct SQL filtering by the persistence layer.
More examples
  • Find all ComputerSystems, which have any extended attribute with the val value:
    • MQL:
      SELECT * FROM ComputerSystem WHERE XA eval '/xml[attribute=\"val\"]' 
    • SQL:
      SELECT * FROM compsys WHERE xmlexists('$c/xml[attribute="val1"]' passing compsys.xa_x as "c")
  • Find a ComputerSystem with the attr2 extended attribute, which has the category set to Other and value set to two:
    • MQL:
      SELECT * FROM ComputerSystem WHERE XA eval '/xml/attribute[@name=\"attr2\" and @category=\"Other\" and text()=\"two\"]'
    • SQL:
      SELECT * FROM compsys WHERE xmlexists('$c/xml/attribute[@name="attr2" and and @category="Other" and text()="two"]' passing compsys.xa_x as "c")