Skip to content

Commit da49f16

Browse files
Merge branch 'main' into feat/DTOSS-8367-get-acess-token-from-singedJWT
2 parents d0835eb + 6d372b2 commit da49f16

23 files changed

Lines changed: 427 additions & 1530 deletions

File tree

.azuredevops/pipelines/acr-image-promote-dev-to-nft.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ stages:
4141
jobs:
4242
- job: re_tag
4343
pool:
44-
name: private-pool-prod-uks
44+
name: private-pool-dev-uks
4545
displayName: Update/copy Docker images with new tag
4646
variables:
4747
- group: NFT_image_pipelines

.azuredevops/pipelines/acr-image-promote-nft-to-integration.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ stages:
4141
jobs:
4242
- job: re_tag
4343
pool:
44-
name: private-pool-prod-uks
44+
name: private-pool-dev-uks
4545
displayName: Update/copy Docker images with new tag
4646
variables:
4747
- group: INT_image_pipelines

application/CohortManager/compose.cohort-distribution.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ services:
2121
- LookupValidationURL=http://lookup-validation:7075/api/LookupValidation
2222
- StaticValidationURL=http://static-validation:7074/api/StaticValidation
2323
- ParticipantDemographicDataServiceURL=http://participant-demographic-data-service:7993/api/ParticipantDemographicDataService
24+
- RemoveOldValidationRecordUrl=http://remove-validation-exception-data:7085/api/RemoveValidationExceptionData
2425
- IgnoreParticipantExceptions=false
2526
- IsExtractedToBSSelect=true
2627

application/CohortManager/compose.core.yaml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ services:
156156
build:
157157
context: ./src/Functions/
158158
dockerfile: ExceptionHandling/UpdateException/Dockerfile
159+
profiles: [non-essential]
159160
environment:
160161
- ASPNETCORE_URLS=http://*:7070
161162
- DtOsDatabaseConnectionString=Server=db,1433;Database=${DB_NAME};User Id=SA;Password=${PASSWORD};TrustServerCertificate=True
@@ -187,11 +188,8 @@ services:
187188
dockerfile: ScreeningValidationService/StaticValidation/Dockerfile
188189
environment:
189190
- ASPNETCORE_URLS=http://*:7074
190-
- CreateValidationExceptionURL=http://create-exception:7070/api/CreateValidationException
191-
- BlobContainerName=rules
192-
- AzureWebJobsStorage=${AZURITE_CONNECTION_STRING}
193191
- ExceptionFunctionURL=http://create-exception:7070/api/CreateException
194-
- RemoveOldValidationRecord=http://remove-validation-exception-data:7085/api/RemoveValidationExceptionData
192+
- AzureWebJobsStorage=${AZURITE_CONNECTION_STRING}
195193

196194
lookup-validation:
197195
container_name: lookup-validation

application/CohortManager/src/Functions/CohortDistributionServices/DistributeParticipant/DistributeParticipantConfig.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ public class DistributeParticipantConfig
88
public string CohortDistributionTopic { get; set; }
99
[Required]
1010
public string DistributeParticipantSubscription { get; set; }
11-
public bool IgnoreParticipantExceptions { get; set; } = false;
1211
[Required]
1312
public string LookupValidationURL { get; set; }
1413
[Required]
@@ -21,5 +20,8 @@ public class DistributeParticipantConfig
2120
public string CohortDistributionDataServiceUrl { get; set; }
2221
[Required]
2322
public string ParticipantDemographicDataServiceUrl { get; set; }
23+
[Required]
24+
public string RemoveOldValidationRecordUrl { get; set; }
2425
public bool IsExtractedToBSSelect { get; set; } = false;
26+
public bool IgnoreParticipantExceptions { get; set; } = false;
2527
}

application/CohortManager/src/Functions/CohortDistributionServices/DistributeParticipant/ValidateParticipant.cs

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ namespace NHS.CohortManager.CohortDistributionServices;
1010
using Model.Enums;
1111
using DataServices.Client;
1212
using Microsoft.Extensions.Options;
13+
using Newtonsoft.Json.Linq;
14+
using RulesEngine.Models;
1315

