@@ -10,10 +10,7 @@ import { getErrorMessage } from '@sim/utils/errors'
1010import { toRecord } from '@sim/utils/object'
1111import { truncate } from '@sim/utils/string'
1212import { getEventsQueueClient } from '@/lib/billing/aws-marketplace/client'
13- import {
14- findAwsMarketplaceProduct ,
15- getAwsMarketplaceProductCodes ,
16- } from '@/lib/billing/aws-marketplace/config'
13+ import { getAwsMarketplaceProducts } from '@/lib/billing/aws-marketplace/config'
1714import {
1815 isInvalidEntitlementRequest ,
1916 verifyLicense ,
@@ -84,8 +81,8 @@ interface AwsMarketplaceReconcileSummary {
8481type BudgetCheck = ( workMs : number ) => boolean
8582
8683interface DrainContext {
87- /** Every configured product ; an event for any other product is not ours to apply . */
88- productCodes : readonly string [ ]
84+ /** This run's configured products, by code ; an event for any other product is not ours. */
85+ products : ReadonlyMap < string , AwsMarketplaceProduct >
8986 queueUrl : string
9087 summary : AwsMarketplaceReconcileSummary
9188 fits : BudgetCheck
@@ -225,15 +222,13 @@ async function applyAgreementEnded(
225222 message : Message
226223) : Promise < MessageOutcome > {
227224 const messageId = message . MessageId
228- const licenses = await listLicensesForAgreement ( context . productCodes , agreementId )
225+ const licenses = await listLicensesForAgreement ( context . products , agreementId )
229226 if ( licenses . length === 0 ) {
230227 logger . info ( 'Ignoring an AWS Marketplace agreement event for no stored license' , { messageId } )
231228 return 'discarded'
232229 }
233230 let incomplete = false
234- for ( const [ index , { licenseArn, productCode } ] of licenses . entries ( ) ) {
235- const product = findAwsMarketplaceProduct ( productCode )
236- if ( ! product ) continue
231+ for ( const [ index , { licenseArn, product } ] of licenses . entries ( ) ) {
237232 if ( ! context . fits ( LICENSE_READ_BUDGET_MS ) ) {
238233 context . summary . outOfBudget = true
239234 return 'retained'
@@ -264,10 +259,11 @@ async function applyAgreementEnded(
264259}
265260
266261async function applyLicenseEvent (
262+ context : DrainContext ,
267263 event : Extract < MarketplaceEvent , { kind : 'license' } > ,
268264 messageId : string | undefined
269265) : Promise < MessageOutcome > {
270- const product = findAwsMarketplaceProduct ( event . productCode )
266+ const product = event . productCode ? context . products . get ( event . productCode ) : undefined
271267 if ( ! product ) {
272268 logger . warn ( 'Discarding an AWS Marketplace event for another product' , { messageId } )
273269 return 'discarded'
@@ -309,24 +305,24 @@ async function applyEvent(
309305 event : MarketplaceEvent ,
310306 message : Message
311307) : Promise < MessageOutcome > {
312- const { productCodes } = context
308+ const { products } = context
313309 const messageId = message . MessageId
314- if ( event . kind === 'license' ) return applyLicenseEvent ( event , messageId )
310+ if ( event . kind === 'license' ) return applyLicenseEvent ( context , event , messageId )
315311 if ( event . kind === 'agreement-ended' ) {
316312 return applyAgreementEnded ( context , event . agreementId , message )
317313 }
318314 const involved =
319315 event . kind === 'advisory'
320316 ? await enqueueAgreementAdvisory ( {
321- productCodes ,
317+ products ,
322318 agreementId : event . agreementId ,
323319 state : event . state ,
324320 detail : event . detail ,
325321 messageId : messageId ?? event . agreementId ,
326322 } )
327323 : event . previousAgreementId
328324 ? await applyAgreementRenewal ( {
329- productCodes ,
325+ products ,
330326 previousAgreementId : event . previousAgreementId ,
331327 agreementId : event . agreementId ,
332328 } )
@@ -418,15 +414,13 @@ async function drainEvents(context: DrainContext): Promise<void> {
418414}
419415
420416async function reverifyStaleLicenses (
421- productCodes : readonly string [ ] ,
417+ products : ReadonlyMap < string , AwsMarketplaceProduct > ,
422418 summary : AwsMarketplaceReconcileSummary ,
423419 fits : BudgetCheck
424420) : Promise < void > {
425421 const cutoff = new Date ( Date . now ( ) - REVERIFY_AFTER_MS )
426- const licenses = await listLicensesDueForReverify ( productCodes , cutoff , REVERIFY_BATCH_SIZE )
427- for ( const { licenseArn, productCode } of licenses ) {
428- const product = findAwsMarketplaceProduct ( productCode )
429- if ( ! product ) continue
422+ const licenses = await listLicensesDueForReverify ( products , cutoff , REVERIFY_BATCH_SIZE )
423+ for ( const { licenseArn, product } of licenses ) {
430424 if ( ! fits ( LICENSE_READ_BUDGET_MS ) ) {
431425 summary . outOfBudget = true
432426 return
@@ -450,8 +444,8 @@ async function reverifyStaleLicenses(
450444 * feature is off.
451445 */
452446export async function reconcileAwsMarketplaceLicenses ( ) : Promise < AwsMarketplaceReconcileSummary | null > {
453- const productCodes = getAwsMarketplaceProductCodes ( )
454- if ( productCodes . length === 0 ) return null
447+ const products = getAwsMarketplaceProducts ( )
448+ if ( products . size === 0 ) return null
455449 const summary : AwsMarketplaceReconcileSummary = {
456450 received : 0 ,
457451 applied : 0 ,
@@ -465,7 +459,7 @@ export async function reconcileAwsMarketplaceLicenses(): Promise<AwsMarketplaceR
465459 const startedAt = Date . now ( )
466460 const fits : BudgetCheck = ( workMs ) => Date . now ( ) - startedAt + workMs <= RUN_BUDGET_MS
467461 const queueUrl = env . AWS_MARKETPLACE_EVENTS_QUEUE_URL
468- if ( queueUrl ) await drainEvents ( { productCodes , queueUrl, summary, fits } )
469- await reverifyStaleLicenses ( productCodes , summary , fits )
462+ if ( queueUrl ) await drainEvents ( { products , queueUrl, summary, fits } )
463+ await reverifyStaleLicenses ( products , summary , fits )
470464 return summary
471465}
0 commit comments