A blog about Identity Integration, with a very large focus on Microsoft Identity Integration Server (MMS),(MIIS),(ILM), (ILM2), (YETA) and identity in the Microsoft platform.

Wednesday, June 25, 2008

Over Communicate

Since early last year I've been meaning to point people to trace logging in .NET instead of using the logging facility in ILM, which might explain why I jumped at the opportunity to harp about it on the TechNet forum.

Last year I stumbled upon trace logging while doing some work using WCF. The log viewer they had was awesome, and I realized it wasn't tied to WCF in any way so it could be a great tool for logging in the ILM sync engine. For more info on the tool, check out:
Using the Service Trace Viewer Tool

As cool as the log viewer is, it is really just the tip of the logging iceberg. Tracing in .NET has some cool features, including:
  • Trace sources spew as much detail as possible in your code
  • Trace listeners only collect the detail they're interested in
  • Trace levels are configured in app config files
  • Trace output can be directed to a number of different formatters

The WCF contents in MSDN have some pretty good examples to start with.

Here is how it applies to ILM:

With your extension code:

  1. Use a TraceSource in your ILM extension code
  2. Call the TraceInfo event to output logging details in your code
  3. Compile the extension with the Trace flag on (it is on by default in Visual Studio)

Now your extension is able to spew log output, but nothing happens until you configure it:

  1. Add a System.Diagnostics section to the miiserver.exe.config file (assuming your extensions run in-process)
  2. Cycle the miiserver process (so it can read the config file)
  3. Check out the fruits of your logging labour

On a regular basis, you may choose to leave logging at a lower level to improve performance. Then during hard times, up the logging to Verbose to figure out what is going on in your extensions.

Saturday, June 21, 2008

When Reliable Sessions Aren't

As an Exchange 4.0 administrator I always wished they'd put the Outlook dev team on the wrong end of a very narrow network connection. This I thought was suitable torture and payback with the glimmer of hope that someday the app would be more reliable on network.

Having produced an XMA to consume web services using WCF I was confident to be standing on the shoulders of WS-ReliableMessaging giants, but my confidence proved to be just cocky.

In the XMA Export routines we have three main players:

1. Begin_Export (where we tend to open connections)
2. Export_Entry (where we tend to use connections)
3. End_Export (where we tend to close connections)

So what happens if the connection dies during Export_Entry? It does happen (although NEVER in my test environment, but I would like a test server co-hosted in my ideal location for the Outlook team). What to do when connections die?

The overall approach is to retry the connection. There are a few challenges in this approach, but overall it isn't that bad.

Exposing the Connection Details and ConfigurationParameters to Export_Entry
In order to retry the connection, you probably need access to the connection details (connectTo, user, password) and the configurationParameters, so any data required to create the connection needs to be available in Export_Entry.

Admitting Defeat
Retrying the connection for an unlimited number of tries won't do anybody any good. Impose some limit on the retries, and even consider making this limit configurable.

FatalEntryExportException
Each call to Export_Entry can throw an exception while allowing the rest of the export run to continue. This per-object failure is handy if the rest of the objects have a chance of succeeding.

In the 'connection limit exceeded' scenario, we know the remote side is just dead, and that the remaining exports should be stopped. This can be achieved by throwing the FatalEntryExportException. This specific exception stops the rest of the exports from processing, leaving the remaining exports as pending exports in the CS, ready to be tried again.

In the list of exceptions available in an XMA, the only one that stops the run is the FatalEntryExportException. The rest let the XMA continue processing other exports.

Friday, June 20, 2008

Export_Password, More Please!

Export_Password is a pretty neat attribute introduced for ILM Password Management. It is neat because it is the attribute you can set and forget, so no nagging export-not-reimported errors if you export it and don't expect it to come back (I've had pets like that).

It works really well when creating objects in an MA where you have a password extension, such as an XMA. In provisioning code you do something like this:

ManagementAgent = mventry.ConnectedMAs["ELMA"];
if (ManagementAgent.Connectors.Count == 0)
{
csentry = ManagementAgent.Connectors.StartNewConnector("person");
csentry["export_password"].StringValue = "is this thing on?"; csentry.CommitNewConnector();
}

It doesn't work so well if you are not provisioning a new object. If you try to use it on an existing connector you'll get an InvalidOperationException, so this will not work:

