-
Notifications
You must be signed in to change notification settings - Fork 188
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Start implementing expression profiles PoC
Expression profiles rely upon the reliable and precise determination of the origin of individual expressions - i.e., in which part of which object they were defined. This allows editing of such places by persons that are less experienced or trustworthy than e.g. the root; in exchange for using more restricting profiles for execution of such expressions. However, this problem is harder than one could expect. The complexity stems from various ways in which parts of midPoint configuration are mixed together - links (inheritance, reuse) between resources, object type definitions, object templates, policy rules, correlators, and many more. In the most complex cases (arbitrary object merging) we will have to use the provenance metadata. This commit provides first steps towards the origin determination and propagation throughout the system. The basic concepts are: 1. ConfigurationItemOrigin describing the origin itself. 2. ConfigurationItem that couples the config data with the origin. 3. Typed "configuration items" that facilitate the work with all kinds of configuration data, along with precise and understandable error reporting. Highly experimental for now, though. Other minor changes: - Fixed forgotten InboundMappingUseType#DATA_TRANSFER -> SYNCHRONIZATION - Adapted code to changes in ItemDeltaItem/ObjectDeltaObject (prism 45570df5a1259d94950f572a08da1ae1eb6e8e00) Work in progress.
- Loading branch information
Showing
171 changed files
with
3,280 additions
and
1,618 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
145 changes: 145 additions & 0 deletions
145
infra/schema/src/main/java/com/evolveum/midpoint/schema/config/ConfigurationItem.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
/* | ||
* 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.config; | ||
|
||
import java.io.Serial; | ||
import java.io.Serializable; | ||
import java.util.List; | ||
import java.util.Objects; | ||
|
||
import com.evolveum.midpoint.util.annotation.Experimental; | ||
import com.evolveum.midpoint.util.exception.ConfigurationException; | ||
import com.evolveum.midpoint.util.exception.SystemException; | ||
|
||
import com.google.common.base.Strings; | ||
import org.jetbrains.annotations.Contract; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
import com.evolveum.midpoint.prism.Containerable; | ||
import com.evolveum.midpoint.prism.path.ItemPath; | ||
|
||
/** | ||
* Helper class that provides complex information about a configuration item (e.g., a mapping). | ||
* Currently, the most prominent information is the origin of the item value. | ||
*/ | ||
@Experimental | ||
public class ConfigurationItem<T extends Serializable> implements Serializable { | ||
|
||
@Serial private static final long serialVersionUID = 0L; | ||
|
||
private final @NotNull T value; | ||
private final @NotNull ConfigurationItemOrigin origin; | ||
|
||
/** For internal use. */ | ||
protected ConfigurationItem( | ||
@NotNull ConfigurationItem<T> original) { | ||
this.value = original.value; | ||
this.origin = original.origin; | ||
} | ||
|
||
public ConfigurationItem( | ||
@NotNull T value, | ||
@NotNull ConfigurationItemOrigin origin) { | ||
this.value = value; | ||
this.origin = origin; | ||
} | ||
|
||
public static @NotNull <T extends Serializable> ConfigurationItem<T> of( | ||
@NotNull T item, @NotNull ConfigurationItemOrigin origin) { | ||
return new ConfigurationItem<>(item, origin); | ||
} | ||
|
||
public static @NotNull <T extends Serializable> List<ConfigurationItem<T>> ofListEmbedded(@NotNull List<T> items) { | ||
return ofList(items, OriginProvider.embedded()); | ||
} | ||
|
||
public static @NotNull <T extends Serializable> List<ConfigurationItem<T>> ofList( | ||
@NotNull List<T> items, @NotNull OriginProvider<? super T> originProvider) { | ||
return items.stream() | ||
.map(i -> of(i, originProvider.origin(i))) | ||
.toList(); | ||
} | ||
|
||
public @NotNull T value() { | ||
return value; | ||
} | ||
|
||
public @NotNull ConfigurationItemOrigin origin() { | ||
return origin; | ||
} | ||
|
||
public @NotNull ConfigurationItemOrigin originFor(@NotNull ItemPath path) { | ||
return origin.child(path); | ||
} | ||
|
||
public <C extends Containerable> @NotNull OriginProvider<C> originProviderFor(@NotNull ItemPath path) { | ||
return item -> originFor(path); | ||
} | ||
|
||
public <X extends ConfigurationItem<T>> @NotNull X as(@NotNull Class<X> clazz) { | ||
try { | ||
var constructor = clazz.getDeclaredConstructor(ConfigurationItem.class); | ||
return constructor.newInstance(this); | ||
} catch (Throwable t) { | ||
throw SystemException.unexpected(t, "when converting " + this + " to " + clazz); | ||
} | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
if (obj == this) { | ||
return true; | ||
} | ||
if (obj == null || obj.getClass() != this.getClass()) { | ||
return false; | ||
} | ||
var that = (ConfigurationItem<?>) obj; | ||
return Objects.equals(this.value, that.value) | ||
&& Objects.equals(this.origin, that.origin); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(value, origin); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "ConfigurationItem[" + | ||
"value=" + value + ", " + | ||
"origin=" + origin + ']'; | ||
} | ||
|
||
/** To be overridden in specific subclasses. */ | ||
public @NotNull String localDescription() { | ||
return value.getClass().getSimpleName(); | ||
} | ||
|
||
public @NotNull String fullDescription() { | ||
return localDescription() + " in " + origin.fullDescription(); | ||
} | ||
|
||
/** The last "%s" is filled with full description */ | ||
public void configCheck(boolean value, String template, Object... arguments) throws ConfigurationException { | ||
if (!value) { | ||
Object[] augmentedArguments = new Object[arguments.length + 1]; | ||
System.arraycopy(arguments, 0, augmentedArguments, 0, arguments.length); | ||
augmentedArguments[arguments.length] = fullDescription(); | ||
|
||
throw new ConfigurationException( | ||
Strings.lenientFormat(template, augmentedArguments)); | ||
} | ||
} | ||
|
||
@Contract("null, _, _ -> fail") | ||
public <V> @NotNull V configNonNull(V value, String template, Object... arguments) throws ConfigurationException { | ||
configCheck(value != null, template, arguments); | ||
assert value != null; | ||
return value; | ||
} | ||
} |
Oops, something went wrong.