# Process event registration

## Event logging

This is an event log in which events that occurred in a case are recorded chronologically. To enable event logging, set the parameter in the platform configuration: CASE\_HISTORY\_ENABLED="true"

We record two types of events:

**System** - performed by users (Client and Employee):

* case creation,
* claiming a manual step by a user (claim),
* saving a manual step by a user (saving a task - interrupting execution - there is no unClaim here),
* unclaiming a manual step by a user (unClaim),
* finalizing a manual step by a user,
* case closure (end of process),
* changing the case priority.

**Business** - events recorded in the History by the process at moments defined in the process (e.g. in an automatic step or from a form).

A business event has common attributes:

* event type: business,
* event kind,
* assigned person,
* event description,
* structure with event attributes,
* event date.

## System Events

### Configuration

To use the plugin used to add particular system events to a topic, set the router-api endpoint in the configuration via the config ROUTER\_ENGINE\_CASE\_HISTORY\_ROUTER\_API\_URL, e.g.:

```
ROUTER_ENGINE_CASE_HISTORY_ROUTER_API_URL=http://eximee-router-api:8080/
```

### Automatic publication of events for types

* **PROCESS\_START** - Process start
* **PROCESS\_END** - Process end
* **CLAIM\_TASK** - User assignment
* **UNCLAIM\_TASK** - User unassignment
* **ASSIGNEE\_TASK** - Assignment of a user by another user
* **SEND\_USER\_TASK** - Sending a user task
* **SAVE\_TASK** - Saving a task
* **PROCESS\_PRIORITY\_CHANGE** - Change of task priority

## Business Events

### Configuration

To register business events, add the dependency in the business application:

**events-connector**

```xml
<dependency>
   <groupId>com.consdata.eximee</groupId>
   <artifactId>events-connector</artifactId>
   <version>${eximee-platform.version}</version>
</dependency>
```

Then add the configuration:

```
events.connector.rest.events.url=${ROUTER_API_URL}
```

where ROUTER\_API\_URL is the address of the router-api application.

Then in the application code, e.g. in a Camunda task handler, inject the bean **CaseHistoryBusinessMessageConnector** and call its publish method passing a BusinessMessage object.

```java
caseHistoryBusinessMessageConnector.publish(BusinessMessage.builder()
        .businessKey(externalTask.getBusinessKey())               // Business process key - required
        .eventCode("Wysyłanie powiadomienia")                     // Event code that will be displayed on the case history list - required
        .processInstanceId(externalTask.getProcessInstanceId())   // Process identifier - required
        .processKey(externalTask.getProcessDefinitionKey())       // Process key - required
        .processName("NazwaProcesu")                              // Process name in Camunda - required
        .eventDescription("Opis zadania")                         // Event description that will be displayed on the case history list - optional
        .userId("123456")                                         // User who performed the action. The value will be displayed on the case history list - required
        .params(Map.of(                                           // Business parameters that will be displayed in the Case History tab, in the event details - optional                                                          
               "Phone number", externalTask.getVariable("authorizationPhoneNumber"),
               "Priority", StringUtils.defaultString(externalTask.getVariable("priority"), "NONE"))
        )
        .build());
```

## Retrieving information for system and business events

For proper operation of recording system and business events, you should also add the variable to the process-starting request **router\_user\_id** and add it to the input parameters:

<figure><img src="https://2112972046-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2Fgit-blob-b7c19dc659e3c8e2a31576b2a8c22243d03e2770%2Frejestracja_zdarzen_procesu_zmienna_sesyjna_router_user_id.png?alt=media" alt=""><figcaption><p><em><strong>Illustration 1.</strong> Session variable "router_user_id"</em></p></figcaption></figure>

<figure><img src="https://2112972046-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2Fgit-blob-8803fec7bd02db66068981034488e83050d659cb%2Frejestracja_zdarzen_procesu_parametr_wejsciowy_router_user_id.png?alt=media" alt=""><figcaption><p><em><strong>Illustration 2.</strong> Input parameter "router_user_id"</em></p></figcaption></figure>

and in requests within the process add the variable **router\_claim\_user\_id** and add it to the input parameters:

<figure><img src="https://2112972046-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2Fgit-blob-6171379ce98c50440b290dbad72fe05969a78778%2Frejestracja_zdarzen_procesu_zmienna_sesyjna_router_claim_user_id.png?alt=media" alt=""><figcaption><p><em><strong>Illustration 3.</strong> Session variable "router_claim_user_id"</em></p></figcaption></figure>

<figure><img src="https://2112972046-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2Fgit-blob-e10ee1054523c25a70acbc84798630d00e213c82%2Frejestracja_zdarzen_procesu_parametr_wejsciowy_router_claim_user_id.png?alt=media" alt=""><figcaption><p><em><strong>Illustration 4.</strong> Input parameter "router_claim_user_id"</em></p></figcaption></figure>

