Zwischenstand (Umbau HIS-Nord Response Parsing auf XDocument / XElement (LinqToXML)

This commit is contained in:
Daniel Schick 2017-07-28 05:42:11 +00:00
parent b46b3606ac
commit 362f0f4285
9 changed files with 198 additions and 1386 deletions

Binary file not shown.

View File

@ -83,6 +83,8 @@ namespace SendNSWMessageService
if (DBManager.Instance.Connect(Properties.Settings.Default.ConnectionString))
{
bsmd.hisnord.Response.ReadAnswers();
// Datenbank auf zu sendende Objekte überprüfen und laden
List<MessageCore> coresMarkedForSending = DBManager.Instance.GetMessageCoresByStatus(MessageCore.BSMDStatus.TOSEND);
@ -271,7 +273,7 @@ namespace SendNSWMessageService
// Auf erhaltene Visit-Ids prüfen (HIS-NORD)
// TODO
bsmd.hisnord.Response.ReadAnswers();
// bsmd.hisnord.Response.ReadAnswers();
DBManager.Instance.Disconnect();

View File

@ -0,0 +1,23 @@
using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
namespace bsmd.hisnord
{
public class NSWResponse
{
public NSWResponse(XElement xml)
{
}
#region Properties
#endregion
}
}

View File

@ -94,5 +94,17 @@ namespace bsmd.hisnord.Properties {
this["AnswerArchiveDir"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("E:\\svnlager\\BSMD\\nsw\\HIS-NORD\\Transmitter-Tool\\ANSWERS_CORRUPT")]
public string AnswerCorruptDir {
get {
return ((string)(this["AnswerCorruptDir"]));
}
set {
this["AnswerCorruptDir"] = value;
}
}
}
}

View File

@ -20,5 +20,8 @@
<Setting Name="AnswerArchiveDir" Type="System.String" Scope="User">
<Value Profile="(Default)">E:\svnlager\BSMD\nsw\HIS-NORD\Transmitter-Tool\ANSWERS_DONE</Value>
</Setting>
<Setting Name="AnswerCorruptDir" Type="System.String" Scope="User">
<Value Profile="(Default)">E:\svnlager\BSMD\nsw\HIS-NORD\Transmitter-Tool\ANSWERS_CORRUPT</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@ -8,6 +8,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using log4net;
using System.Xml.Linq;
namespace bsmd.hisnord
{
@ -21,86 +22,131 @@ namespace bsmd.hisnord
{
foreach (string answerFile in Directory.GetFiles(Properties.Settings.Default.AnswerDir))
{
bool isOK = true;
// TODO: klären was man hier liest: reguläre Antwort oder Schnittstellenfehler
VisitIdResponse visitIdResponse = ReadVisitId(answerFile);
if (visitIdResponse != null)
// Informationen aus dem Dateinamen
// Meldetyp_Referenz_ID_Timestamp.xml
string bareFileName = Path.GetFileNameWithoutExtension(answerFile);
string[] fileNameElems = bareFileName.Split('_');
if (fileNameElems.Length < 4)
{
_log.InfoFormat("HIS-NORD: Visit-ID {0} delivered for Core {1}", visitIdResponse.VisitId, visitIdResponse.ClientRequestId);
// update MessageCore
if (visitIdResponse.ClientRequestId != null)
_log.WarnFormat("ANSWER file {0}.xml has an invalid file name", bareFileName);
isOK = false;
}
else
{
int prozessStatus;
if (!Int32.TryParse(fileNameElems[fileNameElems.Length - 1], out prozessStatus))
{
Guid messageCoreId;
if (Guid.TryParse(visitIdResponse.ClientRequestId, out messageCoreId))
{
MessageCore answerCore = DBManager.Instance.GetMessageCoreById(messageCoreId);
if (answerCore == null)
{
_log.WarnFormat("HIS-NORD: Core not found for notification id {0}", visitIdResponse.NotificationId);
}
else
{
if (!answerCore.IsTransit)
answerCore.VisitId = visitIdResponse.VisitId;
else
answerCore.TransitId = visitIdResponse.VisitId;
answerCore.BSMDStatusInternal = MessageCore.BSMDStatus.RESPONDED;
DBManager.Instance.Save(answerCore);
}
}
else
{
_log.WarnFormat("{0} ANSWER parsed, but MessageCoreId is no Guid: {1}",
Path.GetFileName(answerFile), visitIdResponse.ClientRequestId);
}
_log.WarnFormat("ANSWER file {0}.xml has no process status at the end (2..6)", bareFileName);
isOK = false;
}
else
{
_log.WarnFormat("Client request id is null in {0}", answerFile);
}
// archive file
File.Move(answerFile, Path.Combine(Properties.Settings.Default.AnswerArchiveDir, Path.GetFileName(answerFile)));
}
}
}
internal static VisitIdResponse ReadVisitId (string filename)
{
VisitIdResponse visitIdResponse = null;
try
{
XmlSerializer serializer = new XmlSerializer(typeof(bsmd.hisnord.dataset));
using (FileStream fs = new FileStream(filename, FileMode.Open))
{
// aus dem Gewühl die Antwort fischen..
dataset aDataSet = (dataset)serializer.Deserialize(fs);
if (aDataSet != null)
{
for (int i = 0; i < aDataSet.Items.Length; i++)
int timestampMilliSecs;
if (!Int32.TryParse(fileNameElems[fileNameElems.Length - 2], out timestampMilliSecs))
{
if (aDataSet.Items[i] is Envelope)
_log.WarnFormat("ANSWER file {0}.xml has no readable timestamp", bareFileName);
isOK = false;
}
else
{
string refId = fileNameElems[fileNameElems.Length - 3];
string meldeTyp = fileNameElems[fileNameElems.Length - 4];
if (fileNameElems.Length == 5)
meldeTyp = string.Format("{0}_{1}", fileNameElems[fileNameElems.Length - 5], meldeTyp);
// TODO: klären was man hier liest: reguläre Antwort oder Schnittstellenfehler
// XML Linq statt Serialisierung
try
{
Envelope anEnvelope = (Envelope)aDataSet.Items[i];
if (anEnvelope.Body.Length > 0)
XElement xml = XElement.Load(answerFile);
// declare Namespaces
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";
if(xml.Descendants("SystemError").Count() > 0)
{
visitIdResponse = anEnvelope.Body[0].VisitIdResponse;
break;
}
// Fehlernachricht
SystemError systemError = new SystemError(xml);
// Speichern
}
else
{
// NSW Rückmeldung
NSWResponse nswResponse = new NSWResponse(xml);
// Rückmeldung auswerten
}
/*
if (visitIdResponse != null)
{
_log.InfoFormat("HIS-NORD: Visit-ID {0} delivered for Core {1}", visitIdResponse.VisitId, visitIdResponse.ClientRequestId);
// update MessageCore
if (visitIdResponse.ClientRequestId != null)
{
Guid messageCoreId;
if (Guid.TryParse(visitIdResponse.ClientRequestId, out messageCoreId))
{
MessageCore answerCore = DBManager.Instance.GetMessageCoreById(messageCoreId);
if (answerCore == null)
{
_log.WarnFormat("HIS-NORD: Core not found for notification id {0}", visitIdResponse.NotificationId);
}
else
{
if (!answerCore.IsTransit)
answerCore.VisitId = visitIdResponse.VisitId;
else
answerCore.TransitId = visitIdResponse.VisitId;
answerCore.BSMDStatusInternal = MessageCore.BSMDStatus.RESPONDED;
DBManager.Instance.Save(answerCore);
}
}
else
{
_log.WarnFormat("{0} ANSWER parsed, but MessageCoreId is no Guid: {1}",
Path.GetFileName(answerFile), visitIdResponse.ClientRequestId);
}
}
else
{
_log.WarnFormat("Client request id is null in {0}", answerFile);
}
}
*/
}
catch(Exception ex)
{
_log.WarnFormat("Exception deserializing ANSWER file: {0}", ex.ToString());
isOK = false;
}
}
}
}
if(isOK)
{
// archive file
File.Move(answerFile, Path.Combine(Properties.Settings.Default.AnswerArchiveDir, Path.GetFileName(answerFile)));
}
else
{
File.Move(answerFile, Path.Combine(Properties.Settings.Default.AnswerCorruptDir, Path.GetFileName(answerFile)));
}
}
catch (Exception ex)
{
_log.ErrorFormat("Exception occurred during deserialization: {0}", ex.Message);
}
return visitIdResponse;
}
}
}
}

