Skip to content

Commit 3ac1f42

Browse files
authored
Chore: [AEA-6165] - remove code to make service search v2 calls (#2422)
## Summary - 🤖 Operational or Infrastructure Change ### Details - remove code to make service search v2 calls now that we've rolled v3 out in production
1 parent 079947f commit 3ac1f42

File tree

7 files changed

+81
-149
lines changed

7 files changed

+81
-149
lines changed

.trivyignore.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,9 @@ vulnerabilities:
1515
- id: CVE-2026-26996
1616
statement: minimatch vulnerability accepted as risk
1717
expired_at: 2026-06-01
18+
- id: CVE-2026-27903
19+
statement: minimatch vulnerability accepted as risk
20+
expired_at: 2026-06-01
21+
- id: CVE-2026-27904
22+
statement: minimatch vulnerability accepted as risk
23+
expired_at: 2026-06-01

SAMtemplates/functions/main.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ Globals:
2121
SpineASIDARN: !ImportValue account-resources:SpineASID
2222
SpinePartyKeyARN: !ImportValue account-resources:SpinePartyKey
2323
SpineCAChainARN: !ImportValue account-resources:SpineCAChain
24-
ServiceSearchApiKeyARN: !ImportValue account-resources:ServiceSearchApiKey
2524
ServiceSearch3ApiKeyARN: !Ref ServiceSearch3ApiKeyARN
2625
Layers:
2726
- !Sub arn:aws:lambda:${AWS::Region}:580247275435:layer:LambdaInsightsExtension:52

packages/common/testing/src/mockServiceSearchResponseBodyPharmacy2u.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@
33
"value": [
44
{
55
"@search.score": 12.937448,
6-
"URL": "https://www.pharmacy2u.co.uk",
7-
"OrganisationSubType": "DistanceSelling"
6+
"OrganisationSubType": "DistanceSelling",
7+
"Contacts": [
8+
{
9+
"ContactMethodType": "Website",
10+
"ContactValue": "https://www.pharmacy2u.co.uk"
11+
}
12+
]
813
}
914
]
1015
}

packages/common/testing/src/mockServiceSearchResponseBodyPharmica.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@
33
"value": [
44
{
55
"@search.score": 13.098481,
6-
"URL": "www.pharmica.co.uk",
7-
"OrganisationSubType": "DistanceSelling"
6+
"OrganisationSubType": "DistanceSelling",
7+
"Contacts": [
8+
{
9+
"ContactMethodType": "Website",
10+
"ContactValue": "www.pharmica.co.uk"
11+
}
12+
]
813
}
914
]
1015
}

packages/distanceSelling/tests/distanceSelling.test.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {Logger} from "@aws-lambda-powertools/logger"
1414
const mock = new MockAdapter(axios)
1515
const mockBundleString = JSON.stringify(mockInteractionResponseBody)
1616
const dummyCorrelationId = "corr-id-123"
17+
const SERVICE_SEARCH_API_URL = "https://live/service-search-api/"
1718

