Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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,
            });
        }
Пример #4
0
        /// <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)
                    },
                });
            }
        }
Пример #5
0
        /// <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);
        }
Пример #6
0
        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));
        }
Пример #7
0
        /// <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);
        }
Пример #8
0
        /// <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);
        }
Пример #9
0
        /// <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);
        }
Пример #10
0
        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,
                });
            }
        }
Пример #12
0
        /// <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);
        }
Пример #13
0
        /// <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);
            }
        }
Пример #14
0
        /// <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);
        }
Пример #16
0
        /// <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)
                    },
                });
            }
        }
Пример #17
0
        /// <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);
            }
        }
Пример #18
0
        /// <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)
                    },
                });
            }
        }
Пример #19
0
        /// <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);
        }
Пример #20
0
        /// <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));
        }
Пример #23
0
        /// <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),
                    },
                });
            }
        }
Пример #24
0
        /// <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)
                        },
                    });
                }
            }
        }