/// <summary> /// Sends a request to the UPS Track API to get detailed tracking information on a specific package. /// </summary> /// <param name="upsRequest">The required object to receive a response from UPS. Must include tracking number and API keys (username, pw and access number).</param> /// <returns>UPS Track API response.</returns> public static UPSResponse GetUPSTrackingData(UPSRequest upsRequest) { var retryPolicy = Policy.Handle <Exception>() .WaitAndRetry(4, _ => TimeSpan.FromSeconds(30), (ex, ts, count, context) => { string errorMessage = "Error in GetUPSTrackingData"; Log.Warning(ex, $"{errorMessage} . Retrying..."); if (count == 4) { Log.Error(ex, errorMessage); } }); return(retryPolicy.Execute(() => { var client = new RestClient(upsTrackingApiUrl); var jsonRequest = JsonConvert.SerializeObject(upsRequest); var req = new RestRequest(Method.POST); req.AddHeader("Content-Type", "application/json"); req.AddParameter("application/json; charset=utf-8", jsonRequest, ParameterType.RequestBody); var jsonResponse = client.Execute(req).Content; var upsResponse = JsonConvert.DeserializeObject <UPSResponse>(jsonResponse); return upsResponse; })); }
/// <summary> /// Calls the UPS Track API for each tracking number provided to get the updated status and location of the package. /// Inserts a new line to the StatusUpdates table with the latest tracking information and timestamp. /// </summary> /// <param name="trackingNumbersInTransit">Tracking numbers which require a status and location update.</param> public void UpdateCurrentStatusOfTrackingNumbers(IEnumerable <UPSTracking> trackingNumbersInTransit) { foreach (var trackingRecord in trackingNumbersInTransit) { try { var currTrackingNumber = trackingRecord.TrackingNumber; _logger.LogInformation($"Tracking Number: {currTrackingNumber}"); // Call UPS Track API var upsRequest = new UPSRequest(currTrackingNumber); var upsResponse = TrackAPI.GetUPSTrackingData(upsRequest); if (upsResponse.Fault != null) { var errMessage = upsResponse.Fault.detail?.Errors.ErrorDetail.PrimaryErrorCode.Description; _logger.LogWarning($"{errMessage} {trackingRecord}"); if (errMessage.Contains("host you are trying to connect to")) { continue; } trackingRecord.Status = "Exception"; trackingRecord.ExceptionReason = errMessage; trackingRecord.TimeStamp = DateTime.Now.ToString(); } else { // Get latest status, location and timestamp var latestActivity = TrackAPI.GetLatestActivity(upsResponse); trackingRecord.Status = latestActivity.Status; trackingRecord.Location = latestActivity.Location; trackingRecord.TimeStamp = latestActivity.TimeStamp; trackingRecord.ExceptionReason = latestActivity.ExceptionReason; _logger.LogInformation("Tracking Record: {@TrackingRecord}", trackingRecord); } // Insert to UPS.tracking.StatusUpdates InsertLineToUPSTable(trackingRecord, "StatusUpdates"); } catch (SqlException sqlEx) { _logger.LogInformation(sqlEx, "Duplicate line was not added to StatusUpdates table."); } catch (Exception ex) { _logger.LogError(ex, "Error in UpdateCurrentStatusOfTrackingNumbers. Tracking Record: {@trackingRecord}", trackingRecord); var title = "Error in UpdateCurrentStatusOfTrackingNumbers"; var text = $"Error message: {ex.Message}"; var color = "yellow"; var teamsMessage = new TeamsMessage(title, text, color, trackingErrorLogsUrl); teamsMessage.LogToTeams(teamsMessage); } } }
public void Test_GetUPSTrackingData() { var trackingNumber = "1ZV637F80311397302"; var upsRequest = new UPSRequest(trackingNumber); var upsResponse = TrackAPI.GetUPSTrackingData(upsRequest); Assert.Equal("Success", upsResponse.TrackResponse.Response.ResponseStatus.Description); }
/// <summary> /// For each tracking number provided, adds a new line to the Tracking Numbers table (with address and ref number) and to the /// Status Updates table (with current status and location of the package). /// </summary> /// <param name="trackingDataRecords">Tracking data objects that includes a tracking number. Used in the UPS Track API request.</param> public void AddTrackingNumbersToDB(IEnumerable <UPSTracking> trackingDataRecords) { foreach (var trackingRecord in trackingDataRecords) { try { var trackingNumber = trackingRecord.TrackingNumber; _logger.LogInformation($"Tracking Number: {trackingNumber}"); // Call the Track API var upsRequest = new UPSRequest(trackingNumber); var upsResponse = TrackAPI.GetUPSTrackingData(upsRequest); if (upsResponse.Fault != null) { HandleTrackAPIFault(upsResponse, trackingNumber); continue; } SetOriginAddress(trackingRecord, upsResponse); SetDestinationAddress(trackingRecord, upsResponse); trackingRecord.ReferenceNumber = TrackAPI.GetReferenceNum(upsResponse); // Insert line to UPSIntegration.tracking.TrackingNumbers InsertLineToUPSTable(trackingRecord, "TrackingNumbers"); // Get latest status, location and timestamp SetLatestActivity(trackingRecord, upsResponse); // Insert to UPSIntegration.tracking.StatusUpdates InsertLineToUPSTable(trackingRecord, "StatusUpdates"); } catch (SqlException sqlEx) { _logger.LogWarning(sqlEx, "Duplicate line was not added to TrackingNumbers table."); } catch (Exception ex) { var title = "Error in AddTrackingNumbersToDB"; var text = $"Error message: {ex.Message}"; var color = "red"; var teamsMessage = new TeamsMessage(title, text, color, trackingErrorLogsUrl); teamsMessage.LogToTeams(teamsMessage); _logger.LogError(ex, title); } } }
/// <summary> /// Asynchronously requests verification from the UPS api of the address passed to it /// </summary> /// <param name="request">Object specifying details of the request to the UPS api</param> /// <returns></returns> public async Task <UPSResponse> Request(AddressKeyFormat address) { var request = new UPSRequest() { XAVRequest = new XAVRequest(RequestOption) { AddressKeyFormat = address } }; var requestJson = JsonConvert.SerializeObject(request); var content = new StringContent(requestJson, Encoding.UTF8, "application/json"); var reply = await _httpClient.PostAsync(Url, content); var responseContent = await reply.Content.ReadAsStringAsync(); UPSResponse response = JsonConvert.DeserializeObject <UPSResponse>(responseContent); return(response); }