View File

@ -1,217 +1,64 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
using System.Xml.Serialization;
//
// Dieser Quellcode wurde automatisch generiert von xsd, Version=4.6.1055.0.
//
using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
namespace bsmd.hisnord
{
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class SystemError
public class SystemError
{
private DateTime? _errorAt;
private string _meldeTyp;
private string _referenceId;
private int _processStatus;
private string _importFileName;
private int _errorCode;
private string _errorMessage;
private string _errorDescription;
private string errorAtField;
private string meldetypeField;
private string referenceIdField;
private string processStatusField;
private string transmissionRepeatedAtField;
private string importFilenameField;
private string visitIdField;
private string errorCodeField;
private string errorMessageField;
private string errorDescriptionField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string ErrorAt
public SystemError(XElement xml)
{
get
if(xml.Descendants("ErrorAt").Count() > 0)
{
return this.errorAtField;
_errorAt = DateTime.Parse(xml.Descendants("ErrorAt").First().Value);
}
set
_meldeTyp = xml.Descendants("MeldeType").First()?.Value;
_referenceId = xml.Descendants("ReferenceId").First()?.Value;
if(xml.Descendants("ProcessStatus").Count() > 0)
{
this.errorAtField = value;
_processStatus = Int32.Parse(xml.Descendants("ProcessStatus").First().Value);
}
_importFileName = xml.Descendants("ImportFilename").First()?.Value;
if(xml.Descendants("ErrorCode").Count() > 0)
{
_errorCode = Int32.Parse(xml.Descendants("ErrorCode").First().Value);
}
_errorMessage = xml.Descendants("ErrorMessage").First()?.Value;
_errorDescription = xml.Descendants("ErrorDescription").First()?.Value;
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string Meldetype
{
get
{
return this.meldetypeField;
}
set
{
this.meldetypeField = value;
}
}
#region Properties
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string ReferenceId
{
get
{
return this.referenceIdField;
}
set
{
this.referenceIdField = value;
}
}
public DateTime? ErrorAt { get { return _errorAt; } }
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string ProcessStatus
{
get
{
return this.processStatusField;
}
set
{
this.processStatusField = value;
}
}
public string MeldeTyp { get { return _meldeTyp; } }
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string TransmissionRepeatedAt
{
get
{
return this.transmissionRepeatedAtField;
}
set
{
this.transmissionRepeatedAtField = value;
}
}
public string ReferenceId { get { return _referenceId; } }
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string ImportFilename
{
get
{
return this.importFilenameField;
}
set
{
this.importFilenameField = value;
}
}
public int ProcessStatus { get { return _processStatus; } }
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string VisitId
{
get
{
return this.visitIdField;
}
set
{
this.visitIdField = value;
}
}
public string ImportFileName { get { return _importFileName; } }
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string ErrorCode
{
get
{
return this.errorCodeField;
}
set
{
this.errorCodeField = value;
}
}
public int ErrorCode { get { return _errorCode; } }
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string ErrorMessage
{
get
{
return this.errorMessageField;
}
set
{
this.errorMessageField = value;
}
}
public string ErrorMessage { get { return _errorMessage; } }
public string ErrorDescription { get { return _errorDescription; } }
#endregion
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string ErrorDescription
{
get
{
return this.errorDescriptionField;
}
set
{
this.errorDescriptionField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class NewDataSet
{
private SystemError[] itemsField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("SystemError")]
public SystemError[] Items
{
get
{
return this.itemsField;
}
set
{
this.itemsField = value;
}
}
}
}
}

View File

@ -25,6 +25,9 @@
<setting name="AnswerArchiveDir" serializeAs="String">
<value>E:\svnlager\BSMD\nsw\HIS-NORD\Transmitter-Tool\ANSWERS_DONE</value>
</setting>
<setting name="AnswerCorruptDir" serializeAs="String">
<value>E:\svnlager\BSMD\nsw\HIS-NORD\Transmitter-Tool\ANSWERS_CORRUPT</value>
</setting>
</bsmd.hisnord.Properties.Settings>
</userSettings>
</configuration>

File diff suppressed because it is too large Load Diff