/// <inheritdoc /> public async Task <OptimizeRouteResult> OptimizeRoute(OptimizeRouteCriteria criteria) { var requestIds = new List <Guid>(); if (!string.IsNullOrEmpty(_mappingSettings?.GoogleMapsApiKey)) { try { // todo sgordon: enhance with Polly for retries var response = await _httpClient.GetAsync(GenerateGoogleApiUrl(criteria)); if (response.IsSuccessStatusCode) { var content = await response.Content.ReadAsStringAsync(); var result = JsonConvert.DeserializeObject <GoogleDirectionsResponse>(content); if (result.Status == GoogleDirectionsResponse.OkStatus) { requestIds.AddRange(result.Routes.SelectMany(r => r.WaypointOrder).Select(waypointIndex => criteria.Waypoints[waypointIndex].RequestId)); return(new OptimizeRouteResult { RequestIds = requestIds, Distance = result.TotalDistance, Duration = result.TotalDuration }); } } } catch (Exception ex) { _logger.LogError($"Failure to contact Google Directions API - {ex}"); } } return(null); }
private string GenerateGoogleApiUrl(OptimizeRouteCriteria criteria) { var requestUrl = new StringBuilder("https://maps.googleapis.com/maps/api/directions/json?origin="); requestUrl.Append(criteria.StartAddress); requestUrl.Append("&destination=").Append(criteria.EndAddress); requestUrl.Append("&waypoints=optimize:true"); foreach (var waypoint in criteria.Waypoints) { requestUrl.Append("|").Append(waypoint.Coordinates); } requestUrl.Append("&key=").Append(_mappingSettings.GoogleMapsApiKey); return(requestUrl.ToString()); }
/// <inheritdoc /> public async Task <OptimizeRouteResult> OptimizeRoute(OptimizeRouteCriteria criteria) { var requestIds = new List <Guid>(); if (!string.IsNullOrEmpty(_mappingSettings?.GoogleMapsApiKey)) { try { return(await GetRetryPolicy().ExecuteAsync(async() => { var googleResponse = await _httpClient.GetAsync(GenerateGoogleApiUrl(criteria)); if (googleResponse.IsSuccessStatusCode) { var content = await googleResponse.Content.ReadAsStringAsync(); var result = JsonConvert.DeserializeObject <GoogleDirectionsResponse>(content); if (result.Status == GoogleDirectionsResponse.OkStatus) { requestIds.AddRange(result.Routes.SelectMany(r => r.WaypointOrder).Select(waypointIndex => criteria.Waypoints[waypointIndex].RequestId)); return new OptimizeRouteResult { RequestIds = requestIds, Distance = result.TotalDistance, Duration = result.TotalDuration }; } } else { // for now we fire an exception to force a Polly retry. We could review this later once we have logging to determine specific codes // that represent errors throw new Exception("Non success code"); } return null; })); } catch { // todo - handle other status codes and logging } } return(null); }
/// <inheritdoc /> public async Task <OptimizeRouteResult> OptimizeRoute(OptimizeRouteCriteria criteria) { var requestIds = new List <Guid>(); try { return(await GetRetryPolicy().ExecuteAsync(async() => { var googleResponse = await _httpClient.GetAsync(GenerateGoogleApiUrl(criteria)); googleResponse.EnsureSuccessStatusCode(); var content = await googleResponse.Content.ReadAsStringAsync(); var result = JsonConvert.DeserializeObject <GoogleDirectionsResponse>(content); if (result.Status == GoogleDirectionsResponse.OkStatus) { requestIds.AddRange(result.Routes.SelectMany(r => r.WaypointOrder).Select(waypointIndex => criteria.Waypoints[waypointIndex].RequestId)); return new OptimizeRouteResult { RequestIds = requestIds, Distance = result.TotalDistance, Duration = result.TotalDuration }; } else if (result.Status == GoogleDirectionsResponse.NoResultsStatus || result.Status == GoogleDirectionsResponse.NotFound) { return OptimizeRouteResult.FailedOptimizeRouteResult(OptimizeRouteStatusMessages.ZeroResults); } return OptimizeRouteResult.FailedOptimizeRouteResult(OptimizeRouteStatusMessages.GeneralOptimizeFailure); })); } catch (Exception ex) { _logger.LogError($"Unable to connect to Google API {ex}"); // todo - handle other status codes and logging } return(OptimizeRouteResult.FailedOptimizeRouteResult(OptimizeRouteStatusMessages.GeneralOptimizeFailure)); }