How to use complex queries on IDM


IDM allow running queries.

You can run queries using the “Query” noun from the policy builder.

For example, you can query all users from department number 8 and get some attributes for each one of them:



<do-set-local-variable name="lv.queryResultNS" scope="policy"> <arg-node-set> <token-query> <arg-match-attr name="departmentNumber"> <arg-value type="string"> <token-text xml:space="preserve">8</token-text> </arg-value> </arg-match-attr> <arg-string> <token-text xml:space="preserve">mobile</token-text> </arg-string> </token-query> </arg-node-set> </do-set-local-variable>



The Problem:

The query noun is that it only allow you to use a simple query condition based on “and” values. If for example we want to query all users from department 8 or 9, we cannot do that.


The solution:

The IDM NDS DTD of query allows to use the query operation with options that are not available on the policy builder.

The following example policy runs a query with an “or” condition using XdsQueryProcessor:



<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE policy PUBLIC "policy-builder-dtd" "D:\netiq\idm\apps\Designer\plugins\com.novell.idm.policybuilder_4.0.0.201802280016\DTD\dirxmlscript4.7.dtd"><policy> <rule> <description>Query example</description> <conditions> <and/> </conditions> <actions> <do-set-local-variable name="lv.queryResultNS" scope="policy"> <arg-node-set> <token-xml-parse> <token-text xml:space="preserve">&lt;nds dtdversion="4.0" ndsversion="8.x"> </token-text> <token-text xml:space="preserve">&lt;source> </token-text> <token-text xml:space="preserve">&lt;product edition="Advanced" version="">DirXML&lt;/product> </token-text> <token-text xml:space="preserve">&lt;contact>NetIQ Corporation&lt;/contact></token-text> <token-text xml:space="preserve">&lt;/source> </token-text> <token-text xml:space="preserve">&lt;input> </token-text> <token-text xml:space="preserve">&lt;query scope="subtree" dest-dn="\ </token-text> <token-global-variable name=""/> <token-text xml:space="preserve">\</token-text> <token-global-variable name="gcv.usersOU"/> <token-text xml:space="preserve">"> </token-text> <token-text xml:space="preserve">&lt;search-class class-name="User"/> </token-text> <token-text xml:space="preserve">&lt;read-attr attr-name="mobile"/> </token-text> <token-text xml:space="preserve">&lt;search-condition name="or"> </token-text> <token-text xml:space="preserve">&lt;search-attr attr-name="departmentNumber"> </token-text> <token-text xml:space="preserve">&lt;value type="string">1&lt;/value></token-text> <token-text xml:space="preserve">&lt;/search-attr> </token-text> <token-text xml:space="preserve">&lt;search-attr attr-name="departmentNumber"> </token-text> <token-text xml:space="preserve">&lt;value type="string">1&lt;/value></token-text> <token-text xml:space="preserve">&lt;/search-attr> </token-text> <token-text xml:space="preserve">&lt;/search-condition> </token-text> <token-text xml:space="preserve">&lt;/query> </token-text> <token-text xml:space="preserve">&lt;/input> </token-text> <token-text xml:space="preserve">&lt;/nds></token-text> </token-xml-parse> </arg-node-set> </do-set-local-variable> <do-set-local-variable name="lv.queryResultNS" scope="policy"> <arg-node-set> <token-xpath expression="query:query($srcQueryProcessor,$lv.queryNS)"/> </arg-node-set> </do-set-local-variable> <do-trace-message> <arg-string> <token-text xml:space="preserve">Got query result: </token-text> <token-xml-serialize> <token-local-variable name="lv.queryResultNS"/> </token-xml-serialize> </arg-string> </do-trace-message> <do-if> <arg-conditions> <and> <if-xpath op="true">count($lv.queryResultNS//*[@class-name="User"]/@qualified-src-dn) > 0</if-xpath> </and> </arg-conditions> <arg-actions> <do-trace-message> <arg-string> <token-text xml:space="preserve">Here you can handle the results</token-text> </arg-string> </do-trace-message> </arg-actions> <arg-actions/> </do-if> </actions> </rule> </policy>




** If you want to query destination instead of source datastore, use destQueryProcessor  instead of srcQueryProcessor.

** There are much other options available in the query command which are well documented in the DTD, for example, using "not" condition, scope and more.


How To-Best Practice
Comment List
  • A couple of comments on your post.

    First off, reading your post makes it seem like this is only for Query-ex.  But Query-ex and Query are basicalaly the same thing, just query-ex supports paged queries (if the shim supports it.  The Driver Identification query at startup answers that question to the engine, so not every driver).

    Second the -results does not mean what you think it means.  It defines the page size, not the total results returned.  using max-results=1 is a terrible idea as if you had 1000 response, you would get 1000 pages of 1 entry.

    On the other hand, you are correct that in DTD for Query as of 4.7 adds some new options, which disappointing are not made available in Policy Builder yet (as far as I know).  You have to buld the XML yourself which sucks, since Designer would re-write it to match what it knows if you touched it in Designer.