/// <summary> /// Add additional context to the trail. /// </summary> /// <param name="trail">The trail to extend.</param> /// <param name="context">Datastore context.</param> /// <returns>Task for asynchronous completion.</returns> /// <seealso cref="ITrailExtender.Extend"/> public async Task Extend(Trail trail, MyTrailsContext context) { if (trail.Location != null) { this.Logger.InfoFormat("Looking up driving directions for trail: {0}", trail.Name); List<Address> addresses = context.Addresses .Where(a => a.Directions.All(d => d.TrailId != trail.Id)) .ToList(); // Force EF query to avoid multiple active results sets on enumeration. foreach (Address address in addresses) { await this.AddDrivingDirections(address, trail); } } }
public void TestInitialize() { using (MyTrailsContext context = new MyTrailsContext()) { context.ClearDatabase(); context.SaveChanges(); TripType tripType = context.TripTypes.First(); this._anyTripTypeId = tripType.Id; this._anyTripTypeWtaId = tripType.WtaId; } this._anyTrail = new Trail { Name = "Any Trail Name", WtaId = "any-wta-id", Url = new Uri("http://any/trail/uri"), }; this._wtaClientMock = new Mock<IWtaClient>(MockBehavior.Strict); this._wtaClientMock .Setup(wc => wc.FetchTripReports(It.IsAny<string>())) .Returns((string ti) => TaskExt.WrapInTask<IList<WtaTripReport>>(() => new List<WtaTripReport> { new WtaTripReport { Title = "Any title", Author = "Any author", Date = DateTime.Now, FullReportUrl = new Uri(new Uri("http://any.base.url"), AnyWtaTripReportId), HikeType = this._anyTripTypeWtaId, Photos = { new Uri("http://any/domain/photoUrl.jpg"), }, } })); this._wtaClientMock .Setup(wc => wc.BuildRetryPolicy(It.IsAny<ILog>())) .Returns(new RetryPolicy(new StubErrorDetectionStrategy(), retryCount: 0)); this._extender = new TripReportExtender { WtaClient = this._wtaClientMock.Object, Logger = new StubLog(), }; }
/// <summary> /// Add trip reports to the trail. /// </summary> /// <param name="trail">The trail to extend.</param> /// <param name="context">Registered context.</param> /// <returns>Task for asynchronous completion.</returns> /// <seealso cref="ITrailExtender.Extend"/> public async Task Extend(Trail trail, MyTrailsContext context) { this.Initialize(context); string wtaTrailId = trail.WtaId; RetryPolicy policy = this.WtaClient.BuildRetryPolicy(this.Logger); IList<WtaTripReport> reports = await policy.ExecuteAsync(() => this.WtaClient.FetchTripReports(wtaTrailId)); foreach (WtaTripReport wtaReport in reports) { string wtaReportId = this.ParseWtaReportId(wtaReport); Lazy<bool> firstToAdd = new Lazy<bool>(() => this._tripReportDictionary.TryAdd(wtaReportId, null)); TripReport report; do { report = context.TripReports .Where(tr => tr.WtaId == wtaReportId) .FirstOrDefault(); if (report == null) { if (firstToAdd.Value) { // First thread to access new trip report, create it. this.Logger.InfoFormat("Found new trip report: {0}", wtaReportId); report = this.CreateReport(wtaReportId, wtaReport); } else { this.Logger.DebugFormat("Waiting for other thread to create trip report: {0}.", wtaReportId); await Task.Delay(ConcurrentTripReportDelay); } } } while (report == null); trail.TripReports.Add(report); } }
/// <summary> /// Add trail data to the datastore and return the trail id. /// </summary> /// <param name="trail">The trail to add to the datastore.</param> /// <returns>The ID of the added trail.</returns> private int AddTestData(Trail trail) { int id; using (MyTrailsContext context = new MyTrailsContext()) { context.Trails.Add(trail); context.SaveChanges(); id = trail.Id; } return id; }
/// <summary> /// Add driving directions for the given trail / address pair. /// </summary> /// <param name="address">The starting address.</param> /// <param name="trail">The trail ending address.</param> /// <returns>Task for asynchronous completion.</returns> private async Task AddDrivingDirections(Address address, Trail trail) { RouteRequest request = new RouteRequest { Credentials = new Credentials { ApplicationId = this.Configuration.ApplicationId, }, Waypoints = new[] { new Waypoint { Description = "Start", Location = new Location { Latitude = address.Coordinate.Latitude.Value, Longitude = address.Coordinate.Longitude.Value, }, }, new Waypoint { Description = "End", Location = new Location { Latitude = trail.Location.Latitude.Value, Longitude = trail.Location.Longitude.Value, }, }, }, }; ResponseSummary summary; RouteResult result; RetryPolicy policy = this.BuildRetryPolicy(); IRouteService routeService = this.RouteServiceFactory.CreateRouteService(); try { RouteResponse response = await policy.ExecuteAsync(() => routeService.CalculateRouteAsync(request)); summary = response.ResponseSummary; result = response.Result; } catch (FaultException<ResponseSummary> ex) { summary = ex.Detail; result = null; } finally { IDisposable disposable = routeService as IDisposable; if (disposable != null) { disposable.Dispose(); } } if (summary.StatusCode != ResponseStatusCode.Success) { if (summary.StatusCode == ResponseStatusCode.BadRequest && summary.FaultReason.Contains("No route was found for the waypoints provided.")) { this.Logger.WarnFormat("No route found between trail add address: '{0}', '{1}'", trail, address); } else { throw new ApplicationException(string.Format("Routing service call failed. {0}: {1}", summary.StatusCode, summary.FaultReason)); } } else { address.Directions.Add(new DrivingDirections { Address = address, Trail = trail, DrivingTimeSeconds = (int)result.Summary.TimeInSeconds, }); } }
/// <summary> /// Register test data with the datastore context. /// </summary> /// <param name="trail">Test trail to register.</param> /// <param name="addresses">The test addresses to register.</param> /// <returns>The ID of the trail in the datastore.</returns> private int RegisterTestData(Trail trail, params Address[] addresses) { int trailId; using (MyTrailsContext context = new MyTrailsContext()) { context.Trails.Add(trail); foreach (Address address in addresses) { context.Addresses.Add(address); } context.SaveChanges(); trailId = trail.Id; } return trailId; }
public void TestInitialize() { this.ClearDatabase(); this._anyAddress = new Address { Location = "any location string", Coordinate = DbGeographyExt.PointFromCoordinates(23.45, -67.89), }; this._anyTrail = new Trail { WtaId = "any-wta-trail-id", Name = "Any Trail Name", Url = new Uri("http://any/trail/uri"), Location = DbGeographyExt.PointFromCoordinates(12.34, -56.78), }; this._routeServiceMock = new Mock<IRouteService>(MockBehavior.Strict); this._routeServiceMock .Setup(rs => rs.CalculateRouteAsync(It.IsAny<RouteRequest>())) .Returns(TaskExt.WrapInTask(() => this.CreateRouteResponse(123456))); Mock<IRouteServiceFactory> routeServiceFactoryMock = new Mock<IRouteServiceFactory>(MockBehavior.Strict); routeServiceFactoryMock .Setup(rsf => rsf.CreateRouteService()) .Returns(this._routeServiceMock.Object); this._configurationMock = new Mock<IBingMapsConfiguration>(MockBehavior.Strict); this._configurationMock .SetupGet(c => c.ApplicationId) .Returns("anyApplicationId"); this._configurationMock .SetupGet(c => c.RetryCount) .Returns(0); this._configurationMock .SetupGet(c => c.RetryMinBackOff) .Returns(TimeSpan.FromMilliseconds(1234)); this._configurationMock .SetupGet(c => c.RetryMaxBackOff) .Returns(TimeSpan.FromMilliseconds(2345)); this._configurationMock .SetupGet(c => c.RetryDeltaBackOff) .Returns(TimeSpan.FromMilliseconds(456)); this._extender = new DrivingDistanceExtender { RouteServiceFactory = routeServiceFactoryMock.Object, Configuration = this._configurationMock.Object, Logger = new StubLog(), }; }