Thursday, November 25, 2010

Twitter and TDI - Part 3

A while back, I wrote myself a Twitter connector for Tivoli Directory Integrator. I was bored one weekend and it seemed like an interesting exercise. After all, it was a good opportunity to find out about Twitter's migration to OAuth.

I didn't want a complicated Twitter connector. It only had to perform a handful of functions:
  • Send a tweet
  • Iterate through my tweets
  • Iterate through my friends' tweets
  • Iterate through the public timeline
  • Iterate through a specific person's tweets (other than mine)

I didn't want to bother with direct messaging or retweeting or geo-location or anything fancy. After all, my intention was to show how I could get TDI respond to events posted on Twitter and repond to other events by posting an update on Twitter. (In short, use Twitter as a less-enterprise like MQ system!)

I'm glad to say that the experiment worked and I provide it to the populace at large to take a look at. For a sneak preview, here's the main connector:

In the example above, I'm processing Twitter Object Types of "Tweets: Other" and looking at Stephen Fry's tweets. The Consumer Key/Secret and Access Key/Secret are not displayed for obvious reasons! Indeed, obtaining the key/secret combinations is a little fiddly though there is plenty of documentation out there to help you obtain that info from Twitter.

Running an AL with the connector in iterator mode pointed at "stephenfry" results in the following work entries being dumped in my log:

CTGDIS087I Iterating.
CTGDIS003I *** Start dumping Entry
    Operation: generic
    Entry attributes:
        date (replace):    'Thu Nov 25 09:24:58 GMT 2010'
        tweet (replace):    'Damnably chilly on the Sherlock Holmes set this morning. Frost forming on the supporting artists' moustaches...'
CTGDIS004I *** Finished dumping Entry
CTGDIS003I *** Start dumping Entry
    Operation: generic
    Entry attributes:
        date (replace):    'Thu Nov 25 07:06:52 GMT 2010'
        tweet (replace):    'Lordy. 260 all out. Knew we shouldn't write Australia off. A wounded wallaby us a dangerous thing.  Ho hum. Business as usual. #theashes'
CTGDIS004I *** Finished dumping Entry
CTGDIS003I *** Start dumping Entry
    Operation: generic
    Entry attributes:
        date (replace):    'Wed Nov 24 17:40:50 GMT 2010'
        tweet (replace):    '@AWOLTom Already have...'
CTGDIS004I *** Finished dumping Entry
CTGDIS003I *** Start dumping Entry
    Operation: generic
    Entry attributes:
        date (replace):    'Wed Nov 24 16:55:24 GMT 2010'
        tweet (replace):    'The fine is taken care of, but there is a fighting fund @TwJokeTrialFund A fiver from you to help the appeal?'
CTGDIS004I *** Finished dumping Entry

Wow, you may be thinking. But why would I want to do that?

Indeed. I guess, as I have alluded to in this blog before, you could have your assembly lines "tweet" upon component failure so that an out-of-hours support person can respond. After all, tweets can easily be delivered to smartphones at no cost to the organisation.

Alternatively, you could remotely control assembly lines using this mechanism. Just think, I could tweet "Start HR Feed" to my personal twitter-stream and I could have an assembly line iterating through my twitter-stream just waiting for the instruction to start processing that feed! (NOTE: I wouldn't necessarily advocate that this is a great way of managing your production schedule!)

The connector and supporting JAR files can be retrieved from here:
NOTE: jtwitter.jar and signpost-core. are open source code provided elsewhere on the net. I've added these versions here as they are known to work with my connector.

Drop the twitterConnector.jar into TDI_HOME/jars/connectors. Drop the other JARs into TDI/HOME/jars/3rdparty.

If you need help getting your keys/secrets, I may be able to sort you out, though you will probably appreciate figuring it out for yourself in the long run.

For those interested in the underlying code, it is really very simple. A bind to Twitter using OAuth can be achieved in two lines of code:

// Make an oauth client
OAuthSignpostClient oauthClient = new OAuthSignpostClient(

// Make a Twitter object
this.twitterBind = new Twitter(this.twitterUser, oauthClient);

Sending a tweet is a single line of code:


And iterating through tweets is a matter of invoking one of four methods, like this:

this.tweetList = this.twitterBind.getUserTimeline(this.twitterUser);

You can look through to get a feel for the full source code.

I've had fun building the connector and it can certainly ease the pain of putting together Assembly Lines that need to make calls to Twitter by having such a neat interface. I hope you have fun too.

Wednesday, November 17, 2010

ITIM - Java Version, Password Reset and SAP JCo

It's not very often that I wrapper a combination of topics together into a single post, but these are short snippets that would look a bit strange in a posting all of their own. They are trivial to the point of being unworthy of their own posting!

Java Versions
In the good old days, the version of Java you had installed on your client machine would play havoc with ITIM's applets: Workflow Designer; Form Designer; Join Rules Definition. It used to be that an upgrade of Java would immediately wreck your ability to use these applets. That all changed, though, and for quite some time I've enjoyed the ability to upgrade Java as and when I saw fit and everything still worked. Until yesterday.

Java 1.6.0_18 afforded me the luxury of using the ITIM applets. Java 1.6.0_22 does not! At least, 1.6.0_22 won't allow me to save my workflow! At least, not using ITIM v5.1 FP1.

You have been warned!

Password Resets
This is more of a reminder than anything else. Sometimes, it isn't enough to change a password in ITIM. What happens if the account on the target system has been locked due to authentication failures? A change password may not unlock the account and indeed this is the case when it comes to many systems - SAP springs to mind as my most recent example.

What can be done? Well, in simplistic terms, the changePassword operation for the account type could be updated to perform an account restore function after the password has been changed. The resulting workflow could look like this:

Of course, you may want to put a significant amount of logic around this restore process. You may want to invoke that only if the requestor of the change password operation is a specific person, for example.

The SAP Java Connector that is used by the TDI SAP NetWeaver connector can, periodically, through an error message like this: "max no of 100 conversations exceeded".

The "fix", apparently, is to set an environment variable called CPIC_MAX_CONV and set the variable to a value of at least 500. I'm sure you can figure out how to set the environment variable for your Operating System and I'm sure you can work out that your TDI service will need to be restarted for the variable to have any effect.

And so ends today's collection of snippets. I told you they were trivial. I do hope you aren't too bored as a result of reading the above. Until the next adventure!