<commit_before>package eu.bcvsolutions.idm.core.scheduler.task.impl;

import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;

import eu.bcvsolutions.idm.core.api.domain.ConceptRoleRequestOperation;
import eu.bcvsolutions.idm.core.api.domain.CoreResultCode;
import eu.bcvsolutions.idm.core.api.domain.OperationState;
import eu.bcvsolutions.idm.core.api.domain.RoleRequestState;
import eu.bcvsolutions.idm.core.api.dto.AbstractIdmAutomaticRoleDto;
import eu.bcvsolutions.idm.core.api.dto.DefaultResultModel;
import eu.bcvsolutions.idm.core.api.dto.IdmAutomaticRoleAttributeDto;
import eu.bcvsolutions.idm.core.api.dto.IdmConceptRoleRequestDto;
import eu.bcvsolutions.idm.core.api.dto.IdmIdentityContractDto;
import eu.bcvsolutions.idm.core.api.dto.IdmIdentityDto;
import eu.bcvsolutions.idm.core.api.dto.IdmIdentityRoleDto;
import eu.bcvsolutions.idm.core.api.dto.IdmRoleDto;
import eu.bcvsolutions.idm.core.api.dto.IdmRoleRequestDto;
import eu.bcvsolutions.idm.core.api.dto.IdmRoleTreeNodeDto;
import eu.bcvsolutions.idm.core.api.dto.ResultModel;
import eu.bcvsolutions.idm.core.api.dto.filter.IdmAutomaticRoleRequestFilter;
import eu.bcvsolutions.idm.core.api.dto.filter.IdmConceptRoleRequestFilter;
import eu.bcvsolutions.idm.core.api.entity.OperationResult;
import eu.bcvsolutions.idm.core.api.exception.EntityNotFoundException;
import eu.bcvsolutions.idm.core.api.exception.ResultCodeException;
import eu.bcvsolutions.idm.core.api.service.IdmAutomaticRoleAttributeRuleService;
import eu.bcvsolutions.idm.core.api.service.IdmAutomaticRoleAttributeService;
import eu.bcvsolutions.idm.core.api.service.IdmAutomaticRoleRequestService;
import eu.bcvsolutions.idm.core.api.service.IdmConceptRoleRequestService;
import eu.bcvsolutions.idm.core.api.service.IdmIdentityContractService;
import eu.bcvsolutions.idm.core.api.service.IdmIdentityRoleService;
import eu.bcvsolutions.idm.core.api.service.IdmRoleRequestService;
import eu.bcvsolutions.idm.core.api.service.IdmRoleTreeNodeService;
import eu.bcvsolutions.idm.core.api.utils.AutowireHelper;
import eu.bcvsolutions.idm.core.api.utils.DtoUtils;
import eu.bcvsolutions.idm.core.eav.api.domain.BaseFaceType;
import eu.bcvsolutions.idm.core.eav.api.domain.PersistentType;
import eu.bcvsolutions.idm.core.eav.api.dto.IdmFormAttributeDto;
import eu.bcvsolutions.idm.core.model.entity.IdmIdentityContract_;
import eu.bcvsolutions.idm.core.model.entity.IdmIdentityRole_;
import eu.bcvsolutions.idm.core.model.entity.IdmRoleTreeNode_;
import eu.bcvsolutions.idm.core.scheduler.api.dto.IdmLongRunningTaskDto;
import eu.bcvsolutions.idm.core.scheduler.api.dto.filter.IdmLongRunningTaskFilter;
import eu.bcvsolutions.idm.core.scheduler.api.service.AbstractSchedulableStatefulExecutor;

/**
 * Long running task for remove automatic roles from identities.
 * 
 * @author <NAME> <<EMAIL>>
 * @author <NAME>
 *
 */
@Component(RemoveAutomaticRoleTaskExecutor.TASK_NAME)
public class RemoveAutomaticRoleTaskExecutor extends AbstractSchedulableStatefulExecutor<IdmIdentityRoleDto> {
	
	public static final String TASK_NAME = "core-remove-automatic-role-long-running-task";
	private static final org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(RemoveAutomaticRoleTaskExecutor.class);
	private static final String PARAMETER_AUTOMATIC_ROLE_TREE = "automaticRoleTree";
	private static final String PARAMETER_AUTOMATIC_ROLE_ATTRIBUTE = "automaticRoleAttribute";
	//
	@Autowired private IdmIdentityRoleService identityRoleService;
	@Autowired private IdmRoleTreeNodeService roleTreeNodeService;
	@Autowired private IdmAutomaticRoleAttributeService automaticRoleAttributeService;
	@Autowired private IdmConceptRoleRequestService conceptRequestService;
	@Autowired private IdmRoleRequestService roleRequestService;
	@Autowired private IdmIdentityContractService identityContractService;
	@Autowired private IdmAutomaticRoleAttributeRuleService automaticRoleAttributeRuleService;
	@Autowired private IdmAutomaticRoleRequestService automaticRoleRequestService;
	//
	private boolean deleteEntity = true; // At the end of the task remove whole entity (this isn't possible set via FE parameters)
	private UUID automaticRoleId = null;
	private AbstractIdmAutomaticRoleDto automaticRole = null;
	
