git_bsmd/nsw/Source/bsmd.dbh/Response.cs

264 lines
14 KiB
C#

//
// Class: Response
// Current CLR: 4.0.30319.34209
// System: Microsoft Visual Studio 10.0
// Author: dani
// Created: 3/1/2015 8:12:08 PM
//
// Copyright (c) 2015 Informatikbüro Daniel Schick. All rights reserved.
using System;
using System.Collections.Generic;
using bsmd.database;
using log4net;
using System.IO;
using System.Xml.Serialization;
namespace bsmd.dbh
{
public class Response
{
private static readonly ILog _log = LogManager.GetLogger("dbh Response");
public static void ProcessResponse(string VisitId, string TransitId, DateTime Timestamp,
string SenderReference, response.RootType Type, bsmd.dbh.response.Message[] Messages,
bsmd.dbh.response.RootReportingClassesFull ReportingClassesFull,
bsmd.dbh.response.RootReportingClassesPartial ReportingClassesPartial,
bsmd.dbh.response.RootReportingClassesError ReportingClassesError,
bsmd.dbh.response.RootReportingClassesResetted ReportingClassesResetted,
bsmd.dbh.response.RootReportingClassesNoChanges ReportingClassesNoChanges,
string connectionString)
{
/*
XmlSerializer serializer = new XmlSerializer(typeof(response.Root));
using(StringWriter textWriter = new StringWriter())
{
serializer.Serialize(textWriter, aResponse);
_log.Debug(textWriter.ToString());
}
*/
// _log.Debug(aResponse.Serialize());
if (DBManager.Instance.Connect(connectionString))
{
_log.DebugFormat("Start PROCESS, Timestamp: {0}", Timestamp);
if (!Guid.TryParseExact(SenderReference, "N", out Guid messageId))
{
_log.WarnFormat("SenderReference {0} is not a guid, skipping message processing!", SenderReference);
return;
}
DatabaseEntity dbEntity = DBManager.Instance.GetMessageById(messageId);
Message aMessage = dbEntity as Message;
if (aMessage != null)
{
_log.InfoFormat("Message type {0} found for SenderReference {1}", ((Message)dbEntity).MessageNotificationClassDisplay, messageId);
foreach (MessageError existingError in aMessage.ErrorList)
DBManager.Instance.Delete(existingError);
}
if (dbEntity == null)
{
MessageCore aCore = DBManager.Instance.GetMessageCoreById(messageId);
if ((aCore != null) && (Type == response.RootType.CANCEL))
{
_log.InfoFormat("Cancel confirmation received for {0} ({1})", aCore.Id, aCore.DisplayId);
aCore.BSMDStatusInternal = MessageCore.BSMDStatus.RESPONDED;
aCore.Cancelled = true;
DBManager.Instance.Save(aCore);
return;
}
}
if (dbEntity == null)
{
_log.WarnFormat("Message / Core with ID {0} not found in database, skipping", messageId);
return;
}
if (!(dbEntity is Message) && (Type != dbh.response.RootType.CANCEL))
{
_log.WarnFormat("SenderReference DB Entity Object is no MessageHeader, aborting ({0})", dbEntity.GetType());
return;
}
switch (Type)
{
case dbh.response.RootType.VISIT:
_log.InfoFormat("Visit-Id received: {0}", VisitId ?? "??!");
if(!VisitId.IsNullOrEmpty())
aMessage.MessageCore.VisitId = VisitId;
aMessage.MessageCore.BSMDStatusInternal = MessageCore.BSMDStatus.PREPARE;
aMessage.SendSuccess = true;
DBManager.Instance.Save(aMessage.MessageCore);
aMessage.InternalStatus = Message.BSMDStatus.CONFIRMED;
DBManager.Instance.Save(aMessage);
break;
case dbh.response.RootType.TRANSIT:
_log.InfoFormat("Transit-Id received: {0}", TransitId ?? "??!");
aMessage.MessageCore.TransitId = TransitId;
aMessage.MessageCore.BSMDStatusInternal = MessageCore.BSMDStatus.PREPARE;
aMessage.SendSuccess = true;
DBManager.Instance.Save(aMessage.MessageCore);
aMessage.InternalStatus = Message.BSMDStatus.CONFIRMED;
DBManager.Instance.Save(aMessage);
break;
case dbh.response.RootType.RESET:
// Die Liste ist auch bei erfolgtem RESET offenbar immer NULL...
//if ((ReportingClassesResetted != null) && (ReportingClassesResetted.Count > 0))
// das Mapping stimmt bei uns natürlich so nicht, aber da die Nachrichten einzeln gehen sollte es trotzdem funktionieren
// (int) ReportingClassesResetted[0].ReportingClass[0] == (int)aMessage.MessageNotificationClass)
//{
//_log.InfoFormat("RESET response received for {0}", ReportingClassesResetted[0].ReportingClass[0]);
aMessage.Reset = true;
aMessage.SendSuccess = false; // zurücksetzen des "grünen Punkts" im ENI-2
aMessage.InternalStatus = Message.BSMDStatus.CONFIRMED;
//}
break;
case dbh.response.RootType.DATA:
if(ReportingClassesFull?.ReportingClass.Length > 0)
{
// this was successful, save status to MessageHeader
aMessage.SendSuccess = true;
aMessage.InternalStatus = Message.BSMDStatus.CONFIRMED;
aMessage.Status = Message.MessageStatus.ACCEPTED;
_log.InfoFormat("full message class accepted");
}
if (ReportingClassesPartial?.ReportingClass.Length > 0)
{
// this was successful, save status to MessageHeader
aMessage.SendSuccess = true;
aMessage.InternalStatus = Message.BSMDStatus.ERROR;
aMessage.Status = Message.MessageStatus.ACCEPTED;
_log.InfoFormat("partial message class accepted");
}
if (ReportingClassesError?.ReportingClass.Length > 0)
{
// this was successful, save status to MessageHeader
aMessage.SendSuccess = true;
aMessage.InternalStatus = Message.BSMDStatus.ERROR;
aMessage.Status = Message.MessageStatus.ACCEPTED;
_log.InfoFormat("message class accepted but error");
}
if(ReportingClassesNoChanges?.ReportingClass.Length > 0)
{
// this was successful, yet unnecessary ;-)
aMessage.SendSuccess = true;
aMessage.InternalStatus = Message.BSMDStatus.CONFIRMED;
aMessage.Status = Message.MessageStatus.ACCEPTED;
_log.InfoFormat("message accepted, data was unchanged");
}
bool isReset = false;
if(ReportingClassesResetted?.ReportingClass.Length > 0)
{
aMessage.SendSuccess = false;
aMessage.InternalStatus = Message.BSMDStatus.CONFIRMED;
aMessage.Status = Message.MessageStatus.ACCEPTED;
isReset = true;
_log.InfoFormat("RESET successful for message");
}
if (isReset && !aMessage.Reset)
aMessage.Reset = isReset;
// check the whole thing for completion
MessageCore core = DBManager.Instance.GetMessageCoreById(aMessage.MessageCoreId.Value);
bool stillSomethingSent = false;
foreach(Message message in DBManager.Instance.GetMessagesForCore(core, DBManager.MessageLoad.ALL))
{
if (aMessage.Id.Value == message.Id.Value) continue;
if(message.InternalStatus == Message.BSMDStatus.SENT)
{
stillSomethingSent = true;
break;
}
}
if(!stillSomethingSent && (core.BSMDStatusInternal == MessageCore.BSMDStatus.SENT))
{
core.BSMDStatusInternal = MessageCore.BSMDStatus.RESPONDED;
DBManager.Instance.Save(core);
}
break;
}
if (Messages != null)
{
// Status zu den jeweiligen Nachrichten. Bei uns sollte die Anzahl hier immer 1 sein, da wir die Dinger
// einzeln verschicken.
for (int i = 0; i < Messages.Length; i++)
{
_log.InfoFormat("message {0} type {1}: {2}", i,
Messages[i].Type,
Messages[i].Text ?? "null");
bool hasCode = Int32.TryParse(Messages[i].ID, out int code);
switch (Messages[i].Type)
{
case dbh.response.RootMessageType.ERROR:
MessageError error = new MessageError();
error.ErrorText = Messages[i].Text;
if (hasCode) error.ErrorCode = code;
_log.WarnFormat("Error received for {0}: {1}", Messages[i].Type, error.ErrorText);
error.MessageHeaderId = aMessage.Id.Value;
aMessage.InternalStatus = Message.BSMDStatus.ERROR;
aMessage.StatusInfo = string.Format("Id:{0} Loc:{1} - {2}", Messages[i].ID, Messages[i].Location, Messages[i].Text);
DBManager.Instance.Save(error);
aMessage.SendSuccess = false;
break;
case dbh.response.RootMessageType.VIOLATION:
MessageViolation violation = new MessageViolation();
violation.ViolationText = Messages[i].Text;
if (hasCode) violation.ViolationCode = code;
_log.WarnFormat("Violation received for {0}: {1}", Messages[i].Type, violation.ViolationText);
violation.MessageHeaderId = aMessage.Id.Value;
aMessage.InternalStatus = Message.BSMDStatus.VIOLATION;
aMessage.StatusInfo = string.Format("Id:{0} Loc:{1} - {2}", Messages[i].ID, Messages[i].Location, Messages[i].Text);
aMessage.SendSuccess = true;
DBManager.Instance.Save(violation);
break;
case dbh.response.RootMessageType.WARNING:
_log.InfoFormat("WARNING received for {0}: {1}", Messages[i].Type, Messages[i].Text);
aMessage.StatusInfo = string.Format("Id:{0} Loc:{1} - {2}", Messages[i].ID, Messages[i].Location, Messages[i].Text);
aMessage.SendSuccess = true;
break;
case dbh.response.RootMessageType.INFO:
default:
_log.InfoFormat("INFO received for {0}: {1}", Messages[i].Type, Messages[i].Text);
aMessage.StatusInfo = string.Format("Id:{0} Loc:{1} - {2}", Messages[i].ID, Messages[i].Location, Messages[i].Text);
aMessage.SendSuccess = true;
break;
}
if (aMessage.Reset) aMessage.SendSuccess = false; // Send flag zurücksetzen
}
}
aMessage.ReceivedAt = DateTime.Now;
DBManager.Instance.Save(aMessage);
DBManager.Instance.Disconnect();
}
else
{
_log.Fatal("cannot connect to database");
}
}
}
}