Business Event
Introduction
When developing modern applications, messaging using event streaming platforms like Apache Kafka is often used to communicate between services. Especially for services with a lot of business logic, it makes sense to complement business use cases by using eventing, so that those events can be consumed by others.
Business Event Support
The Business Event Support Extension establishes an easy way to apply event driven architecture into a domain service, by providing enriched modelling and implementation capabilities.
The extension is available for the following stacks:
- Java Spring Boot Stack 2.0.0 and later
- Java Spring Boot Stack 1.0.0 (only for Domain services and always enabled)
- NodeJS TypeScript Stack (only for Domain services and always enabled)
The extension is only available if Domain Modelling Extension is enabled as well.
Business Event Support offers the capability to model business events within a domain namespace, which indicate, that something happened within in a business context. A business event payload is described by a schema from a shared schema registry which can be managed in the Solution Designer UI. Business events are meant to be consumed by agents, which can be modelled as well within a domain namespace. To learn more about modelling business events, please check Domain Modelling - Events and Domain Modelling - Agents.
For a smooth implementation, there are various code artefacts generated, which allow to easily publish events within a domain context. The necessary dependencies are added to the project automatically and also the connection to the event streaming platform is established out of the box. Besides that, the generated code around agents ensures, that the events can be consumed easily while staying compliant with the schemas used in the payload. To find out more about the implementation capabilities please check Java Spring Boot Implementation and NodeJS TypeScript Implementation.
Event
If you created a project with a version prior to 4.0.5 events are handled differently than documented here. Please check the article around Event Support 1.0 to find out how to deal with events there.
Introduction
Events in IBM Industry Solutions Workbench are used to inform the system that something has happened. They are meant to describe occurences rather related to your business use case than to a technical use case. Additionally, they can trigger a change when they are caught by agents (see domain agents). Events can be triggered across domain and service boundaries.
IBM Industry Solutions Workbench uses Apache Kafka as event/messaging system. Therefore, if you are planning to use events in your project make sure you have configured a connection to at least one Kafka cluster.
If you don't have a running Kafka cluster yet, there is instructions on how to install Apache Kafka in your OpenShift cluster.
In case you already have a running cluster make sure you have at least one Message Hub Service Binding (Kafka binding) configured on Environment level. This service binding can then be referred to from any project modelled with IBM Industry Solutions Workbench . You can configure additional Message Hub Service Bindings at the Project level (for each k5-project) in case you want to use different Kafka clusters depending on the stage your microservices get deployed to (e.g., one cluster for development and one for production use).
The next prerequisite is to have at least one event topic binding configured in Solution Hub so you can refer to it from within Solution Designer. These bindings are used to specify the Kafka topic(s) to use for sending or receiving event messages. Depending on your project's requirements, you have the option to either use just one topic for all related events or use separate topics for each event.
Additionally, it is necessary to have a schema registry provided for using schemas as event payloads. For further details, please check Schemas.
Commands, services and agents can all throw events which in turn are published to an event topic (see event topic binding). In case you are in the user role tm_admin you can also create event topic bindings from within Solution Designer.
Publish events in a Domain Service Project
To publish events within a Domain Service project, they need to be modelled within a domain namespace. A domain event is usually something that happens during the execution of business logic and therefore are named accordingly (e. g. "OrderCreated", "CustomerChanged").
Create a new event
Events are created by using the Create capability on the events tab of a domain namespace's Overview page or within commands and services (see edit commands or edit services).
Events are defined using the following master data:
- Local Identifier: Identifier of the event describing what happened in the business use case. This value must be unique within the namespace. Please note that only the characters A-z (without special characters), digits and the special character "_" are permitted for naming fields! Furthermore, identifiers may not begin with a digit (required)
- Label: Label of the command used for displaying purposes (optional)
- Short Label: Short label of the command used for displaying purposes (optional)
- Event Topic Binding: Binding alias which holds the details about the topic on which the event is going to be published. It is recommended to use one binding per Event so that messages are isolated from each other
- Notes: Useful information regarding the event definition used for displaying purposes (optional)
Define event payload
An event can carry a payload with it which can hold additional information around what happened, e. g. the orderId of the order that has been created or the new name of a customer after it changed.
To ensure governance when dealing with events, schemas from a shared schema registry are used to describe the payload of an event. They act as a reliable contract between event producers and consumers. To learn more about schemas and how they are modelled, please check the article about Schema Introduction and Modelling Schemas.
Within an event, you can define your schema via the Select schema from schema registry capability. IBM Industry Solutions Workbench will offer you all schemas from the connected schema registry. As a schema can evolve over time, multiple versions of the schema can exist. Therefore, the version has to be chosen in the second step. There, you also get an overview of all the properties that are defined for the schema.
When a schema has been used as event payload in the event producer, the same schema is expected to be chosen in the service that consumes the event.
Update schema version of event payload
As requirements change over time, new versions of schemas get created and usually the events want to use the new structure as well.
To update the event to use a new schema version, please use the Change schema version capability on the event page. Select your version of choice in the dropdown and save the changes for updating the event.
It is recommended to not update your event to a schema that has breaking changes to the current one. Otherwise event consumers will fail when they are processing the events. If you have major changes that you want to implement, it is recommended to create a new event publishing on a new topic. After all consumers are adjusted to use the new event, it is safe to delete the "old" one.
It is also possible that the producer service updates to a new version of the schema, while the consumer services still keeps the older version. The consuming of the event will keep working as long as no breaking change in the new schema version.
Implement publishing of events
To learn more about how to publish events please check
Consume event in same service
If you want to consume an event within the same service, it is only required to model an agent which has the desired event as trigger event.
Please check the article about Agents for further details.
With every publishing of the event, the agent will get triggered automatically.
Consume event in another Domain Service
To consume an event published by a Domain Service within another Domain Service, you have to recreate an event on the consuming service.
The event in the consuming service should be named dependending on the business context of the consuming service. Contrary to prior versions, from version 4.0.5 on it is no longer necessary to use equal identifiers in the consuming and producing service
When creating the event in the consuming service, it is important to choose the same topic binding as the one that was chosen for the event in the producing service. The chosen topic binding defines on which topics the consumer is subscribing and therefore decides which messages are processed.
After creating the event, the payload has to be defined. It is required to choose the same schema, which is used in the produing service. It is allowed to use a different version of the schema as long as the versions are not in conflict with each other.
After specifying the event, you have to model an agent which has the your modelled event as trigger event.
Please check the article about Agents for further details.
To isolate messages from each other and to ensure that only dedicated agents are processed, it is recommended to use just one event per topic. If multiple events are assigned to one topic, multiple agents will be processed when a message is published.
Consume event from an external service
If you want to consume an event from an external service, it is also possible using IBM Industry Solutions Workbench .
Implementing this is similar as consuming events from other Domain Services. As a first step, you also have to create a new event in the your Domain Service Project. There you have to ensure that you assign the topic binding on which the external event is published to your event. If a schema exists, which describes the structure of the payload, please select this schema and define it as payload of the event.
Schemas used in external events are supported if they are managed by an Apicurio schema registry and provided in the format of JSON Schema 2019-09
In the next step, create a new agent and assign the created event as trigger event.
Event Support Version 1.0 vs 2.0
In IBM Industry Solutions Workbench version prior to 4.0.5, events were handled differently. The previous version will be called Event Support 1.0 whereas the "new" version will be Event Support 2.0. The Event Support Version can be discovered in the General Information section of your project.
The main changes coming with 2.0 are:
- Event payloads are no longer modelled as entities. Instead, shared schemas modelled in a central schema registry are used
- Event identifiers don't have to be named equally in consumer and producer services
- Event filtering by identifier doesn't happen anylonger. Topics need to be used for isolating events
Even though it's deprecated, it will still be allowed to use Event Support 1.0 to be backwards compatible. All projects created prior 4.0.5 will automatically have Event Support Version 1.0 enabled by default. For projects created from scratch with a version 4.0.5 or higher, the Event Support Version will be set to 2.0 by default.
In Event Support Version 1.0 it is possible to create both events of type 1.0 and events of type 2.0. The distinction will be made automatically depending whether you chose an entity as payload (1.0) or a schema as payload (2.0). This way, you can migrate your service event per event depending on your needs (see Migration documentation).
Consume 1.0 events in a new service
If you want to consume an event from a service that is still based on Event Support 1.0, your consuming service has to use version 1.0 as well. If your version is 2.0, you can navigate to the General Information section of your project and adjust Event Support Version there.
Since Event Support 1.0 is deprecated, it is recommended to rather switch all services to 2.0.
Related links to our learning center
Course Model Events and Agents How-To: Consume an event in Generic Service Projects (Java)Agents
An agent is always bound to exactly one event, but you can create multiple agents bound to the same event if necessary. When this event is published to the event topic, the agent(s) bound to this event will be triggered and then executed.
Create agents
Agents are defined using the following master data:
- Type: There is one option available and this is the Event Agent (required)
- Trigger Event: The event to which the agent will be bound (required)
- Local Identifier: This is the identifier (name) of the agent. It is unique within a namespace. Please note that only the characters A-z (without special characters), digits and the special character "_" are permitted for naming agents! Furthermore, names may not begin with a digit and the first character must be uppercase. Furthermore, names may not begin with a digit and the first character must be uppercase (required)
- Tags: To tag the agent (optional)
Agents cannot have the same Local Identifier as a command or a service in the same namespace.
Edit agents
You can edit the master data of a agent by clicking the Edit agent details button in the Agent Details section on the agent's instance page. Alternatively, you can use the Edit capability of each table row on the Agents tab of a domain namespace's Overview page. The fields that can be edited are Local Identifier and Trigger Event.
It's not possible to edit the Type of an agent.
Delete agents
You can delete a agent by clicking the Delete agent button in the upper right corner of the agent instance page. Alternatively, you can use the Delete capability of each table row on the Agents tab of a domain namespace's Overview page.
You will need to confirm the action before the selected agent gets permanently deleted.
Known limitations
Domain Service Projects (Java)
Currently it is not possible to retrieve events, if the payload is a parent entity and children entities are sent as playload.
Related links to our learning center
Course Model Events and AgentsEvents 1.0 (Deprecated)
This feature is deprecated and will be removed by 06/2025. It is recommended to switch to event support 2.0 (see Migration documentation)
Introduction
Events are used to inform the system that something has happened. They are meant to describe business occurrences and not technical. Additionally, they can trigger a change when they are caught by agents ( see domain agents). Events can be triggered across aggregate and domain boundaries.
IBM Industry Solutions Workbench uses Apache Kafka as event/messaging system. Therefore, if you are planning to use events in your project make sure you have configured a connection to at least one Kafka cluster.
If you don't have a running Kafka cluster yet, there is instructions on how to install Apache Kafka in your OpenShift cluster.
In case you already have a running cluster make sure you have at least one Message Hub Service Binding (Kafka binding) configured on Environment level. This service binding can then be referred to from any project modelled with IBM Industry Solutions Workbench . You can configure additional Message Hub Service Bindings at the Project level (for each k5-project) in case you want to use different Kafka clusters depending on the stage your microservices get deployed to (e.g., one cluster for development and one for production use).
The next prerequisite is to have at least one event topic binding configured in Solution Hub so you can refer to it from within Solution Designer. These bindings are used to specify the Kafka topic(s) to use for sending or receiving event messages. Depending on your project's requirements, you have the option to either use just one topic for all related events or use separate topics for each event.
Commands, services and agents can all throw events which in turn are published to an event topic (see event topic bindings). In case you are in the user role tm_admin you can also create event topic bindings from within Solution Designer.
Modelling events
IBM Industry Solutions Workbench supports three different use cases in combination with events. The first one is the Internal Event, meaning that sending and receiving an event happens in the same project. So you might publish an event in one domain namespace and model an agent to listen for it in another domain namespace. This way you could separate the logic into two parts making it easier to maintain and to evolve the business logic. See modelling internal events for further details.
The second use case is to send events from one microservice and receive it in another microservice. Both of these microservices have been modelled and implemented with IBM Industry Solutions Workbench . That's what we call a cross-solution event. See modelling cross-service events for further details.
The last use case is to send and receive events from and to external systems, meaning that
- the Producer is built with IBM Industry Solutions Workbench but the Consumer is an external application
- the Consumer is built with IBM Industry Solutions Workbench but the Producer is an external application
The support for this use case is still limited in IBM Industry Solutions Workbench but there is some workaround described at external events.
Internal events
Internal events are used within a single project to publish a business occurrence from one domain namespace and trigger an action in another domain namespace.
To do so,
- create the event in the domain namespace that should publish the event
- add a payload entity
- go to the second domain namespace that should receive the event ( see create Domain Namespaces)
- create an agent
- select the event you created before from the drop-down
This agent will get triggered whenever an event with this Local Identifier (which will be used as the message key) gets published to the topic specified by the event topic binding. You can later implement what this agent should call, e.g. a domain service, an integration service or you could even call factory commands or instance commands to create new root entities or to update their state and persist them.
Cross-project events
Please be aware that there are some limitations when trying to use the same event between two projects with
different implementation languages (e.g., a TypeScript project and a Java project). Due to different implementation of
some (numeric) property types there may be issues with consuming the payload. In case you already plan to use different
implementation languages we recommend to use only properties of type: string
in the event payload. This datatype is
equal in all implementations and allows proper consumption.
One of the most common use cases with events is to publish an event in one microservice and react on it in another microservice. These cross-service events will only work if both microservices have been modelled and implemented with IBM Industry Solutions Workbench . If you want to react on events that are published by external applications or publish an event and react with an external application, please see external events.
In the following example we will use two projects projectA and projectB, where projectA will publish an event and projectB will receive the event (see setting up projects for further details on creating new projects). All used names are just for the example, meaning you are totally free to name your events, namespaces and topics however you want. Just make sure they match between the two projects.
Modelling the publishing project
projectA has a domain namespace with the prefix dom1 ( see create Domain Namespaces) and a domain service called RaiseEventOne (see create services) that will publish the event. Furthermore, there is an event topic binding called eventTopic1 that specifies the Kafka topic named event-topic-1 to be used (don't forget to set this value either when creating the event or inside Solution Hub).
Follow the instructions below to create the event.
- Inside the domain namespace dom1 create an event called Eve1
- Use the drop-down event topic binding to select the binding called eventTopic1
- Add a payload entity with properties as needed
- Commit & Push your changes
Modelling the receiving project
projectB also needs a domain namespace to model an agent that subscribes to the same topic and listens for the associated event.
The domain namespace in the project that should receive the event MUST have the exact same prefix as the domain namespace that publishes the event! Also, the event MUST have the exact same Local Identifier as the event in the publishing project!
Therefore,
- Create a domain namespace and set the prefix to dom1 (the label doesn't have to be the same as in the other project)
- Create an event called Eve1 inside the domain namespace dom1
- Use the drop-down event topic binding to select the binding called eventTopic1
- Add a payload entity with the exact same properties as the payload entity of the publishing project's event (open a second browser tab to compare both event payloads)
- Create an agent inside the domain namespace dom1 and select the event dom1:Eve1 as Trigger Event
- You can use any name as the Local Identifier for this Agent
- Commit & Push your changes
An agent subscribes to the Kafka topic that is specified in the associated event topic binding and listens for
messages that have a message key that equals the Local Identifier of the Trigger Event. The message key would
be dom1:Eve1
in this example.
External events
Handling external events is still limited in IBM Industry Solutions Workbench . You can of course publish events to arbitrary Kafka topics and consume them with any Kafka client you implemented. Therefore, you just need to provide the necessary info regarding the event message to your external application.
Below you can find a sample event message to help you implement your external application to use events published by projects built with IBM Industry Solutions Workbench. This project has
- a domain namespace with the prefix: procs
- an event with the Local Identifier: Testeve
- a payload entity for this event with the Identifier: procs:Testeve_Payload
- a property called title of type String
- a property called message of type String
No matter to which topic this event will be published, it will have a message key with the
value: procs:Testeve
which your external application can listen for.
Event Message Payload Structure:
{
"type": "procs:Testeve_Payload",
"id": "e93f0c71-d9a2-4ee6-a22d-fc39fddd8d54",
"title": "The title",
"message": "This is the message body"
}
The value for "id" will change on every message. You can use a UUID when sending events.
There will be cases when you want to react on an event that has been published by an external application with a microservice that has been built with IBM Industry Solutions Workbench . Due to the limitations regarding the message key (that is built by concatenating the domain namespace's prefix with the local identifier of the event) it is currently not possible to model agents for arbitrary events.
You can still consume event messages that have been published by external applications with microservices built with IBM Industry Solutions Workbench as long as you use a valid message key and model an appropriate event payload inside Solution Designer.
This message key MUST follow the syntax: prefix:local_identifier and must match the values of the project that should receive the event message.
So if you have the chance to set the message key to the value that the Agent would expect, you can consume external events within IBM Industry Solutions Workbench .
Example:
You want to consume an event with an agent in the domain namespace with the prefix: dom1.
Therefore, you need to model the event inside this domain namespace accordingly to the payload of the event. Let's say you use Event1 as the Local Identifier of that event in Solution Designer. Then, inside the implementation of your external application you would specify the message key to be:
dom1:Event1
With this approach, you are able to consume external events with an Agent.
There will be support for creating Agents that listen for arbitrary events (and their message key) in upcoming releases.
Create events
events are created by using the Create capability on the events tab of a domain namespace's Overview page or when editing commands and services (see edit commands or edit services).
Events are defined using the following master data:
- Local Identifier: Identifier of the command. this value must be unique within the namespace and cannot be changed afterwards. Please note that only the characters A-z (without special characters), digits and the special character "_" are permitted for naming fields! Furthermore, identifiers may not begin with a digit (required)
- Label: Label of the command (optional)
- Short Label: Short label of the command (optional)
- Event Topic Binding: Select the event topic binding that holds the information to about the topic to use (required)
- Notes: Useful information regarding the command definition (optional)
Add event payload
It is possible to add an entity as payload to the event in case the event should carry data. You can choose between
- Create new private entity
- Select existing entity
To add properties to the payload entity click on the Add capability and choose
- Create new property
- Associate existing property
See domain properties for further details on creating properties.
It is not possible to have an array of entities as event payload. But you can of course create an entity with a property that is an array.
Edit events
You can edit the master data using the Info capability on the event's instance page and navigating to the section Master Data.
The following fields can be edited:
- Label
- Short Label
- Event Topic Binding
- Notes
It's not possible to edit the Local Identifier of an event.
Delete events
You can delete an event by using the row capability Delete in the table of the events tab of the domain namespace's Overview page.
You will need to confirm the action before the selected event gets permanently deleted. You can only delete an event if it is not in use. You can check the usages of an event by using the Info capability and navigating the Usages section.