# Event Management
# What is Event Management?
The 4ALLPORTAL creates and uses events, triggered by different functions. These are:
- CE_Delete
- CE_Update
- CE_Create
All changes in these three functions are stored as events in the table {module}_chg_evt
.
Pruning: The _chg_evt
tables are automatically pruned. They are checked daily for successfully completed events (all except open or in progress). All successfully completed events older than 30 days are deleted.
Note: Changes in the following asset properties (technical fields) are not considered:
- id
- created_time
- created_by
- mod_time
- mod_by
- deleted
The 4ALLPORTAL uses these events to work with. For this, there are different change event listeners:
- Audit-listener (takes an event and copies it to the table
{module}_audit
) - PAP-listener (uses events when working with third party connectors)
- ObjectImage-listener (uses events for renewing previews)
- Workflow-listener (uses events to trigger workflows, see event-based workflows)
A change event manager (synchronizer) manages the different listener: As soon as an event is available for a listener, it is processed. Each listener has its own event status, which is returned after the process finished:
# Event Status
- 0 = not applicable
- 1 = done
- 9 = in progress
- 10 = open
- 15 = defective
Each change event listener is called in a single thread. Having one single instance over all instances of an installation (distribution) is controlled in the field "sync_in_progress" in the table obj_chg_evt_listener
. All event listeners have to implement the same interface.
When called, an event listener must answer with a confirmation or an error:
- Confirmation: The change event manager sets the field
event_id
high and the fieldstatus
to "1". - Error: The change event manager does not change the field
event_id
and sets the fieldstatus
to "2".
Attention! As soon as an event reporting thread for an event listener has run through, it checks for new events in the table obj_chg_evt_listner
to be reported to its listener. If this is the case, the thread does not close but reports again.
By this mechanism all open events are always processed, one after the other regardless of the number of 4ALLPORTAL instances, while a thread only runs if there are open events. This is important because new events are stopped during a running synchronization.
# Change Event Bean Properties
Field | Description |
---|---|
id (Long) | automatically generated change event id |
create_time (Date) | creation date |
object_id (String) | id of the object where the event was triggered |
field_name (String) | field where the content was changed |
module_name (String) | name of the module |
object_type (Integer) | object type bean (0) / derivate (1) / fileaccess (2) / relation (3) |
event_type (Integer) | event type delete (0) / update (1) / create (2) |
create_by (String) | contact id of the creator |
value_old (String) | former content of the field |
value_new (String) | new content of the field |
dimensions | dimensions (opens new window) |
related_id (String) | id of a related object (only relation events) |
pap_status (Integer) | event status |
pap_mod_time (Date) | event date |
pap_instance_id (String) | instance id (distributed installation) |
audit_status (Integer) | event status |
audit_mod_time (Date) | event date |
audit_instance_id (String) | instance id (distributed installation) |
object_image_status (Integer) | event status |
object_image_mod_time (Date) | event date |
object_image_instance_id (String) | instance id (distributed installation) |
workflow_status (Integer) | event status |
workflow_mod_time (Date) | event date |
workflow_instance_id (String) | instance id (distributed installation) |
# Connector Event Bean Properties
Field | Description |
---|---|
id (Long) | automatically generated connector event id |
mod_time (Date) | change or creation date |
object_id (String) | id of the object where the event was triggered |
object_type (Integer) | object type bean (0) / derivate (1) / fileaccess (2) / relation (3) |
details (String) | additional information, e.g. the derivate's name if object_type is "derivate" |
event_id (Long) | id of the change event |
event_type (Integer) | event type delete (0) / update (1) / create (2) |
beanType (String) | type of the bean |
# Triggers
Triggers can be either fields (opens new window) or relations between CE-modules or a module itself. Each change to a trigger results in one or more events.
# Module Trigger
The module trigger is a general trigger which on change generates a create
or a delete
event without any field specification.
# Field Trigger
The field trigger creates on change of a CE-field one or more update
events with the corresponding field information. A field trigger can depend on dimensions.
# Relation Trigger
The relation trigger creates on change of a CE-relation one or more create
or delete
events of the type relation
. The field of the event is the full name of the relation.
To configure a relation trigger, the [.]-notation can be used. Use [.] to bind several relations, monitor changes and register them as events for relevant objects from the source module.
# Relation Trigger Example
mod_by.account_contact.friendlyname
mod_by
is a relation of the type "field_link" and refers to the modulecontact
.account_contact
is the relation between the modulesaccount
andcontact
.
In this example, account
is the target module. The CE-field friendlyname
is from the module account
.
Now if the field friendlyname
from the module account
is changed, the relation trigger creates one, several or no (see below) events in the module data
for the relevant objects from this module.
Attention! When evaluating relevant objects, only source module and target module are considered. Everything in between is ignored!
This may be the reason why relevant objects cannot be found and events don't register.
# Trigger Types
- AUDIT_EVENT (1)
- PAP_EVENT (2)
- OBJECT_IMAGE_EVENT (4)
- WORKFLOW_EVENT (8)
- TYPEAHEAD_EVENT (16)
- RELATION_EVENT (32)
# Example Configuration
The following trigger example can be used to configure a workflow or connector:
<triggers>
<trigger>
<selector>field or relation</selector>
<dimensions>
<entry key="locale" class="array">
<value>de_DE</value>
<value class="null">
</entry>
<entry key="channel" class="array">
<value>print</value>
</entry>
</dimensions>
</trigger>
</triggers>
# Event-based Workflows
An event-based workflow is an automatic background process that reacts to changes (events) in your system. It listens to events triggered by CE_Create
, CE_Update
and CE_Delete
and can be configured in an XML file.
Create workflows for example to map asset metadata like IPTC to specific fields (metadata mapping), move or copy assets to specific folders (file action) or automatically create folders (4App Folder Workflow (opens new window)).
You can configure event-based workflows for every module.
# Example Configuration
Create the XML file <workflow_name>.xml
and store it the corresponding module's folder modules/<module_name>/workflow_events
.
The XML must contain the following parameters:
The XML of an event-based workflow may look like this:
<?xml version="1.0" encoding="UTF-8"?>
<workflow_event>
<description>workflow description</description>
<!-- <on_create>false</on_create> -->
<!-- <on_update>false</on_update> -->
<!-- <on_delete>false</on_delete> -->
<conditions>
<condition>
<group>condition-group</group>
<value1 type="field">
<value>field1</value>
</value1>
<operator>not in</operator>
<value2 type="value">
<value>1</value>
<value>2</value>
</value2>
</condition>
<condition>
<group>condition-group</group>
<value1 type="field">
<value>field2</value>
</value1>
<operator>in</operator>
<value2 type="value">
<value>v1</value>
<value>v2</value>
<value>v3</value>
<value>v4</value>
</value2>
</condition>
</conditions>
<trigger_fields>
<trigger_field>field1</trigger_field>
</trigger_fields>
<triggers>
<trigger>
<selector>field or relation</selector>
<dimensions>
<entry key="locale" class="array">
<value>de_DE</value>
<value class="null">
</entry>
<entry key="channel" class="array">
<value>print</value>
</entry>
</dimensions>
</trigger>
</triggers>
<actions>
<action class="class of the action">
<parameters>
<entry key="key1" class="com.cm4ap.ce.vo.types.CEVarchar">
<value>value1</value>
</entry>
<entry key="key2">value2</entry>
<entry
key="fotograf"
class="com.cm4ap.ce.vo.workflow.action.MetadataMappingConf">
<template>{if $["xmp.IPTC.by-line"]}{$["xmp.IPTC.by-line"]}{/if}</template>
<!-- 'merge' (default), 'replace' or 'remove' -->
<!-- by not list fields 'merge' equals to 'replace' -->
<instruction>if_empty</instruction>
<!-- only for list fields -->
<delimiter>;</delimiter>
<!-- units of the metric field or linked modules for the object link field -->
<additions>bytes</additions>
</entry>
</parameters>
</action>
</actions>
</workflow_event>
on_create=true
: All workflow actions will also be executed on CREATE events. The default value isfalse
.on_update=true
: All workflow actions will also be executed on UPDATE events. The default value isfalse
.on_delete=true
: All workflow actions will also be executed on DELETE events. The default value isfalse
.
Please note: on_update
will be ignored if you configure trigger fields.
# Conditions
Conditions determine whether the actions from the workflow execute at all. In conditions, you can also use the variable _event
where the event object can be embedded, e.g.:
{$_event.value_old}
Note: Learn more about how to configure conditions in our conditional operations documentation.
# Trigger Fields
Every change in the metadata fields set here will trigger the workflow.
Please note: This parameter will soon be no longer supported. Currently, the fields configured here are transferred to triggers.
# Trigger
For configuring triggers, please take a look at our detailed triggers chapter.
# Actions
Enter and configure actions that will execute one after the other in the specified order.
To configure an action you need:
Class
The Java class derived fromcom.cm4ap.ce.vo.workflow.action.IAction
is reinitialized at each execution.Parameters
This is a HashMap, where the key attribute is a key of the HashMap, the content of the entry is a value of the HashMap.If you set class attributes, it will try to parse the content to the specified Java class.
The HashMap is specified for the execution of the action withcom.cm4ap.ce.vo.workflow.action.ActionParameter
# Action: Metadata Mapping
Java class com.cm4ap.ce.workflow.action.MetadataMappingAction
represents the workflow action to map certain data (e.g. EXIF, IPTC, XMP, or generated values from the template engine) into fields of the 4ALLPORTAL modules.
A HashMap is expected as input parameter: key
must be the target metadata field, value
a configuration for metadata mapping.
Java class com.cm4ap.ce.vo.workflow.action.MetadataMappingConf
represents the Metadata Mapping configuration and has the following properties:
template
Must contain the template of the template engine. The result is transferred to the target metadata field.additions Can contain the template of the template engine. The result is either metric unit(s) or link module(s). To split the value to array, use delimiter.
delimiter
contains a character or string (default:;
), if you want the result of the template to be split into several values and transfer them to a list field.instruction
set_instruction
defines how to set a value:- overwrite (overwrite existing value - default instruction)
- if_empty (apply only if no value is set)
- list_add (add to list, no duplicate entries)
- list_add_force (add to list, duplicates possible)
- list_remove (delete from list, values including duplicates)
Note: Instructions can be combined (e.g. [if_empty, list_add]) and are then executed one after the other.
# Action: Text Analyse
Use Text Analyse to break down text documents into text segments (per page). These text segments show or are saved in the DAM as markups. By this means, single pages of a document can be found via full-text search.
For this action, we developed Java class com.cm4ap.ce.workflow.action.TextAnalyseAction
.
This is the default configuration for Text Analyse:
<?xml version="1.0" encoding="UTF-8"?>
<workflow_event>
<description>Text Content Analyse Workflow</description>
<conditions>
<condition>
<group>text-analyse</group>
<value1 type="field">
<value>data_status_textcontent</value>
</value1>
<operator>not in</operator>
<value2 type="value">
<value>1</value>
<value>2</value>
</value2>
</condition>
<condition>
<group>text-analyse</group>
<value1 type="field">
<value>data_subtype</value>
</value1>
<operator>in</operator>
<value2 type="value">
<value>text</value>
<value>pdf</value>
<value>presentation</value>
<value>table</value>
</value2>
</condition>
</conditions>
<trigger_fields>
<trigger_field>data_status_textcontent</trigger_field>
</trigger_fields>
<actions>
<action class="com.cm4ap.ce.workflow.action.TextAnalyseAction">
<parameters>
<entry key="status_field">data_status_textcontent</entry>
</parameters>
</action>
</actions>
</workflow_event>
Conditions:
The field data_status_textcontent
is monitored via our event management. If a document is edited or newly created, TextAnalyseAction
starts to extract the text or text segments.
In our example, only assets are accepted whose metadata data_status_textcontent
is not "1" or "2" and whose data_subtype
is "text", "pdf", "presentation" or "table".
# Action: File Action
Use the action com.cm4ap.ce.workflow.action.FileAction
to delete selected assets or to move or copy them to a specific directory within the 4ALLPORTAL (targetFolder
).
<action class="com.cm4ap.ce.workflow.action.FileAction">
<parameters>
<!-- move | copy | delete -->
<entry key="mode">move</entry>
<!-- the target path is relative to mount root directory (e.g. to /4allportal/data//data) -->
<entry key="target">{if $pac_image_folder}Material Images/{$pac_image_folder}/{name}{/if}</entry>
<!-- collision behaviour 0=error | 1=addCounter | 2=replace -->
<entry key="collisionBehaviour" class="java.lang.Integer">2</entry>
</parameters>
</action>
Parameters
mode (required):
- move
- copy
- delete
target (only required if you set move or copy)
collisionBehaviour
- 0: Gives an error message in case of conflict.
- 1: In case of conflict the copied or moved file gets a "counter": the copy of
test.jpg
is namedtest.1.jpg
and so on. - 2: If a file already exists, it will be overwritten.
# Action: Merge Fields
This configuration defines an action of class com.cm4ap.ce.workflow.action.MergeFieldsWorkflowAction
.
It specifies parameters for merging multiple fields with value handling, dimensions, templates, and additional field options:
<action class="com.cm4ap.ce.workflow.action.MergeFieldsWorkflowAction">
<parameters>
<entry key="merge_configs" class="com.cm4ap.ce.vo.workflow.action.MergeFieldsConfig">
<merge_configs>
<merge_config>
<target_field>merge_field</target_field>
<field_list>tags, dim1, status, approvers.email; f_collection_dim2</field_list>
<valueoption_handling>translateIf</valueoption_handling>
<valueoption_keys>
<entry key="status">status</entry>
<entry key="key2">value2</entry>
</valueoption_keys>
<lang>de_DE,en_US</lang>
<dimensions>
<entry key="locale">de_DE, en_US, it_IT, es_ES, pl_PL, fr_CA, fr_FR</entry>
</dimensions>
<add_fields>name, parent_path ; mimetype</add_fields>
<templates>
<entry>{parent_path}/{name}</entry>
</templates>
<delimiter>,</delimiter>
</merge_config>
</merge_configs>
</entry>
</parameters>
</action>
# Elements
Element | Description | Values/Attributes |
---|---|---|
<action> | Defines the workflow action class responsible for merging fields. | class="com.cm4ap.ce.workflow.action.MergeFieldsWorkflowAction" |
<parameters> | Contains a list of configuration entries required for the action. | |
<entry> | Holds one or more <merge_config> definitions inside <merge_configs> . | key: merge_configs class: com.cm4ap.ce.vo.workflow.action.MergeFieldsConfig |
<merge_configs> | A container for multiple <merge_config> entries. | |
<merge_config> | Defines a single merging operation. | Details see Merge Configuration |
# Merge Configuration
Element | Description | Examples |
---|---|---|
<target_field> | The field where the merged result will be stored. | merge_field |
<field_list> | List of fields to merge. Support for simple fields and nested paths (e.g. approvers.email ).Fields can be separated by commas ( , ) or semicolons (; ). | tags, dim1, approvers.email; f_collection_dim2 |
<valueoption_handling> | Defines how value options are handled during the merge. Possible values:
| translateIf |
<valueoption_keys> | Specific key-value mappings for custom translations. | <entry key="key1">value1</entry> <entry key="key2">value2</entry> |
<lang> | Defines languages used for translation. Multiple languages can be separated by commas ( , ) or semicolons (; ). |
|
<dimensions> | Key-value pairs for dimensions used in context-sensitive translations. | <entry key="dim1">dim_value1</entry> <entry key="dim2">dim_value2</entry> |
<add_fields> | Additional fields to be appended to the merge result. Fields can be separated by commas ( , ) or semicolons (; ). | name, parent_path ; mimetype |
<templates> | Templates used for formatting the merged output. Empty template entries are allowed. Placeholders like {parent_path} and {name} are supported. | {parent_path}/{name} |
<delimiter> | Defines the delimiter character used to join multiple merged values. | , |
Please note:
- Comma
,
and semicolon;
can be used as separators infield_list
,lang
, andadd_fields
. - Templates support placeholders dynamically replaced during processing.
- Empty entries are tolerated where applicable (e.g., empty template
<entry>
).