// Copyright (c) 2015-2017 schick Informatik // Description: Hilfsklasse zur Bearbeitung der Antworten / HIS-Nord using System; using System.Collections.Generic; using System.Linq; using System.Xml.Linq; using bsmd.database; using log4net; namespace bsmd.hisnord { public class NSWResponse { private string _clientRequestId; private DateTime _receiveAt; private string _notificationId; private string _status; private string _visitId; private string _transitId; private Message.NotificationClass _notificationClass; private bool _isReset; private List _violations = new List(); private List _errors = new List(); private Guid? _messageCoreId; private ILog _log = LogManager.GetLogger(typeof(NSWResponse)); public NSWResponse(XElement xml) { XNamespace ns1 = "http://api.national-single-window.de/visitIdRequest"; XNamespace ns6 = "http://api.national-single-window.de/receipt"; //XNamespace ns15 = "http://api.national-single-window.de/statusForClientRequestId"; XNamespace soap = "http://schemas.xmlsoap.org/soap/envelope/"; XNamespace ns15 = "http://api.national-single-window.de/visitIdResponse"; XNamespace ns16 = "http://api.national-single-window.de/transitIdResponse"; XNamespace ladgNS = "http://api.national-single-window.de/ladg"; XNamespace hazaNS = "http://api.national-single-window.de/haza"; XNamespace hazdNS = "http://api.national-single-window.de/hazd"; XNamespace mdhNS = "http://api.national-single-window.de/mdh"; XNamespace agntNS = "http://api.national-single-window.de/agnt"; XNamespace vioNS = "http://api.national-single-window.de/violation"; XNamespace errNS = "http://api.national-single-window.de/error"; XNamespace secNS = "http://api.national-single-window.de/sec"; XNamespace statNS = "http://api.national-single-window.de/stat"; XNamespace noa_nodNS = "http://api.national-single-window.de/noanod"; XNamespace ataNS = "http://api.national-single-window.de/ata"; XNamespace atdNS = "http://api.national-single-window.de/atd"; XNamespace pobaNS = "http://api.national-single-window.de/poba"; XNamespace pobdNS = "http://api.national-single-window.de/pobd"; XNamespace nameNS = "http://api.national-single-window.de/name"; XNamespace tiefaNS = "http://api.national-single-window.de/tiefa"; XNamespace tiefdNS = "http://api.national-single-window.de/tiefd"; XNamespace bkraNS = "http://api.national-single-window.de/bkra"; XNamespace bkrdNS = "http://api.national-single-window.de/bkrd"; XNamespace infoNS = "http://api.national-single-window.de/info"; XNamespace servNS = "http://api.national-single-window.de/serv"; XNamespace pre72hNS = "http://api.national-single-window.de/pre72h"; XNamespace wasNS = "http://api.national-single-window.de/was"; XNamespace crewNS = "http://api.national-single-window.de/crew"; XNamespace pasNS = "http://api.national-single-window.de/pas"; XNamespace bpolNS = "http://api.national-single-window.de/bpol"; XNamespace towaNS = "http://api.national-single-window.de/towa"; XNamespace towdNS = "http://api.national-single-window.de/towd"; XName idName = "ConveyanceCode"; var elem = xml.Descendants(idName); if (elem.Count() > 0) { Guid aGuid; if (Guid.TryParse(elem.FirstOrDefault()?.Value, out aGuid)) _messageCoreId = aGuid; else _log.WarnFormat("cannot parse ConveyanceCode {0}", elem.FirstOrDefault()); }else { _log.Warn("NSWResponse does not contain ConveyanceCode!!"); } // detect response type foreach (Message.NotificationClass messageClassType in Enum.GetValues(typeof(Message.NotificationClass))) { XName lookupName; XName resetLookup; switch (messageClassType) { // we won't get answers for these message types case Message.NotificationClass.STO: continue; case Message.NotificationClass.CREWD: continue; case Message.NotificationClass.PASD: continue; case Message.NotificationClass.VISIT: lookupName = ns15 + "VisitIdResponse"; resetLookup = ns15 + "ResetResponse"; break; case Message.NotificationClass.TRANSIT: lookupName = ns16 + "TransitIdResponse"; resetLookup = ns16 + "ResetResponse"; break; case Message.NotificationClass.LADG: lookupName = ladgNS + "LADGResponse"; resetLookup = ladgNS + "ResetResponse"; break; case Message.NotificationClass.HAZA: lookupName = hazaNS + "HAZAResponse"; resetLookup = hazaNS + "ResetResponse"; break; case Message.NotificationClass.HAZD: lookupName = hazdNS + "HAZDResponse"; resetLookup = hazdNS + "ResetResponse"; break; case Message.NotificationClass.MDH: lookupName = mdhNS + "MDHResponse"; resetLookup = mdhNS + "ResetResponse"; break; case Message.NotificationClass.AGNT: lookupName = agntNS + "AGNTResponse"; resetLookup = agntNS + "ResetResponse"; break; case Message.NotificationClass.SEC: lookupName = secNS + "SECResponse"; resetLookup = secNS + "ResetResponse"; break; case Message.NotificationClass.STAT: lookupName = statNS + "STATResponse"; resetLookup = statNS + "ResetResponse"; break; case Message.NotificationClass.NOA_NOD: lookupName = noa_nodNS + "NOA_NODResponse"; resetLookup = noa_nodNS + "ResetResponse"; break; case Message.NotificationClass.ATA: lookupName = ataNS + "ATAResponse"; resetLookup = ataNS + "ResetResponse"; break; case Message.NotificationClass.ATD: lookupName = atdNS + "ATDResponse"; resetLookup = atdNS + "ResetResponse"; break; case Message.NotificationClass.POBA: lookupName = pobaNS + "POBAResponse"; resetLookup = pobaNS + "ResetResponse"; break; case Message.NotificationClass.POBD: lookupName = pobdNS + "POBDResponse"; resetLookup = pobdNS + "ResetResponse"; break; case Message.NotificationClass.NAME: lookupName = nameNS + "NAMEResponse"; resetLookup = nameNS + "ResetResponse"; break; case Message.NotificationClass.TIEFA: lookupName = tiefaNS + "TIEFAResponse"; resetLookup = tiefaNS + "ResetResponse"; break; case Message.NotificationClass.TIEFD: lookupName = tiefdNS + "TIEFDResponse"; resetLookup = tiefdNS + "ResetResponse"; break; case Message.NotificationClass.BKRA: lookupName = bkraNS + "BKRAResponse"; resetLookup = bkraNS + "ResetResponse"; break; case Message.NotificationClass.BKRD: lookupName = bkrdNS + "BKRDResponse"; resetLookup = bkrdNS + "ResetResponse"; break; case Message.NotificationClass.INFO: lookupName = infoNS + "INFOResponse"; resetLookup = infoNS + "ResetResponse"; break; case Message.NotificationClass.SERV: lookupName = servNS + "SERVResponse"; resetLookup = servNS + "ResetResponse"; break; case Message.NotificationClass.PRE72H: lookupName = pre72hNS + "PRE72HResponse"; resetLookup = pre72hNS + "ResetResponse"; break; case Message.NotificationClass.WAS: lookupName = wasNS + "WASResponse"; resetLookup = wasNS + "ResetResponse"; break; case Message.NotificationClass.CREW: lookupName = crewNS + "CREWResponse"; resetLookup = crewNS + "ResetResponse"; break; case Message.NotificationClass.PAS: lookupName = pasNS + "PASResponse"; resetLookup = pasNS + "ResetResponse"; break; case Message.NotificationClass.BPOL: lookupName = bpolNS + "BPOLResponse"; resetLookup = bpolNS + "ResetResponse"; break; case Message.NotificationClass.TOWA: lookupName = towaNS + "TOWAResponse"; resetLookup = towaNS + "ResetResponse"; break; case Message.NotificationClass.TOWD: lookupName = towdNS + "TOWDResponse"; resetLookup = towdNS + "ResetResponse"; break; default: lookupName = "dontmatchmeplease"; resetLookup = "dontmatchmeplease"; break; } bool lookupMatch = (xml.Descendants(lookupName).Count() > 0); bool resetMatch = (xml.Descendants(resetLookup).Count() > 0); if(lookupMatch || resetMatch) { _isReset = resetMatch; _notificationClass = messageClassType; // match found XName xname = ns6 + "ClientRequestId"; elem = xml.Descendants(xname); if (elem.Count() > 0) { _clientRequestId = elem.First()?.Value; } xname = ns6 + "ReceivedAt"; elem = xml.Descendants(xname); if(elem.Count() > 0) { DateTime.TryParse(elem.First()?.Value, out _receiveAt); } xname = ns6 + "NotificationId"; elem = xml.Descendants(xname); if (elem.Count() > 0) _notificationId = elem.First()?.Value; xname = ns6 + "Status"; elem = xml.Descendants(xname); if(elem.Count() > 0) { _status = elem.First()?.Value; } xname = ns6 + "VisitId"; elem = xml.Descendants(xname); if(elem.Count() > 0) { _visitId = elem.First()?.Value; } xname = ns6 + "TransitId"; elem = xml.Descendants(xname); if (elem.Count() > 0) { _transitId = elem.First()?.Value; } // check for violations ------------------------------------------- xname = ns6 + "Violation"; XName vCodeName = vioNS + "ViolationCode"; XName vTextName = vioNS + "ViolationText"; elem = xml.Descendants(xname); foreach(XElement anElem in elem) { MessageViolation mv = new MessageViolation(); int vCode = -1; if (!Int32.TryParse(anElem.Element(vCodeName).Value, out vCode)) _log.WarnFormat("cannot convert violation code to int: {0}", anElem.Element(vCodeName).Value); else mv.ViolationCode = vCode; mv.ViolationText = anElem.Element(vTextName).Value; _violations.Add(mv); } // check for errors ---------------------------------------------- xname = ns6 + "Error"; XName eCodeName = errNS + "ErrorCode"; XName eTextName = errNS + "ErrorText"; elem = xml.Descendants(xname); foreach (XElement anElem in elem) { MessageError me = new MessageError(); int eCode = -1; if (!Int32.TryParse(anElem.Element(eCodeName).Value, out eCode)) _log.WarnFormat("cannot convert error code to int: {0}", anElem.Element(eCodeName).Value); else me.ErrorCode = eCode; me.ErrorText = anElem.Element(eTextName).Value; _errors.Add(me); } break; } } } #region Properties public Guid? MessageCoreId { get { return _messageCoreId; } } public string ClientRequestId { get { return _clientRequestId; } } public DateTime? ReceiveAt { get { return _receiveAt; } } public string NotificationId { get { return _notificationId; } } public string Status { get { return this._status; } } public string VisitId { get { return this._visitId; } } public string TransitId { get { return this._transitId; } } public List Violations { get { return _violations; } } public List Errors { get { return _errors; } } public Message.NotificationClass NotificationClass { get { return this._notificationClass; } } public bool IsReset { get { return this._isReset; } } #endregion } }