123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638 |
- using Dfs.WayneChina.SpsDataCourier.Models;
- using Newtonsoft.Json;
- using Polly;
- using System;
- using System.Collections.Generic;
- using System.Net.Http;
- using System.Net.Http.Headers;
- using System.Text;
- using System.Threading.Tasks;
- namespace Dfs.WayneChina.SpsDataCourier
- {
- public class DataCourier
- {
- #region Fields
- private HttpClient _client = new HttpClient();
- private ConnectionInfo connectionInfo;
- private string grantType = "password";
- private string tokenAuthPath = "token";
- private string authScheme = "bearer";
- private int retryCount;
- private AuthToken currentAuthToken;
- #endregion
- #region Logger
- NLog.Logger logger = NLog.LogManager.LoadConfiguration("NLog.config").GetLogger("SpsDataCourier");
- #endregion
- #region Constructor
- public DataCourier(string username, string password, string authServiceBaseUrl, string accountServiceBaseUrl,
- string accountServiceRelativeUrl, string deviceSN, int retryCount)
- {
- connectionInfo = new ConnectionInfo
- {
- UserName = username,
- Password = password,
- AuthServiceBaseUrl = authServiceBaseUrl,
- AccountServiceBaseUrl = accountServiceBaseUrl,
- AccountServiceRelativeUrl = accountServiceRelativeUrl,
- DeviceSN = deviceSN
- };
- this.retryCount = retryCount;
- _client.DefaultRequestHeaders.Clear();
- }
- #endregion
- #region Get token
- public void GetToken()
- {
- currentAuthToken = GetTokenAsync(connectionInfo.UserName, connectionInfo.Password, connectionInfo.AuthServiceBaseUrl).Result;
- }
- private async Task<AuthToken> GetTokenAsync(string userName, string password, string baseUrl)
- {
- logger.Info("Start to get token...");
- _client.DefaultRequestHeaders.Clear();
- string tokenUrl = string.Concat(baseUrl, tokenAuthPath);
- var formParam = new AuthenticationParameter(grantType, userName, password);
- try
- {
- var response = await _client.PostAsync(tokenUrl, new FormUrlEncodedContent(formParam.Params)).ConfigureAwait(false);
- logger.Info($"Get token, StatusCode = {(int)response.StatusCode}");
- if (response.IsSuccessStatusCode)
- {
- await response.Content.ReadAsStringAsync().ContinueWith(x =>
- {
- currentAuthToken = JsonConvert.DeserializeObject<AuthToken>(x?.Result);
- currentAuthToken.TokenRetrievedTime = DateTime.Now;
- });
- }
- else
- {
- var content = await response.Content.ReadAsStringAsync();
- response.Content?.Dispose();
- }
- return currentAuthToken;
- }
- catch (Exception ex)
- {
- logger.Error(ex.ToString());
- return null;
- }
- }
- #endregion
- #region Send request
- public async Task<SendResult> SendRequest(OfflineRequest offlineRequest, HostOperationType operationType)
- {
- if (currentAuthToken != null && currentAuthToken.IsTokenValid())
- {
- if (!_client.DefaultRequestHeaders.Contains("DeviceSN"))
- _client.DefaultRequestHeaders.Add("DeviceSN", connectionInfo.DeviceSN);
- _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authScheme, currentAuthToken.AccessToken);
- Response resp = null;
- //
- // Create account
- //
- if (operationType == HostOperationType.CreateAccount)
- {
- var request = JsonConvert.SerializeObject(offlineRequest);
- logger.Info(request);
- try
- {
- var response = await _client.PostAsJsonAsync($"{connectionInfo.AccountServiceBaseUrl}{connectionInfo.AccountServiceRelativeUrl}", offlineRequest)
- .ConfigureAwait(false);
- logger.Info($"Upload account, StatusCode: {(int)response.StatusCode}");
- if (response.IsSuccessStatusCode)
- {
- await response.Content.ReadAsStringAsync().ContinueWith(x =>
- {
- resp = JsonConvert.DeserializeObject<Response>(x?.Result);
- });
- if (resp != null)
- {
- logger.Info($" StatusCode: {resp.StatusCode}, Result: {resp.Result}, Message: {resp.Message}");
- if (resp.Result == 0 || resp.Result == 2)
- {
- return OkResult(resp.Result);
- }
- }
- return FailedResult(resp.Result);
- }
- else
- {
- var content = await response.Content.ReadAsStringAsync();
- response.Content?.Dispose();
- return ErrorResult();
- }
- }
- catch (Exception ex)
- {
- logger.Error(ex);
- return ErrorResult();
- }
- }
- //
- // Update account
- //
- else if (operationType == HostOperationType.UpdateAccount)
- {
- var request = JsonConvert.SerializeObject(offlineRequest);
- logger.Info(request);
- try
- {
- var response = await _client.PutAsJsonAsync($"{connectionInfo.AccountServiceBaseUrl}{connectionInfo.AccountServiceRelativeUrl}/update", offlineRequest)
- .ConfigureAwait(false);
- logger.Info($"Update account, StatusCode: {(int)response.StatusCode}");
- if (response.IsSuccessStatusCode)
- {
- await response.Content.ReadAsStringAsync().ContinueWith(x =>
- {
- resp = JsonConvert.DeserializeObject<Response>(x?.Result);
- });
- if (resp != null)
- {
- logger.Info($" StatusCode: {resp.StatusCode}, Result: {resp.Result}, Message: {resp.Message}");
- if (resp.Result == 0 || resp.Result == 2)
- {
- return OkResult(resp.Result);
- }
- }
- return FailedResult(resp.Result);
- }
- else
- {
- var content = await response.Content.ReadAsStringAsync();
- response.Content?.Dispose();
- return ErrorResult();
- }
- }
- catch (Exception ex)
- {
- logger.Error(ex);
- return ErrorResult();
- }
- }
- //
- // Create card
- //
- else if (operationType == HostOperationType.CreateCard)
- {
- var request = JsonConvert.SerializeObject(offlineRequest);
- logger.Info(request);
- try
- {
- var response = await _client.PostAsJsonAsync($"{connectionInfo.AccountServiceBaseUrl}{connectionInfo.AccountServiceRelativeUrl}/cardInfo", offlineRequest)
- .ConfigureAwait(false);
- logger.Info($"Upload card, StatusCode: {(int)response.StatusCode}");
- if (response.IsSuccessStatusCode)
- {
- await response.Content.ReadAsStringAsync().ContinueWith(x =>
- {
- resp = JsonConvert.DeserializeObject<Response>(x?.Result);
- });
- if (resp != null)
- {
- logger.Info($" StatusCode: {resp.StatusCode}, Result: {resp.Result}, Message: {resp.Message}");
- if (resp.Result == 0 || resp.Result == 2)
- {
- return OkResult(resp.Result);
- }
- }
- return FailedResult(resp.Result);
- }
- else
- {
- var content = await response.Content.ReadAsStringAsync();
- response.Content?.Dispose();
- return ErrorResult();
- }
- }
- catch (Exception ex)
- {
- logger.Error(ex);
- return ErrorResult();
- }
- }
- //
- // Update card
- //
- else if (operationType == HostOperationType.UpdateCard)
- {
- var request = JsonConvert.SerializeObject(offlineRequest);
- logger.Info(request);
- try
- {
- var response = await _client.PutAsJsonAsync($"{connectionInfo.AccountServiceBaseUrl}{connectionInfo.AccountServiceRelativeUrl}/update", offlineRequest)
- .ConfigureAwait(false);
- logger.Info($"Update card, StatusCode: {(int)response.StatusCode}");
- if (response.IsSuccessStatusCode)
- {
- await response.Content.ReadAsStringAsync().ContinueWith(x =>
- {
- resp = JsonConvert.DeserializeObject<Response>(x?.Result);
- });
- if (resp != null)
- {
- logger.Info($" StatusCode: {resp.StatusCode}, Result: {resp.Result}, Message: {resp.Message}");
- if (resp.Result == 0 || resp.Result == 2)
- {
- return OkResult(resp.Result);
- }
- }
- return FailedResult(resp.Result);
- }
- else
- {
- var content = await response.Content.ReadAsStringAsync();
- response.Content?.Dispose();
- return ErrorResult();
- }
- }
- catch (Exception ex)
- {
- logger.Error(ex);
- return ErrorResult();
- }
- }
- else if (operationType == HostOperationType.DisableAccount)
- {
- }
- //
- // Create payment record
- //
- else if (operationType == HostOperationType.CreatePayRecord)
- {
- var requestString = JsonConvert.SerializeObject(offlineRequest);
- logger.Info("Card Pay record: " + requestString);
- try
- {
- var maxRetryAttempts = retryCount;
- var pauseBetweenFailures = TimeSpan.FromSeconds(3);
- var retryPolicy = Policy
- .Handle<HttpRequestException>()
- .WaitAndRetryAsync(maxRetryAttempts, i => pauseBetweenFailures, (exception, timeSpan, retryCount, context) =>
- {
- logger.Info("Wait and retry");
- });
- var uploadResult = await retryPolicy.ExecuteAsync(async () =>
- {
- logger.Info("Executing Polly policy...");
- if (!_client.DefaultRequestHeaders.Contains("DeviceSN"))
- {
- logger.Info("Check again the DeviceSN before sending");
- _client.DefaultRequestHeaders.Add("DeviceSN", connectionInfo.DeviceSN);
- }
- var response = await _client.PostAsJsonAsync($"{connectionInfo.AccountServiceBaseUrl}{connectionInfo.AccountServiceRelativeUrl}/payment", offlineRequest)
- .ConfigureAwait(false);
- logger.Info($"Upload pay record, StatusCode: {(int)response?.StatusCode}");
- if (response.IsSuccessStatusCode)
- {
- await response.Content.ReadAsStringAsync().ContinueWith(x =>
- {
- resp = JsonConvert.DeserializeObject<Response>(x?.Result);
- });
- if (resp != null)
- {
- logger.Info($" StatusCode: {resp.StatusCode}, Result: {resp.Result}, Message: {resp.Message}");
- if (resp.Result == 0 || resp.Result == 2) // 2=Don't retry
- {
- return OkResult(resp.Result);
- }
- }
- return FailedResult(resp.Result);
- }
- else
- {
- var content = await response.Content.ReadAsStringAsync();
- response.Content?.Dispose();
- return ErrorResult();
- }
- });
- return uploadResult;
- }
- catch (Exception ex)
- {
- logger.Error($"Upload Pay record exception: {ex}");
- return ErrorResult();
- }
- }
- //
- // Recharge and reduction record
- //
- else if (operationType == HostOperationType.CreateRechargeRecord)
- {
- var request = JsonConvert.SerializeObject(offlineRequest);
- logger.Info(request);
- try
- {
- var response = await _client.PostAsJsonAsync($"{connectionInfo.AccountServiceBaseUrl}{connectionInfo.AccountServiceRelativeUrl}/recharge", offlineRequest)
- .ConfigureAwait(false);
- logger.Info($"Upload recharge/reduction record, StatusCode: {(int)response.StatusCode}");
- if (response.IsSuccessStatusCode)
- {
- await response.Content.ReadAsStringAsync().ContinueWith(x =>
- {
- resp = JsonConvert.DeserializeObject<Response>(x?.Result);
- });
- if (resp != null)
- {
- logger.Info($" StatusCode: {resp.StatusCode}, Result: {resp.Result}, Message: {resp.Message}");
- if (resp.Result == 0 || resp.Result == 2)
- {
- return OkResult(resp.Result);
- }
- }
- return FailedResult(resp.Result);
- }
- else
- {
- var content = await response.Content.ReadAsStringAsync();
- response.Content?.Dispose();
- return ErrorResult();
- }
- }
- catch (Exception ex)
- {
- logger.Error(ex);
- return ErrorResult();
- }
- }
- //Card operations, report for loss, release card, close card...
- else if (operationType == HostOperationType.CardOperation)
- {
- var request = JsonConvert.SerializeObject(offlineRequest);
- logger.Info(request);
- try
- {
- var response = await _client.PutAsJsonAsync($"{connectionInfo.AccountServiceBaseUrl}{connectionInfo.AccountServiceRelativeUrl}/update", offlineRequest)
- .ConfigureAwait(false);
- logger.Info($"Card Operation, StatusCode: {(int)response.StatusCode}");
- if (response.IsSuccessStatusCode)
- {
- await response.Content.ReadAsStringAsync().ContinueWith(x =>
- {
- resp = JsonConvert.DeserializeObject<Response>(x?.Result);
- });
- if (resp != null)
- {
- logger.Info($" StatusCode: {resp.StatusCode}, Result: {resp.Result}, Message: {resp.Message}");
- if (resp.Result == 0 || resp.Result == 2)
- {
- return OkResult(resp.Result);
- }
- }
- return FailedResult(resp.Result);
- }
- else
- {
- var content = await response.Content.ReadAsStringAsync();
- response.Content?.Dispose();
- return ErrorResult();
- }
- }
- catch (Exception ex)
- {
- logger.Error(ex);
- return ErrorResult();
- }
- }
- else if (operationType == HostOperationType.ListedCard)
- {
- var request = JsonConvert.SerializeObject(offlineRequest);
- logger.Info(request);
- try
- {
- var response = await _client.PostAsJsonAsync($"{connectionInfo.AccountServiceBaseUrl}{connectionInfo.AccountServiceRelativeUrl}/blackCard", offlineRequest)
- .ConfigureAwait(false);
- logger.Info($"Black Card, StatusCode: {(int)response.StatusCode}");
- if (response.IsSuccessStatusCode)
- {
- await response.Content.ReadAsStringAsync().ContinueWith(x =>
- {
- resp = JsonConvert.DeserializeObject<Response>(x?.Result);
- });
- if (resp != null)
- {
- logger.Info($" StatusCode: {resp.StatusCode}, Result: {resp.Result}, Message: {resp.Message}");
- if (resp.Result == 0 || resp.Result == 2)
- {
- return OkResult(resp.Result);
- }
- }
- return FailedResult(resp.Result);
- }
- else
- {
- var content = await response.Content.ReadAsStringAsync();
- response.Content?.Dispose();
- return ErrorResult();
- }
- }
- catch (Exception ex)
- {
- logger.Error(ex);
- return ErrorResult();
- }
- }
- else if (operationType == HostOperationType.GrayInfo)
- {
- var request = JsonConvert.SerializeObject(offlineRequest);
- logger.Info(request);
- try
- {
- var response = await _client.PostAsJsonAsync($"{connectionInfo.AccountServiceBaseUrl}{connectionInfo.AccountServiceRelativeUrl}/grayInfo", offlineRequest)
- .ConfigureAwait(false);
- logger.Info($"GrayInfo, StatusCode: {(int)response.StatusCode}");
- if (response.IsSuccessStatusCode)
- {
- await response.Content.ReadAsStringAsync().ContinueWith(x =>
- {
- resp = JsonConvert.DeserializeObject<Response>(x?.Result);
- });
- if (resp != null)
- {
- logger.Info($" StatusCode: {resp.StatusCode}, Result: {resp.Result}, Message: {resp.Message}");
- if (resp.Result == 0 || resp.Result == 2)
- {
- return OkResult(resp.Result);
- }
- }
- return FailedResult(resp.Result);
- }
- else
- {
- var content = await response.Content.ReadAsStringAsync();
- response.Content?.Dispose();
- return ErrorResult();
- }
- }
- catch (Exception ex)
- {
- logger.Error(ex);
- return ErrorResult();
- }
- }
- else if (operationType == HostOperationType.CardRepLoss)
- {
- var request = JsonConvert.SerializeObject(offlineRequest);
- logger.Info(request);
- try
- {
- var response = await _client.PostAsJsonAsync($"{connectionInfo.AccountServiceBaseUrl}{connectionInfo.AccountServiceRelativeUrl}/cardRepLoss", offlineRequest)
- .ConfigureAwait(false);
- logger.Info($"CardRepLoss, StatusCode: {(int)response.StatusCode}");
- if (response.IsSuccessStatusCode)
- {
- await response.Content.ReadAsStringAsync().ContinueWith(x =>
- {
- resp = JsonConvert.DeserializeObject<Response>(x?.Result);
- });
- if (resp != null)
- {
- logger.Info($" StatusCode: {resp.StatusCode}, Result: {resp.Result}, Message: {resp.Message}");
- if (resp.Result == 0 || resp.Result == 2)
- {
- return OkResult(resp.Result);
- }
- }
- return FailedResult(resp.Result);
- }
- else
- {
- var content = await response.Content.ReadAsStringAsync();
- response.Content?.Dispose();
- return ErrorResult();
- }
- }
- catch (Exception ex)
- {
- logger.Error(ex);
- return ErrorResult();
- }
- }
- }
- else
- {
- currentAuthToken = await GetTokenAsync(connectionInfo.UserName, connectionInfo.Password, connectionInfo.AuthServiceBaseUrl);
- if (currentAuthToken != null && currentAuthToken.IsTokenValid())
- {
- return await SendRequest(offlineRequest, operationType);
- }
- }
- logger.Info("Reached here? Impossible");
- return ErrorResult();
- }
- #endregion
- private SendResult OkResult(int code)
- {
- return new SendResult { Success = true, Code = code };
- }
- private SendResult FailedResult(int code)
- {
- return new SendResult { Success = false, Code = code };
- }
- private SendResult ErrorResult()
- {
- return new SendResult { Success = false, Code = -1 };
- }
- }
- }
|