0

我正在使用 Tivoli Directory Integrator (TDI) 将用户从 Domino LDAP 同步到 HCL Connections 的本地 DB2 人员数据库。在测试安装中,尝试初始同步用户时出现以下错误:

[root@cnx65 tdisol]# LANG=en_US.utf8 ./sync_all_dns.sh 
create synchronization lock
log4j:WARN No appenders could be found for logger (server).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
**********
CLFRN1275I: Begin to hash records in database.
CLFRN1269I: Finish hash records in database.
**********
"message": "CLFRN1254E: An error occurred while performing findEntry: {0}."
"exception": "com.ibm.lconn.profiles.api.tdi.service.TDIException: CLFRN1254E: An error occurred while performing findEntry: {0}."
Synchronize of Database Repository failed

HCLs 文档建议在CLFRN1254E. 该文件logs/SyncUpdates.log包含以下异常:

2020-01-21 07:50:03,803 INFO  [org.apache.log4j.DailyRollingFileAppender.7431103d-4d0a-4d63-bdb7-61e274f23ed4] - CTGDIS092I Use entry provided at runtime as work entry (first pass only).
2020-01-21 07:50:11,723 ERROR [org.apache.log4j.DailyRollingFileAppender.7431103d-4d0a-4d63-bdb7-61e274f23ed4] - [hash_db_entries] CTGDIS181E Error while evaluating the hook 'Function error' in the component 'hash_db_entries (hash_db_entries.functioncall_fail).
com.ibm.lconn.profiles.api.tdi.service.TDIException: CLFRN1254E: An error occurred while executing findEntry: {0}.
        at com.ibm.lconn.profiles.api.tdi.connectors.ProfileConnector$ProfileCodeBlock.handleRecoverable(ProfileConnector.java:1063)
        at com.ibm.lconn.profiles.api.tdi.connectors.Util.TDICodeRunner.run(TDICodeRunner.java:41)
        at com.ibm.lconn.profiles.api.tdi.connectors.ProfileConnector.getNextEntry(ProfileConnector.java:155)
        at com.ibm.di.server.AssemblyLineComponent.executeOperation(AssemblyLineComponent.java:3370)
        at com.ibm.di.server.AssemblyLineComponent.getnext(AssemblyLineComponent.java:932)
        at com.ibm.di.server.AssemblyLine.msGetNextIteratorEntry(AssemblyLine.java:3689)
        at com.ibm.di.server.AssemblyLine.executeMainStep(AssemblyLine.java:3388)
        at com.ibm.di.server.AssemblyLine.executeMainLoop(AssemblyLine.java:3000)
        at com.ibm.di.server.AssemblyLine.executeMainLoop(AssemblyLine.java:2983)
        at com.ibm.di.server.AssemblyLine.executeAL(AssemblyLine.java:2952)
        at com.ibm.di.server.AssemblyLine.run(AssemblyLine.java:1319)
Caused by: org.springframework.jdbc.BadSqlGrammarException: SqlMapClient operation; bad SQL grammar []; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:
--- The error occurred while applying a parameter map.
--- Check the TDIProfile.get-InlineParameterMap.
--- Check the statement (query failed).
--- Cause: com.ibm.db2.jcc.c.SqlException: DB2 SQL error: SQLCODE: -551, SQLSTATE: 42501, SQLERRMC: LCUSER;SELECT;EMPINST.EMPLOYEE
        at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:97)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
        at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:212)
        at org.springframework.orm.ibatis.SqlMapClientTemplate.executeWithListResult(SqlMapClientTemplate.java:249)
        at org.springframework.orm.ibatis.SqlMapClientTemplate.queryForList(SqlMapClientTemplate.java:296)
        at com.ibm.lconn.profiles.internal.service.store.sqlmapdao.TDIProfileSqlMapDao.get(TDIProfileSqlMapDao.java:50)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:88)

