FILE NUM SEQUENCE

DBH will eine fortlaufende Nummer bei der Abgabe von Dateien über SFTP
Diese wird über einen zentralen Zähler vergeben und in MessageHeader gespeichert
This commit is contained in:
Daniel Schick 2022-11-14 17:14:26 +01:00
parent b4e403eb16
commit 693c89e599
6 changed files with 90 additions and 21 deletions

11
SQL/Update_7.6_To_7.7.sql Normal file
View File

@ -0,0 +1,11 @@
-- Die DBH will fortlaufende Nummern an den versendeten Dateien. Das können sie
-- haben, aber wir legen eine Numerierung pro Meldeklasse an so dass kein Aufschluss
-- über die Gesamtzahl der versendeten Nachrichten möglich ist
PRINT N'Altering Table [dbo].[MessageHeader]...';
GO
ALTER TABLE [dbo].[MessageHeader]
ADD [FileNumSequence] INT NULL;
GO

View File

@ -454,6 +454,29 @@ namespace bsmd.database
return messageList[0];
}
public Message GetMessageByFileSeqNum(int fileSeqNum)
{
Message aMessage = new Message();
SqlCommand cmd = new SqlCommand();
const Message.LoadFilter filter = Message.LoadFilter.BY_FILE_SEQ_NUM;
aMessage.PrepareLoadCommand(cmd, filter, fileSeqNum);
SqlDataReader reader = this.PerformCommand(cmd);
List<DatabaseEntity> messages = aMessage.LoadList(reader);
List<Message> messageList = new List<Message>();
foreach (Message message in messages)
messageList.Add(message);
if (messageList.Count == 0) return null;
this.LoadMessageDependencies(messageList);
if (messageList[0].MessageCoreId.HasValue)
messageList[0].MessageCore = this.GetMessageCoreById(messageList[0].MessageCoreId.Value);
return messageList[0];
}
public MessageCore GetMessageCoreById(Guid id)
{
MessageCore aCore = new MessageCore();
@ -544,8 +567,6 @@ namespace bsmd.database
return result;
}
public MessageCore GetMessageCoreByShipInfos(string imo, DateTime eta, string poc)
{
MessageCore aCore = new MessageCore();
@ -741,6 +762,18 @@ namespace bsmd.database
}
}
public int? GetMessageFileMaxNum()
{
int? result = 0;
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "SELECT MAX(FileNumSequence) FROM MessageHeader";
result = this.PerformReadIntQuery(cmd);
if (result == null) result = 0;
}
return result;
}
#endregion
#region internal/private funcs

View File

