Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
skublik committed Aug 26, 2021
2 parents 8f1c709 + 228ce78 commit 23442a4
Show file tree
Hide file tree
Showing 68 changed files with 1,985 additions and 1,561 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;

Expand All @@ -19,7 +20,6 @@
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.delta.PropertyDelta;
import com.evolveum.midpoint.prism.delta.builder.S_MaybeDelete;
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition;
Expand All @@ -30,118 +30,106 @@
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

import org.jetbrains.annotations.NotNull;

public class SynchronizationUtils {

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

private static PropertyDelta<SynchronizationSituationType> createSynchronizationSituationDelta(
PrismObject<ShadowType> shadow, SynchronizationSituationType situation,
PrismContext prismContext) {
PrismObject<ShadowType> shadow, SynchronizationSituationType situation) {

if (situation == null) {
SynchronizationSituationType oldValue = shadow.asObjectable().getSynchronizationSituation();
return prismContext.deltaFactory().property().createModificationDeleteProperty(ShadowType.F_SYNCHRONIZATION_SITUATION, shadow.getDefinition(), oldValue);
return PrismContext.get().deltaFactory().property()
.createModificationDeleteProperty(ShadowType.F_SYNCHRONIZATION_SITUATION, shadow.getDefinition(), oldValue);
} else {
return PrismContext.get().deltaFactory().property()
.createModificationReplaceProperty(ShadowType.F_SYNCHRONIZATION_SITUATION, shadow.getDefinition(), situation);
}

return prismContext.deltaFactory().property().createModificationReplaceProperty(ShadowType.F_SYNCHRONIZATION_SITUATION, shadow.getDefinition(), situation);
}

private static PropertyDelta<XMLGregorianCalendar> createSynchronizationTimestampDelta(PrismObject<ShadowType> object,
QName propName, XMLGregorianCalendar timestamp, PrismContext prismContext) {
PropertyDelta<XMLGregorianCalendar> syncSituationDelta = prismContext.deltaFactory().property()
QName propName, XMLGregorianCalendar timestamp) {
return PrismContext.get().deltaFactory().property()
.createReplaceDelta(object.getDefinition(), propName, timestamp);
return syncSituationDelta;
}

public static List<PropertyDelta<?>> createSynchronizationSituationAndDescriptionDelta(PrismObject<ShadowType> shadow,
SynchronizationSituationType situation, String sourceChannel, boolean full, XMLGregorianCalendar timestamp,
PrismContext prismContext) throws SchemaException {
SynchronizationSituationType situation, String sourceChannel, boolean full, XMLGregorianCalendar timestamp)
throws SchemaException {

List<PropertyDelta<?>> propertyDeltas = new ArrayList<>();

PropertyDelta<SynchronizationSituationDescriptionType> syncDescriptionDelta = createSynchronizationSituationDescriptionDelta(shadow, situation,
timestamp, sourceChannel, full, prismContext);
propertyDeltas.add(syncDescriptionDelta);

propertyDeltas.addAll(createSynchronizationTimestampsDelta(shadow, timestamp, full, prismContext));

PropertyDelta<SynchronizationSituationType> syncSituationDelta = createSynchronizationSituationDelta(shadow, situation, prismContext);
propertyDeltas.add(syncSituationDelta);
propertyDeltas.add(
createSynchronizationSituationDescriptionDelta(shadow, situation, timestamp, sourceChannel, full));
propertyDeltas.addAll(createSynchronizationTimestampsDeltas(shadow, timestamp, full));
propertyDeltas.add(createSynchronizationSituationDelta(shadow, situation));

return propertyDeltas;
}

private static PropertyDelta<SynchronizationSituationDescriptionType> createSynchronizationSituationDescriptionDelta(
PrismObject<ShadowType> shadow,
SynchronizationSituationType situation, XMLGregorianCalendar timestamp, String sourceChannel,
boolean full, PrismContext prismContext) throws SchemaException {
SynchronizationSituationDescriptionType syncSituationDescription = new SynchronizationSituationDescriptionType();
syncSituationDescription.setSituation(situation);
syncSituationDescription.setChannel(sourceChannel);
syncSituationDescription.setTimestamp(timestamp);
syncSituationDescription.setFull(full);

S_MaybeDelete builder = prismContext.deltaFor(ShadowType.class)
.item(ShadowType.F_SYNCHRONIZATION_SITUATION_DESCRIPTION).add(syncSituationDescription);

List<SynchronizationSituationDescriptionType> oldSituationDescriptions = getSituationFromSameChannel(
shadow, sourceChannel);
if (CollectionUtils.isNotEmpty(oldSituationDescriptions)) {
builder.deleteRealValues(oldSituationDescriptions);
}

return (PropertyDelta<SynchronizationSituationDescriptionType>) builder.asItemDelta();
PrismObject<ShadowType> shadow, SynchronizationSituationType situation, XMLGregorianCalendar timestamp,
String sourceChannel, boolean full) throws SchemaException {

SynchronizationSituationDescriptionType descriptionToAdd = new SynchronizationSituationDescriptionType();
descriptionToAdd.setSituation(situation);
descriptionToAdd.setChannel(sourceChannel);
descriptionToAdd.setTimestamp(timestamp);
descriptionToAdd.setFull(full);

List<SynchronizationSituationDescriptionType> descriptionsToDelete =
getDescriptionsFromSameChannel(shadow, sourceChannel);

//noinspection unchecked
return (PropertyDelta<SynchronizationSituationDescriptionType>) PrismContext.get().deltaFor(ShadowType.class)
.item(ShadowType.F_SYNCHRONIZATION_SITUATION_DESCRIPTION)
.deleteRealValues(descriptionsToDelete)
.add(descriptionToAdd)
.asItemDelta();
}

public static List<PropertyDelta<?>> createSynchronizationTimestampsDelta(
PrismObject<ShadowType> shadow, PrismContext prismContext) {
XMLGregorianCalendar timestamp = XmlTypeConverter
.createXMLGregorianCalendar(System.currentTimeMillis());
return createSynchronizationTimestampsDelta(shadow, timestamp, true, prismContext);
public static List<PropertyDelta<?>> createSynchronizationTimestampsDeltas(PrismObject<ShadowType> shadow) {
return createSynchronizationTimestampsDeltas(
shadow,
XmlTypeConverter.createXMLGregorianCalendar(),
true);
}

private static List<PropertyDelta<?>> createSynchronizationTimestampsDelta(PrismObject<ShadowType> shadow,
XMLGregorianCalendar timestamp, boolean full, PrismContext prismContext) {
private static List<PropertyDelta<?>> createSynchronizationTimestampsDeltas(PrismObject<ShadowType> shadow,
XMLGregorianCalendar timestamp, boolean full) {

List<PropertyDelta<?>> deltas = new ArrayList<>();
PropertyDelta<XMLGregorianCalendar> timestampDelta = createSynchronizationTimestampDelta(shadow,
ShadowType.F_SYNCHRONIZATION_TIMESTAMP, timestamp, prismContext);
deltas.add(timestampDelta);

deltas.add(createSynchronizationTimestampDelta(shadow, ShadowType.F_SYNCHRONIZATION_TIMESTAMP, timestamp));
if (full) {
timestampDelta = createSynchronizationTimestampDelta(shadow,
ShadowType.F_FULL_SYNCHRONIZATION_TIMESTAMP, timestamp, prismContext);
deltas.add(timestampDelta);
deltas.add(createSynchronizationTimestampDelta(shadow, ShadowType.F_FULL_SYNCHRONIZATION_TIMESTAMP, timestamp));
}
return deltas;
}

private static List<SynchronizationSituationDescriptionType> getSituationFromSameChannel(
private static @NotNull List<SynchronizationSituationDescriptionType> getDescriptionsFromSameChannel(
PrismObject<ShadowType> shadow, String channel) {

List<SynchronizationSituationDescriptionType> syncSituationDescriptions = shadow.asObjectable().getSynchronizationSituationDescription();
List<SynchronizationSituationDescriptionType> valuesToDelete = new ArrayList<>();
if (CollectionUtils.isEmpty(syncSituationDescriptions)) {
return null;
}
for (SynchronizationSituationDescriptionType syncSituationDescription : syncSituationDescriptions) {
if (StringUtils.isEmpty(syncSituationDescription.getChannel()) && StringUtils.isEmpty(channel)) {
valuesToDelete.add(syncSituationDescription);
continue;
}
if ((StringUtils.isEmpty(syncSituationDescription.getChannel()) && channel != null)
|| (StringUtils.isEmpty(channel) && syncSituationDescription.getChannel() != null)) {
continue;
}
if (syncSituationDescription.getChannel().equals(channel)) {
valuesToDelete.add(syncSituationDescription);
continue;
}
List<SynchronizationSituationDescriptionType> existingDescriptions =
shadow.asObjectable().getSynchronizationSituationDescription();

return existingDescriptions.stream()
.filter(description -> isSameChannel(description.getChannel(), channel))
.collect(Collectors.toList());
}

private static boolean isSameChannel(String ch1, String ch2) {
if (StringUtils.isEmpty(ch1)) {
return StringUtils.isEmpty(ch2);
} else {
return ch1.equals(ch2);
}
return valuesToDelete;
}

public static boolean isPolicyApplicable(QName objectClass, ShadowKindType kind, String intent, ObjectSynchronizationType synchronizationPolicy, PrismObject<ResourceType> resource, boolean strictIntent) throws SchemaException {
public static boolean isPolicyApplicable(QName objectClass, ShadowKindType kind, String intent,
ObjectSynchronizationType synchronizationPolicy, PrismObject<ResourceType> resource, boolean strictIntent)
throws SchemaException {

List<QName> policyObjectClasses = synchronizationPolicy.getObjectClass();
//check objectClass if match
Expand All @@ -163,7 +151,7 @@ public static boolean isPolicyApplicable(QName objectClass, ShadowKindType kind,

String policyIntent = synchronizationPolicy.getIntent();

ObjectClassComplexTypeDefinition policyObjectClass = null;
ObjectClassComplexTypeDefinition policyObjectClass;
if (StringUtils.isEmpty(policyIntent)) {
policyObjectClass = schema.findDefaultObjectClassDefinition(policyKind);
if (policyObjectClass != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16667,13 +16667,26 @@
<xsd:enumeration value="exception">
<xsd:annotation>
<xsd:documentation>
Errors are indicated as exceptions.
Errors are indicated as exceptions. (Unless handled by an error handler.)
</xsd:documentation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="EXCEPTION"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="forcedException">
<xsd:annotation>
<xsd:documentation>
Errors are indicated as exceptions. "Object not found" error handler is disabled.
Currently all the other ones are kept enabled. This is because we always need the
processing of e.g. communication exceptions. We are only interested in skipping handling
"object not found" cases. (Maybe the name of this option should be changed.)
</xsd:documentation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="FORCED_EXCEPTION"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="fetchResult">
<xsd:annotation>
<xsd:documentation>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2211,6 +2211,13 @@
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="monitoring" type="tns:ActivityMonitoringDefinitionType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
How the activity is monitored, e.g. using tracing or dynamic profiling.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:long"/>
</xsd:complexType>
Expand Down Expand Up @@ -7052,10 +7059,17 @@
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="policyRules" type="tns:ActivityCounterGroupType" minOccurs="0">
<xsd:element name="simulationModePolicyRules" type="tns:ActivityCounterGroupType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Counters for policy rules in simulation mode.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="executionModePolicyRules" type="tns:ActivityCounterGroupType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Counters for policy rules.
Counters for policy rules in execution mode.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.ShadowUtil;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.task.api.TaskUtil;
import com.evolveum.midpoint.util.QNameUtil;
import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
Expand Down Expand Up @@ -423,7 +424,7 @@ private void updateSituationInShadow(SynchronizationSituationType newSituation,
XMLGregorianCalendar now = clock.currentTimeXMLGregorianCalendar();
List<PropertyDelta<?>> syncSituationDeltas = SynchronizationUtils
.createSynchronizationSituationAndDescriptionDelta(currentShadow, newSituation, task.getChannel(),
projCtx.hasFullShadow(), now, prismContext);
projCtx.hasFullShadow() && TaskUtil.isExecute(task), now);

try {
ModelImplUtils.setRequestee(task, focusContext);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,16 @@
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentHolderType;

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

import org.springframework.stereotype.Component;

import javax.xml.datatype.XMLGregorianCalendar;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.evolveum.midpoint.task.api.ExecutionSupport.CountersGroup.POLICY_RULES;
import static com.evolveum.midpoint.task.api.ExecutionSupport.CountersGroup.*;

/**
* Updates counters for policy rules, with the goal of determining if rules' thresholds have been reached.
Expand Down Expand Up @@ -91,8 +93,12 @@ public <AH extends AssignmentHolderType> void updateCounters(LensContext<AH> con
Map<String, EvaluatedPolicyRule> rulesByIdentifier = rulesToIncrement.stream()
.collect(Collectors.toMap(EvaluatedPolicyRule::getPolicyRuleIdentifier, Function.identity()));

ExecutionSupport.CountersGroup group =
executionSupport.getExecutionMode() == ExecutionModeType.EXECUTE ?
EXECUTION_MODE_POLICY_RULES : SIMULATION_MODE_POLICY_RULES;

Map<String, Integer> currentValues =
executionSupport.incrementCounters(POLICY_RULES, rulesByIdentifier.keySet(), result);
executionSupport.incrementCounters(group, rulesByIdentifier.keySet(), result);

currentValues.forEach((id, value) -> {
rulesByIdentifier.get(id).setCount(value);
Expand Down

0 comments on commit 23442a4

Please sign in to comment.