diff --git a/CHANGELOG.md b/CHANGELOG.md index 74664a4..d72f338 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Added optional parameter to inject your own `HttpClient` + ### Changed - Migrated main repository from Gitlab to Gitea diff --git a/src/LinkMobility/ClientOptions.cs b/src/LinkMobility/ClientOptions.cs index 749d64d..e346372 100644 --- a/src/LinkMobility/ClientOptions.cs +++ b/src/LinkMobility/ClientOptions.cs @@ -40,6 +40,6 @@ namespace AMWD.Net.Api.LinkMobility /// /// Gets or sets the proxy information. /// - public virtual IWebProxy Proxy { get; set; } + public virtual IWebProxy? Proxy { get; set; } } } diff --git a/src/LinkMobility/LinkMobilityClient.Sms.cs b/src/LinkMobility/LinkMobilityClient.Sms.cs index d1986c3..dc9c51b 100644 --- a/src/LinkMobility/LinkMobilityClient.Sms.cs +++ b/src/LinkMobility/LinkMobilityClient.Sms.cs @@ -56,6 +56,7 @@ namespace AMWD.Net.Api.LinkMobility return PostAsync("/smsmessaging/binary", request, cancellationToken: cancellationToken); } + // https://en.wikipedia.org/wiki/MSISDN private static bool IsValidMSISDN(string msisdn) { if (string.IsNullOrWhiteSpace(msisdn)) diff --git a/src/LinkMobility/LinkMobilityClient.cs b/src/LinkMobility/LinkMobilityClient.cs index fea1793..25e7662 100644 --- a/src/LinkMobility/LinkMobilityClient.cs +++ b/src/LinkMobility/LinkMobilityClient.cs @@ -26,8 +26,9 @@ namespace AMWD.Net.Api.LinkMobility /// The username used for basic authentication. /// The password used for basic authentication. /// Optional configuration settings for the client. - public LinkMobilityClient(string username, string password, ClientOptions? clientOptions = null) - : this(new BasicAuthentication(username, password), clientOptions) + /// Optional instance if you want a custom implemented. + public LinkMobilityClient(string username, string password, ClientOptions? clientOptions = null, HttpClient? httpClient = null) + : this(new BasicAuthentication(username, password), clientOptions, httpClient) { } @@ -36,8 +37,9 @@ namespace AMWD.Net.Api.LinkMobility /// /// The bearer token used for authentication. /// Optional configuration settings for the client. - public LinkMobilityClient(string token, ClientOptions? clientOptions = null) - : this(new AccessTokenAuthentication(token), clientOptions) + /// Optional instance if you want a custom implemented. + public LinkMobilityClient(string token, ClientOptions? clientOptions = null, HttpClient? httpClient = null) + : this(new AccessTokenAuthentication(token), clientOptions, httpClient) { } @@ -47,7 +49,8 @@ namespace AMWD.Net.Api.LinkMobility /// /// The authentication mechanism used to authorize requests. /// Optional client configuration settings. - public LinkMobilityClient(IAuthentication authentication, ClientOptions? clientOptions = null) + /// Optional instance if you want a custom implemented. + public LinkMobilityClient(IAuthentication authentication, ClientOptions? clientOptions = null, HttpClient? httpClient = null) { if (authentication == null) throw new ArgumentNullException(nameof(authentication)); @@ -55,7 +58,9 @@ namespace AMWD.Net.Api.LinkMobility _clientOptions = clientOptions ?? new ClientOptions(); ValidateClientOptions(); - _httpClient = CreateHttpClient(); + _httpClient = httpClient ?? CreateHttpClient(); + ConfigureHttpClient(_httpClient); + authentication.AddHeader(_httpClient); } @@ -118,24 +123,29 @@ namespace AMWD.Net.Api.LinkMobility }; } + var httpClient = new HttpClient(handler, disposeHandler: true); + + httpClient.DefaultRequestHeaders.UserAgent.Clear(); + httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(nameof(LinkMobilityClient), version)); + + return httpClient; + } + + private void ConfigureHttpClient(HttpClient httpClient) + { string baseUrl = _clientOptions.BaseUrl.Trim().TrimEnd('/'); - var client = new HttpClient(handler, disposeHandler: true) - { - BaseAddress = new Uri($"{baseUrl}/"), - Timeout = _clientOptions.Timeout - }; + httpClient.BaseAddress = new Uri($"{baseUrl}/"); + httpClient.Timeout = _clientOptions.Timeout; - client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(nameof(LinkMobilityClient), version)); - client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + httpClient.DefaultRequestHeaders.Accept.Clear(); + httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); if (_clientOptions.DefaultHeaders.Count > 0) { foreach (var headerKvp in _clientOptions.DefaultHeaders) - client.DefaultRequestHeaders.Add(headerKvp.Key, headerKvp.Value); + httpClient.DefaultRequestHeaders.Add(headerKvp.Key, headerKvp.Value); } - - return client; } private async Task PostAsync(string requestPath, TRequest? request, IQueryParameter? queryParams = null, CancellationToken cancellationToken = default) @@ -146,8 +156,16 @@ namespace AMWD.Net.Api.LinkMobility string requestUrl = BuildRequestUrl(requestPath, queryParams); var httpContent = ConvertRequest(request); - var response = await _httpClient.PostAsync(requestUrl, httpContent, cancellationToken).ConfigureAwait(false); - return await GetResponse(response, cancellationToken).ConfigureAwait(false); + var httpRequest = new HttpRequestMessage + { + Method = HttpMethod.Post, + RequestUri = new Uri(requestUrl, UriKind.Relative), + Content = httpContent, + }; + + var httpResponse = await _httpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false); + var response = await GetResponse(httpResponse, cancellationToken).ConfigureAwait(false); + return response; } private string BuildRequestUrl(string requestPath, IQueryParameter? queryParams = null) diff --git a/src/LinkMobility/LinkMobilityResponse.cs b/src/LinkMobility/LinkMobilityResponse.cs index cd9f526..876a787 100644 --- a/src/LinkMobility/LinkMobilityResponse.cs +++ b/src/LinkMobility/LinkMobilityResponse.cs @@ -1,20 +1,38 @@ namespace AMWD.Net.Api.LinkMobility { + /// + /// A generic response of the LinkMobility API. + /// public class LinkMobilityResponse { + /// + /// Contains the message id defined in the request. + /// [JsonProperty("clientMessageId")] - public string ClientMessageId { get; set; } + public string? ClientMessageId { get; set; } + /// + /// The actual number of generated SMS. + /// [JsonProperty("smsCount")] - public int SmsCount { get; set; } + public int? SmsCount { get; set; } + /// + /// Status code + /// [JsonProperty("statusCode")] - public StatusCodes StatusCode { get; set; } + public StatusCodes? StatusCode { get; set; } + /// + /// Description of the response status code. + /// [JsonProperty("statusMessage")] - public string StatusMessage { get; set; } + public string? StatusMessage { get; set; } + /// + /// Unique identifier that is set after successful processing of the request. + /// [JsonProperty("transferId")] - public string TransferId { get; set; } + public string? TransferId { get; set; } } } diff --git a/src/LinkMobility/QueryParameters/IQueryParameter.cs b/src/LinkMobility/QueryParameters/IQueryParameter.cs index 444948d..d687432 100644 --- a/src/LinkMobility/QueryParameters/IQueryParameter.cs +++ b/src/LinkMobility/QueryParameters/IQueryParameter.cs @@ -7,6 +7,7 @@ { /// /// Retrieves the query parameters. + /// IReadOnlyDictionary GetQueryParameters(); } }