diff --git a/.gitleaksignore b/.gitleaksignore index 743843dbe..6758264a1 100644 --- a/.gitleaksignore +++ b/.gitleaksignore @@ -25,3 +25,9 @@ debc75a97cfe551a69fd1e8694be483213322a9d:pact-contracts/pacts/letter-rendering/s 4fa1923947bbff2387218d698d766cbb7c121a0f:pact-contracts/pacts/letter-rendering/supplier-api-letter-request-prepared.json:generic-api-key:10 d005112adcfd286c3bef076214836dbb2fe8d0b5:.npmrc:npm-access-token:9 d005112adcfd286c3bef076214836dbb2fe8d0b5:.npmrc:github-pat:7 +ff889d4c3f29da4468ecf1f05f467fe84d35b2a1:lambdas/supplier-mock/.aws-sam/build/SupplierMockFunction/index.js.map:ipv4:4 +ff889d4c3f29da4468ecf1f05f467fe84d35b2a1:lambdas/supplier-mock/.aws-sam/build/SupplierMockFunction/index.js:ipv4:63 +ff889d4c3f29da4468ecf1f05f467fe84d35b2a1:lambdas/supplier-mock/.aws-sam/build/SupplierMockFunction/index.js:ipv4:62 +ff889d4c3f29da4468ecf1f05f467fe84d35b2a1:lambdas/supplier-mock/.aws-sam/build/SupplierMockFunction/index.js:ipv4:60 +ff889d4c3f29da4468ecf1f05f467fe84d35b2a1:lambdas/supplier-mock/.aws-sam/build/SupplierMockFunction/index.js:ipv4:59 +ff889d4c3f29da4468ecf1f05f467fe84d35b2a1:lambdas/supplier-mock/.aws-sam/build/SupplierMockFunction/index.js:ipv4:24 diff --git a/lambdas/supplier-allocator/src/handler/__tests__/allocate-handler.test.ts b/lambdas/supplier-allocator/src/handler/__tests__/allocate-handler.test.ts index eb1a3bfdb..b4606c4f6 100644 --- a/lambdas/supplier-allocator/src/handler/__tests__/allocate-handler.test.ts +++ b/lambdas/supplier-allocator/src/handler/__tests__/allocate-handler.test.ts @@ -69,7 +69,7 @@ function createPreparedV1Event( requestItemId: "requestItem1", requestItemPlanId: "requestItemPlan1", clientId: "client1", - campaignId: "campaign1", + campaignId: overrides.campaignId ?? "campaign1", templateId: "template1", url: overrides.url ?? "s3://letterDataBucket/letter1.pdf", sha256Hash: @@ -230,6 +230,37 @@ describe("createSupplierAllocatorHandler", () => { }); }); + test("parses SNS notification and sends message to SQS queue for v2 event without a campaignId", async () => { + const preparedEvent = createPreparedV2Event({ campaignId: "" }); + const evt: SQSEvent = createSQSEvent([ + createSqsRecord("msg1", JSON.stringify(preparedEvent)), + ]); + + setupDefaultMocks(); + process.env.UPSERT_LETTERS_QUEUE_URL = "https://sqs.test.queue"; + + const handler = createSupplierAllocatorHandler(mockedDeps); + const result = await handler(evt, {} as any, {} as any); + + expect(result).toBeDefined(); + if (!result) throw new Error("expected BatchResponse, got void"); + + expect(result.batchItemFailures).toHaveLength(0); + + expect(mockSqsClient.send).toHaveBeenCalledTimes(1); + const sendCall = (mockSqsClient.send as jest.Mock).mock.calls[0][0]; + expect(sendCall).toBeInstanceOf(SendMessageCommand); + + const messageBody = JSON.parse(sendCall.input.MessageBody); + expect(messageBody.letterEvent).toEqual(preparedEvent); + expect(messageBody.supplierSpec).toEqual({ + supplierId: "supplier1", + specId: "spec1", + priority: 1, + billingId: "billing1", + }); + }); + test("parses SNS notification and sends message to SQS queue for v1 event", async () => { const preparedEvent = createPreparedV1Event(); diff --git a/lambdas/supplier-allocator/src/handler/allocate-handler.ts b/lambdas/supplier-allocator/src/handler/allocate-handler.ts index 2288fae12..8218a6db8 100644 --- a/lambdas/supplier-allocator/src/handler/allocate-handler.ts +++ b/lambdas/supplier-allocator/src/handler/allocate-handler.ts @@ -144,6 +144,27 @@ function emitMetrics( } } +function emitSupCampaignClientMetric( + letterEvent: PreparedEvents, + supplier: string, + status: string, + deps: Deps, +) { + const namespace = "supplier-allocator"; + const { campaignId, clientId } = letterEvent.data; + const dimensions: Record = { + Supplier: supplier, + ClientId: clientId, + CampaignId: campaignId || "unknown", + }; + const metric: MetricEntry = { + key: status, + value: 1, + unit: Unit.Count, + }; + deps.logger.info(buildEMFObject(namespace, dimensions, metric)); +} + export default function createSupplierAllocatorHandler(deps: Deps): SQSHandler { return async (event: SQSEvent) => { const batchItemFailures: SQSBatchItemFailure[] = []; @@ -153,8 +174,9 @@ export default function createSupplierAllocatorHandler(deps: Deps): SQSHandler { const tasks = event.Records.map(async (record) => { let supplier = "unknown"; let priority = "unknown"; + let letterEvent: PreparedEvents | undefined; try { - const letterEvent: unknown = JSON.parse(record.body); + letterEvent = JSON.parse(record.body) as PreparedEvents; deps.logger.info({ description: "Extracted letter event", @@ -163,8 +185,8 @@ export default function createSupplierAllocatorHandler(deps: Deps): SQSHandler { validateType(letterEvent); - const supplierSpec = getSupplier(letterEvent as PreparedEvents, deps); - await getSupplierFromConfig(letterEvent as PreparedEvents, deps); + const supplierSpec = getSupplier(letterEvent, deps); + await getSupplierFromConfig(letterEvent, deps); supplier = supplierSpec.supplierId; priority = String(supplierSpec.priority); @@ -199,6 +221,12 @@ export default function createSupplierAllocatorHandler(deps: Deps): SQSHandler { ); incrementMetric(perAllocationSuccess, supplier, priority); + emitSupCampaignClientMetric( + letterEvent, + supplier, + "supplier_Campaign_Client", + deps, + ); } catch (error) { deps.logger.error({ description: "Error processing allocation of record",