Skip to content

Commit aa19248

Browse files
Merge branch 'main' into DTOSS-12664-Filter-health-alerts-from-logging
2 parents 975758f + 36f8aae commit aa19248

31 files changed

Lines changed: 2128 additions & 682 deletions

.vscode/tasks.json

Lines changed: 50 additions & 621 deletions
Large diffs are not rendered by default.

application/CohortManager/compose.core.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,20 @@ services:
183183
- CohortDistributionDataServiceURL=http://cohort-distribution-data-service:7992/api/CohortDistributionDataService/
184184
- AcceptableLatencyThresholdMs=500
185185

186+
remove-dummy-gp-code:
187+
container_name: remove-dummy-gp-code
188+
image: cohort-manager-remove-dummy-gp-code
189+
networks: [cohman-network]
190+
build:
191+
context: ./src/Functions/
192+
dockerfile: ParticipantManagementServices/RemoveDummyGPCode/Dockerfile
193+
args:
194+
BASE_IMAGE: ${FUNCTION_BASE_IMAGE}
195+
profiles: [ui]
196+
environment:
197+
- ServiceBusConnectionString_client_internal=Endpoint=sb://service-bus;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;
198+
- ServiceNowParticipantManagementTopic=servicenow-participant-management-topic
199+
- RetrievePdsDemographicURL=http://retrieve-pds-demographic:8082/api/RetrievePDSDemographic
186200

