From 51633fefb8cf13efe1f68a641d01cda8ef0ae100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Alberto=20Leiva=20Obando?= Date: Fri, 12 Apr 2024 13:12:03 -0600 Subject: [PATCH 1/2] [DI-1345] Data Import 2.3 .NET 8 Update - Update Resharp Update Resharp to versio 110.2 Replace old interfaces and object with the new definition. Update tests. --- DataImport.Common/DataImport.Common.csproj | 2 +- .../Helpers/OAuthRequestWrapper.cs | 6 +- .../Helpers/OdsApiTokenRetriever.cs | 7 +- .../IRestClientOptionsWrapper.cs | 17 ++++ DataImport.Common/RestClientOptionsWrapper.cs | 32 +++++++ .../EnrollmentComposite/EnrollmentApiTests.cs | 26 +++--- DataImport.EdFi/Api/DescriptorsApi.cs | 10 ++- .../Api/EnrollmentComposite/EnrollmentApi.cs | 86 ++++++++++++------- .../Api/Resources/AssessmentsApi.cs | 50 ++++++++--- .../Resources/LocalEducationAgenciesApi.cs | 9 +- .../Api/Resources/ObjectiveAssessmentsApi.cs | 14 +-- DataImport.EdFi/Api/Resources/SchoolsApi.cs | 22 +++-- DataImport.EdFi/BearerTokenAuthenticator.cs | 4 +- .../ApiServers/TestApiServerConnection.cs | 6 +- DataImport.Web/Services/EdFiServiceV25.cs | 9 +- DataImport.Web/Services/EdFiServiceV311.cs | 9 +- 16 files changed, 212 insertions(+), 97 deletions(-) create mode 100644 DataImport.Common/IRestClientOptionsWrapper.cs create mode 100644 DataImport.Common/RestClientOptionsWrapper.cs diff --git a/DataImport.Common/DataImport.Common.csproj b/DataImport.Common/DataImport.Common.csproj index 6a086a3b..8a821721 100644 --- a/DataImport.Common/DataImport.Common.csproj +++ b/DataImport.Common/DataImport.Common.csproj @@ -36,7 +36,7 @@ - + diff --git a/DataImport.Common/Helpers/OAuthRequestWrapper.cs b/DataImport.Common/Helpers/OAuthRequestWrapper.cs index adff18cc..81afdd17 100644 --- a/DataImport.Common/Helpers/OAuthRequestWrapper.cs +++ b/DataImport.Common/Helpers/OAuthRequestWrapper.cs @@ -28,7 +28,7 @@ public string GetAccessCode(ApiServer apiServer, string encryptionKey) var authUrl = new Uri(apiServer.AuthUrl); var oauthClient = new RestClient(authUrl.GetLeftPart(UriPartial.Authority)); - var accessCodeRequest = new RestRequest(authUrl.AbsolutePath, Method.POST); + var accessCodeRequest = new RestRequest(authUrl.AbsolutePath, Method.Post); var apiServerKey = !string.IsNullOrEmpty(encryptionKey) ? Decrypt(apiServer.Key, encryptionKey) : apiServer.Key; @@ -58,7 +58,7 @@ public string GetBearerToken(ApiServer apiServer, string encryptionKey, string a var tokenUrl = new Uri(apiServer.TokenUrl); var oauthClient = new RestClient(tokenUrl.GetLeftPart(UriPartial.Authority)); - var bearerTokenRequest = new RestRequest(tokenUrl.AbsolutePath, Method.POST); + var bearerTokenRequest = new RestRequest(tokenUrl.AbsolutePath, Method.Post); var apiServerKey = !string.IsNullOrEmpty(encryptionKey) ? Decrypt(apiServer.Key, encryptionKey) @@ -79,9 +79,7 @@ public string GetBearerToken(ApiServer apiServer, string encryptionKey, string a bearerTokenRequest.AddParameter("grant_type", "client_credentials"); } - var bearerTokenResponse = oauthClient.Execute(bearerTokenRequest); - if (bearerTokenResponse.StatusCode != HttpStatusCode.OK) throw new AuthenticationException("Unable to retrieve an access token. Error message: " + bearerTokenResponse.ErrorMessage); diff --git a/DataImport.Common/Helpers/OdsApiTokenRetriever.cs b/DataImport.Common/Helpers/OdsApiTokenRetriever.cs index 6d6e752e..ca58d655 100644 --- a/DataImport.Common/Helpers/OdsApiTokenRetriever.cs +++ b/DataImport.Common/Helpers/OdsApiTokenRetriever.cs @@ -6,6 +6,7 @@ using System; using DataImport.Common.ExtensionMethods; using DataImport.Models; +using System.Text.Json.Serialization; namespace DataImport.Common.Helpers { @@ -45,9 +46,13 @@ internal class AccessCodeResponse internal class BearerTokenResponse { + [JsonPropertyName("access_token")] public string AccessToken { get; set; } - public string ExpiresIn { get; set; } + [JsonPropertyName("expires_in")] + public int ExpiresIn { get; set; } + [JsonPropertyName("token_type")] public string TokenType { get; set; } + [JsonPropertyName("error")] public string Error { get; set; } } } diff --git a/DataImport.Common/IRestClientOptionsWrapper.cs b/DataImport.Common/IRestClientOptionsWrapper.cs new file mode 100644 index 00000000..f72690a3 --- /dev/null +++ b/DataImport.Common/IRestClientOptionsWrapper.cs @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: Apache-2.0 +// Licensed to the Ed-Fi Alliance under one or more agreements. +// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +// See the LICENSE and NOTICES files in the project root for more information. + +using System; +using RestSharp.Authenticators; + +namespace DataImport.EdFi.UnitTests.Api +{ + public interface IRestClientOptionsWrapper + { + IAuthenticator Authenticator { get; set; } + + Uri BaseUrl { get; set; } + } +} diff --git a/DataImport.Common/RestClientOptionsWrapper.cs b/DataImport.Common/RestClientOptionsWrapper.cs new file mode 100644 index 00000000..cbf489f4 --- /dev/null +++ b/DataImport.Common/RestClientOptionsWrapper.cs @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: Apache-2.0 +// Licensed to the Ed-Fi Alliance under one or more agreements. +// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +// See the LICENSE and NOTICES files in the project root for more information. + +using System; +using RestSharp; +using RestSharp.Authenticators; + +namespace DataImport.EdFi.UnitTests.Api +{ + public class RestClientOptionsWrapper : IRestClientOptionsWrapper + { + private readonly RestClientOptions _options; + public RestClientOptionsWrapper(RestClientOptions options) + { + _options = options; + } + + public IAuthenticator Authenticator + { + get => _options.Authenticator; + set => _options.Authenticator = value; + } + + public Uri BaseUrl + { + get => _options.BaseUrl; + set => _options.BaseUrl = value; + } + } +} diff --git a/DataImport.EdFi.UnitTests/Api/EnrollmentComposite/EnrollmentApiTests.cs b/DataImport.EdFi.UnitTests/Api/EnrollmentComposite/EnrollmentApiTests.cs index 39f452c0..16beae0d 100644 --- a/DataImport.EdFi.UnitTests/Api/EnrollmentComposite/EnrollmentApiTests.cs +++ b/DataImport.EdFi.UnitTests/Api/EnrollmentComposite/EnrollmentApiTests.cs @@ -4,8 +4,11 @@ // See the LICENSE and NOTICES files in the project root for more information. using System; +using DataImport.Common.ExtensionMethods; using DataImport.EdFi.Api.EnrollmentComposite; +using DataImport.Models; using FakeItEasy; +using Microsoft.Extensions.Options; using NUnit.Framework; using RestSharp; using Shouldly; @@ -34,15 +37,16 @@ public void Given_suite2_version260_then_should_not_reset_client_url() const string Year = "2199"; const string InitialUrl = "https://example.com"; - var restClient = A.Fake(); - restClient.BaseUrl = new Uri(InitialUrl); + RestClientOptions options = new RestClientOptions(); + options.BaseUrl = new Uri(InitialUrl); + var restClient = new RestClient(options); // Act - var _ = new EnrollmentApiTss(restClient, ApiVersion, Year); + var enrollmentApi = new EnrollmentApiTss(restClient, ApiVersion, Year); // Assert - restClient.BaseUrl.ShouldNotBeNull(); - restClient.BaseUrl.ToString().ShouldBe($"{InitialUrl}/"); + enrollmentApi.Client.Options.BaseUrl.ShouldNotBeNull(); + enrollmentApi.Client.Options.BaseUrl.ToString().ShouldBe($"{InitialUrl}/"); } [TestCase("3.1.1", "2129", "/composites/v1/2129/")] @@ -54,16 +58,16 @@ public void Given_suite_3_then_should_modify_the_url(string apiVersion, string y // Arrange const string InitialUrl = "https://example.com/v3/data/"; const string ExpectedUrl = "https://example.com/v3"; - - var restClient = A.Fake(); - restClient.BaseUrl = new Uri(InitialUrl); + RestClientOptions options = new RestClientOptions(); + options.BaseUrl = new Uri(InitialUrl); + var restClient = new RestClient(options); // Act - var _ = new EnrollmentApiTss(restClient, apiVersion, year); + var enrollmentApi = new EnrollmentApiTss(restClient, apiVersion, year); // Assert - restClient.BaseUrl.ShouldNotBeNull(); - restClient.BaseUrl.ToString().ShouldBe(ExpectedUrl); + enrollmentApi.Client.Options.BaseUrl.ShouldNotBeNull(); + enrollmentApi.Client.Options.BaseUrl.ToString().ShouldBe(ExpectedUrl); } } } diff --git a/DataImport.EdFi/Api/DescriptorsApi.cs b/DataImport.EdFi/Api/DescriptorsApi.cs index 8a05cfdf..71895df1 100644 --- a/DataImport.EdFi/Api/DescriptorsApi.cs +++ b/DataImport.EdFi/Api/DescriptorsApi.cs @@ -22,15 +22,17 @@ public DescriptorsApi(IRestClient client) public List GetAllDescriptors(string descriptorPath, int? offset = null, int? limit = null) { - var request = new RestRequest($"/{descriptorPath}", Method.GET) { RequestFormat = DataFormat.Json }; + var request = new RestRequest($"/{descriptorPath}", Method.Get) { RequestFormat = DataFormat.Json }; if (offset != null) - request.AddParameter("offset", offset); + request.AddParameter("offset", offset, ParameterType.HttpHeader); if (limit != null) - request.AddParameter("limit", limit); + request.AddParameter("limit", limit, ParameterType.HttpHeader); request.AddHeader("Accept", "application/json"); - var response = _client.Execute>(request); + var clientExecute = _client.ExecuteAsync>(request); + clientExecute.Wait(); + var response = clientExecute.Result; if (response.StatusCode == HttpStatusCode.NotFound) throw new DescriptorNotFoundException(new Exception($"Descriptor '{descriptorPath}' could not be found.")); diff --git a/DataImport.EdFi/Api/EnrollmentComposite/EnrollmentApi.cs b/DataImport.EdFi/Api/EnrollmentComposite/EnrollmentApi.cs index f97c0c49..5c6af362 100644 --- a/DataImport.EdFi/Api/EnrollmentComposite/EnrollmentApi.cs +++ b/DataImport.EdFi/Api/EnrollmentComposite/EnrollmentApi.cs @@ -15,7 +15,7 @@ namespace DataImport.EdFi.Api.EnrollmentComposite { public class EnrollmentApi { - protected readonly IRestClient Client; + public readonly IRestClient Client; private readonly string _apiVersion; private readonly IMapper _mapper; protected readonly string CompositePath; @@ -29,65 +29,89 @@ public EnrollmentApi(IRestClient client, string apiVersion, string year, IMapper if (!apiVersion.IsOdsV2()) { CompositePath = year == null ? "/composites/v1" : $"/composites/v1/{year}"; - var baseUrl = Common.Helpers.UrlUtility.RemoveAfterLastInstanceOf(Client.BaseUrl.ToString().Trim(), "/data/"); - Client.BaseUrl = new Uri(baseUrl); + var baseUrl = Common.Helpers.UrlUtility.RemoveAfterLastInstanceOf(Client.Options.BaseUrl.ToString().Trim(), "/data/"); + var options = new RestClientOptions(); + options.Authenticator = client.Options.Authenticator; + options.BaseUrl = new Uri(baseUrl); + Client = new RestClient(options); } } public List GetAllSchools(int? offset = null, int? limit = null) { var request = _apiVersion.IsOdsV2() - ? new RestRequest("/enrollment/schools", Method.GET) - : new RestRequest($"{CompositePath}/ed-fi/enrollment/schools", Method.GET); + ? new RestRequest("/enrollment/schools", Method.Get) + : new RestRequest($"{CompositePath}/ed-fi/enrollment/schools", Method.Get); request.RequestFormat = DataFormat.Json; if (offset != null) - request.AddParameter("offset", offset); + request.AddParameter("offset", offset, ParameterType.HttpHeader); if (limit != null) - request.AddParameter("limit", limit); - - return _apiVersion.IsOdsV2() - ? Client.Execute>(request).Data - .Select(_mapper.Map).ToList() - : Client.Execute>(request).Data; + request.AddParameter("limit", limit, ParameterType.HttpHeader); + if (!_apiVersion.IsOdsV2()) + { + var clientExecute = + Client.ExecuteAsync>(request); + clientExecute.Wait(); + return clientExecute.Result.Data; + } + else + { + var clientExecute = + Client.ExecuteAsync>(request); + clientExecute.Wait(); + return clientExecute.Result.Data + .Select(_mapper.Map).ToList(); + } } public List
GetSectionsBySchoolId(string schoolId, int? offset = null, int? limit = null) { var request = _apiVersion.IsOdsV2() - ? new RestRequest("/enrollment/schools/{school_id}/sections", Method.GET) - : new RestRequest($"{CompositePath}/ed-fi/enrollment/schools/{{school_id}}/sections", Method.GET); + ? new RestRequest("/enrollment/schools/{school_id}/sections", Method.Get) + : new RestRequest($"{CompositePath}/ed-fi/enrollment/schools/{{school_id}}/sections", Method.Get); request.RequestFormat = DataFormat.Json; request.AddUrlSegment("school_id", schoolId); if (schoolId == null) throw new ArgumentException("API method call is missing required parameters"); if (offset != null) - request.AddParameter("offset", offset); + request.AddParameter("offset", offset, ParameterType.HttpHeader); if (limit != null) - request.AddParameter("limit", limit); + request.AddParameter("limit", limit, ParameterType.HttpHeader); - return _apiVersion.IsOdsV2() - ? Client.Execute>(request).Data - .Select(_mapper.Map
).ToList() - : Client.Execute>(request).Data; + if (!_apiVersion.IsOdsV2()) + { + var clientExecute = Client.ExecuteAsync>(request); + clientExecute.Wait(); + return clientExecute.Result.Data; + } + else + { + var clientExecute = Client.ExecuteAsync>(request); + clientExecute.Wait(); + return clientExecute.Result.Data + .Select(_mapper.Map
).ToList(); + } } public List GetStudentsBySchoolId(string schoolId, int? offset = null, int? limit = null) { var request = _apiVersion.IsOdsV2() - ? new RestRequest("/enrollment/schools/{school_id}/students", Method.GET) - : new RestRequest($"{CompositePath}/ed-fi/enrollment/schools/{{school_id}}/students", Method.GET); + ? new RestRequest("/enrollment/schools/{school_id}/students", Method.Get) + : new RestRequest($"{CompositePath}/ed-fi/enrollment/schools/{{school_id}}/students", Method.Get); request.RequestFormat = DataFormat.Json; request.AddUrlSegment("school_id", schoolId); if (schoolId == null) throw new ArgumentException("API method call is missing required parameters"); if (offset != null) - request.AddParameter("offset", offset); + request.AddParameter("offset", offset, ParameterType.HttpHeader); if (limit != null) - request.AddParameter("limit", limit); - var response = Client.Execute>(request); + request.AddParameter("limit", limit, ParameterType.HttpHeader); + var clientExecute = Client.ExecuteAsync>(request); + clientExecute.Wait(); + var response = clientExecute.Result; return response.Data; } @@ -95,18 +119,20 @@ public List GetStudentsBySchoolId(string schoolId, int? offset = null, public List GetStaffsBySchoolId(string schoolId, int? offset = null, int? limit = null) { var request = _apiVersion.IsOdsV2() - ? new RestRequest("/enrollment/schools/{school_id}/staffs", Method.GET) - : new RestRequest($"{CompositePath}/ed-fi/enrollment/schools/{{school_id}}/staffs", Method.GET); + ? new RestRequest("/enrollment/schools/{school_id}/staffs", Method.Get) + : new RestRequest($"{CompositePath}/ed-fi/enrollment/schools/{{school_id}}/staffs", Method.Get); request.RequestFormat = DataFormat.Json; request.AddUrlSegment("school_id", schoolId); if (schoolId == null) throw new ArgumentException("API method call is missing required parameters"); if (offset != null) - request.AddParameter("offset", offset); + request.AddParameter("offset", offset, ParameterType.HttpHeader); if (limit != null) - request.AddParameter("limit", limit); - var response = Client.Execute>(request); + request.AddParameter("limit", limit, ParameterType.HttpHeader); + var clientExecute = Client.ExecuteAsync>(request); + clientExecute.Wait(); + var response = clientExecute.Result; return response.Data; } diff --git a/DataImport.EdFi/Api/Resources/AssessmentsApi.cs b/DataImport.EdFi/Api/Resources/AssessmentsApi.cs index 8200bd01..0da38b10 100644 --- a/DataImport.EdFi/Api/Resources/AssessmentsApi.cs +++ b/DataImport.EdFi/Api/Resources/AssessmentsApi.cs @@ -29,37 +29,59 @@ public AssessmentsApi(IRestClient client, string apiVersion, IMapper mapper) public List GetAllAssessments(int? offset = null, int? limit = null) { var request = _apiVersion.IsOdsV2() - ? new RestRequest("/assessments", Method.GET) - : new RestRequest("/ed-fi/assessments", Method.GET); + ? new RestRequest("/assessments", Method.Get) + : new RestRequest("/ed-fi/assessments", Method.Get); request.RequestFormat = DataFormat.Json; if (offset != null) - request.AddParameter("offset", offset); + request.AddParameter("offset", offset, ParameterType.HttpHeader); if (limit != null) - request.AddParameter("limit", limit); + request.AddParameter("limit", limit, ParameterType.HttpHeader); request.AddHeader("Accept", "application/json"); - return _apiVersion.IsOdsV2() - ? _client.Execute>(request).Data - .Select(_mapper.Map).ToList() - : _client.Execute>(request).Data; + if (!_apiVersion.IsOdsV2()) + { + var clientExecute = + _client.ExecuteAsync>(request); + clientExecute.Wait(); + return clientExecute.Result.Data + .Select(_mapper.Map).ToList(); + } + else + { + var clientExecute = + _client.ExecuteAsync>(request); + clientExecute.Wait(); + return clientExecute.Result.Data + .Select(_mapper.Map).ToList(); + } } public Assessment GetAssessmentById(string id) { var request = _apiVersion.IsOdsV2() - ? new RestRequest("/assessments/{id}", Method.GET) - : new RestRequest("/ed-fi/assessments/{id}", Method.GET); + ? new RestRequest("/assessments/{id}", Method.Get) + : new RestRequest("/ed-fi/assessments/{id}", Method.Get); request.RequestFormat = DataFormat.Json; request.AddUrlSegment("id", id); if (id == null) throw new ArgumentException("API method call is missing required parameters"); request.AddHeader("Accept", "application/json"); - - return _apiVersion.IsOdsV2() - ? _mapper.Map(_client.Execute(request).Data) - : _client.Execute(request).Data; + if (!_apiVersion.IsOdsV2()) + { + var clientExecute = + _client.ExecuteAsync(request); + clientExecute.Wait(); + return clientExecute.Result.Data; + } + else + { + var clientExecute = + _client.ExecuteAsync(request); + clientExecute.Wait(); + return _mapper.Map(clientExecute.Result.Data); + } } } } diff --git a/DataImport.EdFi/Api/Resources/LocalEducationAgenciesApi.cs b/DataImport.EdFi/Api/Resources/LocalEducationAgenciesApi.cs index d91886a1..25c9896e 100644 --- a/DataImport.EdFi/Api/Resources/LocalEducationAgenciesApi.cs +++ b/DataImport.EdFi/Api/Resources/LocalEducationAgenciesApi.cs @@ -4,6 +4,7 @@ // See the LICENSE and NOTICES files in the project root for more information. using System; +using System.Collections.Generic; using DataImport.Common.ExtensionMethods; using DataImport.EdFi.Models.Resources; using RestSharp; @@ -24,15 +25,17 @@ public LocalEducationAgenciesApi(IRestClient client, string apiVersion) public LocalEducationAgency GetLocalEducationAgenciesById(string id) { var request = _apiVersion.IsOdsV2() - ? new RestRequest("/localEducationAgencies/{id}", Method.GET) - : new RestRequest("/ed-fi/localEducationAgencies/{id}", Method.GET); + ? new RestRequest("/localEducationAgencies/{id}", Method.Get) + : new RestRequest("/ed-fi/localEducationAgencies/{id}", Method.Get); request.RequestFormat = DataFormat.Json; request.AddUrlSegment("id", id); if (id == null) throw new ArgumentException("API method call is missing required parameters"); request.AddHeader("Accept", "application/json"); - var response = _client.Execute(request); + var clientExecute = _client.ExecuteAsync(request); + clientExecute.Wait(); + var response = clientExecute.Result; return response.Data; } diff --git a/DataImport.EdFi/Api/Resources/ObjectiveAssessmentsApi.cs b/DataImport.EdFi/Api/Resources/ObjectiveAssessmentsApi.cs index 1cdb7918..7fcbcfe0 100644 --- a/DataImport.EdFi/Api/Resources/ObjectiveAssessmentsApi.cs +++ b/DataImport.EdFi/Api/Resources/ObjectiveAssessmentsApi.cs @@ -24,22 +24,22 @@ public ObjectiveAssessmentsApi(IRestClient client, string apiVersion) public List GetObjectiveAssessmentsByAssessmentKey(int? offset = null, int? limit = null, string assessmentIdentifier = null, string @namespace = null) { var request = _apiVersion.IsOdsV2() - ? new RestRequest("/objectiveAssessments", Method.GET) - : new RestRequest("/ed-fi/objectiveAssessments", Method.GET); + ? new RestRequest("/objectiveAssessments", Method.Get) + : new RestRequest("/ed-fi/objectiveAssessments", Method.Get); request.RequestFormat = DataFormat.Json; if (offset != null) - request.AddParameter("offset", offset); + request.AddParameter("offset", offset, ParameterType.HttpHeader); if (limit != null) - request.AddParameter("limit", limit); + request.AddParameter("limit", limit, ParameterType.HttpHeader); if (assessmentIdentifier != null) request.AddParameter("assessmentIdentifier", assessmentIdentifier); if (@namespace != null) request.AddParameter("@namespace", @namespace); request.AddHeader("Accept", "application/json"); - - var response = _client.Execute>(request); - + var clientExecute = _client.ExecuteAsync>(request); + clientExecute.Wait(); + var response = clientExecute.Result; return response.Data; } } diff --git a/DataImport.EdFi/Api/Resources/SchoolsApi.cs b/DataImport.EdFi/Api/Resources/SchoolsApi.cs index cac88db1..48329e1c 100644 --- a/DataImport.EdFi/Api/Resources/SchoolsApi.cs +++ b/DataImport.EdFi/Api/Resources/SchoolsApi.cs @@ -22,19 +22,21 @@ public SchoolsApi(IRestClient client, string apiVersion) _apiVersion = apiVersion; } - public IRestResponse> GetAllSchoolsWithHttpResponse(int? offset = null, int? limit = null) + public RestResponse> GetAllSchoolsWithHttpResponse(int? offset = null, int? limit = null) { var request = _apiVersion.IsOdsV2() - ? new RestRequest("/schools", Method.GET) - : new RestRequest("/ed-fi/schools", Method.GET); + ? new RestRequest("/schools", Method.Get) + : new RestRequest("/ed-fi/schools", Method.Get); request.RequestFormat = DataFormat.Json; if (offset != null) - request.AddParameter("offset", offset); + request.AddParameter("offset", offset, ParameterType.HttpHeader); if (limit != null) - request.AddParameter("limit", limit); + request.AddParameter("limit", limit, ParameterType.HttpHeader); request.AddHeader("Accept", "application/json"); - var response = _client.Execute>(request); + var clientExecute = _client.ExecuteAsync>(request); + clientExecute.Wait(); + var response = clientExecute.Result; return response; } @@ -42,15 +44,17 @@ public IRestResponse> GetAllSchoolsWithHttpResponse(int? offset = n public School GetSchoolById(string id) { var request = _apiVersion.IsOdsV2() - ? new RestRequest("/schools/{id}", Method.GET) - : new RestRequest("/ed-fi/schools/{id}", Method.GET); + ? new RestRequest("/schools/{id}", Method.Get) + : new RestRequest("/ed-fi/schools/{id}", Method.Get); request.RequestFormat = DataFormat.Json; request.AddUrlSegment("id", id); if (id == null) throw new ArgumentException("API method call is missing required parameters"); request.AddHeader("Accept", "application/json"); - var response = _client.Execute(request); + var clientExecute = _client.ExecuteAsync(request); + clientExecute.Wait(); + var response = clientExecute.Result; return response.Data; } diff --git a/DataImport.EdFi/BearerTokenAuthenticator.cs b/DataImport.EdFi/BearerTokenAuthenticator.cs index baf6a0bb..7bcc4566 100644 --- a/DataImport.EdFi/BearerTokenAuthenticator.cs +++ b/DataImport.EdFi/BearerTokenAuthenticator.cs @@ -5,6 +5,7 @@ using System; using System.Linq; +using System.Threading.Tasks; using DataImport.Common.Helpers; using RestSharp; using RestSharp.Authenticators; @@ -25,13 +26,14 @@ public void UpdateToken(ITokenRetriever tokenRetriever) _bearerToken = tokenRetriever.ObtainNewBearerToken(); } - public void Authenticate(IRestClient client, IRestRequest request) + public ValueTask Authenticate(IRestClient client, RestRequest request) { // confirm bearer token is not already there -- implicit IAuthenticator requirement if (!request.Parameters.Any(p => p.Name.Equals("Authorization", StringComparison.OrdinalIgnoreCase))) { request.AddParameter("Authorization", "bearer " + _bearerToken, ParameterType.HttpHeader); } + return new ValueTask(); } } } diff --git a/DataImport.Web/Features/ApiServers/TestApiServerConnection.cs b/DataImport.Web/Features/ApiServers/TestApiServerConnection.cs index 69bade5b..c3eca80f 100644 --- a/DataImport.Web/Features/ApiServers/TestApiServerConnection.cs +++ b/DataImport.Web/Features/ApiServers/TestApiServerConnection.cs @@ -144,9 +144,11 @@ public async Task Handle(Query request, CancellationToken cancellation try { - var client = new RestClient(url); var tokenRetriever = new OdsApiTokenRetriever(_oAuthRequestWrapper, apiServer); - client.Authenticator = new BearerTokenAuthenticator(tokenRetriever); + var options = new RestClientOptions(); + options.Authenticator = new BearerTokenAuthenticator(tokenRetriever); + options.BaseUrl = new Uri(url); + var client = new RestClient(options); var api = new SchoolsApi(client, apiVersion); var apiCall = api.GetAllSchoolsWithHttpResponse(0, 1); diff --git a/DataImport.Web/Services/EdFiServiceV25.cs b/DataImport.Web/Services/EdFiServiceV25.cs index c29a6868..98ea17e8 100644 --- a/DataImport.Web/Services/EdFiServiceV25.cs +++ b/DataImport.Web/Services/EdFiServiceV25.cs @@ -32,11 +32,10 @@ public EdFiServiceV25(DataImportDbContext dbContext, IEncryptionKeyResolver encr protected override IRestClient EstablishApiClient(ApiServer apiServer) { var tokenRetriever = new OdsApiTokenRetriever(_oauthRequestWrapper, apiServer, _encryptionKey); - - return new RestClient(apiServer?.Url) - { - Authenticator = new BearerTokenAuthenticator(tokenRetriever) - }; + var options = new RestClientOptions(); + options.Authenticator = new BearerTokenAuthenticator(tokenRetriever); + options.BaseUrl = new Uri(apiServer?.Url); + return new RestClient(options); } protected override Task GetYearSpecificYear(ApiServer apiServer, ApiVersion apiVersion) diff --git a/DataImport.Web/Services/EdFiServiceV311.cs b/DataImport.Web/Services/EdFiServiceV311.cs index 288d567b..2ca158d2 100644 --- a/DataImport.Web/Services/EdFiServiceV311.cs +++ b/DataImport.Web/Services/EdFiServiceV311.cs @@ -44,11 +44,10 @@ public override bool CanHandle(string apiVersion) protected override IRestClient EstablishApiClient(ApiServer apiServer) { var tokenRetriever = new OdsApiTokenRetriever(_oauthRequestWrapper, apiServer, EncryptionKey); - - return new RestClient(apiServer?.Url) - { - Authenticator = new BearerTokenAuthenticator(tokenRetriever) - }; + var options = new RestClientOptions(); + options.Authenticator = new BearerTokenAuthenticator(tokenRetriever); + options.BaseUrl = new Uri(apiServer?.Url); + return new RestClient(options); } protected override async Task GetYearSpecificYear(ApiServer apiServer, ApiVersion apiVersion) From b09584dd0ac5b5198d03e1f317ed85be8a9c91cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Alberto=20Leiva=20Obando?= Date: Fri, 12 Apr 2024 14:28:43 -0600 Subject: [PATCH 2/2] Update EnrollmentApiTests.cs Add test to validate Authenticator field with the new object structure --- .../EnrollmentComposite/EnrollmentApiTests.cs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/DataImport.EdFi.UnitTests/Api/EnrollmentComposite/EnrollmentApiTests.cs b/DataImport.EdFi.UnitTests/Api/EnrollmentComposite/EnrollmentApiTests.cs index 16beae0d..68d3ce90 100644 --- a/DataImport.EdFi.UnitTests/Api/EnrollmentComposite/EnrollmentApiTests.cs +++ b/DataImport.EdFi.UnitTests/Api/EnrollmentComposite/EnrollmentApiTests.cs @@ -11,6 +11,7 @@ using Microsoft.Extensions.Options; using NUnit.Framework; using RestSharp; +using RestSharp.Authenticators; using Shouldly; namespace DataImport.EdFi.UnitTests.Api.EnrollmentComposite @@ -69,5 +70,43 @@ public void Given_suite_3_then_should_modify_the_url(string apiVersion, string y enrollmentApi.Client.Options.BaseUrl.ShouldNotBeNull(); enrollmentApi.Client.Options.BaseUrl.ToString().ShouldBe(ExpectedUrl); } + + [Test] + public void Given_suite2_version260_then_should_have_the_authenticator() + { + // Arrange + const string ApiVersion = "2.6.0"; + const string Year = "2199"; + const string InitialUrl = "https://example.com/v3/data/"; + RestClientOptions options = new RestClientOptions(); + options.BaseUrl = new Uri(InitialUrl); + options.Authenticator = A.Fake(); + var restClient = new RestClient(options); + + // Act + var enrollmentApi = new EnrollmentApiTss(restClient, ApiVersion, Year); + + // Assert + enrollmentApi.Client.Options.Authenticator.ShouldNotBeNull(); + } + + [TestCase("3.1.1", "2129")] + [TestCase("3.1.1", null)] + [TestCase("5.1.0", "2129")] + [TestCase("5.1.0", null)] + public void Given_suite_3_then_should_have_the_authenticator(string apiVersion, string year) + { + const string InitialUrl = "https://example.com/v3/data/"; + RestClientOptions options = new RestClientOptions(); + options.BaseUrl = new Uri(InitialUrl); + options.Authenticator = A.Fake(); + var restClient = new RestClient(options); + + // Act + var enrollmentApi = new EnrollmentApiTss(restClient, apiVersion, year); + + // Assert + enrollmentApi.Client.Options.Authenticator.ShouldNotBeNull(); + } } }