use of com.evolveum.midpoint.common.refinery.RefinedResourceSchema in project midpoint by Evolveum.
the class ReconciliationTaskHandler method runInternal.
public TaskRunResult runInternal(Task coordinatorTask) {
ReconciliationTaskResult reconResult = new ReconciliationTaskResult();
boolean finishOperationsOnly = BooleanUtils.isTrue(coordinatorTask.getExtensionPropertyRealValue(SchemaConstants.MODEL_EXTENSION_FINISH_OPERATIONS_ONLY));
OperationResult opResult = new OperationResult(OperationConstants.RECONCILIATION);
opResult.setStatus(OperationResultStatus.IN_PROGRESS);
TaskRunResult runResult = new TaskRunResult();
runResult.setOperationResult(opResult);
String resourceOid = coordinatorTask.getObjectOid();
opResult.addContext("resourceOid", resourceOid);
if (coordinatorTask.getChannel() == null) {
coordinatorTask.setChannel(SchemaConstants.CHANGE_CHANNEL_RECON_URI);
}
if (resourceOid == null) {
throw new IllegalArgumentException("Resource OID is missing in task extension");
}
recordProgress(coordinatorTask, 0, opResult);
// todo consider setting expectedTotal to null here
PrismObject<ResourceType> resource;
ObjectClassComplexTypeDefinition objectclassDef;
try {
resource = provisioningService.getObject(ResourceType.class, resourceOid, null, coordinatorTask, opResult);
RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource, LayerType.MODEL, prismContext);
objectclassDef = Utils.determineObjectClass(refinedSchema, coordinatorTask);
} catch (ObjectNotFoundException ex) {
// This is bad. The resource does not exist. Permanent problem.
processErrorPartial(runResult, "Resource does not exist, OID: " + resourceOid, ex, TaskRunResultStatus.PERMANENT_ERROR, null, coordinatorTask, opResult);
return runResult;
} catch (CommunicationException ex) {
// Error, but not critical. Just try later.
processErrorPartial(runResult, "Communication error", ex, TaskRunResultStatus.TEMPORARY_ERROR, null, coordinatorTask, opResult);
return runResult;
} catch (SchemaException ex) {
// Not sure about this. But most likely it is a misconfigured resource or connector
// It may be worth to retry. Error is fatal, but may not be permanent.
processErrorPartial(runResult, "Error dealing with schema", ex, TaskRunResultStatus.TEMPORARY_ERROR, null, coordinatorTask, opResult);
return runResult;
} catch (RuntimeException ex) {
// Can be anything ... but we can't recover from that.
// It is most likely a programming error. Does not make much sense
// to retry.
processErrorPartial(runResult, "Internal Error", ex, TaskRunResultStatus.PERMANENT_ERROR, null, coordinatorTask, opResult);
return runResult;
} catch (ConfigurationException ex) {
// Not sure about this. But most likely it is a misconfigured resource or connector
// It may be worth to retry. Error is fatal, but may not be permanent.
processErrorPartial(runResult, "Configuration error", ex, TaskRunResultStatus.TEMPORARY_ERROR, null, coordinatorTask, opResult);
return runResult;
} catch (SecurityViolationException ex) {
processErrorPartial(runResult, "Security violation", ex, TaskRunResultStatus.PERMANENT_ERROR, null, coordinatorTask, opResult);
return runResult;
} catch (ExpressionEvaluationException ex) {
processErrorPartial(runResult, "Expression error", ex, TaskRunResultStatus.PERMANENT_ERROR, null, coordinatorTask, opResult);
return runResult;
}
if (objectclassDef == null) {
processErrorPartial(runResult, "Reconciliation without an object class specification is not supported", null, TaskRunResultStatus.PERMANENT_ERROR, null, coordinatorTask, opResult);
return runResult;
}
reconResult.setResource(resource);
reconResult.setObjectclassDefinition(objectclassDef);
LOGGER.info("Start executing reconciliation of resource {}, reconciling object class {}, finish operations only: {}", resource, objectclassDef, finishOperationsOnly);
long reconStartTimestamp = clock.currentTimeMillis();
AuditEventRecord requestRecord = new AuditEventRecord(AuditEventType.RECONCILIATION, AuditEventStage.REQUEST);
requestRecord.setTarget(resource);
auditService.audit(requestRecord, coordinatorTask);
try {
if (!scanForUnfinishedOperations(coordinatorTask, resourceOid, reconResult, opResult)) {
// appends also "last N failures" (TODO refactor)
processInterruption(runResult, resource, coordinatorTask, opResult);
return runResult;
}
} catch (ObjectNotFoundException ex) {
// This is bad. The resource does not exist. Permanent problem.
processErrorPartial(runResult, "Resource does not exist, OID: " + resourceOid, ex, TaskRunResultStatus.PERMANENT_ERROR, resource, coordinatorTask, opResult);
} catch (ObjectAlreadyExistsException ex) {
processErrorPartial(runResult, "Object already exist", ex, TaskRunResultStatus.PERMANENT_ERROR, resource, coordinatorTask, opResult);
} catch (CommunicationException ex) {
// Error, but not critical. Just try later.
// appends also "last N failures" (TODO refactor)
processErrorFinal(runResult, "Communication error", ex, TaskRunResultStatus.TEMPORARY_ERROR, resource, coordinatorTask, opResult);
return runResult;
} catch (SchemaException ex) {
// Not sure about this. But most likely it is a misconfigured resource or connector
// It may be worth to retry. Error is fatal, but may not be permanent.
processErrorPartial(runResult, "Error dealing with schema", ex, TaskRunResultStatus.TEMPORARY_ERROR, resource, coordinatorTask, opResult);
} catch (RuntimeException ex) {
// Can be anything ... but we can't recover from that.
// It is most likely a programming error. Does not make much sense
// to retry.
processErrorFinal(runResult, "Internal Error", ex, TaskRunResultStatus.PERMANENT_ERROR, resource, coordinatorTask, opResult);
return runResult;
} catch (ConfigurationException ex) {
// Not sure about this. But most likely it is a misconfigured resource or connector
// It may be worth to retry. Error is fatal, but may not be permanent.
processErrorFinal(runResult, "Configuration error", ex, TaskRunResultStatus.TEMPORARY_ERROR, resource, coordinatorTask, opResult);
return runResult;
} catch (SecurityViolationException ex) {
processErrorPartial(runResult, "Security violation", ex, TaskRunResultStatus.PERMANENT_ERROR, resource, coordinatorTask, opResult);
}
long beforeResourceReconTimestamp = clock.currentTimeMillis();
long afterResourceReconTimestamp;
long afterShadowReconTimestamp;
try {
if (!finishOperationsOnly && !performResourceReconciliation(resource, objectclassDef, reconResult, coordinatorTask, opResult)) {
processInterruption(runResult, resource, coordinatorTask, opResult);
return runResult;
}
afterResourceReconTimestamp = clock.currentTimeMillis();
if (!finishOperationsOnly && !performShadowReconciliation(resource, objectclassDef, reconStartTimestamp, afterResourceReconTimestamp, reconResult, coordinatorTask, opResult)) {
processInterruption(runResult, resource, coordinatorTask, opResult);
return runResult;
}
afterShadowReconTimestamp = clock.currentTimeMillis();
} catch (ObjectNotFoundException ex) {
// This is bad. The resource does not exist. Permanent problem.
processErrorFinal(runResult, "Resource does not exist, OID: " + resourceOid, ex, TaskRunResultStatus.PERMANENT_ERROR, resource, coordinatorTask, opResult);
return runResult;
} catch (CommunicationException ex) {
// Error, but not critical. Just try later.
processErrorFinal(runResult, "Communication error", ex, TaskRunResultStatus.TEMPORARY_ERROR, resource, coordinatorTask, opResult);
return runResult;
} catch (SchemaException ex) {
// Not sure about this. But most likely it is a misconfigured resource or connector
// It may be worth to retry. Error is fatal, but may not be permanent.
processErrorFinal(runResult, "Error dealing with schema", ex, TaskRunResultStatus.TEMPORARY_ERROR, resource, coordinatorTask, opResult);
return runResult;
} catch (RuntimeException ex) {
// Can be anything ... but we can't recover from that.
// It is most likely a programming error. Does not make much sense
// to retry.
processErrorFinal(runResult, "Internal Error", ex, TaskRunResultStatus.PERMANENT_ERROR, resource, coordinatorTask, opResult);
return runResult;
} catch (ConfigurationException ex) {
// Not sure about this. But most likely it is a misconfigured resource or connector
// It may be worth to retry. Error is fatal, but may not be permanent.
processErrorFinal(runResult, "Configuration error", ex, TaskRunResultStatus.TEMPORARY_ERROR, resource, coordinatorTask, opResult);
return runResult;
} catch (SecurityViolationException ex) {
processErrorFinal(runResult, "Security violation", ex, TaskRunResultStatus.PERMANENT_ERROR, resource, coordinatorTask, opResult);
return runResult;
} catch (ExpressionEvaluationException ex) {
processErrorFinal(runResult, "Expression error", ex, TaskRunResultStatus.PERMANENT_ERROR, resource, coordinatorTask, opResult);
return runResult;
}
opResult.computeStatus();
// This "run" is finished. But the task goes on ...
runResult.setRunResultStatus(TaskRunResultStatus.FINISHED);
runResult.setProgress(coordinatorTask.getProgress());
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Reconciliation.run stopping, result: {}", opResult.getStatus());
// LOGGER.trace("Reconciliation.run stopping, result: {}", opResult.dump());
}
AuditEventRecord executionRecord = new AuditEventRecord(AuditEventType.RECONCILIATION, AuditEventStage.EXECUTION);
executionRecord.setTarget(resource);
executionRecord.setOutcome(OperationResultStatus.SUCCESS);
auditService.audit(executionRecord, coordinatorTask);
long reconEndTimestamp = clock.currentTimeMillis();
long etime = reconEndTimestamp - reconStartTimestamp;
long unOpsTime = beforeResourceReconTimestamp - reconStartTimestamp;
long resourceReconTime = afterResourceReconTimestamp - beforeResourceReconTimestamp;
long shadowReconTime = afterShadowReconTimestamp - afterResourceReconTimestamp;
LOGGER.info("Done executing reconciliation of resource {}, object class {}, Etime: {} ms (un-ops: {}, resource: {}, shadow: {})", new Object[] { resource, objectclassDef, etime, unOpsTime, resourceReconTime, shadowReconTime });
reconResult.setRunResult(runResult);
if (reconciliationTaskResultListener != null) {
reconciliationTaskResultListener.process(reconResult);
}
TaskHandlerUtil.appendLastFailuresInformation(OperationConstants.RECONCILIATION, coordinatorTask, opResult);
return runResult;
}
use of com.evolveum.midpoint.common.refinery.RefinedResourceSchema in project midpoint by Evolveum.
the class ResourceContentTabPanel method initLayout.
private void initLayout(final IModel<PrismObject<ResourceType>> model, final PageBase parentPage) {
setOutputMarkupId(true);
final Form mainForm = new Form(ID_MAIN_FORM);
mainForm.setOutputMarkupId(true);
mainForm.addOrReplace(initTable(model));
add(mainForm);
AutoCompleteTextPanel<String> intent = new AutoCompleteTextPanel<String>(ID_INTENT, new PropertyModel<String>(resourceContentSearch, "intent"), String.class) {
private static final long serialVersionUID = 1L;
@Override
public Iterator<String> getIterator(String input) {
RefinedResourceSchema refinedSchema = null;
try {
refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(model.getObject(), parentPage.getPrismContext());
} catch (SchemaException e) {
return new ArrayList<String>().iterator();
}
return RefinedResourceSchemaImpl.getIntentsForKind(refinedSchema, getKind()).iterator();
}
};
intent.getBaseFormComponent().add(new OnChangeAjaxBehavior() {
private static final long serialVersionUID = 1L;
@Override
protected void onUpdate(AjaxRequestTarget target) {
target.add(get(ID_REAL_OBJECT_CLASS));
updateResourceContentSearch();
mainForm.addOrReplace(initTable(model));
target.add(mainForm);
}
});
intent.setOutputMarkupId(true);
intent.add(new VisibleEnableBehaviour() {
private static final long serialVersionUID = 1L;
@Override
public boolean isVisible() {
return !isUseObjectClass();
}
});
add(intent);
Label realObjectClassLabel = new Label(ID_REAL_OBJECT_CLASS, new AbstractReadOnlyModel<String>() {
private static final long serialVersionUID = 1L;
@Override
public String getObject() {
RefinedObjectClassDefinition ocDef;
try {
RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(model.getObject(), parentPage.getPrismContext());
if (refinedSchema == null) {
return "NO SCHEMA DEFINED";
}
ocDef = refinedSchema.getRefinedDefinition(getKind(), getIntent());
if (ocDef != null) {
return ocDef.getObjectClassDefinition().getTypeName().getLocalPart();
}
} catch (SchemaException e) {
}
return "NOT FOUND";
}
});
realObjectClassLabel.setOutputMarkupId(true);
add(realObjectClassLabel);
AutoCompleteQNamePanel objectClassPanel = new AutoCompleteQNamePanel(ID_OBJECT_CLASS, new PropertyModel<QName>(resourceContentSearch, "objectClass")) {
private static final long serialVersionUID = 1L;
@Override
public Collection<QName> loadChoices() {
return createObjectClassChoices(model);
}
@Override
protected void onChange(AjaxRequestTarget target) {
LOGGER.trace("Object class panel update: {}", isUseObjectClass());
updateResourceContentSearch();
mainForm.addOrReplace(initTable(model));
target.add(mainForm);
}
};
objectClassPanel.add(new VisibleEnableBehaviour() {
private static final long serialVersionUID = 1L;
@Override
public boolean isVisible() {
return isUseObjectClass();
}
});
add(objectClassPanel);
AjaxLink<Boolean> repoSearch = new AjaxLink<Boolean>(ID_REPO_SEARCH, new PropertyModel<Boolean>(resourceContentSearch, "resourceSearch")) {
private static final long serialVersionUID = 1L;
@Override
public void onClick(AjaxRequestTarget target) {
isRepoSearch = true;
getContentStorage(kind, SessionStorage.KEY_RESOURCE_PAGE_REPOSITORY_CONTENT).setResourceSearch(Boolean.FALSE);
getContentStorage(kind, SessionStorage.KEY_RESOURCE_PAGE_RESOURCE_CONTENT).setResourceSearch(Boolean.FALSE);
resourceContentSearch.getObject().setResourceSearch(Boolean.FALSE);
updateResourceContentSearch();
mainForm.addOrReplace(initRepoContent(model));
target.add(getParent().addOrReplace(mainForm));
target.add(this);
target.add(getParent().get(ID_RESOURCE_SEARCH).add(AttributeModifier.replace("class", "btn btn-sm btn-default")));
}
@Override
protected void onBeforeRender() {
super.onBeforeRender();
if (!getModelObject().booleanValue())
add(AttributeModifier.replace("class", "btn btn-sm btn-default active"));
}
};
add(repoSearch);
AjaxLink<Boolean> resourceSearch = new AjaxLink<Boolean>(ID_RESOURCE_SEARCH, new PropertyModel<Boolean>(resourceContentSearch, "resourceSearch")) {
private static final long serialVersionUID = 1L;
@Override
public void onClick(AjaxRequestTarget target) {
isRepoSearch = false;
getContentStorage(kind, SessionStorage.KEY_RESOURCE_PAGE_REPOSITORY_CONTENT).setResourceSearch(Boolean.TRUE);
getContentStorage(kind, SessionStorage.KEY_RESOURCE_PAGE_RESOURCE_CONTENT).setResourceSearch(Boolean.TRUE);
updateResourceContentSearch();
resourceContentSearch.getObject().setResourceSearch(Boolean.TRUE);
mainForm.addOrReplace(initResourceContent(model));
target.add(getParent().addOrReplace(mainForm));
target.add(this.add(AttributeModifier.append("class", " active")));
target.add(getParent().get(ID_REPO_SEARCH).add(AttributeModifier.replace("class", "btn btn-sm btn-default")));
}
@Override
protected void onBeforeRender() {
super.onBeforeRender();
getModelObject().booleanValue();
if (getModelObject().booleanValue())
add(AttributeModifier.replace("class", "btn btn-sm btn-default active"));
}
};
add(resourceSearch);
}
use of com.evolveum.midpoint.common.refinery.RefinedResourceSchema in project midpoint by Evolveum.
the class LensUtil method refineProjectionIntent.
public static String refineProjectionIntent(ShadowKindType kind, String intent, ResourceType resource, PrismContext prismContext) throws SchemaException {
RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource, LayerType.MODEL, prismContext);
RefinedObjectClassDefinition rObjClassDef = refinedSchema.getRefinedDefinition(kind, intent);
if (rObjClassDef == null) {
throw new SchemaException("No projection definition for kind=" + kind + " intent=" + intent + " in " + resource);
}
return rObjClassDef.getIntent();
}
use of com.evolveum.midpoint.common.refinery.RefinedResourceSchema in project midpoint by Evolveum.
the class SynchronizationUtils method isPolicyApplicable.
public static boolean isPolicyApplicable(QName objectClass, ShadowKindType kind, String intent, ObjectSynchronizationType synchronizationPolicy, PrismObject<ResourceType> resource) throws SchemaException {
List<QName> policyObjectClasses = synchronizationPolicy.getObjectClass();
if (policyObjectClasses == null || policyObjectClasses.isEmpty()) {
String policyIntent = synchronizationPolicy.getIntent();
ShadowKindType policyKind = synchronizationPolicy.getKind();
ObjectClassComplexTypeDefinition policyObjectClass = null;
RefinedResourceSchema schema = RefinedResourceSchemaImpl.getRefinedSchema(resource);
if (schema == null) {
throw new SchemaException("No schema defined in resource. Possible configuration problem?");
}
if (policyKind == null && policyIntent == null) {
policyObjectClass = schema.findDefaultObjectClassDefinition(ShadowKindType.ACCOUNT);
}
if (policyKind != null) {
if (StringUtils.isEmpty(policyIntent)) {
policyObjectClass = schema.findDefaultObjectClassDefinition(policyKind);
} else {
policyObjectClass = schema.findObjectClassDefinition(policyKind, policyIntent);
}
}
if (policyObjectClass != null && !policyObjectClass.getTypeName().equals(objectClass)) {
return false;
}
}
if (policyObjectClasses != null && !policyObjectClasses.isEmpty()) {
if (!QNameUtil.contains(policyObjectClasses, objectClass)) {
return false;
}
}
// kind
ShadowKindType policyKind = synchronizationPolicy.getKind();
if (policyKind != null && kind != null && !policyKind.equals(kind)) {
return false;
}
// intent
// TODO is the intent always present in shadow at this time? [med]
String policyIntent = synchronizationPolicy.getIntent();
if (policyIntent != null && intent != null && !MiscSchemaUtil.equalsIntent(intent, policyIntent)) {
return false;
}
return true;
}
use of com.evolveum.midpoint.common.refinery.RefinedResourceSchema in project midpoint by Evolveum.
the class ShadowIntegrityCheckResultHandler method checkShadow.
private void checkShadow(ShadowCheckResult checkResult, PrismObject<ShadowType> shadow, Task workerTask, OperationResult result) throws SchemaException {
ShadowType shadowType = shadow.asObjectable();
ObjectReferenceType resourceRef = shadowType.getResourceRef();
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Checking shadow {} (resource {})", ObjectTypeUtil.toShortString(shadowType), resourceRef != null ? resourceRef.getOid() : "(null)");
}
statistics.incrementShadows();
if (resourceRef == null) {
checkResult.recordError(Statistics.NO_RESOURCE_OID, new SchemaException("No resourceRef"));
fixNoResourceIfRequested(checkResult, Statistics.NO_RESOURCE_OID);
applyFixes(checkResult, shadow, workerTask, result);
return;
}
String resourceOid = resourceRef.getOid();
if (resourceOid == null) {
checkResult.recordError(Statistics.NO_RESOURCE_OID, new SchemaException("Null resource OID"));
fixNoResourceIfRequested(checkResult, Statistics.NO_RESOURCE_OID);
applyFixes(checkResult, shadow, workerTask, result);
return;
}
PrismObject<ResourceType> resource = resources.get(resourceOid);
if (resource == null) {
statistics.incrementResources();
try {
resource = provisioningService.getObject(ResourceType.class, resourceOid, null, workerTask, result);
} catch (ObjectNotFoundException e) {
checkResult.recordError(Statistics.NO_RESOURCE, new ObjectNotFoundException("Resource object does not exist: " + e.getMessage(), e));
fixNoResourceIfRequested(checkResult, Statistics.NO_RESOURCE);
applyFixes(checkResult, shadow, workerTask, result);
return;
} catch (SchemaException e) {
checkResult.recordError(Statistics.CANNOT_GET_RESOURCE, new SchemaException("Resource object has schema problems: " + e.getMessage(), e));
return;
} catch (CommonException | RuntimeException e) {
checkResult.recordError(Statistics.CANNOT_GET_RESOURCE, new SystemException("Resource object cannot be fetched for some reason: " + e.getMessage(), e));
return;
}
resources.put(resourceOid, resource);
}
checkResult.setResource(resource);
ShadowKindType kind = shadowType.getKind();
if (kind == null) {
// TODO or simply assume account?
checkResult.recordError(Statistics.NO_KIND_SPECIFIED, new SchemaException("No kind specified"));
return;
}
if (checkExtraData) {
checkOrFixShadowActivationConsistency(checkResult, shadow, fixExtraData);
}
PrismObject<ShadowType> fetchedShadow = null;
if (checkFetch) {
fetchedShadow = fetchShadow(checkResult, shadow, resource, workerTask, result);
if (fetchedShadow != null) {
shadow.setUserData(KEY_EXISTS_ON_RESOURCE, "true");
}
}
if (checkOwners) {
List<PrismObject<FocusType>> owners = searchOwners(shadow, result);
if (owners != null) {
shadow.setUserData(KEY_OWNERS, owners);
if (owners.size() > 1) {
checkResult.recordError(Statistics.MULTIPLE_OWNERS, new SchemaException("Multiple owners: " + owners));
}
}
if (shadowType.getSynchronizationSituation() == SynchronizationSituationType.LINKED && (owners == null || owners.isEmpty())) {
checkResult.recordError(Statistics.LINKED_WITH_NO_OWNER, new SchemaException("Linked shadow with no owner"));
}
if (shadowType.getSynchronizationSituation() != SynchronizationSituationType.LINKED && owners != null && !owners.isEmpty()) {
checkResult.recordError(Statistics.NOT_LINKED_WITH_OWNER, new SchemaException("Shadow with an owner but not marked as linked (marked as " + shadowType.getSynchronizationSituation() + ")"));
}
}
String intent = shadowType.getIntent();
if (checkIntents && (intent == null || intent.isEmpty())) {
checkResult.recordWarning(Statistics.NO_INTENT_SPECIFIED, "None or empty intent");
}
if (fixIntents && (intent == null || intent.isEmpty())) {
doFixIntent(checkResult, fetchedShadow, shadow, resource, workerTask, result);
}
Pair<String, ShadowKindType> key = new ImmutablePair<>(resourceOid, kind);
ObjectTypeContext context = contextMap.get(key);
if (context == null) {
context = new ObjectTypeContext();
context.setResource(resource);
RefinedResourceSchema resourceSchema;
try {
resourceSchema = RefinedResourceSchemaImpl.getRefinedSchema(context.getResource(), LayerType.MODEL, prismContext);
} catch (SchemaException e) {
checkResult.recordError(Statistics.CANNOT_GET_REFINED_SCHEMA, new SchemaException("Couldn't derive resource schema: " + e.getMessage(), e));
return;
}
if (resourceSchema == null) {
checkResult.recordError(Statistics.NO_RESOURCE_REFINED_SCHEMA, new SchemaException("No resource schema"));
return;
}
context.setObjectClassDefinition(resourceSchema.getRefinedDefinition(kind, shadowType));
if (context.getObjectClassDefinition() == null) {
// TODO or warning only?
checkResult.recordError(Statistics.NO_OBJECT_CLASS_REFINED_SCHEMA, new SchemaException("No refined object class definition for kind=" + kind + ", intent=" + intent));
return;
}
contextMap.put(key, context);
}
try {
provisioningService.applyDefinition(shadow, workerTask, result);
} catch (SchemaException | ObjectNotFoundException | CommunicationException | ConfigurationException | ExpressionEvaluationException e) {
checkResult.recordError(Statistics.OTHER_FAILURE, new SystemException("Couldn't apply definition to shadow from repo", e));
return;
}
Set<RefinedAttributeDefinition<?>> identifiers = new HashSet<>();
Collection<? extends RefinedAttributeDefinition<?>> primaryIdentifiers = context.getObjectClassDefinition().getPrimaryIdentifiers();
identifiers.addAll(primaryIdentifiers);
identifiers.addAll(context.getObjectClassDefinition().getSecondaryIdentifiers());
PrismContainer<ShadowAttributesType> attributesContainer = shadow.findContainer(ShadowType.F_ATTRIBUTES);
if (attributesContainer == null) {
// might happen on unfinished shadows?
checkResult.recordError(Statistics.OTHER_FAILURE, new SchemaException("No attributes container"));
return;
}
for (RefinedAttributeDefinition<?> identifier : identifiers) {
PrismProperty property = attributesContainer.getValue().findProperty(identifier.getName());
if (property == null || property.size() == 0) {
checkResult.recordWarning(Statistics.OTHER_FAILURE, "No value for identifier " + identifier.getName());
continue;
}
if (property.size() > 1) {
// we don't expect multi-valued identifiers
checkResult.recordError(Statistics.OTHER_FAILURE, new SchemaException("Multi-valued identifier " + identifier.getName() + " with values " + property.getValues()));
continue;
}
// size == 1
String value = (String) property.getValue().getValue();
if (value == null) {
checkResult.recordWarning(Statistics.OTHER_FAILURE, "Null value for identifier " + identifier.getName());
continue;
}
if (checkUniqueness) {
if (!checkDuplicatesOnPrimaryIdentifiersOnly || primaryIdentifiers.contains(identifier)) {
addIdentifierValue(checkResult, context, identifier.getName(), value, shadow);
}
}
if (checkNormalization) {
doCheckNormalization(checkResult, identifier, value, context);
}
}
applyFixes(checkResult, shadow, workerTask, result);
}
Aggregations