Skip to content

Commit

Permalink
Implement basic correlators
Browse files Browse the repository at this point in the history
This commit provides FilterCorrelator, ExpressionCorrelator, and
IdMatchCorrelator (using IdMatchService and follow-on correlator).
Includes unit tests for these correlators and refactored matcher tests.
  • Loading branch information
mederly committed Jan 13, 2022
1 parent 062ca96 commit adb2fc6
Show file tree
Hide file tree
Showing 44 changed files with 2,095 additions and 411 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,7 @@ public class ExpressionConstants {
public static final String VAR_REQUEST = "request";
public static final String VAR_ITEM = "item";
public static final String VAR_BUCKET = "bucket";

public static final String VAR_CORRELATION_CONTEXT = "correlationContext";
public static final String VAR_CORRELATION_STATE = "correlationState";
}
106 changes: 87 additions & 19 deletions infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -8905,7 +8905,7 @@
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="correlationDefinition" type="tns:CorrelationType" minOccurs="0"> <!-- TODO name? -->
<xsd:element name="correlationDefinition" type="tns:CorrelatorsType" minOccurs="0"> <!-- TODO name? -->
<xsd:annotation>
<xsd:documentation>
Definition of (complex) correlation. TODO
Expand Down Expand Up @@ -23121,12 +23121,10 @@
</xsd:complexType>
<xsd:element name="plannedOperationAttempt" type="tns:PlannedOperationAttemptType"/>

<xsd:complexType name="CorrelationType">
<xsd:complexType name="CorrelatorsType">
<xsd:annotation>
<xsd:documentation>
Defines how resource objects are correlated i.e. matched with their owners. (TODO)

TODO consider name like CorrelationDefinitionType?
User-friendly way of defining a correlator or correlators.
</xsd:documentation>
<xsd:appinfo>
<a:since>4.5</a:since>
Expand Down Expand Up @@ -23168,7 +23166,7 @@
</xsd:sequence>
<xsd:attribute name="id" type="xsd:long"/>
</xsd:complexType>
<xsd:element name="correlation" type="tns:CorrelationType"/>
<xsd:element name="correlators" type="tns:CorrelatorsType"/>

<xsd:complexType name="AbstractCorrelatorType">
<xsd:annotation>
Expand Down Expand Up @@ -23209,7 +23207,7 @@
</xsd:annotation>
</xsd:element>

