I have a mapping table which contains the employee types and the
resources that each has access to. This is something like

<?xml version="1.0" encoding="UTF-8"?><mapping-table>
<col-def name="EmployeeType" type="nocase"/>
<col-def name="EmployeeTypeCode" type="numeric"/>
<col-def name="eDirAccess" type="numeric"/>
<col-def name="UnixAccess" type="numeric"/>
<col-def name="ADAccess" type="numeric"/>
<col-def name="EmailAccess" type="numeric"/>
<row>
<col>Full Time</col>
<col>1</col>
<col>1</col>
<col>1</col>
<col>1</col>
<col>1</col>
</row>
<row>
<col>Part Time</col>
<col>2</col>
<col>1</col>
<col>0</col>
<col>0</col>
<col>1</col>
</row>
<row>
<col>Temporary</col>
<col>3</col>
<col>1</col>
<col>0</col>
<col>0</col>
<col>0</col>
</row>
</mapping-table>l

This equates to the following table where a 1 means 'access' and 0
means 'no access'.

EmployeeType
EmployeeTypeCode eDirAccess UnixAccess ADAccess EmailAccess
Full Time 1 1 1 1 1
Part Time 2 1 0 1 1
Temporary 3 1 0 0 0

When a change is made to the employeeType, a check needs to be done to
see if there is a change to the access of a resource. In some
instances, this would mean removing access. For example, a Part Time
employee who becomes Temporary, loses access to both AD and Email.
There may be business rules that dictate how these changes must be
handled. What I want to do is to identify the accounts that lose access
to a resource and set up Workorder objects to process them.

In order to do this, I need to read all entries in the row before the
change takes place and compare that with the entries in the row
corresponding to the new employeeType. This should then give me a list
of resources that need to be processed for each account.

A very important consideration is that this code is scalable. I can
add, or remove, rows or columns to the table without making any changes
to the code. I try to design code that requires the minimum amount of
maintenance.

At first sight the solution appears to be the transpose of the
situation described in Extracting Data from a Mapping Table Part 1.

So,
<do-set-local-variable name="lv-Data" scope="policy">
<arg-node-set>
<token-xpath expression="$lv-Nodes//col/row[1]"/>
</arg-node-set>
</do-set-local-variable>

gives all the values in the row labelled Full Time. I can do the same
for the Part Time and Temporary rows.

I could store each of these in a local variable and then use them to
check the changes but this does not scale well. The mapping table I am
using has more than 40 rows in it. The other problem with this is that
having done the comparison, I need to store the results somewhere so
that each account can then have the correct Workorders created.

Something else to be remembered is that the same calculation is being
done every time the policy is used. This becomes very inefficient if
the local variables have to be calculated each time. The answer to this
is to use local variables with 'Driver Scope'. The first time the
policy is used after the driver is started, the local variables are
calculated. Thereafter, they are read from (cache?) memory.

What I decided the best approach to be was to read in the column
headers, do the comparisons and store the names of the columns, where
the use of a resource was removed, in a local variable

If you look at the XML for the mapping table above, you will see that
each column is defined by an entry similar to

<col-def name="EmployeeType" type="nocase"/>

I could extract all the <col-def> entries in my nodeset and use that.
However, notice that all the entries defining access to a resource are
numbers (0, 1 and possibly other values). I can reduce the number of
columns that I have to inspect by filtering out all the columns that are
not numeric. More precisely, selecting the numeric columns only.

WARNING: Text is embedded in the code below. This must be removed
before pasting into a policy. The text is indicated by the ellipses
(...)

<rule>
<comment xml:space="preserve">This policy must be the first for the
policy set because it makes changes that could influence those that
follow.
If the EmployeeType changes so that access to a resource is no longer
available, the existing use of that resource needs to be
removed.</comment>
<conditions>
<and/>
</conditions>
<actions>
<do-if>
<arg-conditions>
<and>
<if-local-variable name="lv-dr-ETAccess" op="not-available"/>

This local variable has driver scope so it can be used to check to see
if this policy has been run since starting the driver. If it has, this
local variable will contain the nodeset for the data extracted from the
mapping table. If not, calculate it ...

