Example #1
0
        public void Perform_RealAdmin_ExistingIdea()
        {
            Add_Accessor target = new Add_Accessor(); // TODO: Initialize to an appropriate value

            IDataStore store = DataStore.GetInstance();

            DailyIdea idea = new DailyIdea
            {
                Idea = "This is the added message",
            };

            store.Save(idea);

            Assert.AreNotEqual(0, idea.Id);

            IncomingSmsMessage message = new IncomingSmsMessage
            {
                From    = Configuration.GetInstance().AdminNumber,
                Message = string.Format(CultureInfo.InvariantCulture, "add {0}", idea.Idea),
            };

            target.Perform(message);

            Assert.AreEqual(1, store.DailyIdeas.Count(i => i.Idea == idea.Idea));
            OutgoingSmsMessage response = store.OutgoingMessages.Where(o => o.Message == SmsResponseStrings.Add_Failed_ExistingIdea(idea.Id)).First();

            Assert.AreEqual(Configuration.GetInstance().AdminNumber, response.Destination);
        }
Example #2
0
        protected static void Say(string destination, string message)
        {
            IDataStore         store = DataStore.GetInstance();
            OutgoingSmsMessage msg   = OutgoingSmsMessage.CreateWithDefaults(destination, message);

            store.Save(msg);
        }
Example #3
0
        public void Run()
        {
            LogManager.Log.Info("WorkerRole.Run Loop Started");

            using (IOutgoingSmsQueue outgoing = OutgoingSmsQueue.GetInstance())
            {
                outgoing.Send(OutgoingSmsMessage.CreateWithDefaults(_Configuration.AdminNumber,
                                                                    "WorkerRole.Run Loop Started"),
                              null,
                              null);

                while (true)
                {
                    // waiting for the queue to drain ensures we won't pick up the same one twice
                    if (outgoing.Length == 0)
                    {
                        IDataStore store = DataStore.GetInstance();

                        ProcessOutgoingMessages(outgoing, store);
                        ProcessSubscriptions(outgoing, store);
                    }
                    else
                    {
                        // there is already a back-log do don't go adding more to it...
                        Thread.Sleep(5 * 1000);
                    }
                }
            }
        }
Example #4
0
 public void Remove(OutgoingSmsMessage msg)
 {
     lock (_lock)
     {
         _outgoingMessages.Remove(msg.Id);
     }
 }
Example #5
0
        public override bool OnStart()
        {
            // Set the maximum number of concurrent connections
            ServicePointManager.DefaultConnectionLimit = 12;

            try
            {
                CreateServiceHost();
                LogManager.Log.Info("WCF Services started");
            }
            catch (Exception ex)
            {
                LogManager.Log.Error("Exception configuring WCF Services", ex);

                using (IOutgoingSmsQueue outgoing = OutgoingSmsQueue.GetInstance())
                {
                    IConfiguration config = Configuration.GetInstance();
                    outgoing.Send(OutgoingSmsMessage.CreateWithDefaults(config.AdminNumber,
                                                                        "WCF STARTUP ERROR: " + ex.GetType().FullName),
                                  null,
                                  null);
                }
            }

            return(base.OnStart());
        }
Example #6
0
        public void SenderSends()
        {
            ObjectFactory.Initialize(x =>
            {
                x.For <ILogging>().Use <TraceLogger>();
                x.For <ISmsTransport>().Use <SuccessSmsSender>();
                x.For <IDataStore>().Use <TestDataStore>();
            });

            int toSend = 10;

            int[]            count = { 0 };
            ManualResetEvent done  = new ManualResetEvent(false);

            bool[] sendFailed = new bool[1] {
                false
            };

            SendCompleteCallback complete = (SentSmsMessageLogEntry result, OutgoingSmsMessage msg) =>
            {
                Assert.AreEqual((int)MessageSendStatus.Success, result.Status);
                Assert.AreEqual(count[0], msg.Id, "The subscription ID was incorrect");

                count[0]++;

                if (count[0] == toSend)
                {
                    done.Set();
                }
            };

            SmsSenderExceptionThrownCallback failed = (OutgoingSmsMessage message, Exception exception) =>
            {
                sendFailed[0] = true;
                Assert.Fail(string.Format(CultureInfo.InvariantCulture, "Sending message {0} failed?", message.Id));
            };

            SmsSenderQueue sender = new SmsSenderQueue();

            for (int i = 0; i < 10; i++)
            {
                OutgoingSmsMessage msg = new OutgoingSmsMessage
                {
                    Message     = "This is the message",
                    Destination = "+11234567890",
                    Id          = i,
                };

                sender.Send(msg, complete, failed);
            }

            Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(toSend)), "Sending timed out ... that's not good!");
            Assert.IsFalse(sendFailed[0], "The send was marked as failed ... wtf???");
        }
