Capability Event processing algorithm

Capabilities and capability sets are created from permissions and permission sets, defined in the module descriptor.

capability-processing-20241010-141938.png
CapabilityEvent Processing flow
@startuml skinparam conditionStyle inside <style> activityDiagram { activity { MinimumWidth 400 MaximumWidth 400 HorizontalAlignment center backgroundColor #f0f0f0 LineColor DimGrey FontSize 14 } group { FontSize 12 LineColor LightGrey } } </style> group mgr-tenant-entitlements { :run entitlement flow for tenant; group CapabilitiesEventPublisher { :Get ModuleDescriptor from context; if (moduleDescriptor != null) then (yes) :Extract folio resources from moduleDescriptor //FolioResource(Permission, List<Endpoint>)// //mgr-tenant-entitlements extracts all provided routing entries and compares them with defined permissionSets, all unused permissionSets also included to the folioResources, but endpoints for them will be empty//; if (folioResources is empty) then (yes) #LightYellow:[debug] log that folioResources is empty; :skip processing current moduleDescriptor; stop; else (no) #LightYellow:[warn] check and log all permission names without defined permissionSets; :generate CapabilitiesEvent body with extracted folioResources; :publish CapabilitiesEvent; end if else (no) :skip processing current moduleDescriptor; stop; end if } } group Apache Kafka :receiveEvent; end group group mod-roles-keycloak { :poll CapabilityEvent from kafka; :process Capability Event; :save all received permissions to the database; group CapabilityEventProcessor { if (module type == MODULE) then (yes) :group permissions by having sub-permissions; :generate capabilities for permissionSets without sub-permissions //This is done to preserve permission names for permissionSets with sub-permissions, because they are relevant for UI components//; :generate capability sets for permissionSets with sub-permissions; else (no) :generate capabilities for all permissionSets; :generate capability sets for permissionSets with sub-permissions; end if :populate it as CapabilityResultHolder //CapabilityResultHolder(List<Capability>, List<CapabilitySetDescriptor>)// //CapabilitySetDescriptor contains capabilities// //as Map<String, List<CapabilityAction>>//; } :upsert Capabilities from CapabilityResultHolder; group CapabilityService { :update capabilities - retrieves existing capabilities by names - identifies what capabilities are new or updated - creates new capabilities or updates existing capabilities; :generate application events for created and updated capabilities // these events will be handled by mod-roles-keycloak application event listeners//; } :upsert CapabilitySetDescriptors from CapabilityResultHolder; group CapabilitySetDescriptorService { :resolve existing Capabilities by name and action from capabilities Map<String, List<CapabilityAction>>; :generate CapabilitySet from CapabilitySetDescriptor and resolved Capabilities; #LightYellow:[warn] log all unresolved capabilities; :update CapabilitySets - retrieves existing capability sets by names - identifies what capabilities are new or updated - creates a new capability sets - updates existing capability sets //A method identifies new and updated capability sets and updates them in the database//; :generate application events for created and updated capabilitySets // these events will be handled by mod-roles-keycloak application event listeners//; } } end @enduml