342 lines
16 KiB
C#
342 lines
16 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 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";
|
|
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.CREW:
|
|
lookupName = crewNS + "CREWResponse";
|
|
break;
|
|
case Message.NotificationClass.PAS:
|
|
lookupName = pasNS + "PASResponse";
|
|
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;
|
|
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();
|
|
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);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
#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
|
|
|
|
}
|
|
|
|
} |