Example #7
0
 public void ScheduleMessage(OutgoingSmsMessage msg, Subscription sub)
 {
     lock (_lock)
     {
         Save(msg);
         Subscription toUpdate = Subscriptions.Where(s => s.Id == sub.Id).FirstOrDefault();
         if (toUpdate != null)
         {
             toUpdate.Next = DateTime.Today.AddDays(1).ToUniversalTime().AddHours(2);
         }
     }
 }
Example #8
0
        public void Save(OutgoingSmsMessage msg)
        {
            lock (_lock)
            {
                if (msg.Id == 0)
                {
                    msg.Id = NextId();
                }

                _outgoingMessages[msg.Id] = msg;
            }
        }
Example #9
0
        public void SenderFailsCallback()
        {
            ObjectFactory.Initialize(x =>
            {
                x.For <ILogging>().Use <TraceLogger>();
                x.For <ISmsTransport>().Use <FailureSmsSender>();
                x.For <IDataStore>().Use <TestDataStore>();
            });

            int toSend = 10;

            int[]            count = { 0 };
            ManualResetEvent done  = new ManualResetEvent(false);

            bool[] sendSucceeded = new[] { false };

            SendCompleteCallback complete = (SentSmsMessageLogEntry result, OutgoingSmsMessage msg) =>
            {
                sendSucceeded[0] = result.Status != (int)MessageSendStatus.Error;
                Assert.AreEqual(count[0], msg.Id, "The subscription ID was incorrect");
                Assert.AreEqual((int)MessageSendStatus.Error, result.Status);

                count[0]++;

                if (count[0] == toSend)
                {
                    done.Set();
                }
            };

            SmsSenderExceptionThrownCallback failed = (OutgoingSmsMessage msg, Exception exception) =>
            {
                Assert.Fail("The exception callback should not have been called");
            };

            SmsSenderQueue sender = new SmsSenderQueue();

            for (int i = 0; i < 10; i++)
            {
                OutgoingSmsMessage msg = new OutgoingSmsMessage
                {
                    Message     = "This is the message",
                    Destination = "+11234567890",
                    Id          = i,
                };

                sender.Send(msg, complete, failed);
            }

            Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(toSend)), "Sending timed out ... that's not good!");
            Assert.IsFalse(sendSucceeded[0], "The send should not have been marked as successful");
        }
Example #10
0
        void MessageSent(SentSmsMessageLogEntry result, OutgoingSmsMessage message)
        {
            IDataStore store = DataStore.GetInstance();

            if (result.Status == (int)MessageSendStatus.Success)
            {
                // delete copy local to this store
                store.Remove(store.OutgoingMessages.Where(m => m.Id == message.Id).FirstOrDefault());
            }
            else
            {
                ProcessSendFailure(message);
            }
        }
Example #11
0
        public void Perform_RealAdmin()
        {
            Add_Accessor       target  = new Add_Accessor(); // TODO: Initialize to an appropriate value
            IncomingSmsMessage message = new IncomingSmsMessage
            {
                From    = Configuration.GetInstance().AdminNumber,
                Message = "add This is the added message",
            };

            target.Perform(message);

            IDataStore store = DataStore.GetInstance();

            DailyIdea          addedIdea = store.DailyIdeas.Where(i => i.Idea == "This is the added message").First();
            OutgoingSmsMessage response  = store.OutgoingMessages.Where(o => o.Message == SmsResponseStrings.Add_Success_AddedNewIdea(addedIdea.Id)).First();

            Assert.AreEqual(Configuration.GetInstance().AdminNumber, response.Destination);
        }
