Search in sources :

Example 1 with RefinedResourceSchema

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;
}
Also used : OperationResult(com.evolveum.midpoint.schema.result.OperationResult) ResourceType(com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType) ObjectClassComplexTypeDefinition(com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition) RefinedResourceSchema(com.evolveum.midpoint.common.refinery.RefinedResourceSchema) AuditEventRecord(com.evolveum.midpoint.audit.api.AuditEventRecord)

Example 2 with RefinedResourceSchema

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);
}
Also used : SchemaException(com.evolveum.midpoint.util.exception.SchemaException) Form(org.apache.wicket.markup.html.form.Form) QName(javax.xml.namespace.QName) ArrayList(java.util.ArrayList) Label(org.apache.wicket.markup.html.basic.Label) AutoCompleteQNamePanel(com.evolveum.midpoint.gui.api.component.autocomplete.AutoCompleteQNamePanel) AutoCompleteTextPanel(com.evolveum.midpoint.gui.api.component.autocomplete.AutoCompleteTextPanel) OnChangeAjaxBehavior(org.apache.wicket.ajax.form.OnChangeAjaxBehavior) AjaxRequestTarget(org.apache.wicket.ajax.AjaxRequestTarget) RefinedObjectClassDefinition(com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition) RefinedResourceSchema(com.evolveum.midpoint.common.refinery.RefinedResourceSchema) VisibleEnableBehaviour(com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour) AjaxLink(org.apache.wicket.ajax.markup.html.AjaxLink)

Example 3 with RefinedResourceSchema

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();
}
Also used : RefinedObjectClassDefinition(com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition) RefinedResourceSchema(com.evolveum.midpoint.common.refinery.RefinedResourceSchema)

Example 4 with RefinedResourceSchema

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;
}
Also used : SchemaException(com.evolveum.midpoint.util.exception.SchemaException) QName(javax.xml.namespace.QName) ShadowKindType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType) ObjectClassComplexTypeDefinition(com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition) RefinedResourceSchema(com.evolveum.midpoint.common.refinery.RefinedResourceSchema)

Example 5 with RefinedResourceSchema

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);
}
Also used : ExpressionEvaluationException(com.evolveum.midpoint.util.exception.ExpressionEvaluationException) PrismObject(com.evolveum.midpoint.prism.PrismObject) SystemException(com.evolveum.midpoint.util.exception.SystemException) ConfigurationException(com.evolveum.midpoint.util.exception.ConfigurationException) RefinedAttributeDefinition(com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition) RefinedResourceSchema(com.evolveum.midpoint.common.refinery.RefinedResourceSchema) HashSet(java.util.HashSet) SchemaException(com.evolveum.midpoint.util.exception.SchemaException) CommunicationException(com.evolveum.midpoint.util.exception.CommunicationException) ShadowType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType) ShadowAttributesType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAttributesType) ResourceType(com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType) ObjectReferenceType(com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType) PrismProperty(com.evolveum.midpoint.prism.PrismProperty) ImmutablePair(org.apache.commons.lang3.tuple.ImmutablePair) ObjectNotFoundException(com.evolveum.midpoint.util.exception.ObjectNotFoundException) CommonException(com.evolveum.midpoint.util.exception.CommonException) ShadowKindType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType)

Aggregations

RefinedResourceSchema (com.evolveum.midpoint.common.refinery.RefinedResourceSchema)26 RefinedObjectClassDefinition (com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition)15 SchemaException (com.evolveum.midpoint.util.exception.SchemaException)11 QName (javax.xml.namespace.QName)10 ObjectClassComplexTypeDefinition (com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition)9 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)4 ResourceType (com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType)4 ShadowType (com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType)4 Test (org.testng.annotations.Test)4 RefinedAttributeDefinition (com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition)3 PolyString (com.evolveum.midpoint.prism.polystring.PolyString)3 ObjectQuery (com.evolveum.midpoint.prism.query.ObjectQuery)3 ResourceAttributeDefinition (com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition)3 ResourceSchema (com.evolveum.midpoint.schema.processor.ResourceSchema)3 ShadowKindType (com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType)3 ArrayList (java.util.ArrayList)3 HashSet (java.util.HashSet)3 AbstractModelIntegrationTest (com.evolveum.midpoint.model.test.AbstractModelIntegrationTest)2 Containerable (com.evolveum.midpoint.prism.Containerable)2 MatchingRule (com.evolveum.midpoint.prism.match.MatchingRule)2