| Subcribe via RSS

Stupid SailPoint Developer Tricks

Hello, mates — as they say Down Under, where I happen to be at the moment on a rather large Sailpoint engagement. It’s been a while, and I’m sorry for that. I keep promising more, new and better content and haven’t delivered.

The last couple of months however have been absolutely crazy and there have been some changes on my end, as you perhaps can see. Now that things have shaped up a bit, maybe I can get back to the business at hand here on the blog, again as I have time.

Stupid Pet Tricks

When I was growing up and in college, a famous comedian became famous (partially) by having a segment on his show called “Stupid Pet Tricks.” Some were hilarious and some… belonged on the 1980’s “Gong Show.” (If you’ve never heard of “The Gong Show,” trust me, you aren’t missing anything).

Since that time, I’ve always thought of various developer tricks in the same light. Some are quite slick and useful and some… really just need to be buried. I’ll leave it to you to decide on this one.

Out of sheer laziness, while onboarding Sailpoint applications that feature a BuildMap rule (eg. BuildMap, JDBCBuildMap, and SAPBuildMap), I sometimes utilize a method for “printing debug statements” that I can see directly and immediately in connectorDebug, without having to jump into or tail the Sailpoint IIQ log or application server logs.

It’s also just a bit less verbose as the Sailpoint IIQ logs typically have a large class identification prefix in front of them, which can get rather cumbersome and make it more difficult to pick out one’s intended debug output.

Plus I hate changing logging levels in log4j.properties even though the Sailpoint IIQ debug page allows me to load a new logging configuration dynamically. In short, I’m just a lazy, complaining type when it comes to Sailpoint IIQ debug statements.

Someone mentioned this would be worth blogging about, so here goes. (At the very least, this is an easy article to write and perhaps will get me back into the blogging swing?!)

__DEBUG__ Schema

Now, I would definitely recommend doing this only on a local or designated sandbox and then making sure you clean up before checking in your code. (You are using some form of source code control for your Sailpoint IIQ development, aren’t you?!)
More »

Tags: , , , , ,

SailPoint IIQ: BuildMap – I Told You So :-)

Okay, here’s an article I wasn’t planning on posting, but based on some feedback I received privately via email, I thought I would throw this one example out there. Sometimes the simplest and unlikeliest of examples can tell you a whole lot about the plumbing of a product such as Sailpoint IIQ. Concerning my most recent post on SailPoint IIQ Build Map rules, this next exercise I think will fit the bill of being quite revealing even though simple and extremely unlikely to mirror real world.

I Told You So :-)

In my last post, I indicated that Build Map rules (as well as other rule hooks in Sailpoint IIQ) do not care what you are doing inside them, in general. In the case of the Build Map rule, I stated that Sailpoint IIQ does not do a single thing to validate your code. It does not validate it against your application schema; it’s trusting you 100% to wire your build map rule to your schema in the right way — 100%. The only thing Sailpoint IIQ does do is map fields from your build map into a resource object (later in aggregation processing) that matches the schema, which is a short way of saying…

(1) If you don’t provide a field from your return map that matches the application schema, that field in the schema will be blank (or null), and…

(2) If you provide a field from your return map that does NOT match the application schema, that field in the build map will be dropped.

That’s it. The rest is up to you and here’s a very small example that in my mind pretty much demonstrates everything about how build map rules work.

Setting This Up

Let’s set this up. Try this in your development sandbox. First, create a plain text file that has nothing in it but one number per line — lines numbered from say 1 to 25. Nothing else. This is easy to setup on the Linux command line. (For you Windows peeps, I’m sorry to say it may be just as easy to jump into NotePad and bang out 25 lines by hand! :-( :-))

$ perl -e 'for (1..25) { print "$_\n" }' > dummy25.txt

More »

Tags: , , , , , , ,

SailPoint IIQ: The BuildMap Rule Revisited

Well, I’m behind on posting again. Apologies to those following here who I know were looking forward to this particular post which I promised in person to a number of you.

Build Map Rules in Aggregations

The BuildMap Rule… Just what is a “build map rule” exactly? Maybe you’ve used or even written one, but you admit you still really don’t understand what it’s actually doing or how it really works in the case of account aggregations. I actually get that kind of comment all the time, so don’t feel bad. Let’s crack ‘er open and see if we can crystalize the concept of how this actually works. Once the concept is crystal clear, you’ll know exactly when to use it, and your usage of it will be that much more sophisticated and precise.

Hang On… What Is A Map, First Of All?!

Before we get into what a build map rule is, we first need to cover the concept of a “map” to begin. Again, this is a comment I often get as I am on site implementing Sailpoint IIQ for the first time in enterprises — “what is a map?”

Sailpoint IIQ is built using JEE technology. Therefore, it draws from many paradigms within that reference technology platform. A Map object in Java, or just a “map,” is essentially an indexed name/value pair system. Focusing on strings as the map implementation (it’s possible to have other map types in Java, but we’ll forgo that discussion here), a very stripped down version of a map is something like you might find in a configuration or initializer file of some sort:

