Skip to content
valeriibilenko edited this page Dec 2, 2022 · 7 revisions

Configuration

Default configuration

  1. Add next dependency to gradle.build file of your microservice
implementation "com.icthh.xm.commons:xm-commons-domainevent:{version}"
  1. This lib uses xm-commons-migration-db so make sure you have this file in your resources folder:
/META-INF/services/org.hibernate.boot.spi.SessionFactoryBuilderFactory

and this file contains following line:

com.icthh.xm.commons.migration.db.jsonb.JsonbTypeRegistrator
  1. Create configuration file in your configuration repository project
/config/tenants/<tenant>/<microservice-name>/domainevent.yml

with the next structure:

enabled: true
sources:
  DB:
    enabled: true
    transport: outboxTransport

where

  • enabled - is domainevent feature enabled, if enabled initialization will be started
  • sources - all listed configurations for each source will be supported
  • DB - example name of the domain event source (database)
  • enabled (under sources) - is this source enabled
  • transport - name of spring bean (implementation of Transport interface) that will be used for the source

Outbox

To use outbox extension (store domain events in database table), you need to add next dependency to gradle.build file of your microservice

implementation "com.icthh.xm.commons:xm-commons-domainevent-outbox:{version}"

With it you will be able to use outboxTransport implementation of transport, build domain events with prefilled current database transaction id, use OutboxTransportService to manage outbox table, etc...

Usage

Creating DomainEvent

Create with DomainEventFactory:

  1. Autowire com.icthh.xm.commons.domain.event.service.builder.DomainEventFactory
  2. Build prefilled domain event:
DomainEvent domainEvent = domainEventFactory.build();

domainEvent will be prefilled with next fields:

  • msName - microservice name
  • tenant - current tenant where domain event was created
  • eventDate - creation date
  • clientId - client id from jwt Access Token
  • userKey - user key from jwt Access Token
  1. You can build domainEvent with id of the current database transaction:
    To make this feature supported, you need to add next dependency to gradle.build file of your microservice:
implementation "com.icthh.xm.commons:xm-commons-domainevent-db:{version}"

Or any dependency that extends xm-commons-domainevent-db (for example xm-commons-domainevent-outbox).
Usage example:

DomainEvent domainEvent = domainEventFactory.withTransaction().build();

domain event will be prefilled with all mentioned above fields and txId. withTransaction() factory will retrieve current transaction id from database and insert it into txId field. Additional database query will be executed. If creating multiple domain events for the same transaction, query will be run only once, next build calls will set cached transaction id.

4. More examples of domainEventFactory usage:
build domain event with minimum fields (msName, tenant, eventDate, clientId, userKey are already inserted):

        DomainEvent event = domainEventFactory
            .build();

        assertEquals(MS_NAME, event.getMsName());
        assertEquals(TENANT_KEY, event.getTenant());
        assertNotNull(event.getEventDate());
        assertEquals(CLIENT_ID, event.getClientId());
        assertEquals(USER_KEY, event.getUserKey());

build domain event with operation, aggregateId and aggregateType (msName, tenant, eventDate, clientId, userKey are already inserted):

        DomainEvent event = domainEventFactory
            .build(CREATE, "aggregateId", "aggregateType");

        assertEquals(MS_NAME, event.getMsName());
        assertEquals(TENANT_KEY, event.getTenant());
        assertNotNull(event.getEventDate());
        assertEquals(CLIENT_ID, event.getClientId());
        assertEquals(USER_KEY, event.getUserKey());

        assertEquals("aggregateType", event.getAggregateType());
        assertEquals("aggregateId", event.getAggregateId());
        assertEquals(CREATE.name(), event.getOperation());

get lombok builder and set custom fields that we need (in this case withTransaction() is used, so current transaction id will be retrieved from database and inserted into txId field, to use it you need xm-commons-domainevent-db dependency)
(msName, tenant, eventDate, clientId, userKey, txId are already inserted):

        DomainEvent event = domainEventFactory
            .withTransaction()
            .builder()
            .aggregateType("aggregateType")
            .aggregateId("aggregateId")
            .build();

        assertEquals(TX_ID, event.getTxId());

        assertEquals(MS_NAME, event.getMsName());
        assertEquals(TENANT_KEY, event.getTenant());
        assertNotNull(event.getEventDate());
        assertEquals(CLIENT_ID, event.getClientId());
        assertEquals(USER_KEY, event.getUserKey());
        
        assertEquals("aggregateId", event.getAggregateId());
        assertEquals("aggregateType", event.getAggregateType());

build domain event with operation, aggregateId and aggregateType (in this case withTransaction() is used, so current transaction id will be retrieved from database and inserted into txId field, to use it you need xm-commons-domainevent-db dependency)
(msName, tenant, eventDate, clientId, userKey are already inserted):

        DomainEvent event = domainEventFactory
            .withTransaction()
            .build(CREATE, "aggregateId", "aggregateType");

        assertEquals(TX_ID, event.getTxId());

        assertEquals(MS_NAME, event.getMsName());
        assertEquals(TENANT_KEY, event.getTenant());
        assertNotNull(event.getEventDate());
        assertEquals(CLIENT_ID, event.getClientId());
        assertEquals(USER_KEY, event.getUserKey());

        assertEquals("aggregateType", event.getAggregateType());
        assertEquals("aggregateId", event.getAggregateId());
        assertEquals(CREATE.name(), event.getOperation());

Create with default constructor or lombok builder as usual:

        DomainEvent domainEvent = new DomainEvent();
        domainEvent.setAggregateId("aggregateId");
        etc...

        domainEvent = DomainEvent
            .builder()
            .aggregateId("aggregateId")
             etc...
            .build();

Publishing DomainEvent

  1. autowire com.icthh.xm.commons.domain.event.service.EventPublisher bean
  2. use it to publish domain event with source defined in your configuration:
eventPublisher.publish("DB", domainEvent);

where "DB" is source enabled in your domainevent.yml file
you can use com.icthh.xm.commons.domain.event.domain.enums.DefaultDomainEventSource enum if you use default sources:

eventPublisher.publish(DB, domainEvent);
Clone this wiki locally