<xsd:element name="name" type="t:PolyStringType" minOccurs="0">
<xsd:element name="name" type="xsd:string" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Name of the correlator. Should be unique in the given context (object type definition,
Expand Down Expand Up @@ -23269,6 +23267,7 @@
<xsd:element name="filter" type="tns:ConditionalSearchFilterType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
WE MAY RENAME THIS BEFORE RELEASE.
<!-- TODO should the focus type be specified here? -->
<p>The filter that should return a list of candidate focus entries that may be owners
of a particular shadow.</p>
Expand All @@ -23290,22 +23289,31 @@
The evaluation of the confirmation expression may be relatively inefficient, as it will only
be run for candidate entries returned by correlation expression.

Called only when multiple objects are found.

TODO review this
The expression variables should be set as follows:
$user - the candidate user object (one of the results of correlation expression)
$account - the changed account object
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="useConfirmationForSingleCandidate" type="xsd:boolean" minOccurs="0" default="true">
<xsd:annotation>
<xsd:documentation>
Should be the confirmation expression used also when there is only a single candidate
found by the filter? (The default is true. This is consistent with midPoint 4.3+ behavior.
Before midPoint 4.3, the default was false.)
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="selection" type="c:ExpressionType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Selection expression. Obtains a collection of all found candidate objects, and returns
the one that should be selected.

TODO specify better -- can this one be used also to start correlation cases?

NOT IMPLEMENTED YET.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
Expand All @@ -23329,14 +23337,23 @@
<xsd:complexContent>
<xsd:extension base="tns:AbstractCorrelatorType">
<xsd:sequence>
<!-- TODO name: expression/expression looks weird -->
<xsd:element name="expression" type="c:ExpressionType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
TODO specify
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:choice>
<xsd:element name="owner" type="c:ExpressionType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Expression that returns owner as an ObjectType.
(MAYBE WE WILL REMOVE THIS.)
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="ownerRef" type="c:ExpressionType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Expression that returns owner as an ObjectReferenceType.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:choice>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
Expand Down Expand Up @@ -23379,7 +23396,7 @@
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="correlator" type="tns:AbstractCorrelatorType" minOccurs="0">
<xsd:element name="followOn" type="tns:CorrelatorsType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
The correlator that is applied to the resolved reference identifier
Expand All @@ -23391,7 +23408,7 @@
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="idMatchCorrelator" type="tns:ExpressionCorrelatorType"/>
<xsd:element name="idMatchCorrelator" type="tns:IdMatchCorrelatorType"/>

<!--<xsd:complexType name="CorrelationRequestType">-->
<!-- <xsd:annotation>-->
Expand Down Expand Up @@ -23644,4 +23661,55 @@
<!-- <xsd:attribute name="id" type="xsd:long"/>-->
<!--</xsd:complexType>-->

<xsd:complexType name="AbstractCorrelationStateType">
<xsd:annotation>
<xsd:documentation>
Current state of the correlation process.
</xsd:documentation>
<xsd:appinfo>
<a:since>4.5</a:since>
<a:container>true</a:container>
<a:experimental>true</a:experimental>
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<!-- Should be anything here? -->
</xsd:sequence>
<xsd:attribute name="id" type="xsd:long"/>
</xsd:complexType>

<xsd:complexType name="IdMatchCorrelationStateType">
<xsd:annotation>
<xsd:documentation>
State of the process driven by ID Match correlator.
</xsd:documentation>
<xsd:appinfo>
<a:since>4.5</a:since>
<a:container>true</a:container>
<a:experimental>true</a:experimental>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexContent>
<xsd:extension base="tns:AbstractCorrelationStateType">
<xsd:sequence>
<xsd:element name="referenceId" type="xsd:string" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Reference ID determined by ID Match (if known).
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="matchRequestId" type="xsd:string" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Match request ID - present if the match is pending.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="idMatchCorrelationState" type="tns:IdMatchCorrelationStateType"/>

</xsd:schema>
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright (C) 2010-2022 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.api.correlator;

import com.evolveum.midpoint.schema.processor.ResourceObjectTypeDefinition;
import com.evolveum.midpoint.util.DebugDumpable;
import com.evolveum.midpoint.util.DebugUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractCorrelationStateType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;

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

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

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

/**
* The context of the correlation operation(s).
*
* TODO decide on the exact use of this class -- will it be only at API level? Or will the correlator write its own notes here?
*/
public class CorrelationContext implements DebugDumpable {

/**
* What type of focus object(s) are we correlating against.
*/
@NotNull private final Class<? extends ObjectType> focusType;

/**
* Resource on which the correlated shadow resides.
*/
@NotNull private final ResourceType resource;

/**
* Resource object type definition (~ schemaHandling section).
*/
@NotNull private final ResourceObjectTypeDefinition objectTypeDefinition;

/**
* System configuration to use during the correlation.
*/
@Nullable private final SystemConfigurationType systemConfiguration;

/**
* Information about the current state of the correlation process.
* Usually provided by upstream (parent) correlator.
*/
private AbstractCorrelationStateType correlationState;

public CorrelationContext(
@NotNull Class<? extends ObjectType> focusType,
@NotNull ResourceType resource,
@NotNull ResourceObjectTypeDefinition objectTypeDefinition,
@Nullable SystemConfigurationType systemConfiguration) {
this.focusType = focusType;
this.resource = resource;
this.objectTypeDefinition = objectTypeDefinition;
this.systemConfiguration = systemConfiguration;
}

@NotNull public Class<? extends ObjectType> getFocusType() {
return focusType;
}

public @NotNull ResourceType getResource() {
return resource;
}

public @NotNull ResourceObjectTypeDefinition getObjectTypeDefinition() {
return objectTypeDefinition;
}

public @Nullable SystemConfigurationType getSystemConfiguration() {
return systemConfiguration;
}

public AbstractCorrelationStateType getCorrelationState() {
return correlationState;
}

public void setCorrelationState(AbstractCorrelationStateType correlationState) {
this.correlationState = correlationState;
}

@Override
public String toString() {
return "CorrelationContext("
+ focusType.getSimpleName() + ", "
+ objectTypeDefinition.getHumanReadableName() + "@" + resource
+ ')';
}

@Override
public String debugDump(int indent) {
StringBuilder sb = DebugUtil.createTitleStringBuilderLn(getClass(), indent);
DebugUtil.debugDumpWithLabelLn(sb, "focusType", focusType, indent + 1);
DebugUtil.debugDumpWithLabelLn(sb, "resource", String.valueOf(resource), indent + 1);
DebugUtil.debugDumpWithLabelLn(sb, "objectTypeDefinition", String.valueOf(objectTypeDefinition), indent + 1);
DebugUtil.debugDumpWithLabelLn(sb, "systemConfiguration", String.valueOf(systemConfiguration), indent + 1);
DebugUtil.debugDumpWithLabel(sb, "correlationState", correlationState, indent + 1);
return sb.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.exception.*;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;

import org.jetbrains.annotations.NotNull;
Expand All @@ -26,8 +27,12 @@ public interface Correlator {
* We assume that the correlator is already configured. See {@link CorrelatorFactory}.
*
* @param resourceObject Resource object to correlate (should contain attributes, and be shadowed)
* @param correlationContext Additional information about the overall context for correlation (e.g. type of focal objects)
* @param task Task in context of which the correlation takes place
* @param result Operation result where the method should record its operation
*/
CorrelationResult correlate(@NotNull ShadowType resourceObject, @NotNull Task task, @NotNull OperationResult result);
CorrelationResult correlate(@NotNull ShadowType resourceObject, @NotNull CorrelationContext correlationContext,
@NotNull Task task, @NotNull OperationResult result)
throws SchemaException, ExpressionEvaluationException, CommunicationException, SecurityViolationException,
ConfigurationException, ObjectNotFoundException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright (C) 2010-2022 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.api.correlator;

import org.jetbrains.annotations.NotNull;

import com.evolveum.midpoint.prism.PrismContainerValue;
import com.evolveum.midpoint.prism.path.ItemName;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractCorrelatorType;

/**
* Wrapper for both typed (bean-only) and untyped (bean + item name) correlator configuration.
*/
public abstract class CorrelatorConfiguration {

@NotNull private final AbstractCorrelatorType configurationBean;

CorrelatorConfiguration(@NotNull AbstractCorrelatorType configurationBean) {
this.configurationBean = configurationBean;
}

public @NotNull AbstractCorrelatorType getConfigurationBean() {
return configurationBean;
}

public static class TypedCorrelationConfiguration extends CorrelatorConfiguration {
public TypedCorrelationConfiguration(@NotNull AbstractCorrelatorType configurationBean) {
super(configurationBean);
}
}

public static class UntypedCorrelationConfiguration extends CorrelatorConfiguration {
@NotNull private final ItemName configurationItemName;

public UntypedCorrelationConfiguration(
@NotNull ItemName configurationItemName,
@NotNull PrismContainerValue<? extends AbstractCorrelatorType> pcv) {
super(pcv.asContainerable());
this.configurationItemName = configurationItemName;
}

public @NotNull ItemName getConfigurationItemName() {
return configurationItemName;
}
}
}

0 comments on commit adb2fc6

Please sign in to comment.