예제 #1
0
        public async Task ShouldHandleChangeSaveAndDispatchWhenMxRecordsPolledReceived()
        {
            string snsTopicArn = "SnsTopicArn";

            A.CallTo(() => _mxEntityConfig.SnsTopicArn).Returns(snsTopicArn);

            string        domainName  = "testDomainName";
            MxEntityState stateFromDb = new MxEntityState(domainName.ToLower())
            {
                MxState = MxState.Created
            };

            A.CallTo(() => _dao.Get(domainName.ToLower())).Returns(Task.FromResult(stateFromDb));


            A.CallTo(() => _mxEntityConfig.NextScheduledInSeconds).Returns(33);
            A.CallTo(() => _clock.GetDateTimeUtc()).Returns(DateTime.MinValue);

            MxRecordsPolled message = new MxRecordsPolled(domainName, new List <HostMxRecord>(), null)
            {
                Timestamp = DateTime.UnixEpoch
            };

            await _mxEntity.Handle(message);

            Assert.AreEqual(stateFromDb.MxState, MxState.Evaluated);
            Assert.AreEqual(stateFromDb.HostMxRecords, message.Records);
            Assert.AreEqual(stateFromDb.LastUpdated, message.Timestamp);

            A.CallTo(() => _changeNotifiersComposite.Handle(stateFromDb, message)).MustHaveHappenedOnceExactly();
            A.CallTo(() => _dao.Save(stateFromDb)).MustHaveHappenedOnceExactly();
            A.CallTo(() => _dispatcher.Dispatch(A <MxRecordsUpdated> .That.Matches(a => a.Id == message.Id.ToLower() && a.Records.Count == 0), snsTopicArn)).MustHaveHappenedOnceExactly();
            A.CallTo(() => _dispatcher.Dispatch(A <CreateScheduledReminder> .That.Matches(a => a.ResourceId == domainName.ToLower() && a.Service == "Mx" && a.ScheduledTime.Second == 33), snsTopicArn)).MustHaveHappenedOnceExactly();
        }
        public void DoesNotNotifyWhenNoChangesWithDifferentCaseType()
        {
            string testDomain = "domain";

            MxEntityState state = new MxEntityState(testDomain)
            {
                HostMxRecords = new List <HostMxRecord>
                {
                    new HostMxRecord("HOSTNAME", 5, new List <string> {
                        "192.168.0.1"
                    })
                }
            };

            List <HostMxRecord> hostMxRecords = new List <HostMxRecord>
            {
                new HostMxRecord("hostname", 5, new List <string> {
                    "192.168.0.1"
                })
            };

            MxRecordsPolled mxRecordsPolled = new MxRecordsPolled(testDomain, hostMxRecords, TimeSpan.MinValue);

            _recordChangedNotifier.Handle(state, mxRecordsPolled);

            A.CallTo(() => _dispatcher.Dispatch(A <MxRecordAdded> ._, A <string> ._)).MustNotHaveHappened();
            A.CallTo(() => _dispatcher.Dispatch(A <MxRecordRemoved> ._, A <string> ._)).MustNotHaveHappened();
        }
        public void DoesNotNotifyWhenNoChanges()
        {
            string testDomain   = "domain";
            string testHostName = "hostname";

            MxEntityState state  = new MxEntityState(testDomain);
            HostMxRecord  record = new HostMxRecord(testHostName, 5, new List <string> {
                "192.168.0.1", "192.168.0.2"
            });

            state.HostMxRecords = new List <HostMxRecord> {
                new HostMxRecord(testHostName, 5, new List <string> {
                    "192.168.0.1"
                })
            };
            List <HostMxRecord> hostMxRecords = new List <HostMxRecord> {
                record
            };
            MxRecordsPolled mxRecordsPolled = new MxRecordsPolled(testDomain, hostMxRecords, TimeSpan.MinValue);

            _recordChangedNotifier.Handle(state, mxRecordsPolled);

            A.CallTo(() => _dispatcher.Dispatch(A <MxRecordAdded> ._, A <string> ._)).MustNotHaveHappened();
            A.CallTo(() => _dispatcher.Dispatch(A <MxRecordRemoved> ._, A <string> ._)).MustNotHaveHappened();
        }
        public async Task Handle(MxRecordsPolled message)
        {
            string domainName = message.Id.ToLower();

            MxEntityState state = await LoadState(domainName, nameof(message));

            MxState oldState       = state.MxState;
            int     oldRecordCount = state.HostMxRecords?.Count ?? 0;
            int     newRecordCount = message.Records?.Count ?? 0;

            _changeNotifiersComposite.Handle(state, message);

            List <HostMxRecord> validHostRecords = new List <HostMxRecord>();

            if (message.Records != null)
            {
                foreach (HostMxRecord hostRecord in message.Records)
                {
                    if (Uri.CheckHostName(hostRecord.Id) != UriHostNameType.Unknown)
                    {
                        validHostRecords.Add(hostRecord);
                    }
                    else
                    {
                        _log.LogInformation($"Erroneous host: {hostRecord.Id} found for domain: {domainName}");
                    }
                }
            }

            if (message.Error == null)
            {
                state.HostMxRecords = validHostRecords;
            }

            state.LastUpdated = message.Timestamp;
            state.Error       = message.Error;
            state.MxState     = MxState.Evaluated;

            await _dao.Save(state);

            _log.LogInformation($"Updated MxEntity from {oldState} to {MxState.Evaluated} and MX records before: {oldRecordCount} after: {newRecordCount} for {domainName}.");

            Message mxRecordsUpdated = new MxRecordsUpdated(domainName, validHostRecords);

            _dispatcher.Dispatch(mxRecordsUpdated, _mxEntityConfig.SnsTopicArn);
            _log.LogInformation($"An MxRecordsUpdated message for Domain: {domainName} has been dispatched to SnsTopic: {_mxEntityConfig.SnsTopicArn}");

            // Should probably change this so it only happens for a new host
            validHostRecords?.ForEach(mxRecord => {
                _dispatcher.Dispatch(new MxHostTestPending(mxRecord.Id), _mxEntityConfig.SnsTopicArn);
                _log.LogInformation($"An MxHostTestPending message for Host: {mxRecord.Id} has been dispatched to SnsTopic: {_mxEntityConfig.SnsTopicArn}");
            });

            Message createScheduledReminder = new CreateScheduledReminder(Guid.NewGuid().ToString(), "Mx", domainName, _clock.GetDateTimeUtc().AddSeconds(_mxEntityConfig.NextScheduledInSeconds));

            _dispatcher.Dispatch(createScheduledReminder, _mxEntityConfig.SnsTopicArn);
            _log.LogInformation($"A CreateScheduledReminder message for Domain: {domainName} has been dispatched to SnsTopic: {_mxEntityConfig.SnsTopicArn}");
        }
