use of eu.bcvsolutions.idm.acc.domain.SynchronizationContext in project CzechIdMng by bcvsolutions.
the class AbstractSynchronizationExecutor method fillEntity.
/**
* Fill entity with attributes from IC module (by mapped attributes).
*
* @param mappedAttributes
* @param uid
* @param icAttributes
* @param dto
* @param create (is create or update entity situation)
* @param context
* @return
*/
protected DTO fillEntity(List<SysSystemAttributeMappingDto> mappedAttributes, String uid, List<IcAttribute> icAttributes, DTO dto, boolean create, SynchronizationContext context) {
mappedAttributes.stream().filter(attribute -> {
// Skip disabled attributes
// Skip extended attributes (we need update/ create entity first)
// Skip confidential attributes (we need update/ create entity
// first)
boolean fastResult = !attribute.isDisabledAttribute() && attribute.isEntityAttribute() && !attribute.isConfidentialAttribute();
if (!fastResult) {
return false;
}
// Can be value set by attribute strategy?
return this.canSetValue(uid, attribute, dto, create);
}).forEach(attribute -> {
String attributeProperty = attribute.getIdmPropertyName();
// Set transformed value from target system to entity
Object transformedValue = getValueByMappedAttribute(attribute, icAttributes, context);
setEntityValue(uid, dto, context, attribute, attributeProperty, transformedValue);
});
return dto;
}
use of eu.bcvsolutions.idm.acc.domain.SynchronizationContext in project CzechIdMng by bcvsolutions.
the class AbstractSynchronizationExecutor method process.
@Override
public AbstractSysSyncConfigDto process(UUID synchronizationConfigId) {
// Clear cache
idmCacheManager.evictCache(CACHE_NAME);
SysSyncLogDto log = new SysSyncLogDto();
// Create basic synchronization log
log.setSynchronizationConfig(synchronizationConfigId);
log.setStarted(ZonedDateTime.now());
try {
// 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
String lastToken = config.isReconciliation() ? null : config.getToken();
IcSyncToken lastIcToken = Strings.isNullOrEmpty(lastToken) ? null : new IcSyncTokenImpl(lastToken);
log.setToken(lastToken != null ? lastToken : null);
log.setRunning(true);
log = syncStarted(log, context);
// List of all accounts keys (used in reconciliation)
Set<String> systemAccountsList = new HashSet<>();
longRunningTaskExecutor.setCounter(0L);
log = synchronizationLogService.save(log);
List<SysSyncActionLogDto> actionsLog = new ArrayList<>();
// add logs to context
context.addLog(log).addActionLogs(actionsLog);
// Is differential sync enabled?
if (config.isDifferentialSync()) {
log.addToLog("Synchronization is running as differential (entities will be updated only if least one attribute was changed).");
}
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(systemService.getConnectorInstance(system), 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(systemService.getConnectorInstance(system), 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);
}
return synchronizationConfigService.save(config);
} catch (Exception e) {
String message = "Error during synchronization";
log.addToLog(message);
log.setContainsError(true);
log.addToLog(Throwables.getStackTraceAsString(e));
throw e;
} finally {
syncEnd(log, syncContext);
log.setRunning(false);
log.setEnded(ZonedDateTime.now());
synchronizationLogService.save(log);
//
longRunningTaskExecutor.setCount(longRunningTaskExecutor.getCounter());
longRunningTaskExecutor.updateState();
// Clear cache
idmCacheManager.evictCache(CACHE_NAME);
}
}
use of eu.bcvsolutions.idm.acc.domain.SynchronizationContext in project CzechIdMng by bcvsolutions.
the class AbstractSynchronizationExecutor method updateConfidentialAttributes.
/**
* @deprecated since 10.1.0
*
* Update confidential attribute for given entity. Entity must be persisted
* first.
*
* @param mappedAttributes
* @param uid
* @param icAttributes
* @param dto
* @param create (is create or update entity situation)
* @param context
* @return
*/
@Deprecated
protected DTO updateConfidentialAttributes(List<SysSystemAttributeMappingDto> mappedAttributes, String uid, List<IcAttribute> icAttributes, DTO dto, boolean create, SynchronizationContext context) {
mappedAttributes.stream().filter(attribute -> {
// Skip disabled attributes
// Only for confidential attribute
boolean fastResult = !attribute.isDisabledAttribute() && attribute.isConfidentialAttribute();
if (!fastResult) {
return false;
}
// Can be value set by attribute strategy?
return this.canSetValue(uid, attribute, dto, create);
}).forEach(attribute -> {
String attributeProperty = attribute.getIdmPropertyName();
Object transformedValue = getValueByMappedAttribute(attribute, icAttributes, context);
// secured storage
if (!(transformedValue == null || transformedValue instanceof GuardedString)) {
throw new ProvisioningException(AccResultCode.CONFIDENTIAL_VALUE_IS_NOT_GUARDED_STRING, ImmutableMap.of("property", attributeProperty, "class", transformedValue.getClass().getName()));
}
confidentialStorage.saveGuardedString(dto.getId(), dto.getClass(), attributeProperty, (GuardedString) transformedValue);
});
return dto;
}
use of eu.bcvsolutions.idm.acc.domain.SynchronizationContext in project CzechIdMng by bcvsolutions.
the class AbstractSynchronizationExecutor method startReconciliation.
/**
* Start reconciliation. Is call after synchronization. Main purpose is find and
* resolve missing accounts
*
* @param entityType
* @param allAccountsSet
* @param config
* @param system
* @param log
* @param actionsLog
*/
protected void startReconciliation(SystemEntityType entityType, Set<String> allAccountsSet, AbstractSysSyncConfigDto config, SysSystemDto system, SysSyncLogDto log, List<SysSyncActionLogDto> actionsLog) {
if (!log.isRunning()) {
return;
}
AccAccountFilter accountFilter = new AccAccountFilter();
accountFilter.setSystemId(system.getId());
List<AccAccountDto> accounts = accountService.find(accountFilter, null).getContent();
for (AccAccountDto account : accounts) {
if (!log.isRunning()) {
return;
}
String uid = account.getRealUid();
if (!allAccountsSet.contains(uid)) {
SysSyncItemLogDto itemLog = new SysSyncItemLogDto();
try {
// Default setting for log item
itemLog.setIdentification(uid);
itemLog.setDisplayName(uid);
itemLog.setType(entityType.getEntityType().getSimpleName());
// Do reconciliation for one item (produces event)
// Start in new Transaction
SynchronizationContext builder = new SynchronizationContext();
builder.addUid(uid).addType(IcSyncDeltaTypeEnum.DELETE).addConfig(config).addSystem(system).addEntityType(entityType).addAccount(account).addLog(log).addLogItem(itemLog).addActionLogs(actionsLog);
CoreEvent<SysSyncItemLogDto> event = new CoreEvent<>(SynchronizationEventType.START_ITEM, itemLog);
event.getProperties().put(SynchronizationService.WRAPPER_SYNC_ITEM, builder);
EventResult<SysSyncItemLogDto> lastResult = entityEventManager.process(event).getLastResult();
boolean result = false;
if (lastResult != null && lastResult.getEvent().getProperties().containsKey(SynchronizationService.RESULT_SYNC_ITEM)) {
result = (boolean) lastResult.getEvent().getProperties().get(SynchronizationService.RESULT_SYNC_ITEM);
}
// Update (increased counter) and check state of sync (maybe was cancelled from
// sync or LRT)
updateAndCheckState(result, log);
} catch (Exception ex) {
String message = MessageFormat.format("Reconciliation - error for uid [{0}]", uid);
log.addToLog(message);
log.addToLog(Throwables.getStackTraceAsString(ex));
LOG.error(message, ex);
} finally {
config = synchronizationConfigService.save(config);
boolean existingItemLog = existItemLogInActions(actionsLog, itemLog);
actionsLog = saveActionLogs(actionsLog, log.getId());
//
if (!existingItemLog) {
addToItemLog(itemLog, MessageFormat.format("Missing action log for UID [{0}]!", uid));
initSyncActionLog(SynchronizationActionType.UNKNOWN, OperationResultType.ERROR, itemLog, log, actionsLog);
syncItemLogService.save(itemLog);
}
}
}
}
}
use of eu.bcvsolutions.idm.acc.domain.SynchronizationContext in project CzechIdMng by bcvsolutions.
the class AbstractSynchronizationExecutor method validate.
/**
* Validate synchronization on: Exist, enable, running, has mapping, has
* connector key, has connector configuration
*
* @param synchronizationConfigId
* @return
*/
protected SynchronizationContext validate(UUID synchronizationConfigId) {
SynchronizationContext context = new SynchronizationContext();
// Set context as main context for whole sync.
syncContext = context;
AbstractSysSyncConfigDto config = synchronizationConfigService.get(synchronizationConfigId);
//
if (config == null) {
throw new ProvisioningException(AccResultCode.SYNCHRONIZATION_NOT_FOUND, ImmutableMap.of("id", synchronizationConfigId));
}
// Synchronization must be enabled
if (!config.isEnabled()) {
throw new ProvisioningException(AccResultCode.SYNCHRONIZATION_IS_NOT_ENABLED, ImmutableMap.of("name", config.getName()));
}
// Synchronization can not be running twice
SysSyncLogFilter logFilter = new SysSyncLogFilter();
logFilter.setSynchronizationConfigId(config.getId());
logFilter.setRunning(Boolean.TRUE);
if (!synchronizationLogService.find(logFilter, null).getContent().isEmpty()) {
throw new ProvisioningException(AccResultCode.SYNCHRONIZATION_IS_RUNNING, ImmutableMap.of("name", config.getName()));
}
SysSystemMappingDto mapping = systemMappingService.get(config.getSystemMapping());
Assert.notNull(mapping, "Mapping is required.");
SysSchemaObjectClassDto schemaObjectClassDto = schemaObjectClassService.get(mapping.getObjectClass());
SysSystemDto system = DtoUtils.getEmbedded(schemaObjectClassDto, SysSchemaObjectClass_.system);
Assert.notNull(system, "System is required.");
// System must be enabled
if (system.isDisabled()) {
throw new ProvisioningException(AccResultCode.SYNCHRONIZATION_SYSTEM_IS_NOT_ENABLED, ImmutableMap.of("name", config.getName(), "system", system.getName()));
}
SystemEntityType entityType = mapping.getEntityType();
SysSystemAttributeMappingFilter attributeHandlingFilter = new SysSystemAttributeMappingFilter();
attributeHandlingFilter.setSystemMappingId(mapping.getId());
List<SysSystemAttributeMappingDto> mappedAttributes = systemAttributeMappingService.find(attributeHandlingFilter, null).getContent();
// Find connector identification persisted in system
IcConnectorKey connectorKey = system.getConnectorKey();
if (connectorKey == null) {
throw new ProvisioningException(AccResultCode.CONNECTOR_KEY_FOR_SYSTEM_NOT_FOUND, ImmutableMap.of("system", system.getName()));
}
// Find connector configuration persisted in system
IcConnectorConfiguration connectorConfig = systemService.getConnectorConfiguration(system);
if (connectorConfig == null) {
throw new ProvisioningException(AccResultCode.CONNECTOR_CONFIGURATION_FOR_SYSTEM_NOT_FOUND, ImmutableMap.of("system", system.getName()));
}
context.addConfig(config).addSystem(system).addEntityType(entityType).addMappedAttributes(mappedAttributes).addConnectorConfig(connectorConfig);
return context;
}
Aggregations