name=Chris Olive
address=123 Somewhere St.
city=St. Paul
state=MN
zip=55102

This is also known as a key/value pairing because the name on the left hand side can only occur once. If you are familiar with other programming languages, a Java Map is roughly equivalent to what is called a hash in Perl and Ruby, a dictionary in the older Microsoft development parlances (VBScript, etc.), or a dictionary in Javascript (though popularization of Javascript and it’s object orient model extends this scheme into JSON objects, which again we will forgo delving into in depth in this discussion.)

Here are the equivalent “maps” in some of the languages I’ve mentioned above. If you are familiar with all or any of these, then you know what a Java Map (object) is:

Perl:

my $map = {
   name    => 'Chris Olive',
   address => '123 Somewhere St.',
   city    => 'St. Paul',
   state   => 'MN',
   zip     => '55102'
};

Ruby:

map = {
   :name    => 'Chris Olive', \
   :address => '123 Somewhere St.', \
   :city    => 'St. Paul', \
   :state   => 'MN', \
   :zip     => '55102' \
}

Javascript/JSON:

map = {
   "name"    : "Chris Olive",
   "address" : "123 Somewhere St.",
   "city"    : "St. Paul",
   "state"   : "MN",
   "zip"     : "55102"
};

Java (BeanShell):

// Unfortunately, Java doesn't offer a shortcut way of initializing
// a HashMap. I'll just not comment on that here. :-)
//
// Since Java 5, real Java wants these sorts of things "typed" as
// well.  We'll forgo that and do this BeanShell style as per IIQ.
// BeanShell doesn't require type syntax.

import java.utils.HashMap; // Not required in BeanShell
   :
   :
HashMap map = new HashMap();
map.add( "name", "Chris Olive" );
map.add( "address", "123 Somewhere St." );
map.add( "city", "St. Paul" );
map.add( "state", "MN" );
map.add( "zip", "55102" );

Now, that last example looks somewhat familiar if you’d done any writing (or plagiarizing :-)) of Sailpoint IIQ build map rules already. (Funny how in literary circles, plagiarism is very much frowned upon, whereas in IT, it’s very much encouraged, isn’t it?! :-))

So while we’re here, let me just say that the variable name “map” carries no special significance. People tend to name their variables in simple scenarios according to what they are and the variable name could just has easily been “foo” or “frank” — it’s doesn’t matter (other than when you program that way, things get a little unclear fairly quickly.)

So this would do just as well:

HashMap me = new HashMap();
me.add( "name", "Chris Olive" );
me.add( "address", "123 Somewhere St." );
me.add( "city", "St. Paul" );
me.add( "state", "MN" );
me.add( "zip", "55102" );

IIQ Uses Maps EVERYWHERE

So now that you (hopefully) know what a “map” is, then maybe at least the name has suddenly taken on more significance. “Build Map” means… a Java Map object instance (or just a map) is going to be built. “Why” will be explained in just a moment.

The main thing to emphasize here is… Sailpoint IIQ uses maps literally EVERYWHERE. So just get used to it. And that being said, I can’t think of a concept in Sailpoint IIQ that you need to make sure is rock solid any more than the concept of a map. Again, Sailpoint IIQ uses them literally EVERYWHERE.
More »

Tags: , , , , , ,

SailPoint IIQ: Get Your JavaDocs

November 1st, 2012 | No Comments | Posted in IAM Development, Object-Oriented Development

Interestingly, I was on a call this morning with a lot of really smart people, and I was surprised to learn some of them didn’t know that Java documentation on all the internal Sailpoint IIQ Java objects comes bundled with every install of IIQ. All ya gotta do is set a bookmark to a static URL after a Sailpoint IIQ install, and you are good to go.

This means, if you have multiple IIQ versions installed (as I do), then you can get the JavaDocs specific to each one of them with a URL for each version. They are all located at the same URL for each install:

http://your-hostname-here:8080/identityiq/doc/javadoc

If you just happen to have Sailpoint IIQ installed on the same machine you are reading this post on, click here and you should see them. Otherwise, adjust the URL above accordingly if you are reverse proxying your Sailpoint IIQ install or used a different context root for IIQ or what have you.

If you are doing any customization at all of your Sailpoint IIQ installation — be it in Java itself or in BeanShell — this URL will be indispensable for you. Set ‘er up and have fun reading JavaDocs to your children at bed time!

Tags: , , , , ,

SailPoint IIQ: Creating & Using Rule Libraries

September 19th, 2012 | No Comments | Posted in IAM Development

So you’ve been writing and using simple BeanShell rules in Sailpoint IIQ but you’ve come to a point in your solving of use cases where you’ve got code replication in various places. This, as in other development situations outside of Sailpoint IIQ, is a perfect scenario for consolidating such code into a library of some sort (you are thinking, right?!) and calling that code from the rules you are writing.