In the case of the event "unclaiming a manual step by a user" (unclaim), when called other than within Router 2 (i.e. directly via the Camunda API), you must add handling of a business event that will intercept the unclaim call.

Additionally, to properly record the event channel, add the variable on every request **router\_channel** (analogous to the case of **router\_user\_id** and **router\_claim\_user\_id**):

<figure><img src="https://2112972046-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2Fgit-blob-f844b15b0ba08fb77b855ea972d79a6f56239143%2Frejestracja_zdarzen_procesu_zmienna_sesyjna_router_channel.png?alt=media" alt=""><figcaption><p><em><strong>Illustration 5.</strong> Session variable "router_channel"</em></p></figcaption></figure>

<figure><img src="https://2112972046-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2Fgit-blob-d0b9a81fa49fbb335bba011fa0270e264e51027a%2Frejestracja_zdarzen_procesu_parametr_wejsciowy_router_channel.png?alt=media" alt=""><figcaption><p><em><strong>Illustration 6.</strong> Input parameter "router_channel"</em></p></figcaption></figure>

## Kafka

Kafka configuration for process event logging:

```
spring.kafka.bootstrap-servers=${KAFKA_BOOTSTRAP_SERVERS:}
event.topic.all.name=${EVENT_TOPIC_ALL_NAME:all}
event.topic.all.groupId=${EVENT_TOPIC_ALL_GROUP_ID:case-history}
```

### Topic

On the Kafka environment a topic 'all' was created. All events arrive to this new topic, including those for process event logging. The router-api application retrieves data from the 'all' topic for the Case History tab in the Eximee Dashboard.

An example event object that goes to the queue:

```js
{
  "origin": "BUSINESS/SYSTEM",
  "type": "START_PROCESS",
  "timestamp: "1673525273",
  "payload" : {
        "processInstanceId": "123e4567-e89b-12d3-a456-426614174000",
        "uuid": "789a4567-e89b-12d3-a456-426614174222",     
        "processName": "nazwaProcesu",
        "businessKey": "businessKey001",
        "processKey": "processName",
        "assignee" : "user001",
        "eventDescription": "Description0001",
        "params": {
            "Label 1": "Value 1",
            "Label 2": "Value 2"
        }
   }
}
```

### Error handling

In case of an error while retrieving an event, error information goes to the log **eximee-events-errors.log**.

An example error entry:

\[router2-api-docker] 2023-03-03 15:14:34.074 \[key=**c1411d4a-3d9e-47fc-9970-711138451a06**]\[offset=43]\[value=**EventData(origin=SYSTEM, type=PROCESS\_PRIORITY\_CHANGE, timestamp=1673541340, payload={processInstanceId=f442acfd-877f-11ed-9beb-0242ac120003, eventDescription=Setting high case priority, channel=EXIMEE\_DASHBOARD, processKey=kredytHipoteczny, username=user0001, params={}}**))]\[topic=all] \[org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1] ERROR java.lang.ClassCastException: **Cannot cast java.lang.String to java.lang.Boolean**

where:

* \[router2-api-docker] - identifier of the container that reported the error,
* key - event key,
* offset - message index in Kafka,
* value - the processed object,
* topic - the Kafka topic from which the event was consumed.

### Diagnostic endpoint for errors while retrieving events from case history

An endpoint was created to check whether there is an entry in the current error file for events:

***GET*** TRAEFIK\_HOST:TRAEFIK\_PORT/router-api/case-history/event/errors

Response: **false - the file is empty** **true - there are some errors in the file**

### Retrying errors

Erroneously processed events should be manually added to the database. To do this, retrieve from the log **eximee-events-errors.log** the event data, e.g.:

```js
EventData(origin=SYSTEM, type=PROCESS_PRIORITY_CHANGE, timestamp=1673541340, payload={processInstanceId=f442acfd-877f-11ed-9beb-0242ac120003, uuid=f442acfd-877f-11ed-9beb-0242ac120003, eventDescription=Setting high case priority, channel=EXIMEE_DASHBOARD, processKey=kredytHipoteczny, username=user0001, params={}}
```

then prepare an appropriate insert into the database, e.g.:

```js
INSERT INTO case_history_process_history
VALUES (default, 'SYSTEM', to_timestamp(1673541340), 'f442acfd-877f-11ed-9beb-0242ac120003', 'PROCESS_PRIORITY_CHANGE', 'user0001', 'firstName', 'lastName', 'EXIMEE_DASHBOARD', 'Setting high case priority', '{}', 'f442acfd-877f-11ed-9beb-0242ac120003');
```

Where:

* **firstName** should be replaced with the correct employee first name (e.g. based on data from Keycloak),
* **lastName** should be replaced with the correct employee last name (e.g. based on data from Keycloak).
