Keeping it simple, you should always start the ibmdisrv or ibmditk processes with the "-s" flag to specify the solution directory to use. If you don't do this, then you're just using whatever happens to be set in your environment, which could lead to quite a bit of confusion. As an example, you could have your CE (the eclipse IDI GUI) running with a DIFFERENT solution directory than your Default ibmdisrv process. This could lead to a case where properties that resolve perfectly in the GUI don't resolve when you go to run an AL. You can avoid this by always using full paths to properties files, but then that makes your solutions much less portable.
Thursday, January 2, 2025
IDI Operations: Finding the Solution Directory of a Running ibmdisrv Process
Background
Solution
Additional Details
Tuesday, December 24, 2024
Logging in IBM Directory Integrator
Introduction
I've been creating a bunch of AssemblyLines in IDI/TDI/ISVDI recently, and wanted to share a trick to help you set up logging to a file whose path includes BOTH the name of the project and the name of the AssemblyLine.
Quick and Dirty
1. In the Log Settings for the AL, make sure to add a log. I prefer FileRollerAppender, but you choose whatever you want.
2. Click on File Path and set it to Advanced (JavaScript)
3. Set the value to the following:
4. Click OK and you're ready to go. The logfile for the AL will be:
/opt/IBM/TDI/logs/project_name/AL_name.log
Longer and More Details
The Quick and Dirty section above is for advanced/experienced users who have been working with the product for a while and have been beating their heads against a wall trying to find this solution (maybe a handful of people out there). This section is for everyone else.
Background
IDI has tons and tons and tons of logging options. So many, in fact, that most customers will just stick with the default, which logs everything to ibmdi.log, which can make life difficult because all ALs are logged in the exact same file, with their messages intertwined. There can absolutely be benefits to that (i if you're using something like Splunk for centralized log storage, for example). To me, it's much easier to have a different log file for each AssemblyLine. And because you can easily end up with hundreds of ALs in your implementation, it makes sense to me to have one directory per Project, just to make it easier to work through the directory structure.
The specific situation I'm in is that my client has had ITIM and TDI running for over a decade, with different people managing the implementation over the years. This means that they have multiple TDI servers (at various versions) running on the same host. If I was to set this up from scratch starting right now, an easier way to accomplish something VERY similar is to add these two lines to solution.properties for the DI server:
SystemLog.defaultCreateLog=true
SystemLog.defaultMaxGenerations=10
This will cause each AL to log messages in files named:
$SOLDIR/system_logs/$project/$ALName/<logfile>.<timestamp>.log (10 max)
Walkthrough
Explanation
try/catch
This is true for any form element in IDI that you implement as JavaScript. If you reference the task or work or conn objects, you'll get a big red error similar to the one above. That's why I first declare the variable logName with a string value. Then inside the try block, I set it to the value I want to see at runtime. The catch block does nothing, but syntactically it's required.
getParent()
Why did you change the Pattern for the logger?
What to do next?
Comments
Parting thoughts
Friday, August 30, 2024
Working with dates in IBM Security Directory Integrator
Working with dates in TDI can be tricky, since you'll normally be dealing with not only ISIM's internal format, but also various formats from different databases and other sources. The easiest way I've found is to use the java.time.* classes that were introduced in Java 8. Specifically, the LocalDateTime class is great because it has methods like minusHours(), minusDays(), etc. to make it easy to get a time from "X time ago".
Here are some examples I've come up with to use with the different formats I've run into on my latest contract:
Friday, August 9, 2024
Update erlaststatuschangedate in ISIM with a TDI HR Feed
IBM has a support article on this topic here:
Unfortunately, the code provided is incorrect and will throw an exception if you try to use it.
// set up variables to set the erlaststatuschangedate attribute// get milliseconds since epoch in local time zone.var mydate = new Date().valueOf();// get milliseconds of offset from Zulu/UTCvar localOffset = new Date().getTimezoneOffset() * 60000;// add/subtract milliseconds based on local timezone to get Zulu time.var myTZ = mydate + localOffset;// create a new Date() object representing "now" in Zulu time.var utcDate = new Date(myTZ);// Format the date into a string in the correct formatvar myTZStr = new java.text.SimpleDateFormat("yyyyMMddHHmm").format(utcDate);// Add "Z" to the end of the string to complete the correct format.var myTZStrZ = myTZStr + "Z";// set the value of erlaststatuschangedatework.setAttribute("erlaststatuschangedate",myTZStrZ);
Monday, July 22, 2024
IBM Directory Integrator error "unknown format type at"
So here's a strange one that I didn't find anywhere in my numerous searches, so I figured I would post it here. When running a TDI AssemblyLine, I got the following exception / error:
12:14:43,274 ERROR - [My-JDBC-Connector] CTGDIS810E handleException - cannot handle exception , addonly
Tuesday, July 16, 2024
Tivoli Directory Integrator Entry.toJSON() function produces bad JSON for single-element arrays
TDI lets you create a JSON string from an Entry type object using that class's toJSON() method. It works like a champ UNLESS you happen to have a property that is an array with a single element, like this:
entry = system.newEntry()entry.foobar = [ "0" ];task.logmsg(entry.toJSON());
goodString = entry.toJSON().replace('"foobar":"0"','"foobar":["0"]');