Code consolidation is just good, universally accepted development practice. But can this be done in Sailpoint IIQ, and if so, how? Glad you asked. Here’s how you do it. We’ll use an over-simplified example in a very easy use case to illustrate.

Creating A Rule Library

The easiest way to create a rule library from scratch is to go into the Sailpoint IIQ debug pages and grab a rule you already have. Grab the rule XML from the text area and cut and paste it into your favorite editor. Then pare your XML down to this:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule language="beanshell" name="My Library">
  <Source>

// My Library - only a comment for now... :-)

   </Source>
</Rule>

Ha, well I guess… there you go. You can now just use the above as a rule library template instead of digging this out of your Sailpoint IIQ debug pages. :-)

Save this to an XML file on your local hard drive. Make sure you change the name of the library on the 3rd line above to something that makes sense for you. Then import this XML into Sailpoint IIQ. You can import this XML in one of two ways:

(1) Navigate to the System Setup page and choose the “Import From File” option, or…
(2) Import from the IIQ console using the import command.

Now, re-navigate to your debug pages, re-list your rules and you should see a rule named “My Library” (or whatever else you might have named your rule). For updating this rule and actually adding code, you’ll need to edit this rule from right here in the debug pages as it’s not going to show up anywhere else, really. We’ll keep that in mind for later.

The Background/Sample Use Case

Okay, so now you’ve created a rule library — simply a place to stick code that will be shared by other rules. How to we reference this library?

Before we get into that, let’s look at our use case code. We have two build map rules for aggregation — one build map rule called from a CSV connector and the other build map rule from a JDBC connector. In both cases, we’re going to say each needs to build a string formatted a certain way, and we want to isolate this formatting to one place — in our new rule library — and call that code from both rules.

Here is the CSV build map rule:

// Imports.
import sailpoint.object.Schema;
import sailpoint.connector.Connector;
import sailpoint.connector.DelimitedFileConnector;

// Build an initial map from the current record.
HashMap map = DelimitedFileConnector.defaultBuildMap( cols, record );

// Only perform these steps for account aggregations.
if (schema.getObjectType().compareTo( Connector.TYPE_ACCOUNT ) == 0) {
   String path = map.get( "path" );
   String filename = map.get( "filename" );
   String filespec = path + "/" + filename;
   map.put( "filespec", filespec );
}

// Return the resulting map.  For group aggregations, the default
// map falls through and is returned.  For account maps, we return
// the modified map.
return map;

More »

Tags: , , , , , , , , , , ,

SailPoint IIQ: Keep Application From Aggregating

September 12th, 2012 | No Comments | Posted in IAM Development

One of the primary vendor products for which we at Qubera provide expert advisory and implementation services is Sailpoint IIQ. It’s really a terrific product in a lot of ways and it’s capable of some pretty incredible things in the GRC arena.

I won’t go into the whole sales pitch here. The main thing to note from a technical perspective is, Sailpoint IIQ is fairly easy to use out of the box. However, some of its sophistication necessarily brings some complexity, and under the covers, Sailpoint IIQ offers a plethora of customization options for the not-so-faint-of-heart.

I’ve been wanting to throw a few simple technical and business use cases around that can either serve as a taste for Sailpoint IIQ and it’s capabilities or, alternately, give you a starting point for some use cases you may need to solve on your own. As always, Qubera is there to help if you need expert implementation services — just give us a call. :-)

Let’s start with something really super simple, but for which some of you out there may have wanted to do and never thought of doing. Sometimes, it’s the simplest stuff that provides the most elegant solution. At the very least, it’s always interesting to me to see how others have solved problems.

Technical Use Case: Prevent Application from Accidental Aggregation

So you are in your Sailpoint IIQ sandbox or development environment. You’ve created an application using one connector type and then recreated that same application using another connector type. Say the first connector type was DelimitedFile (CSV), and you’ve now migrated that application to a JDBC connector. You don’t want to delete the DelimitedFile (CSV) connector application because there is perhaps BeanShell code you’ve developed or you’ve perfected a merge or entitlements situation to work just right (*).

Whatever the reason, you don’t want to delete the original connector, but yet… you want to make sure it is never accidentally aggregated either via a task or from the IIQ console. Remember, this is your development environment or sandbox… You would never do something like this in Production, would you?! (Then again, maybe you would?! :-))

In most cases, you could:

(1) Create a Build Map rule for the old connector — call it “BuildMap – Do Not Aggregate”.
(2) Simply return an empty HashMap.
(3) The connector will not aggregate and there will be no errors in most cases.

This will work for most applications, unless you had a Build Map rule that was creating either the application’s Identity Attribute or the Display Attribute.

// BuildMap - Do Not Aggregate
// Don't allow the application to aggregate -- just return an empty HashMap.
return new HashMap();

Salut from Montreal!


* – Yes, you could export the application to XML for safekeeping, and yes, any associated BeanShell code will still be accessible from the Debug pages even if the application definition is deleted. :-)

Tags: , , ,