@message-queue-toolkit/core
Version:
Useful utilities, interfaces and base classes for message queue handling. Supports AMQP and SQS with a common abstraction on top currently
142 lines • 5.79 kB
JavaScript
export class AbstractPublisherManager {
publisherFactory;
newPublisherOptions;
metadataFiller;
metadataField;
// In this context "target" can be a topic or an exchange, depending on the transport
targetToEventMap = {};
isAsync;
targetToPublisherMap = {};
publisherDependencies;
constructor({ publisherFactory, newPublisherOptions, publisherDependencies, metadataFiller, eventRegistry, metadataField, isAsync, }) {
this.publisherFactory = publisherFactory;
this.newPublisherOptions = newPublisherOptions;
this.metadataFiller = metadataFiller;
this.metadataField = metadataField;
this.isAsync = isAsync;
this.publisherDependencies = publisherDependencies;
this.registerEvents(eventRegistry.supportedEvents);
this.registerPublishers();
}
resolvePublisherConfigOverrides(_eventTarget) {
return {};
}
registerEvents(events) {
for (const supportedEvent of events) {
const eventTarget = this.resolveEventTarget(supportedEvent);
if (!eventTarget) {
continue;
}
if (!this.targetToEventMap[eventTarget]) {
this.targetToEventMap[eventTarget] = [];
}
this.targetToEventMap[eventTarget].push(supportedEvent);
}
}
registerPublishers() {
for (const eventTarget in this.targetToEventMap) {
if (this.targetToPublisherMap[eventTarget]) {
continue;
}
const messageSchemas = this.targetToEventMap[eventTarget].map((entry) => {
return entry.consumerSchema;
});
const creationConfig = this.resolveCreationConfig(eventTarget);
const configOverrides = this.resolvePublisherConfigOverrides(eventTarget);
this.targetToPublisherMap[eventTarget] = this.publisherFactory.buildPublisher(this.publisherDependencies, {
...this.newPublisherOptions,
creationConfig,
messageSchemas,
...configOverrides,
});
}
}
async initRegisteredPublishers(publishersToInit) {
if (publishersToInit) {
for (const eventTarget of publishersToInit) {
const resolvedPublisher = this.targetToPublisherMap[eventTarget];
if (!resolvedPublisher) {
throw new Error(`Unsupported publisher ${eventTarget}`);
}
await resolvedPublisher.init();
}
return;
}
for (const eventTarget in this.targetToPublisherMap) {
await this.targetToPublisherMap[eventTarget].init();
}
}
injectPublisher(eventTarget, publisher) {
this.targetToPublisherMap[eventTarget] = publisher;
}
injectEventDefinition(eventDefinition) {
const eventTarget = this.resolveEventTarget(eventDefinition);
if (!eventTarget) {
throw new Error('eventTarget could not be resolved for the event');
}
if (!this.targetToEventMap[eventTarget]) {
this.targetToEventMap[eventTarget] = [];
}
this.targetToEventMap[eventTarget].push(eventDefinition);
}
async publish(eventTarget, message, precedingEventMetadata, messageOptions) {
const publisher = this.targetToPublisherMap[eventTarget];
if (!publisher) {
throw new Error(`No publisher for target ${eventTarget} - did you perhaps forget to update supportedEvents passed to EventRegistry?`);
}
const messageDefinition = this.resolveMessageDefinition(eventTarget, message);
if (!messageDefinition) {
throw new Error(`MessageDefinition for target "${eventTarget}" and type "${message.type}" not found in EventRegistry`);
}
const resolvedMessage = this.resolveMessage(messageDefinition, message, precedingEventMetadata);
if (this.isAsync) {
await publisher.publish(resolvedMessage, messageOptions);
}
else {
publisher.publish(resolvedMessage, messageOptions);
}
return resolvedMessage;
}
resolveMessageDefinition(eventTarget, message) {
// ToDo optimize the lookup
return this.targetToEventMap[eventTarget].find((entry) => entry.consumerSchema.shape.type.value === message.type);
}
resolveMessage(messageDefinition, message, precedingEventMetadata) {
const producedMetadata = this.metadataFiller.produceMetadata(
// @ts-ignore
message, messageDefinition, precedingEventMetadata);
// @ts-ignore
const resolvedMetadata = message[this.metadataField]
? {
...producedMetadata,
// @ts-ignore
...message[this.metadataField],
}
: // @ts-ignore
producedMetadata;
// @ts-ignore
return {
id: this.metadataFiller.produceId(),
timestamp: this.metadataFiller.produceTimestamp(),
...message,
metadata: resolvedMetadata,
};
}
resolveBaseFields() {
return {
id: this.metadataFiller.produceId(),
timestamp: this.metadataFiller.produceTimestamp(),
};
}
/**
* @param eventTarget - topic or exchange
*/
handlerSpy(eventTarget) {
const publisher = this.targetToPublisherMap[eventTarget];
if (!publisher) {
throw new Error(`No publisher for target ${eventTarget} - did you perhaps forget to update supportedEvents passed to EventRegistry?`);
}
return publisher.handlerSpy;
}
}
//# sourceMappingURL=AbstractPublisherManager.js.map