Skip to main content

Business Events: Implement Events and Agents

Publish Events

Using the Business Event Support extension, additional code will be generated, which allows to easily publish an event.

Event factory

For creating an event, the event factory can be used in commands, services and agents, which have events associated. The return value of the factory methods are objects, which e.g. provide methods to set the payload and publish the event.

The code below shows and example of how to create a new event object by using the factory:

// Create an event using event factory
const event1 = this.factory.event.nsacrnm.EventIdentifier();

// Set event payload
event1.payload = payload;

// publish event
await event1.publish();

Publish events

For each event, the payload, a custom message key and custom headers can be set. At publishing, the event is published to the Kafka topic, which was specified at the event while modelling.

ℹ️note

When setting custom message headers for schema type events, the header key 'apicurio.value.globalId' is reserved and will be overwritten by the sdk, as it is used for integration purposes.

The code below shows how to define a payload for the event (using a schema from the schema registry), set a custom message key and custom headers:

import { schemaRegistry } from 'solution-framework';

/**
* Event publishing in Command or Service
*/
public async execute(): Promise<void> {

// create a new event instance
const event = this.factory.event.domainNs.OrderAccepted();

// Create payload object using the type defined in schemaRegistry
const payload: schemaRegistry.SchemaName = {
property1: 'val'
}
event.payload = payload;

// set message key (optional)
event.messageKey = 'customMessageKey';

// set message headers (optional)
event.messageHeaders = {
'headerKey': 'headerValue',
}

// Publish the event
await event.publish();
}
warning

Using time property in an entity as event payload is not compatible with Java events using properties of type time due to different implementation between Node.js and Java stacks. Consider migrating to schema payloads for events.

Publish event using entity as payload (deprecated)

An event using an entity as payload is published by using the structure of the following code, however this is deprecated and it is recommended to use schemas from the schema registry instead.

In this case, it is allowed to set custom message headers for the event, but no custom message key is allowed.

  /**
* Event publishing in Command or Service
*/
public async execute(): Promise<void> {

// create a new event instance
const event = this.factory.event.domainNs.OrderAccepted();

// Create payload entity for event and set values
event.payload = this.factory.entity.domainNs.OrderAccepted_Payload();
payload.property1 = value1;

// set message headers (optional)
event.messageHeaders = {
'headerKey': 'headerValue',
}

// Publish the event
await event.publish();
}

Implement Agents

A published event will automatically trigger the agents, which have the event assigned as trigger event. The payload provided in the event will be available as input in the agent. Besides that, any kind of logic can be implemented in an agent (e. g. calling another service).

Within the agent implementation, the message key, the message headers and the message timestamp are available and can be used. Both custom headers as well as commonly used headers can be accessed here.

  /**
* Agent execution
*/
public async execute(): Promise<void> {
const log = this.util.log;

// Get the payload from the event that triggered the agent
const { property1 } = this.input;

// log message key
log.info(`Message key: ${this.messageKey}`);

// log value of my custom header, wich has a string as value
const strHeaderValue = this.messageHeaders['customHeader1'].toString();
log.info(`Custom header "customHeader1" has value: ${strHeaderValue}`);

// log value of another header, which has Buffer as value
const bufHeaderValue = this.messageHeaders['customHeader2'].toString();
log.info(`Custom header "customHeader2" has value: ${bufHeaderValue}`);

// log value of message timestamp in the format of an ISO String
const msgTime = new Date(this.messageTimestamp);
log.info(`Message timestamp: ${msgTime.toISOString()}`)

// Initialize input for calling another service
const input = this.factory.entity.order.ServiceIdentifier_Input();

// Set the value from the event payload as input value
input.property1 = property1;

// Call service and pass as input the input entity created above
await this.services.order.ServiceIdentifier(input);
}