Although I don’t want this to turn into an IdM blog, I want to share at least a couple of more posts on using Sun IdM.
The reason is mainly that when I first started developing on Sun IdM last summer, I couldn’t find much information on the web. At the same time, I was, and is, not very happy with the (java)docs. I also assume that as the SOX and similar acts are getting widespread and gain impact, there will be more and more people in the same situation as myself and Holly.
So if you’re a Java or web- turning IdM developer, then hopefully this post can save some of your hair from certain death. If not, please bare with me
XPress Rules
Once you start building your XPress project the pile of code stored in XPress rules is sure to grow. One of the things that I soon came to dislike with XPress is how awkward it is to test these rules manually (creating a form with a bugus Field executing the rule, tracing the result, etc.), and how often they break because you forget to test them (note to Sun: or because XML was never meant to be a freakin’ programming language platform).
I had absolutely no idea of how to automate testing of such rules, however, until an experienced IdM developer joined the project. Interestingly, it is very easy to execute XPress code from IdM’s Java API (don’t expect to find this in the documentation though), and thanks to him, I now know how to do so.
Example Rule
As a simple example, let’s say we have a rule getUserAttribute that gets and returns a specified attribute – for example fullname – of a user identified by her accountId:
<Rule name="getUserAttribute">
<RuleArgument name="context" />
<RuleArgument name="accountId" />
<RuleArgument name="attrName" />
<defvar name="wsUser">
<invoke name="getObjectIfExists">
<ref>context</ref>
<s>User</s>
<ref>accountId</ref>
</invoke>
</defvar>
<invoke name="getAttribute">
<ref>wsUser</ref>
<ref>attrName</ref>
</invoke>
</Rule>
Executing Rules from Java
Let’s say this rule is stored in a configuration object of wsType EndUserLibrary whose name is MyCorp-UserRuleLibrary.
That is, the full name to our rule is MyCorp-UserRuleLibrary:getUserAttribute.
It takes only a few lines to execute this rule from Java. Let’s first create a Util class holding our method:
package com.mycorp.util.XpressUtil;
import java.util.Map;
import com.waveset.expression.ExState;
import com.waveset.object.LighthouseContext;
import com.waveset.object.Rule;
import com.waveset.util.WavesetException;
public class XpressUtil {
public static Object executeRule(LighthouseContext context,
String ruleName, Map args) throws WavesetException {
Rule rule = Rule.findRule(context.getCache(), ruleName);
ExState state = new ExState();
return rule.eval(state, args);
}
}
Now we can execute our XPress rule from Java:
import java.util.Map;
import java.util.HashMap;
import com.waveset.session.Session;
import com.waveset.session.SessionFactory;
import com.waveset.util.EncryptedData;
import com.mycorp.util.XpressUtil;
// somewhere in our java code...
EncryptedData encryptedPassword = new EncryptedData("configurator");
Session wsSess = SessionFactory.getSession("Configurator", encryptedPassword);
String ruleName = "MyCorp-UserRuleLibrary:getUserAttribute";
Map<String, Object> args = new HashMap<String, Object>();
args.put("context", wsSess);
args.put("accountId", "Configurator");
args.put("attrName", "fullname");
Object result = XpressUtil.executeRule( wsSess, ruleName, args );
Yes. It’s that easy.
pete
/ 20/05/2009Does this really work? line 20 is passing in a Session object to XpressUtil.executeRule, which is looking for a LighthouseContext object.
Is there some code you have not posted?
Thanks
Trond
/ 22/05/2009com.waveset.session.Session implements LighthouseContext, which is an interface, so yes, it works.
I see that I had forgotten an import declaration in the 2nd code snippet, though (com.waveset.session.Session).
pete
/ 18/06/2009i’m new to junit and idm, but junit sucks
how to pass in or run many data points into simple rule execution?
@parameterized seems to only take in 1 arg
Benbbh
/ 21/07/2009Hi,
Thanks for this, but I think I found 2 problems using this.
1) Looks like it bugs when you have that kind of code inside your rule to get the session:
:display.session
context
WF_CONTEXT
2) Looks like it bugs when the rule is between tags:
Let’s create a simple rule such as:
(|)
With that previous rule, no problem, but as soon as I need to use
(|)
myVar
I only get null as a result.
Any idea on how to avoid those 2 issues ?
Thanks,
Ben
D Prabhagar
/ 13/09/2009Hi,
No bug in Xpress, I can resolve your first issue by using following code snippets..
GenericObject args = null;
Map options = new HashMap();
options.put(UserViewConstants.OP_NO_FETCH, “true”);
args = _wsSess.getView(“UserViewer:”+runAsUser, options);
// then add the lighthouse context so the rule writer can invoke
// methods that require it (e.g. getResourceObjects, etc.)
if (args != null) {
args.put(“context”, _wsSess);
}
Thanks
DP
pete
/ 22/02/2010are you sure that new code is correct? GenericObject args does not have a “put”. do you mean to name it something else? and then add it to the args Map? as follows:
GenericObject go=null;
go=_wsSess.getView(“UserViewer:”+runAsUser, options);
args.put(“context”,go);
?
Aravind
/ 08/07/2010Please give me a code snippet of java which invokes Sun IDM workflows.