Skip to content

Commit

Permalink
Add task "affected objects" computation
Browse files Browse the repository at this point in the history
Here we added the model-level computation of task.affectedObjects item.

Related changes:

- Added the idea of "activity type name", currently bound to the name
of the work configuration bean like (c:recomputation). It was also added
to the "affected objects" structure.

- Added preliminary concept of DeltaExecutionPreprocessor, as
a generalization of various similar "computers".

Unrelated changes:

- Fixed RuntimeException handling in Clockwork.
  • Loading branch information
mederly committed Aug 3, 2023
1 parent 4a188c4 commit 5eccb5d
Show file tree
Hide file tree
Showing 84 changed files with 1,169 additions and 295 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,4 @@ public static Collection<QName> getWorkDefinitionTypeNames(WorkDefinitionsType d
.map(WorkDefinitionBean::getBeanTypeName)
.collect(Collectors.toSet());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -584,11 +584,15 @@
<xsd:element name="affectedObjects" type="tns:TaskAffectedObjectsType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Searchable set of object set coordinates (eg. resource + kind + intent for resource objects,
or type for objects) for objects which are directly affected by execution of task.
Searchable set of object set coordinates (e.g., resource + kind + intent for resource objects,
or type + archetype for repository objects) for objects which are directly affected
by the execution of this task.

NOTE: This data are only for task indexing and searching purposes derived from activity definitions.
This data are not cannonical and for some edge-cases they may not be computed.
This data are not canonical and for some edge-cases they may not be computed.

Please never change this information directly, except for in raw mode. It is maintained
by the system automatically, so the result will be unpredictable if you do.
</xsd:documentation>
<xsd:appinfo>
<a:since>4.8</a:since>
Expand Down Expand Up @@ -6820,7 +6824,6 @@
</xsd:complexType>
<xsd:element name="objectSet" type="tns:ObjectSetType"/>


<xsd:complexType name="BasicResourceObjectSetType">
<xsd:annotation>
<xsd:documentation>
Expand Down Expand Up @@ -8984,24 +8987,78 @@
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="resourceObjects" type="tns:BasicResourceObjectSetType" minOccurs="0" maxOccurs="unbounded">
<xsd:element name="resourceObjects" type="tns:ActivityAffectedResourceObjectsType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Resource objects (defined by their object class, intent/kind), which are affected by task. Does not contain
explicit enumeration of affected resource objects.
Resource objects (defined by their object class, intent/kind), which are affected by task.
Does not contain explicit enumeration of affected resource objects.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="objects" type="tns:BasicObjectSetType" minOccurs="0" maxOccurs="unbounded">
<xsd:element name="objects" type="tns:ActivityAffectedObjectsType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Objects (defined by their type and archetype), which are affected by task. Does not contain explicit
enumeration of affected resource objects.
Repository objects (defined by their type and archetype), which are affected by task.
Does not contain explicit enumeration of affected objects.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:complexType>

<xsd:complexType name="ActivityAffectedResourceObjectsType">
<xsd:annotation>
<xsd:documentation>
Resource objects potentially affected by a particular activity.
</xsd:documentation>
<xsd:appinfo>
<a:container>true</a:container>
<a:since>4.8</a:since>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexContent>
<xsd:extension base="tns:BasicResourceObjectSetType">
<xsd:sequence>
<xsd:element name="activityType" type="xsd:QName" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Type of activity (identified by configuration item name) carried out on these resource objects.
</xsd:documentation>
<xsd:appinfo>
<a:displayName>ActivityAffectedResourceObjectsType.activity</a:displayName>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="ActivityAffectedObjectsType">
<xsd:annotation>
<xsd:documentation>
Objects (presumably in the repository) potentially affected by a particular activity.
</xsd:documentation>
<xsd:appinfo>
<a:container>true</a:container>
<a:since>4.8</a:since>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexContent>
<xsd:extension base="tns:BasicObjectSetType">
<xsd:sequence>
<xsd:element name="activityType" type="xsd:QName" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Type of activity (identified by configuration item name) carried out on these resource objects.
</xsd:documentation>
<xsd:appinfo>
<a:displayName>ActivityAffectedObjectsType.activity</a:displayName>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:schema>
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@ public OperationResultAssert isSuccess() {
return this;
}

public OperationResultAssert isWarning() {
isNotNull();
actual.computeStatusIfUnknown();
if (!actual.isWarning()) {
failWithMessage("Expected operation result to be warning: %s", actual);
}
return this;
}