Example #12
0
        private void ProcessSendFailure(OutgoingSmsMessage msg)
        {
            IDataStore store = DataStore.GetInstance();

            // reload from the local store
            msg = store.OutgoingMessages.Where(m => m.Id == msg.Id).First();
            if (msg != null)
            {
                if (msg.Attempts < 10)
                {
                    msg.Attempts++;

                    DateTime next;
                    if (msg.Attempts < 10)
                    {
                        next = DateTime.UtcNow.AddMinutes(msg.Attempts * 10);
                    }
                    else
                    {
                        next = DateTime.UtcNow.AddHours(18);
                    }

                    msg.NextAttempt = next;
                    store.Save(msg);
                }
                else
                {
                    SentSmsMessageLogEntry entry = new SentSmsMessageLogEntry
                    {
                        Date        = DateTime.UtcNow,
                        Destination = msg.Destination,
                        Message     = msg.Message,
                        Status      = (int)MessageSendStatus.Abandoned,
                        Details     = string.Format(CultureInfo.InvariantCulture, "Fatal SMS Send error - giving up on sending message {0} - it was attempted {1} times.",
                                                    msg.Id,
                                                    msg.Attempts),
                    };

                    store.Save(entry);
                    store.Remove(msg);
                }
            }
        }
Example #13
0
        public void Send(OutgoingSmsMessage msg, SendCompleteCallback complete, SmsSenderExceptionThrownCallback exceptionThrown)
        {
            ThrowIfDisposed();

            lock (_lock)
            {
                if (!queued.Contains(msg.Id))
                {
                    _processor.Add(new SmsSenderMessage
                    {
                        Message  = msg,
                        Complete = complete,
                        Failed   = exceptionThrown,
                    });

                    queued.Add(msg.Id);
                }
            }
        }
Example #14
0
        public void Perform_UnknownUser()
        {
            string destinationNumber = "+11112223333";

            Add_Accessor       target  = new Add_Accessor(); // TODO: Initialize to an appropriate value
            IncomingSmsMessage message = new IncomingSmsMessage
            {
                From    = destinationNumber,
                Message = "add This is the added message",
            };

            target.Perform(message);

            IDataStore store = DataStore.GetInstance();

            Assert.IsFalse(store.DailyIdeas.Any());
            OutgoingSmsMessage response = store.OutgoingMessages.Where(o => o.Message == SmsResponseStrings.PublicHelp()).First();

            Assert.AreEqual(destinationNumber, response.Destination);
        }
Example #15
0
        private static void ProcessSubscriptions(IOutgoingSmsQueue outgoing, IDataStore store)
        {
            DailyIdea idea = DailyIdea.TodaysIdea(DateTime.Today.ToUniversalTime());

            if (idea != null)
            {
                // now deal with the existing subscriptions
                // all where doing here is creating entries in the OutgoingSmsMessage table and updating the Next field on the
                // Subscription.  These will be picked up on the next pass through the loop by the message sender.
                IList <Subscription> toProcess = store.Subscriptions.Where(s => s.Next < DateTime.UtcNow)
                                                 .Take(outgoing.MessagesPerMinute)
                                                 .ToList();

                foreach (Subscription sub in toProcess)
                {
                    OutgoingSmsMessage msg = OutgoingSmsMessage.CreateWithDefaults(sub.Phone, idea.Idea);
                    store.ScheduleMessage(msg, sub);
                }
            }
        }
Example #16
0
 void MessageSendThrewException(OutgoingSmsMessage msg, Exception ex)
 {
     LogManager.Log.Error("Exception sending SMS message", ex);
     ProcessSendFailure(msg);
 }