Bulk actions

Bulk actions were introduced to IdM in order to make actions, applied to items in a table, more efficient and safe. Higher efficiency means that there is sent to BE only a list of IDs of affected items or items can also be selected by filter. Filter is accompanied with the list of IDs of items excluded from that action. Safety is reached by adding a validation feature which is, if implemented for particular action, evaluated before bulk action itself and is intended for notification of users that there may occur some conflicts which may prevent from successful action completion.

Ways of item selection:

  • Individual item selection - When user checks individual items in a table such items are chosen to be processed by bulk action. IDs of these items are sent to BE together with type of the selected bulk action.
  • All items selection - In case of using the checkbox which marks all items as selected, selection is controlled by filter. Individual items may be unchecked by which they are added to the list of items excluded from processing. Such filter setting is sent to BE together with the list of excluded items.

* Applying action without item specification - The last supported option is to apply bulk action to the whole agenda without any item specification. All items are included. This option is by default disabled and needs to by enabled in BE bulk action implementation by overloading method showWithoutSelection returning true value.

Every agenda is allowed to have more implemented bulk actions for different purposes. It is possible to combine all selection strategies. First two selection strategies are controlled by another method showWithSelection with default returning value set to true.

Available bulk actions are shown with respect currently logged user authorities - required authority can be specified in bulk action getAuthoritiesForEntity method.

After that controller receives a new bulk action request (rest post method), it transforms given map<String, Object> to filter and executes new bulk action as new long running task. Abstract parent of all bulk action classes AbstractBulkAction provides basic validation method for form attributes and functionality of sending notification message. It also ensures processing of the set filter or received set of IDs. In case of using filter, IDs to process are obtained by findIds method invocation with given filter. From this moment the set of IDs cannot be changed. All bulk actions has implementation of processEntities method. This method processes supplied entities and returns operation result. If this method throws an exception it is caught by parent method and a new failure log record is created.

After processing entity (regardless whether successful or not) a new log with result is created. These log items are saved into processed items in the same table as schedulable tasks are but without removing or checking that item exists. It is necessary to check permission for every processed item and return exception (ForbiddenEntityException) or ResultModels with NOT_EXECUTED state. This check is provided by abstract class method checkPermissionForEntity.

In some cases, we need to obtain additional information and show it to user before bulk operation starts. For example operation invoking account management for all identities with specific role. In this case we want to show how many identities has assigned that role (before operation starts).

Prevalidate feature was developed exactly for this purpose. Every bulk operation implements method `prevalidate` which is supposed to be overloaded by developer. Overloaded method implements entire process of validation and its result is stored into info list of the `ResultModels` object which is returned from this method. Items in the info list are ResultModel objects consisting of AccResultCode and a Map of values which are then rendered on the FE.

Every `ResultModel` record in `infos` list will be shown on the bulk action detail.
Messages are defined as standard result codes. See code `AccResultCode.ROLE_ACM_BULK_ACTION_NUMBER_OF_IDENTITIES` in the example below.

There is example implementation of the prevalidate method in the `RoleAccountManagementBulkAction`:

@Override
	public ResultModels prevalidate() {
		IdmBulkActionDto action = getAction();
		List<UUID> entities = getEntities(action, new StringBuilder());
		ResultModels result = new ResultModels();
 
		Map<ResultModel, Long> models = new HashMap<>();
		entities.forEach(roleId -> {
			IdmIdentityRoleFilter identityRoleFilter = new IdmIdentityRoleFilter();
			identityRoleFilter.setRoleId(roleId);
			IdmRoleDto role = getService().get(roleId);
 
			long count = identityRoleService.find(identityRoleFilter, null).getTotalElements();
			if (count > 0) {
				models.put(new DefaultResultModel(AccResultCode.ROLE_ACM_BULK_ACTION_NUMBER_OF_IDENTITIES,
						ImmutableMap.of("role", role.getName(), "count", count)), count);
			}
		});
 
		boolean someIdentitiesFound = models.values() //
				.stream() //
				.filter(count -> count > 0) //
				.findFirst() //
				.isPresent(); //
 
		if (!someIdentitiesFound) {
			result.addInfo(new DefaultResultModel(AccResultCode.ROLE_ACM_BULK_ACTION_NONE_IDENTITIES));
		} else {
			// Sort by count
			List<Entry<ResultModel, Long>> collect = models //
					.entrySet() //
					.stream() //
					.sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) //
					.limit(5) //
					.collect(Collectors.toList()); //
			collect.forEach(entry -> {
				result.addInfo(entry.getKey());
			});
		}
 
		return result;
	}

@since 10.6.0

Bulk action order, icon, level and other properties can be configured by application setting.

Available bulk action can be shown in bulk action agenda available from menu - Settings - Modules - Bulk actions

All configurable properties (e.g. order) are shown in frontend agenda. Bulk Action can be disabled (or enabled) directly from this agenda (other configurable properties will be added in future).

New bulk action creation

For easy start of creating a new bulk action you need just extend the abstract class AbstractBulkAction. Descendant then simply overrides used methods:

  • getName - name of bulk action, it will be used as key in localization
  • getAuthoritiesForEntity - required permissions for processing of entities
  • getOrder - order in selectbox in agenda
  • getService - the service, items of which are processed by bulk action
  • processEntities - iterates over all selected items and is supposed to provide check of permissions and processing invocation
  • processDto - is called by processEntities method and implements processing of every single item
  • getLevel - level for bulk action button (success ​by default)
  • isDeleteAction - false by default. Action deletes records (for FE only). Action will be in bottom menu section, is action is included in menu.
  • isQuickButton - false by default. Render action as quick button (for FE only). The first available actions are rendered as buttons, if icon is defined. This configuration enforces rendering action as quick button (order is ignored).

If one wants to use some settings of the bulk action it is necessary to override getFormAttributes method too. This method returns list of form attributes displayed in the window on FE.

Bulk actions don't use persistent form definition kept in IdmFormAttributeDto. This definition is created ad hoc by calling getFormAttributes method.

After implementation of all BE parts enabling support of the required bulk action, it is also necessary to add its localization. It needs to be put into section following this path eav.bulk-action.<my-new-bulk-action> in all localization files. Form attribute localization parts are placed into eav.bulk-action.<my-new-bulk-action>.attributes section.

"provisioning-operation-cancel-bulk-action": {
   "label": "Cancel operation",
   "help": "Cancel provisioning operations.",
   "icon": "fa:ban",
   "attributes": {
      "retrywholebatch": {
         "label": "Cancel full batch",
         "help": "Cancel all operations for entity in queue? After uncheck will be canceled only selected operation in queue."
      }
   }
}

In order to add support of bulk actions for particular agenda, it is necessary to implement following methods.

  1. in BE controller class (for example you can check IdmIdentityController):
    • getAvailableBulkActions - returns all available bulk actions (mandatory)
    • bulkAction - processes the bulk action (mandatory)
    • prevalidateBulkAction - invokes the bulk action prevalidation (optional)
  2. in FE service class (for inspiration see IdentityService)
    • supportsBulkAction - has to return true
    • showRowSelection - this Advanced.Table property needs to be set true without any permission conditions (permissions are resolved on BE)

Now you can start using bulk actions.

  • by husniko