Showing posts with label TDI. Show all posts
Showing posts with label TDI. Show all posts

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:


var ldtObj = java.time.LocalDateTime.now();
var dtfObj = java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd");
var today = ldtObj.format(dtfObj);  
// today is "20240830" for August 30, 2024

var dtfObjHHmm = java.time.format.DateTimeFormatter.ofPattern("yyyyMMddHHmm");
var todayHHmm = ldtObj.format(dtfObjHHmm);  
// todayHHmm is  "202408301531" for 15:31 on August 30, 2024

var dtfObjH = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd:HH");
var todayH = ldtObj.format(dtfObjH);  
// todayH is "2024-08-30:15" for 15:00 on August 30, 2024

var dtfObjChars = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH'hrs'mm'mins'");
var todayChars = ldtObj.format(dtfObjChars);  
// todayChars is "2024-08-30T15hrs31mins" for 15:31 on August 30, 2024
// just put single quotes in the Pattern around any literal characters you want in the resulting string.

var utcZone = java.time.ZoneId.of("UTC");
var ldtObjUtc = java.time.LocalDateTime.now(utcZone);
var dtfObjZ = java.time.format.DateTimeFormatter.ofPattern("yyyyMMddHHmm'Z'");
var todayZ = ldtObjUtc.format(dtfObjZ);  
// todayZ is  "202408301531Z" for 15:31 on August 30, 2024 Zulu (UTC) time.

// get the time "3 hours ago"
var ldtObjThreeHoursAgo = ldtObj.minusHours(3);
var dtfObj = java.time.format.DateTimeFormatter.ofPattern("yyyyMMddHHmm");
var today = ldtObj.format(dtfObj);  
// today is "202408301231" for three hours before 15:31 August 30, 2024 (so 12:31)

Friday, August 9, 2024

Update erlaststatuschangedate in ISIM with a TDI HR Feed

IBM has a support article on this topic here:

https://www.ibm.com/support/pages/how-update-erlaststatuschangedate-through-tdi-hr-feed#:~:text=If%20the%20%22erpersonstatus%22%20attribute%20value%20is%20being%20modified,Work%20attribute%20called%20%22erlaststatuschange%22%20to%20the%20Input%20Map 

Unfortunately, the code provided is incorrect and will throw an exception if you try to use it.

Here's the corrected code:

// 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/UTC
var 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 format
var 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 erlaststatuschangedate
work.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

java.lang.IllegalArgumentException: unknown format type at
        at com.ibm.icu.text.MessageFormat.makeFormat(MessageFormat.java:2086)
        at com.ibm.icu.text.MessageFormat.applyPattern(MessageFormat.java:589)
        at com.ibm.icu.text.MessageFormat.<init>(MessageFormat.java:437)
        at com.ibm.icu.text.MessageFormat.format(MessageFormat.java:1137)
        at com.ibm.di.util.ParameterSubstitution.substitute(ParameterSubstitution.java:229)
        at com.ibm.di.util.ParameterSubstitution.substitute(ParameterSubstitution.java:173)
        at com.ibm.di.util.ParameterSubstitution.substitute(ParameterSubstitution.java:245)
        at com.ibm.di.connector.JDBCConnector.putEntry(JDBCConnector.java:1202)
        at com.ibm.di.server.AssemblyLineComponent.executeOperation(AssemblyLineComponent.java:3351)
        at com.ibm.di.server.AssemblyLineComponent.add1(AssemblyLineComponent.java:2012)
        at com.ibm.di.server.AssemblyLineComponent.add(AssemblyLineComponent.java:1965)
        at com.ibm.di.server.AssemblyLine.msExecuteNextConnector(AssemblyLine.java:3780)
        at com.ibm.di.server.AssemblyLine.executeMainStep(AssemblyLine.java:3391)
        at com.ibm.di.server.AssemblyLine.executeMainLoop(AssemblyLine.java:2989)
        at com.ibm.di.server.AssemblyLine.executeMainLoop(AssemblyLine.java:2972)
        at com.ibm.di.server.AssemblyLine.executeAL(AssemblyLine.java:2939)
        at com.ibm.di.server.AssemblyLine.run(AssemblyLine.java:1317)
