Skip to content

Commit

Permalink
Add structural archetype OID metric dimension
Browse files Browse the repository at this point in the history
The structural archetype OID was added to existing dimensions of object
type, resource OID, kind, and intent, according which the simulation
metrics are evaluated.
  • Loading branch information
mederly committed Feb 2, 2023
1 parent befa6a6 commit 8c4cf88
Show file tree
Hide file tree
Showing 11 changed files with 162 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,21 @@
public class PartitionScope {

private final QName objectType;
private final String structuralArchetypeOid;
private final String resourceOid;
private final ShadowKindType kind;
private final String intent;
private final Set<QName> allDimensions;

public PartitionScope(QName objectType, String resourceOid, ShadowKindType kind, String intent, Set<QName> allDimensions) {
public PartitionScope(
QName objectType,
String structuralArchetypeOid,
String resourceOid,
ShadowKindType kind,
String intent,
Set<QName> allDimensions) {
this.objectType = objectType;
this.structuralArchetypeOid = structuralArchetypeOid;
this.resourceOid = resourceOid;
this.kind = kind;
this.intent = intent;
Expand All @@ -45,10 +53,12 @@ public PartitionScope(QName objectType, String resourceOid, ShadowKindType kind,

public static PartitionScope fromBean(SimulationMetricPartitionScopeType scope, Set<QName> availableDimensions) {
if (scope == null) {
return new PartitionScope(null, null, null, null, availableDimensions);
return new PartitionScope(
null, null, null, null, null, availableDimensions);
} else {
return new PartitionScope(
ifAvailable(scope.getTypeName(), availableDimensions, F_TYPE_NAME),
ifAvailable(scope.getStructuralArchetypeOid(), availableDimensions, F_STRUCTURAL_ARCHETYPE_OID),
ifAvailable(scope.getResourceOid(), availableDimensions, F_RESOURCE_OID),
ifAvailable(scope.getKind(), availableDimensions, F_KIND),
ifAvailable(scope.getIntent(), availableDimensions, F_INTENT),
Expand Down Expand Up @@ -76,6 +86,7 @@ public boolean equals(Object o) {
}
PartitionScope that = (PartitionScope) o;
return Objects.equals(objectType, that.objectType)
&& Objects.equals(structuralArchetypeOid, that.structuralArchetypeOid)
&& Objects.equals(resourceOid, that.resourceOid)
&& kind == that.kind
&& Objects.equals(intent, that.intent)
Expand All @@ -84,19 +95,23 @@ public boolean equals(Object o) {

@Override
public int hashCode() {
return Objects.hash(objectType, resourceOid, kind, intent);
return Objects.hash(objectType, structuralArchetypeOid, resourceOid, kind, intent);
}

public SimulationMetricPartitionScopeType toBean() {
SimulationMetricPartitionScopeType bean = new SimulationMetricPartitionScopeType()
.typeName(objectType)
.structuralArchetypeOid(structuralArchetypeOid)
.resourceOid(resourceOid)
.kind(kind)
.intent(intent);
List<QName> nullDimensions = bean.getNullDimensions();
if (objectType == null && allDimensions.contains(F_TYPE_NAME)) {
nullDimensions.add(F_TYPE_NAME);
}
if (structuralArchetypeOid == null && allDimensions.contains(F_STRUCTURAL_ARCHETYPE_OID)) {
nullDimensions.add(F_STRUCTURAL_ARCHETYPE_OID);
}
if (resourceOid == null && allDimensions.contains(F_RESOURCE_OID)) {
nullDimensions.add(F_RESOURCE_OID);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* 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.schema.util;

import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
import com.evolveum.prism.xml.ns._public.types_3.PolyStringType;

public class ObjectReferenceTypeUtil {

public static String getTargetNameOrOid(ObjectReferenceType ref) {
if (ref == null) {
return null;
}
PolyStringType targetName = ref.getTargetName();
if (targetName != null) {
String orig = targetName.getOrig();
if (orig != null) {
return orig;
}
}
return ref.getOid();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ public static Set<QName> getDimensions(@Nullable SimulationMetricPartitionScopeT
if (scope.getTypeName() != null) {
dimensions.add(SimulationMetricPartitionScopeType.F_TYPE_NAME);
}
if (scope.getStructuralArchetypeOid() != null) {
dimensions.add(SimulationMetricPartitionScopeType.F_STRUCTURAL_ARCHETYPE_OID);
}
if (scope.getResourceOid() != null) {
dimensions.add(SimulationMetricPartitionScopeType.F_RESOURCE_OID);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class SimulationMetricPartitionTypeUtil {

public static final Set<QName> ALL_DIMENSIONS = Set.of(
SimulationMetricPartitionScopeType.F_TYPE_NAME,
SimulationMetricPartitionScopeType.F_STRUCTURAL_ARCHETYPE_OID,
SimulationMetricPartitionScopeType.F_RESOURCE_OID,
SimulationMetricPartitionScopeType.F_KIND,
SimulationMetricPartitionScopeType.F_INTENT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,13 @@
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="structuralArchetypeOid" type="xsd:string" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Value of the "structural archetype OID" dimension. Applies only to focus objects.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="resourceOid" type="xsd:string" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Expand Down Expand Up @@ -953,6 +960,17 @@
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="structuralArchetypeRef" type="tns:ObjectReferenceType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Structural archetype of the object processed. Applies only to focal objects (assignment holders).
</xsd:documentation>
<xsd:appinfo>
<a:displayName>SimulationResultProcessedObjectType.structuralArchetypeRef</a:displayName>
<a:objectReferenceTargetType>tns:ArchetypeType</a:objectReferenceTargetType>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="resourceObjectCoordinates" type="tns:ShadowDiscriminatorType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

import java.util.*;

import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
import com.evolveum.midpoint.util.MiscUtil;

import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;

Expand Down Expand Up @@ -145,6 +148,13 @@ public void setArchetypes(List<ArchetypeType> archetypes) {
this.archetypes = archetypes;
}

/** Precondition: context is "complete" i.e. {@link #archetypes} are filled in. */
public ObjectReferenceType getStructuralArchetypeRef() throws SchemaException {
return ObjectTypeUtil.createObjectRef(
ArchetypeTypeUtil.getStructuralArchetype(
MiscUtil.stateNonNull(archetypes, () -> "Information about archetypes is not present")));
}

public ObjectTemplateType getFocusTemplate() {
return focusTemplate;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@

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

import static com.evolveum.midpoint.schema.util.ObjectReferenceTypeUtil.getTargetNameOrOid;
import static com.evolveum.midpoint.schema.util.ObjectTypeUtil.asObjectable;
import static com.evolveum.midpoint.schema.util.SimulationMetricPartitionTypeUtil.ALL_DIMENSIONS;
import static com.evolveum.midpoint.util.MiscUtil.*;
import static com.evolveum.midpoint.util.MiscUtil.argCheck;
import static com.evolveum.midpoint.util.MiscUtil.emptyIfNull;

import java.math.BigDecimal;
import java.util.*;
Expand Down Expand Up @@ -65,6 +67,7 @@ public class ProcessedObjectImpl<O extends ObjectType> implements ProcessedObjec
@NotNull private final String transactionId;
private final String oid; // TODO may be null?
@NotNull private final Class<O> type;
@Nullable private final ObjectReferenceType structuralArchetypeRef;
@NotNull private final QName typeName;
private final ShadowDiscriminatorType shadowDiscriminator;
private final PolyStringType name;
Expand Down Expand Up @@ -93,6 +96,7 @@ private ProcessedObjectImpl(
@NotNull String transactionId,
String oid,
@NotNull Class<O> type,
@Nullable ObjectReferenceType structuralArchetypeRef,
ShadowDiscriminatorType shadowDiscriminator,
PolyStringType name,
@NotNull ObjectProcessingStateType state,
Expand All @@ -107,6 +111,7 @@ private ProcessedObjectImpl(
this.oid = oid;
this.type = type;
this.typeName = ObjectTypes.getObjectType(type).getTypeQName();
this.structuralArchetypeRef = structuralArchetypeRef;
this.shadowDiscriminator = shadowDiscriminator;
this.name = name;
this.state = state;
Expand All @@ -129,6 +134,7 @@ public static <O extends ObjectType> ProcessedObjectImpl<O> parse(@NotNull Simul
bean.getTransactionId(),
bean.getOid(),
(Class<O>) type,
bean.getStructuralArchetypeRef(),
bean.getResourceObjectCoordinates(),
bean.getName(),
MiscUtil.argNonNull(bean.getState(), () -> "No processing state in " + bean),
Expand Down Expand Up @@ -195,6 +201,8 @@ private void addComputedMetricValues(@NotNull List<SimulationProcessedObjectMetr
simulationTransaction.getTransactionId(),
elementContext.getOid(),
type,
elementContext instanceof LensFocusContext<?> ?
((LensFocusContext<?>) elementContext).getStructuralArchetypeRef() : null,
determineShadowDiscriminator(anyState),
anyState.getName(),
delta != null ?
Expand Down Expand Up @@ -258,6 +266,10 @@ public String getOid() {
return typeName;
}

private @Nullable String getStructuralArchetypeOid() {
return Referencable.getOid(structuralArchetypeRef);
}

public String getResourceOid() {
return shadowDiscriminator != null ?
Referencable.getOid(shadowDiscriminator.getResourceRef()) : null;
Expand Down Expand Up @@ -342,6 +354,7 @@ public SimulationResultProcessedObjectType toBean() {
.oid(oid)
.type(
PrismContext.get().getSchemaRegistry().determineTypeForClass(type))
.structuralArchetypeRef(structuralArchetypeRef)
.resourceObjectCoordinates(shadowDiscriminator != null ? shadowDiscriminator.clone() : null)
.name(name)
.state(state)
Expand Down Expand Up @@ -388,6 +401,9 @@ private ObjectType prepareObjectForStorage(@Nullable O original) {
public String debugDump(int indent) {
StringBuilder sb = DebugUtil.createTitleStringBuilder(getClass(), indent);
sb.append(" of ").append(type.getSimpleName());
if (structuralArchetypeRef != null) {
sb.append("/").append(getTargetNameOrOid(structuralArchetypeRef));
}
sb.append(" ").append(oid);
sb.append(" (").append(name).append("): ");
sb.append(state);
Expand Down Expand Up @@ -570,7 +586,7 @@ public void resolveEventMarks(OperationResult result) {
}

PartitionScope partitionScope() {
return new PartitionScope(getTypeName(), getResourceOid(), getKind(), getIntent(), ALL_DIMENSIONS);
return new PartitionScope(getTypeName(), getStructuralArchetypeOid(), getResourceOid(), getKind(), getIntent(), ALL_DIMENSIONS);
}

void propagateRecordId() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@

import static com.evolveum.midpoint.schema.constants.SchemaConstants.*;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import com.evolveum.midpoint.model.test.TestSimulationResult;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.schema.util.SimulationResultTypeUtil;

import org.testng.SkipException;
import org.testng.annotations.Test;

Expand Down Expand Up @@ -89,7 +93,9 @@ public void test100CreateUser() throws Exception {

given("a user");
UserType user = new UserType()
.name("test100");
.name("test100")
.assignment(new AssignmentType()
.targetRef(ARCHETYPE_CUSTOMER.oid, ArchetypeType.COMPLEX_TYPE));

when("user is created in simulation");
TestSimulationResult simResult =
Expand All @@ -104,7 +110,20 @@ public void test100CreateUser() throws Exception {
objectsCounter.assertNoNewObjects(result);

and("simulation result is OK");
assertSimulationResultAfter(simResult); // TODO some asserts here
SimulationResultType resultBean = assertSimulationResultAfter(simResult) // TODO some asserts here
.assertMetricValueByEventMark(MARK_USER_ADD.oid, BigDecimal.ONE)
.getObjectable();

// TODO write an asserter for this
SimulationMetricValuesType mv =
SimulationResultTypeUtil.getAggregatedMetricValuesByEventMarkOid(resultBean, MARK_USER_ADD.oid);
displayDumpable("metric value", mv);
List<SimulationMetricPartitionType> partitions = mv.getPartition();
assertThat(partitions).as("metric partitions").hasSize(1);
SimulationMetricPartitionScopeType scope = partitions.get(0).getScope();
assertThat(scope.getTypeName()).as("type name").isEqualTo(UserType.COMPLEX_TYPE);
assertThat(scope.getStructuralArchetypeOid()).as("archetype OID").isEqualTo(ARCHETYPE_CUSTOMER.oid);

// @formatter:off
assertProcessedObjects(simResult)
.display()
Expand Down Expand Up @@ -132,10 +151,33 @@ public void test100CreateUser() throws Exception {
and("the model context is OK");
ModelContext<?> modelContext = simResult.getLastModelContext();
displayDumpable("model context", modelContext);
assertUserPrimaryAndSecondaryDeltas(modelContext);
assertUserPrimaryAndSecondaryDeltasWithArchetype(modelContext);
}

private void assertUserPrimaryAndSecondaryDeltasWithArchetype(ModelContext<?> modelContext) {
ModelElementContext<?> focusContext = modelContext.getFocusContextRequired();
// @formatter:off
assertDelta(focusContext.getPrimaryDelta(), "primary delta")
.display()
.assertAdd()
.objectToAdd()
.assertItems(UserType.F_NAME, UserType.F_ASSIGNMENT); // The primary delta is that simple
assertDelta(focusContext.getSummarySecondaryDelta(), "summary secondary delta")
.display()
.assertModify()
.assertModifiedExclusive( // This list may change if projector internals change
PATH_ACTIVATION_EFFECTIVE_STATUS,
PATH_ACTIVATION_ENABLE_TIMESTAMP,
FocusType.F_ITERATION,
FocusType.F_ITERATION_TOKEN,
FocusType.F_METADATA,
FocusType.F_ROLE_MEMBERSHIP_REF,
FocusType.F_ARCHETYPE_REF,
ItemPath.create(FocusType.F_ASSIGNMENT, 1L)); // effective status + metadata
// @formatter:on
}

private void assertUserPrimaryAndSecondaryDeltas(ModelContext<?> modelContext) {
private void assertUserPrimaryAndSecondaryDeltasNoArchetype(ModelContext<?> modelContext) {
ModelElementContext<?> focusContext = modelContext.getFocusContextRequired();
// @formatter:off
assertDelta(focusContext.getPrimaryDelta(), "primary delta")
Expand Down Expand Up @@ -238,7 +280,7 @@ private void executeTest11xCreateUserWithLinkedAccount(String name, DummyTestRes

// The user deltas are the same as in test100.
// The linkRef delta is audited but (currently) it is not among secondary deltas.
assertUserPrimaryAndSecondaryDeltas(modelContext);
assertUserPrimaryAndSecondaryDeltasNoArchetype(modelContext);

Collection<? extends ModelProjectionContext> projectionContexts = modelContext.getProjectionContexts();
assertThat(projectionContexts).as("projection contexts").hasSize(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ public class AbstractSimulationsTest extends AbstractEmptyModelIntegrationTest {
SIM_TEST_DIR, "archetype-person-dev-archetype.xml", "be5bf6fb-11ce-40a8-b588-ec44cf051523");
private static final TestResource<ArchetypeType> ARCHETYPE_PERSON_DEV_TEMPLATE = new TestResource<>(
SIM_TEST_DIR, "archetype-person-dev-template.xml", "be7f8541-64ec-4bee-a5c3-855923ae9b90");
static final TestResource<ArchetypeType> ARCHETYPE_CUSTOMER = new TestResource<>(
SIM_TEST_DIR, "archetype-customer.xml", "075ebbed-f3b9-4bac-90c2-bb8811121636");

private static final String ATTR_TYPE_NAME = "type";
// private static final ItemName ATTR_TYPE_ITEM_NAME = new ItemName(NS_RI, ATTR_TYPE_NAME);
Expand Down Expand Up @@ -115,6 +117,7 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti
repoAdd(ARCHETYPE_PERSON, initResult);
repoAdd(ARCHETYPE_PERSON_DEV_ARCHETYPE, initResult);
repoAdd(ARCHETYPE_PERSON_DEV_TEMPLATE, initResult);
repoAdd(ARCHETYPE_CUSTOMER, initResult);

RESOURCE_SIMPLE_PRODUCTION_TARGET.initAndTest(this, initTask, initResult);
RESOURCE_SIMPLE_DEVELOPMENT_TARGET.initAndTest(this, initTask, initResult);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!--
~ 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.
-->

<archetype
xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
oid="075ebbed-f3b9-4bac-90c2-bb8811121636">
<name>customer</name>
</archetype>

0 comments on commit 8c4cf88

Please sign in to comment.