// // 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, Properties.Settings.Default.SFTPSessionName); // 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), Properties.Settings.Default.SFTPSessionName); } } 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; } } }