187201
# Screening Data Service
188202
create-exception:
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# Launches every Azure Function in its own Windows Terminal tab.
2+
# Edit the $functions list below to add/remove/reorder functions - it's the single source of truth.
3+
4+
$ErrorActionPreference = "Stop"
5+
$functionsRoot = Resolve-Path (Join-Path $PSScriptRoot "..\src\Functions")
6+
7+
$functions = @(
8+
# ── CaaS Integration ────────────────────────────────────────────────────────
9+
@{ Path = "CaasIntegration\receiveCaasFile"; Port = 7060 },
10+
11+
# ── Participant Management Services ──────────────────────────────────────────
12+
@{ Path = "ParticipantManagementServices\ManageParticipant"; Port = 7061 },
13+
@{ Path = "ParticipantManagementServices\ManageServiceNowParticipant"; Port = 7064 },
14+
@{ Path = "ParticipantManagementServices\UpdateBlockedFlag"; Port = 7027 },
15+
16+
# ── Audit Services ───────────────────────────────────────────────────────────
17+
@{ Path = "AuditServices\AuditWriter"; Port = 7062 },
18+
19+
# ── Exception Handling ───────────────────────────────────────────────────────
20+
@{ Path = "ExceptionHandling\CreateException"; Port = 7070 },
21+
@{ Path = "ExceptionHandling\UpdateException"; Port = 7073 },
22+
23+
# ── Screening Validation Service ─────────────────────────────────────────────
24+
@{ Path = "ScreeningValidationService\StaticValidation"; Port = 7074 },
25+
@{ Path = "ScreeningValidationService\LookupValidation"; Port = 7075 },
26+
@{ Path = "ScreeningValidationService\RemoveValidationException"; Port = 7085 },
27+
28+
# ── Demographic Services ─────────────────────────────────────────────────────
29+
@{ Path = "DemographicServices\DemographicDurableFunction"; Port = 7079 },
30+
@{ Path = "DemographicServices\RetrievePDSDemographic"; Port = 8082 },
31+
@{ Path = "DemographicServices\ManageCaasSubscription"; Port = 9084 },
32+
33+
# ── Cohort Distribution Services ─────────────────────────────────────────────
34+
@{ Path = "CohortDistributionServices\DistributeParticipant"; Port = 7063 },
35+
@{ Path = "CohortDistributionServices\TransformDataService"; Port = 7080 },
36+
@{ Path = "CohortDistributionServices\RetrieveCohortDistribution"; Port = 7078 },
37+
@{ Path = "CohortDistributionServices\RetrieveCohortRequestAudit"; Port = 7086 },
38+
39+
# ── Service Now Integration ───────────────────────────────────────────────────
40+
@{ Path = "ServiceNowIntegration\ServiceNowMessageHandler"; Port = 9092 },
41+
@{ Path = "ServiceNowIntegration\ServiceNowCohortLookup"; Port = 7180 },
42+
43+
# ── Screening Data Services ───────────────────────────────────────────────────
44+
@{ Path = "screeningDataServices\ExceptionManagementDataService"; Port = 7911 },
45+
@{ Path = "screeningDataServices\ScreeningLkpDataService"; Port = 8996 },
46+
@{ Path = "screeningDataServices\ParticipantDemographicDataService"; Port = 7993 },
47+
@{ Path = "screeningDataServices\ParticipantManagementDataService"; Port = 7994 },
48+
@{ Path = "screeningDataServices\CohortDistributionDataService"; Port = 7992 },
49+
@{ Path = "screeningDataServices\ReferenceDataService"; Port = 7988 },
50+
@{ Path = "screeningDataServices\GetValidationExceptions"; Port = 7071 },
51+
@{ Path = "screeningDataServices\BsSelectRequestAudit"; Port = 7989 },
52+
@{ Path = "screeningDataServices\NemsSubscriptionDataService"; Port = 7990 },
53+
@{ Path = "screeningDataServices\GeneCodeLkpDataService"; Port = 7991 },
54+
@{ Path = "screeningDataServices\HigherRiskReferralReasonLkpDataService"; Port = 7972 },
55+
@{ Path = "screeningDataServices\ServiceNowCasesDataService"; Port = 9996 }
56+
)
57+
58+
Write-Host "Functions root: $functionsRoot" -ForegroundColor DarkGray
59+
60+
# Build all functions first
61+
Write-Host "Building $($functions.Count) Azure Functions..." -ForegroundColor Cyan
62+
foreach ($fn in $functions) {
63+
$cwd = Join-Path $functionsRoot $fn.Path
64+
$name = Split-Path $fn.Path -Leaf
65+
66+
if (-not (Test-Path $cwd)) {
67+
Write-Host " [SKIP] $name - path not found: $cwd" -ForegroundColor Yellow
68+
continue
69+
}
70+
71+
Write-Host " [BUILD] $name" -ForegroundColor DarkCyan
72+
$result = & dotnet publish "$cwd" -o "$cwd\bin\output" --nologo -v q 2>&1
73+
if ($LASTEXITCODE -ne 0) {
74+
Write-Host " [FAIL] $name build failed:`n$result" -ForegroundColor Red
75+
exit 1
76+
}
77+
}
78+
79+
Write-Host "All functions built successfully.`n" -ForegroundColor Green
80+
81+
# Launch all functions
82+
Write-Host "Starting $($functions.Count) Azure Functions..." -ForegroundColor Cyan
83+
84+
$hasWT = [bool](Get-Command wt.exe -ErrorAction SilentlyContinue)
85+
if (-not $hasWT) {
86+
Write-Host "Windows Terminal (wt.exe) not found - falling back to separate pwsh windows." -ForegroundColor Yellow
87+
}
88+
89+
foreach ($fn in $functions) {
90+
$cwd = Join-Path $functionsRoot $fn.Path
91+
$name = Split-Path $fn.Path -Leaf
92+
$title = "$name :$($fn.Port)"
93+
94+
if (-not (Test-Path $cwd)) {
95+
Write-Host " [SKIP] $title - path not found: $cwd" -ForegroundColor Yellow
96+
continue
97+
}
98+
99+
Write-Host " [RUN] $title" -ForegroundColor Green
100+
101+
if ($hasWT) {
102+
$wtArgs = "-w CohortFunctions new-tab --title `"$title`" -d `"$cwd`" pwsh.exe -NoExit -Command `"func start --port $($fn.Port)`""
103+
Start-Process wt.exe -ArgumentList $wtArgs
104+
} else {
105+
Start-Process pwsh.exe -ArgumentList @(
106+
"-NoExit", "-Command",
107+
"Set-Location '$cwd'; `$Host.UI.RawUI.WindowTitle='$title'; func start --port $($fn.Port)"
108+
)
109+
}
110+
111+
# Waits until the port is actually listening before starting the next function
112+
$timeout = 60
113+
$elapsed = 0
114+
Write-Host " Waiting for port $($fn.Port)..." -ForegroundColor DarkGray
115+
while ($elapsed -lt $timeout) {
116+
$tcp = [System.Net.Sockets.TcpClient]::new()
117+
try {
118+
$tcp.Connect("localhost", $fn.Port)
119+
$tcp.Close()
120+
Write-Host " Port $($fn.Port) is up." -ForegroundColor DarkGreen
121+
break
122+
} catch {
123+
Start-Sleep -Seconds 1
124+
$elapsed++
125+
} finally {
126+
$tcp.Dispose()
127+
}
128+
}
129+
if ($elapsed -ge $timeout) {
130+
Write-Host " [WARN] Timed out waiting for port $($fn.Port) - continuing anyway." -ForegroundColor Yellow
131+
}
132+
}
133+
134+
Write-Host "`nAll functions launched. Check the 'CohortFunctions' Windows Terminal window." -ForegroundColor Cyan
135+