</and>
</arg-conditions>
<arg-actions>
<do-set-local-variable name="lv-Nodes" scope="policy">
<arg-string>
<token-base64-decode>
<token-src-attr name="DirXML-Data">
<arg-dn>
<token-global-variable name="gv-MappingTablePath"/>
<token-text xml:space="preserve">\EmployeeTypes</token-text>
</arg-dn>
</token-src-attr>
</token-base64-decode>
</arg-string>
</do-set-local-variable>
<do-set-local-variable name="lv-Nodes" scope="policy">
<arg-node-set>
<token-xml-parse>
<token-local-variable name="lv-Nodes"/>
</token-xml-parse>
</arg-node-set>
</do-set-local-variable>

as in Part 1, do a Base 64 conversion and then parse the result ...


<do-set-local-variable name="lv-dr-ETAccess" scope="driver">

Make sure the scope is defined as 'driver' ...

<arg-node-set>
<token-xpath expression="$lv-Nodes//col-def[@type='numeric']"/>
</arg-node-set>
</do-set-local-variable>

select all those columns that are of type numeric. Note that we are
using the <col-def> label not the <row> or <col> label. This is found
by looking at the XML for the mapping table. The XML also shows us the
type of attributes we can search on : name or type. In this instance we
require type. This expression will return all the nodes that have a
type of numeric ...

</arg-actions>
<arg-actions/>
</do-if>
<do-set-local-variable name="lv-dr-ChangeAccess" scope="driver">
<arg-string/>
</do-set-local-variable>

set up local variable that will contain list of resources that the
account no longer needs. This must have scope driver if it is to be
used in other policies in this policy set ...

<do-for-each>
<arg-node-set>
<token-local-variable name="lv-dr-ETAccess"/>
</arg-node-set>
<arg-actions>
<do-set-local-variable name="lv-Access" scope="policy">
<arg-string>
<token-xpath expression="$current-node//@name"/>

Get the name of the column from the current node ...

</arg-string>
</do-set-local-variable>
<do-set-local-variable name="lv-old-ITAccess" scope="policy">
<arg-string>
<token-map default-value="0" dest="$lv-Access$"
src="EmployeeTypeCode" table="..\..\VaultLibrary\EmployeeTypes">
<token-removed-attr name="employeeType"/>
</token-map>
</arg-string>
</do-set-local-variable>

get the resource access value for the old (removed) EmployeeTypeCode
by using the map token...

<do-if>
<arg-conditions>
<and>
<if-local-variable mode="nocase" name="lv-old-ITAccess"
op="lt">1</if-local-variable>

if the returned value is 1 this means that the account had access to
that resource. This also means that a check needs to be done to see if
the new EmployeeType no longer requires this resource ...

</and>
</arg-conditions>
<arg-actions/>
<arg-actions>
<do-set-local-variable name="lv-ITAccess" scope="policy">
<arg-string>
<token-map default-value="0" dest="$lv-Access$"
src="EmployeeTypeCode" table="..\..\VaultLibrary\EmployeeTypes">
<token-src-attr name="employeeType"/>
</token-map>
</arg-string>
</do-set-local-variable>

do the same for the new EmployeeType, again using the map token ...


<do-if>
<arg-conditions>
<and>
<if-local-variable mode="nocase" name="lv-ITAccess"
op="not-lt">1</if-local-variable>
</and>
</arg-conditions>

we are only interested in situations where the resource access value
is not 0 ...

<arg-actions/>
<arg-actions>
<do-set-local-variable name="lv-dr-ChangeAccess"
scope="driver">
<arg-string>
<token-local-variable name="lv-dr-ChangeAccess"/>
<token-text xml:space="preserve">-</token-text>
<token-local-variable name="lv-Access"/>
</arg-string>
</do-set-local-variable>
</arg-actions>

Store the name of the resource in the local variable, making sure
that the scope is set to driver. This is because the variable is used
by other policies in this driver set ...

</do-if>
</arg-actions>
</do-if>
</arg-actions>
</do-for-each>
<do-if>
<arg-conditions>
<and>
<if-local-variable mode="nocase" name="lv-dr-ChangeAccess"
op="equal"/>
</and>
</arg-conditions>
<arg-actions>
<do-break/>

break if no resources are to be removed ...

</arg-actions>
<arg-actions/>
</do-if>
</actions>
</rule>


Code to create Workorders follows ...


--
chall
------------------------------------------------------------------------
chall's Profile: http://forums.novell.com/member.php?userid=34675
View this thread: http://forums.novell.com/showthread.php?t=429488