@ -142,7 +142,8 @@ namespace bsmd.database
IMPORTHEADER_ID,
BY_CORE_AND_CLASS,
BY_AGE,
WASRCPT_ID
WASRCPT_ID,
BY_FILE_SEQ_NUM
}
/// <summary>
@ -396,6 +397,12 @@ namespace bsmd.database
/// </summary>
public int Flags { get; set; }
/// <summary>
/// If message was sent via dbh, this is the consecutive number used in the file name,
/// null if unused
/// </summary>
public int? FileSequenceNumber { get; set; }
#endregion
#region IDatabaseEntity implementation
@ -443,13 +450,14 @@ namespace bsmd.database
cmd.Parameters.AddWithNullableValue("@SENDSUCCESS", this.SendSuccess);
cmd.Parameters.AddWithNullableValue("@SENTBY", this.SentBy);
cmd.Parameters.AddWithValue("@FLAGS", this.Flags);
cmd.Parameters.AddWithNullableValue("@FILESEQNUM", this.FileSequenceNumber);
if (this.IsNew)
{
this.CreateId();
cmd.Parameters.AddWithValue("@ID", this.Id);
string query = string.Format("INSERT INTO {0} (Id, ClientRequestId, MessageCoreId, MessageId, SentAt, ReceivedAt, RequestedAt, NotificationClass, Reset, Cancel, Status, ReportingPartyId, BSMDStatus, LastStatus, HIS, CreatedBy, ChangedBy, StatusInfo, SendSuccess, SentBy, Flags) " +
"VALUES (@ID, @CLIENTREQUESTID, @MESSAGECOREID, @MESSAGEID, @SENTAT, @RECEIVEDAT, @REQUESTEDAT, @NOTIFICATIONCLASS, @RESET, @CANCEL, @STATUS, @REPORTINGPARTYID, @BSMDSTATUS, @LASTSTATUS, @HIS, @CREATEDBY, @CHANGEDBY, @STATUSINFO, @SENDSUCCESS, @SENTBY, @FLAGS)",
string query = string.Format("INSERT INTO {0} (Id, ClientRequestId, MessageCoreId, MessageId, SentAt, ReceivedAt, RequestedAt, NotificationClass, Reset, Cancel, Status, ReportingPartyId, BSMDStatus, LastStatus, HIS, CreatedBy, ChangedBy, StatusInfo, SendSuccess, SentBy, Flags, FileNumSequence) " +
"VALUES (@ID, @CLIENTREQUESTID, @MESSAGECOREID, @MESSAGEID, @SENTAT, @RECEIVEDAT, @REQUESTEDAT, @NOTIFICATIONCLASS, @RESET, @CANCEL, @STATUS, @REPORTINGPARTYID, @BSMDSTATUS, @LASTSTATUS, @HIS, @CREATEDBY, @CHANGEDBY, @STATUSINFO, @SENDSUCCESS, @SENTBY, @FLAGS, @FILESEQNUM)",
this.Tablename);
cmd.CommandText = query;
}
@ -458,7 +466,7 @@ namespace bsmd.database
cmd.Parameters.AddWithValue("@ID", this.Id);
cmd.CommandText = string.Format("UPDATE {0} SET ClientRequestId = @CLIENTREQUESTID, MessageId = @MESSAGEID, SentAt = @SENTAT, ReceivedAt = @RECEIVEDAT, RequestedAt = @REQUESTEDAT, " +
"NotificationClass = @NOTIFICATIONCLASS, Reset = @RESET, Cancel = @CANCEL, Status = @STATUS, ReportingPartyId = @REPORTINGPARTYID, BSMDStatus = @BSMDSTATUS, LastStatus = @LASTSTATUS, HIS = @HIS, " +
"CreatedBy = @CREATEDBY, ChangedBy = @CHANGEDBY, StatusInfo = @STATUSINFO, SendSuccess = @SENDSUCCESS, SentBy = @SENTBY, Flags = @FLAGS WHERE Id = @ID", this.Tablename);
"CreatedBy = @CREATEDBY, ChangedBy = @CHANGEDBY, StatusInfo = @STATUSINFO, SendSuccess = @SENDSUCCESS, SentBy = @SENTBY, Flags = @FLAGS, FileNumSequence = @FILESEQNUM WHERE Id = @ID", this.Tablename);
}
}
@ -466,7 +474,7 @@ namespace bsmd.database
public override void PrepareLoadCommand(IDbCommand cmd, LoadFilter filter, params object[] criteria )
{
string query = string.Format("SELECT Id, ClientRequestId, MessageCoreId, MessageId, SentAt, ReceivedAt, RequestedAt, NotificationClass, " +
"Reset, Cancel, Status, ReportingPartyId, BSMDStatus, LastStatus, HIS, Created, CreatedBy, ChangedBy, Changed, StatusInfo, SendSuccess, SentBy, Flags FROM {0} ",
"Reset, Cancel, Status, ReportingPartyId, BSMDStatus, LastStatus, HIS, Created, CreatedBy, ChangedBy, Changed, StatusInfo, SendSuccess, SentBy, Flags, FileNumSequence FROM {0} ",
this.Tablename);
switch (filter)
@ -520,6 +528,12 @@ namespace bsmd.database
((SqlCommand)cmd).Parameters.AddWithValue("@CLASS", criteria[1]);
break;
}
case LoadFilter.BY_FILE_SEQ_NUM:
{
query += "WHERE FileNumSequence = @FILESEQNUM";
((SqlCommand)cmd).Parameters.AddWithValue("@FILESEQNUM", criteria[0]);
break;
}
case LoadFilter.ALL:
default:
break;
@ -557,6 +571,7 @@ namespace bsmd.database
if (!reader.IsDBNull(20)) msg.SendSuccess = reader.GetBoolean(20);
if (!reader.IsDBNull(21)) msg.SentBy = reader.GetString(21);
if (!reader.IsDBNull(22)) msg.Flags = reader.GetInt32(22);
if (!reader.IsDBNull(23)) msg.FileSequenceNumber = reader.GetInt32(23);
result.Add(msg);
}
reader.Close();

