/// <inheritdoc /> public RequestResult <IEnumerable <UserNote> > GetNotes(string hdId, int page = 0, int pageSize = 500) { int offset = page * pageSize; DBResult <IEnumerable <Note> > dbNotes = this.noteDelegate.GetNotes(hdId, offset, pageSize); UserProfile profile = this.profileDelegate.GetUserProfile(hdId).Payload; string? key = profile.EncryptionKey; // If there is no key yet, generate one and store it in the profile. Only valid while not all profiles have a encryption key. if (key == null) { this.logger.LogInformation($"First time note retrieval with key for user ${hdId}"); key = this.EncryptFirstTime(profile, dbNotes.Payload); dbNotes = this.noteDelegate.GetNotes(hdId, offset, pageSize); } // Check that the key has been set if (key == null) { this.logger.LogError($"User does not have a key: ${hdId}"); return(new RequestResult <IEnumerable <UserNote> >() { ResultStatus = ResultType.Error, ResultError = new RequestResultError() { ResultMessage = "Profile Key not set", ErrorCode = ErrorTranslator.InternalError(ErrorType.InvalidState) }, }); } RequestResult <IEnumerable <UserNote> > result = new RequestResult <IEnumerable <UserNote> >() { ResourcePayload = UserNote.CreateListFromDbModel(dbNotes.Payload, this.cryptoDelegate, key), PageIndex = page, PageSize = pageSize, TotalResultCount = dbNotes.Payload.ToList().Count, ResultStatus = dbNotes.Status == DBStatusCode.Read ? ResultType.Success : ResultType.Error, ResultError = dbNotes.Status == DBStatusCode.Read ? null : new RequestResultError() { ResultMessage = dbNotes.Message, ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database) }, }; return(result); }
/// <inheritdoc /> public RequestResult <Dictionary <string, string> > GetUserPreferences(string hdid) { this.logger.LogTrace($"Getting user preference... {hdid}"); DBResult <IEnumerable <UserPreference> > dbResult = this.userPreferenceDelegate.GetUserPreferences(hdid); RequestResult <Dictionary <string, string> > requestResult = new RequestResult <Dictionary <string, string> >() { ResourcePayload = dbResult.Payload.ToDictionary(x => x.Preference, x => x.Value), ResultStatus = dbResult.Status == DBStatusCode.Read ? ResultType.Success : ResultType.Error, ResultError = dbResult.Status == DBStatusCode.Read ? null : new RequestResultError() { ResultMessage = dbResult.Message, ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database) } }; this.logger.LogTrace($"Finished getting user preference. {JsonSerializer.Serialize(dbResult)}"); return(requestResult); }
/// <inheritdoc /> public RequestResult <UserProfileModel> GetUserProfile(string hdid, DateTime?lastLogin = null) { this.logger.LogTrace($"Getting user profile... {hdid}"); DBResult <UserProfile> retVal = this.userProfileDelegate.GetUserProfile(hdid); this.logger.LogDebug($"Finished getting user profile. {JsonSerializer.Serialize(retVal)}"); if (retVal.Status == DBStatusCode.NotFound) { return(new RequestResult <UserProfileModel>() { ResultStatus = ResultType.Success, ResourcePayload = new UserProfileModel(), }); } DateTime?previousLastLogin = retVal.Payload.LastLoginDateTime; if (lastLogin.HasValue) { this.logger.LogTrace($"Updating user last login... {hdid}"); retVal.Payload.LastLoginDateTime = lastLogin; DBResult <UserProfile> updateResult = this.userProfileDelegate.Update(retVal.Payload); this.logger.LogDebug($"Finished updating user last login. {JsonSerializer.Serialize(updateResult)}"); } RequestResult <TermsOfServiceModel> termsOfServiceResult = this.GetActiveTermsOfService(); UserProfileModel userProfile = UserProfileModel.CreateFromDbModel(retVal.Payload); userProfile.HasTermsOfServiceUpdated = previousLastLogin.HasValue && termsOfServiceResult.ResourcePayload?.EffectiveDate > previousLastLogin.Value; return(new RequestResult <UserProfileModel>() { ResultStatus = retVal.Status != DBStatusCode.Error ? ResultType.Success : ResultType.Error, ResultError = retVal.Status != DBStatusCode.Error ? null : new RequestResultError() { ResultMessage = retVal.Message, ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database) }, ResourcePayload = userProfile, }); }
/// <inheritdoc /> public RequestResult <Communication> Add(Communication communication) { this.logger.LogTrace($"Communication recieved: {JsonSerializer.Serialize(communication)}"); if (communication.CommunicationTypeCode == CommunicationType.Email) { if (communication.Text.Length == 0 || communication.Subject.Length == 0) { throw new ArgumentException("One of: Email Subject, Email Content is invalid."); } communication.EffectiveDateTime = DateTime.UtcNow; communication.ExpiryDateTime = DateTime.UtcNow; } this.logger.LogTrace($"Adding communication... {JsonSerializer.Serialize(communication)}"); if (communication.EffectiveDateTime < communication.ExpiryDateTime) { this.logger.LogTrace($"Adding communication... {JsonSerializer.Serialize(communication)}"); DBResult <HealthGateway.Database.Models.Communication> dbResult = this.communicationDelegate.Add(communication.ToDbModel()); return(new RequestResult <Communication>() { ResourcePayload = new Communication(dbResult.Payload), ResultStatus = dbResult.Status == DBStatusCode.Created ? ResultType.Success : ResultType.Error, ResultError = dbResult.Status == DBStatusCode.Created ? null : new RequestResultError() { ResultMessage = dbResult.Message, ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database) }, }); } else { return(new RequestResult <Communication>() { ResourcePayload = null, ResultStatus = ResultType.Error, ResultError = new RequestResultError() { ResultMessage = "Effective Date should be before Expiry Date.", ErrorCode = ErrorTranslator.InternalError(ErrorType.InvalidState) }, }); } }
/// <inheritdoc /> public RequestResult <Rating> CreateRating(Rating rating) { this.logger.LogTrace($"Creating rating... {JsonConvert.SerializeObject(rating)}"); DBResult <Rating> dbRating = this.ratingDelegate.InsertRating(rating); this.logger.LogDebug($"Finished creating user feedback. {JsonConvert.SerializeObject(dbRating)}"); RequestResult <Rating> result = new RequestResult <Rating>() { ResourcePayload = dbRating.Payload, ResultStatus = dbRating.Status == DBStatusCode.Created ? ResultType.Success : ResultType.Error, ResultError = new RequestResultError() { ResultMessage = dbRating.Message, ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database) }, }; return(result); }
public void Default() { int pageIndex = 0; RequestResult <IEnumerable <ImmunizationResponse> > expectedResult = new RequestResult <IEnumerable <ImmunizationResponse> >() { ResultStatus = Common.Constants.ResultType.Error, ResultError = new RequestResultError() { ResultMessage = $"Unable to connect to Immunizations Endpoint, HTTP Error {HttpStatusCode.RequestTimeout}", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.PHSA) }, PageIndex = pageIndex, }; using Microsoft.Extensions.Logging.ILoggerFactory loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()); IHttpClientService httpClientService = GetHttpClientService(HttpStatusCode.RequestTimeout, string.Empty); IImmunizationDelegate immsDelegate = new RestImmunizationDelegate(loggerFactory.CreateLogger <RestImmunizationDelegate>(), httpClientService, this.configuration); var actualResult = immsDelegate.GetImmunizations("token", pageIndex).Result; Assert.True(actualResult.IsDeepEqual(expectedResult)); }
/// <inheritdoc /> public RequestResult <DependentModel> Remove(DependentModel dependent) { DBResult <ResourceDelegate> dbDependent = this.resourceDelegateDelegate.Delete(dependent.ToDBModel(), true); if (dbDependent.Status == DBStatusCode.Deleted) { this.UpdateNotificationSettings(dependent.OwnerId, dependent.DelegateId, isDelete: true); } RequestResult <DependentModel> result = new RequestResult <DependentModel>() { ResourcePayload = new DependentModel(), ResultStatus = dbDependent.Status == DBStatusCode.Deleted ? ResultType.Success : ResultType.Error, ResultError = dbDependent.Status == DBStatusCode.Deleted ? null : new RequestResultError() { ResultMessage = dbDependent.Message, ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database) }, }; return(result); }
/// <inheritdoc /> public RequestResult <IDictionary <string, IEnumerable <UserComment> > > GetProfileComments(string hdId) { UserProfile profile = this.profileDelegate.GetUserProfile(hdId).Payload; string? key = profile.EncryptionKey; // Check that the key has been set if (key == null) { this.logger.LogError($"User does not have a key: ${hdId}"); return(new RequestResult <IDictionary <string, IEnumerable <UserComment> > >() { ResultStatus = ResultType.Error, ResultError = new RequestResultError() { ResultMessage = "Profile Key not set", ErrorCode = ErrorTranslator.InternalError(ErrorType.InvalidState) }, }); } DBResult <IEnumerable <Comment> > dbComments = this.commentDelegate.GetAll(hdId); IEnumerable <UserComment> comments = UserComment.CreateListFromDbModel(dbComments.Payload, this.cryptoDelegate, key); IDictionary <string, IEnumerable <UserComment> > userCommentsByEntry = comments.GroupBy(x => x.ParentEntryId).ToDictionary(g => g.Key, g => g.AsEnumerable()); RequestResult <IDictionary <string, IEnumerable <UserComment> > > result = new RequestResult <IDictionary <string, IEnumerable <UserComment> > >() { ResourcePayload = userCommentsByEntry, TotalResultCount = userCommentsByEntry.Count, PageIndex = 0, PageSize = userCommentsByEntry.Count, ResultStatus = dbComments.Status == DBStatusCode.Read ? ResultType.Success : ResultType.Error, ResultError = dbComments.Status != DBStatusCode.Read ? new RequestResultError() { ResultMessage = dbComments.Message, ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database) } : null, }; return(result); }
/// <inheritdoc /> public RequestResult <UserPreferenceModel> CreateUserPreference(UserPreferenceModel userPreferenceModel) { this.logger.LogTrace($"Creating user preference... {userPreferenceModel.Preference}"); UserPreference userPreference = userPreferenceModel.ToDbModel(); DBResult <UserPreference> dbResult = this.userPreferenceDelegate.CreateUserPreference(userPreference); this.logger.LogDebug($"Finished creating user preference. {JsonSerializer.Serialize(dbResult)}"); RequestResult <UserPreferenceModel> requestResult = new RequestResult <UserPreferenceModel>() { ResourcePayload = UserPreferenceModel.CreateFromDbModel(dbResult.Payload), ResultStatus = dbResult.Status == DBStatusCode.Created ? ResultType.Success : ResultType.Error, ResultError = dbResult.Status == DBStatusCode.Created ? null : new RequestResultError() { ResultMessage = dbResult.Message, ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database), }, }; return(requestResult); }
public void BadData() { string json = "{}"; RequestResult <IEnumerable <ImmunizationResponse> > expectedResult = new RequestResult <IEnumerable <ImmunizationResponse> >() { PageIndex = 0, ResultStatus = Common.Constants.ResultType.Error, ResultError = new RequestResultError() { ResultMessage = $"Error with JSON data", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.PHSA) }, }; using Microsoft.Extensions.Logging.ILoggerFactory loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()); IHttpClientService httpClientService = GetHttpClientService(HttpStatusCode.OK, json); IImmunizationDelegate immsDelegate = new RestImmunizationDelegate(loggerFactory.CreateLogger <RestImmunizationDelegate>(), httpClientService, this.configuration); var actualResult = immsDelegate.GetImmunizations("token", 0).Result; Assert.True(expectedResult.IsDeepEqual(actualResult)); }
private RequestResult <PatientModel> ParseResponse(HCIM_IN_GetDemographicsResponse1 reply) { using (Source.StartActivity("ParsePatientResponse")) { this.logger.LogDebug($"Parsing patient response... {JsonSerializer.Serialize(reply)}"); // Verify that the reply contains a result string responseCode = reply.HCIM_IN_GetDemographicsResponse.controlActProcess.queryAck.queryResponseCode.code; if (!responseCode.Contains("BCHCIM.GD.0.0013", StringComparison.InvariantCulture)) { PatientModel emptyPatient = new PatientModel(); this.logger.LogWarning($"Client Registry did not return a person. Returned message code: {responseCode}"); this.logger.LogDebug($"Finished getting patient. {JsonSerializer.Serialize(emptyPatient)}"); return(new RequestResult <PatientModel>() { ResultStatus = ResultType.Error, ResultError = new RequestResultError() { ResultMessage = "Client Registry did not return a person", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.ClientRegistries) }, }); } HCIM_IN_GetDemographicsResponseIdentifiedPerson retrievedPerson = reply.HCIM_IN_GetDemographicsResponse.controlActProcess.subject[0].target; // If the deceased indicator is set and true, return an empty person. bool deceasedInd = retrievedPerson.identifiedPerson.deceasedInd?.value ?? false; if (deceasedInd) { PatientModel emptyPatient = new PatientModel(); this.logger.LogWarning($"Client Registry returned a person with the deceasedIndicator set to true. No PHN was populated. {deceasedInd}"); this.logger.LogDebug($"Finished getting patient. {JsonSerializer.Serialize(emptyPatient)}"); return(new RequestResult <PatientModel>() { ResultStatus = ResultType.Error, ResultError = new RequestResultError() { ResultMessage = "Client Registry returned a person with the deceasedIndicator set to true", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.ClientRegistries) }, }); } PN?nameSection = retrievedPerson.identifiedPerson.name.Where(x => x.use.Any(u => u == cs_EntityNameUse.C)).FirstOrDefault(); if (nameSection == null) { this.logger.LogWarning($"Client Registry returned a person with an invalid name."); return(new RequestResult <PatientModel>() { ResultStatus = ResultType.ActionRequired, ResultError = ErrorTranslator.ActionRequired(ErrorMessages.InvalidServicesCard, ActionType.InvalidName), }); } // Extract the subject names List <string> givenNameList = new List <string>(); List <string> lastNameList = new List <string>(); for (int i = 0; i < nameSection.Items.Length; i++) { ENXP name = nameSection.Items[i]; if (name.GetType() == typeof(engiven) && (name.qualifier == null || !name.qualifier.Contains(cs_EntityNamePartQualifier.CL))) { givenNameList.Add(name.Text[0]); } else if (name.GetType() == typeof(enfamily) && (name.qualifier == null || !name.qualifier.Contains(cs_EntityNamePartQualifier.CL))) { lastNameList.Add(name.Text[0]); } } string delimiter = " "; string givenNames = givenNameList.Aggregate((i, j) => i + delimiter + j); string lastNames = lastNameList.Aggregate((i, j) => i + delimiter + j); string? dobStr = ((TS)retrievedPerson.identifiedPerson.birthTime).value; // yyyyMMdd DateTime dob = DateTime.ParseExact(dobStr, "yyyyMMdd", CultureInfo.InvariantCulture); string genderCode = retrievedPerson.identifiedPerson.administrativeGenderCode.code; string gender = "NotSpecified"; if (genderCode == "F") { gender = "Female"; } else if (genderCode == "M") { gender = "Male"; } PatientModel patient = new PatientModel() { FirstName = givenNames, LastName = lastNames, Birthdate = dob, Gender = gender, EmailAddress = string.Empty }; II? identifiedPersonId = (II?)retrievedPerson.identifiedPerson.id.GetValue(0); string?personIdentifierType = identifiedPersonId?.root; string personIdentifier = identifiedPersonId?.extension ?? string.Empty; if (personIdentifierType == OIDType.HDID.ToString()) { patient.HdId = personIdentifier; } else if (personIdentifierType == OIDType.PHN.ToString()) { patient.PersonalHealthNumber = personIdentifier; } else { this.logger.LogWarning($"Client Registry returned a person with a person identifier not recognized. No PHN or HDID was populated."); return(new RequestResult <PatientModel>() { ResultStatus = ResultType.ActionRequired, ResultError = ErrorTranslator.ActionRequired(ErrorMessages.InvalidServicesCard, ActionType.NoHdId), }); } II? subjectId = (II?)retrievedPerson.id.GetValue(0); string?subjectIdentifierType = subjectId?.root; string subjectIdentifier = subjectId?.extension ?? string.Empty; if (subjectIdentifierType == OIDType.HDID.ToString()) { patient.HdId = subjectIdentifier; } else if (personIdentifierType == OIDType.PHN.ToString()) { patient.PersonalHealthNumber = subjectIdentifier; } else { this.logger.LogWarning($"Client Registry returned a person with a subject identifier not recognized. No PHN or HDID was populated."); return(new RequestResult <PatientModel>() { ResultStatus = ResultType.ActionRequired, ResultError = ErrorTranslator.ActionRequired(ErrorMessages.InvalidServicesCard, ActionType.NoHdId), }); } return(new RequestResult <PatientModel>() { ResultStatus = ResultType.Success, ResourcePayload = patient, }); } }
/// <inheritdoc/> public async Task <RequestResult <List <MedicationStatementHistory> > > GetMedicationStatementsHistory(string hdid, string?protectiveWord) { using ITracer tracer = this.traceService.TraceMethod(this.GetType().Name); this.logger.LogDebug("Getting history of medication statements"); this.logger.LogTrace($"User hdid: {hdid}"); RequestResult <List <MedicationStatementHistory> > result = new RequestResult <List <MedicationStatementHistory> >(); var validationResult = ValidateProtectiveWord(protectiveWord); bool okProtectiveWord = validationResult.Item1; if (okProtectiveWord) { // Retrieve the phn string jwtString = this.httpContextAccessor.HttpContext.Request.Headers["Authorization"][0]; RequestResult <Patient> patientResult = this.patientDelegate.GetPatient(hdid, jwtString); if (patientResult.ResultStatus == ResultType.Success && patientResult.ResourcePayload != null) { Patient patient = patientResult.ResourcePayload; MedicationHistoryQuery historyQuery = new MedicationHistoryQuery() { StartDate = patient.Birthdate, EndDate = System.DateTime.Now, PHN = patient.PersonalHealthNumber, PageSize = 20000, }; IPAddress address = this.httpContextAccessor.HttpContext.Connection.RemoteIpAddress; string ipv4Address = address.MapToIPv4().ToString(); RequestResult <MedicationHistoryResponse> response = await this.medicationStatementDelegate.GetMedicationStatementsAsync(historyQuery, protectiveWord, hdid, ipv4Address).ConfigureAwait(true); result.ResultStatus = response.ResultStatus; result.ResultError = response.ResultError; if (response.ResultStatus == ResultType.Success) { result.PageSize = historyQuery.PageSize; result.PageIndex = historyQuery.PageNumber; if (response.ResourcePayload != null && response.ResourcePayload.Results != null) { result.TotalResultCount = response.ResourcePayload.Records; result.ResourcePayload = MedicationStatementHistory.FromODRModelList(response.ResourcePayload.Results.ToList()); this.PopulateBrandName(result.ResourcePayload.Select(r => r.MedicationSumary).ToList()); } else { result.ResourcePayload = new List <MedicationStatementHistory>(); } } } else { result.ResultError = patientResult.ResultError; } } else { this.logger.LogInformation($"Invalid protective word. {hdid}"); result.ResultStatus = ResultType.Protected; result.ResultError = new RequestResultError() { ResultMessage = validationResult.Item2, ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationInternal, ServiceType.Patient) }; } this.logger.LogDebug($"Finished getting history of medication statements"); return(result); }
/// <inheritdoc/> public async Task <RequestResult <IEnumerable <LaboratoryOrder> > > GetLaboratoryOrders(string bearerToken, string hdid, int pageIndex = 0) { using (Source.StartActivity("GetLaboratoryOrders")) { RequestResult <IEnumerable <LaboratoryOrder> > retVal = new RequestResult <IEnumerable <LaboratoryOrder> >() { ResultStatus = Common.Constants.ResultType.Error, PageIndex = pageIndex, }; this.logger.LogDebug($"Getting laboratory orders..."); using HttpClient client = this.httpClientService.CreateDefaultHttpClient(); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", bearerToken); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json)); var query = new Dictionary <string, string?> { ["limit"] = this.labConfig.FetchSize, ["subjectHdid"] = hdid, }; try { Uri endpoint = new Uri(QueryHelpers.AddQueryString(this.labConfig.Endpoint, query)); HttpResponseMessage response = await client.GetAsync(endpoint).ConfigureAwait(true); string payload = await response.Content.ReadAsStringAsync().ConfigureAwait(true); this.logger.LogTrace($"Response: {response}"); switch (response.StatusCode) { case HttpStatusCode.OK: var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, IgnoreNullValues = true, WriteIndented = true, }; this.logger.LogTrace($"Response payload: {payload}"); PHSAResult <List <LaboratoryOrder> >?phsaResult = JsonSerializer.Deserialize <PHSAResult <List <LaboratoryOrder> > >(payload, options); if (phsaResult != null && phsaResult.Result != null) { retVal.ResultStatus = Common.Constants.ResultType.Success; retVal.ResourcePayload = phsaResult.Result; retVal.TotalResultCount = phsaResult.Result.Count; #pragma warning disable CA1305 // Specify IFormatProvider retVal.PageSize = int.Parse(this.labConfig.FetchSize); #pragma warning restore CA1305 // Specify IFormatProvider } else { retVal.ResultError = new RequestResultError() { ResultMessage = "Error with JSON data", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.PHSA) }; } break; case HttpStatusCode.NoContent: // No Lab exits for this user retVal.ResultStatus = Common.Constants.ResultType.Success; retVal.ResourcePayload = new List <LaboratoryOrder>(); retVal.TotalResultCount = 0; #pragma warning disable CA1305 // Specify IFormatProvider retVal.PageSize = int.Parse(this.labConfig.FetchSize); #pragma warning restore CA1305 // Specify IFormatProvider break; case HttpStatusCode.Forbidden: retVal.ResultError = new RequestResultError() { ResultMessage = $"DID Claim is missing or can not resolve PHN, HTTP Error {response.StatusCode}", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.PHSA) }; break; default: retVal.ResultError = new RequestResultError() { ResultMessage = $"Unable to connect to Labs Endpoint, HTTP Error {response.StatusCode}", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.PHSA) }; this.logger.LogError($"Unable to connect to endpoint {endpoint}, HTTP Error {response.StatusCode}\n{payload}"); break; } } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception e) #pragma warning restore CA1031 // Do not catch general exception types { retVal.ResultError = new RequestResultError() { ResultMessage = $"Exception getting Lab Orders: {e}", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.PHSA) }; this.logger.LogError($"Unexpected exception in Get Lab Orders {e}"); } this.logger.LogDebug($"Finished getting Laboratory Orders"); return(retVal); } }
/// <inheritdoc/> public async Task <RequestResult <LaboratoryReport> > GetLabReport(Guid id, string hdid, string bearerToken) { using (Source.StartActivity("GetLaboratoryOrders")) { RequestResult <LaboratoryReport> retVal = new RequestResult <LaboratoryReport>() { ResultStatus = Common.Constants.ResultType.Error, }; this.logger.LogTrace($"Getting laboratory report... {id}"); using HttpClient client = this.httpClientService.CreateDefaultHttpClient(); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", bearerToken); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json)); var query = new Dictionary <string, string> { ["subjectHdid"] = hdid, }; try { Uri endpoint = new Uri(QueryHelpers.AddQueryString($"{this.labConfig.Endpoint}/{id}/LabReportDocument", query)); HttpResponseMessage response = await client.GetAsync(endpoint).ConfigureAwait(true); string payload = await response.Content.ReadAsStringAsync().ConfigureAwait(true); this.logger.LogTrace($"Get laboratory report response payload: {payload}"); switch (response.StatusCode) { case HttpStatusCode.OK: var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, IgnoreNullValues = true, WriteIndented = true, }; LaboratoryReport?report = JsonSerializer.Deserialize <LaboratoryReport>(payload, options); if (report != null) { retVal.ResultStatus = Common.Constants.ResultType.Success; retVal.ResourcePayload = report; retVal.TotalResultCount = 1; } else { retVal.ResultError = new RequestResultError() { ResultMessage = "Error with JSON data", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.PHSA) }; } break; case HttpStatusCode.NoContent: // No report found. retVal.ResultError = new RequestResultError() { ResultMessage = "Report not found.", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.PHSA) }; break; case HttpStatusCode.Forbidden: retVal.ResultError = new RequestResultError() { ResultMessage = $"DID Claim is missing or can not resolve PHN, HTTP Error {response.StatusCode}", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.PHSA) }; break; default: retVal.ResultError = new RequestResultError() { ResultMessage = $"Unable to connect to Labs Endpoint, HTTP Error {response.StatusCode}", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.PHSA) }; this.logger.LogError($"Unable to connect to endpoint {endpoint}, HTTP Error {response.StatusCode}\n{payload}"); break; } } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception e) #pragma warning restore CA1031 // Do not catch general exception types { retVal.ResultError = new RequestResultError() { ResultMessage = $"Exception getting Lab Report: {e}", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.PHSA) }; this.logger.LogError($"Unexpected exception in Lab Report {e}"); } this.logger.LogDebug($"Finished getting Laboratory Report"); return(retVal); } }
/// <inheritdoc/> public RequestResult <Patient> GetPatient(string hdid, string authorization) { RequestResult <Patient> retVal = new RequestResult <Patient>() { ResultStatus = Constants.ResultType.Error, }; using ITracer tracer = this.traceService.TraceMethod(this.GetType().Name); this.logger.LogDebug($"GetPatientAsync: Getting patient information {hdid}"); using HttpClient client = this.httpClientService.CreateDefaultHttpClient(); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Add("Authorization", authorization); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json)); client.BaseAddress = new Uri(this.configuration.GetSection("PatientService").GetValue <string>("Url")); try { using HttpResponseMessage response = Task.Run <HttpResponseMessage>(async() => await client.GetAsync(new Uri($"v1/api/Patient/{hdid}", UriKind.Relative)).ConfigureAwait(true)).Result; string payload = Task.Run <string>(async() => await response.Content.ReadAsStringAsync().ConfigureAwait(true)).Result; if (response.IsSuccessStatusCode) { RequestResult <Patient> result = JsonSerializer.Deserialize <RequestResult <Patient> >(payload); Patient?patient = result.ResourcePayload; if (result.ResultStatus == ResultType.Success && patient != null) { if (!string.IsNullOrEmpty(patient.PersonalHealthNumber)) { retVal.ResultStatus = Constants.ResultType.Success; retVal.ResourcePayload = patient; this.logger.LogDebug($"Finished getting patient. {hdid}"); this.logger.LogTrace($"{patient.PersonalHealthNumber.Substring(0, 3)}"); } else { retVal.ResultError = new RequestResultError() { ResultMessage = "PHN not found", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationInternal, ServiceType.Patient) }; this.logger.LogDebug($"Finished getting patient. {hdid}, PHN not found"); } } else { if (result.ResultError != null) { retVal.ResultError = result.ResultError; } else { retVal.ResultError = new RequestResultError() { ResultMessage = "Invalid response object returned from PatientService", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationInternal, ServiceType.Patient) }; this.logger.LogError($"Could not deserialize patient response object"); } } } else { retVal.ResultError = new RequestResultError() { ResultMessage = $"Response {response.StatusCode}/{response.ReasonPhrase} from Patient Service", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationInternal, ServiceType.Patient) }; this.logger.LogError($"Error getting patient. {hdid}, {payload}"); } } catch (AggregateException e) { this.logger.LogError($"Error connecting to Patient service {e.ToString()}"); retVal.ResultError = new RequestResultError() { ResultMessage = "Unable to connect to Health Gateway Patient Service", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationInternal, ServiceType.Patient) }; } return(retVal); }
/// <summary> /// Gets the patient record. /// </summary> /// <param name="hdid">The patient id.</param> /// <returns>The patient model.</returns> public async System.Threading.Tasks.Task <RequestResult <Patient> > GetPatient(string hdid) { Stopwatch timer = new Stopwatch(); timer.Start(); this.logger.LogTrace($"Getting patient... {hdid}"); Patient patient; // Create request HCIM_IN_GetDemographicsRequest request = this.CreateRequest(hdid); // Perform the request try { HCIM_IN_GetDemographicsResponse1 reply = await this.clientRegistriesDelegate.GetDemographicsAsync(request).ConfigureAwait(true); // Verify that the reply contains a result string responseCode = reply.HCIM_IN_GetDemographicsResponse.controlActProcess.queryAck.queryResponseCode.code; if (!responseCode.Contains("BCHCIM.GD.0.0013", StringComparison.InvariantCulture)) { patient = new Patient(); this.logger.LogWarning($"Client Registry did not return a person. Returned message code: {responseCode}"); this.logger.LogDebug($"Finished getting patient. {JsonSerializer.Serialize(patient)}"); return(new RequestResult <Patient>() { ResultStatus = ResultType.Error, ResultError = new RequestResultError() { ResultMessage = "Client Registry did not return a person", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.ClientRegistries) }, }); } HCIM_IN_GetDemographicsResponseIdentifiedPerson retrievedPerson = reply.HCIM_IN_GetDemographicsResponse.controlActProcess.subject[0].target; // If the deceased indicator is set and true, return an empty person. bool deceasedInd = retrievedPerson.identifiedPerson.deceasedInd?.value == true; if (deceasedInd) { patient = new Patient(); this.logger.LogWarning($"Client Registry returned a person with the deceasedIndicator set to true. No PHN was populated. {deceasedInd}"); this.logger.LogDebug($"Finished getting patient. {JsonSerializer.Serialize(patient)}"); return(new RequestResult <Patient>() { ResultStatus = ResultType.Error, ResultError = new RequestResultError() { ResultMessage = "Client Registry returned a person with the deceasedIndicator set to true", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.ClientRegistries) }, }); } // Extract the subject names List <string> givenNameList = new List <string>(); List <string> lastNameList = new List <string>(); for (int i = 0; i < retrievedPerson.identifiedPerson.name[0].Items.Length; i++) { ENXP name = retrievedPerson.identifiedPerson.name[0].Items[i]; if (name.GetType() == typeof(engiven)) { givenNameList.Add(name.Text[0]); } else if (name.GetType() == typeof(enfamily)) { lastNameList.Add(name.Text[0]); } } string delimiter = " "; string givenNames = givenNameList.Aggregate((i, j) => i + delimiter + j); string lastNames = lastNameList.Aggregate((i, j) => i + delimiter + j); string phn = ((II)retrievedPerson.identifiedPerson.id.GetValue(0) !).extension; string? dobStr = ((TS)retrievedPerson.identifiedPerson.birthTime).value; // yyyyMMdd DateTime dob = DateTime.ParseExact(dobStr, "yyyyMMdd", CultureInfo.InvariantCulture); patient = new Patient(hdid, phn, givenNames, lastNames, dob, string.Empty); timer.Stop(); this.logger.LogDebug($"Finished getting patient. {JsonSerializer.Serialize(patient)} Time Elapsed: {timer.Elapsed}"); return(new RequestResult <Patient>() { ResultStatus = ResultType.Success, ResourcePayload = patient, }); } catch (CommunicationException e) { this.logger.LogError(e.ToString()); return(new RequestResult <Patient>() { ResultStatus = ResultType.Error, ResultError = new RequestResultError() { ResultMessage = "Communication Exception when trying to retrieve the PHN", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.ClientRegistries) }, }); } }
/// <inheritdoc/> public async Task <RequestResult <IList <MedicationRequest> > > GetMedicationRequestsAsync(string phn) { using (Source.StartActivity("GetMedicationRequestsAsync")) { RequestResult <IList <MedicationRequest> > retVal = new() { ResultStatus = Common.Constants.ResultType.Error, }; string?accessToken = this.authDelegate.AuthenticateAsUser(this.salesforceConfig.TokenUri, this.salesforceConfig.ClientAuthentication).AccessToken; if (string.IsNullOrEmpty(accessToken)) { this.logger.LogError($"Authenticated as User System access token is null or emtpy, Error:\n{accessToken}"); retVal.ResultStatus = Common.Constants.ResultType.Error; retVal.ResultError = new RequestResultError() { ResultMessage = $"Unable to authenticate to retrieve Medication Requests", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.SF) }; return(retVal); } else { this.logger.LogDebug($"Getting Medication Requests..."); using HttpClient client = this.httpClientService.CreateDefaultHttpClient(); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json)); client.DefaultRequestHeaders.Add("phn", phn); try { Uri endpoint = new Uri(this.salesforceConfig.Endpoint); HttpResponseMessage response = await client.GetAsync(endpoint).ConfigureAwait(true); string payload = await response.Content.ReadAsStringAsync().ConfigureAwait(true); this.logger.LogTrace($"Response: {response}"); switch (response.StatusCode) { case HttpStatusCode.OK: var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, IgnoreNullValues = true, WriteIndented = true, }; this.logger.LogTrace($"Response payload: {payload}"); Models.Salesforce.ResponseWrapper?replyWrapper = JsonSerializer.Deserialize <Models.Salesforce.ResponseWrapper>(payload, options); if (replyWrapper != null) { retVal.ResultStatus = Common.Constants.ResultType.Success; retVal.ResourcePayload = replyWrapper.ToHGModels(); retVal.TotalResultCount = replyWrapper.Items.Count; retVal.PageSize = replyWrapper.Items.Count; retVal.PageIndex = 0; } else { retVal.ResultError = new RequestResultError() { ResultMessage = "Error with JSON data", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.SF) }; } break; case HttpStatusCode.NoContent: // No Medication Requests exits for this user retVal.ResultStatus = Common.Constants.ResultType.Success; retVal.ResourcePayload = new List <MedicationRequest>(); retVal.TotalResultCount = 0; retVal.PageSize = 0; break; case HttpStatusCode.Forbidden: retVal.ResultError = new RequestResultError() { ResultMessage = $"DID Claim is missing or can not resolve PHN, HTTP Error {response.StatusCode}", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.SF) }; break; default: retVal.ResultError = new RequestResultError() { ResultMessage = $"Unable to connect to Medication Requests endpoint, HTTP Error {response.StatusCode}", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.SF) }; this.logger.LogError($"Unable to connect to endpoint {endpoint}, HTTP Error {response.StatusCode}\n{payload}"); break; } } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception e) #pragma warning restore CA1031 // Do not catch general exception types { retVal.ResultError = new RequestResultError() { ResultMessage = $"Exception getting Medication Requests: {e}", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.SF) }; this.logger.LogError($"Unexpected exception in GetMedicationRequestsAsync {e}"); } } this.logger.LogDebug($"Finished getting Medication Requests"); return(retVal); } }
/// <inheritdoc /> public RequestResult <DependentModel> AddDependent(string delegateHdId, AddDependentRequest addDependentRequest) { this.logger.LogTrace($"Dependent hdid: {delegateHdId}"); int?maxDependentAge = this.configurationService.GetConfiguration().WebClient.MaxDependentAge; if (maxDependentAge.HasValue) { DateTime minimumBirthDate = DateTime.UtcNow.AddYears(maxDependentAge.Value * -1); if (addDependentRequest.DateOfBirth < minimumBirthDate) { return(new RequestResult <DependentModel>() { ResultStatus = ResultType.Error, ResultError = new RequestResultError() { ResultMessage = "Dependent age exceeds the maximum limit", ErrorCode = ErrorTranslator.ServiceError(ErrorType.InvalidState, ServiceType.Patient) }, }); } } this.logger.LogTrace("Getting dependent details..."); RequestResult <PatientModel> patientResult = Task.Run(async() => await this.patientService.GetPatient(addDependentRequest.PHN, PatientIdentifierType.PHN).ConfigureAwait(true)).Result; if (patientResult.ResultStatus == ResultType.Error) { return(new RequestResult <DependentModel>() { ResultStatus = ResultType.Error, ResultError = new RequestResultError() { ResultMessage = "Communication Exception when trying to retrieve the Dependent", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.Patient) }, }); } if (patientResult.ResultStatus == ResultType.ActionRequired) { return(new RequestResult <DependentModel>() { ResultStatus = ResultType.ActionRequired, ResultError = ErrorTranslator.ActionRequired(ErrorMessages.DataMismatch, ActionType.DataMismatch), }); } this.logger.LogDebug($"Finished getting dependent details...{JsonSerializer.Serialize(patientResult)}"); // Verify dependent's details entered by user if (patientResult.ResourcePayload == null || !this.ValidateDependent(addDependentRequest, patientResult.ResourcePayload)) { this.logger.LogDebug($"Dependent information does not match request: {JsonSerializer.Serialize(addDependentRequest)} response: {JsonSerializer.Serialize(patientResult.ResourcePayload)}"); return(new RequestResult <DependentModel>() { ResultStatus = ResultType.ActionRequired, ResultError = ErrorTranslator.ActionRequired(ErrorMessages.DataMismatch, ActionType.DataMismatch), }); } // Verify dependent has HDID if (string.IsNullOrEmpty(patientResult.ResourcePayload.HdId)) { return(new RequestResult <DependentModel>() { ResultStatus = ResultType.ActionRequired, ResultError = ErrorTranslator.ActionRequired(ErrorMessages.InvalidServicesCard, ActionType.NoHdId), }); } string json = JsonSerializer.Serialize(addDependentRequest.TestDate, addDependentRequest.TestDate.GetType()); JsonDocument jsonDoc = JsonDocument.Parse(json); // Insert Dependent to database var dependent = new ResourceDelegate() { ResourceOwnerHdid = patientResult.ResourcePayload.HdId, ProfileHdid = delegateHdId, ReasonCode = ResourceDelegateReason.COVIDLab, ReasonObjectType = addDependentRequest.TestDate.GetType().AssemblyQualifiedName, ReasonObject = jsonDoc, }; DBResult <ResourceDelegate> dbDependent = this.resourceDelegateDelegate.Insert(dependent, true); if (dbDependent.Status == DBStatusCode.Created) { this.logger.LogTrace("Finished adding dependent"); this.UpdateNotificationSettings(dependent.ResourceOwnerHdid, delegateHdId); return(new RequestResult <DependentModel>() { ResourcePayload = DependentModel.CreateFromModels(dbDependent.Payload, patientResult.ResourcePayload), ResultStatus = ResultType.Success, }); } else { this.logger.LogError("Error adding dependent"); return(new RequestResult <DependentModel>() { ResourcePayload = new DependentModel(), ResultStatus = ResultType.Error, ResultError = new RequestResultError() { ResultMessage = dbDependent.Message, ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database) }, }); } }
/// <inheritdoc/> public async Task <RequestResult <NotificationSettingsResponse> > GetNotificationSettings(string bearerToken) { RequestResult <NotificationSettingsResponse> retVal = new RequestResult <NotificationSettingsResponse>() { ResultStatus = Common.Constants.ResultType.Error, }; Stopwatch timer = new Stopwatch(); timer.Start(); this.logger.LogTrace($"Getting Notification Settings from PHSA..."); using HttpClient client = this.httpClientService.CreateDefaultHttpClient(); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", bearerToken); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json)); try { Uri endpoint = new Uri(this.nsConfig.Endpoint); HttpResponseMessage response = await client.GetAsync(endpoint).ConfigureAwait(true); string payload = await response.Content.ReadAsStringAsync().ConfigureAwait(true); switch (response.StatusCode) { case HttpStatusCode.OK: var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, IgnoreNullValues = true, WriteIndented = true, }; NotificationSettingsResponse?notificationSettings = JsonSerializer.Deserialize <NotificationSettingsResponse>(payload, options); if (notificationSettings != null) { retVal.ResultStatus = Common.Constants.ResultType.Success; retVal.ResourcePayload = notificationSettings; retVal.TotalResultCount = 1; } else { retVal.ResultError = new RequestResultError() { ResultMessage = "Error with JSON data", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.PHSA) }; } break; case HttpStatusCode.NoContent: // No Notification Settings exits for this user retVal.ResultStatus = Common.Constants.ResultType.Success; retVal.ResourcePayload = new NotificationSettingsResponse(); retVal.TotalResultCount = 0; break; case HttpStatusCode.Forbidden: // TODO: Parse Problem Details. this.logger.LogError($"Error Details: {payload}"); retVal.ResultError = new RequestResultError() { ResultMessage = $"DID Claim is missing or can not resolve PHN, HTTP Error {response.StatusCode}", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.PHSA) }; break; default: retVal.ResultError = new RequestResultError() { ResultMessage = $"Unable to connect to Notification Settings Endpoint, HTTP Error {response.StatusCode}", ErrorCode = ErrorTranslator.ServiceError(ErrorType.SMSInvalid, ServiceType.PHSA) }; this.logger.LogError($"Unable to connect to endpoint {endpoint}, HTTP Error {response.StatusCode}\n{payload}"); break; } } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception e) #pragma warning restore CA1031 // Do not catch general exception types { retVal.ResultError = new RequestResultError() { ResultMessage = $"Exception getting Notification Settings: {e}", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.PHSA) }; this.logger.LogError($"Unexpected exception in GetNotificationSettings {e}"); } timer.Stop(); this.logger.LogDebug($"Finished getting Notification Settings, Time Elapsed: {timer.Elapsed}"); return(retVal); }
/// <inheritdoc/> public async Task <RequestResult <NotificationSettingsResponse> > SetNotificationSettings(NotificationSettingsRequest notificationSettings, string bearerToken) { RequestResult <NotificationSettingsResponse> retVal = new RequestResult <NotificationSettingsResponse>() { ResultStatus = Common.Constants.ResultType.Error, }; Stopwatch timer = new Stopwatch(); timer.Start(); this.logger.LogDebug($"Sending Notification Settings to PHSA..."); this.logger.LogTrace($"Bearer token: {bearerToken}"); using HttpClient client = this.httpClientService.CreateDefaultHttpClient(); client.DefaultRequestHeaders.Clear(); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", bearerToken); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json)); client.DefaultRequestHeaders.Add(SubjectResourceHeader, notificationSettings.SubjectHdid); try { Uri endpoint = new Uri(this.nsConfig.Endpoint); var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, IgnoreNullValues = true, WriteIndented = true, }; string json = JsonSerializer.Serialize(notificationSettings, options); using HttpContent content = new StringContent(json, Encoding.UTF8, MediaTypeNames.Application.Json); this.logger.LogTrace($"Http content: {json}"); HttpResponseMessage response = await client.PutAsync(endpoint, content).ConfigureAwait(true); string payload = await response.Content.ReadAsStringAsync().ConfigureAwait(true); switch (response.StatusCode) { case HttpStatusCode.Created: case HttpStatusCode.OK: NotificationSettingsResponse?nsResponse = JsonSerializer.Deserialize <NotificationSettingsResponse>(payload, options); retVal.ResultStatus = Common.Constants.ResultType.Success; retVal.TotalResultCount = 1; retVal.ResourcePayload = nsResponse; break; case HttpStatusCode.UnprocessableEntity: retVal.ResultStatus = Constants.ResultType.ActionRequired; this.logger.LogInformation($"PHSA has indicated that the SMS number is invalid: {notificationSettings.SMSNumber}"); retVal.ResultError = new RequestResultError() { ResultMessage = $"PHSA has indicated that the SMS number is invalid: {notificationSettings.SMSNumber}", ErrorCode = ErrorTranslator.ServiceError(ErrorType.SMSInvalid, ServiceType.PHSA) }; break; case HttpStatusCode.BadRequest: this.logger.LogError($"Error Details: {payload}"); retVal.ResultError = new RequestResultError() { ResultMessage = $"Bad Request, HTTP Error {response.StatusCode}\nDetails:\n{payload}", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.PHSA) }; break; case HttpStatusCode.Forbidden: this.logger.LogError($"Error Details: {payload}"); retVal.ResultError = new RequestResultError() { ResultMessage = $"DID Claim is missing or can not resolve PHN, HTTP Error {response.StatusCode}", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.PHSA) }; break; default: retVal.ResultError = new RequestResultError() { ResultMessage = $"Unable to connect to Notification Settings Endpoint, HTTP Error {response.StatusCode}", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.PHSA) }; this.logger.LogError($"Unable to connect to endpoint {endpoint}, HTTP Error {response.StatusCode}\n{payload}"); break; } } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception e) #pragma warning restore CA1031 // Do not catch general exception types { retVal.ResultError = new RequestResultError() { ResultMessage = $"Exception getting Notification Settings: {e}", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.PHSA) }; this.logger.LogError($"Unexpected exception in GetNotificationSettings {e}"); } timer.Stop(); this.logger.LogDebug($"Finished getting Notification Settings, Time Elapsed: {timer.Elapsed}"); return(retVal); }
/// <inheritdoc /> public async System.Threading.Tasks.Task <RequestResult <PatientModel> > GetDemographicsByPHNAsync(string phn) { using (Source.StartActivity("GetDemographicsByPHNAsync")) { // Create request object HCIM_IN_GetDemographicsRequest request = CreateRequest(OIDType.PHN, phn); try { // Perform the request HCIM_IN_GetDemographicsResponse1 reply = await this.clientRegistriesClient.HCIM_IN_GetDemographicsAsync(request).ConfigureAwait(true); return(this.ParseResponse(reply)); } catch (CommunicationException e) { this.logger.LogError(e.ToString()); return(new RequestResult <PatientModel>() { ResultStatus = ResultType.Error, ResultError = new RequestResultError() { ResultMessage = "Communication Exception when trying to retrieve the patient information from PHN", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.ClientRegistries) }, }); } } }
public void ValidateSetNotificationSettings403() { RequestResult <NotificationSettingsRequest> expected = new RequestResult <NotificationSettingsRequest>() { ResultStatus = Common.Constants.ResultType.Error, ResultError = new RequestResultError() { ResultMessage = "DID Claim is missing or can not resolve PHN, HTTP Error Forbidden", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.PHSA) }, }; NotificationSettingsRequest notificationSettings = new NotificationSettingsRequest() { SMSEnabled = true, SMSNumber = "5551231234", SMSScope = new List <NotificationTarget> { NotificationTarget.Covid19, }, EmailEnabled = true, EmailAddress = "*****@*****.**", EmailScope = new List <NotificationTarget> { NotificationTarget.Covid19, }, }; var handlerMock = new Mock <HttpMessageHandler>(); handlerMock .Protected() .Setup <Task <HttpResponseMessage> >( "SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>() ) .ReturnsAsync(new HttpResponseMessage() { StatusCode = HttpStatusCode.Forbidden, Content = new StringContent(string.Empty), }) .Verifiable(); using var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()); Mock <IHttpClientService> mockHttpClientService = new Mock <IHttpClientService>(); mockHttpClientService.Setup(s => s.CreateDefaultHttpClient()).Returns(() => new HttpClient(handlerMock.Object)); INotificationSettingsDelegate nsDelegate = new RestNotificationSettingsDelegate(loggerFactory.CreateLogger <RestNotificationSettingsDelegate>(), mockHttpClientService.Object, this.configuration); RequestResult <NotificationSettingsResponse> actualResult = Task.Run(async() => await nsDelegate.SetNotificationSettings(notificationSettings, string.Empty)).Result; Assert.True(actualResult.IsDeepEqual(expected)); }
/// <inheritdoc /> public async Task <RequestResult <UserProfileModel> > CreateUserProfile(CreateUserRequest createProfileRequest, DateTime jwtAuthTime) { this.logger.LogTrace($"Creating user profile... {JsonSerializer.Serialize(createProfileRequest)}"); string registrationStatus = this.configurationService.GetConfiguration().WebClient.RegistrationStatus; if (registrationStatus == RegistrationStatus.Closed) { this.logger.LogWarning($"Registration is closed. {JsonSerializer.Serialize(createProfileRequest)}"); return(new RequestResult <UserProfileModel>() { ResultStatus = ResultType.Error, ResultError = new RequestResultError() { ResultMessage = "Registration is closed", ErrorCode = ErrorTranslator.InternalError(ErrorType.InvalidState), }, }); } // Validate registration age string hdid = createProfileRequest.Profile.HdId; PrimitiveRequestResult <bool> isMimimunAgeResult = await this.ValidateMinimumAge(hdid).ConfigureAwait(true); if (isMimimunAgeResult.ResultStatus != ResultType.Success) { return(new RequestResult <UserProfileModel>() { ResultStatus = isMimimunAgeResult.ResultStatus, ResultError = isMimimunAgeResult.ResultError, }); } else if (!isMimimunAgeResult.ResourcePayload) { this.logger.LogWarning($"Patient under minimum age. {JsonSerializer.Serialize(createProfileRequest)}"); return(new RequestResult <UserProfileModel>() { ResultStatus = ResultType.Error, ResultError = new RequestResultError() { ResultMessage = "Patient under minimum age", ErrorCode = ErrorTranslator.InternalError(ErrorType.InvalidState), }, }); } // Create profile UserProfile newProfile = new () { HdId = hdid, IdentityManagementId = createProfileRequest.Profile.IdentityManagementId, AcceptedTermsOfService = createProfileRequest.Profile.AcceptedTermsOfService, Email = string.Empty, SMSNumber = null, CreatedBy = hdid, UpdatedBy = hdid, LastLoginDateTime = jwtAuthTime, EncryptionKey = this.cryptoDelegate.GenerateKey(), }; DBResult <UserProfile> insertResult = this.userProfileDelegate.InsertUserProfile(newProfile); if (insertResult.Status == DBStatusCode.Created) { UserProfile createdProfile = insertResult.Payload; string? requestedSMSNumber = createProfileRequest.Profile.SMSNumber; string? requestedEmail = createProfileRequest.Profile.Email; // Add email verification if (!string.IsNullOrWhiteSpace(requestedEmail)) { this.userEmailService.CreateUserEmail(hdid, requestedEmail); } // Add SMS verification if (!string.IsNullOrWhiteSpace(requestedSMSNumber)) { this.userSMSService.CreateUserSMS(hdid, requestedSMSNumber); } this.notificationSettingsService.QueueNotificationSettings(new NotificationSettingsRequest(createdProfile, requestedEmail, requestedSMSNumber)); this.logger.LogDebug($"Finished creating user profile. {JsonSerializer.Serialize(insertResult)}"); return(new RequestResult <UserProfileModel>() { ResourcePayload = UserProfileModel.CreateFromDbModel(insertResult.Payload), ResultStatus = ResultType.Success, }); } else { this.logger.LogError($"Error creating user profile. {JsonSerializer.Serialize(insertResult)}"); return(new RequestResult <UserProfileModel>() { ResultStatus = ResultType.Error, ResultError = new RequestResultError() { ResultMessage = insertResult.Message, ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database), }, }); } }
/// <inheritdoc /> public RequestResult <DependentModel> AddDependent(string delegateHdId, AddDependentRequest addDependentRequest) { this.logger.LogTrace($"Dependent hdid: {delegateHdId}"); this.logger.LogDebug("Getting dependent details..."); RequestResult <PatientModel> patientResult = Task.Run(async() => await this.patientService.GetPatient(addDependentRequest.PHN, PatientIdentifierType.PHN).ConfigureAwait(true)).Result; if (patientResult.ResourcePayload == null) { return(new RequestResult <DependentModel>() { ResultStatus = ResultType.Error, ResultError = new RequestResultError() { ResultMessage = "Communication Exception when trying to retrieve the Dependent", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.Patient) }, }); } // Verify dependent's details entered by user if (!addDependentRequest.Equals(patientResult.ResourcePayload)) { return(new RequestResult <DependentModel>() { ResultStatus = ResultType.Error, ResultError = new RequestResultError() { ResultMessage = "The information you entered did not match. Please try again.", ErrorCode = ErrorTranslator.ServiceError(ErrorType.InvalidState, ServiceType.Patient) }, }); } else { // Insert Dependent to database var dependent = new UserDelegate() { OwnerId = patientResult.ResourcePayload.HdId, DelegateId = delegateHdId }; DBResult <UserDelegate> dbDependent = this.userDelegateDelegate.Insert(dependent, true); if (dbDependent.Status == DBStatusCode.Created) { this.logger.LogDebug("Finished adding dependent"); this.UpdateNotificationSettings(dependent.OwnerId, delegateHdId); return(new RequestResult <DependentModel>() { ResourcePayload = DependentModel.CreateFromModels(dbDependent.Payload, patientResult.ResourcePayload), ResultStatus = ResultType.Success, }); } else { this.logger.LogError("Error adding dependent"); return(new RequestResult <DependentModel>() { ResourcePayload = new DependentModel(), ResultStatus = ResultType.Error, ResultError = new RequestResultError() { ResultMessage = dbDependent.Message, ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database) }, }); } } }