public async Task should_not_create_service_health_data_when_found()
        {
            var now   = DateTime.UtcNow;
            var start = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 0, DateTimeKind.Utc);

            var service = new Heimdall.Mongo.Infrastructure.Entities.Service()
            {
                Id        = Guid.NewGuid(),
                Active    = true,
                Name      = "lorem",
                Endpoints = Enumerable.Empty <Heimdall.Mongo.Infrastructure.Entities.ServiceEndpoint>()
            };
            var mockRepo = RepositoryUtils.MockRepository(service);

            var mockEventsRepo = RepositoryUtils.MockRepository <Heimdall.Mongo.Infrastructure.Entities.TraceEvent>();

            var mockDbContext = new Mock <IDbContext>();

            mockDbContext.Setup(db => db.Services).Returns(mockRepo.Object);
            mockDbContext.Setup(db => db.TraceEvents).Returns(mockEventsRepo.Object);

            var serviceHealth = new Infrastructure.Entities.ServiceHealth()
            {
                ServiceId       = service.Id,
                TimestampMinute = start.Ticks
            };
            var mockServicesHealthRepo = RepositoryUtils.MockRepository <Infrastructure.Entities.ServiceHealth>();

            mockServicesHealthRepo.Setup(r => r.FindOneAndUpdateAsync(It.IsAny <Expression <Func <Infrastructure.Entities.ServiceHealth, bool> > >(),
                                                                      It.IsAny <MongoDB.Driver.UpdateDefinition <Infrastructure.Entities.ServiceHealth> >()))
            .ReturnsAsync((Expression <Func <Infrastructure.Entities.ServiceHealth, bool> > filter, MongoDB.Driver.UpdateDefinition <Infrastructure.Entities.ServiceHealth> update) =>
            {
                return(serviceHealth);
            });

            var mockAnalyticsDb = new Mock <IAnalyticsDbContext>();

            mockAnalyticsDb.Setup(db => db.ServicesHealth).Returns(mockServicesHealthRepo.Object);

            var @event = new ServiceRefreshed(service.Id);
            var sut    = new ServiceRefreshedHandler(mockDbContext.Object, mockAnalyticsDb.Object);
            await sut.Handle(@event);

            mockServicesHealthRepo.Verify(m => m.InsertOneAsync(It.Is <Infrastructure.Entities.ServiceHealth>(
                                                                    sh => null != sh &&
                                                                    sh.ServiceId == service.Id &&
                                                                    sh.TimestampMinute >= start.Ticks &&
                                                                    null != sh.Details &&
                                                                    sh.Details.Count() == 1
                                                                    )
                                                                ), Times.Never);
        }
Beispiel #2
0
        public async Task should_append_service_health_data_when_found()
        {
            var endpoint = new Heimdall.Mongo.Infrastructure.Entities.ServiceEndpoint()
            {
                Active        = true,
                CreationDate  = DateTime.UtcNow.Ticks,
                RoundtripTime = 1,
                Address       = "ipsum"
            };
            var service = new Heimdall.Mongo.Infrastructure.Entities.Service()
            {
                Active       = true,
                CreationDate = DateTime.UtcNow.Ticks,
                Endpoints    = new[] { endpoint },
                Id           = Guid.NewGuid(),
                Name         = "lorem"
            };

            await base.DbContext.Services.InsertOneAsync(service);

            var now   = DateTime.UtcNow;
            var start = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 0, DateTimeKind.Utc);

            var serviceHealth = new Infrastructure.Entities.ServiceHealth()
            {
                ServiceId       = service.Id,
                TimestampMinute = start.Ticks,
                Details         = Enumerable.Empty <Infrastructure.Entities.ServiceHealthDetails>()
            };
            await base.AnalyticsDbContext.ServicesHealth.InsertOneAsync(serviceHealth);

            var sut = new ServiceRefreshedHandler(base.DbContext, base.AnalyticsDbContext);

            var @event = new ServiceRefreshed(service.Id);
            await sut.Handle(@event);

            var foundServicesHealth = await base.AnalyticsDbContext.ServicesHealth.FindAsync(sh => sh.ServiceId == service.Id);

            foundServicesHealth.Should().NotBeNullOrEmpty();
            foundServicesHealth.Count().ShouldBeEquivalentTo(1);

            var foundServiceHealth = foundServicesHealth.ElementAt(0);

            foundServiceHealth.Should().NotBeNull();
            foundServiceHealth.Details.Should().NotBeNullOrEmpty();
            foundServiceHealth.Details.Count().ShouldBeEquivalentTo(1);
            var foundDetails = foundServiceHealth.Details.ElementAt(0);

            foundDetails.BestEndpoint.ShouldBeEquivalentTo(endpoint.Address);
            foundDetails.RoundtripTime.ShouldBeEquivalentTo(endpoint.RoundtripTime);
        }
        public async Task Handle(ServiceRefreshed @event)
        {
            if (null == @event)
            {
                throw new ArgumentNullException(nameof(@event));
            }

            var service = await _db.Services.FindOneAsync(s => s.Id == @event.ServiceId);

            if (null == service)
            {
                throw new ArgumentOutOfRangeException(nameof(@event), "invalid service id");
            }

            var now = DateTime.UtcNow;

            var healthDetails = new Infrastructure.Entities.ServiceHealthDetails()
            {
                Timestamp     = now.Ticks,
                RoundtripTime = long.MaxValue,
                BestEndpoint  = string.Empty
            };

            var bestEndpoint = service.FindBestEndpoint();

            if (null != bestEndpoint)
            {
                healthDetails.RoundtripTime = bestEndpoint.RoundtripTime;
                healthDetails.BestEndpoint  = bestEndpoint.Address;
            }

            var update = Builders <Infrastructure.Entities.ServiceHealth> .Update.Push(sh => sh.Details, healthDetails);

            var start = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 0, DateTimeKind.Utc);

            var serviceHealth = await _analyticsDb.ServicesHealth.FindOneAndUpdateAsync(sh => sh.ServiceId == service.Id && sh.TimestampMinute == start.Ticks, update);

            if (null != serviceHealth)
            {
                return;
            }

            var newServiceHealth = new Infrastructure.Entities.ServiceHealth()
            {
                ServiceId       = service.Id,
                TimestampMinute = start.Ticks,
                Details         = new [] { healthDetails }
            };
            await _analyticsDb.ServicesHealth.InsertOneAsync(newServiceHealth);
        }