Novell Identity Manager ECMA Script & Tracing

  • 7000888
  • 09-Jul-2008
  • 29-Apr-2013

Environment

Novell Identity Manager 3.5.1
Novell Identity Manager Engine DirXML Script
Novell Identity Manager Engine Reporting

Situation

I don't see any ECMA script information in the trace logs but there is information being sent to the trace screen. I used the following for my testing...

importPackage(Packages.com.novell.ldap);
/**
* ldapSearch
*
* @param (String} host LDAP Server, either DNS or IP-Address
* @param (Number} port LDAP listening port
* @param (String} user user account, full distinguished name, LDAP syntax
* @param (String} password the cleartext LDAP userpassword
* @param (String} base search base
* @param (String} scope (base | one | sub)
* @param (String} filter LDAP search filter according to RFC2254 (see {@link #ldapCount(DirContext, String, String)}
* @param (String} attrList comma separated list of attributes to return
* @type Nodeset
* @return NodeSet containing instances from search result, or status element with error message
*/
function ldapSearch(host, port, user, password, base, scope, filter, attrList)
{
var nodeSet = new Packages.com.novell.xml.xpath.NodeSet();
var document = Packages.com.novell.xml.dom.DocumentFactory.newDocument();
debugMessage("Nodeset and document declared properly.");
var ndsElement = document.createElement("nds");
document.appendChild(ndsElement);
ndsElement.setAttributeNS(null, "dtdversion", "3.5");
var outputElement = document.createElement("output");
ndsElement.appendChild(outputElement);
var searchScope = LDAPConnection.SCOPE_ONE;
if (scope == "base")
{
searchScope = LDAPConnection.SCOPE_BASE;
} else if (scope == "sub")
{
searchScope = LDAPConnection.SCOPE_SUB;
}
var attrSplit = attrList.split(',');
var attrArray = java.lang.reflect.Array.newInstance(java.lang.String, attrSplit.length);
for (var attrIndex in attrSplit)
{
attrArray[attrIndex] = attrSplit[attrIndex];
}
var lc = new LDAPConnection();
debugMessage("new connection object declared properly.");
try
{
// connect and bind to the server
lc.connect( host, port );
debugMessage(53);
lc.bind( LDAPConnection.LDAP_V3, user, new java.lang.String(password).getBytes("UTF8") );
debugMessage("LDAP bind completed successfully with credentials.");
var searchResults = lc.search(base,
searchScope,
filter,
attrArray, // return all attributes
false); // return attrs and values
/* process the results
* -- The first while loop goes through all the entries
* -- The second while loop goes through all the attributes
* -- The third while loop goes through all the attribute values
*/
debugMessage("LDAP Search completed successfully. Starting loop through results.");
while (searchResults.hasMore())
{
var nextEntry = searchResults.next();
// create the instance node
var instanceElement = document.createElement("instance");
instanceElement.setAttributeNS(null,"src-dn", nextEntry.getDN());
debugMessage("Found object: " + nextEntry.getDN());
var attributeSet = nextEntry.getAttributeSet();
var allAttributes = attributeSet.iterator();
// create the attr nodes
while(allAttributes.hasNext())
{
var attribute = allAttributes.next();
var attrElement = document.createElement("attr");
attrElement.setAttributeNS(null, "attr-name", attribute.getName());
var allValues = attribute.getStringValues();
// create the value nodes
if( allValues != null)
{
while(allValues.hasMoreElements())
{
var valueElement = document.createElement("value");
valueElement.appendChild(document.createTextNode(allValues.nextElement()));
attrElement.appendChild(valueElement);
}
instanceElement.appendChild(attrElement);
}
}
outputElement.appendChild(instanceElement);
nodeSet.add(instanceElement);
}
}
catch(e)
{
var statusElement = document.createElement("status");
statusElement.setAttributeNS(null, "level", "error");
statusElement.appendChild(document.createTextNode(e.toString()));
outputElement.appendChild(statusElement);
nodeSet.add(statusElement);
}
finally
{
// disconnect with the server
lc.disconnect();
}
return nodeSet;
}
function serialize(nodeSet)
{
var stringWriter = new java.io.StringWriter();
for (var node = nodeSet.first(); node; node=nodeSet.next())
{
var domWriter = new Packages.com.novell.xml.dom.DOMWriter(node, stringWriter);
domWriter.setIndent(true);
domWriter.write();
domWriter.flush();
stringWriter.write('\n');
}
return stringWriter.toString();
}
 
function debugMessage(message)
{
if (Packages.com.novell.nds.dirxml.engine.DirXML.isExternal())
{
Packages.javax.swing.JOptionPane.showMessageDialog(null,
message.toString());
}
else
{
java.lang.System.out.println(message.toString());
}
}
The call to the script : <token-xpath expression="es:ldapSearch('151.132.249.158', '389',
cn=jobsadmin,ou=services,o=pbc', $password, 'OU=DELETED-USERS,O=PBC', 'sub', $filter, 'cn')"/>

Resolution

A: System.out and System.err go directly to DSTrace, bypassing the normal IDM trace & logging. It should also be possible to call the trace facility used by drivers from ECMAScript and this will go into the java trace file as well.

https://developer.novell.com/documentation/dirxml/dirxmlbk/ref/javadocs/com/novell/nds/dirxml/driver/Trace.html

This has some additional benefits over going to System.out:
1. Goes into the trace in both the engine and in the simulator.
2. Goes into the java trace file.
3. Can use indent, color, etc.
4. Can specify trace level so message only appear when trace level set at or above the level, default level being 1.
Something like:
// this is declared at the top level outside of any function
var tracer = new Packages.com.novell.nds.dirxml.driver.Trace("ECMAScript");
function myfunction()
{
tracer.trace("Entering myfunction", 3);
// do some stuff
tracer.trace("Exiting myfunction", 3);
}