An event mechanism has been designed to make extending and overlapping of the CzechIdM core functionality within any module possible.
The event (EntityEvent
) with type (EventType
) is published via EntityEventManager
from different places in the application (⇒ hook
). A number of processors can react to the event (AbstractEntityEventProcessor
) in a defined order (number ⇒ the smaller it is, the sooner the processor is run). Processors run synchronously at default and in one transaction (see next section). Processors with the same order will be run in a random order (OrderComparator) - it's good practice to design and set different processor's order (think about it in design). Instead of the annotation @Order
, the method getOrder
needs to be overloaded (see the example). Event content could be any Serializable
object, but AbstractDto
descendant is preffered - see original source lifecycle feature. Event content is required, event without content couldn't exist.
EntityEvent<IdmIdentityDto> event = new IdentityEvent(IdentityEventType.UPDATE, updateIdentity);
EntityEventManager
EventContext<IdmIdentityDto> context = entityEventManager.process(event);
AbstractDto
, then original source is filled to the event - original source contains previously persisted (original) dto and could be used in "check modification" processors. If event creating new dto, then original source is null
. Original source could be set externally - then no automatic filling occurs.closed
) or (suspended
) and therefore skip all the other processors. If the suspended event is published again via EntityEventManager
, the processing will continue where it was suspended, if context (with processed results) is preserved. If the processing of the event is (suspended
), the called method should return the adequate accepted
state.
Event is published with content and specific event type (e.g. CREATE
, PASSWORD
). Processors can be register by content type and event type - e.g. process event with IdmIdentityDto
content and event type CREATE
⇒ other event contents and other event types will not be processed by this processor.
Event types has to be compared by their string representation, NOT by instance. Concrete event types e.q. IdentityEventType
are used for documentation reason only - which domain type supports which event. Event types can be added in different modules with different type, but processor can react across all module (⇒ is registered to string event type representation eventType.name()
).
... EntityEvent<IdmIdentityDto> event = new CoreEvent<IdmIdentityDto>(CoreEventType.CREATE, identity); if (event.hasType(IdentityEventType.CREATE)) { // do something } ...
Module can publish their own event types. Basic (core) event types
CREATE
- synchronous, new entity is createdUPDATE
- synchronous, entity is updatedDELETE
- synchronous, entity is removedNOTIFY
- asynchronous, notify about entity is changed (CU).EAV_SAVE
- synchronous, some entity extended attribute is modified (CUD) - it is synonym for NOTIFY
type ⇒ notify about entity extended attribute is changed (only extended attribute is changed). When entity is saved together with extended attributes, then only source event (e.g. CREATE) on owner entity is published (⇒ eav attributes are saved after owner entity is saved in once process line - e.g. CREATE).Different (and custom) event types can be used for different entities.
Supported events for individual entities:
core
:IdmAuthorizationPolicyDto
- authoriyation policiesCREATE
, UPDATE
, DELETE
IdmAutomaticRoleAttributeDto
- automatic role by attributeCREATE
, UPDATE
, DELETE
IdmAutomaticRoleAttributeRuleDto
- rule of automatic role by attributeCREATE
, UPDATE
, DELETE
IdmIdentityDto
- operation with the identityCREATE
, UPDATE
, DELETE
, EAV_SAVE
, NOTIFY
PASSWORD
- changes passwordPASSWORD_EXPIRED
- password expiresIdmProfileDto
- operation with the identity profileCREATE
, UPDATE
, DELETE
IdmPasswordDto
- operation with the CzechIdM passwordCREATE
, UPDATE
, DELETE
IdmTokenDto
- operation with the CzechIdM tokenCREATE
, UPDATE
, DELETE
cidmst
)IdmRoleDto
- operation with the roleCREATE
, UPDATE
, DELETE
, EAV_SAVE
, NOTIFY
DUPLICATE
- duplicate role, event is published for create / update role duplicate, read more here.IdmRoleGuaranteeDto
- operation with the role guarantee by identityCREATE
, UPDATE
, DELETE
IdmRoleGuaranteeRoleDto
- operation with the role guarantee by roleCREATE
, UPDATE
, DELETE
IdmRoleRequestDto
- role requestsCREATE
, UPDATE
, DELETE
EXCECUTE
- execute role request (i know EXECUTE!, but it's too late …)NOTIFY
- is published, when request is completely approved or executed - provisioning listen this event mainly.IdmRoleCatalogueDto
- operation with the role catalogueCREATE
, UPDATE
, DELETE
, NOTIFY
IdmRoleCompositionDto
- operation with the business rolesCREATE
, UPDATE
, DELETE
IdmIdentityRoleValidRequestDto
- role starts to be validIDENTITY_ROLE_VALID
.IdmIdentityRoleDto
- assigning a role to the userCREATE
, UPDATE
, DELETE
NOTIFY
- when parent role request event is propagated, then provisioning listener skips this elementary event processing and waits to role request is completed - listen NOTIFY
on IdmRoleRequestDto
.IdmIdentityContractDto
- labor-law relationCREATE
, UPDATE
, DELETE
, EAV_SAVE
, NOTIFY
IdmContractPositionDto
- other contract positionCREATE
, UPDATE
, DELETE
, NOTIFY
IdmRoleTreeNodeDto
- automatic role by tree structureCREATE
, UPDATE
, DELETE
PasswordChangeDto
- used in password prevalidation onlyPASSWORD_PREVALIDATION
- evaluates registered password policies - show policies setting before password is changed.IdmContractGuaranteeDto
- manually added guarantee to contractCREATE
, UPDATE
, DELETE
, NOTIFY
IdmTreeTypeDto
- tree structure typeCREATE
, UPDATE
, DELETE
IdmTreeNodeDto
- tree structure nodeCREATE
, UPDATE
, DELETE
, EAV_SAVE
, NOTIFY
IdmPasswordPolicyDto
- password policyCREATE
, UPDATE
, DELETE
IdmLongRunningTaskDto
- long running taskCREATE
, UPDATE
, DELETE
END
- long running task ended.IdmEntityEventDto
- persisted eventCREATE
, UPDATE
, DELETE
EXECUTE
- executes persisted event.IdmEntityStateDto
- persisted entity / event stateCREATE
, UPDATE
, DELETE
IdmFormInstanceDto
- eav attribute values from single definition.UPDATE
- update event type is used for saving eav attributes (⇒ CUD form values)IdmCodeListDto
- code listsCREATE
, UPDATE
, DELETE
IdmCodeListItemDto
- code list itemsCREATE
, UPDATE
, DELETE
IdmNotificationTemplateDto
- notification templatesCREATE
, UPDATE
, DELETE
IdmIdentityProjectionDto
- identity form projectionsCREATE
, UPDATE
acc
:AccAccountDto
- Accounts on target systemCREATE
, UPDATE
, DELETE
START
- starts provisioning for given account.AccIdentityAccountDto
- Identity accounts on target systemCREATE
, UPDATE
, DELETE
SysSystemDto
- System in ACC moduleCREATE
, UPDATE
, DELETE
SysSystemMappingDto
- Mapping between system and his mapping of provisioning or syncCREATE
, UPDATE
, DELETE
SysSchemaAttributeDto
- Connector schema on systemDELETE
SysProvisioningOperationDto
- execute provisioning operation. Look out, persisting provisioning operation into queue itself doesn't support events. Events are added for executing operations from queue:CREATE
- execute provisioning for CREATE
operationUPDATE
- execute provisioning for UPDATE
operationDELETE
- execute provisioning for DELETE
operationCANCEL
- cancels provisioning operationAbstractSysSyncConfigDto
(SysSyncConfigDto
, SysSyncContractConfigDto
, SysSyncIdentityConfigDto
) - synchronizationSTART
- starts synchronizationSTART_ITEM
- starts synchronization of one item (~entity)CANCEL
- cancels synchronizationSysSyncItemLogDto
- synchronization item vs
:VsRequestDto
- Request for account change in virtual system EXCECUTE
- executes requestrpt
:RptReportDto
- generate reportGENERATE
- generates requestA page has been created directly in the application on the module page for an overview of all entity types and event types migrating through event processing. All the registered processors including the configuration are listed there:
The default order for listeners (-
⇒ before, +
⇒ after):
core
: 0provisioning
: 1000delete / archivate processed
: 5000EntityEvent
- an event migrating through the processors. The content of the event can be BaseEntity
, BaseDto
or any serializable content.EventContext
- holds the context of the processed event - which processors it has been processed by, with what results, if the processing is suspended, closed, etc.EventResult
- the result of processing of the event by one processor.EntityEventProcessor
- event processor. Processor has to have unique identifier by module.AsyncEntityEventProcessor
- asynchronous entity event processor. Processor can control asynchronous processing priority.EntityEventManager
- ensures publishing of the event to processors.EventableDtoService
- adds event processing support to service - event processors have to be provided (e.g. for save, delete).AbstractEntityEvent
- an abstract event migrating through the processors - when adding a proper one can be simply inherited from.DefaultEventContext
- the default context of the processed event - all abstract and default events and processors use it.DefaultEventResult
- The default event result processed by one processor - all abstract and default events and processors use it.AbstractEntityEventProcessor
- abstract event processor - when adding a proper one can be simply inherited from.AbstractApprovableEventProcessor
- the event processor will send the whole event with dto (or serializable) content to WF for approval. It is necessary to configure the definition of the WF where the event will be sent to.AbstractPublishEntityChangeProcessor
- publish asynchronous NOTIFY
event.DefaultEntityEventManager
- ensures publishing of the events to processors.AbstractEventableDtoService
- adds default event processing support to service - event processors have to be provided (e.g. for save, delete).Use this super class, when creating new processor implementation (this class contains some boring parts).
Methods, which have to be implemented:
getName()
- Unique (module scope) configurable object identifier. Its used in configuration key etc.process(event)
- the main processors method with business logic.getOrder()
- when will be processor processed. Processors are executed in defined order. Methods, which could be implemented [optional]:
supports(event)
- Returns true
, when processor supports given event. Default implementation takes processor's template entity class and event type given in constructor (or configured by eventTypes
property).conditional(event)
- Returns true
, when processor supports given event. Returns true
by default. Override this method for adding some condition.isClosable()
- Returns true
, when processor could close event (only documentation purpose now). Returns false
by default.Use this super class, when creating new asynchronous processor implementation.
Methods, which could be implemented [optional]:
getPriority(event)
- Registered async processor can vote about priority of processing for given event. Returns null
by default ⇒ processor doesn't vote about priority - preserve original event priority. Use IMMEDIATE
to execute whole event synchronously. All registered processors votes about event priority - whole event will be processed with the highest priority.Transactional processing is controlled before the event publishing itself - the whole processing now takes place in a one transaction and all processors run synchronously by default. In case of an error in any processor, the whole transaction is rolled back, which has some advantages:
and disadvantages as well:
Propagation.REQUIRES_NEW
)
Event properties (Map
) can be specified for the event. Properties could be used in event processing.
Event properties are propagated automatically from parent into child event:
EntityEvent
.NOTIFY
event is published and event will be processed synchronously (asynchronous event processing is disabled or event has IMMEDIATE
priority), the properties set by processing NOTIFY
event is also available in the original event.
CzechIdM 8.0.0 brings new feature - asynchronous event processing. New event type NOTIFY
was added, all previous events (CREATE
, UPDATE
, DELETE
, EAV_SAVE
etc.) are still synchronous.
Asynchronous NOTIFY
event is published for dtos:
IdmIdentityDto
- published, when identity is created or updated (or eav is saved, updated, deleted)IdmIdentityContractDto
- published, when contract is created or updated (or eav is saved, updated, deleted)IdmContractGuaranteeDto
- published, when contract guarantee is created or updated (or eav is saved, updated, deleted)IdmIdentityRoleDto
- published, when identity role is created or updated (or eav is saved, updated, deleted)IdmRoleDto
- published, when role is created or updated (or eav is saved, updated, deleted)IdmRoleRequestDto
- published, when request is completely approved or executed - provisioning listen this event mainly.IdmTreeNodeDto
- published, when tree node is created or updated (or eav is saved, updated, deleted)IdmRoleCatalogueDto
- published, when identity role catalogue is created or updated (doesn't have eav attributes)DELETE
event is still synchronous.
Other entities will be added soon, when new asynchronous entity event processors will be implemented.
NOTIFY
event type is processed asynchronously:
When asynchronous event is published, it's persisted into event queue (IdmEntityEvent
). Internal scheduled task executes events from queue - all registered processors for event type NOTIFY
is processed - the same behavior as standard event processing, processors are called in defined order synchronously by defult. Event (~entity) states (IdmEntityState
) are persisted during event is processed (created / running / failed). Successfully processed events are deleted from queue by processor EntityEventDeleteExecutedProcessor. When exception occurs, event stays in queue with appropriate result code. Event agenda is available under APP_ADMIN
permission on frontend from audit menu (shortcut tab can be added on all entity details e.g. see identity detail).
Events from queue are processed by event owner id - one event for one owner can be executed in the same time ⇒ we need to preserven event order by created date for one owner. Super owner id (EntityEventManager.EVENTPROPERTYSUPEROWNERID
) can be used for setting custom event owner - this property will be resolved for evaluating running events for the same owner concurrency.
Before event is persisted into queue, then event priority is evaluated, priority types:
IMMEDIATE
- immediate ~ synchronously. Event will be executed synchronously.HIGH
- asynchronously (7 / 10 in one cycle, batch size can be configured)NORMAL
- asynchronously (3 / 10 in one cycle, batch size can be configured)
Events are processed from queue by internal scheduled tasks by priority. Events with HIGH
priority will use 7 slots, events with NORMAL
priority will use 3 slots ⇒ events will be processed 7 / 3, when internal scheduled task for processing events will be executed.
Priority can be set to event manually or registered processors can vote about event's priority - see AsyncEntityEventProcessor - the highest priority is used.
Execute date can be set to event manually. Event with priority HIGH
or NORMAL
will be processed after given date. Can be used for events, which could be executed sometimes "in night".
Event can be published by another event ~ event chain (tree) is persisted. For example, when contract is saved, then contract NOTIFY
event is published. This event is processed by provisioning processors - but only NOTIFY
event with contract's identity is published here only. Provisioning is physically executed in other processor, which processes identity NOTIFY
event.
When asynchronous event is published, then event content (and previous ~ original content) and event parameters is persisted into queue. This persisted attributes are used, when event is resurrected from queue and executed. Attributes are available in registered asynchronous processors - evaluate modifications, skipping by event parameter value etc. can be implemented in processors business logic.
When internal scheduled task for executing event from queue is processed, then duplicate events are removed.
Duplicate event is event with the same:
Older duplicate events are removed - the newest event is used. Events are processed by priority in batch, default batch size can be configured ⇒ duplicates are removed only in this batch (not configurable for now, see future development). Batch size is designed this way, because events are processed by priority - event with HIGH
priority should not wait too long for another bulk is begin to process. Remove duplicates should be redesigned from scratch - remove duplicates through whole queue.
Persist event (~entity) state, when event is processed. State can be persisted manually, even without event processing. This state will be shown on entity detail soon (new frontend component).
Notification about registered asynchronous processors is prepared, when asynchronous event is published. Notification is send into topic core:event
- uses console log by default and is send to currently logged identity - e.g. identity is saved, but provisioning will be executed asynchronously. Localization for asynchronous processors was added on frontend (see key acc:processor.identity-save-processor
).
save
, delete
etc.save
- e.g. sends notifications.NOTIFY
event about entity is changed.delete
provisioning (before identity role is deleted).after
provisioning actions (e.g. sends notifications)Other orders can be found directly in application, see supported event types.
Processors can be configured through Configurable
interface by standard application configuration.
Basic save and delete processors are not listed.
## ## approve create automatic role idm.sec.core.processor.role-tree-node-create-approve-processor.enabled=true # wf definition idm.sec.core.processor.role-tree-node-create-approve-processor.wf=approve-create-automatic-role ## ## approve delete automatic role idm.sec.core.processor.role-tree-node-delete-approve-processor.enabled=true # wf definition idm.sec.core.processor.role-tree-node-delete-approve-processor.wf=approve-delete-automatic-role
# Identity changed monitored fields - Check if defined fields on identity was changed. If yes, then send notification. # Default is disabled idm.sec.core.processor.identity-monitored-fields-processor.enabled=false # Monitored fields on change (for Identity, extended attributes are not supported) idm.sec.core.processor.identity-monitored-fields-processor.monitoredFields=firstName, lastName # Notification will be send to all identities with this role idm.sec.core.processor.identity-monitored-fields-processor.recipientsRole=superAdminRole
# Default is enabled idm.sec.core.processor.role-request-approval-processor.enabled=true # Workflow process for change permissions (as default is "approve-identity-change-permissions") idm.sec.core.processor.role-request-approval-processor.wf=approve-identity-change-permissions
# The role can be changed in the application configuration "idm.sec.core.wf.approval.helpdesk.role", the default setting is Helpdesk. idm.sec.core.wf.approval.helpdesk.role=Helpdesk # Default is disabled idm.sec.core.wf.approval.helpdesk.enabled=false
# Default is disabled idm.sec.core.wf.approval.manager.enabled=false
# The role can be changed in the application configuration "idm.sec.core.wf.approval.usermanager.role", the default setting is Usermanager. idm.sec.core.wf.approval.usermanager.role=Usermanager # Default is disabled idm.sec.core.wf.approval.usermanager.enabled=false
## ## HR process - enable identity's contract process. The processes is started ## for contracts that are both valid (meaning validFrom and validTill and disabled state) and ## not excluded. idm.sec.core.processor.identity-contract-enable-processor.enabled=true # wf definition idm.sec.core.processor.identity-contract-enable-processor.wf=hrEnableContract ## ## HR process - end or delete of identity's contract process. The processes is started ## for contracts that are not valid (meaning validFrom and validTill or disabled by state) and deleted. ## If the processed contract was the last valid contract of the identity, the identity is disabled. ## Additionally all added roles, which were assigned to the ended contract, are removed by the process. idm.sec.core.processor.identity-contract-end-processor.enabled=true # wf definition idm.sec.core.processor.identity-contract-end-processor.wf=hrEndContract ## ## HR process - identity's contract exclusion. The processes is started for ## contracts that are both valid (meaning validFrom and validTill) and excluded. ## If the processed contract was the last valid contract of the identity, the identity is disabled. idm.sec.core.processor.identity-contract-exclusion-processor.enabled=true # wf definition idm.sec.core.processor.identity-contract-exclusion-processor.wf=hrContractExclusion
## Provisioning identity after add or update IdmContractGuaranteeDto idm.sec.acc.processor.contract-guarantee-save.enabled=true ## ## Provisioning identity before IdmContractGuaranteeDto will be removed idm.sec.acc.processor.contract-guarantee-delete.enabled=true
When some long running task ends, then END
event is fired. This processor persists task's state.
When some long running task ends, then END
event is fired. This processor executes scheduled long running tasks, which depends on currently ended scheduled task.
Processes GENERATE
event type with RptReportDto
content, order -1000
. Generates output data for report by long running task.
## Enable / disable idm.sec.rpt.processor.report-generate-processor.enabled=true
Processes GENERATE
event type with RptReportDto
content, order 0
. Saves generated report metadata (binary data are stored as attachment).
## Enable / disable idm.sec.rpt.processor.report-generate-end-processor.enabled=true
Processes GENERATE
event type with RptReportDto
content, order 1000
. Sends notification after report is generated to report creator.
## Enable / disable idm.sec.rpt.processor.report-generate-end-send-notification-processor.enabled=true
Processes UPDATE
event type with IdmIdentityDto
content, order 200
. When identity starts to be valid and has at least one account on target system, then new password is generated and changed on all identity's accounts ⇒ identity ha the same password in all accounts. Notification is send (see acc:newPasswordAllSystems
template) to identity about new password on which accounts.
Identity is starting, when their state is changed from CREATED
, NO_CONTRACT
, FUTURE_CONTRACT
to the VALID
state.
## Enable / disable idm.sec.acc.processor.identity-set-password-processor.enabled=true
IdmEntityEventDto
EXECUTE
Start execution of entity event.
## Enable / disable idm.sec.core.processor.entity-event-start-processor.enabled=true
IdmEntityEventDto
EXECUTE
## Enable / disable idm.sec.core.processor.entity-event-execute-processor.enabled=true
Execute entity event - resurrects entity event and process her - execute all registered processors.
IdmEntityEventDto
EXECUTE
End execution of entity event - persist state only.
## Enable / disable idm.sec.core.processor.entity-event-end-processor.enabled=true
IdmEntityEventDto
EXECUTE
Delete successfully executed entity events.
## Enable / disable idm.sec.core.processor.entity-event-delete-executed-processor.enabled=true
@since 9.0.0
IdmRoleCompositionDto
NOTIFY
Assign sub roles for currently assigned roles, after composition (business role) is created. Update role composition is not supported now - NOTIFY
event is propagated, when composition is created only.
## Enable / disable idm.sec.core.processor.core-role-composition-after-create-processor.enabled=true
@since 9.0.0
IdmIdentityRoleDto
NOTIFY
Assign sub roles of currently assigned identity roles:
## Enable / disable idm.sec.core.processor.core-identity-role-assign-subroles-processor.enabled=true
IdmIdentityRoleDto
DELETE
Checks modifications in identity authorities after role removal and disable authentication tokens.
## Enable / disable idm.sec.core.processor.identity-role-delete-authorities-processor.enabled=true
@since 9.1.0
IdmContractPositionDto
NOTIFY
Automatic roles recount while contract position is created or updated.
## Enable / disable idm.sec.core.processor.core-contract-position-automatic-role-processor.enabled=true
@since 9.2.0
FormableDto
CREATE
, UPDATE
Persists formable entity's (owner's) prepared eav attribute values.
## Enable / disable idm.sec.core.processor.core-formable-save-processor.enabled=true
@since 9.2.0
IdmFormInstanceDto
UPDATE
Persists form instance (eav attributes).
## Enable / disable idm.sec.core.processor.core-form-instance-save-processor.enabled=true
@since 9.3.0
IdmRoleDto
CREATE
, UPDATE
Appends environment into role code. Checks filled code, base code and environment.
## Enable / disable idm.sec.core.processor.core-role-code-environment-processor.enabled=true
Implemented processors in the product sorted by order of the processing:
@since 9.5.0
IdmRoleDto
DUPLICATE
Prepares role's basic properties.
## Enable / disable idm.sec.core.processor.core-duplicate-role-prepare-processor.enabled=true
@since 9.5.0
IdmRoleDto
DUPLICATE
Here is the role persisted into database.
## Enable / disable idm.sec.core.processor.core-duplicate-role-save-processor.enabled=true
@since 9.5.0
IdmRoleDto
DUPLICATE
Duplicate role form attributes - parameters for the identity (~assigned) roles. Parameters are created for the target role or updated - extended attribute code is used for pairing.
Parameters provided to the bulk action form:
Configuration properties:
## Enable / disable idm.sec.core.processor.core-duplicate-role-form-attribute-processor.enabled=true
@since 9.5.0
IdmRoleDto
DUPLICATE
Duplicate configured role composition (sub roles by business role definition) and duplicate sub roles recursively. If the same environment is selected, the only role composition is created - existing sub roles are used. If the different environment (~target environment) is used, then sub roles with the same environment as original are duplicated recursively into target environment.
Parameters provided to the bulk action form:
Overidable methods (can be used for on the projects, e.g. example below):
duplicateRecursively
- Returns true, when role should be cloned recursively - can be overriden, if some role hasn't be cloned recursively, if doesn't exist on the target environment before.includeComposition
- Returns true, when role composition should be included in the target role - can be overriden, if some role hasn't be cloned recursively, if doesn't have the same environment etc.Configuration properties:
## Enable / disable idm.sec.core.processor.core-duplicate-role-composition-processor.enabled=true
Core processor can be disabled and overriden by processor implemented in custom module, if behavior of the core processor has to be changed.
/** * Project specific processor for duplicate role composition. */ @Component(CustomDuplicateRoleCompositionProcessor.PROCESSOR_NAME) @Description("Duplicate role - composition and recursion.") public class CustomDuplicateRoleCompositionProcessor extends DuplicateRoleCompositionProcessor { public static final String PROCESSOR_NAME = "custom-duplicate-role-composition-processor"; @Override public String getName() { return PROCESSOR_NAME; } /** * Returns true, when role should be cloned recursively * - it's not cloned, if application sub role doesn't exist on the target environment before. * * @param event processed event * @param originalSubRole original sub role * @param targetSubRole duplicate sub role. {@code null} if target role has to be created. * @return */ @Override public boolean duplicateRecursively(EntityEvent<IdmRoleDto> event, IdmRoleDto originalSubRole, IdmRoleDto targetSubRole) { return (targetSubRole != null && targetSubRole.getId() != null) || originalSubRole.getChildrenCount() > 0; } /** * Returns true, when role composition should be included in the target role * - it's not included, when sub role doesn't have the same environment * * @param event processed event * @param composition source composition * @return */ @Override public boolean includeComposition(EntityEvent<IdmRoleDto> event, IdmRoleCompositionDto composition) { IdmRoleDto subRole = DtoUtils.getEmbedded(composition, IdmRoleComposition_.sub); // return Objects.equals(event.getOriginalSource().getEnvironment(), subRole.getEnvironment()); } }
@since 9.5.0
IdmRoleDto
DUPLICATE
Duplicate configured automatic roles by tree structure. Automatic roles are duplicated recursively, if composition is duplicated recursively (see DuplicateRoleCompositionProcessor
above).
Parameters provided to the bulk action form:
Configuration properties:
## Enable / disable idm.sec.core.processor.core-duplicate-role-automatic-by-tree-processor.enabled=true
@since 9.5.0
IdmRoleDto
DUPLICATE
Duplicate configured automatic roles by attribute. Automatic roles are duplicated recursively, if composition is duplicated recursively (see DuplicateRoleCompositionProcessor
above).
Parameters provided to the bulk action form:
Configuration properties:
## Enable / disable idm.sec.core.processor.core-duplicate-role-automatic-by-attribute-processor.enabled=true
If we want to get hooked
after updating the identity
, we should implement a processor to the event type IdentityEventType.UPDATE
with an order number higher than 0:
@Enabled(ExampleModuleDescriptor.MODULE_ID) @Component("exampleLogIdentityUpdateSyncProcessor") @Description("Logs after identity is updated") public class LogIdentityUpdateSyncProcessor extends CoreEventProcessor<IdmIdentityDto> implements IdentityProcessor { /** * Processor's identifier - has to be unique by module */ public static final String PROCESSOR_NAME = "log-identity-update-sync-processor"; private static final org.slf4j.Logger LOG = org.slf4j.LoggerFactory .getLogger(LogIdentityUpdateSyncProcessor.class); public LogIdentityUpdateSyncProcessor() { // processing identity UPDATE event only super(IdentityEventType.UPDATE); } @Override public String getName() { // processor's identifier - has to be unique by module return PROCESSOR_NAME; } @Override public EventResult<IdmIdentityDto> process(EntityEvent<IdmIdentityDto> event) { // event content - identity IdmIdentityDto updateddIdentity = event.getContent(); // log LOG.info("Identity [{},{}] was updated.", updateddIdentity.getUsername(), updateddIdentity.getId()); // result return new DefaultEventResult<>(event, this); } @Override public int getOrder() { // right after identity update return CoreEvent.DEFAULT_ORDER + 1; } }
If we want to implement the same feature as above but asynchronously, we can process asynchronous IdentityEventType.NOTIFY
instead IdentityEventType.UPDATE
. When we need to change synchronous processors to asynchronous, we can simply change processed event type and add some condition, when only some original event types has to be processed ⇒ asynchronous NOTIFY
event type is published for CREATE, UPDATE and EAV_SAVE event types.
@Enabled(ExampleModuleDescriptor.MODULE_ID) @Component("exampleLogIdentityUpdateAsyncProcessor") @Description("Logs after identity is updated") public class LogIdentityUpdateAsyncProcessor extends CoreEventProcessor<IdmIdentityDto> implements IdentityProcessor { /** * Processor's identifier - has to be unique by module */ public static final String PROCESSOR_NAME = "log-identity-update-async-processor"; private static final org.slf4j.Logger LOG = org.slf4j.LoggerFactory .getLogger(LogIdentityUpdateAsyncProcessor.class); public LogIdentityUpdateAsyncProcessor() { // processing identity NOTIFY event only super(IdentityEventType.NOTIFY); } @Override public boolean conditional(EntityEvent<IdmIdentityDto> event) { // we want to process original UPDATE event only // async NOTIFY event is published for CREATE, UPDATE, EAV_SAVE event types return super.conditional(event) && IdentityEventType.UPDATE.name().equals(event.getProperties().get(EntityEventManager.EVENT_PROPERTY_PARENT_EVENT_TYPE)); } @Override public String getName() { // processor's identifier - has to be unique by module return PROCESSOR_NAME; } @Override public EventResult<IdmIdentityDto> process(EntityEvent<IdmIdentityDto> event) { // event content - identity IdmIdentityDto updateddIdentity = event.getContent(); // log LOG.info("Identity [{},{}] was updated.", updateddIdentity.getUsername(), updateddIdentity.getId()); // result return new DefaultEventResult<>(event, this); } @Override public int getOrder() { // notify event has their own process line - we can use default order return CoreEvent.DEFAULT_ORDER; } }