use of eu.bcvsolutions.idm.core.api.dto.IdmImportLogDto in project CzechIdMng by bcvsolutions.
the class DefaultImportManager method executeImportForType.
/**
* Ensures add new and update existed DTOs by given batch.
*
* @param descriptor
* @param context
*/
private void executeImportForType(ExportDescriptorDto descriptor, ImportContext context) {
Class<? extends BaseDto> dtoClass = descriptor.getDtoClass();
Path dtoTypePath = Paths.get(context.getTempDirectory().toString(), dtoClass.getSimpleName());
try {
List<BaseDto> dtos;
try (Stream<Path> paths = Files.walk(dtoTypePath)) {
dtos = //
paths.filter(//
Files::isRegularFile).map(path -> {
BaseDto dto = convertFileToDto(path.toFile(), dtoClass, context);
Assert.notNull(dto, "DTO cannot be null after conversion from the batch!");
return dto;
}).collect(Collectors.toList());
}
if (dtos.isEmpty()) {
return;
}
// Sorts all DTOs for this type (maybe it is tree).
dtos = sortsDTOs(dtoClass, dtos);
int i = 0;
for (BaseDto dto : dtos) {
// Flush Hibernate in batch - performance improving
if (i % 20 == 0 && i > 0) {
// Call hard hibernate session flush and clear
if (getHibernateSession().isOpen()) {
getHibernateSession().flush();
getHibernateSession().clear();
}
}
i++;
// Increase counter and update state of import LRT.
context.getImportTaskExecutor().increaseCounter();
context.getImportTaskExecutor().updateState();
BaseDto parentDto = getParentDtoFromBatch(dto, context);
if (parentDto == null) {
parentDto = dto;
}
BaseDto originalDto = dto;
try {
dto = makeAdvancedPairing(dto, context, dtoClass);
if (dto == null) {
// If DTO after advanced pairing is null, then was not found and is optional ->
// skip.
IdmImportLogDto dtoLog = new IdmImportLogDto(context.getBatch(), originalDto, RequestOperationType.ADD, (UUID) parentDto.getId());
ResultModel resultModel = new DefaultResultModel(CoreResultCode.IMPORT_DTO_SKIPPED, ImmutableMap.of("dto", originalDto.toString()));
dtoLog.setResult(new OperationResultDto.Builder(OperationState.CANCELED).setModel(resultModel).build());
importLogService.saveDistinct(dtoLog);
continue;
}
} catch (ResultCodeException ex) {
if (context.isDryRun() && ex.getError() != null && ex.getError().getError() != null && CoreResultCode.IMPORT_ADVANCED_PARING_FAILED_NOT_FOUND.name().equals(ex.getError().getError().getStatusEnum())) {
// Not found DTO we will mark as skipped in dry run mode.
IdmImportLogDto dtoLog = new IdmImportLogDto(context.getBatch(), originalDto, RequestOperationType.ADD, (UUID) parentDto.getId());
dtoLog.setResult(new OperationResultDto.Builder(OperationState.EXCEPTION).setException(ex).build());
importLogService.saveDistinct(dtoLog);
continue;
} else if (ex.getError() != null && ex.getError().getError() != null && CoreResultCode.IMPORT_ADVANCED_PARING_NOT_FOUND_OPTIONAL.name().equals(ex.getError().getError().getStatusEnum())) {
// Not found DTO, but optional, we will mark as skipped.
IdmImportLogDto dtoLog = new IdmImportLogDto(context.getBatch(), originalDto, RequestOperationType.ADD, (UUID) parentDto.getId());
dtoLog.setResult(new OperationResultDto.Builder(OperationState.CANCELED).setException(ex).build());
importLogService.saveDistinct(dtoLog);
continue;
}
throw ex;
}
Class<? extends BaseDto> serviceDtoClass = dtoClass;
if (dto instanceof IdmFormInstanceDto) {
// Form instance is very special here (doesn't have entity in DB).
IdmFormInstanceDto formInstance = (IdmFormInstanceDto) dto;
IdmFormDefinitionDto definition = formInstance.getFormDefinition();
Assert.notNull(definition, "Definition cannot be null for import!");
CoreEvent<IdmFormInstanceDto> event = new CoreEvent<>(CoreEventType.UPDATE, formInstance);
// Check if owner exist (UPDATE/ADD)
@SuppressWarnings("unchecked") Class<? extends BaseDto> ownerType = (Class<? extends BaseDto>) ((IdmFormInstanceDto) dto).getOwnerType();
UUID ownerId = UUID.fromString((String) ((IdmFormInstanceDto) dto).getOwnerId());
BaseDto ownerDto = this.getDtoService(ownerType).get(ownerId);
IdmImportLogDto dtoLog = new IdmImportLogDto(context.getBatch(), dto, ownerDto != null ? RequestOperationType.UPDATE : RequestOperationType.ADD, ownerId);
if (!context.isDryRun()) {
formService.publish(event);
dtoLog.setResult(new OperationResultDto(OperationState.EXECUTED));
} else {
dtoLog.setResult(new OperationResultDto.Builder(OperationState.NOT_EXECUTED).setModel(//
new DefaultResultModel(CoreResultCode.IMPORT_EXECUTED_AS_DRYRUN)).build());
}
importLogService.saveDistinct(dtoLog);
continue;
}
if (dto.getClass().isAnnotationPresent(Inheritable.class)) {
serviceDtoClass = dto.getClass().getAnnotation(Inheritable.class).dtoService();
}
ReadWriteDtoService<BaseDto, ?> dtoService = getDtoService(serviceDtoClass);
BaseDto currentDto = dtoService.get(dto.getId());
if (currentDto != null) {
// DTO with same ID already exists -> update.
IdmImportLogDto dtoLog = new IdmImportLogDto(context.getBatch(), dto, RequestOperationType.UPDATE, (UUID) parentDto.getId());
// Resolve excluded fields
dto = this.excludeFields(dto, currentDto, context);
if (!context.isDryRun()) {
dtoService.save(dto);
dtoLog.setResult(new OperationResultDto(OperationState.EXECUTED));
} else {
dtoLog.setResult(new OperationResultDto.Builder(OperationState.NOT_EXECUTED).setModel(//
new DefaultResultModel(CoreResultCode.IMPORT_EXECUTED_AS_DRYRUN)).build());
}
importLogService.saveDistinct(dtoLog);
continue;
}
if (dto instanceof Codeable) {
// We try to find exists DTO by code.
currentDto = lookupService.lookupDto(serviceDtoClass, ((Codeable) dto).getCode());
}
// Find target DTO by example source DTO (typically by more then one filter field).
currentDto = findByExample(dto, null, context);
if (dto instanceof IdmFormDefinitionDto) {
IdmFormDefinitionDto definition = (IdmFormDefinitionDto) dto;
// We try to find exists definition by code and type (IdmFormDefinitionDto is
// not Codeable).
currentDto = formService.getDefinition(definition.getType(), definition.getCode());
}
if (dto instanceof IdmFormAttributeDto) {
IdmFormAttributeDto attribute = (IdmFormAttributeDto) dto;
IdmFormDefinitionDto definition = formService.getDefinition(attribute.getFormDefinition());
if (definition != null) {
// We try to find exists attribute definition by code and form definition.
currentDto = formService.getAttribute(definition, attribute.getCode());
} else {
currentDto = null;
}
}
if (currentDto != null) {
// We found current DTO in IdM.
// Save old and new ID for next DTOs.
context.getReplacedIDs().put((UUID) dto.getId(), (UUID) currentDto.getId());
// We have to change the ID in import DTO.
dto.setId(currentDto.getId());
// Update current DTO by batch DTO.
IdmImportLogDto dtoLog = new IdmImportLogDto(context.getBatch(), dto, RequestOperationType.UPDATE, (UUID) parentDto.getId());
if (!context.isDryRun()) {
// Resolve excluded fields
dto = this.excludeFields(dto, currentDto, context);
// Save a DTO.
dtoService.save(dto);
dtoLog.setResult(new OperationResultDto(OperationState.EXECUTED));
} else {
dtoLog.setResult(new OperationResultDto.Builder(OperationState.NOT_EXECUTED).setModel(//
new DefaultResultModel(CoreResultCode.IMPORT_EXECUTED_AS_DRYRUN)).build());
}
importLogService.saveDistinct(dtoLog);
} else {
IdmImportLogDto dtoLog = new IdmImportLogDto(context.getBatch(), dto, RequestOperationType.ADD, (UUID) parentDto.getId());
// No current DTO was found -> create.
if (!context.isDryRun()) {
// Resolve excluded fields
dto = this.excludeFields(dto, null, context);
// Save new DTO.
dtoService.save(dto);
dtoLog.setResult(new OperationResultDto(OperationState.EXECUTED));
} else {
dtoLog.setResult(new OperationResultDto.Builder(OperationState.NOT_EXECUTED).setModel(//
new DefaultResultModel(CoreResultCode.IMPORT_EXECUTED_AS_DRYRUN)).build());
}
importLogService.saveDistinct(dtoLog);
}
}
} catch (IOException | IllegalArgumentException e) {
throw new ResultCodeException(CoreResultCode.EXPORT_IMPORT_IO_FAILED, e);
}
}
use of eu.bcvsolutions.idm.core.api.dto.IdmImportLogDto in project CzechIdMng by bcvsolutions.
the class DefaultImportManager method removeRedundant.
/**
* Ensures delete redundant entities in target IdM. Deletes DTOs are within
* golden DTO type (super parent = typically system, role, ...).
*
* @param descriptor
* @param context
*/
private void removeRedundant(ExportDescriptorDto descriptor, ImportContext context) {
Class<? extends BaseDto> dtoClass = descriptor.getDtoClass();
// Does this DTO support the authoritative mode?
boolean supportsAuthoritativeMode = descriptor.isSupportsAuthoritativeMode();
if (!supportsAuthoritativeMode) {
return;
}
String superParentFilterProperty = descriptor.getSuperParentFilterProperty();
Assert.notNull(superParentFilterProperty, "For authoritative mode must be superParentFilterProperty defined!");
// Find super parent (gold) DTO (typically it is DTO for system, role ...)
Class<? extends AbstractDto> superParentDtoClass = getSuperParentDtoClass(descriptor, context);
Assert.notNull(superParentDtoClass, "Supper parent cannot be null here!");
Path superParentDtoTypePath = Paths.get(context.getTempDirectory().toString(), superParentDtoClass.getSimpleName());
try {
// Find all super parent IDs for this DTO type in batch.
Set<UUID> superParentIdsInBatch;
try (Stream<Path> paths = Files.walk(superParentDtoTypePath)) {
superParentIdsInBatch = //
paths.filter(//
Files::isRegularFile).map(path -> {
BaseDto dto = convertFileToDto(path.toFile(), superParentDtoClass, context);
return (UUID) dto.getId();
}).collect(Collectors.toSet());
}
Set<Class<? extends BaseDto>> inheritedClasses = getInheritedClasses(dtoClass, context.getManifest());
// Find all IDs for all children classes
Set<Serializable> childrenIdsInBatch = Sets.newHashSet();
for (Class<? extends BaseDto> inheritedClass : inheritedClasses) {
// Find all IDs for this DTO type in batch.
Path dtoTypePath = Paths.get(context.getTempDirectory().toString(), inheritedClass.getSimpleName());
try (Stream<Path> paths = Files.walk(dtoTypePath)) {
Set<Serializable> childrenIds = //
paths.filter(//
Files::isRegularFile).map(//
path -> convertFileToDto(path.toFile(), inheritedClass, context)).map(dto -> {
// If ID has been replaced, then we need to also replace it.
if (context.getReplacedIDs().containsKey((UUID) dto.getId())) {
return context.getReplacedIDs().get((UUID) dto.getId());
}
return dto.getId();
}).collect(Collectors.toSet());
childrenIdsInBatch.addAll(childrenIds);
}
}
superParentIdsInBatch.forEach(superParentId -> {
try {
Class<? extends BaseDto> serviceDtoClass = dtoClass;
if (dtoClass.isAnnotationPresent(Inheritable.class)) {
serviceDtoClass = dtoClass.getAnnotation(Inheritable.class).dtoService();
}
ReadWriteDtoService<BaseDto, BaseFilter> dtoService = getDtoService(serviceDtoClass);
BaseFilter filterBase = dtoService.getFilterClass().getDeclaredConstructor().newInstance();
// Fill super-parent-property by superParentId (call setter = check if filter is
// implemented).
new PropertyDescriptor(superParentFilterProperty, dtoService.getFilterClass()).getWriteMethod().invoke(filterBase, superParentId);
// Load all IDs in IdM for this parent ID.
List<UUID> childrenIdsInIdM = //
dtoService.find(filterBase, null).getContent().stream().map(//
childDto -> ((AbstractDto) childDto).getId()).collect(Collectors.toList());
// IDs to delete = entities missing in the batch.
Set<UUID> idsToDelete = //
childrenIdsInIdM.stream().filter(//
idmId -> !childrenIdsInBatch.contains(idmId)).collect(Collectors.toSet());
idsToDelete.forEach(id -> {
BaseDto baseDto = dtoService.get(id);
IdmImportLogDto dtoLog = new IdmImportLogDto(context.getBatch(), baseDto, RequestOperationType.REMOVE, superParentId);
if (!context.isDryRun()) {
dtoService.delete(baseDto);
dtoLog.setResult(new OperationResultDto(OperationState.EXECUTED));
} else {
dtoLog.setResult(new OperationResultDto.Builder(OperationState.NOT_EXECUTED).setModel(//
new DefaultResultModel(CoreResultCode.IMPORT_EXECUTED_AS_DRYRUN)).build());
}
importLogService.saveDistinct(dtoLog);
});
} catch (ReflectiveOperationException | IllegalArgumentException | IntrospectionException e) {
throw new ResultCodeException(CoreResultCode.EXPORT_IMPORT_REFLECTION_FAILED, e);
}
});
} catch (IOException e) {
throw new ResultCodeException(CoreResultCode.EXPORT_IMPORT_IO_FAILED, e);
}
}
use of eu.bcvsolutions.idm.core.api.dto.IdmImportLogDto in project CzechIdMng by bcvsolutions.
the class IdmImportLogController method toFilter.
@Override
protected IdmImportLogFilter toFilter(MultiValueMap<String, Object> parameters) {
IdmImportLogFilter filter = new IdmImportLogFilter(parameters);
// If parent property contains ID of IdmImportLog, then we need to change filter to DTO id.
if (filter.getParent() != null) {
IdmImportLogDto logDto = getService().get(filter.getParent());
if (logDto != null) {
filter.setParent(logDto.getDtoId());
filter.setBatchId(logDto.getBatch());
}
}
return filter;
}
use of eu.bcvsolutions.idm.core.api.dto.IdmImportLogDto in project CzechIdMng by bcvsolutions.
the class ImportLogSaveProcessor method process.
@Override
public EventResult<IdmImportLogDto> process(EntityEvent<IdmImportLogDto> event) {
IdmImportLogDto dto = event.getContent();
dto = service.saveInternal(dto);
event.setContent(dto);
return new DefaultEventResult<>(event, this);
}
use of eu.bcvsolutions.idm.core.api.dto.IdmImportLogDto in project CzechIdMng by bcvsolutions.
the class DefaultIdmImportLogService method saveDistinct.
@Override
@Transactional
public IdmImportLogDto saveDistinct(IdmImportLogDto dto, BasePermission... permission) {
if (this.isNew(dto)) {
Assert.notNull(dto.getBatch(), "Batch ID must be filled for distinct save!");
Assert.notNull(dto.getDtoId(), "DTO ID must be filled for distinct save!");
IdmImportLogFilter filter = new IdmImportLogFilter();
filter.setBatchId(dto.getBatch());
filter.setDtoId(dto.getDtoId());
// If exists import-log for same batch and DTO ID, then is used his ID (prevent creation of duplicated logs).
if (this.count(filter) > 0) {
IdmImportLogDto originalLog = this.find(filter, null).getContent().get(0);
dto.setId(originalLog.getId());
}
}
return super.save(dto, permission);
}
Aggregations