This is an old revision of the document!


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.

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;
	}
Now is possible add new bulk action only for identites. In future will be implement bulk actions for another agendas.

For easy start with creating new bulk action you can simple extends from abstract class AbstractBulkAction. Child is simple override methods:

  • processIdentity - process one identity,
  • getName - name of bulk action, this will be used for key in localization,
  • getPermissionForIdentity - required permission for process one identity,
  • getOrder - order in selecbox in identity agenda.
  • getLevel - level for bulk action button (success by default).

If you want use some settings for the bulk action you also must override method getFormAttributes. The method returns list of form attributes. With create the list of form attributes you can see example bulk action.

For all bulk actions doesn't exist form definition. Bulk action only return IdmFormAttributeDto. The IdmFormAttributeDto isn't persist.

After you implement all required method's and behavior for bulk action is necessary add localization for bulk action. For bulk actions is separate section in each localization. The section starts with bulkAction. Next key is actions and then name of your bulk action. For example: eav.bulk-action.<my-new-bulk-action>. Localization for form attributes is placed in localization with key: eav.bulk-action.<my-new-bulk-action>.attributes.

When we need add new agenda that will be support bulk actions on backend is necessary made this required steps:

  1. implements two method's in controller for specific agenda (for example you can check IdmIdentityController):
    • getAvailableBulkActions - return all available bulk action for the entity,
    • bulkAction - process the bulk action.
    • prevalidateBulkAction - prevalidate the bulk action.
  2. into frontend service change service's boolean with bulk action to true
    • supportsBulkAction=true

Now you can start use bulk actions.

  • by husniko