@@ -17,13 +17,11 @@ import { CreateHealthCheckCommand, Route53Client } from "@aws-sdk/client-route-5
1717import { defaultProvider } from "@aws-sdk/credential-provider-node" ;
1818import { SignatureV4MultiRegion } from "@aws-sdk/signature-v4-multi-region" ;
1919import { HttpRequest } from "@smithy/protocol-http" ;
20- import { beforeAll , describe , expect , it , vi } from "vitest" ;
20+ import { afterAll , beforeAll , describe , expect , it , vi } from "vitest" ;
2121
2222const LONG_TIMEOUT = 5 * 60 * 1000 ;
23- const POLLING_DELAY = 5000 ;
24- const MAX_POLLING_ATTEMPTS = 40 ;
2523
26- // long -lived resources
24+ // Long -lived resources
2725const RESOURCE_PREFIX = "jsv3-e2e-global" ;
2826
2927const wait = ( ms : number ) => new Promise ( ( resolve ) => setTimeout ( resolve , ms ) ) ;
@@ -55,6 +53,7 @@ describe("EventBridge Client with SignatureV4a", () => {
5553 let primaryEventBusArn : string | undefined ;
5654 let secondaryEventBusArn : string | undefined ;
5755 let healthCheckId : string | undefined ;
56+ let endpointArn : string | undefined ;
5857
5958 beforeAll ( async ( ) => {
6059 vi . setConfig ( { hookTimeout : LONG_TIMEOUT } ) ;
@@ -78,64 +77,60 @@ describe("EventBridge Client with SignatureV4a", () => {
7877 signer,
7978 } ) ;
8079
81- try {
82- eventBusName = `${ RESOURCE_PREFIX } -bus` ;
83- endpointName = `${ RESOURCE_PREFIX } -endpoint` ;
80+ eventBusName = `${ RESOURCE_PREFIX } -bus` ;
81+ endpointName = `${ RESOURCE_PREFIX } -endpoint` ;
8482
85- const managementClient = new EventBridgeClient ( { region : primaryRegion } ) ;
86- try {
87- await managementClient . send ( new DescribeEndpointCommand ( { Name : endpointName } ) ) ;
88- } catch ( error : any ) {
89- if ( error . name === "ResourceNotFoundException" ) {
90- // Create resources if they don't exist
91- const primaryBus = await primaryEbClient . send ( new CreateEventBusCommand ( { Name : eventBusName } ) ) ;
92- primaryEventBusArn = primaryBus . EventBusArn ;
93-
94- const secondaryBus = await secondaryEbClient . send ( new CreateEventBusCommand ( { Name : eventBusName } ) ) ;
95- secondaryEventBusArn = secondaryBus . EventBusArn ;
96-
97- const healthCheck = await route53Client . send (
98- new CreateHealthCheckCommand ( {
99- CallerReference : `${ RESOURCE_PREFIX } -${ Date . now ( ) } ` ,
100- HealthCheckConfig : {
101- Type : "HTTP" ,
102- FullyQualifiedDomainName : "example.com" ,
103- Port : 80 ,
104- ResourcePath : "/" ,
105- RequestInterval : 30 ,
106- FailureThreshold : 3 ,
107- } ,
108- } )
109- ) ;
110- healthCheckId = healthCheck . HealthCheck ?. Id ;
111- await wait ( 10000 ) ;
112-
113- const createEndpointResponse = await managementClient . send (
114- new CreateEndpointCommand ( {
115- Name : endpointName ,
116- RoutingConfig : {
117- FailoverConfig : {
118- Primary : { HealthCheck : `arn:aws:route53:::healthcheck/${ healthCheckId } ` } ,
119- Secondary : { Route : secondaryRegion } ,
120- } ,
83+ const managementClient = new EventBridgeClient ( { region : primaryRegion } ) ;
84+ try {
85+ const existingEndpoint = await managementClient . send ( new DescribeEndpointCommand ( { Name : endpointName } ) ) ;
86+ endpointArn = existingEndpoint . Arn ;
87+ } catch ( error : any ) {
88+ if ( error . name === "ResourceNotFoundException" ) {
89+ const primaryBus = await primaryEbClient . send ( new CreateEventBusCommand ( { Name : eventBusName } ) ) ;
90+ primaryEventBusArn = primaryBus . EventBusArn ;
91+
92+ const secondaryBus = await secondaryEbClient . send ( new CreateEventBusCommand ( { Name : eventBusName } ) ) ;
93+ secondaryEventBusArn = secondaryBus . EventBusArn ;
94+
95+ const healthCheck = await route53Client . send (
96+ new CreateHealthCheckCommand ( {
97+ CallerReference : `${ RESOURCE_PREFIX } -${ Date . now ( ) } ` ,
98+ HealthCheckConfig : {
99+ Type : "HTTP" ,
100+ FullyQualifiedDomainName : "example.com" ,
101+ Port : 80 ,
102+ ResourcePath : "/" ,
103+ RequestInterval : 30 ,
104+ FailureThreshold : 3 ,
105+ } ,
106+ } )
107+ ) ;
108+ healthCheckId = healthCheck . HealthCheck ?. Id ;
109+ await wait ( 10000 ) ;
110+
111+ const createEndpointResponse = await managementClient . send (
112+ new CreateEndpointCommand ( {
113+ Name : endpointName ,
114+ RoutingConfig : {
115+ FailoverConfig : {
116+ Primary : { HealthCheck : `arn:aws:route53:::healthcheck/${ healthCheckId } ` } ,
117+ Secondary : { Route : secondaryRegion } ,
121118 } ,
122- ReplicationConfig : { State : ReplicationState . DISABLED } ,
123- EventBuses : [ { EventBusArn : primaryEventBusArn } , { EventBusArn : secondaryEventBusArn } ] ,
124- } )
125- ) ;
126- } else {
127- throw error ;
128- }
129- } finally {
130- managementClient . destroy ( ) ;
119+ } ,
120+ ReplicationConfig : { State : ReplicationState . DISABLED } ,
121+ EventBuses : [ { EventBusArn : primaryEventBusArn } , { EventBusArn : secondaryEventBusArn } ] ,
122+ } )
123+ ) ;
124+ endpointArn = createEndpointResponse . Arn ;
125+ } else {
126+ throw error ;
131127 }
132- } catch ( error ) {
133- console . error ( "Error during setup:" , error ) ;
134- throw error ;
128+ } finally {
129+ managementClient . destroy ( ) ;
135130 }
136131 } , LONG_TIMEOUT ) ;
137132
138- beforeAll ( async ( ) => {
133+ afterAll ( async ( ) => {
139134 primaryEbClient ?. destroy ( ) ;
140135 secondaryEbClient ?. destroy ( ) ;
141136 route53Client ?. destroy ( ) ;
@@ -184,39 +179,15 @@ describe("EventBridge Client with SignatureV4a", () => {
184179 it (
185180 "should send an event to an EventBridge Global Endpoint using SignatureV4a" ,
186181 async ( ) => {
187- let attempts = 0 ;
188- let currentState : EndpointState | string | undefined ;
189- let endpointUrl : string | undefined ;
190182 const managementClient = new EventBridgeClient ( { region : primaryRegion } ) ;
191-
192- while ( attempts < MAX_POLLING_ATTEMPTS ) {
193- attempts ++ ;
194- try {
195- const describeResponse = await managementClient . send ( new DescribeEndpointCommand ( { Name : endpointName } ) ) ;
196- currentState = describeResponse . State ;
197- if ( currentState === EndpointState . ACTIVE ) {
198- endpointUrl = describeResponse . EndpointUrl ;
199- break ;
200- }
201- if ( currentState === EndpointState . CREATE_FAILED || currentState === EndpointState . UPDATE_FAILED ) {
202- throw new Error ( `Endpoint entered failed state: ${ currentState } ` ) ;
203- }
204- } catch ( error ) {
205- console . warn ( `DescribeEndpoint failed (attempt ${ attempts } ):` , error ) ;
206- }
207- await wait ( POLLING_DELAY ) ;
208- }
183+ const describeResponse = await managementClient . send ( new DescribeEndpointCommand ( { Name : endpointName } ) ) ;
209184 managementClient . destroy ( ) ;
210185
211- if ( currentState !== EndpointState . ACTIVE ) {
212- throw new Error ( `Endpoint ${ endpointName } did not become ACTIVE after ${ attempts } attempts.` ) ;
213- }
214- expect ( endpointUrl ) . toBeDefined ( ) ;
186+ expect ( describeResponse . State ) . toBe ( EndpointState . ACTIVE ) ;
187+ expect ( describeResponse . EndpointUrl ) . toBeDefined ( ) ;
215188
216- const endpointSubdomain = getSubdomainFromUrl ( endpointUrl ) ;
217- if ( ! endpointSubdomain ) {
218- throw new Error ( `Failed to extract subdomain from Endpoint URL: ${ endpointUrl } ` ) ;
219- }
189+ const endpointSubdomain = getSubdomainFromUrl ( describeResponse . EndpointUrl ) ;
190+ expect ( endpointSubdomain ) . toBeDefined ( ) ;
220191
221192 const putEventsInput : PutEventsCommandInput = {
222193 Entries : [
@@ -236,6 +207,9 @@ describe("EventBridge Client with SignatureV4a", () => {
236207 expect ( putEventsResponse . FailedEntryCount ) . toBe ( 0 ) ;
237208 expect ( putEventsResponse . Entries ) . toHaveLength ( 1 ) ;
238209 expect ( putEventsResponse . Entries ?. [ 0 ] ?. EventId ) . toBeDefined ( ) ;
210+ // Note: Verifying the event *arrived* in the target bus (primary or secondary)
211+ // would require additional setup and is omitted
212+ // here to focus on the PutEvents call itself succeeding with SigV4a.
239213 } ,
240214 LONG_TIMEOUT
241215 ) ;
0 commit comments