Modules - Notification [ntf]
The notification module contains a simplified mechanism for notification configuration. It helps the administrator with:
- define events that should trigger a notification (for example, changes on a user),
- define rules when the notification should be sent (for example, change of user state),
- edit the topic for individual notifications,
- easily disable or enable individual configurations,
- define multiple types of notifications for one event and one rule.
Initialization of the notification module [idm-ntf
] is fully automated. After correct installation of the module into IdM, the initial module configuration is done and all settings are applied without the need for administrator action.
Version
Version | Compatible with product | Notes |
---|---|---|
12.0.0 | 12.3.4 | First module implementation for 12.x.x IdM |
14.0.0 | 14.10.0 | First module implementation for 14.x.x IdM |
14.0.1 | 14.10.0 | Bug fixing |
"Compatible with the product" means that this is the recommended product version.
Supported notification types
Currently, the notification module supports notifications only for the following object/entity types:
- Users (
IdmIdentityDto
). - Provisioning operations (
SysProvisioningOperationDto
).
For each supported object type, a notification can react to any attribute change for that object. Examples:
- (
IdmIdentityDto
) when the user state changes, - (
IdmIdentityDto
) when the username changes, - (
SysProvisioningOperationDto
) when the description value is written to the system, - (
SysProvisioningOperationDto
) when groups are written to the system.
Lifecycle of sending notification
In the current version, notifications are sent only when an object change is triggered, and always for each object separately.
For example, if a synchronization/HR process changes the user state from VALID
to LEFT
, the notification is sent at the moment of the change, not in advance.
Notifications are not grouped! For each change, one notification is sent even if the recipient is the same.
Example of sending a notification on state change
The following example describes a notification for a change of a user attribute and notifying, for example, the user's manager.
In the notification code list, we have a configuration that means:
when the user state changes from Valid (VALID
) to Excluded from evidence count (EXCLUDED
), an email notification is sent to the user's manager.
- From the HR system, information arrives about a state change of a single contract (
IdmIdentityContractDto
) for the user, - the contract change means a change of the contract
STATE
from NULL to Excluded from evidence count (EXCLUDED
), - the HR process in IdM (
HrContractExclusionProcess
) automatically recalculates the user state and detects a change of theSTATE
attribute for the user (IdmIdentityDto
), - the HR process evaluates a change of
STATE
from Valid (VALID
) to Excluded from evidence count (DISABLED) and also deactivates the user (DISABLED
) fromFALSE
toTRUE
, - after the user with the new state is successfully saved, this event is caught by the notification module,
- the notification module evaluates all valid notification configurations for this event, and if the rule match, sends the notification according to the configuration.
Example of sending a notification on attribute change during provisioning
The following example describes a notification for an attribute change on an end system. The notification is, for example, sent to users with a defined role.
In the notification code list, we have a configuration that means: when the value of the attribute Description (description) changes on the end system, an email notification is sent to users with the assigned role.
- On the end system, IdM manages the description attribute. This attribute is also mapped 1:1 to the standard user attribute Description (
description
), - in IdM, the Description attribute on the user is changed,
- this attribute change triggers a write to the end system,
- the notification module catches the successfully executed provisioning operation and then sends the notification.
Installation
This section describes the installation process of the Notification idm-ntf
module, including its activation, required prerequisites, access rights configuration, and integration with target systems. It serves as a starting point for administrators when introducing the module into the IdM environment.
Configuration
Code list: Entity types [ntf-entity-type]
This code list is automatically created at application startup based on the presence of the idm-ntf
module.
The code list contains all objects/entities for which it is possible to configure notifications using the notification module. Currently, the module supports the following objects/entities:
- Users (
IdmIdentityDto
), - Provisioning operations (
SysProvisioningOperationDto
).
Code list: Entity events [ntf-entity-event]
This code list is automatically created at application startup based on the presence of the idm-ntf
module.
The code list contains all event types that can be checked/caught by the notification module. Currently, the following event types are supported:
- Create (
CREATE
), - Delete (
DELETE
), - Update (
UPDATE
).
Code list: Notification code list [ntf-notification]
This code list is automatically created at application startup based on the presence of the idm-ntf
module.
The code list contains the main definition of notifications.
It is the only configuration part of the module that can be edited/modified by the administrator.
Each code list value contains the following attributes:
- Entity type
- Defines for which object/entity type this notification configuration will be sent.
- Event type
- Event type for which this configuration will be evaluated.
- Form projection
- Form projection / user type. Currently, it can only be used for the
IdmIdentityDto
object/entity. Limits for which user type the notification configuration will be evaluated.
- System
- System definition – restriction only for the defined system. Currently, it can only be used for the
SysProvisioningOperationDto
object/entity.
- Rules
- Definition of rules for this configuration. Currently, only one rule per configuration is supported. More about rules is described in a separate section.
- Rules by script
- Definition of rules using a script. Instead of the rules above, you can configure the condition using a script. More about the script is in a separate section.
- Topic
- Standard notification configuration – the code of the script to which the notification will be sent if the conditions are met.
- Level
- Standard notification configuration – the "level" defines whether the notification will be
SUCCESS
,WARNING
, etc.
- Send to identity itself
- Defines whether, if conditions are met, the notification will be sent to the identity itself.
- Send to manager
- Defines whether, if conditions are met, the notification will be sent to the user’s manager.
- Send to identities
- Defines whether, if conditions are met, the notification will be sent to the multi-value list of identities specified here from IdM.
- Send to roles
- Defines whether, if conditions are met, the notification will be sent to the multi-value list of roles specified here from IdM.
- Recipients by script
- Defines whether, if conditions are met, the notification will be sent to the list of users returned by a script. More about scripts is in a separate section.
- Disable
- Defines whether this configuration will be evaluated or not.
Rules
The following section describes how to evaluate rules using a script and using pseudo syntax.
Rules
The rules can contain the following parts:
- Attribute type definition.
- Attribute code
- Separator.
- Value from which the rule is evaluated.
- Change separator.
- Value to which the rule is evaluated.
The following modifiers can also be used in the rules:
- Wild card - *,
- allows defining a change from any value, or to any value.
- null,
- means that the value was not filled before, or the value was deleted.
- Always - !
- means that the notification is sent every time without checking for changes.
- Change - CHANGED
- means that the attribute changed. It does not check from which value to which value.
Rule examples in practice
Rule | Rule type | Description |
---|---|---|
firstName:John->Johny | Standard identity attribute | Rule describes a change of the user’s standard attribute `firstName` from value `John` to `Johny`. Other changes of `firstName` will not be evaluated as matched. |
EAV:clinicCode:100->200 | EAV identity attribute | Rule describes a change of the EAV attribute with code `clinicCode` from value `100` to `200`. For all other changes, the rule will not match. |
EAV:alternateEmail:john@example.tld->johny@externist_example.tld | EAV identity attribute | Rule describes a change of the EAV attribute with code `alternateEmail` from value `john@example.tld` to `johny@externist_example.tld`. |
EAV:supervisor:*->true | EAV identity attribute | Rule describes a change of the EAV attribute with code `supervisor` from any value ("*") to the value `"true"`. |
email:*->null | Standard identity attribute | Rule describes a change of the standard attribute `email` from any value to an empty (null) value – i.e., attribute deletion. |
externalCode:CHANGED | Standard identity attribute | Rule describes a change of the standard attribute `externalCode` (personnel number) to any value. |
Rules by script
For more complex rules, it is possible to use evaluation by script. This script always has priority over standard rule evaluation. If both rules and a script are defined, only the script will be evaluated.
The script is defined through the standard IdM configuration agenda: Configuration → Script definitions. Scripts can be written and selected only from the category System. Script permissions are handled by the standard IdM mechanism. It is also allowed to call scripts from other scripts.
The script return value must always be of type Boolean.TRUE
or Boolean.FALSE
.
For any other return type, the rule will be skipped! In the IdM log, an error message will be available saying that the script did not return the required type.
The input parameters of the script are different for the objects/entities IdmIdentityDto
and SysProvisioningOperationDto
.
IdmIdentityDto
The input parameters for the IdmIdentityDto
object are:
- oldDto,
- the original
IdmIdentityDto
object for which the rule is evaluated, - the value can be null – for example, on creation,
- newDto,
- the newly updated `IdmIdentityDto` object for which the rule is evaluated,
- oldEavs,
- the original list of EAV values,
- the collection contains items of type
IdmFormValueDto
, - the value can be null,
- newEavs,
- the new list of EAV values,
- the collection contains items of type
IdmFormValueDto
, - the value can be null,
- scriptEvaluator,
- the standard script evaluator,
- can be used to run other scripts.
An example script for the IdmIdentityDto
object can be as follows:
// Check email if is null or empty rule will pass if (oldDto.getEmail() == null || oldDto.getEmail().isEmpty) { return Boolean.TRUE; } // Check form projection if is same as external. External form projection is defined by UUID not code. if (oldDto.getFormProjection() != null && oldDto.getFormProjection().equals(UUID.fromString('8a02783b-c4a8-4ed8-84a5-808ae3c69657'))) { return Boolean.TRUE; } // For all another state return false; return Boolean.FALSE;
SysProvisioningOperationDto
The input parameters for the SysProvisioningOperationDto
object are:
- entity,
- the currently processed provisioning operation,
- an object of type
SysProvisioningOperationDto
,
- scriptEvaluator,
- the standard script evaluator,
- can be used to run other scripts.
An example script for the SysProvisioningOperationDto
object can be as follows:
import eu.bcvsolutions.idm.acc.dto.SysProvisioningOperationDto; SysProvisioningOperationDto provisioningOperation = (SysProvisioningOperationDto) entity; if (provisioningOperation.getProvisioningContext().getConnectorObject().getAttributes().size() != 1) { return Boolean.FALSE; } if (provisioningOperation.getProvisioningContext().getConnectorObject().getAttributes().getFirst().getName().equals('__ENABLE__')) { return Boolean.TRUE; } return Boolean.FALSE;
Templates
The notification module by default does not contain any templates or text for notifications. All templates must be created by the IdM administrator.
For each type of monitored object/entity, there are different template parameters that can be used in notifications.
Template parameters for IdmIdentityDto
For IdmIdentityDto
, the following parameters can be used:
- rule (
NtfConfigurationItemCacheDto
),- the matched rule sent to the notification, mainly to get the old and new value from the rule,
- entity (
IdmIdentityDto
),- the updated
IdmIdentityDto
object that matched the above rules.
Template parameters for SysProvisioningOperationDto
For SysProvisioningOperationDto
, the following parameters can be used:
- rule (
NtfConfigurationItemCacheDto
),- the matched rule sent to the notification, mainly to get the old and new value from the rule,
- entity (
SysProvisioningOperationDto
),- the full provisioning operation containing information about the executed provisioning,
- identity (
IdmIdentityDto
),- the user for whom the operation was performed,
- if the provisioning is for a type other than
IDENTITY
, this value will be null,
- system (
SysSystemDto
),- the system for which the provisioning operation was performed,
- account (
String
),- note: this is the UID of the system entity (`getSystemEntityUid`), not the account UID,
- changes (
List<List<String»
),- the complete list of changed attributes sent by the provisioning.
Recipients
Recipients can be configured differently for each managed object/entity. The following sections describe the recipients for each object/entity.
Recipients for IdmIdentity
For a configuration monitoring the IdmIdentityDto
object/entity, the following recipient options are available:
- the user itself,
- the notification will be sent to the user,
- the user’s manager,
- a combination of managers from the organizational structure and those specifically assigned to contracts,
- if the user has multiple contracts, the result is the union of their managers,
- if the user has no managers, the recipient list is replaced with IdM Administrators (users with the `SuperAdminRole`).
Recipients for SysProvisioningOperation
For a configuration monitoring the SysProvisioningOperationDto
object/entity, the following recipient options are available:
- the user itself,
- the notification will be sent to the user,
- the user’s manager,
- a combination of managers from the organizational structure and those specifically assigned to contracts,
- if the user has multiple contracts, the result is the union of their managers,
- if the user has no managers, the recipient list is replaced with IdM Administrators (users with the `SuperAdminRole`).
IDENTITY
, the above behavior is not available. Please use recipients defined by script.
Recipients by script
If none of the above recipient definition options are suitable, it is possible to define recipients by script.
Scripts can be written and selected only from the System category. Scripts can also call other scripts (only from the same category).
The following parameters are sent to the script that evaluates recipients:
- entity,
- a DTO (currently
IdmIdentityDto
andSysProvisioningOperationDto
) for which the rule was evaluated,
- scriptEvaluator,
- the standard system script evaluator,
- can be used to run other scripts.
The script must return an object of type List<IdmIdentityDto>
.
For all other object types, processing will end with an error.
The return value can also be empty or null. In these cases, the recipient list will be filled with IdM Administrators (users with the `SuperAdminRole`).
Configuration
idm-ntf
contains several configuration items that do not need to be configured manually – they are set automatically on the first application startup.
# Configuration property that holds the ID of the code list containing notification configurations for identities. idm.sec.ntf.codeListId= # Codelist with saved all supported entity types. idm.sec.ntf.entityType.codeListId= # Codelist with saved all available entity events. idm.sec.ntf.entityEvent.codeListId= # Configuration property specifying for which entity is this configuration used. idm.sec.ntf.codeList.eav.entityTypeId= # Configuration property specifying for which {@link eu.bcvsolutions.idm.core.api.event.EventType} the notification configuration is used. idm.sec.ntf.codeList.eav.eventTypeId= # Configuration property specifying for which system the rule is used. Currently, this configuration is used only for {@link eu.bcvsolutions.idm.acc.dto.SysProvisioningOperationDto}. idm.sec.ntf.codeList.eav.systemId= # Configuration property for the EAV attribute of the code list that stores all rules required for sending notifications. idm.sec.ntf.codeList.eav.ruleId= # Configuration property for the EAV attribute containing a script. The script is evaluated with its own rule-checking logic. idm.sec.ntf.codeList.eav.scriptRuleId= # Configuration property for the topic code used to search for notification configurations. idm.sec.ntf.codeList.eav.topicId= # Configuration property for the notification level used to search for notification configurations. idm.sec.ntf.codeList.eav.levelId= # Configuration property indicating whether to send notifications to the currently processed {@link eu.bcvsolutions.idm.core.api.dto.IdmIdentityDto}. idm.sec.ntf.codeList.eav.sendIdentityItselfId= # Configuration property indicating whether to send notifications to the manager of the given {@link eu.bcvsolutions.idm.core.api.dto.IdmIdentityDto}. Used only for this type. idm.sec.ntf.codeList.eav.sendManagerId= # Configuration property indicating whether to send notifications to static identities list. idm.sec.ntf.codeList.eav.sendIdentityId= # Configuration property indicating whether to send notifications to identities assigned to a specific role. idm.sec.ntf.codeList.eav.sendRoleId= # Configuration property specifying script that returns notification recipients. idm.sec.ntf.codeList.eav.sendScriptId= # Configuration property that enables or disables the current notification configuration. idm.sec.ntf.codeList.eav.disabledId=
Developer guide
The following section describes a simplified mechanism of how the notification module works.
Executor
Currently, the notification module supports only the following executors that catch events in IdM, evaluate rules, and send notifications. These executors are:
NtfNotificationProvisioningOperationExecutor
- Evaluates changes on
IdmIdentityDto
and their EAV attributes.
NtfNotificationIdentityExecutor
- Evaluates changes on
SysProvisioningOperationDto
(write/provisioning to the system).
Implementing a new executor
If, in a new project (which depends on the idm-ntf
module) or directly in the idm-ntf
module, we decide to implement a new notification for a new type of monitored object/entity, it is necessary to create a new executor that extends the abstract class AbstractNtfNotificationExecutor
with the generic type we are interested in.
For example:
@Component("notificationProvisioningOperationExecutor") public class NtfNotificationTreeNodeExecutor extends AbstractNtfNotificationExecutor<IdmTreeNodeDto> { ... }
Add all required methods that the abstract class asks you to implement. You can use finished implementations here:
/idm-ntf/src/main/java/eu/bcvsolutions/idm/ntf/service/impl/NtfNotificationProvisioningOperationExecutor.java
/idm-ntf/src/main/java/eu/bcvsolutions/idm/ntf/service/impl/NtfNotificationIdentityExecutor.java
Creating an executor is only one part. Next, you must add capture points in the application. These are standard processors that, from the standard values of the given event, call the DefaultNtfNotificationManager
, which decides which executor to call. For our example on IdmTreeNodeDto, this can be implemented like this:
- A processor before saving the given object, which evaluates changes and stores which notification rules matched:
@Component(NtfBeforeTreeNodeProcessor.PROCESSOR_NAME) public class NtfBeforeTreeNodeProcessor extends AbstractNtfNotificationProcessor<IdmTreeNodeDto> { public static final String PROCESSOR_NAME = "ntf-before-identity-processor"; public NtfBeforeTreeNodeProcessor() { super(); } @Override public EventResult<IdmTreeNodeDto> process(EntityEvent<IdmTreeNodeDto> entityEvent) { IdmTreeNodeDto oldDto = entityEvent.getOriginalSource(); IdmTreeNodeDto newDto = entityEvent.getContent(); List<IdmFormValueDto> oldEavs = Lists.newArrayList(); if (oldDto != null) { oldEavs = getValues(oldDto.getEavs()); } List<IdmFormValueDto> newEavs = Lists.newArrayList(); if (newEavs != null) { newEavs = getValues(newDto.getEavs()); } List<NtfConfigurationItemCacheDto> passed = notificationManager.checkCachedNotifications( entityEvent.getType(), oldDto, newDto, oldEavs, newEavs, newDto); if (CollectionUtils.isNotEmpty(passed)) { Map<String, Serializable> properties = entityEvent.getProperties(); // TODO set whole cached object or just IDs? properties.put(PASSED_RULES, new NtfWrapperCacheDto(passed)); } return new DefaultEventResult<>(entityEvent, this); } @Override public int getOrder() { // Before save return -5; }
- A processor after saving the given object, which checks the number of matched rules and performs the sending:
@Component(NtfAfterTreeNodeProcessor.PROCESSOR_NAME) public class NtfAfterTreeNodeProcessor extends AbstractNtfNotificationProcessor<IdmTreeNodeDto> { public static final String PROCESSOR_NAME = "ntf-after-tree-node-processor"; public NtfAfterTreeNodeProcessor() { super(); } @Override public EventResult<IdmTreeNodeDto> process(EntityEvent<IdmTreeNodeDto> entityEvent) { Map<String, Serializable> properties = entityEvent.getProperties(); NtfWrapperCacheDto wrapper = (NtfWrapperCacheDto) properties.get(PASSED_RULES); if (wrapper != null) { IdmTreeNodeDto entity = entityEvent.getContent(); List<NtfConfigurationItemCacheDto> items = wrapper.getItems(); if (CollectionUtils.isNotEmpty(items)) { notificationManager.sendNotification(items, entity); } } return new DefaultEventResult<>(entityEvent, this); } @Override public int getOrder() { // After save return 5; }
Cache
@since 12.0.0
When evaluating rules during the saving of objects/entities, rules may be checked and evaluated frequently.
Rules are now stored in IdmCodeListItemDto
entities, and retrieving them from the database and then transforming them into rules (NtfConfigurationRuleTypeCacheDto
) can be a costly operation when used often.
In the notification module (idm-ntf
), a standard cache implementation named notification-cache
has been introduced in IdM.
This cache is managed and initialized by the notification module and contains pre-prepared rules from all configurations. The default validity of this cache is 12 hours. It is also automatically reset when any value in the notification code list is modified/added/deleted (this state is not checked for other code lists).