コード例 #1
0
        /// <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);
                }
            }
        }
コード例 #2
0
        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(),
            };
        }
コード例 #3
0
        /// <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);
            }
        }
コード例 #4
0
        /// <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;
        }
コード例 #5
0
        /// <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,
                });
            }
        }
コード例 #6
0
        /// <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;
        }
コード例 #7
0
        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(),
            };
        }