	@Override
	public String getName() {
		return TASK_NAME;
	}
	
	/**
	 * Automatic role removal can be start, if previously LRT ended.
	 */
	@Override
	public void validate(IdmLongRunningTaskDto task) {
		super.validate(task);
		//
		UUID automaticRoleId = getAutomaticRoleId();
		AbstractIdmAutomaticRoleDto automaticRole = roleTreeNodeService.get(automaticRoleId);
		if (automaticRole == null) {
			// get from automatic role attribute service
			automaticRole = automaticRoleAttributeService.get(automaticRoleId);
		}
		if (automaticRole == null) {
			throw new EntityNotFoundException(AbstractIdmAutomaticRoleDto.class, automaticRoleId);
		}
		//
		IdmLongRunningTaskFilter filter = new IdmLongRunningTaskFilter();
		filter.setTaskType(AutowireHelper.getTargetType(this));
		filter.setRunning(Boolean.TRUE);
		//
		for (UUID longRunningTaskId : getLongRunningTaskService().findIds(filter, PageRequest.of(0, 1))) {
			throw new ResultCodeException(
					CoreResultCode.AUTOMATIC_ROLE_TASK_RUNNING,
					ImmutableMap.of("taskId", longRunningTaskId.toString())
			);
		}
		//
		filter.setTaskType(AutowireHelper.getTargetType(ProcessAutomaticRoleByTreeTaskExecutor.class));
		for (UUID longRunningTaskId : getLongRunningTaskService().findIds(filter, PageRequest.of(0, 1))) {
			throw new ResultCodeException(
					CoreResultCode.AUTOMATIC_ROLE_TASK_RUNNING,
					ImmutableMap.of("taskId", longRunningTaskId.toString())
			);
		}
		//
		filter.setTaskType(AutowireHelper.getTargetType(ProcessAutomaticRoleByAttributeTaskExecutor.class));
		for (IdmLongRunningTaskDto longRunningTask : getLongRunningTaskService().find(filter, null)) {
			if (longRunningTask.getTaskProperties().get(AbstractAutomaticRoleTaskExecutor.PARAMETER_ROLE_TREE_NODE).equals(automaticRole.getId())) {
				throw new ResultCodeException(CoreResultCode.AUTOMATIC_ROLE_REMOVE_TASK_ADD_RUNNING,
						ImmutableMap.of(
								"automaticRoleId", automaticRole.getId().toString(),
								"taskId", longRunningTask.getId().toString()));
			}
		}
	}
	