1819
describe("ServiceSearch tests", function () {
1920
const logger = new Logger({serviceName: "distanceSelling"})
@@ -204,7 +205,7 @@ describe("ServiceSearch tests", function () {
204205
})
205206

206207
it("processOdsCodes uses returned value in telecom", async () => {
207-
mock.onGet("https://live/service-search").reply(200, mockPharmacy2uResponse)
208+
mock.onGet(SERVICE_SEARCH_API_URL).reply(200, mockPharmacy2uResponse)
208209
const distanceSelling = new DistanceSelling({}, logger)
209210
const searchsetBundle = JSON.parse(mockBundleString) as Bundle
210211

@@ -250,7 +251,7 @@ describe("ServiceSearch tests", function () {
250251
})
251252

252253
it("searchOdsCode adds item to cache when url returned by service search", async () => {
253-
mock.onGet("https://live/service-search").reply(200, mockPharmacy2uResponse)
254+
mock.onGet(SERVICE_SEARCH_API_URL).reply(200, mockPharmacy2uResponse)
254255
const servicesCache: ServicesCache = {}
255256
const distanceSelling = new DistanceSelling(servicesCache, logger)
256257
const searchsetBundle = JSON.parse(mockBundleString) as Bundle
@@ -267,7 +268,7 @@ describe("ServiceSearch tests", function () {
267268
})
268269

269270
it("searchOdsCode adds empty item to cache when no url returned by service search", async () => {
270-
mock.onGet("https://live/service-search").reply(200, {value: []})
271+
mock.onGet(SERVICE_SEARCH_API_URL).reply(200, {"@odata.context": "", value: []})
271272
const servicesCache: ServicesCache = {}
272273
const distanceSelling = new DistanceSelling(servicesCache, logger)
273274
const searchsetBundle = JSON.parse(mockBundleString) as Bundle
@@ -284,7 +285,7 @@ describe("ServiceSearch tests", function () {
284285
})
285286

286287
it("searchOdsCode does not add to cache when service search error", async () => {
287-
mock.onGet("https://live/service-search").networkError()
288+
mock.onGet(SERVICE_SEARCH_API_URL).networkError()
288289
const servicesCache: ServicesCache = {}
289290
const distanceSelling = new DistanceSelling(servicesCache, logger)
290291
const searchsetBundle = JSON.parse(mockBundleString) as Bundle

packages/serviceSearchClient/src/live-serviceSearch-client.ts

Lines changed: 11 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,11 @@ import {ServiceSearchClient} from "./serviceSearch-client"
1717
const SERVICE_SEARCH_TIMEOUT = 3000 // 3 seconds
1818
const DISTANCE_SELLING = "DistanceSelling"
1919

20-
type Service = {
21-
"URL": string
22-
"OrganisationSubType": string
23-
}
24-
2520
type Contact = {
2621
"ContactMethodType": string
2722
"ContactValue": string
2823
}
2924

30-
export type ServiceSearchData = {
31-
"value": Array<Service>
32-
}
33-
3425
export type ServiceSearch3Data = {
3526
"@odata.context": string
3627
"value": Array<{
@@ -41,33 +32,21 @@ export type ServiceSearch3Data = {
4132
}
4233

4334
export const SERVICE_SEARCH_BASE_QUERY_PARAMS = {
44-
"api-version": 2,
35+
"api-version": 3,
4536
"searchFields": "ODSCode",
46-
"$filter": "OrganisationTypeId eq 'PHA' and OrganisationSubType eq 'DistanceSelling'",
47-
"$select": "URL,OrganisationSubType",
37+
"$filter": `OrganisationTypeId eq 'PHA' and OrganisationSubType eq '${DISTANCE_SELLING}'`,
38+
"$select": "Contacts,OrganisationSubType",
4839
"$top": 1
4940
}
5041

5142
export function getServiceSearchVersion(logger: Logger | null = null): number {
52-
const endpoint = process.env.TargetServiceSearchServer || "service-search"
53-
if (endpoint.toLowerCase().includes("api.service.nhs.uk")) {
54-
logger?.info("Using service search v3 endpoint")
55-
SERVICE_SEARCH_BASE_QUERY_PARAMS["api-version"] = 3
56-
SERVICE_SEARCH_BASE_QUERY_PARAMS["$select"] = "Contacts,OrganisationSubType"
57-
return 3
58-
}
59-
logger?.warn("Using service search v2 endpoint")
60-
return 2
43+
logger?.info("Service search v3 enabled")
44+
return 3
6145
}
6246

6347
export function getServiceSearchEndpoint(logger: Logger | null = null): string {
64-
switch (getServiceSearchVersion(logger)) {
65-
case 3:
66-
return `https://${process.env.TargetServiceSearchServer}/service-search-api/`
67-
case 2:
68-
default:
69-
return `https://${process.env.TargetServiceSearchServer}/service-search`
70-
}
48+
logger?.info("Using service search v3 endpoint")
49+
return `https://${process.env.TargetServiceSearchServer}/service-search-api/`
7150
}
7251

7352
export class LiveServiceSearchClient implements ServiceSearchClient {
@@ -76,7 +55,6 @@ export class LiveServiceSearchClient implements ServiceSearchClient {
7655
private readonly httpsAgent: Agent
7756
private readonly outboundHeaders: {
7857
"apikey"?: string,
79-
"Subscription-Key"?: string,
8058
"x-request-id"?: string,
8159
"x-correlation-id"?: string
8260
}
@@ -85,7 +63,6 @@ export class LiveServiceSearchClient implements ServiceSearchClient {
8563
this.logger = logger
8664
this.logger.info("ServiceSearchClient configured",
8765
{
88-
v2: process.env.ServiceSearchApiKey !== undefined,
8966
v3: process.env.ServiceSearch3ApiKey !== undefined
9067
})
9168
this.httpsAgent = new Agent({
@@ -149,15 +126,8 @@ export class LiveServiceSearchClient implements ServiceSearchClient {
149126
return Promise.reject(err)
150127
})
151128

152-
const version = getServiceSearchVersion(this.logger)
153-
if (version === 3) {
154-
this.outboundHeaders = {
155-
"apikey": process.env.ServiceSearch3ApiKey
156-
}
157-
} else {
158-
this.outboundHeaders = {
159-
"Subscription-Key": process.env.ServiceSearchApiKey
160-
}
129+
this.outboundHeaders = {
130+
"apikey": process.env.ServiceSearch3ApiKey
161131
}
162132
}
163133

@@ -211,11 +181,7 @@ export class LiveServiceSearchClient implements ServiceSearchClient {
211181

212182
this.logger.info(`received response from serviceSearch for ods code ${odsCode}`,
213183
{odsCode: odsCode, status: response.status, data: response.data})
214-
if (apiVsn === 2) {
215-
return this.handleV2Response(odsCode, response.data)
216-
} else {
217-
return this.handleV3Response(odsCode, response.data)
218-
}
184+
return this.handleV3Response(odsCode, response.data)
219185
}
220186

221187
private getReusedSocket(request: unknown): boolean | undefined {
@@ -238,26 +204,8 @@ export class LiveServiceSearchClient implements ServiceSearchClient {
238204
return serviceUrl
239205
}
240206

241-
handleV2Response(odsCode: string, data: ServiceSearchData): URL | undefined {
242-
const services = data.value
243-
if (services.length === 0) {
244-
return undefined
245-
}
246-
247-
this.logger.info(`pharmacy with ods code ${odsCode} is of type ${DISTANCE_SELLING}`, {odsCode: odsCode})
248-
const service = services[0]
249-
const urlString = service["URL"]
250-
251-
if (urlString === null) {
252-
this.logger.warn(`ods code ${odsCode} has no URL but is of type ${DISTANCE_SELLING}`, {odsCode: odsCode})
253-
return undefined
254-
}
255-
const serviceUrl = handleUrl(urlString, odsCode, this.logger)
256-
return serviceUrl
257-
}
258-
259207
stripApiKeyFromHeaders(error: AxiosError) {
260-
const headerKeys = ["subscription-key", "apikey"]
208+
const headerKeys = ["apikey"]
261209
headerKeys.forEach((key) => {
262210
if (error.response?.headers?.[key]) {
263211
delete error.response.headers[key]

0 commit comments

Comments
 (0)