Modelling Events

General Information

IBM Financial Services 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 Financial Services 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.

Tip: In case you are in the user role tm_admin you can also create Event Topic Bindings from within Solution Designer.

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,

  1. create the event in the domain namespace that should publish the event

  2. add a payload entity

  3. go to the second domain namespace that should receive the event (see Create Domain Namespaces)

  4. create an Agent

  5. 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-Solution Events

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-Solution Events will only work if both microservices have been modelled and implemented with IBM Financial Services 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 this 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).

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.

Follow the instructions below to create the event.

  1. Inside the domain namespace dom1 create an event called Eve1

  2. Use the drop-down Event Topic Binding to select the binding called eventTopic1

  3. Add a payload entity with properties as needed

  4. 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.

Attention: 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,

  1. Create a Domain Namespace with prefix set to dom1 (the label doesn't have to be the same as in the other project)

  2. Inside the domain namespace dom1 create an event called Eve1

  3. Use the drop-down Event Topic Binding to select the binding called eventTopic1

  4. 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)

  5. Commit & Push your changes

Note: 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 Financial Services Workbench 2.9. 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 implementing your external application to use events published by projects built with IBM Financial Services Workbench. This project has

  • a solution acronym: CNR

  • a domain namespace with the prefix: sconr

  • an event with the Local Identifier: OfferAccepted

  • a payload entity for this event called OfferAccepted_Payload

  • a property called customerNeedIdentifier of type String

  • a property called financialProposalId of type String

Note: No matter to which topic this event will be published, it will have a message key with the value: sconr:OfferAccepted which your external application can listen for.

Each event message on the broker will consist also of a JSON Schema to declare the payload's structure.

Event Message Payload Structure:

{
    "_jsonSchema": {
        "identifier": "sconr:OfferAccepted_Payload",
        "title": "Offer Accepted Payload",
        "type": "object",
        "format": "knowis/entity",
        "additionalProperties": false,
        "properties": {
            "_id": {
                "type": "string"
            },
            "_type": {
                "type": "string"
            },
            "_app": {
                "type": "string"
            },
            "customerNeedIdentifier": {
                "identifier": "sconr:customerNeedIdentifier",
                "title": "Customer Need Identifier",
                "description": "",
                "namespacePrefix": "sconr",
                "type": "string",
                "format": "knowis/text"
            },
            "financialProposalId": {
                "identifier": "sconr:financialProposalId",
                "title": "Financial Proposal",
                "description": "",
                "namespacePrefix": "sconr",
                "type": "string",
                "format": "knowis/text"
            }
        },
        "required": [
            "_id",
            "_type"
        ]
    },
    "_valueDict": {
        "customerNeedIdentifier": "377141b6-d53a-4323-a5a9-277992946489",
        "financialProposalId": "dbbf1843-9ae5-46d4-8a5a-d90a96c05923"
    },
    "_value": {
        "_type": "sconr:OfferAccepted_Payload",
        "_id": "abf671c7-0b18-4855-b672-8e7a42364a3e"
    },
    "_superEntities": [],
    "_subEntities": [],
    "_requestContext": {
        "idToken": "some-token",
        "locale": "en_US",
        "actionExecutionId": "b769d7ce-cc3a-4f30-a626-c501fafef513",
        "datastoreEndpointAddressV1": "http://localhost:8080/CNR/data/v1/items",
        "eventEndpointAddressV1": "http://localhost:8080/CNR/message/v1/events",
        "revlogEndpointAddressV1": "http://localhost:8080/CNR/audit/v1/records",
        "actionEndpointAddressV1": "http://localhost:8080/CNR/action/v1",
        "apiBindingEndpointAddressV1": "http://localhost:8080/CNR/api-binding/v1/bindings",
        "tracing": {
            "b3": "69bfe168a13d34f8-69bfe238a92d34f8-0"
        },
        "logLevel": "INFO"
    },
    "_type": "sconr:OfferAccepted_Payload"

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 Financial Services 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.

Tip: You can still consume event messages that have been published by external applications with microservices built with IBM Financial Services Workbench as long as you use a valid message key.

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 Financial Services 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. Than, 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.

Note: There will be support for creating Agents that listen for arbitrary events (and their message key) in upcoming releases.