12:14:43,276 ERROR - CTGDIS266E Error in NextConnectorOperation. Exception occurred: java.lang.IllegalArgumentException: unknown format type at
java.lang.IllegalArgumentException: unknown format type at
        at com.ibm.icu.text.MessageFormat.makeFormat(MessageFormat.java:2086)
        at com.ibm.icu.text.MessageFormat.applyPattern(MessageFormat.java:589)
        at com.ibm.icu.text.MessageFormat.<init>(MessageFormat.java:437)
        at com.ibm.icu.text.MessageFormat.format(MessageFormat.java:1137)
        at com.ibm.di.util.ParameterSubstitution.substitute(ParameterSubstitution.java:229)
        at com.ibm.di.util.ParameterSubstitution.substitute(ParameterSubstitution.java:173)
        at com.ibm.di.util.ParameterSubstitution.substitute(ParameterSubstitution.java:245)
        at com.ibm.di.connector.JDBCConnector.putEntry(JDBCConnector.java:1202)
        at com.ibm.di.server.AssemblyLineComponent.executeOperation(AssemblyLineComponent.java:3351)
        at com.ibm.di.server.AssemblyLineComponent.add1(AssemblyLineComponent.java:2012)
        at com.ibm.di.server.AssemblyLineComponent.add(AssemblyLineComponent.java:1965)
        at com.ibm.di.server.AssemblyLine.msExecuteNextConnector(AssemblyLine.java:3780)
        at com.ibm.di.server.AssemblyLine.executeMainStep(AssemblyLine.java:3391)
        at com.ibm.di.server.AssemblyLine.executeMainLoop(AssemblyLine.java:2989)
        at com.ibm.di.server.AssemblyLine.executeMainLoop(AssemblyLine.java:2972)
        at com.ibm.di.server.AssemblyLine.executeAL(AssemblyLine.java:2939)
        at com.ibm.di.server.AssemblyLine.run(AssemblyLine.java:1317)


The problem was that I had a scriptable field in a connector that was set as "Text w/substitution", but needed to be set to "Advanced (JavaScript)". Sometimes (with only a tiny bit of JavaScript, for example), you can get away with this. But in my case, I had a LOT of JavaScript and this error was the result.

To figure that out, I put lots of debugging code in the JavaScript itself and in the Component Hooks around when this field should have been evaluated.

Monday, July 15, 2024

Tivoli Directory Integrator Certificate Chain Exception

 Saw this error today in an HTTP Client Connector in TDI 7.1.1:

 java.security.cert.CertPathValidatorException: Certificate chaining error

I had the remote host's entire certificate chain imported into serverapi/testadmin.jks . I also made certain that my solution.properties file was pointing to the correct JKS file, restarted the TDI CE multiple times, and it simply kept failing. I thought I was going crazy, so I:
  • stopped TDI CE
  • moved testadmin.jks
  • zeroed out testadmin.jks
  • started TDI CE
  • Went to the connector and clicked "Get Certificate" and it complained, whereas before it said "Certificate is already trusted", so I knew I was dealing with the correct JKS file.
  • FINALLY, out of desperation, I deleted the server certificate, but left the other two certs in the chain (the signer and the signer of THAT certificate), and THEN IT WORKED.

So I'm not certain what the moral of the story is, but that's how I solved this problem, which is slightly different than I've seen anywhere else and I wanted to record it to hopefully help anyone who runs into this in the future.

Wednesday, June 8, 2016

Installing ITIC and TDI on Windows Server 2012

Both of these tools use the ZeroG InstallAnywhere installer, which doesn't completely get along with Windows Server 2012. Luckily, there's an easy fix within Windows. You need to set the "Compatibility mode" to run with compatibility for "Windows 7". You need to perform this procedure on the setup.exe file for ITIC (under Install\ITIC wherever you've extracted the install images) and the install_tdiv71_win_x86_64.exe file in the TDI installer directory.

On each file, right click and select Properties.

Then on the Compatibility tab, click the "Change settings for all users" button at the bottom.

In the "Compatibility mode" section, select "Run this program in compatibility mode for:" checkbox.

Select "Windows 7" from the drop down list.

Click OK, then OK again.

And now you're ready to install

UPDATE: You do also need to ensure that the java executable is in your path. If not, it will fail when trying to create the Java Virtual Machine.

UPDATE 2: And it MUST be the Java 1.7 executable in your path. 1.8 will fail.

Tuesday, May 19, 2015

Video - Creating a REST Service with Tivoli Directory Integrator (TDI)

Tivoli Directory Integrator is a truly amazing tool. It has all of the plumbing in place to connect to numerous datasources and to automatically transform endless types of data. Plus it's included with many IBM products. Your company probably owns a license for it, and you're probably not leveraging even a fraction of its capabilities. 


Monday, May 18, 2015

Video - Integrating data with SmartCloud Control Desk (SCCD) using TDI

It's a little old, but still absolutely valid. TSRM is one component of IBM's SCCD offering, and it still has the same architecture that it had in 2008. TDI has some new features, but it still has the same architecture and the process is still the same for integration.