View File

@ -15,6 +15,7 @@ namespace bsmd.dbh
public static class MessageController
{
private static readonly ILog _log = LogManager.GetLogger(typeof(MessageController));
private static int? _fileSequenceCounter = null;
public static bool SendMessage(MessageCore core, Message message)
{
@ -38,6 +39,11 @@ namespace bsmd.dbh
return false;
}
if (!_fileSequenceCounter.HasValue)
_fileSequenceCounter = DBManager.Instance.GetMessageFileMaxNum();
_fileSequenceCounter += 1;
message.FileSequenceNumber = _fileSequenceCounter;
string messageFile = RequestUtil.CreateMessageFile(core, message);
if (messageFile != null)

View File

@ -1639,7 +1639,7 @@ namespace bsmd.dbh
// serialize output structure to file
string filename = string.Format("NSW.BSMD.DBH.{1}.{0}.xml", (message == null) ? "CANCEL" : message.MessageNotificationClassDisplay, core.Id.Value);
string filename = string.Format("NSW.DBH.BSMD.{0}.xml", message.FileSequenceNumber);
_log.InfoFormat("saving {0} to output directory", filename);
string filePath = Path.Combine(Path.GetTempPath(), filename);

View File

@ -17,7 +17,7 @@ namespace bsmd.dbh
internal static class ResponseUtil
{
private static readonly ILog _log = LogManager.GetLogger(typeof(ResponseUtil));
private static readonly Regex _regexFilename = new Regex(@".*NSW\.DBH\.BSMD\.(.*)\.(.*)\.xml");
private static readonly Regex _regexFilename = new Regex(@".*NSW\.DBH\.BSMD\.(.*)\.xml");
internal static bool Read(string inputFile)
{
@ -33,23 +33,27 @@ namespace bsmd.dbh
_log.WarnFormat("returned file doesn't follow naming convention NSW.DBH.BSMD.*:{0}", inputFile);
return result;
}
string guidString = m.Groups[0].Value;
if(!Guid.TryParse(guidString, out Guid coreId))
string fileSeqString = m.Groups[0].Value;
if(!Int32.TryParse(fileSeqString, out int fileSeqNum))
{
_log.ErrorFormat("matched Guid couldn't be parsed: {0}", guidString);
return result;
}
string notificationClassString = m.Groups[1].Value;
if(!Enum.TryParse<Message.NotificationClass>(notificationClassString, out Message.NotificationClass notificationClass))
{
_log.WarnFormat("Notification class couldn't be parsed: {0}", notificationClassString);
_log.ErrorFormat("matched file sequence number couldn't be parsed: {0}", fileSeqString);
return result;
}
MessageCore aCore = DBManager.Instance.GetMessageCoreById(coreId);
// load message(s?) by file seq string
Message sentMessage = DBManager.Instance.GetMessageByFileSeqNum(fileSeqNum);
if(sentMessage == null)
{
_log.ErrorFormat("cannot find a message for file sequence number {0}", fileSeqNum);
return result;
}
MessageCore aCore = DBManager.Instance.GetMessageCoreById(sentMessage.MessageCoreId.Value);
if(aCore == null)
{
_log.ErrorFormat("There is no core with id {0}", coreId);
_log.ErrorFormat("There is no core with id {0}", sentMessage.MessageCoreId.Value);
return result;
}