	@Override
	public void init(Map<String, Object> properties) {
		super.init(properties);
		//
		this.automaticRole = null;
		
		UUID id = getParameterConverter().toUuid(properties, AbstractAutomaticRoleTaskExecutor.PARAMETER_ROLE_TREE_NODE);
		if (id == null) {
			UUID automaticRoleTreeId = getParameterConverter().toUuid(properties, PARAMETER_AUTOMATIC_ROLE_TREE);
			UUID automaticRoleAttributeId = getParameterConverter().toUuid(properties, PARAMETER_AUTOMATIC_ROLE_ATTRIBUTE);
			if (automaticRoleTreeId != null && automaticRoleAttributeId != null) {
				throw new ResultCodeException(CoreResultCode.AUTOMATIC_ROLE_TASK_INVALID);
			}
			id = automaticRoleTreeId == null ? automaticRoleAttributeId : automaticRoleTreeId;
		}
		if (id == null) {
			throw new ResultCodeException(CoreResultCode.AUTOMATIC_ROLE_TASK_EMPTY);
		}
		this.setAutomaticRoleId(id);
	}<commit_msg>#2498 remove automatic role by attribute - validate currently removed role only<commit_after>package eu.bcvsolutions.idm.core.scheduler.task.impl;

import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;

import eu.bcvsolutions.idm.core.api.domain.ConceptRoleRequestOperation;
import eu.bcvsolutions.idm.core.api.domain.CoreResultCode;
import eu.bcvsolutions.idm.core.api.domain.OperationState;
import eu.bcvsolutions.idm.core.api.domain.RoleRequestState;
import eu.bcvsolutions.idm.core.api.dto.AbstractIdmAutomaticRoleDto;
import eu.bcvsolutions.idm.core.api.dto.DefaultResultModel;
import eu.bcvsolutions.idm.core.api.dto.IdmAutomaticRoleAttributeDto;
import eu.bcvsolutions.idm.core.api.dto.IdmConceptRoleRequestDto;
import eu.bcvsolutions.idm.core.api.dto.IdmIdentityContractDto;
import eu.bcvsolutions.idm.core.api.dto.IdmIdentityDto;
import eu.bcvsolutions.idm.core.api.dto.IdmIdentityRoleDto;
import eu.bcvsolutions.idm.core.api.dto.IdmRoleDto;
import eu.bcvsolutions.idm.core.api.dto.IdmRoleRequestDto;
import eu.bcvsolutions.idm.core.api.dto.IdmRoleTreeNodeDto;
import eu.bcvsolutions.idm.core.api.dto.ResultModel;
import eu.bcvsolutions.idm.core.api.dto.filter.IdmAutomaticRoleRequestFilter;
import eu.bcvsolutions.idm.core.api.dto.filter.IdmConceptRoleRequestFilter;
import eu.bcvsolutions.idm.core.api.entity.OperationResult;
import eu.bcvsolutions.idm.core.api.exception.EntityNotFoundException;
import eu.bcvsolutions.idm.core.api.exception.ResultCodeException;
import eu.bcvsolutions.idm.core.api.service.IdmAutomaticRoleAttributeRuleService;
import eu.bcvsolutions.idm.core.api.service.IdmAutomaticRoleAttributeService;
import eu.bcvsolutions.idm.core.api.service.IdmAutomaticRoleRequestService;
import eu.bcvsolutions.idm.core.api.service.IdmConceptRoleRequestService;
import eu.bcvsolutions.idm.core.api.service.IdmIdentityContractService;
import eu.bcvsolutions.idm.core.api.service.IdmIdentityRoleService;
import eu.bcvsolutions.idm.core.api.service.IdmRoleRequestService;
import eu.bcvsolutions.idm.core.api.service.IdmRoleTreeNodeService;
import eu.bcvsolutions.idm.core.api.utils.AutowireHelper;
import eu.bcvsolutions.idm.core.api.utils.DtoUtils;
import eu.bcvsolutions.idm.core.eav.api.domain.BaseFaceType;
import eu.bcvsolutions.idm.core.eav.api.domain.PersistentType;
import eu.bcvsolutions.idm.core.eav.api.dto.IdmFormAttributeDto;
import eu.bcvsolutions.idm.core.model.entity.IdmIdentityContract_;
import eu.bcvsolutions.idm.core.model.entity.IdmIdentityRole_;
import eu.bcvsolutions.idm.core.model.entity.IdmRoleTreeNode_;
import eu.bcvsolutions.idm.core.scheduler.api.dto.IdmLongRunningTaskDto;
import eu.bcvsolutions.idm.core.scheduler.api.dto.filter.IdmLongRunningTaskFilter;
import eu.bcvsolutions.idm.core.scheduler.api.service.AbstractSchedulableStatefulExecutor;

/**
 * Long running task for remove automatic roles from identities.
 * 
 * @author <NAME> <<EMAIL>>
 * @author <NAME>
 *
 */
@Component(RemoveAutomaticRoleTaskExecutor.TASK_NAME)
public class RemoveAutomaticRoleTaskExecutor extends AbstractSchedulableStatefulExecutor<IdmIdentityRoleDto> {
	
	public static final String TASK_NAME = "core-remove-automatic-role-long-running-task";
	private static final org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(RemoveAutomaticRoleTaskExecutor.class);
	private static final String PARAMETER_AUTOMATIC_ROLE_TREE = "automaticRoleTree";
	private static final String PARAMETER_AUTOMATIC_ROLE_ATTRIBUTE = "automaticRoleAttribute";
	//
	@Autowired private IdmIdentityRoleService identityRoleService;
	@Autowired private IdmRoleTreeNodeService roleTreeNodeService;
	@Autowired private IdmAutomaticRoleAttributeService automaticRoleAttributeService;
	@Autowired private IdmConceptRoleRequestService conceptRequestService;
	@Autowired private IdmRoleRequestService roleRequestService;
	@Autowired private IdmIdentityContractService identityContractService;
	@Autowired private IdmAutomaticRoleAttributeRuleService automaticRoleAttributeRuleService;
	@Autowired private IdmAutomaticRoleRequestService automaticRoleRequestService;
	//
	private boolean deleteEntity = true; // At the end of the task remove whole entity (this isn't possible set via FE parameters)
	private UUID automaticRoleId = null;
	private AbstractIdmAutomaticRoleDto automaticRole = null;
	
