184 lines
8.3 KiB
C#
184 lines
8.3 KiB
C#
//
|
|
// Class: Response
|
|
// Current CLR: 4.0.30319.34209
|
|
// System: Microsoft Visual Studio 10.0
|
|
// Author: dani
|
|
// Created: 5/5/2015 8:13:01 AM
|
|
//
|
|
// Copyright (c) 2015 Informatikbüro Daniel Schick. All rights reserved.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Xml;
|
|
using System.Xml.Serialization;
|
|
using System.Text;
|
|
using log4net;
|
|
|
|
using bsmd.database;
|
|
|
|
|
|
namespace bsmd.dakosy
|
|
{
|
|
public static class Response
|
|
{
|
|
private static readonly ILog _log = LogManager.GetLogger(typeof(Request));
|
|
|
|
public static void ReadAll()
|
|
{
|
|
// SFTP verbindung öffnen und alle Dateien herunterladen
|
|
string localDir = Properties.Settings.Default.SFTPInDir;
|
|
string remoteDir = Properties.Settings.Default.RemoteOutgoingDir;
|
|
|
|
SFtp.TransmitAll(remoteDir, localDir, SFtp.Direction.INCOMING);
|
|
|
|
// lokale Dateien verarbeiten
|
|
foreach (string inputFile in Directory.GetFiles(localDir))
|
|
{
|
|
if (!Response.Read(inputFile))
|
|
{
|
|
_log.ErrorFormat("Error reading input file {0}", inputFile);
|
|
}
|
|
else
|
|
{
|
|
File.Delete(inputFile); // alternativ: move to archive folder
|
|
}
|
|
// remote Dateien löschen
|
|
SFtp.RemoveProcessedFile(remoteDir, Path.GetFileName(inputFile));
|
|
}
|
|
}
|
|
|
|
|
|
public static bool Read(string fullPath)
|
|
{
|
|
bool retval = true;
|
|
|
|
try
|
|
{
|
|
|
|
XmlSerializer serializer = new XmlSerializer(typeof(eDeclarationMessage));
|
|
FileStream fs = new FileStream(fullPath, FileMode.Open);
|
|
using (TextReader reader = new StreamReader(fs, System.Text.Encoding.UTF8))
|
|
{
|
|
eDeclarationMessage eDeclaration = (eDeclarationMessage)serializer.Deserialize(reader);
|
|
if (eDeclaration.InterchangeHeader.TestIndicator)
|
|
_log.Info("Test response message received");
|
|
eDeclarationMessageInterchangeBodyEdiResponseList responseList = eDeclaration.InterchangeBody.Item as eDeclarationMessageInterchangeBodyEdiResponseList;
|
|
foreach(EdiResponse ediResponse in responseList.EdiResponse)
|
|
{
|
|
if (!Guid.TryParseExact(ediResponse.LocalReferenceNumber, "N", out Guid localReferenceId))
|
|
{
|
|
_log.ErrorFormat("unable to parse local reference number {0}", ediResponse.LocalReferenceNumber);
|
|
}
|
|
if (!Guid.TryParseExact(ediResponse.PreviousMessageNumber, "N", out Guid messageReferenceId))
|
|
{
|
|
_log.ErrorFormat("unable to parse message reference id {0}", ediResponse.MessageHeader.MessageReferenceNumber);
|
|
}
|
|
|
|
// passendes Objekt in der DB finden:
|
|
MessageCore core = DBManager.Instance.GetMessageCoreById(localReferenceId);
|
|
DatabaseEntity dbEntity = DBManager.Instance.GetMessageById(messageReferenceId);
|
|
|
|
if (dbEntity == null)
|
|
{
|
|
_log.WarnFormat("Message not found for reference Id {0}", messageReferenceId);
|
|
continue;
|
|
}
|
|
|
|
// Objekte aktualisieren und speichern
|
|
|
|
Message aMessage = null;
|
|
if (dbEntity.GetType().IsAssignableFrom(typeof(Message)))
|
|
aMessage = (Message)dbEntity;
|
|
else
|
|
aMessage = dbEntity.MessageHeader;
|
|
|
|
//ediResponse.ResponseSubType == EdiResponseSubType.FUNCTIONAL // TECHNICAL
|
|
|
|
switch (ediResponse.ResponseType)
|
|
{
|
|
case EdiResponseType.ACCEPTED:
|
|
_log.Info("response message accepted");
|
|
|
|
if (aMessage.MessageNotificationClass == Message.NotificationClass.TRANSIT)
|
|
{
|
|
core.TransitId = ediResponse.TransitID;
|
|
DBManager.Instance.Save(core);
|
|
}
|
|
|
|
if(aMessage.MessageNotificationClass == Message.NotificationClass.VISIT)
|
|
{
|
|
core.VisitId = ediResponse.VisitID;
|
|
DBManager.Instance.Save(core);
|
|
}
|
|
aMessage.InternalStatus = Message.BSMDStatus.CONFIRMED;
|
|
|
|
break;
|
|
case EdiResponseType.ERROR:
|
|
_log.Info("response message error status");
|
|
|
|
foreach (ResponseError responseError in ediResponse.Errors)
|
|
{
|
|
MessageError messageError = new MessageError();
|
|
|
|
if (Int32.TryParse(responseError.ErrorCode, out int errCode))
|
|
messageError.ErrorCode = errCode;
|
|
else
|
|
_log.WarnFormat("cannot parse error code [{0}]", responseError.ErrorCode);
|
|
StringBuilder sb = new StringBuilder();
|
|
foreach(ErrorInfo errorInfo in responseError.ErrorInformations)
|
|
{
|
|
sb.AppendLine(errorInfo.Text);
|
|
}
|
|
messageError.ErrorText = sb.ToString();
|
|
messageError.MessageHeaderId = aMessage.Id.Value;
|
|
aMessage.ErrorList.Add(messageError);
|
|
DBManager.Instance.Save(messageError);
|
|
}
|
|
aMessage.InternalStatus = Message.BSMDStatus.ERROR;
|
|
|
|
break;
|
|
case EdiResponseType.PART_ACCEPTED:
|
|
_log.Info("response message part accepted");
|
|
|
|
// was passiert in diesem Zustand? Kann wahrscheinlich bei uns nicht passieren,
|
|
// weil immer nur eine Nachricht versendet wird
|
|
aMessage.InternalStatus = Message.BSMDStatus.ERROR;
|
|
|
|
break;
|
|
case EdiResponseType.RECEIVED:
|
|
_log.Info("response message received");
|
|
|
|
aMessage.InternalStatus = Message.BSMDStatus.CONFIRMED; // ? Ok?
|
|
break;
|
|
default:
|
|
_log.InfoFormat("unknown response type {0}", ediResponse.ResponseType);
|
|
break;
|
|
}
|
|
|
|
DBManager.Instance.Save(aMessage);
|
|
}
|
|
}
|
|
fs.Close();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_log.ErrorFormat("error parsing response:{0}", ex.ToString());
|
|
/*
|
|
* Zum Debuggen. Das funktioniert nur, wenn die PDB's mitkopiert werden
|
|
StackTrace st = new StackTrace(ex, true);
|
|
StackFrame sf = st.GetFrame(0);
|
|
string method = sf.GetMethod().Name;
|
|
int line = sf.GetFileLineNumber();
|
|
int col = sf.GetFileColumnNumber();
|
|
_log.ErrorFormat("Method {0} Line {1} Col{2}", method, line, col);
|
|
*/
|
|
retval = false;
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
}
|
|
}
|