Skip to content

Commit

Permalink
Fix resource objects lifecycle state handling
Browse files Browse the repository at this point in the history
The lifecycle state is "negatively" propagated from a resource
to its object classes and from an object class to its object types:
if an item at some level is in non-production state, all its children
are considered to be in non-production state, regardless of their
lifecycle state value.
  • Loading branch information
mederly committed Nov 19, 2022
1 parent e151c09 commit 5dcaca7
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.task.api;
package com.evolveum.midpoint.schema;

/**
* Describes the execution mode this task runs in. For example, if it is a "full execution" or a preview/simulation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,16 @@ public static <R extends AbstractRoleType> VirtualAssignmenetSpecification<R> ge
return virtualAssignmenetSpecification;
}

@Experimental // The behavior should be configurable
/**
* Returns true if the specified configuration item (e.g. resource, object class, object type, item, mapping, ...)
* is in "production" lifecycle state.
*
* The idea is that configuration items in `active` and `deprecated` states will have a different behavior
* than the ones in `proposed` state. (The behavior of other states is going to be determined later.)
*
* TODO Preliminary code.
*/
@Experimental
public static boolean isInProduction(String lifecycleState) {
return lifecycleState == null
|| SchemaConstants.LIFECYCLE_ACTIVE.equals(lifecycleState)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,20 @@
<xsd:element ref="tns:documentation" minOccurs="0"/>
<xsd:element ref="tns:lifecycleState" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Lifecycle state of the object class or object type. First, it drives the visibility of the configuration
for production-like or simulation tasks. Second, it influences the behavior of specific provisioning
operations (like shadow classification).

The lifecycle state is propagated downwards, from the level of a resource, down to the level
of an object class, and finally to the level of an object type. If the state is evaluated
as "non-matching" at a given level, all lower levels are ignored. For example, if an object class
has a "proposed" lifecycle state, all its object types are considered to be in non-production
development state, regardless of their own lifecycle state values.

See https://docs.lab.evolveum.com/midpoint/devel/design/simulations/simulated-shadows/ for more
information.
</xsd:documentation>
<xsd:appinfo>
<a:displayName>ObjectType.lifecycleState</a:displayName>
<a:since>4.7</a:since>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -476,26 +476,33 @@ public boolean isInMaintenance() {
return ResourceTypeUtil.isInMaintenance(resource);
}

// Preliminary code
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
private boolean isResourceInProduction() {
return LifecycleUtil.isInProduction(
resource.getLifecycleState());
}

// Preliminary code
// FIXME implement checking for refined object class LC state - currently it is overridden by respective object type
// state, which is not always what is needed (most probably we want the 'proposed' state at OC level to override
// anything that could be set at the type level ... we should decide on this)
/**
* Returns true if the definition of the current resource object is in "production" lifecycle state
* (`active` or `deprecated`). This determines the behavior of some processing components, as described in
* https://docs.lab.evolveum.com/midpoint/devel/design/simulations/simulated-shadows/.
*/
public boolean isObjectDefinitionInProduction() {
if (!isResourceInProduction()) {
return false; // We ignore any object class/type level settings here.
// Level 1: resource
if (!LifecycleUtil.isInProduction(resource.getLifecycleState())) {
// The whole resource is in development mode. We ignore any object class/type level settings in this case.
return false;
}
if (resourceObjectDefinition == null) {
// Resource is in production, and we have no further information.
throw new IllegalStateException(
"Asked for production state of the object definition, but there is no object definition: " + this);
}
// Level 2: object class
ResourceObjectClassDefinition classDefinition = resourceObjectDefinition.getObjectClassDefinition();
if (!LifecycleUtil.isInProduction(classDefinition.getLifecycleState())) {
return false;
}
// Level 3: object type (if there's any)
ResourceObjectTypeDefinition typeDefinition = resourceObjectDefinition.getTypeDefinition();
if (typeDefinition == null) {
return true;
}
// Note that the object type/class lifecycle state may be null. This means that it should inherit the value
// of the resource LC state. In that case it means that it should be considered as "production", because the resource
// itself is in production state (per above condition). Hence the following code is OK.
return resourceObjectDefinition == null
|| LifecycleUtil.isInProduction(resourceObjectDefinition.getLifecycleState());
return LifecycleUtil.isInProduction(typeDefinition.getLifecycleState());
}

public void checkNotInMaintenance() throws MaintenanceException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

import static org.assertj.core.api.Assertions.assertThat;

import static com.evolveum.midpoint.task.api.TaskExecutionMode.*;
import static com.evolveum.midpoint.schema.TaskExecutionMode.*;
import static com.evolveum.midpoint.test.util.MidPointTestConstants.TEST_RESOURCES_DIR;

import java.io.File;
Expand All @@ -33,7 +33,7 @@
import com.evolveum.midpoint.schema.processor.ResourceAttribute;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.task.api.TaskExecutionMode;
import com.evolveum.midpoint.schema.TaskExecutionMode;
import com.evolveum.midpoint.test.DummyTestResource;
import com.evolveum.midpoint.util.exception.CommonException;
import com.evolveum.midpoint.util.exception.ConfigurationException;
Expand Down Expand Up @@ -210,7 +210,9 @@ public void test120ClassificationOnResourceWithProposedClasses() throws Exceptio
I_SECURITY_GROUP); // no reclassification (production-like mode)

// The non-production object type with "simulated development" task
// Note that the lifecycle state is of the type "entitlement/mail-group" is "proposed" because of the type inheritance.
// Note that the lifecycle state is of the type "entitlement/mail-group" is "proposed" in spite of the type inheritance,
// because the class "proposed" state makes the whole class proposed, without considering the declared states of
// individual object types.
checkClassification(
RESOURCE_DUMMY_PROPOSED_CLASSES,
SIMULATED_DEVELOPMENT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
<objectType>
<kind>entitlement</kind>
<intent>mail-group</intent>
<lifecycleState>active</lifecycleState> <!-- will be ignored, as the whole class is "proposed" -->
<delineation>
<objectClass>ri:GroupObjectClass</objectClass>
<filter>
Expand All @@ -92,6 +93,7 @@
<objectType>
<kind>entitlement</kind>
<intent>security-group</intent>
<lifecycleState>active</lifecycleState> <!-- will be ignored, as the whole class is "proposed" -->
<delineation>
<objectClass>ri:GroupObjectClass</objectClass>
<filter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.evolveum.midpoint.prism.delta.ItemDelta;
import com.evolveum.midpoint.prism.path.ItemName;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.schema.TaskExecutionMode;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.statistics.StatisticsCollector;
import com.evolveum.midpoint.schema.util.task.ActivityPath;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.evolveum.midpoint.prism.delta.ItemDelta;
import com.evolveum.midpoint.prism.path.ItemName;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.schema.TaskExecutionMode;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.statistics.*;
import com.evolveum.midpoint.task.api.*;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.schema.TaskExecutionMode;
import com.evolveum.midpoint.schema.constants.ObjectTypes;

import com.evolveum.midpoint.schema.reporting.ConnIdOperation;
Expand Down

0 comments on commit 5dcaca7

Please sign in to comment.