Article

geoffc's picture
article
Reads:

4753

Score:
3
3
4
 
Comments:

0

Troubleshooting IF-THEN-ELSE Blocks with IDM Code

Author Info

24 October 2007 - 7:34am
Submitted by: geoffc

(View Disclaimer)

Problem

I was working on the Publisher Input Transform channel of an eDirectory driver, and the Password (Pub)-Sub rule, which handles sending an email on error synchronizing it to the other system to the end user. By default it sends a generic error message email. I wanted to handle a couple of different error codes. Specifically, I started testing for 16018 errors, which is "Password Minimum Life is triggered" (the UP policy says you have to wait a day between password changes).

So I copied the emailing rule and pasted it into an IF-THEN-ELSE block, having set the local variable ERROR-MESSAGES with text() of the error. This way, I could build a set of IF-THEN's to send a different email based on the actual error message. In the case of a 16018, the
message: -16018 0xFFFFC16E NMAS_E_PASSWORD_LIFE_MIN is not very helpful to an end user. So, I created a new email template that explains more clearly that the policy only allows password changes once a day, and because the user tried to soon since the last change, they should please wait and try again tomorrow.

Here is the rule that I ended up with. (I disabled the default send mail rule that comes with the driver and deleted it from the rule below to save space.)

<?xml version="1.0" encoding="UTF-8"?><policy>
<description>Email notifications for failed password
subscriptions</description>
<rule>
<conditions>
  <and>
    <if-global-variable mode="nocase"
name="notify-user-on-password-dist-failure"
op="equal">true
    </if-global-variable>
    <if-operation op="equal">status
    </if-operation>
    <if-xpath op="true">self::status[@level != 'success'][text() !=
'']/operation-data/password-subscribe-status/association[text() !='']
    </if-xpath>
  </and>
</conditions>
<actions>
  <do-set-local-variable name="ERROR-MESSAGE">
    <arg-string>
      <token-xpath expression="self::status/child::text()"/>
    </arg-string>
  </do-set-local-variable>
  <do-if>
    <arg-actions>
      <do-send-email-from-template
notification-dn="cn=security\cn=Default Notification Collection"
template-dn="Security\Default Notification Collection\Password 16018
error">
        <arg-string name="UserFullName">
          <token-dest-attr name="Full Name">
            <arg-association>
              <token-xpath
expression="self::status/operation-data/password-subscribe-status/association"/>
            </arg-association>
          </token-dest-attr>
        </arg-string>
        <arg-string name="UserGivenName">
          <token-dest-attr name="Given Name">
            <arg-association>
              <token-xpath
expression="self::status/operation-data/password-subscribe-status/association"/>
            </arg-association>
          </token-dest-attr>
        </arg-string>
        <arg-string name="UserLastName">
          <token-dest-attr name="Surname">
            <arg-association>
              <token-xpath
expression="self::status/operation-data/password-subscribe-status/association"/>
            </arg-association>
          </token-dest-attr>
        </arg-string>
        <arg-string name="ConnectedSystemName">
          <token-global-variable name="ConnectedSystemName"/>
        </arg-string>
        <arg-string name="FailureReason">
          <token-text/>
            <token-xpath expression="self::status/child::text()"/>
        </arg-string>
<arg-string name="to">
        <token-dest-attr name="Internet EMail Address">
        <arg-association>
          <token-xpath
expression="self::status/operation-data/password-subscribe-status/association"/>
        </arg-association>
        </token-dest-attr>
        </arg-string>
      </do-send-email-from-template>
      <do-break/>
    </arg-actions>
  <arg-conditions>
    <and>
      <if-xpath op="true">contains($ERROR-MESSAGE, "16018")</if-xpath>
    </and>
  </arg-conditions>
  <arg-actions>
    <do-send-email-from-template
notification-dn="cn=security\cn=Default Notification Collection"
template-dn="cn=security\cn=Default Notification
Collection\cn=Password Set Fail">
      <arg-string name="UserFullName">
        <token-dest-attr name="Full Name">
          <arg-association>
            <token-xpath
expression="self::status/operation-data/password-subscribe-status/association"/>
          </arg-association>
        </token-dest-attr>
      </arg-string>
      <arg-string name="UserGivenName">
        <token-dest-attr name="Given Name">
          <arg-association>
            <token-xpath
expression="self::status/operation-data/password-subscribe-status/association"/>
          </arg-association>
        </token-dest-attr>
      </arg-string>
      <arg-string name="UserLastName">
        <token-dest-attr name="Surname">
          <arg-association>
            <token-xpath
expression="self::status/operation-data/password-subscribe-status/association"/>
          </arg-association>
        </token-dest-attr>
      </arg-string>
      <arg-string name="ConnectedSystemName">
        <token-global-variable name="ConnectedSystemName"/>
      </arg-string>
      <arg-string name="FailureReason">
        <token-text/>
          <token-xpath expression="self::status/child::text()"/>
      </arg-string>
      <arg-string name="to">
        <token-dest-attr name="Internet EMail Address">
          <arg-association>
            <token-xpath
expression="self::status/operation-data/password-subscribe-status/association"/>
          </arg-association>
        </token-dest-attr>
      </arg-string>
    </do-send-email-from-template>
    </arg-actions>
  </do-if>
</actions>
</rule>

When I start this driver, I get the following error:

DirXML Log Event -------------------
   Driver:  \ACMEIDVAULT\ACME\services\ACMEFLAT\eDirectory Driver
   Channel: Subscriber
   Status:  Error
   Message: Code(-9127) Error in
vnd.nds.stream://ACMEVAULT/acme/services/ACMEFLAT/eDirectory+Driver/Password%28Pub%29-Sub+Email+Notifications#XmlData:71
: Missing 'arg-conditions' element.

What you should notice is that this block:

<arg-conditions>
<and>
<if-xpath op="true">contains($ERROR-MESSAGE, "16018")</if-xpath>
</and>
</arg-conditions>

is now stuck in between two <arg-actions> blocks. The way an IF-THEN-ELSE action is structured is that first you have a arg-conditions block with your IF test or tests. Then the first arg-actions is the THEN block, and the second one is the ELSE block of actions.

I am not sure how I got there, based on my actions, but it was probably related to cutting and pasting. Regardless, the driver would not start with this ordering, even though iManager could parse the XML back to a valid-looking set of rules. It was only when I looked at the XML itself that this became obvious.

Solution

This was a tricky problem to catch! However, fixing it is simple.

In the XML view, cut the <arg-conditions> block and paste it before the first <arg-actions> block.

A corollary to this: If you are working on an IF-THEN-ELSE action, and you realize you need to switch the order of the THEN and ELSE actions, you can easily do it in the XML view by just changing the order. Of course, you usually could just negate the IF test to get the same effect, but there may be a reason why that would not work for you.


Disclaimer: As with everything else at Cool Solutions, this content is definitely not supported by Novell (so don't even think of calling Support if you try something and it blows up).

It was contributed by a community member and is published "as is." It seems to have worked for at least one person, and might work for you. But please be sure to test, test, test before you do anything drastic with it.




User Comments

© 2013 Novell