use of eu.bcvsolutions.idm.acc.domain.AttributeMapping in project CzechIdMng by bcvsolutions.
the class DefaultSysProvisioningServiceTest method compileAttributesDefaultTest.
@Test
@Transactional
public void compileAttributesDefaultTest() {
List<AttributeMapping> defaultAttributes = new ArrayList<>();
List<SysRoleSystemAttributeDto> overloadingAttributes = new ArrayList<>();
AttributeMapping defOne = new SysRoleSystemAttributeDto();
defOne.setEntityAttribute(true);
defOne.setStrategyType(AttributeMappingStrategyType.SET);
defOne.setIdmPropertyName("one");
defOne.setName("defOne");
defOne.setDisabledAttribute(true);
defaultAttributes.add(defOne);
AttributeMapping defTwo = new SysRoleSystemAttributeDto();
defTwo.setEntityAttribute(true);
defTwo.setStrategyType(AttributeMappingStrategyType.SET);
defTwo.setIdmPropertyName("two");
defTwo.setName("defTwo");
defaultAttributes.add(defTwo);
List<AttributeMapping> compilledAttributes = provisioningService.compileAttributes(defaultAttributes, overloadingAttributes, SystemEntityType.IDENTITY);
Assert.assertEquals(1, compilledAttributes.size());
Assert.assertEquals("defTwo", compilledAttributes.get(0).getName());
}
use of eu.bcvsolutions.idm.acc.domain.AttributeMapping in project CzechIdMng by bcvsolutions.
the class AbstractProvisioningExecutor method prepareMappedAttributesValues.
/**
* Prepare all mapped attribute values (= account)
*
* @param dto
* @param operationType
* @param systemEntity
* @param attributes
* @return
*/
protected Map<ProvisioningAttributeDto, Object> prepareMappedAttributesValues(DTO dto, ProvisioningOperationType operationType, SysSystemEntityDto systemEntity, List<? extends AttributeMapping> attributes) {
AccAccountDto account = getAccountSystemEntity(systemEntity.getId());
String uid = systemEntity.getUid();
SysSystemDto system = DtoUtils.getEmbedded(systemEntity, SysSystemEntity_.system, SysSystemDto.class);
Map<ProvisioningAttributeDto, Object> accountAttributes = new HashMap<>();
// delete - account attributes is not needed
if (ProvisioningOperationType.DELETE == operationType) {
return accountAttributes;
}
// First we will resolve attribute without MERGE strategy
attributes.stream().filter(attribute -> {
return !attribute.isDisabledAttribute() && AttributeMappingStrategyType.AUTHORITATIVE_MERGE != attribute.getStrategyType() && AttributeMappingStrategyType.MERGE != attribute.getStrategyType();
}).forEach(attribute -> {
SysSchemaAttributeDto schemaAttributeDto = getSchemaAttribute(attribute);
if (attribute.isUid()) {
// TODO: now we set UID from SystemEntity, may be UID from
// AccAccount will be more correct
Object uidValue = getAttributeValue(uid, dto, attribute);
if (uidValue == null) {
throw new ProvisioningException(AccResultCode.PROVISIONING_GENERATED_UID_IS_NULL, ImmutableMap.of("system", system.getName()));
}
if (!(uidValue instanceof String)) {
throw new ProvisioningException(AccResultCode.PROVISIONING_ATTRIBUTE_UID_IS_NOT_STRING, ImmutableMap.of("uid", uidValue, "system", system.getName()));
}
updateAccountUid(account, uid, (String) uidValue);
accountAttributes.put(ProvisioningAttributeDto.createProvisioningAttributeKey(attribute, schemaAttributeDto.getName()), uidValue);
} else {
accountAttributes.put(ProvisioningAttributeDto.createProvisioningAttributeKey(attribute, schemaAttributeDto.getName()), getAttributeValue(uid, dto, attribute));
}
});
// Second we will resolve MERGE attributes
List<? extends AttributeMapping> attributesMerge = attributes.stream().filter(attribute -> {
return !attribute.isDisabledAttribute() && (AttributeMappingStrategyType.AUTHORITATIVE_MERGE == attribute.getStrategyType() || AttributeMappingStrategyType.MERGE == attribute.getStrategyType());
}).collect(Collectors.toList());
for (AttributeMapping attributeParent : attributesMerge) {
SysSchemaAttributeDto schemaAttributeParent = getSchemaAttribute(attributeParent);
ProvisioningAttributeDto attributeParentKey = ProvisioningAttributeDto.createProvisioningAttributeKey(attributeParent, schemaAttributeParent.getName());
if (!schemaAttributeParent.isMultivalued()) {
throw new ProvisioningException(AccResultCode.PROVISIONING_MERGE_ATTRIBUTE_IS_NOT_MULTIVALUE, ImmutableMap.of("object", uid, "attribute", schemaAttributeParent.getName(), "system", system.getName()));
}
// we use SET collection because we want collection of merged values without duplicates
Set<Object> mergedValues = new LinkedHashSet<>();
attributes.stream().filter(attribute -> {
SysSchemaAttributeDto schemaAttribute = getSchemaAttribute(attribute);
return !accountAttributes.containsKey(attributeParentKey) && schemaAttributeParent.equals(schemaAttribute) && attributeParent.getStrategyType() == attribute.getStrategyType();
}).forEach(attribute -> {
Object value = getAttributeValue(uid, dto, attribute);
// provisioning in IC)
if (value != null) {
// main list!
if (value instanceof Collection) {
Collection<?> collectionNotNull = ((Collection<?>) value).stream().filter(item -> {
return item != null;
}).collect(Collectors.toList());
mergedValues.addAll(collectionNotNull);
} else {
mergedValues.add(value);
}
}
});
if (!accountAttributes.containsKey(attributeParentKey)) {
// we must put merged values as array list
accountAttributes.put(attributeParentKey, new ArrayList<>(mergedValues));
}
}
return accountAttributes;
}
use of eu.bcvsolutions.idm.acc.domain.AttributeMapping in project CzechIdMng by bcvsolutions.
the class AbstractSynchronizationExecutor method handleIcObject.
/**
* Handle IC connector object
*
* @param tokenAttribute
* @param itemContext
* @return
*/
protected boolean handleIcObject(SynchronizationContext itemContext) {
Assert.notNull(itemContext);
String uid = itemContext.getUid();
IcConnectorObject icObject = itemContext.getIcObject();
AbstractSysSyncConfigDto config = itemContext.getConfig();
SysSyncLogDto log = itemContext.getLog();
List<SysSyncActionLogDto> actionLogs = itemContext.getActionLogs();
AttributeMapping tokenAttribute = itemContext.getTokenAttribute();
SysSyncItemLogDto itemLog = new SysSyncItemLogDto();
// Synchronization by custom filter not supported DELETE
// event
IcSyncDeltaTypeEnum type = IcSyncDeltaTypeEnum.CREATE_OR_UPDATE;
itemContext.addLogItem(itemLog).addType(type);
// Find token by token attribute
// For Reconciliation can be token attribute null
Object tokenObj = null;
if (tokenAttribute != null) {
tokenObj = getValueByMappedAttribute(tokenAttribute, icObject.getAttributes(), itemContext);
}
// Token is saved in Sync as String, therefore we transform token (from
// IcObject) to String too.
String token = tokenObj != null ? tokenObj.toString() : null;
if (token != null && config.getToken() != null && token.compareTo(config.getToken()) <= -1) {
token = config.getToken();
}
// Save token
log.setToken(token);
config.setToken(token);
boolean result = startItemSynchronization(itemContext);
// We reload log (maybe was synchronization canceled)
longRunningTaskExecutor.increaseCounter();
log.setRunning(synchronizationLogService.get(log.getId()).isRunning());
if (!log.isRunning()) {
result = false;
}
if (!result) {
log.setRunning(false);
log.addToLog(MessageFormat.format("Synchronization canceled during resolve UID [{0}]", uid));
addToItemLog(itemLog, "Canceled!");
initSyncActionLog(SynchronizationActionType.IGNORE, OperationResultType.WARNING, itemLog, log, actionLogs);
}
return result;
}
use of eu.bcvsolutions.idm.acc.domain.AttributeMapping in project CzechIdMng by bcvsolutions.
the class AbstractSynchronizationExecutor method resolveSynchronizationFilter.
/**
* Compile filter for search from filter attribute and filter script
*
* @param config
* @return
*/
protected IcFilter resolveSynchronizationFilter(AbstractSysSyncConfigDto config) {
// If is reconciliation, then is filter null
if (config.isReconciliation()) {
return null;
}
IcFilter filter = null;
AttributeMapping filterAttributeMapping = null;
if (config.getFilterAttribute() != null) {
filterAttributeMapping = systemAttributeMappingService.get(config.getFilterAttribute());
}
String configToken = config.getToken();
String filterScript = config.getCustomFilterScript();
if (filterAttributeMapping == null && configToken == null && StringUtils.isEmpty(filterScript)) {
return null;
}
if (filterAttributeMapping != null) {
Object transformedValue = systemAttributeMappingService.transformValueToResource(null, configToken, filterAttributeMapping, config);
if (transformedValue != null) {
SysSchemaAttributeDto schemaAttributeDto = schemaAttributeService.get(filterAttributeMapping.getSchemaAttribute());
IcAttributeImpl filterAttribute = new IcAttributeImpl(schemaAttributeDto.getName(), transformedValue);
switch(config.getFilterOperation()) {
case GREATER_THAN:
filter = IcFilterBuilder.greaterThan(filterAttribute);
break;
case LESS_THAN:
filter = IcFilterBuilder.lessThan(filterAttribute);
break;
case EQUAL_TO:
filter = IcFilterBuilder.equalTo(filterAttribute);
break;
case CONTAINS:
filter = IcFilterBuilder.contains(filterAttribute);
break;
case ENDS_WITH:
filter = IcFilterBuilder.endsWith(filterAttribute);
break;
case STARTS_WITH:
filter = IcFilterBuilder.startsWith(filterAttribute);
break;
}
}
}
if (StringUtils.hasLength(filterScript)) {
Map<String, Object> variables = new HashMap<>();
variables.put("filter", filter);
variables.put("token", configToken);
List<Class<?>> allowTypes = new ArrayList<>();
// Allow all IC filter operator
for (IcFilterOperationType operation : IcFilterOperationType.values()) {
allowTypes.add(operation.getImplementation());
}
allowTypes.add(IcAndFilter.class);
allowTypes.add(IcOrFilter.class);
allowTypes.add(IcFilterBuilder.class);
allowTypes.add(IcAttributeImpl.class);
allowTypes.add(IcAttribute.class);
Object filterObj = groovyScriptService.evaluate(filterScript, variables, allowTypes);
if (filterObj != null && !(filterObj instanceof IcFilter)) {
throw new ProvisioningException(AccResultCode.SYNCHRONIZATION_FILTER_VALUE_WRONG_TYPE, ImmutableMap.of("type", filterObj.getClass().getName()));
}
filter = (IcFilter) filterObj;
}
return filter;
}
use of eu.bcvsolutions.idm.acc.domain.AttributeMapping in project CzechIdMng by bcvsolutions.
the class AbstractSynchronizationExecutor method process.
@Override
public AbstractSysSyncConfigDto process(UUID synchronizationConfigId) {
// Clear cache
this.clearCache();
// Validate and create basic context
SynchronizationContext context = this.validate(synchronizationConfigId);
AbstractSysSyncConfigDto config = context.getConfig();
SystemEntityType entityType = context.getEntityType();
SysSystemDto system = context.getSystem();
IcConnectorConfiguration connectorConfig = context.getConnectorConfig();
SysSystemMappingDto systemMapping = systemMappingService.get(config.getSystemMapping());
SysSchemaObjectClassDto schemaObjectClassDto = schemaObjectClassService.get(systemMapping.getObjectClass());
IcObjectClass objectClass = new IcObjectClassImpl(schemaObjectClassDto.getObjectClassName());
// Load last token
Object lastToken = config.isReconciliation() ? null : config.getToken();
IcSyncToken lastIcToken = lastToken != null ? new IcSyncTokenImpl(lastToken) : null;
// Create basic synchronization log
SysSyncLogDto log = new SysSyncLogDto();
log.setSynchronizationConfig(config.getId());
log.setStarted(LocalDateTime.now());
log.setRunning(true);
log.setToken(lastToken != null ? lastToken.toString() : null);
log.addToLog(MessageFormat.format("Synchronization was started in {0}.", log.getStarted()));
// List of all accounts keys (used in reconciliation)
Set<String> systemAccountsList = new HashSet<>();
// TODO: Export is not fully implemented (FE, configuration and Groovy
// part missing)
boolean export = false;
longRunningTaskExecutor.setCounter(0L);
try {
log = synchronizationLogService.save(log);
List<SysSyncActionLogDto> actionsLog = new ArrayList<>();
// add logs to context
context.addLog(log).addActionLogs(actionsLog);
if (export) {
// Start exporting entities to resource
log.addToLog("Exporting entities to resource started...");
this.startExport(entityType, config, context.getMappedAttributes(), log, actionsLog);
} else if (config.isCustomFilter() || config.isReconciliation()) {
// Custom filter Sync
log.addToLog("Synchronization will use custom filter (not synchronization implemented in connector).");
AttributeMapping tokenAttribute = null;
if (config.getTokenAttribute() != null) {
tokenAttribute = systemAttributeMappingService.get(config.getTokenAttribute());
}
if (tokenAttribute == null && !config.isReconciliation()) {
throw new ProvisioningException(AccResultCode.SYNCHRONIZATION_TOKEN_ATTRIBUTE_NOT_FOUND);
}
context.addTokenAttribute(tokenAttribute);
// Resolve filter for custom search
IcFilter filter = resolveSynchronizationFilter(config);
log.addToLog(MessageFormat.format("Start search with filter {0}.", filter != null ? filter : "NONE"));
connectorFacade.search(system.getConnectorInstance(), connectorConfig, objectClass, filter, new DefaultResultHandler(context, systemAccountsList));
} else {
// Inner Sync
log.addToLog("Synchronization will use inner connector synchronization implementation.");
DefalutSyncResultHandler syncResultsHandler = new DefalutSyncResultHandler(context, systemAccountsList);
connectorFacade.synchronization(system.getConnectorInstance(), connectorConfig, objectClass, lastIcToken, syncResultsHandler);
}
// We do reconciliation (find missing account)
if (config.isReconciliation() && log.isRunning()) {
startReconciliation(entityType, systemAccountsList, config, system, log, actionsLog);
}
// Sync is correctly ends if wasn't cancelled
if (log.isRunning()) {
log = syncCorrectlyEnded(log, context);
}
config = synchronizationConfigService.save(config);
} catch (Exception e) {
String message = "Error during synchronization";
log.addToLog(message);
log.setContainsError(true);
log.addToLog(Throwables.getStackTraceAsString(e));
LOG.error(message, e);
} finally {
log.setRunning(false);
log.setEnded(LocalDateTime.now());
log = synchronizationLogService.save(log);
//
longRunningTaskExecutor.setCount(longRunningTaskExecutor.getCounter());
longRunningTaskExecutor.updateState();
// Clear cache
this.clearCache();
}
return config;
}
Aggregations