Thursday, November 20, 2014

Connections 5 - External Users - I walked straight into the trap!

After enabling External Users in Connections 5, I started getting TDI (Yes, I still call it TDI, even though the new name is SDI) sync errors on existing profiles.

The error that showed in the tdi log was just:
14:06:06,665 ERROR - !com.ibm.lconn.profiles.api.tdi.service.TDIException: CLFRN1254E: An error occurred while performing findEntry: USERNAME.!
14:06:06,665 INFO  - CTGDIS274I Skipping entry from [addorUpdateDB], CTGDIS393I Throwing this exception to tell the AssemblyLine to skip the current Entry. If used in an EventHandler, this exception tells the EventHandler to skip the remaining actions..

And after enabling all kinds of TDI debugging, still no luck in expanding the error message into a more understandable one.

I reached out to a lot of people on this, and we struggled for a while discussing "has the TDISOL dir changed..... Has there been dominoUNID changes in your domino ldap.... Has the dbschema changed for the profilesDB.... Which tdi version are you on.....

But no luck.

I did notice, after doing a step-by-step debugging into the AssemblyLine, that the "addorUpdateDB" script had a
ProfileConnector.connector.putEntry(theEntry);
Which immediatly after being run gave the error message.

And using the javascript execution field inside the debugger, I could do a listing of that "theEntry" contained:
theEntry >> {
    "mobileNumber": [],
    "preferredLanguage": "",
    "jobResp": [],
    "displayNameLdapAttr": "Ole Anders Elgen",
    "employeeTypeCode": "",
    "orgId": "Company AS",
    "displayName": "Ole Anders Elgen",
    "faxNumber": "",
    "officeName": "",
    "surname": "Elgen",
    "secretaryUid": [],
    "givenName": "Ole Anders",
    "telephoneNumber": [],
    "uid": "oleand",
    "deptNumber": [],
    "employeeNumber": [],
    "mode": [],
    "email": "oleandelgen@company.com",
    "guid": "31E00858-3759-5A61-C125-7D96002AEF61",
    "workLocationCode": "",
    "decorateVisitorDisplayName": "",
    "description": "",
    "distinguishedName": "CN=Ole Anders Elgen,O=Company",
    "givenNames": "Ole Anders",
    "surnames": "Elgen",
    "managerUid": "",
    "title": []
}

 
Looks good, right?
But what´s not good is that the field "mode" is set to empty brackets... Which actually means that tdi interprets this as "null".
 So I reached out to my good friend, Eddie Hartman, and he helped me debug even more.

Eddie helped me figure out which class is used by entering commands like, while running the tdi debugger:
sw = java.io.StringWriter();
pw = java.io.PrintWriter(sw);
e.printStackTrace(pw);
pw.close();
task.logmsg(sw.toString());

We opened up a Java Decompiler, opened up the profiles_tdi.jar file and found the correct class.
The class was:
com.ibm.lconn.profiles.api.tdi.util.TDIServiceHelper.TDIServiceHelper.entryToDescriptor
Here we noticed that 

Here it checks the length of the field "mode"... No "null" checking to see if the object actually exists.

So the reason for my sync errors was a trap that I walked straight into!!

To sum up why i walked into the trap:

In CNX5 there´s a new option to create external users and bring them into communities where you can collaborate with them.

In order to do this, there has to be a field in the person document in the ldap server which has the value “external”. (There are other ways as well, but I chose this one)
This is defined in the "map_dbrepos_from_source.properties” file.

I set this to:
mode=memberType
and then created a tdi job which set this field on the external users in the domino ldap.
Value of the memberType field is just a text string I set to "external".

But I forgot to read, or I misread, the comments on this field, which says:

# In all cases, the value of the LDAP attribute/js-function must be one of two strings.
# either "internal" for employees or "external" for visitors.  Actually, any string other
# than “external" is interpreted as employee.

I thought that “any other string” meant also that the field did not have to exist… But alas…

And the domino usersdocuments does not have this as a field originally!! That´s why we saw this as “null”.
So, problem was solved as soon as I created this field in the domino userdocument, all of the documents.

I could perhaps used an already created domino field for this :-)

Thanks to Martin, Sjaak, Rainer, Lars, Keith and Klaus for participating in the debug-discussion! And of course: Eddie Hartman for President!!




2 comments:

webstick said...

Typically you would define a javascript function which evaluates the current work item. While iterating thru all your users, you somehow need to differ between internal users or external users.

So, it does not have to be a direct LDAP attribute which contains the value "external". It could be also the mail address which includes the term ".external". Or a specific LDAP tree and you evaluate $DN property.

At the end, the javascript function returns either "external" or "internal" (or an empty string "", which would be an internal user).

Robert Farstad said...

Thanks for this. The next implementation of Connections, I´ll try the javascript method.