Geplanter Task Abraxas
Der geplante Task für Abraxas besteht aus zwei Teilen. Der erste Teil wird in ContactSync konfiguriert ( siehe hier). Zusätzlich ist eine Konfiguration des zweiten Teils in der CMI-Lösungsplattform erforderlich.
Die Abraxas-Schnittstelle speichert Änderungen und Mutationen von Kontakten in XML-Dateien. Diese Dateien müssen verarbeitet und anschliessend der Kontakt erneut mit der Schnittstelle abgeglichen werden. Dazu muss in CMI ein Folder-Watcher auf dem Ordner eingerichtet werden, in dem die XML-Dateien abgelegt werden. Diese Dateien werden dann eingelesen und das Datumsfeld "Nächste Synchronisierung" wird beim entsprechenden Kontakt gesetzt. Anschliessend holt sich der ContactSync-Service alle Kontakte, bei denen das Datumsfeld in der Vergangenheit liegt, und gleicht diese Kontakte erneut mit der EWK-Schnittstelle ab.
Einrichtung Folder-Watcher
Ein Folder-Watcher wird in CMI unter Servereinstellungen -> File-Handler hinzugefügt. Dort kann ein neuer File-Handler erstellt werden. Anschliessend kann der nachfolgende Code eingefügt werden.
Wichtig: Es werden nur Dateien berücksichtigt, die mit
data_
anfangen. Restliche Dateien werden ignoriert (zum Beispielevent_
).
Das Skript unterstützt auch das Senden von E-Mails im Fehlerfall. Um diese Funktion zu aktivieren, muss eine
E-Mail-Adresse in der Variable SendErrorMailTo
(in Zeile 14) eingetragen werden.
using System;
using System.Collections.Generic;
using System.Text;
using CMI.DomainModel;
using CMI.Server.Interfaces;
using CMI.MetaTool.Generated;
using System.Xml;
using System.IO;
namespace CMI.MetaTool.FileHandlers
{
public class AbraxasImporter : FileHandlerBase
{
private string SendErrorMailTo = "";
public override void HandleFile(string filePath)
{
if (!Path.GetFileName(filePath).StartsWith("data_"))
return;
var fileContent = File.ReadAllText(filePath);
try
{
ProcessSingleFile(filePath, fileContent);
}
catch (Exception ex)
{
SendMail(filePath, ex.ToString(), fileContent);
}
}
private Kontakt GetKontakt(string fremdkey)
{
var refNumCriterion = (RefNumCriterion)KontaktFields.Fremdkey.CreateCriterion();
refNumCriterion.SearchString = fremdkey;
var queryKontakt = new Query(TypeDefinitions.Kontakt);
queryKontakt.Criterions.Add(refNumCriterion);
var list = _metaContext.Mapper.ExecuteObjektQuery(queryKontakt, TypeDefinitions.Kontakt.AllFieldAndAssocFieldIds);
if (list.Count < 1)
throw new Exception("Kontakt mit dem Fremdschlüssel " + fremdkey + " nicht gefunden.");
if (list.Count > 1)
throw new Exception("Mehrere Kontakte (" + list.Count + ") mit dem Fremdschlüssel " + fremdkey + " gefunden.");
return list[0] as Kontakt;
}
private void ProcessSingleFile(string filePath, string fileContent)
{
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(fileContent);
if (xmlDoc == null)
throw new Exception("Das XML " + filePath + " konnte nicht geparsed werden");
var nsManager = new XmlNamespaceManager(xmlDoc.NameTable);
nsManager.AddNamespace("ABX-Reporting", "http://www.abraxas.ch/xmlns/ABX-Reporting/1");
nsManager.AddNamespace("eCH-0044", "http://www.ech.ch/xmlns/eCH-0044-f/4");
nsManager.AddNamespace("eCH-0097", "http://www.ech.ch/xmlns/eCH-0097-f/4");
try
{
var id = GetPersonId(xmlDoc, nsManager) ?? GetOrganisationId(xmlDoc, nsManager);
if (id == null)
throw new Exception("Im XML " + filePath + " wurde keine Personen-ID noch Organisations-ID gefunden.");
var kontakt = GetKontakt(id.GetCmiSearchKey());
kontakt.NaechsteSynchronisation = ZeitpunktWert.CreateZeitpunktWert(KontaktFields.NaechsteSynchronisation, DateTime.MinValue);
_metaContext.Mapper.Save(kontakt, true);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
private void SendMail(string filePath, string error, string fileContent)
{
try
{
if (string.IsNullOrEmpty(SendErrorMailTo))
return;
var msg = new EmailMessage();
msg.IsHtmlMessage = false;
msg.Subject = "Abraxas-EWK Import: Eine Datei konnte nicht verarbeitet werden";
msg.Body = "Die Datei \"" + filePath + "\" konnte nicht verarbeitet werden. Fehler: \"" + error;
msg.ToAddresses = new string[]
{
SendErrorMailTo
};
var attachment = new EmailAttachment();
attachment.Content = Encoding.UTF8.GetBytes(fileContent);
attachment.ContentId = "FILE";
attachment.Titel = Path.GetFileName(filePath);
msg.EmailAttachments = new EmailAttachment[]
{
attachment
};
_metaContext.Mapper.SendMail(msg);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
private AbraxasId GetPersonId(XmlDocument xmlDoc, XmlNamespaceManager xmlNamespaceManager)
{
var id = GetFirstValueOrThrowIfMoreThanOne(xmlDoc.SelectSingleNode("//eCH-0044:localPersonId/eCH-0044:personId", xmlNamespaceManager));
var category = GetFirstValueOrThrowIfMoreThanOne(xmlDoc.SelectSingleNode("//eCH-0044:localPersonId/eCH-0044:personIdCategory", xmlNamespaceManager));
if (id == null || category == null)
return null;
return new AbraxasId(category, id, "Contact");
}
private AbraxasId GetOrganisationId(XmlDocument xmlDoc, XmlNamespaceManager xmlNamespaceManager)
{
var id = GetFirstValueOrThrowIfMoreThanOne(xmlDoc.SelectSingleNode("//ABX-Reporting:localOrganisationId/eCH-0097:organisationId", xmlNamespaceManager));
var category = GetFirstValueOrThrowIfMoreThanOne(xmlDoc.SelectSingleNode("//ABX-Reporting:localOrganisationId/eCH-0097:organisationIdCategory", xmlNamespaceManager));
if (id == null || category == null)
return null;
return new AbraxasId(category, id, "Organisation");
}
private string GetFirstValueOrThrowIfMoreThanOne(XmlNode node)
{
if (node == null || !node.HasChildNodes)
return null;
if (node.ChildNodes.Count > 1)
throw new Exception("'" + node.Name + "' enthält mehrere Werte. Dieser Zustand wird nicht unterstützt.");
return node.ChildNodes[0].Value;
}
private class AbraxasId
{
public AbraxasId(string category, string id, string syncType)
{
Category = category;
Id = id;
SyncType = syncType;
}
public string Category { get; set; }
public string Id { get; set; }
public string SyncType { get; set; }
public string GetCmiSearchKey()
{
return "VRSG." + SyncType + "=" + Id + "@" + Category;
}
}
}
}
Anschliessend muss in der Datei Metatool.ini des Servers Folgendes ergänzt werden:
[FolderWatcher1]
Folder=PFAD-ZUM-ORDNER
Handler=AbraxasImporter
Unter Folder
wird der Ordner angegeben, bei welchem die XML-Dateien von der Abraxas-Schnittstelle abgelegt werden.
Fehlerhafte Verarbeitung
Konnte eine XML-Datei nicht verarbeitet werden, wird im selben Ordner ein neuer Unterordner mit dem Namen "Bad" erstellt. In diesem Unterordner werden alle fehlerhaften Dateien abgelegt. Dieser Ordner muss überwacht werden. Ausserdem wird, wenn aktiviert, auch eine E-Mail mit dem Fehler verschickt (siehe hier).