application/CohortManager/src/Functions/Functions.sln

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TransformDataServiceTests",
259259
EndProject
260260
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "integration-tests", "integration-tests", "{A1000001-0001-0001-0001-00000000000A}"
261261
EndProject
262+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RemoveDummyGPCode", "ParticipantManagementServices\RemoveDummyGPCode\RemoveDummyGPCode.csproj", "{A48E0AAF-053F-47C2-9862-B748F1423AF2}"
263+
EndProject
264+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RemoveDummyGPCodeTests", "..\..\..\..\tests\UnitTests\ParticipantManagementServicesTests\RemoveDummyGPCodeTests\RemoveDummyGPCodeTests.csproj", "{80857F35-B5A1-4846-A283-F15B75CBC32A}"
265+
EndProject
262266
Global
263267
GlobalSection(SolutionConfigurationPlatforms) = preSolution
264268
Debug|Any CPU = Debug|Any CPU
@@ -1457,6 +1461,30 @@ Global
14571461
{2ACD4ADF-2769-4D68-8DB4-5094F384C4BC}.Release|x64.Build.0 = Release|Any CPU
14581462
{2ACD4ADF-2769-4D68-8DB4-5094F384C4BC}.Release|x86.ActiveCfg = Release|Any CPU
14591463
{2ACD4ADF-2769-4D68-8DB4-5094F384C4BC}.Release|x86.Build.0 = Release|Any CPU
1464+
{A48E0AAF-053F-47C2-9862-B748F1423AF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1465+
{A48E0AAF-053F-47C2-9862-B748F1423AF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
1466+
{A48E0AAF-053F-47C2-9862-B748F1423AF2}.Debug|x64.ActiveCfg = Debug|Any CPU
1467+
{A48E0AAF-053F-47C2-9862-B748F1423AF2}.Debug|x64.Build.0 = Debug|Any CPU
1468+
{A48E0AAF-053F-47C2-9862-B748F1423AF2}.Debug|x86.ActiveCfg = Debug|Any CPU
1469+
{A48E0AAF-053F-47C2-9862-B748F1423AF2}.Debug|x86.Build.0 = Debug|Any CPU
1470+
{A48E0AAF-053F-47C2-9862-B748F1423AF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
1471+
{A48E0AAF-053F-47C2-9862-B748F1423AF2}.Release|Any CPU.Build.0 = Release|Any CPU
1472+
{A48E0AAF-053F-47C2-9862-B748F1423AF2}.Release|x64.ActiveCfg = Release|Any CPU
1473+
{A48E0AAF-053F-47C2-9862-B748F1423AF2}.Release|x64.Build.0 = Release|Any CPU
1474+
{A48E0AAF-053F-47C2-9862-B748F1423AF2}.Release|x86.ActiveCfg = Release|Any CPU
1475+
{A48E0AAF-053F-47C2-9862-B748F1423AF2}.Release|x86.Build.0 = Release|Any CPU
1476+
{80857F35-B5A1-4846-A283-F15B75CBC32A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1477+
{80857F35-B5A1-4846-A283-F15B75CBC32A}.Debug|Any CPU.Build.0 = Debug|Any CPU
1478+
{80857F35-B5A1-4846-A283-F15B75CBC32A}.Debug|x64.ActiveCfg = Debug|Any CPU
1479+
{80857F35-B5A1-4846-A283-F15B75CBC32A}.Debug|x64.Build.0 = Debug|Any CPU
1480+
{80857F35-B5A1-4846-A283-F15B75CBC32A}.Debug|x86.ActiveCfg = Debug|Any CPU
1481+
{80857F35-B5A1-4846-A283-F15B75CBC32A}.Debug|x86.Build.0 = Debug|Any CPU
1482+
{80857F35-B5A1-4846-A283-F15B75CBC32A}.Release|Any CPU.ActiveCfg = Release|Any CPU
1483+
{80857F35-B5A1-4846-A283-F15B75CBC32A}.Release|Any CPU.Build.0 = Release|Any CPU
1484+
{80857F35-B5A1-4846-A283-F15B75CBC32A}.Release|x64.ActiveCfg = Release|Any CPU
1485+
{80857F35-B5A1-4846-A283-F15B75CBC32A}.Release|x64.Build.0 = Release|Any CPU
1486+
{80857F35-B5A1-4846-A283-F15B75CBC32A}.Release|x86.ActiveCfg = Release|Any CPU
1487+
{80857F35-B5A1-4846-A283-F15B75CBC32A}.Release|x86.Build.0 = Release|Any CPU
14601488
EndGlobalSection
14611489
GlobalSection(SolutionProperties) = preSolution
14621490
HideSolutionNode = FALSE
@@ -1579,5 +1607,7 @@ Global
15791607
{83DD16A7-B7DF-47A4-9DC7-472D9F09EE35} = {2F646680-91A4-F107-74F4-9BF3126A0F16}
15801608
{A1000001-0001-0001-0001-00000000000A} = {2F646680-91A4-F107-74F4-9BF3126A0F16}
15811609
{2ACD4ADF-2769-4D68-8DB4-5094F384C4BC} = {A1000001-0001-0001-0001-00000000000A}
1610+
{A48E0AAF-053F-47C2-9862-B748F1423AF2} = {19500E0D-AAAB-6F02-E24F-82619ACA2290}
1611+
{80857F35-B5A1-4846-A283-F15B75CBC32A} = {AF3A5F34-77F2-7915-5806-A9586C50EB46}
15821612
EndGlobalSection
15831613
EndGlobal
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
ARG BASE_IMAGE
2+
FROM ${BASE_IMAGE} AS function
3+
4+
COPY ./ParticipantManagementServices/RemoveDummyGPCode /app/src/dotnet-function-app
5+
WORKDIR /app/src/dotnet-function-app
6+
7+
RUN --mount=type=cache,target=/root/.nuget/packages \
8+
dotnet publish *.csproj --output /home/site/wwwroot
9+
10+
# To enable ssh & remote debugging on app service change the base image to the one below
11+
# FROM mcr.microsoft.com/azure-functions/dotnet-isolated:4-dotnet-isolated8.0-appservice
12+
FROM mcr.microsoft.com/azure-functions/dotnet-isolated:4-dotnet-isolated8.0
13+
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
14+
AzureFunctionsJobHost__Logging__Console__IsEnabled=true
15+
16+
COPY --from=function ["/home/site/wwwroot", "/home/site/wwwroot"]
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
namespace NHS.CohortManager.ParticipantManagementServices;
2+
3+
using HealthChecks.Extensions;
4+
using Microsoft.Azure.Functions.Worker;
5+
using Microsoft.Azure.Functions.Worker.Http;
6+
using Microsoft.Extensions.Diagnostics.HealthChecks;
7+
8+
public class HealthCheckFunction
9+
{
10+
private readonly HealthCheckService _healthCheckService;
11+
12+
public HealthCheckFunction(HealthCheckService healthCheckService)
13+
{
14+
_healthCheckService = healthCheckService;
15+
}
16+
17+
[Function("health")]
18+
public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequestData req)
19+
{
20+
return await HealthCheckServiceExtensions.CreateHealthCheckResponseAsync(req, _healthCheckService);
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
namespace NHS.CohortManager.ParticipantManagementServices.Models;
2+
3+
using System.ComponentModel.DataAnnotations;
4+
using System.Text.Json.Serialization;
5+
6+
public class RemoveDummyGPCodeRequestBody
7+
{
8+
[Required]
9+
[JsonPropertyName("nhs_number")]
10+
public required string NhsNumber { get; set; }
11+
12+
[Required]
13+
[JsonPropertyName("forename")]
14+
public required string Forename { get; set; }
15+
16+
[Required]
17+
[JsonPropertyName("surname")]
18+
public required string Surname { get; set; }
19+
20+
[Required]
21+
[JsonPropertyName("date_of_birth")]
22+
public required DateOnly DateOfBirth { get; set; }
23+
24+
[Required]
25+
[JsonPropertyName("request_id")]
26+
public required string RequestId { get; set; }
27+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using Common;
2+
using HealthChecks.Extensions;
3+
using Microsoft.Extensions.DependencyInjection;
4+
using Microsoft.Extensions.Hosting;
5+
using NHS.CohortManager.ParticipantManagementServices;
6+
7+
var host = new HostBuilder()
8+
.AddConfiguration(out RemoveDummyGpCodeConfig config)
9+
.ConfigureFunctionsWorkerDefaults()
10+
.ConfigureServices(services =>
11+
{
12+
services.AddSingleton<ICreateResponse, CreateResponse>();
13+
services.AddBasicHealthCheck("RemoveDummyGPCode");
14+
})
15+
.AddTelemetry()
16+
.AddHttpClient()
17+
.AddServiceBusClient(config.ServiceBusConnectionString_client_internal)
18+
.Build();
19+
20+
await host.RunAsync();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"profiles": {
3+
"ManageServiceNowParticipant": {
4+
"commandName": "Project",
5+
"commandLineArgs": "--port 9092",
6+
"launchBrowser": false
7+
}
8+
}
9+
}

0 commit comments

Comments
 (0)