// reflect-metadata polyfill should be imported once in the entire application because the Reflect object is meant to be a global singleton. import 'reflect-metadata'; import { Context, SQSEvent } from 'aws-lambda'; import { ApplicationContainer } from '../../app/application-container'; import { Event } from '../events/event'; import { EventHandler } from '../handler/event-handler.interface'; import { HandlesEventService } from '../handler/handles-event.service'; // cache container instance if we get the same lambda container let _applicationContainer: ApplicationContainer; /** * Broker each SQS message to the registered event handlers. * @param event * @param context */ export const handler = async (event: SQSEvent, context: Context): Promise<void> => { if (!_applicationContainer) { _applicationContainer = ApplicationContainer.instance(); } _applicationContainer.logger.debug('Queue Broker: %o', event); // process each record by calling registered handlers for the event type for (const record of event.Records) { const currentEvent: Event = JSON.parse(record.body); // call handlers for this event for (const handlerName of HandlesEventService.getHandlers(currentEvent.$name)) { await callHandler(currentEvent, handlerName); } }; }; /** * Get and call Event Handler. * @param currentEvent * @param handlerName */ const callHandler = async (currentEvent: Event, handlerName: string): Promise<void> => { const handler = _applicationContainer.get<EventHandler>(handlerName); if (handler) { await handler.handle(currentEvent) .then(() => _applicationContainer.logger.debug('Successfully called Handler %s for event %o', handlerName, currentEvent)) .catch(err => _applicationContainer.logger.error('Error in Handler %s for event %o: %o', handlerName, currentEvent, err)); } else { _applicationContainer.logger.error('Event Handler %s not found for event %o', handlerName, currentEvent); } }