ManagementAgent = mventry.ConnectedMAs["ELMA"];
if (ManagementAgent.Connectors.Count == 1)
{
ManagementAgent.Connectors.ByIndex[0]["export_password"].StringValue = "is this thing on?";
}

If that worked then it would enable a scenario currently implemented in the Live@Edu solution where Import Attribute Flow can trigger a password reset in LiveID. It only really works because the MA doesn't do imports, thereby sidestepping the Export-Not-Reimported error.

If Export_Password worked on existing connectors then we'd have the same functionality, plus we wouldn't need to worry about Export-Not-Reimported.

I'll add it to my wish list unless somebody has some sneaky/cool alternatives.

Monday, November 19, 2007

WCF LOB Adapter SDK - The Future of the XMA?

People have been talking about ILM adopting the WCF LOB Adapter SDK sometime in the future. What does that mean to you? Personally I'm excited about it, since it has the opportuntity to improve the XMA experience for ILM fans. I'm doing a talk on XMAs at DEC 2008, and might have a demo ready by then using an XMA with the WCF LOB Adapter SDK. In the meantime if you are curious here are some links:

Thursday, November 15, 2007

ILM 2007 FP1

FP1 is available for download now. Look for new and improved Exchange 2007 provisioning support on the ADMA (check out the last property page of the MA). Haven't tried this in a lab yet but the installation didn't ask me about PowerShell so I am not sure what will happen when I provision a new mailbox with the ADMA.

Wednesday, November 07, 2007

DEC 2008 - Anybody Up For A Hockey Game?

Vegas will be sadly missed but I'm pretty excited about the opportunity to speak at the Directory Experts Conference again (this time in Chicago, anybody up for a hockey game?).

Here's a peek into what my session will be:

ILM Extensibility
Hello my name is Craig, and I have a problem. I get XMA hammered on a regular basis. Every problem is a nail and I pound it with my trusty XMA. In this session the Open Source LDAP XMA will be used as a basis for discussion on XMA development, including when and how to use and XMA, but more importantly, when NOT to use and how NOT to use the XMA.

Wednesday, August 22, 2007

DirSync Control - SearchResult Without ObjectClass

The DirSync control is super-easy to use in .NET 2.0 with System.DirectoryServices. It is really as easy as adding one line to your regular DirectorySearcher.
DirectorySearcher searcher = new DirectorySearcher();
searcher.DirectorySynchronization = new DirectorySynchronization();

Once your query is done you can get the cookie quite easily:
Byte[] cookie = searcher.DirectorySynchronization.GetDirectorySynchronizationCookie();

I was happily using this in an XMA when I ran into what I suspect is a bug. ILM requires the objectClass when you import deleted objects. The dirSync control dutifully shows me the objectGuid (my MA's anchor attribute) then I ask it for the objectClass attribute. The attribute is there on the tombstone, I can see it using LDP. The attribute is in the DirectorySearcher's PropertiesToLoad collection, but sometimes when I ask for the objectClass it just isn't there.

Turns out this repros consistently. If the first SearchResult returned by the DirSync search is a delete then the objectClass attribute will not be present in the SearchResult.Properties collection. It will be there for the remaining SearchResult objects, but not the first.

The workaround for my MA was to put the DN back together using the 'name' and 'lastKnownParent' attributes on the tombstone, then find the objectClass using a WMI search of the ILM CS. Bugger, but the workaround works.

Attribute Replace or Object Replace?

Recently I ran into a fun issue with a DSML import in ILM. For years I've assumed delta imports for file MAs did attribute level deltas, meaning that the delta import did not require the full attribute set, only the changed attributes. For example, if an object has ten attributes in the CS and your delta file only has one attribute then the import should just update that one attribute and leave the rest alone, right?

Wrong. My assumption was wrong (for years) and the delta import needs to contain the full attribute set. Importing a delta with missing attributes will result in those missing attributes being deleted from the CS object, which will in turn trigger the sync rules and cause re-population if any other MA is contributing.

I ran into this when doing a dirSync delta for the LDAP XMA. The dirSync control neatly tells you the exact attributes that have changed, so you can package them up into the DSML file and hand it over to ILM. On import I was seeing attributes getting whacked which proved that indeed there is a lot to learn ;-) This problem didn't repro with the changeLog deltas we do on the LDAP XMA because for changeLog we just go to the DS to get the real object, instead of parsing the LDIF from the changeLog entry into DSML for our import file. Turns out that is exactly the way to do it for dirSync deltas too.