Skip to content

Commit

Permalink
Add preliminary <items> correlator
Browse files Browse the repository at this point in the history
This covers the most basic cases like TestSimpleCorrelationSimplified.

Unrelated changes:
 - Fixed a couple of incorrect uses of Comparator.nullsLast().
  • Loading branch information
mederly committed Feb 28, 2022
1 parent 54a9533 commit 4d49c9e
Show file tree
Hide file tree
Showing 22 changed files with 636 additions and 132 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,6 @@ public static Set<String> getValuesForPath(ObjectType object, Object... pathComp
return getValuesForPath(object.asPrismObject(), ItemPath.create(pathComponents));
}

public static Set<String> getValuesForPath(ObjectType object, ItemPath path) {
return getValuesForPath(object.asPrismObject(), path);
}

public static Set<String> getValuesForPath(PrismObject<?> object, ItemPath path) {
return object.getAllValues(path).stream()
.filter(Objects::nonNull)
Expand All @@ -74,6 +70,18 @@ public static Set<String> getValuesForPath(PrismObject<?> object, ItemPath path)
.collect(Collectors.toSet());
}

public static Set<?> getRealValuesForPath(ObjectType object, ItemPath path) {
return getRealValuesForPath(object.asPrismObject(), path);
}

private static Set<?> getRealValuesForPath(PrismObject<?> object, ItemPath path) {
return object.getAllValues(path).stream()
.filter(Objects::nonNull)
.map(PrismValue::getRealValue)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
}

