Now that I have your attention, let me point you to this forum post where I describe the steps it takes to bring the SyncDBfromSource AssemblyLine -- the AL that forms the entire API into Connections' Profiles registry -- into the TDI Debugger in order to step through it for purposes of troubleshooting and adventure:
Google Group post about how to debug the Connections TDI ALs (near the bottom of the thread)
My wordy response is at the bottom of this thread. If you have an AssemblyLine that you wish to debug, but are still unable to (even after video #6 here) then let me know!
Saturday, November 22, 2008
Monday, November 10, 2008
...now I remember
Remember to check out the FormEntry Connector. This is the perfect companion to the AL Debugger, letting you set up an infinite feed while you interactively set up Attribute values in order to exercise every corner of your AssemblyLine logic.
Plus, you can map out to the
Very handy indeed!
Plus, you can map out to the
entryRawData
parameter when this component is used in a Connector Loop, letting you use multiple Parsers on the same bytestream.Very handy indeed!
New Component and Library .jar Files
Generally, adding a new component to TDI's library amounts to either 1) copying the relevant jar files to the
This latter is done by setting the
According to the instructional comments found in the property file, you can set this property to a list of directory paths, or a list of files, or any combination of the two. For example,
Using this property lets you keep custom jar files either in place, or in a common area like the CustomJars folder I use. This can be preferrable to copying them into the TDI product installation folder.
Due to the mystical dance of Java loaders, sometimes these library files may need to be available to other loaders, in which case you end up having to do one or both of the following:
a). Modifying the PATH in the
b). Modifying the CLASSPATH line in these files for this same purpose.
I have several sub-folders to my own CustomJars directory, each containing the library files associated with a particular data source, like "Maximo", "Lotus" and so forth. TDI's loader checks all sub-folders under root directory specified, making it simple to keep these organized and backed up.
Note: libraries can be in zip files as well.
*Note: For Domino integration you will want to put the Notes path first: SET PATH=c:\Notes;%PATH% - since a little bird told me that only the first 128 chars are used by the Notes loader. At least for older versions.
...and I know there was something else I wanted to mention...
[TDI Installation Folder]/jars
sub-directory; or 2) leaving these files where they are and instead telling TDI where to find them.This latter is done by setting the
com.ibm.di.loader.userjars
property found near the top of the solution.properties
file which is located in your Solution Directory.According to the instructional comments found in the property file, you can set this property to a list of directory paths, or a list of files, or any combination of the two. For example,
com.ibm.di.loader.userjars=C:\Notes;CustomJars;C:\Drivers\jdbcDrv.jar
Using this property lets you keep custom jar files either in place, or in a common area like the CustomJars folder I use. This can be preferrable to copying them into the TDI product installation folder.
Due to the mystical dance of Java loaders, sometimes these library files may need to be available to other loaders, in which case you end up having to do one or both of the following:
a). Modifying the PATH in the
ibmditk
and ibmdisrv
files to include additional folders*.b). Modifying the CLASSPATH line in these files for this same purpose.
I have several sub-folders to my own CustomJars directory, each containing the library files associated with a particular data source, like "Maximo", "Lotus" and so forth. TDI's loader checks all sub-folders under root directory specified, making it simple to keep these organized and backed up.
Note: libraries can be in zip files as well.
*Note: For Domino integration you will want to put the Notes path first: SET PATH=c:\Notes;%PATH% - since a little bird told me that only the first 128 chars are used by the Notes loader. At least for older versions.
...and I know there was something else I wanted to mention...
Thursday, November 6, 2008
Exceptional Solutions
There are two types: those that go beyond the call of duty to deliver scalable, available and maintainable integration; and those that are defined by the stack dumps of unhandled exceptions.
How do you keep an AssemblyLine in the air? By catching and dealing with exceptions yourself. This is broadly done in two ways:
1) By putting code in Error Hooks. At the very least, you should log the error. I tend to use a script function to handle this.
Of course, no error report would be complete without a dump of the various Entry objects available -- at least
And then added it to my error function, making sure not to throw any exceptions whilst calling it:
Now it's easy to customize the format of the messages, as well as include other functionality if needed; for example, using a Passive Connector to write out error information, or using
2) Surround any script that can throw exceptions (like library calls) with a try-catch block:
If you don't handle it, then your AssemblyLine will stop running.
I'm just saying...
How do you keep an AssemblyLine in the air? By catching and dealing with exceptions yourself. This is broadly done in two ways:
1) By putting code in Error Hooks. At the very least, you should log the error. I tend to use a script function to handle this.
function logerror(msg) {
task.logmsg("ERROR", "@@ERROR - " + msg);
task.logmsg("ERROR", "@@ AL[Component]: " + task.getShortName()
+ "[" + error.getString("connectorname") + "]");
task.logmsg("ERROR", "@@ Operation: " + error.getString("operation"));
task.logmsg("ERROR", "@@ Message: " + error.getString("message"));
task.logmsg("ERROR", "@@ Exception: " + error.getString("exception"));
}
Of course, no error report would be complete without a dump of the various Entry objects available -- at least
work
and conn
. Unfortunately, the dumpEntry() call does not let you set the log level. So I made my own:
function attList( e ) {
if (typeof(e) == "undefined" || !e)
return;
var attnames = e.getAttributeNames();
java.util.Arrays.sort(attnames);
var str = "";
for (var name in attnames) {
var att = e.getAttribute(name);
str += "@@ " + name + ": ";
for (var i = 0; i < att.size(); i++)
str += att.getValue(i) + " | ";
str = str.substring(0, str.length-3) + "\n";
}
return str;
}
function dumpEntry( logLevel, e, name ) {
if (typeof(e) == "undefined" || !e)
return;
task.logmsg(logLevel, "\n@@ ******** Entry Dump: " + name + " ********\n"
+ attList( e )
+ "@@ ***************************************\n")
}
And then added it to my error function, making sure not to throw any exceptions whilst calling it:
function logerror( msg ) {
task.logmsg("ERROR", "@@ **** ERROR - " + msg);
task.logmsg("ERROR", "@@ AL[Component]: " + task.getShortName()
+ "[" + thisConnector.getName() + "]");
logval("operation");
logval("message");
logval("exception");
if (typeof(work) != "undefined" && work)
dumpEntry("ERROR", work, "Work");
if (typeof(conn) != "undefined" && conn)
dumpEntry("ERROR", conn, "Conn");
if (typeof(current) != "undefined" && current)
dumpEntry("ERROR", current, "Current");
}
Now it's easy to customize the format of the messages, as well as include other functionality if needed; for example, using a Passive Connector to write out error information, or using
java.lang.System.out.println()
to print messages to the command window where the TDI Server was started from.2) Surround any script that can throw exceptions (like library calls) with a try-catch block:
try {
makeSomeCall(); // if this fails, catch below
} catch (exc) {
task.logmsg("@@ Error: " + exc);
}
If you don't handle it, then your AssemblyLine will stop running.
I'm just saying...
Saturday, November 1, 2008
Integrated Service Management (ISM) leverages TDI
TDI is bundled with IBM's ISM offerings to provide integration services for deployment of solutions like TADDM (System/Asset & Relationship Discovery Tool), CCMDB (Change & Configuration Management DB) and TSRM (IBM's Service Desk and Service Catalog product).
Here's a TSRM scenario captured on film:
Here's a TSRM scenario captured on film:
Subscribe to:
Posts (Atom)