可能是什么问题呢?我怎样才能找到更多信息为什么会发生此错误?

我已经尝试过的

提高日志级别

profiles_tdi.properties我为每个组件启用调试日志时:

debug_collect=true
debug_draft=true
debug_fill_codes=true
debug_managers=true
debug_photos=true
debug_pronounce=true
debug_special=true
debug_update_profile=true
trace_profile_tdi_javascript=on

由于这没有效果,我将 log4j 级别设置为调试整个应用程序etc/log4j.properties

log3j.rootCategory=DEBUG, Default

也试过ALL代替DEBUG. 但是,输出没有变化。我希望看到导致异常的 SQL 查询。

mode在属性中设置

根据这篇文章,该mode属性将用于决定用户是内部用户还是外部用户。由于示例配置说

Actually, any string other than "external" is interpreted as employee.

它设置为mode=memberType。也试过mode=uidmode=mail。两者都是包含不等于“外部”的字符串的字段,因此这应该导致所有成员都作为内部用户导入。

同步单个用户

由于我的 LDAP 过滤器适用于大约 60 个用户,因此我./collect_dns.sh成功运行并从collect.dns文件中删除了除我自己之外的所有用户。然后将 dn 文件中的用户与./populate_from_dn_file.sh. 这是为另外两个用户完成的,总是导致相同的错误:

CLFRN0027I: After operation, success records is 0, duplicate records 0, failure records is 1, and last successful entry is null.
CLFRN1280I: 20200121105123 Iterations total number: 1.

唯一的区别是它logs/PopulateDBFromDNFile.log包含有关获取的属性、映射等的更详细信息。不幸的是,它在错误方面并没有真正帮助我,因为它会产生类似的消息:

2020-01-21 10:55:27,530 INFO  [com.ibm.di.log.FileRollerAppender.268b5e1d-d0fc-4a7c-9e12-4d742c44faa5] - [callSyncDB_mod] [add_manager_data] [setup_if_lookup] CTGDIS126I Return false.
2020-01-21 10:55:27,530 INFO  [com.ibm.di.log.FileRollerAppender.268b5e1d-d0fc-4a7c-9e12-4d742c44faa5] - [callSyncDB_mod] [add_manager_data] [setup_if_lookup] CTGDIS123I Returned object class java.lang.Boolean.
2020-01-21 10:55:27,530 INFO  [com.ibm.di.log.FileRollerAppender.268b5e1d-d0fc-4a7c-9e12-4d742c44faa5] - [callSyncDB_mod] [add_manager_data] CTGDIS075I Trying to exit TaskCallBlock.
2020-01-21 10:55:27,531 INFO  [com.ibm.di.log.FileRollerAppender.268b5e1d-d0fc-4a7c-9e12-4d742c44faa5] - [callSyncDB_mod] [add_manager_data] CTGDIS076I Succeeded exiting TaskCallBlock.
2020-01-21 10:55:27,531 INFO  [com.ibm.di.log.FileRollerAppender.268b5e1d-d0fc-4a7c-9e12-4d742c44faa5] - [callSyncDB_mod] [add_manager_data] CTGDIS057I Hook after_functioncall not enabled.
2020-01-21 10:55:27,531 INFO  [com.ibm.di.log.FileRollerAppender.268b5e1d-d0fc-4a7c-9e12-4d742c44faa5] - [callSyncDB_mod] CTGDIS352I Use null Behavior for $_already_lookup_manager.
2020-01-21 10:55:27,531 INFO  [com.ibm.di.log.FileRollerAppender.268b5e1d-d0fc-4a7c-9e12-4d742c44faa5] - [callSyncDB_mod] CTGDIS351I Map Attribute $manager_uid [1].
2020-01-21 10:55:27,531 INFO  [com.ibm.di.log.FileRollerAppender.268b5e1d-d0fc-4a7c-9e12-4d742c44faa5] - [callSyncDB_mod] CTGDIS353I Script is: conn["$manager_uid"]
2020-01-21 10:55:27,531 INFO  [com.ibm.di.log.FileRollerAppender.268b5e1d-d0fc-4a7c-9e12-4d742c44faa5] - [callSyncDB_mod] CTGDIS352I Use null Behavior for $manager_uid.
2020-01-21 10:55:27,531 INFO  [com.ibm.di.log.FileRollerAppender.268b5e1d-d0fc-4a7c-9e12-4d742c44faa5] - [callSyncDB_mod] [add_manager_data] CTGDIS057I Hook functioncall_ok not enabled.
2020-01-21 10:55:27,531 INFO  [com.ibm.di.log.FileRollerAppender.268b5e1d-d0fc-4a7c-9e12-4d742c44faa5] - [callSyncDB_mod] [add_manager_data] CTGDIS057I Hook default_ok not enabled.
2020-01-21 10:55:27,538 INFO  [com.ibm.di.log.FileRollerAppender.268b5e1d-d0fc-4a7c-9e12-4d742c44faa5] - [callSyncDB_mod] Result: <My Name of the User in dn file>
2020-01-21 10:55:27,591 ERROR [com.ibm.di.log.FileRollerAppender.268b5e1d-d0fc-4a7c-9e12-4d742c44faa5] - [callSyncDB_mod] [ProfileConnector] SqlMapClient operation; bad SQL grammar []; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:
--- The error occurred while applying a parameter map.
--- Check the TDIProfile.get-InlineParameterMap.
--- Check the statement (query failed).
--- Cause: com.ibm.db2.jcc.c.SqlException: DB2 SQL error: SQLCODE: -551, SQLSTATE: 42501, SQLERRMC: LCUSER;SELECT;EMPINST.EMPLOYEE
4

