Uploaded image for project: 'Confluence Data Center'
  1. Confluence Data Center
  2. CONFSERVER-35047

Confluence user synchronisation create duplicated user account after user rename in the remote repository

    XMLWordPrintable

Details

    Description

      Here are the step to reproduce:

      1. Set up an LDAP connector with Crowd and create an application with this user directory.
      2. Set up the Crowd user directory on Confluence with the incremental synchronisation option check.
      3. Once all the synchronisation is done.
      4. Change one of the user name on the LDAP repository.
      5. Wait a couple hours so that the Crowd is synchronise the change and Confluence also perform the incremental synchronisation.
      6. Restart Confluence, so that a full synchronisation will be triggered, but it is failed with the following error message:
        2014-09-24 10:26:47,356 INFO [scheduler_Worker-6] [atlassian.crowd.directory.DbCachingRemoteDirectory] synchroniseCache synchronisation for directory [ 1376257 ] starting
        
        2014-09-24 10:26:48,507 INFO [scheduler_Worker-6] [directory.ldap.cache.RemoteDirectoryCacheRefresher] findAllRemoteUsers found [ 4 ] remote users in [ 110ms ]
        
        2014-09-24 10:26:48,516 INFO [scheduler_Worker-6] [atlassian.crowd.directory.DbCachingRemoteChangeOperations] deleteCachedUsersNotIn scanned and compared [ 4 ] users for delete in DB cache in [ 7ms ]
        
        2014-09-24 10:26:48,516 INFO [scheduler_Worker-6] [atlassian.crowd.directory.DbCachingRemoteChangeOperations] deleteCachedUsersNotIn scanned for deleted users in [ 8ms ]
        
        2014-09-24 10:26:48,523 INFO [scheduler_Worker-6] [atlassian.crowd.directory.DbCachingRemoteChangeOperations] getUsersToAddAndUpdate scanning [ 4 ] users to add or update
        
        2014-09-24 10:26:48,526 INFO [scheduler_Worker-6] [atlassian.crowd.directory.DirectoryCacheImplUsingChangeOperations] addOrUpdateCachedUsers scanned and compared [ 4 ] users for update in DB cache in [ 9ms ]
        
        2014-09-24 10:26:48,527 INFO [scheduler_Worker-6] [atlassian.crowd.directory.DbCachingRemoteChangeOperations] updateUsers updating [ 1 ] users
        
        2014-09-24 10:26:48,536 INFO [scheduler_Worker-6] [atlassian.crowd.directory.DbCachingRemoteChangeOperations] updateUsers updated [ 1 ] users in [ 8ms ]
        
        2014-09-24 10:26:48,537 INFO [scheduler_Worker-6] [atlassian.crowd.directory.DirectoryCacheImplUsingChangeOperations] addOrUpdateCachedUsers synchronised [ 4 ] users in [ 20ms ]
        
        2014-09-24 10:26:48,537 INFO [scheduler_Worker-6] [atlassian.crowd.directory.DbCachingRemoteDirectory] synchroniseCache failed synchronisation complete for directory [ 1376257 ] in [ 1181ms ]
        
        2014-09-24 10:26:48,607 ERROR [scheduler_Worker-6] [atlassian.crowd.directory.DbCachingDirectoryPoller] pollChanges Error occurred while refreshing the cache for directory [ 1376257 ].
        
        org.springframework.dao.IncorrectResultSizeDataAccessException: query did not return a unique result: 2
        
        at org.springframework.orm.hibernate.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:590)
        
        at org.springframework.orm.hibernate.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:353)
        
        at org.springframework.orm.hibernate.HibernateTemplate.execute(HibernateTemplate.java:375)
        
        at org.springframework.orm.hibernate.HibernateTemplate.execute(HibernateTemplate.java:337)
        
        at com.atlassian.crowd.embedded.hibernate2.HibernateUserDao.internalFindUserByExternalId(HibernateUserDao.java:501)
        
        at com.atlassian.crowd.embedded.hibernate2.HibernateUserDao.internalFindByExternalId(HibernateUserDao.java:473)
        
        at com.atlassian.crowd.embedded.hibernate2.HibernateUserDao.findByExternalId(HibernateUserDao.java:449)
        
        at com.atlassian.confluence.user.crowd.CachedCrowdUserDao.findByExternalId(CachedCrowdUserDao.java:164)
        
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        
        at java.lang.reflect.Method.invoke(Method.java:606)
        
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
        
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
        
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
        
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
        
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
        
        at com.sun.proxy.$Proxy40.findByExternalId(Unknown Source)
        
        at com.atlassian.crowd.directory.AbstractInternalDirectory.findUserByExternalId(AbstractInternalDirectory.java:157)
        
        at com.atlassian.crowd.directory.DbCachingRemoteChangeOperations.updateUsers(DbCachingRemoteChangeOperations.java:224)
        
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        
        at java.lang.reflect.Method.invoke(Method.java:606)
        
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
        
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
        
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
        
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
        
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
        
        at com.atlassian.crowd.directory.$Proxy2232.updateUsers(Unknown Source)
        
        at com.atlassian.crowd.directory.DirectoryCacheImplUsingChangeOperations.addOrUpdateCachedUsers(DirectoryCacheImplUsingChangeOperations.java:59)
        
        at com.atlassian.crowd.directory.ldap.cache.RemoteDirectoryCacheRefresher.synchroniseAllUsers(RemoteDirectoryCacheRefresher.java:68)
        
        at com.atlassian.crowd.directory.ldap.cache.AbstractCacheRefresher.synchroniseAll(AbstractCacheRefresher.java:78)
        
        at com.atlassian.crowd.directory.ldap.cache.EventTokenChangedCacheRefresher.synchroniseAll(EventTokenChangedCacheRefresher.java:71)
        
        at com.atlassian.crowd.directory.DbCachingRemoteDirectory.synchroniseCache(DbCachingRemoteDirectory.java:1008)
        
        at com.atlassian.crowd.manager.directory.DirectorySynchroniserImpl.synchronise(DirectorySynchroniserImpl.java:75)
        
        at com.atlassian.crowd.directory.DbCachingDirectoryPoller.pollChanges(DbCachingDirectoryPoller.java:50)
        
        at com.atlassian.crowd.manager.directory.monitor.poller.DirectoryPollerJobBean.executeInternal(DirectoryPollerJobBean.java:29)
        
        at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:86)
        
        at org.quartz.core.JobRunShell.run(JobRunShell.java:199)
        
        at com.atlassian.confluence.schedule.quartz.ConfluenceQuartzThreadPool$1.run(ConfluenceQuartzThreadPool.java:20)
        
        at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549)
        
        2014-09-24 11:00:00,017 INFO [scheduler_Worker-5] [plugins.dailysummary.scheduling.SummaryEmailJob] execute Executing scheduled Summary Email Job
        
        2014-09-24 11:00:00,030 INFO [scheduler_Worker-5] [dailysummary.components.impl.DefaultSummaryEmailService] sendEmailForDate Summary email job firing @ Wed Sep 24 11:00:00 CEST 2014, scheduled fire time was : Wed Sep 24 11:00:00 CEST 2014.  false users to receive notifications.
        
        2014-09-24 11:00:00,030 INFO [scheduler_Worker-5] [plugins.dailysummary.scheduling.SummaryEmailJob] execute Completed scheduled Summary email job, 0 emails added to notification queue
        
        2014-09-24 11:26:47,243 INFO [scheduler_Worker-2] [atlassian.crowd.directory.DbCachingRemoteDirectory] synchroniseCache synchronisation for directory [ 1376257 ] starting
        
        2014-09-24 11:26:47,527 INFO [scheduler_Worker-2] [atlassian.crowd.directory.DbCachingRemoteDirectory] synchroniseCache INCREMENTAL synchronisation complete for directory [ 1376257 ] in [ 284ms ]
        

        And the output from the database shows that there are duplication user with the same external ID but a different user name on Confluence but not on Crowd:

        crowd_272=# select * from cwd_user where user_name like '%momo%'                                                                                                                                                                              ;
        
           id   | user_name | lower_user_name | active |      created_date       |      updated_date       | first_name | lower_first_name | last_name | lower_last_name | display_name | lower_display_name | email_address | lower_email_address |           external_id            | directory_id | credential 
        
        --------+-----------+-----------------+--------+-------------------------+-------------------------+------------+------------------+-----------+-----------------+--------------+--------------------+---------------+---------------------+----------------------------------+--------------+------------
        
         753666 | momo3     | momo3           | T      | 2014-09-23 10:13:16.352 | 2014-09-23 17:07:02.991 | MOMO       | momo             | A         | a               | MOMO A       | momo a             | momo@test     | momo@test           | 8224257f1e4c4542bf43c3f123da1037 |       720897 | nopass
        
        (1 row)
        
        
        
        crowd_272=# \c conf_552;
        
        You are now connected to database "conf_552" as user "yilinmo".
        
        conf_552=# select * from cwd_user where user_name like '%momo%';       
           id    | user_name | lower_user_name | active |      created_date       |      updated_date       | first_name | lower_first_name | last_name | lower_last_name | display_name | lower_display_name | email_address | lower_email_address |               external_id               | directory_id | credential 
        
        ---------+-----------+-----------------+--------+-------------------------+-------------------------+------------+------------------+-----------+-----------------+--------------+--------------------+---------------+---------------------+-----------------------------------------+--------------+------------
        
         1441795 | momo2     | momo2           | T      | 2014-09-23 10:33:12.736 | 2014-09-23 15:06:57.776 | MOMO       | momo             | A         | a               | MOMO A       | momo a             | momo@test     | momo@test           | 720897:8224257f1e4c4542bf43c3f123da1037 |      1376257 | nopass
        
         1900545 | momo3     | momo3           | T      | 2014-09-23 18:06:27.583 | 2014-09-23 18:06:27.583 | MOMO       | momo             | A         | a               | MOMO A       | momo a             | momo@test     | momo@test           | 720897:8224257f1e4c4542bf43c3f123da1037 |      1376257 | X
        
        (2 rows)
        

        So it seems that the incremental synchronisation is creating a duplicated user based on the user name instead of the external ID.

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              yilinmo Yilin (Inactive)
              Votes:
              15 Vote for this issue
              Watchers:
              18 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: