Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace NHS.CohortManager.DemographicServices;

public static class PdsConstants
{
public const string InvalidatedResourceCode = "INVALIDATED_RESOURCE";
public const string OrrRemovalReason = "ORR";
public const string DefaultFileName = "NemsMessages";
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace NHS.Screening.ProcessNemsUpdate;
namespace NHS.CohortManager.DemographicServices;

public class PdsCoding
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace NHS.Screening.ProcessNemsUpdate;
namespace NHS.CohortManager.DemographicServices;

public class PdsErrorResponse
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace NHS.Screening.ProcessNemsUpdate;
namespace NHS.CohortManager.DemographicServices;

public class PdsIssue
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace NHS.Screening.ProcessNemsUpdate;
namespace NHS.CohortManager.DemographicServices;

public class PdsErrorDetails
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@
services.AddSingleton<ICreateResponse, CreateResponse>();
services.AddSingleton<IHttpParserHelper, HttpParserHelper>();
services.AddSingleton<IFhirPatientDemographicMapper, FhirPatientDemographicMapper>();
services.AddSingleton<IAddBatchToQueue, AddBatchToQueue>();
services.AddSingleton<ICreateBasicParticipantData, CreateBasicParticipantData>();
// Register health checks
services.AddBasicHealthCheck("RetrievePdsDemographic");
})
.AddJwtTokenSigning(config.UseFakePDSServices)
.AddTelemetry()
.AddServiceBusClient(config.ServiceBusConnectionString)
.AddHttpClient(config.UseFakePDSServices)
.Build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace NHS.CohortManager.DemographicServices;
using System.Threading.Tasks;
using Model;
using System.Net.Http.Json;
using Hl7.Fhir.Support;
using System.Collections.Concurrent;

public class RetrievePdsDemographic
{
Expand All @@ -24,6 +24,8 @@ public class RetrievePdsDemographic
private readonly IFhirPatientDemographicMapper _fhirPatientDemographicMapper;
private readonly IDataServiceClient<ParticipantDemographic> _participantDemographicClient;
private readonly IBearerTokenService _bearerTokenService;
private readonly ICreateBasicParticipantData _createBasicParticipantData;
private readonly IAddBatchToQueue _addBatchToQueue;
private const string PdsParticipantUrlFormat = "{0}/{1}";


Expand All @@ -34,6 +36,8 @@ public RetrievePdsDemographic(
IFhirPatientDemographicMapper fhirPatientDemographicMapper,
IOptions<RetrievePDSDemographicConfig> retrievePDSDemographicConfig,
IDataServiceClient<ParticipantDemographic> participantDemographicClient,
ICreateBasicParticipantData createBasicParticipantData,
IAddBatchToQueue addBatchToQueue,
IBearerTokenService bearerTokenService
)
{
Expand All @@ -43,7 +47,9 @@ IBearerTokenService bearerTokenService
_fhirPatientDemographicMapper = fhirPatientDemographicMapper;
_config = retrievePDSDemographicConfig.Value;
_participantDemographicClient = participantDemographicClient;
_createBasicParticipantData = createBasicParticipantData;
_bearerTokenService = bearerTokenService;
_addBatchToQueue = addBatchToQueue;
}

// TODO: Need to send an exception to the EXCEPTION_MANAGEMENT table whenever this function returns a non OK status.
Expand Down Expand Up @@ -73,8 +79,8 @@ public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Anonymou

if (response.StatusCode == HttpStatusCode.NotFound)
{
var pdsErrorResponse = await response.Content.ReadAsStringAsync();
return _createResponse.CreateHttpResponse(HttpStatusCode.NotFound, req, pdsErrorResponse);
await ProcessPdsResponse(response, nhsNumber);
return _createResponse.CreateHttpResponse(HttpStatusCode.NotFound, req, "PDS returned a 404 please database for details");
}

response.EnsureSuccessStatusCode();
Expand All @@ -95,6 +101,48 @@ public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Anonymou
}
}

private async Task ProcessPdsResponse(HttpResponseMessage pdsResponse, string nhsNumber)
Comment thread
SamRobinson75684 marked this conversation as resolved.
{
var errorResponse = await pdsResponse!.Content.ReadFromJsonAsync<PdsErrorResponse>();
// we now create a record as an update record and send to the manage participant function. Reason for removal for date should be today and the reason for remove of ORR
if (errorResponse!.issue!.FirstOrDefault()!.details!.coding!.FirstOrDefault()!.code == PdsConstants.InvalidatedResourceCode)
{
var pdsDemographic = new PdsDemographic()
{
NhsNumber = nhsNumber,
PrimaryCareProvider = null,
ReasonForRemoval = PdsConstants.OrrRemovalReason,
RemovalEffectiveFromDate = DateTime.UtcNow.Date.ToString("yyyyMMdd")
};
var participant = new Participant(pdsDemographic);
participant.RecordType = Actions.Removed;
//sends record for an update
await ProcessRecord(participant);
return;
}
_logger.LogError("the PDS function has returned a 404 error. function now stopping processing");
}


private async Task ProcessRecord(Participant participant)
{
var updateRecord = new ConcurrentQueue<BasicParticipantCsvRecord>();
participant.RecordType = participant.RecordType = Actions.Removed;

var basicParticipantCsvRecord = new BasicParticipantCsvRecord
{
BasicParticipantData = _createBasicParticipantData.BasicParticipantData(participant),
FileName = PdsConstants.DefaultFileName,
Participant = participant
};

updateRecord.Enqueue(basicParticipantCsvRecord);

_logger.LogInformation("Sending record to the update queue.");
await _addBatchToQueue.ProcessBatch(updateRecord, _config.ParticipantManagementTopic);
}


private async Task<bool> UpsertDemographicRecordFromPDS(ParticipantDemographic participantDemographic)
{
ParticipantDemographic oldParticipantDemographic = await _participantDemographicClient.GetSingleByFilter(i => i.NhsNumber == participantDemographic.NhsNumber);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ public class RetrievePDSDemographicConfig
[Required]
public required string AuthTokenURL { get; set; }

[Required]
public required string ParticipantManagementTopic { get; set; }

[Required]
public required string ServiceBusConnectionString { get; set; }

public required bool UseFakePDSServices { get; set; } = false;
public string ClientId { get; set; } = string.Empty;
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public async Task Run([BlobTrigger("nems-updates/{name}", Connection = "nemsmesh
var pdsResponse = await RetrievePdsRecord(nhsNumber!);
if (pdsResponse!.StatusCode == System.Net.HttpStatusCode.NotFound)
{
await ProcessPdsResponse(pdsResponse, nhsNumber!);
_logger.LogError("the PDS function has returned a 404 error. function now stopping processing");
// we can stop processing here as we know that not found means the participant ether needed an update or they were actually not found
return;
}
Expand All @@ -102,29 +102,6 @@ public async Task Run([BlobTrigger("nems-updates/{name}", Connection = "nemsmesh

}

private async Task ProcessPdsResponse(HttpResponseMessage pdsResponse, string nhsNumber)
{
var errorResponse = await pdsResponse!.Content.ReadFromJsonAsync<PdsErrorResponse>();
// we now create a record as an update record and send to the manage participant function. Reason for removal for date should be today and the reason for remove of ORR
if (errorResponse!.issue!.FirstOrDefault()!.details!.coding!.FirstOrDefault()!.code == "INVALIDATED_RESOURCE")
{
var pdsDemographic = new PdsDemographic()
{
NhsNumber = nhsNumber,
PrimaryCareProvider = null,
ReasonForRemoval = "ORR",
RemovalEffectiveFromDate = DateTime.UtcNow.Date.ToString("yyyyMMdd")
};
var participant = new Participant(pdsDemographic);
participant.RecordType = Actions.Removed;
//sends record for an update
await ProcessRecord(participant);
return;
}
_logger.LogError("the PDS function has returned a 404 error. function now stopping processing");

}

private async Task UnsubscribeFromNems(string nhsNumber, PdsDemographic retrievedPdsRecord)
{
var supersededRecord = new PdsDemographic()
Expand Down Expand Up @@ -207,7 +184,7 @@ private async Task ProcessRecord(Participant participant)
}
else
{
participant.RecordType = participant.RecordType != Actions.Removed ? Actions.Amended : participant.RecordType;
participant.RecordType = Actions.Amended;
_logger.LogWarning("The participant already exists in Cohort Manager. Existing record will get updated.");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace NHS.CohortManager.Tests.UnitTests.DemographicServicesTests;
using NHS.CohortManager.Tests.TestUtils;
using System.Linq.Expressions;
using Microsoft.Extensions.Caching.Memory;
using System.ComponentModel;

[TestClass]
public class RetrievePdsDemographicTests : DatabaseTestBaseSetup<RetrievePdsDemographic>
Expand All @@ -20,6 +21,8 @@ public class RetrievePdsDemographicTests : DatabaseTestBaseSetup<RetrievePdsDemo
private static readonly Mock<IOptions<RetrievePDSDemographicConfig>> _mockConfig = new();
private static readonly Mock<IFhirPatientDemographicMapper> _mockFhirPatientDemographicMapper = new();
private static readonly Mock<IDataServiceClient<ParticipantDemographic>> _mockParticipantDemographicClient = new();
private static readonly Mock<ICreateBasicParticipantData> _mockCreateBasicParticipantService = new();
private static readonly Mock<IAddBatchToQueue> _mockAddBatchToQueue = new();

private static Mock<IBearerTokenService> _bearerTokenService = new();

Expand All @@ -35,7 +38,10 @@ public RetrievePdsDemographicTests() : base((conn, logger, transaction, command,
_mockFhirPatientDemographicMapper.Object,
_mockConfig.Object,
_mockParticipantDemographicClient.Object,
_bearerTokenService.Object))
_mockCreateBasicParticipantService.Object,
_mockAddBatchToQueue.Object,
_bearerTokenService.Object
))
{
CreateHttpResponseMock();
}
Expand Down
Loading