1 回答 1

0

发现这是我一个不幸的逻辑错误。该数据库是使用 SQL 文件创建的,随 Connections 安装向导一起提供。我会自动循环导入它们。由于它非常慢(所有脚本大约需要 30 分钟),我尝试通过&在命令末尾添加 a 来并行化它们,最后wait在末尾添加以确保所有脚本都已执行。

- name: Check and create non existing DBs for CNX
  become: yes
  become_user: "{{ db2.instance.name }}"
  shell: |
    db={{ item.name }}
    scripts=({{ item.files | join(' ') }})
    existing_dbs=$(echo -e '{{ existing_dbs.stdout }}')
    echo "Check db ${db}"

    if ! echo ${existing_dbs} | grep -q ${db}; then
      echo "DB ${db} doesn't exist, execute scripts"
      for script in "${scripts[@]}"
      do
        echo "${db}: Execute script ${script}"
        {{ db2.target }}/bin/db2 -td@ -f {{ cnx_sql_dir }}/${script} &
      done
      wait
    fi
  register: db_check
  changed_when: "'execute scripts' in db_check.stdout"
  loop: "{{ cnx.db_scripts }}"

cnx.db_scripts是数据库名称到 SQL 文件的映射:

  db_scripts:
    - name: PEOPLEDB
      files:
        - profiles/db2/createDb.sql
        - profiles/db2/appGrants.sql
    - name: FORUM
      files: 
         # - ...

回想起来,这是一个可怕的逻辑错误,因为我错过了这些脚本相互依赖的事实:当在完成profiles/db2/appGrants.sql之前执行profiles/db2/createDb.sql时,它不会工作,因为数据库不存在。

结果,TDI 查询失败,因为数据库和表只创建了一部分。我没有立即注意到这一点,因为在 Ansible playbook 开发过程中多次重新部署了机器。奇怪的是,TDI 在 10 次部署中只有 2 次失败。似乎 DB2 制作了某种队列,并且根据时间,在某些运行中成功创建了 TDI 所需的人员数据库。

于 2020-01-21T11:14:17.987 回答