{"id":7193,"date":"2021-05-05T17:43:49","date_gmt":"2021-05-05T15:43:49","guid":{"rendered":"https:\/\/u-labs.de\/portal\/?p=7193"},"modified":"2021-05-05T17:43:50","modified_gmt":"2021-05-05T15:43:50","slug":"hcl-connections-touchpoint-erscheint-immer-wieder-ursache-und-workaround","status":"publish","type":"post","link":"https:\/\/u-labs.de\/portal\/hcl-connections-touchpoint-erscheint-immer-wieder-ursache-und-workaround\/","title":{"rendered":"HCL Connections Touchpoint erscheint immer wieder: Ursache und Workaround"},"content":{"rendered":"<p>In der Standardkonfiguration von HCL Connections Touchpoint bekamen wir das Feedback, dass die Software st\u00e4ndig automatisch neu aufgerufen werde. Nicht in Intervallen von Monaten, sondern Tagen &#8211; teils sogar Stunden. Dies war nat\u00fcrlich nicht Sinn der Sache. Zusammen mit Christoph St\u00f6ttner habe ich das Problem analysiert und es konnte ein Workaround gefunden werden.<\/p>\n<h2 class=\"wp-block-heading\">Was ist Touchpoint?<\/h2>\n<p>Die Software ist m\u00f6glicherweise noch gar nicht allen bekannt. Bei Touchpoint handelt es sich um eine Art <em>Onboarding-Assistent<\/em>: Neue Nutzer werden durch wichtige Systemfunktionen gef\u00fchrt. Dazu geh\u00f6rt beispielsweise das Ausf\u00fcllen ihres Profiles oder dem Folgen von Communitys\/Kollegen. Zus\u00e4tzlich kann man den Nutzer auf seine Datenschutzerkl\u00e4rung und Nutzungsbedingungen verweisen, sodass zur Verwendung des Systemes beides akzeptiert werden muss. Praktisch: Die Nutzungsbedingungen k\u00f6nnen versioniert werden. Steht eine neue Version zur Verf\u00fcgung, \u00f6ffnet sich der Touchpoint automatisch erneut.<\/p>\n<p>Touchpoint gibt es zwar bereits seit einigen Jahren. Bisher jedoch als eigenst\u00e4ndige Komponente, die h\u00e4ndisch installiert werden musste. Mit Connections 6.5.1 \u00e4nderte HCL dies und lieferte die Anwendung standardm\u00e4\u00dfig mit Connections aus &#8211; allerdings nicht aktiv. Wer sie nutzen m\u00f6chte, muss sie in der <strong>touchpoint-config.xml <\/strong>aktivieren.<\/p>\n<h2 class=\"wp-block-heading\">Wo werden die Daten gespeichert?<\/h2>\n<p>Diese Frage war essenziell, um das Problem \u00fcberhaupt sinnvoll analysieren zu k\u00f6nnen. S\u00e4mtliche Daten werden als benutzerdefinierte Profilfelder in der PeopleDB-Tabelle <strong>PROFILE_EXTENSIONS<\/strong> gespeichert und somit einem Connections-Profil zugeordnet:<\/p>\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/u-labs.de\/portal\/wp-content\/uploads\/2021\/05\/grafik-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"84\" src=\"https:\/\/u-labs.de\/portal\/wp-content\/uploads\/2021\/05\/grafik-1-1024x84.png\" alt=\"\" class=\"wp-image-7194\" srcset=\"https:\/\/u-labs.de\/portal\/wp-content\/uploads\/2021\/05\/grafik-1-1024x84.png 1024w, https:\/\/u-labs.de\/portal\/wp-content\/uploads\/2021\/05\/grafik-1-300x25.png 300w, https:\/\/u-labs.de\/portal\/wp-content\/uploads\/2021\/05\/grafik-1-768x63.png 768w, https:\/\/u-labs.de\/portal\/wp-content\/uploads\/2021\/05\/grafik-1-70x6.png 70w, https:\/\/u-labs.de\/portal\/wp-content\/uploads\/2021\/05\/grafik-1.png 1099w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n<p><strong>touchpointSession<\/strong> ist ein riesiges JSON-Dokument, bin\u00e4r gespeichert. Es enth\u00e4lt s\u00e4mtliche Informationen zum und \u00fcber den Benutzer, sobald er eine Touchpoint-Sitzung begonnen hat. Neben der Ausstiegsseite umfasst dies auch beispielsweise eingegebene Daten. Der Anwender muss also nicht von neuem beginnen, wenn er Touchpoint abbricht. <\/p>\n<p><strong>privacyAndGuidelines<\/strong> enth\u00e4lt die Version der Nutzungsbedingungen, die akzeptiert wurden. Im obigen Beispiel ist dies Version <strong>1.0<\/strong>. Erscheint eine neue Version 1.1, kann das System dadurch erkennen, dass der Nutzer die neue Version noch nicht akzeptiert hat und leitet ihn daher zu Touchpoint um.<\/p>\n<p><strong>touchpointState<\/strong> speichert den Zeitstempel des erfolgreichen Abschlusses in einem kleinen JSON-Dokument. Dementsprechend wird es erst angelegt, nachdem der Touchpoint vollst\u00e4ndig durchlaufen wurde.<\/p>\n<h2 class=\"wp-block-heading\">Warum muss der Touchpoint st\u00e4ndig neu absolviert werden?<\/h2>\n<p>Zusammenfassend war meine Feststellung bei der Fehlersuche: Der Nutzer schlie\u00dft den Touchpoint erfolgreich ab, wodurch die Profilfelder <strong>touchpointState<\/strong> und <strong>privacyAndGuidelines<\/strong> entsprechend gesetzt wurden. Die detailliertere Beobachtung zeigte jedoch, dass diese Daten sp\u00e4ter aus unerkl\u00e4rlichen Gr\u00fcnden wieder verschwanden. Folglich erscheint der Touchpoint erneut, da der Nutzer ihn laut vorliegenden Daten nie abgeschlossen hatte. Allerdings teils deutlich verz\u00f6gert. Dies scheint mit verschiedenen Caching-Mechanismen auf Client- und Serverseite zusammenzuh\u00e4ngen. Weiter erschwert wurde die Analyse dadurch, dass nicht alle Benutzer betroffen waren. Es schien kein Muster zu geben &#8211; mal betraf es neue Nutzer die den Touchpoint erst k\u00fcrzlich abgeschlossen haben. Teils auch \u00e4ltere.<\/p>\n<p>Die Ursache lag in einer problematischen Standardkonfiguration des TDI: Dieser geht davon aus, dass die Touchpoint-Daten im LDAP gespeichert sind. Daf\u00fcr m\u00fcsste man eine Schemaerweiterung f\u00fcr alle ben\u00f6tigten Felder durchf\u00fchren. Ferner sehe ich wenig Sinn darin. Diese Daten geh\u00f6ren zu Connections und damit in die Datenbank der Anwendung. Gerade beim gro\u00dfen JSON-Dokument in <strong>touchpointSession<\/strong> sehe ich zudem Probleme. Nachvollziehbar w\u00e4re eine zentrale Speicherung h\u00f6chstens noch beim <strong>privacyAndGuidelines<\/strong> Attribute. So k\u00f6nnte aus anderen Anwendungen heraus leicht abgefragt werden, ob und wenn ja welche Version der Nutzer akzeptiert hat. <\/p>\n<p>Unabh\u00e4ngig davon versucht der TDI, die Felder aus dem LDAP in Connections zu synchronisieren. Und hier liegt das Problem: Fehlen die vom Touchpoint verwendeten LDAP-Felder, wird kein Fehler geworfen. Stattdessen geht der TDI von einem leeren Wert aus. Hat der Nutzer Touchpoint abgeschlossen, \u00fcberschreibt der TDI beim n\u00e4chsten Durchlauf diesen Datensatz. <strong>Allerdings nur, wenn sich an dem dazugeh\u00f6rigen LDAP-Nutzer auch etwas ge\u00e4ndert hat<\/strong>. Dadurch war das Problem nur schwer zu erkennen und zu reproduzieren: Erst wenn der TDI eine \u00c4nderung erkennt, wird der Touchpoint durch die L\u00f6schung zur\u00fcckgesetzt.<\/p>\n<h2 class=\"wp-block-heading\">So l\u00e4sst sich das automatische L\u00f6schen verhindern<\/h2>\n<p>Es gibt grunds\u00e4tzlich zwei M\u00f6glichkeiten:<\/p>\n<ol class=\"wp-block-list\">\n<li>Die TDI-Konfiguration wird angepasst, um s\u00e4mtliche Touchpoint-Attribute nicht zu synchronisieren<\/li>\n<li>Man m\u00f6chte die Daten im LDAP speichern und legt eine geeignete Schemaerweiterung selbstst\u00e4ndig an<\/li>\n<\/ol>\n<p>Aus obigen Gr\u00fcnden sehe ich Variante 2 als sinnvoller an. Hierzu reicht es jedoch <strong>nicht<\/strong>, s\u00e4mtliche Attribute in der <strong>map_dbrepos_from_source.properties<\/strong> Konfigurationsdatei auf Null zu setzen:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"\" data-line=\"\">extattr.touchpointSession=null<\/code><\/pre>\n<p>Stattdessen m\u00fcssen die Felder komplett aus der Konfiguration entfernt werden. Dabei beginnen wir bei den benutzerdefinierten Feldern in der Datei <strong>conf\/LotusConnections-config\/tdi-profiles-config.xml.<\/strong> Dort sind alle drei o.g. Felder definiert inklusive <strong>recommendedTags <\/strong>und <strong>departmentKey<\/strong>. Wie der Name vermuten l\u00e4sst, sammelt das System in <strong>recommendedTags<\/strong> ein paar personalisierte Schlagw\u00f6rter, die dem Nutzer angeboten werden sollen. Alle vier m\u00fcssen dort wie folgt auskommentiert oder alternativ gel\u00f6scht werden:<\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;!--\n        These extension attributes are required by the &#039;Touchpoint&#039; component\n--&gt;\n&lt;!--\n&lt;simpleAttribute extensionId=&quot;recommendedTags&quot; length=&quot;256&quot; sourceKey=&quot;recommendedTags&quot; \/&gt;\n&lt;!--&lt;simpleAttribute extensionId=&quot;departmentKey&quot; length=&quot;256&quot; sourceKey=&quot;departmentKey&quot; \/&gt;\n&lt;simpleAttribute extensionId=&quot;privacyAndGuidelines&quot; length=&quot;256&quot; sourceKey=&quot;privacyAndGuidelines&quot; \/&gt;\n&lt;simpleAttribute extensionId=&quot;touchpointState&quot; length=&quot;256&quot; sourceKey=&quot;touchpointState&quot; \/&gt;\n&lt;richtextAttribute extensionId=&quot;touchpointSession&quot; maxBytes=&quot;1000000&quot; sourceKey=&quot;touchpointSession&quot; \/&gt;\n--&gt;\n<\/pre>\n<\/div>\n<p>Anschlie\u00dfend die Definitionen auch in <strong>conf\/LotusConnections-config\/profiles-types.xml<\/strong> entfernen<\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;!--\n&lt;property&gt;\n        &lt;ref&gt;recommendedTags&lt;\/ref&gt;\n        &lt;updatability&gt;readwrite&lt;\/updatability&gt;\n        &lt;hidden&gt;true&lt;\/hidden&gt;\n        &lt;fullTextIndexed&gt;false&lt;\/fullTextIndexed&gt;\n&lt;\/property&gt;\n&lt;property&gt;\n        &lt;ref&gt;departmentKey&lt;\/ref&gt;\n        &lt;updatability&gt;read&lt;\/updatability&gt;\n        &lt;hidden&gt;true&lt;\/hidden&gt;\n        &lt;fullTextIndexed&gt;true&lt;\/fullTextIndexed&gt;\n&lt;\/property&gt;\n\n&lt;property&gt;\n        &lt;ref&gt;privacyAndGuidelines&lt;\/ref&gt;\n        &lt;updatability&gt;readwrite&lt;\/updatability&gt;\n        &lt;hidden&gt;true&lt;\/hidden&gt;\n        &lt;fullTextIndexed&gt;false&lt;\/fullTextIndexed&gt;\n&lt;\/property&gt;\n&lt;property&gt;\n        &lt;ref&gt;touchpointState&lt;\/ref&gt;\n        &lt;updatability&gt;readwrite&lt;\/updatability&gt;\n        &lt;hidden&gt;true&lt;\/hidden&gt;\n        &lt;fullTextIndexed&gt;false&lt;\/fullTextIndexed&gt;\n&lt;\/property&gt;\n&lt;property&gt;\n        &lt;ref&gt;touchpointSession&lt;\/ref&gt;\n        &lt;updatability&gt;readwrite&lt;\/updatability&gt;\n        &lt;hidden&gt;true&lt;\/hidden&gt;\n        &lt;fullTextIndexed&gt;false&lt;\/fullTextIndexed&gt;\n&lt;\/property&gt;\n--&gt;\n<\/pre>\n<\/div>\n<h2 class=\"wp-block-heading\">Testlauf<\/h2>\n<p>Verifizieren l\u00e4sst sich der Workaround mit folgenden Schritten, die im besten Falle mit einem eigens angelegten Testbenutzer durchgef\u00fchrt werden:<\/p>\n<ol class=\"wp-block-list\">\n<li>Der Benutzer schlie\u00dft den Touchpoint ab<\/li>\n<li><a href=\"https:\/\/u-labs.de\/portal\/hcl-connections-pruefen-wer-touchpoint-nicht-abgeschlossen-hat\/\">In der Datenbank pr\u00fcfen, dass der entsprechende Datensatz zum Abschluss vorliegt<\/a><\/li>\n<li>Ein synchronisiertes Feld im LDAP des Testbenutzers \u00e4ndern, beispielsweise der Anzeigename (<strong>displayName<\/strong>)<\/li>\n<li>Nun den TDI durch Aufruf von <strong>.\/sync_all_dns.sh<\/strong> synchronisieren lassen. Es muss eine \u00c4nderung im Log sichtbar sein:\r\n<em>After synchronization, added or modified records is 1 &#8230;<\/em><\/li>\n<li><a href=\"https:\/\/u-labs.de\/portal\/hcl-connections-pruefen-wer-touchpoint-nicht-abgeschlossen-hat\/\">Ein erneuter Blick in die Datenbank<\/a> sollte zeigen, dass der Abschluss f\u00fcr den Testbenutzer dort weiterhin gespeichert ist<\/li>\n<\/ol>\n<p><strong>Warum nicht einfach Connections mit dem Testbenutzer im Browser \u00f6ffnen, statt in der Datenbank zu schauen?<\/strong><\/p>\n<p>Wie bereits oben erw\u00e4hnt, gibt es hier offensichtlich mehrere Layer an Caches. Teilweise funktioniert es in einem Ikognito-Fenster bzw. nach dem L\u00f6schen aller clientseitigen Speicher des Browsers &#8211; jedoch nicht immer. Auch das neu einloggen ist keine Garantie. Dies hat die Fehlersuche anfangs verkompliziert, da der Touchpoint teilweise erst etliche Tage nach der L\u00f6schung des Datensatzes wieder sichtbar wurde. Die Datenbank ist daher am zuverl\u00e4ssigsten &#8211; fr\u00fcher oder sp\u00e4ter werden alle Caches geleert, dann z\u00e4hlt was in unserer DB steht.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In der Standardkonfiguration von HCL Connections Touchpoint bekamen wir das Feedback, dass die Software st\u00e4ndig automatisch neu aufgerufen werde. Nicht in Intervallen von Monaten, sondern Tagen &#8211; teils sogar Stunden. Dies war nat\u00fcrlich nicht Sinn der Sache. Zusammen mit Christoph St\u00f6ttner habe ich das Problem analysiert und es konnte ein Workaround gefunden werden. Was ist &#8230;<\/p>\n","protected":false},"author":5,"featured_media":7121,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[765],"tags":[869,796],"class_list":["post-7193","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-hcl-connections","tag-hcl-connections-touchpoint","tag-tdi"],"_links":{"self":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/7193","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/comments?post=7193"}],"version-history":[{"count":9,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/7193\/revisions"}],"predecessor-version":[{"id":7203,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/7193\/revisions\/7203"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/media\/7121"}],"wp:attachment":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/media?parent=7193"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/categories?post=7193"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/tags?post=7193"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}