1416
public class ValidateParticipant
1517
{
@@ -36,7 +38,7 @@ public ValidateParticipant(IDataServiceClient<CohortDistribution> cohortDistribu
3638
}
3739

3840
/// <summary>
39-
/// Orchestration for the validation and trasnformation process
41+
/// Orchestrator for the validation and trasnformation process
4042
/// </summary>
4143
/// <param name="context">Context containing a validation record</param>
4244
/// <returns>The transformed <see cref="CohortDistributionParticipant"/>, or null if the validation/ transformation failed</returns>
@@ -52,21 +54,28 @@ public ValidateParticipant(IDataServiceClient<CohortDistribution> cohortDistribu
5254
var previousRecord = await context.CallActivityAsync<CohortDistributionParticipant>(nameof(GetCohortDistributionRecord), validationRecord.Participant.ParticipantId);
5355
validationRecord.PreviousParticipantRecord = previousRecord;
5456

57+
// Remove Previous Validation Errors from DB
58+
await context.CallActivityAsync( nameof(RemoveOldValidationExceptions), new OldExceptionRecord()
59+
{
60+
NhsNumber = validationRecord.Participant.NhsNumber,
61+
ScreeningName = validationRecord.Participant.ScreeningName
62+
});
63+
5564
// Lookup & Static Validation
5665
_logger.LogInformation("Validating participant");
57-
ValidationExceptionLog[] validationResults = await Task.WhenAll(
58-
context.CallActivityAsync<ValidationExceptionLog>(nameof(StaticValidation), validationRecord),
59-
context.CallActivityAsync<ValidationExceptionLog>(nameof(LookupValidation), validationRecord)
60-
);
66+
var staticTask = context.CallActivityAsync<List<ValidationRuleResult>>(nameof(StaticValidation), validationRecord);
67+
var lookupTask = context.CallActivityAsync<List<ValidationRuleResult>>(nameof(LookupValidation), validationRecord);
68+
69+
await Task.WhenAll(staticTask, lookupTask);
6170

62-
var validationResult = new ValidationExceptionLog(validationResults[0], validationResults[1]);
71+
var validationResult = staticTask.Result.Concat(lookupTask.Result).ToList();
6372

6473
// Update exception flag and return
65-
if (validationResult.CreatedException)
74+
if (validationResult.Any())
6675
{
67-
_logger.LogError("Participant {ParticipantId} triggered a validation rule", validationRecord.Participant.ParticipantId);
76+
_logger.LogWarning("Participant {ParticipantId} triggered a validation rule", validationRecord.Participant.ParticipantId);
6877

69-
await context.CallActivityAsync(nameof(UpdateExceptionFlag), validationRecord.Participant.ParticipantId);
78+
await context.CallActivityAsync(nameof(HandleValidationExceptions), new ValidationExceptionRecord(validationRecord, validationResult));
7079

7180
if (!_config.IgnoreParticipantExceptions)
7281
{
@@ -115,13 +124,23 @@ public async Task<CohortDistributionParticipant> GetCohortDistributionRecord([Ac
115124
}
116125
}
117126

127+
/// <summary>
128+
/// Calls the remove old validation exception function
129+
/// </summary>
130+
[Function(nameof(RemoveOldValidationExceptions))]
131+
public async Task RemoveOldValidationExceptions([ActivityTrigger] OldExceptionRecord request)
132+
{
133+
string json = JsonSerializer.Serialize(request);
134+
await _httpClient.SendPost(_config.RemoveOldValidationRecordUrl, json);
135+
}
136+
118137
/// <summary>
119138
/// Calls static validation
120139
/// </summary>
121140
/// <param name="validationRecord"></param>
122141
/// <returns>A <see cref="ValidationExceptionLog"/> representing if the participant has triggered a rule</returns>
123142
[Function(nameof(StaticValidation))]
124-
public async Task<ValidationExceptionLog> StaticValidation([ActivityTrigger] ValidationRecord validationRecord)
143+
public async Task<List<ValidationRuleResult>?> StaticValidation([ActivityTrigger] ValidationRecord validationRecord)
125144
{
126145
var request = new ParticipantCsvRecord
127146
{
@@ -133,9 +152,14 @@ public async Task<ValidationExceptionLog> StaticValidation([ActivityTrigger] Val
133152

134153
var response = await _httpClient.SendPost(_config.StaticValidationURL, json);
135154
response.EnsureSuccessStatusCode();
155+
156+
if (response.StatusCode == HttpStatusCode.NoContent)
157+
{
158+
return new List<ValidationRuleResult>();
159+
}
136160
string body = await _httpClient.GetResponseText(response);
137161

138-
var exceptionLog = JsonSerializer.Deserialize<ValidationExceptionLog>(body);
162+
var exceptionLog = JsonSerializer.Deserialize<List<ValidationRuleResult>>(body);
139163

140164
return exceptionLog;
141165
}
@@ -146,7 +170,7 @@ public async Task<ValidationExceptionLog> StaticValidation([ActivityTrigger] Val
146170
/// <param name="validationRecord"></param>
147171
/// <returns>A <see cref="ValidationExceptionLog"/> representing if the participant has triggered a rule</returns>
148172
[Function(nameof(LookupValidation))]
149-
public async Task<ValidationExceptionLog> LookupValidation([ActivityTrigger] ValidationRecord validationRecord)
173+
public async Task<List<ValidationRuleResult>> LookupValidation([ActivityTrigger] ValidationRecord validationRecord)
150174
{
151175
var request = new LookupValidationRequestBody
152176
{
@@ -159,9 +183,14 @@ public async Task<ValidationExceptionLog> LookupValidation([ActivityTrigger] Val
159183

160184
var response = await _httpClient.SendPost(_config.LookupValidationURL, json);
161185
response.EnsureSuccessStatusCode();
186+
if (response.StatusCode == HttpStatusCode.NoContent)
187+
{
188+
return new List<ValidationRuleResult>();
189+
}
190+
162191
string body = await _httpClient.GetResponseText(response);
163192

164-
var exceptionLog = JsonSerializer.Deserialize<ValidationExceptionLog>(body);
193+
var exceptionLog = JsonSerializer.Deserialize<List<ValidationRuleResult>>(body);
165194
return exceptionLog;
166195
}
167196

@@ -194,20 +223,30 @@ public async Task<ValidationExceptionLog> LookupValidation([ActivityTrigger] Val
194223
}
195224

196225
/// <summary>
197-
/// Updates the exception flag in participant management
226+
/// Creates a validation excpetion and updates the exception flag
227+
/// in participant management
198228
/// </summary>
199-
/// <param name="participantId"></param>
200229
/// <exception cref="IOException">Thrown if the update fails</exception>
201-
[Function(nameof(UpdateExceptionFlag))]
202-
public async Task UpdateExceptionFlag([ActivityTrigger] string participantId)
230+
[Function(nameof(HandleValidationExceptions))]
231+
public async Task HandleValidationExceptions([ActivityTrigger] ValidationExceptionRecord validationExceptionRecord)
203232
{
204-
var participantManagement = await _participantManagementClient.GetSingle(participantId);
233+
// Send exceptions to DB
234+
ParticipantCsvRecord participantRecord = new()
235+
{
236+
Participant = new Participant(validationExceptionRecord.ValidationRecord.Participant),
237+
FileName = validationExceptionRecord.ValidationRecord.FileName
238+
};
239+
240+
var exceptionCreated = await _exceptionHandler.CreateValidationExceptionLog(validationExceptionRecord.ValidationExceptions, participantRecord);
241+
242+
var participantManagement = await _participantManagementClient.GetSingle(participantRecord.Participant.ParticipantId);
205243
participantManagement.ExceptionFlag = 1;
206244

207245
var exceptionFlagUpdated = await _participantManagementClient.Update(participantManagement);
208246
if (!exceptionFlagUpdated)
209247
{
210248
throw new IOException("Failed to update exception flag");
211249
}
250+
_logger.LogInformation("Created validation exception and set exception flag to 1 for participant {ParticipantId}", participantRecord.Participant.ParticipantId);
212251
}
213252
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
namespace NHS.CohortManager.CohortDistributionServices;
2+
3+
using Model;
4+
5+
/// <summary>
6+
/// Wrapper needed for handling validation exceptions
7+
/// (you cannot pass in mutiple params to durable function activites)
8+
/// </summary>
9+
public class ValidationExceptionRecord
10+
{
11+
public ValidationRecord ValidationRecord { get; set; }
12+
public List<ValidationRuleResult> ValidationExceptions { get; set; }
13+
14+
public ValidationExceptionRecord(ValidationRecord validationRecord, List<ValidationRuleResult> validationExceptions)
15+
{
16+
ValidationRecord = validationRecord;
17+
ValidationExceptions = validationExceptions;
18+
}
19+
}

application/CohortManager/src/Functions/ScreeningValidationService/LookupValidation/LookupValidation.cs

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -95,25 +95,15 @@ public async Task<HttpResponseData> RunAsync([HttpTrigger(AuthorizationLevel.Ano
9595
}
9696

9797
// Validation rules are logically reversed
98-
var validationErrors = resultList.Where(x => !x.IsSuccess);
98+
var validationErrors = resultList.Where(x => !x.IsSuccess).Select(x => new ValidationRuleResult(x));
9999

100100
if (validationErrors.Any())
101101
{
102-
_logger.LogInformation("There was an error in the Validation Rules");
103-
var participantCsvRecord = new ParticipantCsvRecord()
104-
{
105-
Participant = newParticipant,
106-
FileName = requestBody.FileName
107-
};
108-
var exceptionCreated = await _handleException.CreateValidationExceptionLog(validationErrors, participantCsvRecord);
109-
return _createResponse.CreateHttpResponse(HttpStatusCode.Created, req, JsonSerializer.Serialize(exceptionCreated));
102+
string errors = JsonSerializer.Serialize(validationErrors);
103+
return _createResponse.CreateHttpResponse(HttpStatusCode.OK, req, errors);
110104
}
111105

112-
return _createResponse.CreateHttpResponse(HttpStatusCode.OK, req, JsonSerializer.Serialize(new ValidationExceptionLog()
113-
{
114-
IsFatal = false,
115-
CreatedException = false
116-
}));
106+
return _createResponse.CreateHttpResponse(HttpStatusCode.NoContent, req);
117107
}
118108
catch (Exception ex)
119109
{

application/CohortManager/src/Functions/ScreeningValidationService/StaticValidation/Program.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33
using HealthChecks.Extensions;
44
using Microsoft.Extensions.DependencyInjection;
55
using Microsoft.Extensions.Hosting;
6-
using NHS.Screening.StaticValidation;
76

87
var host = new HostBuilder()
9-
.AddConfiguration<StaticValidationConfig>(out StaticValidationConfig config)
108
.ConfigureFunctionsWorkerDefaults()
119
.ConfigureServices(services =>
1210
{

application/CohortManager/src/Functions/ScreeningValidationService/StaticValidation/StaticValidation.cs

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,22 @@ namespace NHS.CohortManager.ScreeningValidationService;
1212
using Microsoft.Extensions.Options;
1313
using Model;
1414
using Model.Enums;
15-
using NHS.Screening.StaticValidation;
1615
using RulesEngine.Models;
1716

1817
public class StaticValidation
1918
{
2019
private readonly ILogger<StaticValidation> _logger;
2120
private readonly ICreateResponse _createResponse;
22-
private readonly IExceptionHandler _handleException;
2321
private readonly IReadRules _readRules;
24-
private readonly IHttpClientFunction _httpClientFunction;
25-
private readonly StaticValidationConfig _config;
2622

2723
public StaticValidation(
2824
ILogger<StaticValidation> logger,
29-
IExceptionHandler handleException,
3025
ICreateResponse createResponse,
31-
IReadRules readRules,
32-
IHttpClientFunction httpClientFunction,
33-
IOptions<StaticValidationConfig> staticValidationConfig)
26+
IReadRules readRules)
3427
{
3528
_logger = logger;
36-
_handleException = handleException;
3729
_createResponse = createResponse;
3830
_readRules = readRules;
39-
_httpClientFunction = httpClientFunction;
40-
_config = staticValidationConfig.Value;
4131
}
4232

4333
// TODO: refactor to accept a cohort distribution participant
@@ -69,7 +59,7 @@ public async Task<HttpResponseData> RunAsync([HttpTrigger(AuthorizationLevel.Ano
6959
var re = new RulesEngine.RulesEngine(rules, reSettings);
7060

7161
var ruleParameters = new[] {
72-
new RuleParameter("participant", participantCsvRecord.Participant),
62+
new RuleParameter("participant", participantCsvRecord.Participant)
7363
};
7464
var resultList = await re.ExecuteAllRulesAsync("Common", ruleParameters);
7565

@@ -80,35 +70,20 @@ public async Task<HttpResponseData> RunAsync([HttpTrigger(AuthorizationLevel.Ano
8070
resultList.AddRange(ActionResults);
8171
}
8272

83-
var validationErrors = resultList.Where(x => !x.IsSuccess);
73+
var validationErrors = resultList.Where(x => !x.IsSuccess).Select(x => new ValidationRuleResult(x));
8474

85-
await RemoveOldValidationRecord(participantCsvRecord.Participant.NhsNumber, participantCsvRecord.Participant.ScreeningName);
8675
if (validationErrors.Any())
8776
{
88-
var createExceptionLogResponse = await _handleException.CreateValidationExceptionLog(validationErrors, participantCsvRecord);
89-
return _createResponse.CreateHttpResponse(HttpStatusCode.Created, req, JsonSerializer.Serialize(createExceptionLogResponse));
77+
string errors = JsonSerializer.Serialize(validationErrors);
78+
return _createResponse.CreateHttpResponse(HttpStatusCode.OK, req, errors);
9079
}
9180

92-
return _createResponse.CreateHttpResponse(HttpStatusCode.OK, req, JsonSerializer.Serialize(new ValidationExceptionLog()
93-
{
94-
IsFatal = false,
95-
CreatedException = false
96-
}));
81+
return _createResponse.CreateHttpResponse(HttpStatusCode.NoContent, req);
9782
}
9883
catch (Exception ex)
9984
{
10085
_logger.LogError(ex, ex.Message);
10186
return _createResponse.CreateHttpResponse(HttpStatusCode.InternalServerError, req);
10287
}
10388
}
104-
105-
private async Task RemoveOldValidationRecord(string nhsNumber, string screeningName)
106-
{
107-
var OldExceptionRecordJson = JsonSerializer.Serialize(new OldExceptionRecord()
108-
{
109-
NhsNumber = nhsNumber,
110-
ScreeningName = screeningName
111-
});
112-
await _httpClientFunction.SendPost(_config.RemoveOldValidationRecord, OldExceptionRecordJson);
113-
}
11489
}

0 commit comments

Comments
 (0)