예제 #5
0
        public async Task ShouldOmitErroneousHostsFound()
        {
            string domainName = "test.gov.uk";
            string hostName1  = "test-host-inbound1 .com";
            string hostName2  = "test-host-inbound2.com";


            string snsTopicArn = "SnsTopicArn";

            A.CallTo(() => _mxEntityConfig.SnsTopicArn).Returns(snsTopicArn);

            List <HostMxRecord> hostMxRecords = new List <HostMxRecord>
            {
                new HostMxRecord(hostName1, 0, new List <string>()),
                new HostMxRecord(hostName2, 0, new List <string>()),
            };

            MxEntityState stateFromDb = new MxEntityState(domainName.ToLower())
            {
                MxState       = MxState.Created,
                HostMxRecords = hostMxRecords,
            };

            A.CallTo(() => _dao.Get(domainName.ToLower())).Returns(Task.FromResult(stateFromDb));


            A.CallTo(() => _mxEntityConfig.NextScheduledInSeconds).Returns(33);
            A.CallTo(() => _clock.GetDateTimeUtc()).Returns(DateTime.MinValue);

            MxRecordsPolled message = new MxRecordsPolled(domainName, hostMxRecords, null)
            {
                Timestamp = DateTime.UnixEpoch
            };
            List <HostMxRecord> validRecords = new List <HostMxRecord> {
                new HostMxRecord(hostName2, 0, new List <string>())
            };
            await _mxEntity.Handle(message);

            Assert.AreEqual(stateFromDb.MxState, MxState.Evaluated);
            Assert.AreEqual(stateFromDb.HostMxRecords[0], message.Records[1]); // Make sure erroneous host is ommitted
            Assert.AreEqual(stateFromDb.LastUpdated, message.Timestamp);

            A.CallTo(() => _changeNotifiersComposite.Handle(stateFromDb, message)).MustHaveHappenedOnceExactly();
            A.CallTo(() => _dao.Save(stateFromDb)).MustHaveHappenedOnceExactly();
            A.CallTo(() => _dispatcher.Dispatch(A <MxHostTestPending> .That.Matches(a => a.Id == hostName1.ToLower()), snsTopicArn)).MustNotHaveHappened();
            A.CallTo(() => _dispatcher.Dispatch(A <MxHostTestPending> .That.Matches(a => a.Id == hostName2.ToLower()), snsTopicArn)).MustHaveHappenedOnceExactly();
        }
        public async Task Handle(MxPollPending message)
        {
            try
            {
                MxPollResult dmarcPollResult = await _processor.Process(message.Id);

                _log.LogInformation("Polled MX records for {Domain}", message.Id);

                MxRecordsPolled mxRecordsPolled = dmarcPollResult.ToMxRecordsPolled();

                _dispatcher.Dispatch(mxRecordsPolled, _config.SnsTopicArn);

                _log.LogInformation("Published MX records for {Domain}", message.Id);
            }
            catch (System.Exception ex)
            {
                _log.LogError(ex, $"Error occurred polling domain {message.Id}");
                throw;
            }
        }
        public void NotifiesWhenRecordAddedAndRemoved()
        {
            string testDomain    = "domain";
            string testHostName1 = "hostname1";
            string testHostName2 = "hostname2";


            MxEntityState state   = new MxEntityState(testDomain);
            HostMxRecord  record1 = new HostMxRecord(testHostName1, 5, new List <string> {
                "192.168.0.1"
            });
            HostMxRecord record2 = new HostMxRecord(testHostName2, 5, new List <string> {
                "192.168.0.1"
            });

            state.HostMxRecords = new List <HostMxRecord> {
                record1
            };
            List <HostMxRecord> hostMxRecords = new List <HostMxRecord> {
                record2
            };
            MxRecordsPolled mxRecordsPolled = new MxRecordsPolled(testDomain, hostMxRecords, TimeSpan.MinValue);

            _recordChangedNotifier.Handle(state, mxRecordsPolled);

            A.CallTo(() => _dispatcher.Dispatch(A <MxRecordRemoved> ._, A <string> ._))
            .MustHaveHappenedOnceExactly();
            A.CallTo(() =>
                     _dispatcher.Dispatch(
                         A <MxRecordRemoved> .That.Matches(x => x.Id == testDomain && x.Records[0].Id == testHostName1),
                         A <string> ._)).MustHaveHappenedOnceExactly();

            A.CallTo(() => _dispatcher.Dispatch(A <MxRecordAdded> ._, A <string> ._))
            .MustHaveHappenedOnceExactly();
            A.CallTo(() =>
                     _dispatcher.Dispatch(
                         A <MxRecordAdded> .That.Matches(x => x.Id == testDomain && x.Records[0].Id == testHostName2),
                         A <string> ._)).MustHaveHappenedOnceExactly();
        }
        public void NotifiesWhenMxPreferenceChanges()
        {
            string testDomain   = "domain";
            string testHostName = "hostname";

            MxEntityState state = new MxEntityState(testDomain);

            state.HostMxRecords = new List <HostMxRecord>
            {
                new HostMxRecord(testHostName, 5, new List <string> {
                    "192.168.0.1"
                })
            };

            List <HostMxRecord> hostMxRecords = new List <HostMxRecord>
            {
                new HostMxRecord(testHostName, 10, new List <string> {
                    "192.168.0.1"
                }),
            };

            MxRecordsPolled mxRecordsPolled = new MxRecordsPolled(testDomain, hostMxRecords, TimeSpan.MinValue);

            _recordChangedNotifier.Handle(state, mxRecordsPolled);

            A.CallTo(() => _dispatcher.Dispatch(A <MxRecordAdded> ._, A <string> ._))
            .MustHaveHappenedOnceExactly();
            A.CallTo(() =>
                     _dispatcher.Dispatch(A <MxRecordAdded> .That.Matches(x => x.Id == testDomain), A <string> ._))
            .MustHaveHappenedOnceExactly();

            A.CallTo(() => _dispatcher.Dispatch(A <MxRecordRemoved> ._, A <string> ._))
            .MustHaveHappenedOnceExactly();
            A.CallTo(() =>
                     _dispatcher.Dispatch(A <MxRecordRemoved> .That.Matches(x => x.Id == testDomain), A <string> ._))
            .MustHaveHappenedOnceExactly();
        }