/**
* Finds a property even if the path was reduced by removing all container IDs.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,15 @@ public CorrelationContext clone() {
throw new SystemException(e);
}
}

public @NotNull ObjectType getSourceObject(@NotNull SourceObjectType type) {
switch (type) {
case FOCUS:
return preFocus;
case PROJECTION:
return resourceObject;
default:
throw new AssertionError(type);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public abstract class CorrelatorConfiguration {
return configurationBean.getOrder();
}

public @NotNull String getDebugName() {
private @NotNull String getDebugName() {
return configurationBean.getName() != null ?
configurationBean.getName() : getDefaultDebugName();
}
Expand Down Expand Up @@ -120,7 +120,7 @@ private static boolean canBeStandalone(CorrelatorConfiguration configuration) {
public static List<CorrelatorConfiguration> getConfigurationsSorted(CompositeCorrelatorType correlatorsBean) {
List<CorrelatorConfiguration> configurations = new ArrayList<>(getConfigurations(correlatorsBean));
configurations.sort(
Comparator.nullsLast(Comparator.comparing(CorrelatorConfiguration::getOrder))
Comparator.comparing(CorrelatorConfiguration::getOrder, Comparator.nullsLast(Comparator.naturalOrder()))
.thenComparing(CorrelatorConfiguration::getAuthority));
return configurations;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

package com.evolveum.midpoint.model.api.correlator;

import com.evolveum.midpoint.util.DebugDumpable;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.VisibleForTesting;
Expand All @@ -21,7 +23,7 @@
* Differs from {@link CorrelationContext} in that the latter covers only a single correlation operation.
* The former covers the whole life of a correlator, and operations other than correlation.
*/
public class CorrelatorContext<C extends AbstractCorrelatorType> {
public class CorrelatorContext<C extends AbstractCorrelatorType> implements DebugDumpable {

@NotNull private final C configurationBean;

Expand Down Expand Up @@ -83,4 +85,11 @@ public boolean shouldCreateCases() {
&& synchronizationBean.getCorrelationDefinition().getCases() != null
&& !Boolean.FALSE.equals(synchronizationBean.getCorrelationDefinition().getCases().isEnabled());
}

@Override
public String debugDump(int indent) {
// Temporary: this config bean is the core of the context; other things need not be so urgently dumped
// (maybe they might be - in some shortened form).
return configurationBean.debugDump(indent);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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.constants.ExpressionConstants;
import com.evolveum.midpoint.util.annotation.Experimental;
import com.evolveum.midpoint.util.exception.ConfigurationException;

import org.jetbrains.annotations.NotNull;

import javax.xml.namespace.QName;

@Experimental
public enum SourceObjectType {

FOCUS, PROJECTION;

public static SourceObjectType fromVariable(@NotNull QName variableName) throws ConfigurationException {
switch (variableName.getLocalPart()) {
case ExpressionConstants.VAR_FOCUS:
case ExpressionConstants.VAR_USER:
return FOCUS;
case ExpressionConstants.VAR_PROJECTION:
case ExpressionConstants.VAR_SHADOW:
case ExpressionConstants.VAR_ACCOUNT:
return PROJECTION;
default:
throw new ConfigurationException("Unsupported variable name: " + variableName);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ private ProvenanceMetadataType compute() {
for (ProvenanceAcquisitionType representativeAcquisition : representativeProvenance.getAcquisition()) {
List<ProvenanceAcquisitionType> compatibleAcquisitions = getCompatibleAcquisitions(representativeAcquisition);
ProvenanceAcquisitionType earliest = compatibleAcquisitions.stream()
.min(Comparator.nullsLast(Comparator.comparing(acquisition -> XmlTypeConverter.toMillisNullable(acquisition.getTimestamp()))))
.min(Comparator.comparing(
acquisition -> XmlTypeConverter.toMillisNullable(acquisition.getTimestamp()),
Comparator.nullsLast(Comparator.naturalOrder())))
.orElseThrow(() -> new IllegalStateException("No earliest acquisition"));
resultingProvenance.getAcquisition().add(earliest.clone());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@

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

import com.evolveum.midpoint.model.api.correlator.CorrelatorContext;

import com.evolveum.midpoint.model.impl.ModelBeans;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractCorrelatorType;

import org.jetbrains.annotations.NotNull;

import com.evolveum.midpoint.model.api.correlator.CorrelationContext;
Expand All @@ -16,10 +21,43 @@
import com.evolveum.midpoint.util.exception.*;
import com.evolveum.midpoint.util.logging.Trace;

public abstract class BaseCorrelator implements Correlator {
/**
* Abstract superclass for non-trivial built-in correlators.
*
* @param <CCB> correlator configuration bean
*/
public abstract class BaseCorrelator<CCB extends AbstractCorrelatorType> implements Correlator {

private static final String OP_CORRELATE_SUFFIX = ".correlate";

/** Correlator-specific logger. */
@NotNull private final Trace logger;

/** Correlator type name (like "filter", "expression", etc) - for diagnostics purposes. */
@NotNull protected final String typeName;

/** Correlator [instantiation] context. */
@NotNull protected final CorrelatorContext<CCB> correlatorContext;

/** Configuration of the correlator. */
@NotNull protected final CCB configurationBean;

/** Useful beans. */
@NotNull protected final ModelBeans beans;

protected BaseCorrelator(
@NotNull Trace logger,
@NotNull String typeName,
@NotNull CorrelatorContext<CCB> correlatorContext,
@NotNull ModelBeans beans) {
this.logger = logger;
this.typeName = typeName;
this.correlatorContext = correlatorContext;
this.configurationBean = correlatorContext.getConfigurationBean();
this.beans = beans;
logger.trace("Instantiating the correlator with the context:\n{}", correlatorContext.debugDumpLazily(1));
}

@Override
public @NotNull CorrelationResult correlate(
@NotNull CorrelationContext correlationContext, @NotNull OperationResult parentResult)
Expand All @@ -29,11 +67,11 @@ public abstract class BaseCorrelator implements Correlator {
OperationResult result = parentResult.subresult(getClass().getName() + OP_CORRELATE_SUFFIX)
.build();
try {
getLogger().trace("Correlating:\n{}", correlationContext.debugDumpLazily(1));
logger.trace("Correlating:\n{}", correlationContext.debugDumpLazily(1));

CorrelationResult correlationResult = correlateInternal(correlationContext, result);

getLogger().trace("Result:\n{}", correlationResult.debugDumpLazily(1));
logger.trace("Result:\n{}", correlationResult.debugDumpLazily(1));

result.addArbitraryObjectAsReturn("correlationResult", correlationResult);

Expand All @@ -51,5 +89,10 @@ public abstract class BaseCorrelator implements Correlator {
throws ConfigurationException, SchemaException, ExpressionEvaluationException, CommunicationException,
SecurityViolationException, ObjectNotFoundException;

protected abstract Trace getLogger();
protected @NotNull String getDefaultContextDescription(@NotNull CorrelationContext correlationContext) {
return (typeName + " correlator" +
(configurationBean.getName() != null ? " '" + configurationBean.getName() + "'" : ""))
+ " for " + correlationContext.getObjectTypeDefinition().getHumanReadableName()
+ " in " + correlationContext.getResource();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,19 @@
import java.util.Objects;

/**
* TODO
* Composite correlator that evaluates its components (child correlators) and builds up the result
* according to their results.
*
* PRELIMINARY IMPLEMENTATION!
*
* TODO ignore identifiers in owner options
*/
class CompositeCorrelator extends BaseCorrelator {
class CompositeCorrelator extends BaseCorrelator<CompositeCorrelatorType> {

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

/**
* Configuration of the this correlator.
*/
@NotNull private final CorrelatorContext<CompositeCorrelatorType> correlatorContext;

/** Useful beans. */
@NotNull private final ModelBeans beans;

CompositeCorrelator(@NotNull CorrelatorContext<CompositeCorrelatorType> correlatorContext, @NotNull ModelBeans beans) {
this.correlatorContext = correlatorContext;
this.beans = beans;
LOGGER.trace("Instantiated the correlator with the configuration:\n{}", getConfiguration().debugDumpLazily(1));
super(LOGGER, "composite", correlatorContext, beans);
}

@Override
Expand All @@ -55,7 +48,6 @@ class CompositeCorrelator extends BaseCorrelator {
@NotNull OperationResult result)
throws SchemaException, ExpressionEvaluationException, CommunicationException, SecurityViolationException,
ConfigurationException, ObjectNotFoundException {

return new Correlation(correlationContext)
.execute(result);
}
Expand All @@ -64,11 +56,6 @@ class CompositeCorrelator extends BaseCorrelator {
return correlatorContext.getConfigurationBean();
}

@Override
protected Trace getLogger() {
return LOGGER;
}

private class Correlation {

@NotNull private final CorrelationContext correlationContext;
Expand All @@ -81,11 +68,7 @@ private class Correlation {
Correlation(@NotNull CorrelationContext correlationContext) {
this.correlationContext = correlationContext;
this.task = correlationContext.getTask();
this.contextDescription =
("composite correlator" +
(getConfiguration().getName() != null ? " '" + getConfiguration().getName() + "'" : ""))
+ " for " + correlationContext.getObjectTypeDefinition().getHumanReadableName()
+ " in " + correlationContext.getResource();
this.contextDescription = getDefaultContextDescription(correlationContext);
}

public CorrelationResult execute(OperationResult result)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import java.util.List;
import java.util.Objects;

import com.evolveum.midpoint.model.api.correlator.CorrelatorContext;

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

Expand Down Expand Up @@ -45,22 +47,12 @@
* A correlator based on expressions that directly provide focal object(s) (or their references) for given resource object.
* Similar to synchronization sorter, but simpler - it treats only correlation, not the classification part.
*/
class ExpressionCorrelator extends BaseCorrelator {
class ExpressionCorrelator extends BaseCorrelator<ExpressionCorrelatorType> {

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

/**
* Configuration of the correlator.
*/
@NotNull private final ExpressionCorrelatorType configuration;

/** Useful beans. */
@NotNull private final ModelBeans beans;

ExpressionCorrelator(@NotNull ExpressionCorrelatorType configuration, @NotNull ModelBeans beans) {
this.configuration = configuration;
this.beans = beans;
LOGGER.trace("Instantiated the correlator with the configuration:\n{}", configuration.debugDumpLazily(1));
ExpressionCorrelator(@NotNull CorrelatorContext<ExpressionCorrelatorType> correlatorContext, @NotNull ModelBeans beans) {
super(LOGGER, "expression", correlatorContext, beans);
}

@Override
Expand All @@ -74,11 +66,6 @@ class ExpressionCorrelator extends BaseCorrelator {
.execute(result);
}

@Override
protected Trace getLogger() {
return LOGGER;
}

private class Correlation<F extends FocusType> {

@NotNull private final ShadowType resourceObject;
Expand All @@ -92,11 +79,7 @@ private class Correlation<F extends FocusType> {
this.resourceObject = correlationContext.getResourceObject();
this.correlationContext = correlationContext;
this.task = correlationContext.getTask();
this.contextDescription =
("expression correlator" +
(configuration.getName() != null ? " '" + configuration.getName() + "'" : ""))
+ " for " + correlationContext.getObjectTypeDefinition().getHumanReadableName()
+ " in " + correlationContext.getResource();
this.contextDescription = getDefaultContextDescription(correlationContext);
}

public CorrelationResult execute(OperationResult result)
Expand All @@ -112,21 +95,21 @@ public CorrelationResult execute(OperationResult result)

ExpressionType expressionBean;
ItemDefinition<?> outputDefinition;
if (configuration.getOwner() != null) {
if (configuration.getOwnerRef() != null) {
if (configurationBean.getOwner() != null) {
if (configurationBean.getOwnerRef() != null) {
throw new ConfigurationException("Both owner and ownerRef expressions found in " + contextDescription);
}
expressionBean = configuration.getOwner();
expressionBean = configurationBean.getOwner();
outputDefinition =
Objects.requireNonNull(
PrismContext.get().getSchemaRegistry()
.findObjectDefinitionByCompileTimeClass(correlationContext.getFocusType()),
() -> "No definition for focus type " + correlationContext.getFocusType());
} else {
if (configuration.getOwnerRef() == null) {
if (configurationBean.getOwnerRef() == null) {
throw new ConfigurationException("Neither owner nor ownerRef expression found in " + contextDescription);
}
expressionBean = configuration.getOwnerRef();
expressionBean = configurationBean.getOwnerRef();
outputDefinition =
PrismContext.get().definitionFactory().createReferenceDefinition(
ExpressionConstants.OUTPUT_ELEMENT_NAME, ObjectReferenceType.COMPLEX_TYPE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,6 @@ public void register() {
@NotNull CorrelatorContext<ExpressionCorrelatorType> context,
@NotNull Task task,
@NotNull OperationResult result) throws ConfigurationException {
return new ExpressionCorrelator(context.getConfigurationBean(), beans);
return new ExpressionCorrelator(context, beans);
}
}

0 comments on commit 4d49c9e

Please sign in to comment.