	@Override
	public String getName() {
		return TASK_NAME;
	}
	
	/**
	 * Automatic role removal can be start, if previously LRT ended.
	 */
	@Override
	public void validate(IdmLongRunningTaskDto task) {
		super.validate(task);
		//
		UUID automaticRoleId = getAutomaticRoleId();
		boolean byTree = true;
		AbstractIdmAutomaticRoleDto automaticRole = roleTreeNodeService.get(automaticRoleId);
		if (automaticRole == null) {
			// get from automatic role attribute service
			byTree = false;
			automaticRole = automaticRoleAttributeService.get(automaticRoleId);
		}
		if (automaticRole == null) {
			throw new EntityNotFoundException(AbstractIdmAutomaticRoleDto.class, automaticRoleId);
		}
		//
		IdmLongRunningTaskFilter filter = new IdmLongRunningTaskFilter();
		filter.setTaskType(AutowireHelper.getTargetType(this));
		filter.setRunning(Boolean.TRUE);
		//
		if (byTree) {
			for (UUID longRunningTaskId : getLongRunningTaskService().findIds(filter, PageRequest.of(0, 1))) {
				throw new ResultCodeException(
						CoreResultCode.AUTOMATIC_ROLE_TASK_RUNNING,
						ImmutableMap.of("taskId", longRunningTaskId.toString())
				);
			}
			//
			filter.setTaskType(AutowireHelper.getTargetType(ProcessAutomaticRoleByTreeTaskExecutor.class));
			for (UUID longRunningTaskId : getLongRunningTaskService().findIds(filter, PageRequest.of(0, 1))) {
				throw new ResultCodeException(
						CoreResultCode.AUTOMATIC_ROLE_TASK_RUNNING,
						ImmutableMap.of("taskId", longRunningTaskId.toString())
				);
			}
		} else { // by attribute - prevent currently removed role only
			for (IdmLongRunningTaskDto longRunningTask : getLongRunningTaskService().find(filter, null)) {
				if (longRunningTask.getTaskProperties().get(AbstractAutomaticRoleTaskExecutor.PARAMETER_ROLE_TREE_NODE).equals(automaticRole.getId())) {
					throw new ResultCodeException(CoreResultCode.AUTOMATIC_ROLE_REMOVE_TASK_RUN_CONCURRENTLY,
							ImmutableMap.of(
									"roleTreeNode", automaticRole.getId().toString(),
									"taskId", longRunningTask.getId().toString()));
				}
			}
			//
			filter.setTaskType(AutowireHelper.getTargetType(ProcessAutomaticRoleByAttributeTaskExecutor.class));
			for (IdmLongRunningTaskDto longRunningTask : getLongRunningTaskService().find(filter, null)) {
				if (longRunningTask.getTaskProperties().get(AbstractAutomaticRoleTaskExecutor.PARAMETER_ROLE_TREE_NODE).equals(automaticRole.getId())) {
					throw new ResultCodeException(CoreResultCode.AUTOMATIC_ROLE_REMOVE_TASK_ADD_RUNNING,
							ImmutableMap.of(
									"automaticRoleId", automaticRole.getId().toString(),
									"taskId", longRunningTask.getId().toString()));
				}
			}
		}	
	}
	
	@Override
	public void init(Map<String, Object> properties) {
		super.init(properties);
		//
		this.automaticRole = null;
		
		UUID id = getParameterConverter().toUuid(properties, AbstractAutomaticRoleTaskExecutor.PARAMETER_ROLE_TREE_NODE);
		if (id == null) {
			UUID automaticRoleTreeId = getParameterConverter().toUuid(properties, PARAMETER_AUTOMATIC_ROLE_TREE);
			UUID automaticRoleAttributeId = getParameterConverter().toUuid(properties, PARAMETER_AUTOMATIC_ROLE_ATTRIBUTE);
			if (automaticRoleTreeId != null && automaticRoleAttributeId != null) {
				throw new ResultCodeException(CoreResultCode.AUTOMATIC_ROLE_TASK_INVALID);
			}
			id = automaticRoleTreeId == null ? automaticRoleAttributeId : automaticRoleTreeId;
		}
		if (id == null) {
			throw new ResultCodeException(CoreResultCode.AUTOMATIC_ROLE_TASK_EMPTY);
		}
		this.setAutomaticRoleId(id);
	}
{'fraction_non_alphanumeric': 0.0961092663366957, 'fraction_numerical': 0.0011277488879142912, 'mean_word_length': 6.298582533150435, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6726837', 'n_tokens_mistral': 5267, 'n_tokens_neox': 5075, 'n_words': 738}