using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Neo.Afx.Services;
namespace Neo.Afx.WinService.Messages
{
///
/// A base class for sending batches of SMS's or emails.
///
public abstract class MessageSender : Worker, IExecutable
{
readonly MessageTypeEnum _messageType;
#region Initialization
///
/// Initializes a new instance of the
/// class with the given configuration section and verbose logging.
///
/// The type of the message.
protected MessageSender(MessageTypeEnum messageType)
{
_messageType = messageType;
}
#endregion
#region MessageType
///
/// Gets the message type being handled.
///
protected MessageTypeEnum MessageType
{
get
{
return _messageType;
}
}
#endregion
#region Abstract Methods
protected abstract void InitializeSender(MessageDatabase database);
protected abstract void FinalizeSender(MessageDatabase database);
protected abstract bool ShouldRun(int count, out string error);
protected abstract bool SendMessage(Message message, List attachments, char recipientSeparator, out string error);
#endregion
#region Run
///
/// Sends the messages.
///
public void Run()
{
var trace = new StringBuilder();
using(var database = new MessageDatabase(Settings["ConnectionString"]))
{
try
{
InitializeSender(database);
var maxRetries = Int32.Parse(Settings["MaxRetries"]);
var recipientSeparator = Settings["RecipientSeparator"][0];
var messages = database.GetPendingMessages(MessageType).ToList();
if(messages.Count > 0)
{
string error;
var shouldRun = ShouldRun(messages.Count, out error);
if(!shouldRun)
{
trace.AppendLine(error);
}
else
{
#region Send messages
var n = 0;
foreach(var message in messages)
{
List attachments = null;
if(MessageType == MessageTypeEnum.Email)
{
attachments = database.GetAttachments(message).ToList();
}
var successful = SendMessage(message, attachments, recipientSeparator, out error);
if(successful)
{
n++;
message.SentDate = DateTime.Now;
}
else
{
trace.AppendFormat("Send Message {0} failed: {1}", message.MessageID, error);
trace.AppendLine();
message.Retries++;
if(message.Retries >= maxRetries)
{
message.IsCancelled = true;
}
}
message.UpdatedByID = UserID;
message.UpdatedDate = DateTime.Now;
database.Update(message, false);
}
database.Save();
trace.Insert(0, string.Format("Sent {0} of {1} messages.\n", n, messages.Count));
#endregion
}
}
}
finally
{
FinalizeSender(database);
}
}
TraceInfo = trace.ToString();
}
#endregion
}
}