use of eu.bcvsolutions.idm.core.api.dto.filter.IdmContractPositionFilter in project CzechIdMng by bcvsolutions.
the class IdentityContractDeleteProcessor method process.
@Override
public EventResult<IdmIdentityContractDto> process(EntityEvent<IdmIdentityContractDto> event) {
IdmIdentityContractDto contract = event.getContent();
UUID contractId = contract.getId();
Assert.notNull(contractId, "Contract must have a ID!");
boolean forceDelete = getBooleanProperty(PROPERTY_FORCE_DELETE, event.getProperties());
//
// check contract can be deleted - cannot be deleted, when is controlled by slices
IdmContractSliceFilter sliceFilter = new IdmContractSliceFilter();
sliceFilter.setParentContract(contractId);
if (contractSliceService.find(sliceFilter, null).getTotalElements() > 0) {
// Cannot be enforced => contract cannot be deleted at all.
throw new ResultCodeException(CoreResultCode.CONTRACT_IS_CONTROLLED_CANNOT_BE_DELETED, ImmutableMap.of("contractId", contractId));
}
//
// Find all concepts and remove relation on contract
IdmConceptRoleRequestFilter conceptRequestFilter = new IdmConceptRoleRequestFilter();
conceptRequestFilter.setIdentityContractId(contractId);
conceptRequestService.find(conceptRequestFilter, null).getContent().forEach(concept -> {
String message = null;
if (concept.getState().isTerminatedState()) {
message = MessageFormat.format("IdentityContract [{0}] (requested in concept [{1}]) was deleted (not from this role request)!", contractId, concept.getId());
} else {
message = MessageFormat.format("Request change in concept [{0}], was not executed, because requested IdentityContract [{1}] was deleted (not from this role request)!", concept.getId(), contractId);
// Cancel concept and WF
concept = conceptRequestService.cancel(concept);
}
IdmRoleRequestDto request = roleRequestService.get(concept.getRoleRequest());
roleRequestService.addToLog(request, message);
conceptRequestService.addToLog(concept, message);
roleRequestService.save(request);
conceptRequestService.save(concept);
});
//
// delete referenced roles
List<IdmConceptRoleRequestDto> concepts = new ArrayList<>();
identityRoleService.findAllByContract(contractId).forEach(identityRole -> {
// but automatic roles has to be removed in the same request.
if (identityRole.getDirectRole() == null) {
IdmConceptRoleRequestDto conceptRoleRequest = new IdmConceptRoleRequestDto();
conceptRoleRequest.setIdentityRole(identityRole.getId());
conceptRoleRequest.setRole(identityRole.getRole());
conceptRoleRequest.setOperation(ConceptRoleRequestOperation.REMOVE);
// ignore not found
conceptRoleRequest.setIdentityContract(contractId);
//
concepts.add(conceptRoleRequest);
}
});
if (forceDelete) {
// ~ async with force
IdmRoleRequestDto roleRequest = new IdmRoleRequestDto();
roleRequest.setApplicant(contract.getIdentity());
roleRequest.setConceptRoles(concepts);
//
RoleRequestEvent requestEvent = new RoleRequestEvent(RoleRequestEventType.EXCECUTE, roleRequest);
requestEvent.setPriority(PriorityType.HIGH);
//
roleRequestService.startConcepts(requestEvent, event);
} else {
// ~ sync
roleRequestService.executeConceptsImmediate(contract.getIdentity(), concepts);
}
// delete contract guarantees
IdmContractGuaranteeFilter filter = new IdmContractGuaranteeFilter();
filter.setIdentityContractId(contractId);
contractGuaranteeService.find(filter, null).forEach(guarantee -> {
contractGuaranteeService.delete(guarantee);
});
// delete contract positions
IdmContractPositionFilter positionFilter = new IdmContractPositionFilter();
positionFilter.setIdentityContractId(contractId);
contractPositionService.find(positionFilter, null).forEach(position -> {
contractPositionService.delete(position);
});
//
// delete all contract's delegations
IdmDelegationDefinitionFilter delegationFilter = new IdmDelegationDefinitionFilter();
delegationFilter.setDelegatorContractId(contractId);
delegationDefinitionService.find(delegationFilter, null).forEach(delegation -> {
delegationDefinitionService.delete(delegation);
});
// delete identity contract
if (forceDelete) {
LOG.debug("Contract [{}] should be deleted by caller after all asynchronus processes are completed.", contractId);
//
// dirty flag only - will be processed after asynchronous events ends
IdmEntityStateDto stateDeleted = new IdmEntityStateDto();
stateDeleted.setEvent(event.getId());
stateDeleted.setResult(new OperationResultDto.Builder(OperationState.RUNNING).setModel(new DefaultResultModel(CoreResultCode.DELETED)).build());
entityStateManager.saveState(contract, stateDeleted);
//
// set disabled
contract.setState(ContractState.DISABLED);
service.saveInternal(contract);
} else {
service.deleteInternal(contract);
}
return new DefaultEventResult<>(event, this);
}
use of eu.bcvsolutions.idm.core.api.dto.filter.IdmContractPositionFilter in project CzechIdMng by bcvsolutions.
the class IdentityContractUpdateByAutomaticRoleProcessor method process.
@Override
public EventResult<IdmIdentityContractDto> process(EntityEvent<IdmIdentityContractDto> event) {
IdmIdentityContractDto contract = event.getContent();
IdmIdentityContractDto previous = event.getOriginalSource();
UUID previousPosition = previous == null ? null : previous.getWorkPosition();
UUID newPosition = contract.getWorkPosition();
boolean validityChangedToValid = previous == null ? false : contract.isValidNowOrInFuture() && previous.isValidNowOrInFuture() != contract.isValidNowOrInFuture();
IdmRoleRequestDto roleRequest = new IdmRoleRequestDto();
// flag can be processed afterwards
if (getBooleanProperty(AutomaticRoleManager.SKIP_RECALCULATION, event.getProperties())) {
LOG.debug("Automatic roles are skipped for contract [{}], state [{}] " + "for position will be created only.", contract.getId(), CoreResultCode.AUTOMATIC_ROLE_SKIPPED.getCode());
//
Map<String, Serializable> properties = new HashMap<>();
// original contract as property
properties.put(EntityEvent.EVENT_PROPERTY_ORIGINAL_SOURCE, event.getOriginalSource());
entityStateManager.createState(contract, OperationState.BLOCKED, contract.isValidNowOrInFuture() ? CoreResultCode.AUTOMATIC_ROLE_SKIPPED : CoreResultCode.AUTOMATIC_ROLE_SKIPPED_INVALID_CONTRACT, properties);
//
return new DefaultEventResult<>(event, this);
}
if (!contract.isValidNowOrInFuture()) {
// but we need to add skipped flag above, even when invalid contract is updated
return new DefaultEventResult<>(event, this);
}
//
if (previous == null || !Objects.equals(newPosition, previousPosition) || validityChangedToValid) {
// work positions has some difference or validity changes
List<IdmIdentityRoleDto> assignedRoles = getAssignedAutomaticRoles(contract.getId());
// remove all automatic roles by attribute and by other contract position
if (!assignedRoles.isEmpty()) {
assignedRoles = assignedRoles.stream().filter(autoRole -> {
// remove automatic roles by attribute - solved by different process
AbstractIdmAutomaticRoleDto automaticRoleDto = DtoUtils.getEmbedded(autoRole, IdmIdentityRole_.automaticRole, (AbstractIdmAutomaticRoleDto) null);
if (automaticRoleDto instanceof IdmRoleTreeNodeDto) {
return true;
}
return false;
}).filter(identityRole -> {
// remove automatic roles by attribute - solved by different process
return identityRole.getContractPosition() == null;
}).collect(Collectors.toList());
}
//
Set<UUID> previousAutomaticRoles = assignedRoles.stream().filter(identityRole -> {
return identityRole.getAutomaticRole() != null;
}).map(identityRole -> {
return identityRole.getAutomaticRole();
}).collect(Collectors.toSet());
Set<IdmRoleTreeNodeDto> addedAutomaticRoles = new HashSet<>();
if (newPosition != null && contract.isValidNowOrInFuture()) {
addedAutomaticRoles = roleTreeNodeService.getAutomaticRolesByTreeNode(newPosition);
}
// prevent to remove newly added or still exists roles
Set<UUID> removedAutomaticRoles = new HashSet<>(previousAutomaticRoles);
removedAutomaticRoles.removeAll(addedAutomaticRoles.stream().map(IdmRoleTreeNodeDto::getId).collect(Collectors.toList()));
addedAutomaticRoles.removeIf(a -> {
return previousAutomaticRoles.contains(a.getId());
});
//
for (UUID removedAutomaticRole : removedAutomaticRoles) {
Iterator<IdmIdentityRoleDto> iter = assignedRoles.iterator();
while (iter.hasNext()) {
IdmIdentityRoleDto identityRole = iter.next();
if (Objects.equals(identityRole.getAutomaticRole(), removedAutomaticRole)) {
// check, if role will be added by new automatic roles and prevent removing
IdmRoleTreeNodeDto addedAutomaticRole = getByRole(identityRole.getRole(), addedAutomaticRoles);
if (addedAutomaticRole == null) {
// remove assigned role
IdmConceptRoleRequestDto conceptRoleRequest = new IdmConceptRoleRequestDto();
conceptRoleRequest.setIdentityRole(identityRole.getId());
conceptRoleRequest.setRole(identityRole.getRole());
conceptRoleRequest.setOperation(ConceptRoleRequestOperation.REMOVE);
//
roleRequest.getConceptRoles().add(conceptRoleRequest);
iter.remove();
} else {
// change relation only
IdmConceptRoleRequestDto conceptRoleRequest = new IdmConceptRoleRequestDto();
conceptRoleRequest.setIdentityRole(identityRole.getId());
conceptRoleRequest.setAutomaticRole(addedAutomaticRole.getId());
conceptRoleRequest.setIdentityContract(contract.getId());
conceptRoleRequest.setValidFrom(contract.getValidFrom());
conceptRoleRequest.setValidTill(contract.getValidTill());
conceptRoleRequest.setRole(identityRole.getRole());
conceptRoleRequest.setOperation(ConceptRoleRequestOperation.UPDATE);
//
roleRequest.getConceptRoles().add(conceptRoleRequest);
//
// new automatic role is not needed
addedAutomaticRoles.remove(addedAutomaticRole);
}
}
}
}
// change date - for unchanged assigned roles only
if (previous != null && EntityUtils.validableChanged(previous, contract)) {
roleRequest.getConceptRoles().addAll(changeValidable(contract, assignedRoles));
}
// add identity roles
for (AbstractIdmAutomaticRoleDto autoRole : addedAutomaticRoles) {
IdmConceptRoleRequestDto conceptRoleRequest = new IdmConceptRoleRequestDto();
conceptRoleRequest.setIdentityContract(contract.getId());
conceptRoleRequest.setValidFrom(contract.getValidFrom());
conceptRoleRequest.setValidTill(contract.getValidTill());
conceptRoleRequest.setRole(autoRole.getRole());
conceptRoleRequest.setAutomaticRole(autoRole.getId());
conceptRoleRequest.setOperation(ConceptRoleRequestOperation.ADD);
//
roleRequest.getConceptRoles().add(conceptRoleRequest);
}
// contract is enabled => process all contract positions
if (validityChangedToValid) {
IdmContractPositionFilter filter = new IdmContractPositionFilter();
filter.setIdentityContractId(contract.getId());
//
for (IdmContractPositionDto position : contractPositionService.find(filter, null).getContent()) {
CoreEvent<IdmContractPositionDto> positionEvent = new CoreEvent<>(CoreEventType.NOTIFY, position);
// we don't need the second asynchronicity
positionEvent.setPriority(PriorityType.IMMEDIATE);
positionEvent.getProperties().put(EVENT_PROPERTY_REQUEST, roleRequest);
// recount automatic roles for given position
EventContext<IdmContractPositionDto> context = contractPositionService.publish(positionEvent, event);
// get modified prepared request
if (context.getLastResult() != null) {
roleRequest = (IdmRoleRequestDto) context.getLastResult().getEvent().getProperties().get(EVENT_PROPERTY_REQUEST);
}
}
}
} else if (previous != null && EntityUtils.validableChanged(previous, contract)) {
// process validable change only
roleRequest.getConceptRoles().addAll(changeValidable(contract, getAssignedAutomaticRoles(contract.getId())));
}
// start request at end asynchronously
roleRequest.setApplicant(contract.getIdentity());
RoleRequestEvent requestEvent = new RoleRequestEvent(RoleRequestEventType.EXCECUTE, roleRequest);
roleRequestService.startConcepts(requestEvent, event);
//
return new DefaultEventResult<>(event, this);
}
use of eu.bcvsolutions.idm.core.api.dto.filter.IdmContractPositionFilter in project CzechIdMng by bcvsolutions.
the class ContractSynchronizationExecutor method save.
/**
* Save entity
*
* @param entity
* @param skipProvisioning
* @return
*/
@Override
protected IdmIdentityContractDto save(IdmIdentityContractDto entity, boolean skipProvisioning, SynchronizationContext context) {
if (entity.getIdentity() == null) {
throw new ProvisioningException(AccResultCode.SYNCHRONIZATION_IDM_FIELD_CANNOT_BE_NULL, ImmutableMap.of("property", CONTRACT_IDENTITY_FIELD));
}
EntityEvent<IdmIdentityContractDto> event = new IdentityContractEvent(contractService.isNew(entity) ? IdentityContractEventType.CREATE : IdentityContractEventType.UPDATE, entity, ImmutableMap.of(ProvisioningService.SKIP_PROVISIONING, skipProvisioning));
// We do not want execute HR processes for every contract. We need start
// them for every identity only once.
// For this we skip them now. HR processes must be start after whole
// sync finished (by using dependent scheduled task)!
event.getProperties().put(IdmIdentityContractService.SKIP_HR_PROCESSES, Boolean.TRUE);
//
// We don't want recalculate automatic role by attribute recalculation for every
// contract.
// Recalculation will be started only once.
event.getProperties().put(AutomaticRoleManager.SKIP_RECALCULATION, Boolean.TRUE);
EventContext<IdmIdentityContractDto> publishContext = contractService.publish(event);
IdmIdentityContractDto contract = publishContext.getContent();
// We need to flag recalculation for contract immediately to prevent synchronization ends before flag is created by NOTIFY event asynchronously.
Map<String, Serializable> properties = new HashMap<>();
EventResult<IdmIdentityContractDto> lastResult = publishContext.getLastResult();
if (lastResult != null) {
// original contract as property
properties.put(EntityEvent.EVENT_PROPERTY_ORIGINAL_SOURCE, lastResult.getEvent().getOriginalSource());
}
if (contract.isValidNowOrInFuture()) {
entityStateManager.createState(contract, OperationState.BLOCKED, CoreResultCode.AUTOMATIC_ROLE_SKIPPED, properties);
} else {
entityStateManager.createState(contract, OperationState.BLOCKED, CoreResultCode.AUTOMATIC_ROLE_SKIPPED_INVALID_CONTRACT, properties);
}
//
if (entity.getEmbedded().containsKey(SYNC_CONTRACT_FIELD)) {
SyncIdentityContractDto syncContract = (SyncIdentityContractDto) entity.getEmbedded().get(SYNC_CONTRACT_FIELD);
// Positions
IdmContractPositionFilter positionFilter = new IdmContractPositionFilter();
positionFilter.setIdentityContractId(contract.getId());
List<IdmContractPositionDto> currentPositions = contractPositionService.find(positionFilter, null).getContent();
// Search positions to delete
List<IdmContractPositionDto> positionsToDelete = currentPositions.stream().filter(position -> {
return position.getWorkPosition() != null && !syncContract.getPositions().contains(new IdmTreeNodeDto(position.getWorkPosition()));
}).collect(Collectors.toList());
// Search positions to add
List<IdmTreeNodeDto> positionsToAdd = syncContract.getPositions().stream().filter(position -> {
return !currentPositions.stream().filter(currentPosition -> {
return position.getId().equals(currentPosition.getWorkPosition());
}).findFirst().isPresent();
}).collect(Collectors.toList());
// Create new positions
positionsToAdd.forEach(position -> {
IdmContractPositionDto contractPosition = new IdmContractPositionDto();
contractPosition.setIdentityContract(contract.getId());
contractPosition.setWorkPosition(position.getId());
//
EntityEvent<IdmContractPositionDto> positionEvent = new ContractPositionEvent(ContractPositionEventType.CREATE, contractPosition, ImmutableMap.of(ProvisioningService.SKIP_PROVISIONING, skipProvisioning, AutomaticRoleManager.SKIP_RECALCULATION, Boolean.TRUE));
contractPosition = contractPositionService.publish(positionEvent).getContent();
// We need to flag recalculation for contract immediately to prevent synchronization ends before flag is created by NOTIFY event asynchronously.
if (contract.isValidNowOrInFuture()) {
entityStateManager.createState(contractPosition, OperationState.BLOCKED, CoreResultCode.AUTOMATIC_ROLE_SKIPPED, null);
}
});
// Delete positions - should be after new positions are created (prevent to drop and create => delete is sync).
positionsToDelete.forEach(position -> {
EntityEvent<IdmContractPositionDto> positionEvent = new ContractPositionEvent(ContractPositionEventType.DELETE, position, ImmutableMap.of(ProvisioningService.SKIP_PROVISIONING, skipProvisioning, AutomaticRoleManager.SKIP_RECALCULATION, Boolean.TRUE));
contractPositionService.publish(positionEvent);
});
// Guarantees
IdmContractGuaranteeFilter guaranteeFilter = new IdmContractGuaranteeFilter();
guaranteeFilter.setIdentityContractId(contract.getId());
List<IdmContractGuaranteeDto> currentGuarantees = guaranteeService.find(guaranteeFilter, null).getContent();
// Search guarantees to delete
List<IdmContractGuaranteeDto> guaranteesToDelete = currentGuarantees.stream().filter(sysImplementer -> {
return sysImplementer.getGuarantee() != null && !syncContract.getGuarantees().contains(new IdmIdentityDto(sysImplementer.getGuarantee()));
}).collect(Collectors.toList());
// Search guarantees to add
List<IdmIdentityDto> guaranteesToAdd = syncContract.getGuarantees().stream().filter(identity -> {
return !currentGuarantees.stream().filter(currentGuarrantee -> {
return identity.getId().equals(currentGuarrantee.getGuarantee());
}).findFirst().isPresent();
}).collect(Collectors.toList());
// Delete guarantees
guaranteesToDelete.forEach(guarantee -> {
EntityEvent<IdmContractGuaranteeDto> guaranteeEvent = new ContractGuaranteeEvent(ContractGuaranteeEventType.DELETE, guarantee, ImmutableMap.of(ProvisioningService.SKIP_PROVISIONING, skipProvisioning));
guaranteeService.publish(guaranteeEvent);
});
// Create new guarantees
guaranteesToAdd.forEach(identity -> {
IdmContractGuaranteeDto guarantee = new IdmContractGuaranteeDto();
guarantee.setIdentityContract(contract.getId());
guarantee.setGuarantee(identity.getId());
//
EntityEvent<IdmContractGuaranteeDto> guaranteeEvent = new ContractGuaranteeEvent(ContractGuaranteeEventType.CREATE, guarantee, ImmutableMap.of(ProvisioningService.SKIP_PROVISIONING, skipProvisioning));
guaranteeService.publish(guaranteeEvent);
});
}
return contract;
}
use of eu.bcvsolutions.idm.core.api.dto.filter.IdmContractPositionFilter in project CzechIdMng by bcvsolutions.
the class ContractSynchronizationExecutor method isPositionsSame.
/**
* Check if current contract's positions are same as in account values
*
* @param dto
* @param newPositions
* @return
*/
private boolean isPositionsSame(IdmIdentityContractDto dto, List<IdmTreeNodeDto> newPositions) {
// Find current positions
IdmContractPositionFilter positionFilter = new IdmContractPositionFilter();
positionFilter.setIdentityContractId(dto.getId());
List<IdmContractPositionDto> currentPositions = contractPositionService.find(positionFilter, null).getContent();
List<UUID> currentPositionsIds = currentPositions.stream().map(position -> {
return position.getWorkPosition();
}).collect(Collectors.toList());
List<UUID> newPositionIds = newPositions.stream().map(position -> {
return position.getId();
}).collect(Collectors.toList());
return CollectionUtils.isEqualCollection(currentPositionsIds, newPositionIds);
}
use of eu.bcvsolutions.idm.core.api.dto.filter.IdmContractPositionFilter in project CzechIdMng by bcvsolutions.
the class TreeNodeDeleteProcessor method checkWithoutForceDelete.
/**
* Check tree node can be deleted without force delete.
*
* @param treeNode deleted tree node
* @throws ResultCodeException if not
*/
private void checkWithoutForceDelete(IdmTreeNodeDto treeNode) {
UUID treeNodeId = treeNode.getId();
//
if (service.findChildrenByParent(treeNodeId, PageRequest.of(0, 1)).getTotalElements() > 0) {
throw new TreeNodeException(CoreResultCode.TREE_NODE_DELETE_FAILED_HAS_CHILDREN, ImmutableMap.of("treeNode", treeNode.getCode()));
}
//
IdmIdentityContractFilter contractFilter = new IdmIdentityContractFilter();
contractFilter.setWorkPosition(treeNodeId);
contractFilter.setRecursionType(RecursionType.NO);
if (identityContractService.count(contractFilter) > 0) {
throw new TreeNodeException(CoreResultCode.TREE_NODE_DELETE_FAILED_HAS_CONTRACTS, ImmutableMap.of("treeNode", treeNode.getCode()));
}
//
IdmContractSliceFilter sliceFilter = new IdmContractSliceFilter();
sliceFilter.setTreeNode(treeNodeId);
if (contractSliceService.find(sliceFilter, null).getTotalElements() > 0) {
throw new TreeNodeException(CoreResultCode.TREE_NODE_DELETE_FAILED_HAS_CONTRACT_SLICES, ImmutableMap.of("treeNode", treeNode.getCode()));
}
//
IdmContractPositionFilter positionFilter = new IdmContractPositionFilter();
positionFilter.setWorkPosition(treeNodeId);
if (contractPositionService.find(positionFilter, PageRequest.of(0, 1)).getTotalElements() > 0) {
throw new TreeNodeException(CoreResultCode.TREE_NODE_DELETE_FAILED_HAS_CONTRACT_POSITIONS, ImmutableMap.of("treeNode", treeNode.getCode()));
}
//
// check related automatic roles
IdmRoleTreeNodeFilter filter = new IdmRoleTreeNodeFilter();
filter.setTreeNodeId(treeNodeId);
if (roleTreeNodeService.find(filter, null).getTotalElements() > 0) {
throw new TreeNodeException(CoreResultCode.TREE_NODE_DELETE_FAILED_HAS_ROLE, ImmutableMap.of("treeNode", treeNode.getCode()));
}
}
Aggregations