git_bsmd/bsmd.hisnord/NSWResponse.cs

353 lines
17 KiB
C#

// 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 readonly DateTime _receiveAt;
private Guid? _messageCoreId;
private readonly 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 statusNS = "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 resetNS = "http://api.national-single-window.de/reset";
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 crewaNS = "http://api.national-single-window.de/crewa";
XNamespace pasaNS = "http://api.national-single-window.de/pasa";
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";
XNamespace crewdNS = "http://api.national-single-window.de/crewd";
XNamespace pasdNS = "http://api.national-single-window.de/pasd";
XNamespace was_rcptNS = "http://api.national-single-window.de/wasrcpt";
XNamespace cancelVisitNS = "http://api.national-single-window.de/visitIdCancelRequest";
XNamespace cancelTransitNS = "http://api.national-single-window.de/transitIdCancelRequest";
XName lookupName = "dontmatchmeplease";
XName idName = "ConveyanceCode";
var elem = xml.Descendants(idName);
if (elem.Any())
{
if (Guid.TryParse(elem.FirstOrDefault()?.Value, out Guid aGuid))
_messageCoreId = aGuid;
else
_log.WarnFormat("cannot parse ConveyanceCode {0}", elem.FirstOrDefault());
}
else
{
_log.Warn("NSWResponse does not contain ConveyanceCode!!");
}
XName meldeTypeName = "Meldetype";
var mElem = xml.Descendants(meldeTypeName);
Message.NotificationClass? notificationClass = null;
if(mElem.Any())
{
if (Enum.TryParse<Message.NotificationClass>(mElem.FirstOrDefault()?.Value, out Message.NotificationClass tmpClass))
notificationClass = tmpClass;
else
{
// könnte VISIT/TRANSIT Id Beantragung sein
XName test = ns15 + "VisitIdResponse";
if (xml.Descendants(test).Any())
{
notificationClass = Message.NotificationClass.VISIT;
}
else
{
test = ns16 + "TransitIdResponse";
if (xml.Descendants(test).Any()) notificationClass = Message.NotificationClass.TRANSIT;
}
if (!notificationClass.HasValue)
{
XName cancelVisit = cancelVisitNS + "CancelVisitIdResponse";
XName cancelTransit = cancelTransitNS + "CancelTransitIdResponse";
if (xml.Descendants(cancelVisit).Any())
{
lookupName = cancelVisit;
notificationClass = Message.NotificationClass.STO; // HACK, es gibt keine Klasse für "Cancel"
_log.WarnFormat("CANCEL VISIT, setting Not.Class to STO (experimental)");
NotificationClass = Message.NotificationClass.STO;
}
else if (xml.Descendants(cancelTransit).Any())
{
lookupName = cancelTransit;
notificationClass = Message.NotificationClass.STO; // HACK, es gibt keine Klasse für "Cancel"
_log.WarnFormat("CANCEL TRANSIT, setting Not.Class to STO (experimental)");
NotificationClass = Message.NotificationClass.STO;
}
else
{
_log.WarnFormat("NSWResponse does not contain Notification class");
}
}
}
}
// detect response type
if(notificationClass.HasValue)
{
XName resetLookup = resetNS + "ResetResponse";
switch (notificationClass.Value)
{
case Message.NotificationClass.VISIT:
lookupName = ns15 + "VisitIdResponse";
break;
case Message.NotificationClass.TRANSIT:
lookupName = ns16 + "TransitIdResponse";
break;
case Message.NotificationClass.LADG:
lookupName = ladgNS + "LADGResponse";
break;
case Message.NotificationClass.HAZA:
lookupName = hazaNS + "HAZAResponse";
break;
case Message.NotificationClass.HAZD:
lookupName = hazdNS + "HAZDResponse";
break;
case Message.NotificationClass.MDH:
lookupName = mdhNS + "MDHResponse";
break;
case Message.NotificationClass.AGNT:
lookupName = agntNS + "AGNTResponse";
break;
case Message.NotificationClass.SEC:
lookupName = secNS + "SECResponse";
break;
case Message.NotificationClass.STAT:
lookupName = statNS + "STATResponse";
break;
case Message.NotificationClass.NOA_NOD:
lookupName = noa_nodNS + "NOA_NODResponse";
break;
case Message.NotificationClass.ATA:
lookupName = ataNS + "ATAResponse";
break;
case Message.NotificationClass.ATD:
lookupName = atdNS + "ATDResponse";
break;
case Message.NotificationClass.POBA:
lookupName = pobaNS + "POBAResponse";
break;
case Message.NotificationClass.POBD:
lookupName = pobdNS + "POBDResponse";
break;
case Message.NotificationClass.NAME:
lookupName = nameNS + "NAMEResponse";
break;
case Message.NotificationClass.TIEFA:
lookupName = tiefaNS + "TIEFAResponse";
break;
case Message.NotificationClass.TIEFD:
lookupName = tiefdNS + "TIEFDResponse";
break;
case Message.NotificationClass.BKRA:
lookupName = bkraNS + "BKRAResponse";
break;
case Message.NotificationClass.BKRD:
lookupName = bkrdNS + "BKRDResponse";
break;
case Message.NotificationClass.INFO:
lookupName = infoNS + "INFOResponse";
break;
case Message.NotificationClass.SERV:
lookupName = servNS + "SERVResponse";
break;
case Message.NotificationClass.PRE72H:
lookupName = pre72hNS + "PRE72HResponse";
break;
case Message.NotificationClass.WAS:
lookupName = wasNS + "WASResponse";
break;
case Message.NotificationClass.CREWA:
lookupName = crewaNS + "CREWAResponse";
break;
case Message.NotificationClass.PASA:
lookupName = pasaNS + "PASAResponse";
break;
case Message.NotificationClass.BPOL:
lookupName = bpolNS + "BPOLResponse";
break;
case Message.NotificationClass.TOWA:
lookupName = towaNS + "TOWAResponse";
break;
case Message.NotificationClass.TOWD:
lookupName = towdNS + "TOWDResponse";
break;
case Message.NotificationClass.CREWD:
lookupName = crewdNS + "CREWDResponse";
break;
case Message.NotificationClass.PASD:
lookupName = pasdNS + "PASDResponse";
break;
case Message.NotificationClass.WAS_RCPT:
lookupName = was_rcptNS + "WAS_RCPTResponse";
break;
default:
break;
}
bool lookupMatch = (xml.Descendants(lookupName).Any());
bool resetMatch = (xml.Descendants(resetLookup).Any());
if(lookupMatch || resetMatch)
{
IsReset = resetMatch;
NotificationClass = notificationClass.Value;
// match found
XName xname = ns6 + "ClientRequestId";
elem = xml.Descendants(xname);
if (elem.Any())
{
ClientRequestId = elem.First()?.Value;
}
xname = ns6 + "ReceivedAt";
elem = xml.Descendants(xname);
if(elem.Any())
{
DateTime.TryParse(elem.First()?.Value, out _receiveAt);
}
xname = ns6 + "NotificationId";
elem = xml.Descendants(xname);
if (elem.Any())
NotificationId = elem.First()?.Value;
xname = ns6 + "Status";
elem = xml.Descendants(xname);
if(elem.Any())
{
Status = elem.First()?.Value;
}
xname = ns6 + "VisitId";
elem = xml.Descendants(xname);
if(elem.Any())
{
VisitId = elem.First()?.Value;
}
xname = ns6 + "TransitId";
elem = xml.Descendants(xname);
if (elem.Any())
{
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();
if (!Int32.TryParse(anElem.Element(vCodeName).Value, out int 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();
if (!Int32.TryParse(anElem.Element(eCodeName).Value, out int 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);
}
}
}
}
#region Properties
public Guid? MessageCoreId { get { return _messageCoreId; } }
public string ClientRequestId { get; }
public DateTime? ReceiveAt { get { return _receiveAt; } }
public string NotificationId { get; }
public string Status { get; }
public string VisitId { get; }
public string TransitId { get; }
public List<MessageViolation> Violations { get; } = new List<MessageViolation>();
public List<MessageError> Errors { get; } = new List<MessageError>();
public Message.NotificationClass NotificationClass { get; }
public bool IsReset { get; }
#endregion
}
}