Bug #124
Clean phase of db2ldap deletes all entities
| Status: | Feedback | Start: | 13/10/2009 | |
|---|---|---|---|---|
| Priority: | High | Due date: | ||
| Assigned to: | - | % Done: | 0% |
|
| Category: | Documentation | |||
| Target version: | - | |||
| Problem in version: |
Description
During the clean phase of a db2ldap job, all entities in the destination are deleted.
After tracking the problem a bit, it seems that the method clean2Ldap of org.lsc.AbstractSynchronize loops on all destination entries and calls the getObject method of org.lsc.service.AbstractJdbcService passing it the id of the entry (to look for it in the source).
The problem is that the format of the id is the DN of the LDAP entry (uid=john.do,dc=mydomain,dc=com) and in the case of a JDBC source, that value is irrelevant.
History
Updated by Jonathan Clarke 10 months ago
Hi,
Thanks for the report. Which version are you seeing this on?
The id parameter that is passed to the JDBC source should be a structure containing a string (the DN you describe), and a map of parameter names and values that are passed into your SQL select query. Could you provide an extract of your configuration (dstService.*) and an extract of your sqlMap?
Thanks,
Jonathan
Updated by Jérôme Schell 10 months ago
Hi Jonathan,
I'm using v1.1.0.
I think I don't understand how Ibatis works ;)
After adding some debugging code, I have seen what you told about the parameters map. In my case the map contains the field "uid" with the good value for it. Nevertheless the source object is not found.
Here is some portions of my configuration.
lsc.properties:
lsc.tasks.mytask.srcService.pivotAttrs = uid
lsc.tasks.mytask.srcService = org.lsc.service.InetOrgPersonJDBCService
lsc.tasks.mytask.srcService.attrs = uid userPassword mail supannCivilite sn givenName birthDate promotion supannCodeINE street postalCode l homePhone mobile supannMailPerso jpegPhoto
...
lsc.tasks.mytask.dstService.pivotAttrs = uid
lsc.tasks.mytask.dstService.filterId = (&(objectClass=inetOrgPerson)(uid={logname}))
lsc.tasks.mytask.dstService.filterAll = (&(objectClass=inetOrgPerson))
lsc.tasks.mytask.dstService.baseDn = ou=people
lsc.tasks.mytask.dstService.attrs = uid userPassword mail sn givenName cn displayName objectClass street postalCode l homePhone mobile jpegPhoto ...
lsc.tasks.mytask.dstService = org.lsc.jndi.SimpleJndiDstService
sql-map-config.d/InetOrgPerson.xml:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="InetOrgPersonJDBCService">
<typeAlias alias="InetOrgPerson" type="org.lsc.objects.flat.fInetOrgPerson" />
<resultMap id="InetOrgPersonResult" class="InetOrgPerson">
<result property="uid" column="logname"/>
<result property="userPassword" column="logpassw"/>
<result property="mail" column="email"/>
<result property="sn" column="nom"/>
<result property="givenName" column="prenom"/>
<result property="street" column="adrl1"/>
<!-- ... -->
</resultMap>
<select id="getInetOrgPerson" resultMap="InetOrgPersonResult" parameterClass="java.util.Map">
<!-- FILL IT, BE CAREFULL AT SPECIAL CHARACTER REPRESENTATION -->
Select
ideleve,
logname,
logpassw,
nom,
prenom,
email,
FROM mytable
WHERE logname = #logname#
</select>
<select id="getInetOrgPersonList" resultClass="java.util.HashMap">
<!-- FILL IT, BE CAREFULL AT SPECIAL CHARACTER REPRESENTATION -->
Select logname
FROM mytable
WHERE logname IS NOT NULL AND
logname != ""
</select>
The sync phase is working ok with that configuration.
Updated by Jérôme Schell 10 months ago
I think the problem is in the name of the key attribute.
Correct me if I'm wrong...
- entries are retrieved from source (database)
- loop is performed on the list and corresponding objects are search in the destination LDAP (method synchronize2Ldap of AbstractSynchronize)
- getObject method of AbstractJdbcService is called with attribute map containing "logname = value"
- it works ok
- entries are retrieved from destination (LDAP)
- loop is performed on the list and corresponding objects are search in the source database (method clean2Ldap of AbstractSynchronize)
- getObject method of AbstractJdbcService is called with attribute map containing "uid = value"
- it doesn't work
So what should I put in lsc.properties or SQL map in order for this to work?
Updated by Jérôme Schell 10 months ago
I resolved my problem for now by renaming the key attribute in the database table to "uid" instead of "logname".
This way it all seems to work ok.
My primary interrogation is still valid. What is the good configuration to have the clean and sync phase working when the keys have different name in database and LDAP?
Updated by Jonathan Clarke 10 months ago
- Category changed from Core to Documentation
- Status changed from New to Feedback
Jérôme Schell wrote:
I resolved my problem for now by renaming the key attribute in the database table to "uid" instead of "logname". This way it all seems to work ok.
My primary interrogation is still valid. What is the good configuration to have the clean and sync phase working when the keys have different name in database and LDAP?
Hi Jérôme,
You are right about the problem here - the name of the pivot is different in sync and clean modes: you use logname to sync, and uid to clean. So when iBatis runs your getInetOrgPerson request, it only has a parameter uid, but doesn't use it.
The simplest solution is to change your SQL requests to use the "SELECT <DB pivot> AS <LDAP pivot>". For example, here, you would change getInetOrgPersonList to "Select logname AS uid ...", and getInetOrgPerson to "Select ... WHERE logname = #uid#". And of course remove uid from the resultMap. And, you should then change lsc.tasks.mytask.dstService.filterId to use {uid} instead of {logname}. Please let us know how it goes.
This is bug #35 (see the discussion there). As a general rule, I try to map all information to LDAP attribute names as soon as possible (in the SQL requests).
I think the documentation doesn't reflect this clearly (or at all). Any volunteers to update the wiki?
Jonathan
Updated by Jérôme Schell 10 months ago
Ok thanks Jonathan, this works.
Nevertheless, if I remove <result property="uid" column="uid"/> from the resultMap, I get a NPE:
0 - WARN - Starting sync for mytask (db2ldap)
620 - ERROR - java.lang.NullPointerException
java.lang.NullPointerException
at org.lsc.AbstractSynchronize.logActionError(AbstractSynchronize.java:476)
at org.lsc.AbstractSynchronize.synchronize2Ldap(AbstractSynchronize.java:436)
at org.lsc.SimpleSynchronize.launchTask(SimpleSynchronize.java:291)
at org.lsc.SimpleSynchronize.launch(SimpleSynchronize.java:179)
at org.lsc.Launcher.run(Launcher.java:125)
at org.lsc.Launcher.main(Launcher.java:113)
When I leave it, it works.