Skip to content

Commit 46860df

Browse files
feat: DTOSS-9454-ServiceNowMessageHandler (#1138)
* feat: DTOSS-9454-ServiceNowHandler Integration * feat: DTOSS-9454-updating correct project dependencies * feat: DTOSS-9454-updating tests * feat: DTOSS-9454-review comment update * feat: 9454-test update * feat: DTOSS-9454-consolidated failure update * feat: 9454-DTOSS-consolidated 2 * feat: 9454-DTOSS-consolidated 3 * feat: 9454-DTOSS-consolidated 4 * feat: 9454-DTOSS-consolidated 5 * feat: 9454-DTOSS-consolidated 6 * feat: 9454-DTOSS-consolidated 7 * feat: 9454-DTOSS-review comment updates * feat: 9454-DTOSS-updating yaml * feat: 9454-DTOSS-fixing yaml error * feat: 9454-DTOSS-sonarqube issues fix * feat: 9454-DTOSS-review comment updates
1 parent f595485 commit 46860df

File tree

18 files changed

+337
-387
lines changed

18 files changed

+337
-387
lines changed

application/CohortManager/compose.core.yaml

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ services:
155155
- CohortDistributionServiceURL=http://create-cohort-distribution:7082/api/CreateCohortDistribution
156156
- CohortQueueName=cohort-distribution-queue
157157
- UpdateQueueName=update-participant-queue
158-
158+
159159
update-blocked-flag:
160160
container_name: update-blocked-flag
161161
image: cohort-manager-update-blocked-flag
@@ -166,7 +166,7 @@ services:
166166
profiles: [non-essential]
167167
ports:
168168
- "7027:7027"
169-
environment:
169+
environment:
170170
- ASPNETCORE_URLS=http://*:7027
171171
- AzureWebJobsStorage=UseDevelopmentStorage=true
172172
- ParticipantManagementUrl=http://participant-management-data-service:7994/api/ParticipantManagementDataService
@@ -344,25 +344,13 @@ services:
344344
- AcceptableLatencyThresholdMs=500
345345

346346
# Service Now Integration Service
347-
receive-service-now-message:
348-
container_name: receive-service-now-message
349-
networks: [cohman-network]
350-
build:
351-
context: ./src/Functions/
352-
dockerfile: ServiceNowIntegrationService/ReceiveServiceNowMessage/Dockerfile
353-
ports:
354-
- 7912:7912
355-
profiles: [not-implemented]
356-
environment:
357-
- ASPNETCORE_URLS=http://*:7912
358-
359-
send-servicenow-message:
360-
container_name: send-servicenow-message
361-
image: cohort-manager-send-servicenow-message
347+
servicenow-message-handler:
348+
container_name: servicenow-message-handler
349+
image: cohort-manager-servicenow-message-handler
362350
networks: [cohman-network]
363351
build:
364352
context: ./src/Functions/
365-
dockerfile: ServiceNowIntegrationService/SendServiceNowMessage/Dockerfile
353+
dockerfile: ServiceNowIntegration/ServiceNowMessageHandler/Dockerfile
366354
profiles: [non-essential]
367355
environment:
368356
- ASPNETCORE_URLS=http://*:9092

application/CohortManager/src/Functions/Functions.sln

Lines changed: 31 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -235,12 +235,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeleteParticipantTests", ".
235235
EndProject
236236
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataServices.Migrations", "Shared\DataServices.Migrations\DataServices.Migrations.csproj", "{43AF1482-6B3E-41C9-BF92-531EB00FEA20}"
237237
EndProject
238-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SendServiceNowMessage", "ServiceNowIntegrationService\SendServiceNowMessage\SendServiceNowMessage.csproj", "{53D67486-6264-4554-BD21-F47811F16FEC}"
239-
EndProject
240-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReceiveServiceNowMessage", "ServiceNowIntegrationService\ReceiveServiceNowMessage\ReceiveServiceNowMessage.csproj", "{0F5234AE-1991-491D-A7E2-0921EF90B7BA}"
241-
EndProject
242-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SendServiceNowMessageTests", "..\..\..\..\tests\UnitTests\SendServiceNowMessageTests\SendServiceNowMessageTests.csproj", "{10EADCB8-DF07-495F-8EBA-5A399962956D}"
243-
EndProject
244238
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateBlockedFlag", "ParticipantManagementServices\UpdateBlockedFlag\UpdateBlockedFlag.csproj", "{AE5EAAE6-E74E-4080-AED0-0CCC4A3EBBB2}"
245239
EndProject
246240
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UnitTests", "UnitTests", "{2F646680-91A4-F107-74F4-9BF3126A0F16}"
@@ -261,10 +255,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProcessNemsUpdate", "NemsSu
261255
EndProject
262256
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProcessNemsUpdateTests", "..\..\..\..\tests\UnitTests\NemsSubscriptionServiceTests\ProcessNemsUpdateTests\ProcessNemsUpdateTests.csproj", "{0F8F78E8-9DC7-4BF7-8BA8-E56A79615434}"
263257
EndProject
258+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceNowMessageHandlerTests", "..\..\..\..\tests\UnitTests\ServiceNowMessageHandlerTests\ServiceNowMessageHandlerTests.csproj", "{33C49482-E216-4170-A2B9-00C816206566}"
259+
EndProject
264260
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ManageParticipant", "ParticipantManagementServices\ManageParticipant\ManageParticipant.csproj", "{6F35BE1C-121E-5D91-98E7-83CAF153EF2E}"
265261
EndProject
266262
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DistributeParticipant", "CohortDistributionServices\DistributeParticipant\DistributeParticipant.csproj", "{87F24206-BDE4-471F-B031-791308443CEE}"
267263
EndProject
264+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ServiceNowIntegration", "ServiceNowIntegration", "{707D3294-6E53-492E-8AA8-1B2F0D358AC4}"
265+
EndProject
266+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceNowMessageHandler", "ServiceNowIntegration\ServiceNowMessageHandler\ServiceNowMessageHandler.csproj", "{EFAEEEFA-5970-4905-8F81-2471BA5DB8ED}"
267+
EndProject
268268
Global
269269
GlobalSection(SolutionConfigurationPlatforms) = preSolution
270270
Debug|Any CPU = Debug|Any CPU
@@ -1439,42 +1439,6 @@ Global
14391439
{43AF1482-6B3E-41C9-BF92-531EB00FEA20}.Release|x64.Build.0 = Release|Any CPU
14401440
{43AF1482-6B3E-41C9-BF92-531EB00FEA20}.Release|x86.ActiveCfg = Release|Any CPU
14411441
{43AF1482-6B3E-41C9-BF92-531EB00FEA20}.Release|x86.Build.0 = Release|Any CPU
1442-
{53D67486-6264-4554-BD21-F47811F16FEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1443-
{53D67486-6264-4554-BD21-F47811F16FEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
1444-
{53D67486-6264-4554-BD21-F47811F16FEC}.Debug|x64.ActiveCfg = Debug|Any CPU
1445-
{53D67486-6264-4554-BD21-F47811F16FEC}.Debug|x64.Build.0 = Debug|Any CPU
1446-
{53D67486-6264-4554-BD21-F47811F16FEC}.Debug|x86.ActiveCfg = Debug|Any CPU
1447-
{53D67486-6264-4554-BD21-F47811F16FEC}.Debug|x86.Build.0 = Debug|Any CPU
1448-
{53D67486-6264-4554-BD21-F47811F16FEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
1449-
{53D67486-6264-4554-BD21-F47811F16FEC}.Release|Any CPU.Build.0 = Release|Any CPU
1450-
{53D67486-6264-4554-BD21-F47811F16FEC}.Release|x64.ActiveCfg = Release|Any CPU
1451-
{53D67486-6264-4554-BD21-F47811F16FEC}.Release|x64.Build.0 = Release|Any CPU
1452-
{53D67486-6264-4554-BD21-F47811F16FEC}.Release|x86.ActiveCfg = Release|Any CPU
1453-
{53D67486-6264-4554-BD21-F47811F16FEC}.Release|x86.Build.0 = Release|Any CPU
1454-
{0F5234AE-1991-491D-A7E2-0921EF90B7BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1455-
{0F5234AE-1991-491D-A7E2-0921EF90B7BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
1456-
{0F5234AE-1991-491D-A7E2-0921EF90B7BA}.Debug|x64.ActiveCfg = Debug|Any CPU
1457-
{0F5234AE-1991-491D-A7E2-0921EF90B7BA}.Debug|x64.Build.0 = Debug|Any CPU
1458-
{0F5234AE-1991-491D-A7E2-0921EF90B7BA}.Debug|x86.ActiveCfg = Debug|Any CPU
1459-
{0F5234AE-1991-491D-A7E2-0921EF90B7BA}.Debug|x86.Build.0 = Debug|Any CPU
1460-
{0F5234AE-1991-491D-A7E2-0921EF90B7BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
1461-
{0F5234AE-1991-491D-A7E2-0921EF90B7BA}.Release|Any CPU.Build.0 = Release|Any CPU
1462-
{0F5234AE-1991-491D-A7E2-0921EF90B7BA}.Release|x64.ActiveCfg = Release|Any CPU
1463-
{0F5234AE-1991-491D-A7E2-0921EF90B7BA}.Release|x64.Build.0 = Release|Any CPU
1464-
{0F5234AE-1991-491D-A7E2-0921EF90B7BA}.Release|x86.ActiveCfg = Release|Any CPU
1465-
{0F5234AE-1991-491D-A7E2-0921EF90B7BA}.Release|x86.Build.0 = Release|Any CPU
1466-
{10EADCB8-DF07-495F-8EBA-5A399962956D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1467-
{10EADCB8-DF07-495F-8EBA-5A399962956D}.Debug|Any CPU.Build.0 = Debug|Any CPU
1468-
{10EADCB8-DF07-495F-8EBA-5A399962956D}.Debug|x64.ActiveCfg = Debug|Any CPU
1469-
{10EADCB8-DF07-495F-8EBA-5A399962956D}.Debug|x64.Build.0 = Debug|Any CPU
1470-
{10EADCB8-DF07-495F-8EBA-5A399962956D}.Debug|x86.ActiveCfg = Debug|Any CPU
1471-
{10EADCB8-DF07-495F-8EBA-5A399962956D}.Debug|x86.Build.0 = Debug|Any CPU
1472-
{10EADCB8-DF07-495F-8EBA-5A399962956D}.Release|Any CPU.ActiveCfg = Release|Any CPU
1473-
{10EADCB8-DF07-495F-8EBA-5A399962956D}.Release|Any CPU.Build.0 = Release|Any CPU
1474-
{10EADCB8-DF07-495F-8EBA-5A399962956D}.Release|x64.ActiveCfg = Release|Any CPU
1475-
{10EADCB8-DF07-495F-8EBA-5A399962956D}.Release|x64.Build.0 = Release|Any CPU
1476-
{10EADCB8-DF07-495F-8EBA-5A399962956D}.Release|x86.ActiveCfg = Release|Any CPU
1477-
{10EADCB8-DF07-495F-8EBA-5A399962956D}.Release|x86.Build.0 = Release|Any CPU
14781442
{AE5EAAE6-E74E-4080-AED0-0CCC4A3EBBB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
14791443
{AE5EAAE6-E74E-4080-AED0-0CCC4A3EBBB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
14801444
{AE5EAAE6-E74E-4080-AED0-0CCC4A3EBBB2}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -1571,6 +1535,18 @@ Global
15711535
{0F8F78E8-9DC7-4BF7-8BA8-E56A79615434}.Release|x64.Build.0 = Release|Any CPU
15721536
{0F8F78E8-9DC7-4BF7-8BA8-E56A79615434}.Release|x86.ActiveCfg = Release|Any CPU
15731537
{0F8F78E8-9DC7-4BF7-8BA8-E56A79615434}.Release|x86.Build.0 = Release|Any CPU
1538+
{33C49482-E216-4170-A2B9-00C816206566}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1539+
{33C49482-E216-4170-A2B9-00C816206566}.Debug|Any CPU.Build.0 = Debug|Any CPU
1540+
{33C49482-E216-4170-A2B9-00C816206566}.Debug|x64.ActiveCfg = Debug|Any CPU
1541+
{33C49482-E216-4170-A2B9-00C816206566}.Debug|x64.Build.0 = Debug|Any CPU
1542+
{33C49482-E216-4170-A2B9-00C816206566}.Debug|x86.ActiveCfg = Debug|Any CPU
1543+
{33C49482-E216-4170-A2B9-00C816206566}.Debug|x86.Build.0 = Debug|Any CPU
1544+
{33C49482-E216-4170-A2B9-00C816206566}.Release|Any CPU.ActiveCfg = Release|Any CPU
1545+
{33C49482-E216-4170-A2B9-00C816206566}.Release|Any CPU.Build.0 = Release|Any CPU
1546+
{33C49482-E216-4170-A2B9-00C816206566}.Release|x64.ActiveCfg = Release|Any CPU
1547+
{33C49482-E216-4170-A2B9-00C816206566}.Release|x64.Build.0 = Release|Any CPU
1548+
{33C49482-E216-4170-A2B9-00C816206566}.Release|x86.ActiveCfg = Release|Any CPU
1549+
{33C49482-E216-4170-A2B9-00C816206566}.Release|x86.Build.0 = Release|Any CPU
15741550
{6F35BE1C-121E-5D91-98E7-83CAF153EF2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15751551
{6F35BE1C-121E-5D91-98E7-83CAF153EF2E}.Debug|Any CPU.Build.0 = Debug|Any CPU
15761552
{6F35BE1C-121E-5D91-98E7-83CAF153EF2E}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -1595,6 +1571,18 @@ Global
15951571
{87F24206-BDE4-471F-B031-791308443CEE}.Release|x64.Build.0 = Release|Any CPU
15961572
{87F24206-BDE4-471F-B031-791308443CEE}.Release|x86.ActiveCfg = Release|Any CPU
15971573
{87F24206-BDE4-471F-B031-791308443CEE}.Release|x86.Build.0 = Release|Any CPU
1574+
{EFAEEEFA-5970-4905-8F81-2471BA5DB8ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1575+
{EFAEEEFA-5970-4905-8F81-2471BA5DB8ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
1576+
{EFAEEEFA-5970-4905-8F81-2471BA5DB8ED}.Debug|x64.ActiveCfg = Debug|Any CPU
1577+
{EFAEEEFA-5970-4905-8F81-2471BA5DB8ED}.Debug|x64.Build.0 = Debug|Any CPU
1578+
{EFAEEEFA-5970-4905-8F81-2471BA5DB8ED}.Debug|x86.ActiveCfg = Debug|Any CPU
1579+
{EFAEEEFA-5970-4905-8F81-2471BA5DB8ED}.Debug|x86.Build.0 = Debug|Any CPU
1580+
{EFAEEEFA-5970-4905-8F81-2471BA5DB8ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
1581+
{EFAEEEFA-5970-4905-8F81-2471BA5DB8ED}.Release|Any CPU.Build.0 = Release|Any CPU
1582+
{EFAEEEFA-5970-4905-8F81-2471BA5DB8ED}.Release|x64.ActiveCfg = Release|Any CPU
1583+
{EFAEEEFA-5970-4905-8F81-2471BA5DB8ED}.Release|x64.Build.0 = Release|Any CPU
1584+
{EFAEEEFA-5970-4905-8F81-2471BA5DB8ED}.Release|x86.ActiveCfg = Release|Any CPU
1585+
{EFAEEEFA-5970-4905-8F81-2471BA5DB8ED}.Release|x86.Build.0 = Release|Any CPU
15981586
EndGlobalSection
15991587
GlobalSection(SolutionProperties) = preSolution
16001588
HideSolutionNode = FALSE
@@ -1660,8 +1648,6 @@ Global
16601648
{5F0DAA07-D15F-460B-9FDA-B10AABD144C6} = {055277D8-0B3B-A388-B9E2-0CA913C660FF}
16611649
{68293DEC-C32E-4CD0-ADD0-EDF273017584} = {72FBAE8E-5F64-9545-D6D4-8F59D0E91151}
16621650
{43AF1482-6B3E-41C9-BF92-531EB00FEA20} = {4F52FD11-658E-A102-6CD3-7D7C16FFA15B}
1663-
{53D67486-6264-4554-BD21-F47811F16FEC} = {ADBDFBE0-1F6C-9F07-943C-8060402FBCEA}
1664-
{0F5234AE-1991-491D-A7E2-0921EF90B7BA} = {ADBDFBE0-1F6C-9F07-943C-8060402FBCEA}
16651651
{AE5EAAE6-E74E-4080-AED0-0CCC4A3EBBB2} = {19500E0D-AAAB-6F02-E24F-82619ACA2290}
16661652
{AF3A5F34-77F2-7915-5806-A9586C50EB46} = {2F646680-91A4-F107-74F4-9BF3126A0F16}
16671653
{A4EBDA0F-060E-4454-AD01-D56ECC2D1BBE} = {AF3A5F34-77F2-7915-5806-A9586C50EB46}
@@ -1670,5 +1656,6 @@ Global
16701656
{1538902B-C11F-492B-86A6-86A0DB72C761} = {81415B60-C1D4-887B-0030-6F6B04DE9059}
16711657
{6F35BE1C-121E-5D91-98E7-83CAF153EF2E} = {19500E0D-AAAB-6F02-E24F-82619ACA2290}
16721658
{87F24206-BDE4-471F-B031-791308443CEE} = {72FBAE8E-5F64-9545-D6D4-8F59D0E91151}
1659+
{EFAEEEFA-5970-4905-8F81-2471BA5DB8ED} = {707D3294-6E53-492E-8AA8-1B2F0D358AC4}
16731660
EndGlobalSection
16741661
EndGlobal

application/CohortManager/src/Functions/ServiceNowIntegrationService/SendServiceNowMessage/Dockerfile renamed to application/CohortManager/src/Functions/ServiceNowIntegration/ServiceNowMessageHandler/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ RUN mkdir -p /home/site/wwwroot && \
1414

1515
FROM base AS function
1616

17-
COPY ./ServiceNowIntegrationService/SendServiceNowMessage /src/dotnet-function-app
17+
COPY ./ServiceNowIntegration/ServiceNowMessageHandler /src/dotnet-function-app
1818
WORKDIR /src/dotnet-function-app
1919

2020
RUN --mount=type=cache,target=/root/.nuget/packages \

application/CohortManager/src/Functions/ServiceNowIntegrationService/SendServiceNowMessage/HealthCheckFunction.cs renamed to application/CohortManager/src/Functions/ServiceNowIntegration/ServiceNowMessageHandler/HealthCheckFunction.cs

File renamed without changes.

application/CohortManager/src/Functions/ServiceNowIntegrationService/SendServiceNowMessage/Program.cs renamed to application/CohortManager/src/Functions/ServiceNowIntegration/ServiceNowMessageHandler/Program.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
.ConfigureServices(services =>
1313
{
1414
services.AddSingleton<ICreateResponse, CreateResponse>();
15-
services.AddHttpClient<ServiceNowMessageHandler>();
16-
1715
})
1816
.AddTelemetry()
1917
.Build();

application/CohortManager/src/Functions/ServiceNowIntegrationService/SendServiceNowMessage/SendServiceNowMsgConfig.cs renamed to application/CohortManager/src/Functions/ServiceNowIntegration/ServiceNowMessageHandler/SendServiceNowMsgConfig.cs

File renamed without changes.
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
namespace NHS.CohortManager.ServiceNowIntegrationService;
2+
3+
using System;
4+
using System.IO;
5+
using System.Net;
6+
using System.Net.Http;
7+
using System.Net.Http.Headers;
8+
using System.Text;
9+
using System.Text.Json;
10+
using System.Threading.Tasks;
11+
using Microsoft.Azure.Functions.Worker;
12+
using Microsoft.Azure.Functions.Worker.Http;
13+
using Microsoft.Extensions.Logging;
14+
using Microsoft.Extensions.Options;
15+
using NHS.CohortManager.ServiceNowMessageService.Models;
16+
using Common;
17+
18+
public class ServiceNowMessageHandler
19+
{
20+
private readonly HttpClient _httpClient;
21+
private readonly ILogger<ServiceNowMessageHandler> _logger;
22+
private readonly SendServiceNowMsgConfig _config;
23+
private readonly ICreateResponse _createResponse;
24+
25+
private string? _cachedAccessToken;
26+
private DateTime _lastTokenRefresh = DateTime.MinValue;
27+
private static readonly TimeSpan TokenExpiryBuffer = TimeSpan.FromMinutes(55);
28+
29+
public ServiceNowMessageHandler(
30+
IHttpClientFactory httpClientFactory,
31+
ILogger<ServiceNowMessageHandler> logger,
32+
IOptions<SendServiceNowMsgConfig> sendServiceNowMsgConfig,
33+
ICreateResponse createResponse)
34+
{
35+
_httpClient = httpClientFactory.CreateClient();
36+
_logger = logger;
37+
_config = sendServiceNowMsgConfig.Value;
38+
_createResponse = createResponse;
39+
}
40+
41+
/// <summary>
42+
/// Azure Function to receive and log incoming ServiceNow messages.
43+
/// </summary>
44+
/// <param name="req">The HTTP request containing the incoming message payload.</param>
45+
/// <returns>A 200 OK HTTP response containing the original body content.</returns>
46+
[Function("ReceiveServiceNowMessage")]
47+
public async Task<HttpResponseData> ReceiveServiceNowMessage(
48+
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "servicenow/receive")] HttpRequestData req)
49+
{
50+
_logger.LogInformation("ReceiveServiceNowMessage function triggered.");
51+
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
52+
_logger.LogInformation("Received body: {Body}", requestBody);
53+
return _createResponse.CreateHttpResponse(HttpStatusCode.OK, req, requestBody);
54+
}
55+
56+
/// <summary>
57+
/// Azure Function to send a message to the ServiceNow API, with automatic token refresh handling.
58+
/// </summary>
59+
/// <param name="req">The HTTP request containing the message to be sent.</param>
60+
/// <param name="baseUrl">Base URL of the ServiceNow instance.</param>
61+
/// <param name="profile">The profile environment (e.g., dev, test, prod).</param>
62+
/// <param name="sysId">The system identifier (sys_id) used for the PUT request path.</param>
63+
/// <returns>
64+
/// An HTTP response indicating the result of the operation:
65+
/// - 200 OK on success
66+
/// - 400 Bad Request for invalid input
67+
/// </returns>
68+
[Function("SendServiceNowMessage")]
69+
public async Task<HttpResponseData> SendServiceNowMessage(
70+
[HttpTrigger(AuthorizationLevel.Anonymous, "put", Route = "servicenow/send/{baseUrl}/{profile}/{sysId}")] HttpRequestData req,
71+
string baseUrl,
72+
string profile,
73+
string sysId)
74+
{
75+
_logger.LogInformation("SendServiceNowMessage function triggered.");
76+
77+
var requestBody = await req.ReadAsStringAsync();
78+
if (string.IsNullOrWhiteSpace(requestBody))
79+
return _createResponse.CreateHttpResponse(HttpStatusCode.BadRequest, req, "Request body is missing or empty.");
80+
81+
ServiceNowRequestModel? input;
82+
try
83+
{
84+
input = JsonSerializer.Deserialize<ServiceNowRequestModel>(requestBody);
85+
}
86+
catch
87+
{
88+
return _createResponse.CreateHttpResponse(HttpStatusCode.BadRequest, req, "ServiceNow update failed.");
89+
}
90+
91+
if (string.IsNullOrWhiteSpace(input?.WorkNotes))
92+
return _createResponse.CreateHttpResponse(HttpStatusCode.BadRequest, req, "Invalid request payload.");
93+
94+
var url = $"https://{baseUrl}/{_config.EndpointPath}/{profile}/{_config.Definition}/{sysId}";
95+
96+
var payload = new
97+
{
98+
state = input.State,
99+
work_notes = input.WorkNotes
100+
};
101+
102+
var json = JsonSerializer.Serialize(payload);
103+
var content = new StringContent(json, Encoding.UTF8, "application/json");
104+
105+
var token = await GetValidAccessTokenAsync();
106+
_httpClient.DefaultRequestHeaders.Clear();
107+
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
108+
109+
var response = await _httpClient.PutAsync(url, content);
110+
if (response.StatusCode == HttpStatusCode.Unauthorized)
111+
{
112+
_logger.LogWarning("Token expired. Retrying with refreshed token.");
113+
token = await RefreshAccessTokenAsync();
114+
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
115+
response = await _httpClient.PutAsync(url, content);
116+
}
117+
118+
var responseBody = await response.Content.ReadAsStringAsync();
119+
_logger.LogInformation("ServiceNow Response: {Code} - {Body}", response.StatusCode, responseBody);
120+
response.EnsureSuccessStatusCode();
121+
return _createResponse.CreateHttpResponse(response.StatusCode, req, responseBody);
122+
}
123+
124+
private async Task<string> GetValidAccessTokenAsync()
125+
{
126+
if (_cachedAccessToken == null || DateTime.UtcNow - _lastTokenRefresh > TokenExpiryBuffer)
127+
{
128+
_cachedAccessToken = await RefreshAccessTokenAsync();
129+
}
130+
return _cachedAccessToken;
131+
}
132+
133+
private async Task<string> RefreshAccessTokenAsync()
134+
{
135+
_logger.LogInformation("Refreshing access token...");
136+
await Task.Delay(500); // simulate external call
137+
_lastTokenRefresh = DateTime.UtcNow;
138+
return _config.AccessToken; // Replace with real token logic
139+
}
140+
}

application/CohortManager/src/Functions/ServiceNowIntegrationService/SendServiceNowMessage/SendServiceNowMessage.csproj renamed to application/CohortManager/src/Functions/ServiceNowIntegration/ServiceNowMessageHandler/ServiceNowMessageHandler.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
</PropertyGroup>
99
<ItemGroup>
1010
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="2.0.0" />
11-
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.3.0" />
12-
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="2.0.2" />
13-
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="2.0.4" />
11+
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.2.0" />
12+
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="2.0.0" />
13+
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="2.0.2" />
1414
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="9.0.2" />
1515
</ItemGroup>
1616
<ItemGroup>

application/CohortManager/src/Functions/ServiceNowIntegrationService/SendServiceNowMessage/ServiceNowRequestModel.cs renamed to application/CohortManager/src/Functions/ServiceNowIntegration/ServiceNowMessageHandler/ServiceNowRequestModel.cs

File renamed without changes.

0 commit comments

Comments
 (0)