public OperationResultAssert isFatalError() {
isNotNull();
actual.computeStatusIfUnknown();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public class TestUtil {
*/
public static final String NON_EXISTENT_OID = "4e4f4e5f-4558-4953-5445-4e545f4f4944";

public static boolean checkResults = true;
private static final boolean checkResults = true;

private static DatatypeFactory datatypeFactory = null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package com.evolveum.midpoint.model.impl;

import com.evolveum.midpoint.model.impl.controller.transformer.DataAccessProcessor;
import com.evolveum.midpoint.model.impl.lens.tasks.TaskOperationalDataManager;
import com.evolveum.midpoint.model.impl.security.AuthorizationMigrator;

import com.evolveum.midpoint.repo.common.activity.handlers.ActivityHandlerRegistry;
Expand Down Expand Up @@ -112,6 +113,7 @@ public static ModelBeans get() {
@Autowired public SecurityEnforcer securityEnforcer;
@Autowired public SecurityContextManager securityContextManager;
@Autowired public OperationalDataManager metadataManager;
@Autowired public TaskOperationalDataManager taskOperationalDataManager;
@Autowired public IdentitiesManager identitiesManager;
@Autowired public IndexingManager indexingManager;
@Autowired public TaskManager taskManager;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,40 +9,38 @@

import java.util.ArrayList;
import java.util.function.Predicate;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;

import com.evolveum.midpoint.model.api.ModelAuthorizationAction;
import com.evolveum.midpoint.repo.common.activity.run.state.ActivityStateDefinition;
import com.evolveum.midpoint.repo.common.activity.run.CompositeActivityRun;
import com.evolveum.midpoint.security.enforcer.api.AuthorizationParameters;
import com.evolveum.midpoint.security.enforcer.api.SecurityEnforcer;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.exception.CommonException;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;

import com.evolveum.midpoint.util.exception.SystemException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.cases.api.CaseManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

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

import com.evolveum.midpoint.audit.api.AuditService;
import com.evolveum.midpoint.cases.api.CaseManager;
import com.evolveum.midpoint.model.api.AccessCertificationService;
import com.evolveum.midpoint.model.api.ModelAuthorizationAction;
import com.evolveum.midpoint.model.impl.tasks.ModelActivityHandler;
import com.evolveum.midpoint.repo.common.activity.Activity;
import com.evolveum.midpoint.repo.common.activity.EmbeddedActivity;
import com.evolveum.midpoint.repo.common.activity.run.ActivityRunInstantiationContext;
import com.evolveum.midpoint.repo.common.activity.run.CompositeActivityRun;
import com.evolveum.midpoint.repo.common.activity.run.state.ActivityStateDefinition;
import com.evolveum.midpoint.report.api.ReportManager;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.security.enforcer.api.AuthorizationParameters;
import com.evolveum.midpoint.security.enforcer.api.SecurityEnforcer;
import com.evolveum.midpoint.task.api.RunningTask;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.task.api.TaskManager;
import com.evolveum.midpoint.util.exception.CommonException;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.exception.SystemException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

@Component
public class CleanupActivityHandler
Expand All @@ -62,7 +60,7 @@ public class CleanupActivityHandler
@PostConstruct
public void register() {
handlerRegistry.register(
CleanupWorkDefinitionType.COMPLEX_TYPE,
CleanupWorkDefinitionType.COMPLEX_TYPE, WorkDefinitionsType.F_CLEANUP,
CleanupWorkDefinition.class, CleanupWorkDefinition::new, this);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,20 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.CleanupPoliciesType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.CleanupWorkDefinitionType;

import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskAffectedObjectsType;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.xml.namespace.QName;

public class CleanupWorkDefinition extends AbstractWorkDefinition {

@Nullable
private final CleanupPoliciesType cleanupPolicies;

CleanupWorkDefinition(@NotNull WorkDefinitionBean source) {
CleanupWorkDefinition(@NotNull WorkDefinitionBean source, @NotNull QName activityTypeName) {
super(activityTypeName);
var typedDefinition = (CleanupWorkDefinitionType) source.getBean();
cleanupPolicies = typedDefinition.getPolicies();
}
Expand All @@ -30,6 +35,11 @@ public class CleanupWorkDefinition extends AbstractWorkDefinition {
return cleanupPolicies;
}

@Override
public @Nullable TaskAffectedObjectsType getAffectedObjects() {
return null; // not easily determinable
}

@Override
protected void debugDumpContent(StringBuilder sb, int indent) {
DebugUtil.debugDumpWithLabel(sb, "cleanupPolicies", cleanupPolicies, indent + 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import com.evolveum.midpoint.util.exception.CommonException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

import javax.xml.namespace.QName;

/**
* Scanner that looks for pending operations in the shadows and updates the status.
*
Expand All @@ -43,7 +45,7 @@ public class ShadowRefreshActivityHandler
@PostConstruct
public void register() {
handlerRegistry.register(
ShadowRefreshWorkDefinitionType.COMPLEX_TYPE,
ShadowRefreshWorkDefinitionType.COMPLEX_TYPE, WorkDefinitionsType.F_SHADOW_REFRESH,
MyWorkDefinition.class, MyWorkDefinition::new, this);
}

Expand Down Expand Up @@ -129,7 +131,8 @@ public static class MyWorkDefinition extends AbstractWorkDefinition implements O

@NotNull private final ObjectSetType objects;

MyWorkDefinition(@NotNull WorkDefinitionBean source) {
MyWorkDefinition(@NotNull WorkDefinitionBean source, @NotNull QName activityTypeName) {
super(activityTypeName);
var typedDefinition = (ShadowRefreshWorkDefinitionType) source.getBean();
objects = ObjectSetUtil.emptyIfNull(typedDefinition.getShadows());
ObjectSetUtil.assumeObjectType(objects, ShadowType.COMPLEX_TYPE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ public class ObjectIntegrityCheckActivityHandler
return ObjectIntegrityCheckWorkDefinitionType.COMPLEX_TYPE;
}

@Override
protected @NotNull QName getWorkDefinitionItemName() {
return WorkDefinitionsType.F_OBJECT_INTEGRITY_CHECK;
}

@Override
protected @NotNull Class<MyWorkDefinition> getWorkDefinitionClass() {
return MyWorkDefinition.class;
Expand Down Expand Up @@ -163,12 +168,13 @@ private void dumpStatistics(ObjectStatistics objectStatistics, int histogramColu
LOGGER.info("Objects processed with errors: {}", objectStatistics.getErrors());
}

static class MyWorkDefinition extends AbstractWorkDefinition implements ObjectSetSpecificationProvider {
protected static class MyWorkDefinition extends AbstractWorkDefinition implements ObjectSetSpecificationProvider {

@NotNull private final ObjectSetType objects;
private final int histogramColumns;

MyWorkDefinition(@NotNull WorkDefinitionBean source) {
MyWorkDefinition(@NotNull WorkDefinitionBean source, @NotNull QName activityTypeName) {
super(activityTypeName);
var typedDefinition = (ObjectIntegrityCheckWorkDefinitionType) source.getBean();
objects = ObjectSetUtil.emptyIfNull(typedDefinition.getObjects());
histogramColumns = MoreObjects.firstNonNull(typedDefinition.getHistogramColumns(), DEFAULT_HISTOGRAM_COLUMNS);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

package com.evolveum.midpoint.model.impl.integrity.shadows;

import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkDefinitionsType;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;

Expand Down Expand Up @@ -44,7 +46,7 @@ public class ShadowIntegrityCheckActivityHandler
@PostConstruct
public void register() {
handlerRegistry.register(
ShadowIntegrityCheckWorkDefinitionType.COMPLEX_TYPE,
ShadowIntegrityCheckWorkDefinitionType.COMPLEX_TYPE, WorkDefinitionsType.F_SHADOW_INTEGRITY_CHECK,
ShadowIntegrityCheckWorkDefinition.class, ShadowIntegrityCheckWorkDefinition::new, this);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowIntegrityCheckWorkDefinitionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;

import javax.xml.namespace.QName;

public class ShadowIntegrityCheckWorkDefinition extends AbstractWorkDefinition implements ObjectSetSpecificationProvider {

private static final Map<String, ShadowIntegrityAspectType> KNOWN_KEYS = Map.of(
Expand All @@ -44,7 +46,8 @@ public class ShadowIntegrityCheckWorkDefinition extends AbstractWorkDefinition i
@NotNull private final String duplicateShadowsResolver;
private final boolean checkDuplicatesOnPrimaryIdentifiersOnly;

ShadowIntegrityCheckWorkDefinition(@NotNull WorkDefinitionBean source) {
ShadowIntegrityCheckWorkDefinition(@NotNull WorkDefinitionBean source, @NotNull QName activityTypeName) {
super(activityTypeName);
var typedDefinition = (ShadowIntegrityCheckWorkDefinitionType) source.getBean();
shadows = ObjectSetUtil.emptyIfNull(typedDefinition.getShadows());
ObjectSetUtil.assumeObjectType(shadows, ShadowType.COMPLEX_TYPE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public <F extends ObjectType> HookOperationMode run(LensContext<F> context, Task

return clockworkConflictResolver.resolveFocusConflictIfPresent(context, conflictResolutionContext, mode, task, result);

} catch (CommonException t) {
} catch (Throwable t) {
result.recordException(t);
throw t;
} finally {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (C) 2010-2023 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.model.impl.lens;

import com.evolveum.midpoint.model.impl.lens.indexing.IndexingManager;
import com.evolveum.midpoint.model.impl.lens.tasks.TaskOperationalDataManager;

/**
* Just a marker interface for now, reminding us that there seems to be a repeated pattern of "delta execution preprocessors"
* (currently {@link OperationalDataManager}, {@link TaskOperationalDataManager}, and {@link IndexingManager}) that tweak
* the deltas before they are executed.
*
* In the future we can think about some generalization of these preprocessors, including extracting common
* methods to this interface, code deduplication, and so on.
*/
public interface DeltaExecutionPreprocessor {
}

0 comments on commit 5eccb5d

Please sign in to comment.