Skip to content

Commit

Permalink
Simplify ShadowManager and "shadows" pkg code
Browse files Browse the repository at this point in the history
ShadowManager as a class no longer exists. It was a mere facade
lately, and all it did was forwarding method calls. Now it was replaced
by three classes: ShadowFinder, ShadowCreator, and ShadowUpdater which
collectively provide the shadow management functionality to "shadows"
package.

Some other parts in the "shadows" package were cleaned up as well.
  • Loading branch information
mederly committed Nov 17, 2022
1 parent 648ec2d commit a3ea0d1
Show file tree
Hide file tree
Showing 65 changed files with 2,958 additions and 3,129 deletions.
12 changes: 12 additions & 0 deletions infra/common/src/main/java/com/evolveum/midpoint/common/Clock.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package com.evolveum.midpoint.common;

import javax.annotation.PostConstruct;
import javax.xml.datatype.Duration;
import javax.xml.datatype.XMLGregorianCalendar;

Expand All @@ -25,6 +26,17 @@
*/
public class Clock {

private static Clock instance;

@PostConstruct
public void init() {
instance = this;
}

public static Clock get() {
return instance;
}

private static final Trace LOGGER = TraceManager.getTrace(Clock.class);

volatile private Long override = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,15 @@ public ResourceAttribute<String> getDescriptionAttribute() {

@Override
public ResourceAttribute<String> getNamingAttribute() {
if (getDefinition() == null) {
ResourceAttributeContainerDefinition containerDef = getDefinition();
if (containerDef == null) {
return null;
}
if (getDefinition().getNamingAttribute()==null) {
ResourceAttributeDefinition<?> namingAttrDef = containerDef.getNamingAttribute();
if (namingAttrDef == null) {
return null;
}
return findAttribute(getDefinition().getNamingAttribute());
return findAttribute(namingAttrDef);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,23 @@ public static ResourceAttribute<String> getNamingAttribute(PrismObject<? extends
return attributesContainer.getNamingAttribute();
}

public static Collection<ResourceAttribute<?>> getAttributes(ShadowType shadowType) {
public static @NotNull Collection<ResourceAttribute<?>> getAttributes(ShadowType shadowType) {
return getAttributes(shadowType.asPrismObject());
}

// TODO what if there's no attributes container?
public static Collection<ResourceAttribute<?>> getAttributes(PrismObject<? extends ShadowType> shadow) {
return getAttributesContainer(shadow).getAttributes();
public static @NotNull Collection<ResourceAttribute<?>> getAttributes(PrismObject<? extends ShadowType> shadow) {
ResourceAttributeContainer attributesContainer = getAttributesContainer(shadow);
return attributesContainer != null ? attributesContainer.getAttributes() : List.of();
}

/** Here we assume that the definition may not be applied yet. */
public static @NotNull Collection<Item<?, ?>> getAttributesRaw(PrismObject<? extends ShadowType> shadow) {
PrismContainer<?> attributesContainer = shadow.findContainer(ShadowType.F_ATTRIBUTES);
if (attributesContainer != null && attributesContainer.hasAnyValue()) {
return attributesContainer.getValue().getItems();
} else {
return List.of();
}
}

public static <T> ResourceAttribute<T> getAttribute(ShadowType shadow, QName attrName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -534,12 +534,17 @@ private void executeModification(OperationResult result)
PrismObject<E> baseObject = elementContext.getObjectCurrent();
try {
OwnerResolver ownerResolver = createOwnerResolver(result);
b.securityEnforcer.authorize(ModelAuthorizationAction.MODIFY.getUrl(), AuthorizationPhaseType.EXECUTION,
AuthorizationParameters.Builder.buildObjectDelta(baseObject, delta), ownerResolver, task, result);
b.securityEnforcer.authorize(
ModelAuthorizationAction.MODIFY.getUrl(),
AuthorizationPhaseType.EXECUTION,
AuthorizationParameters.Builder.buildObjectDelta(baseObject, delta),
ownerResolver,
task,
result);

if (shouldApplyModifyMetadata(objectClass, context.getSystemConfigurationBean())) {
b.metadataManager.applyMetadataModify(delta, objectClass, elementContext,
b.clock.currentTimeXMLGregorianCalendar(), task, context);
b.metadataManager.applyMetadataModify(
delta, objectClass, elementContext, b.clock.currentTimeXMLGregorianCalendar(), task, context);
}
b.indexingManager.updateIndexDataOnElementModify(
asObjectable(baseObject), delta, objectClass, elementContext, task, result);
Expand All @@ -563,8 +568,8 @@ private void executeModification(OperationResult result)
FocusConstraintsChecker.clearCacheForDelta(delta.getModifications());
ModificationPrecondition<E> precondition = createRepoModificationPrecondition();
try {
b.cacheRepositoryService.modifyObject(objectClass, delta.getOid(),
delta.getModifications(), precondition, null, result);
b.cacheRepositoryService.modifyObject(
objectClass, delta.getOid(), delta.getModifications(), precondition, null, result);
} catch (PreconditionViolationException e) {
throw new ConflictDetectedException(e);
}
Expand Down Expand Up @@ -679,8 +684,13 @@ private void executeDeletion(OperationResult result)
PrismObject<E> objectOld = elementContext.getObjectOld();
try {
OwnerResolver ownerResolver = createOwnerResolver(result);
b.securityEnforcer.authorize(ModelAuthorizationAction.DELETE.getUrl(), AuthorizationPhaseType.EXECUTION,
AuthorizationParameters.Builder.buildObjectDelete(objectOld), ownerResolver, task, result);
b.securityEnforcer.authorize(
ModelAuthorizationAction.DELETE.getUrl(),
AuthorizationPhaseType.EXECUTION,
AuthorizationParameters.Builder.buildObjectDelete(objectOld),
ownerResolver,
task,
result);

if (TaskType.class.isAssignableFrom(objectTypeClass)) {
b.taskManager.deleteTask(oid, result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3003,7 +3003,15 @@ public void test212RenameUserMorgan() throws Exception {
dummyAuditService.assertHasDelta(ChangeType.MODIFY, UserType.class);
ObjectDeltaOperation<ShadowType> auditShadowDelta = dummyAuditService.assertHasDelta(ChangeType.MODIFY, ShadowType.class);

assertEquals("Unexpected number of modifications in shadow audit delta: " + auditShadowDelta.debugDump(), 8, auditShadowDelta.getObjectDelta().getModifications().size());
assertEquals(
"Unexpected number of modifications in shadow audit delta: " + auditShadowDelta.debugDump(),
8,
auditShadowDelta.getObjectDelta().getModifications().size());

// The modifications are following:
// metadata/modifyChannel, modifyTimestamp, modifierRef, modifyTaskRef, modifyApproverRef, modifyApprovalComment
// attributes/icfs:name: morgan -> sirhenry
// attributes/icfs:uid: morgan -> sirhenry - this is a change induced by the connector/resource

dummyAuditService.assertOldValue(ChangeType.MODIFY, UserType.class,
UserType.F_NAME, PrismTestUtil.createPolyString("morgan"));
Expand Down
2 changes: 1 addition & 1 deletion model/model-intest/src/test/resources/logback-test.xml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
<logger name="com.evolveum.midpoint.provisioning.impl.resources.ConnectorManager" level="DEBUG" />
<logger name="com.evolveum.midpoint.provisioning.impl.resources.ResourceCache" level="DEBUG" />
<logger name="com.evolveum.midpoint.provisioning.impl.shadows.ShadowsFacade" level="DEBUG" />
<logger name="com.evolveum.midpoint.provisioning.impl.shadows.manager.ShadowManager" level="DEBUG" />
<logger name="com.evolveum.midpoint.provisioning.impl.shadows.manager" level="DEBUG" />
<logger name="com.evolveum.midpoint.provisioning.impl.shadows.task" level="DEBUG" />
<logger name="com.evolveum.midpoint.provisioning.impl.shadows.errors" level="DEBUG" />
<logger name="com.evolveum.midpoint.repo.common.expression" level="DEBUG" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,9 @@ <T extends ObjectType> SearchResultMetadata searchObjectsIterative(
*
* TODO: optimistic locking
*
* TODO decide if it's OK that the callee modifies the `modifications` collection by adding side-effects provided
* by the connector.
*
* @param scripts
* scripts that should be executed before of after operation
* @param parentResult
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@

package com.evolveum.midpoint.provisioning.impl;

import com.evolveum.midpoint.repo.common.SystemObjectCache;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
Expand All @@ -21,8 +19,8 @@
import com.evolveum.midpoint.provisioning.impl.resources.ResourceManager;
import com.evolveum.midpoint.provisioning.impl.resources.ResourceOperationalStateManager;
import com.evolveum.midpoint.provisioning.impl.shadows.ShadowsFacade;
import com.evolveum.midpoint.provisioning.impl.shadows.manager.ShadowManager;
import com.evolveum.midpoint.repo.api.RepositoryService;
import com.evolveum.midpoint.repo.common.SystemObjectCache;
import com.evolveum.midpoint.repo.common.expression.ExpressionFactory;
import com.evolveum.midpoint.schema.RelationRegistry;
import com.evolveum.midpoint.util.annotation.Experimental;
Expand All @@ -36,7 +34,6 @@ public class CommonBeans {
@Autowired public ExpressionFactory expressionFactory;
@Autowired public PrismContext prismContext;
@Autowired public ShadowsFacade shadowsFacade;
@Autowired public ShadowManager shadowManager;
@Autowired public ResourceObjectConverter resourceObjectConverter;
@Autowired @Qualifier("cacheRepositoryService") public RepositoryService cacheRepositoryService;
@Autowired public ProvisioningServiceImpl provisioningService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,10 @@ public void updateShadowState(ShadowType shadow) {
getCaretaker().updateShadowState(this, shadow);
}

public ShadowLifecycleStateType determineShadowState(ShadowType shadow) {
return getCaretaker().determineShadowState(this, shadow);
}

// TODO not sure if it's ok here
public @NotNull ShadowType futurizeShadow(
@NotNull ShadowType repoShadow,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -997,8 +997,6 @@ public ConstraintsCheckingResult checkConstraints(
OperationResult result = parentResult.createSubresult(ProvisioningService.class.getName() + ".checkConstraints");
try {
ConstraintsChecker checker = new ConstraintsChecker();
checker.setCacheConfigurationManager(cacheConfigurationManager);
checker.setShadowsFacade(shadowsFacade);
checker.setShadowObjectOld(shadowObjectOld);
// "Whole class": we should not need it here. We do not invoke the search on resource here.
ProvisioningContext ctx = ctxFactory.createForDefinition(resource, objectDefinition, null, task);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -404,12 +404,4 @@ void updateShadowState(ProvisioningContext ctx, ShadowType shadow) {
shadow.setShadowLifecycleState(
determineShadowState(ctx, shadow));
}

/** Determines and updates the shadow state - in situations where we don't have the context. */
public void updateShadowStateInEmergency(ShadowType shadow)
throws SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException,
ObjectNotFoundException {
ShadowLifecycleStateType state = determineShadowStateInternal(null, shadow, clock.currentTimeXMLGregorianCalendar());
shadow.setShadowLifecycleState(state);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1501,6 +1501,10 @@ PrismObject<ShadowType> fetchResourceObject(
return resourceObject;
}

/**
* Attributes returned by the connector update the original shadow: they are either added (if not present before),
* or they replace their previous versions.
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private void applyAfterOperationAttributes(ShadowType shadow,
Collection<ResourceAttribute<?>> resourceAttributesAfterAdd) throws SchemaException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,65 +6,56 @@
*/
package com.evolveum.midpoint.provisioning.impl.resourceobjects;

import static com.evolveum.midpoint.util.MiscUtil.argCheck;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceObjectReferenceResolutionFrequencyType.*;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;

import javax.xml.namespace.QName;

import com.evolveum.midpoint.provisioning.impl.ProvisioningContext;
import com.evolveum.midpoint.provisioning.impl.shadows.manager.ShadowManager;
import com.evolveum.midpoint.provisioning.impl.shadows.ShadowsFacade;

import com.evolveum.midpoint.schema.constants.MidPointConstants;
import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition;
import com.evolveum.midpoint.schema.processor.ResourceObjectDefinition;
import com.evolveum.midpoint.util.QNameUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.evolveum.midpoint.prism.Containerable;
import com.evolveum.midpoint.prism.PrismContainer;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.PrismProperty;
import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.prism.query.ObjectFilter;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.provisioning.api.GenericConnectorException;
import com.evolveum.midpoint.provisioning.impl.ProvisioningContext;
import com.evolveum.midpoint.provisioning.impl.shadows.ShadowsFacade;
import com.evolveum.midpoint.provisioning.impl.shadows.manager.ShadowFinder;
import com.evolveum.midpoint.provisioning.ucf.api.AttributesToReturn;
import com.evolveum.midpoint.provisioning.ucf.api.ConnectorInstance;
import com.evolveum.midpoint.provisioning.ucf.api.GenericFrameworkException;
import com.evolveum.midpoint.repo.api.RepositoryService;
import com.evolveum.midpoint.repo.common.expression.ExpressionFactory;
import com.evolveum.midpoint.repo.common.expression.ExpressionUtil;
import com.evolveum.midpoint.schema.expression.VariablesMap;
import com.evolveum.midpoint.schema.ResultHandler;
import com.evolveum.midpoint.schema.constants.MidPointConstants;
import com.evolveum.midpoint.schema.expression.VariablesMap;
import com.evolveum.midpoint.schema.processor.ResourceAttribute;
import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition;
import com.evolveum.midpoint.schema.processor.ResourceObjectDefinition;
import com.evolveum.midpoint.schema.processor.ResourceObjectIdentification;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.MiscSchemaUtil;
import com.evolveum.midpoint.schema.util.ObjectQueryUtil;
import com.evolveum.midpoint.schema.util.ShadowUtil;
import com.evolveum.midpoint.util.Holder;
import com.evolveum.midpoint.util.PrettyPrinter;
import com.evolveum.midpoint.util.exception.CommunicationException;
import com.evolveum.midpoint.util.exception.ConfigurationException;
import com.evolveum.midpoint.util.exception.ExpressionEvaluationException;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.exception.SecurityViolationException;
import com.evolveum.midpoint.util.QNameUtil;
import com.evolveum.midpoint.util.exception.*;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceObjectReferenceResolutionFrequencyType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceObjectReferenceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.ReadCapabilityType;

import static com.evolveum.midpoint.util.MiscUtil.argCheck;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceObjectReferenceResolutionFrequencyType.*;

/**
* Resolves resource objects (also) with the help of the repository / shadow manager.
*
Expand All @@ -79,7 +70,7 @@ class ResourceObjectReferenceResolver {

@Autowired private PrismContext prismContext;
@Autowired private ExpressionFactory expressionFactory;
@Autowired private ShadowManager shadowManager;
@Autowired private ShadowFinder shadowFinder;
@Autowired private ShadowsFacade shadowsFacade;

@Autowired
Expand Down Expand Up @@ -177,7 +168,7 @@ Collection<? extends ResourceAttribute<?>> resolvePrimaryIdentifier(Provisioning
}
ResourceObjectDefinition objDef = ctx.getObjectDefinitionRequired();
Collection<ResourceAttribute<?>> secondaryIdentifiers = ShadowUtil.getSecondaryIdentifiers(identifiers, objDef);
PrismObject<ShadowType> repoShadow = shadowManager.lookupShadowBySecondaryIds(ctx, secondaryIdentifiers, result);
PrismObject<ShadowType> repoShadow = shadowFinder.lookupShadowBySecondaryIds(ctx, secondaryIdentifiers, result);
if (repoShadow == null) {
return null;
}
Expand Down Expand Up @@ -278,7 +269,7 @@ private ResourceObjectIdentification resolvePrimaryIdentifiers(ProvisioningConte
return identification;
}
Collection<ResourceAttribute<?>> secondaryIdentifiers = (Collection<ResourceAttribute<?>>) identification.getSecondaryIdentifiers();
PrismObject<ShadowType> repoShadow = shadowManager.lookupShadowBySecondaryIds(ctx, secondaryIdentifiers, result);
PrismObject<ShadowType> repoShadow = shadowFinder.lookupShadowBySecondaryIds(ctx, secondaryIdentifiers, result);
if (repoShadow == null) {
// TODO: we should attempt resource search here
throw new ObjectNotFoundException(
Expand Down

0 comments on commit a3ea0d1

Please sign in to comment.