Skip to content

Commit

Permalink
Consistency update, part 2 (Work in progress)
Browse files Browse the repository at this point in the history
  • Loading branch information
semancik committed Jul 18, 2018
1 parent a2f112c commit ed442ff
Show file tree
Hide file tree
Showing 31 changed files with 971 additions and 396 deletions.
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2015 Evolveum
* Copyright (c) 2010-2018 Evolveum
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -60,8 +60,8 @@ public PropertyDelta(QName name, PrismPropertyDefinition<T> propertyDefinition,
super(name, propertyDefinition, prismContext);
}

public PropertyDelta(ItemPath parentPath, QName name, PrismPropertyDefinition<T> propertyDefinition, PrismContext prismContext) {
super(parentPath, name, propertyDefinition, prismContext);
public PropertyDelta(ItemPath itemPath, QName name, PrismPropertyDefinition<T> propertyDefinition, PrismContext prismContext) {
super(itemPath, name, propertyDefinition, prismContext);
}

public PropertyDelta(ItemPath propertyPath, PrismPropertyDefinition<T> propertyDefinition, PrismContext prismContext) {
Expand Down
Expand Up @@ -6032,9 +6032,11 @@
<xsd:documentation>
Postpone the operation in case that an error is encountered. The operation
will be re-tried later (consistency mechanism).
DEPRECATED. Use operationRetryMaxAttempts instead.
</xsd:documentation>
<xsd:appinfo>
<a:deprecated>true</a:deprecated>
<a:plannedRemoval>4.0</a:plannedRemoval>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
Expand Down Expand Up @@ -6074,6 +6076,27 @@
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="operationRetryPeriod" type="xsd:duration" minOccurs="0" default="PT30M">
<xsd:annotation>
<xsd:documentation>
Duration for which the system will wait before re-trying failed operation.
</xsd:documentation>
<xsd:appinfo>
<a:since>3.9</a:since>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="operationRetryMaxAttempts" type="xsd:int" minOccurs="0" default="3">
<xsd:annotation>
<xsd:documentation>
Maximum number of attempts to re-try a failed operation.
If set to 0 then operation re-tries are disabled.
</xsd:documentation>
<xsd:appinfo>
<a:since>3.9</a:since>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:long" use="optional"/>
</xsd:complexType>
Expand Down
Expand Up @@ -5015,17 +5015,6 @@ protected UserValuePolicyOriginResolver createUserOriginResolver(PrismObject<Use
return new UserValuePolicyOriginResolver(user, modelObjectResolver);
}

protected XMLGregorianCalendar getTimestamp(String duration) {
return XmlTypeConverter.addDuration(clock.currentTimeXMLGregorianCalendar(), duration);
}

protected void clockForward(String duration) {
XMLGregorianCalendar before = clock.currentTimeXMLGregorianCalendar();
clock.overrideDuration(duration);
XMLGregorianCalendar after = clock.currentTimeXMLGregorianCalendar();
display("Clock going forward", before + " --[" + duration + "]--> " + after);
}

protected List<PrismObject<TaskType>> getTasksForObject(String oid, QName type,
Collection<SelectorOptions<GetOperationOptions>> options, Task task, OperationResult result)
throws CommunicationException, ObjectNotFoundException, SchemaException, SecurityViolationException,
Expand Down
Expand Up @@ -15,12 +15,18 @@
*/
package com.evolveum.midpoint.provisioning.impl;

import java.util.ArrayList;
import java.util.List;

import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.schema.result.AsynchronousOperationResult;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.result.OperationResultStatus;
import com.evolveum.midpoint.util.ShortDumpable;
import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultStatusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.PendingOperationExecutionStatusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.PendingOperationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;

/**
* @author semancik
Expand All @@ -30,8 +36,9 @@ public class ProvisioningOperationState<A extends AsynchronousOperationResult> i

private A asyncResult;
private PendingOperationExecutionStatusType executionStatus;
private String existingShadowOid;
private PrismObject<ShadowType> repoShadow;
private Integer attemptNumber;
private List<PendingOperationType> pendingOperations;

public A getAsyncResult() {
return asyncResult;
Expand All @@ -49,12 +56,27 @@ public void setExecutionStatus(PendingOperationExecutionStatusType executionStat
this.executionStatus = executionStatus;
}

public String getExistingShadowOid() {
return existingShadowOid;
public PrismObject<ShadowType> getRepoShadow() {
return repoShadow;
}

public void setRepoShadow(PrismObject<ShadowType> repoShadow) {
this.repoShadow = repoShadow;
}

public List<PendingOperationType> getPendingOperations() {
return pendingOperations;
}

public boolean hasPendingOperations() {
return pendingOperations != null;
}

public void setExistingShadowOid(String existingShadowOid) {
this.existingShadowOid = existingShadowOid;
public void addPendingOperation(PendingOperationType pendingOperation) {
if (pendingOperations == null) {
pendingOperations = new ArrayList<>();
}
pendingOperations.add(pendingOperation);
}

public Integer getAttemptNumber() {
Expand Down Expand Up @@ -125,7 +147,7 @@ public void processAsyncResult(A asyncReturnValue) {
@Override
public String toString() {
return "ProvisioningOperationState(asyncResult=" + asyncResult + ", executionStatus="
+ executionStatus + ", existingShadowOid=" + existingShadowOid + ", attemptNumber="+attemptNumber+")";
+ executionStatus + ", repoShadow=" + repoShadow + ", attemptNumber="+attemptNumber+")";
}

@Override
Expand All @@ -134,8 +156,11 @@ public void shortDump(StringBuilder sb) {
if (attemptNumber != null) {
sb.append(", attempt #").append(attemptNumber);
}
if (pendingOperations != null) {
sb.append(", ").append(pendingOperations.size()).append(" pending operations");
}
if (asyncResult != null) {
sb.append(":");
sb.append(", result=");
asyncResult.shortDump(sb);
}
}
Expand All @@ -157,5 +182,28 @@ public void determineExecutionStatusFromResult() {
executionStatus = PendingOperationExecutionStatusType.COMPLETED;
}
}

// TEMPORARY: TODO: remove
public static <A extends AsynchronousOperationResult> ProvisioningOperationState<A> fromPendingOperation(
PrismObject<ShadowType> repoShadow, PendingOperationType pendingOperation) {
List<PendingOperationType> pendingOperations = new ArrayList<>();
pendingOperations.add(pendingOperation);
return fromPendingOperations(repoShadow, pendingOperations);
}

public static <A extends AsynchronousOperationResult> ProvisioningOperationState<A> fromPendingOperations(
PrismObject<ShadowType> repoShadow, List<PendingOperationType> pendingOperations) {
ProvisioningOperationState<A> opState = new ProvisioningOperationState<>();
if (pendingOperations == null || pendingOperations.isEmpty()) {
throw new IllegalArgumentException("Empty list of pending operations, cannot create ProvisioningOperationState");
}
opState.pendingOperations = pendingOperations;
// TODO: check that they have the same status
opState.executionStatus = pendingOperations.get(0).getExecutionStatus();
// TODO: better algorithm
opState.attemptNumber = pendingOperations.get(0).getAttemptNumber();
opState.repoShadow = repoShadow;
return opState;
}

}
Expand Up @@ -867,17 +867,9 @@ public void refreshShadow(PrismObject<ShadowType> shadow, ProvisioningOperationO

try {

// TODO: RECON RECON RECON mode
shadowCache.refreshShadow(shadow, task, result);

refreshShadowLegacy(shadow, options, task, result);

} catch (GenericFrameworkException e) {
ProvisioningUtil.recordFatalError(LOGGER, result, "Couldn't refresh shadow: " + e.getClass().getSimpleName() + ": "+ e.getMessage(), e);
throw new CommunicationException(e.getMessage(), e);

} catch (CommunicationException | SchemaException | ObjectNotFoundException | ConfigurationException
| SecurityViolationException | ObjectAlreadyExistsException | ExpressionEvaluationException | RuntimeException | Error e) {
} catch (CommunicationException | SchemaException | ObjectNotFoundException | ConfigurationException | ExpressionEvaluationException | RuntimeException | Error e) {
ProvisioningUtil.recordFatalError(LOGGER, result, "Couldn't refresh shadow: " + e.getClass().getSimpleName() + ": "+ e.getMessage(), e);
throw e;

Expand All @@ -892,28 +884,6 @@ public void refreshShadow(PrismObject<ShadowType> shadow, ProvisioningOperationO
LOGGER.debug("Finished refreshing shadow {}: {}", shadow, result);
}

private void refreshShadowLegacy(PrismObject<ShadowType> shadow, ProvisioningOperationOptions options, Task task, OperationResult result)
throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException,
ObjectAlreadyExistsException, SecurityViolationException, GenericFrameworkException, ExpressionEvaluationException, EncryptionException {

ShadowType shadowType = shadow.asObjectable();

// TODO: RECON RECON RECON mode

if (shadowType.getFailedOperationType() == null) {
return;
} else if (FailedOperationTypeType.ADD == shadowType.getFailedOperationType()) {
shadowCache.addShadow(shadow, null, null, options, task, result);
} else if (FailedOperationTypeType.MODIFY == shadowType.getFailedOperationType()) {
shadowCache.modifyShadow(shadow, new ArrayList<>(), null, options, task, result);
} else if (FailedOperationTypeType.DELETE == shadowType.getFailedOperationType()) {
shadowCache.deleteShadow(shadow, options, null, task, result);
} else {
result.recordWarning("Missing or unknown type of operation to finish: " + shadowType.getFailedOperationType());
}

}

// TODO: move to ResourceManager and ConnectorManager
// the shadow-related code is already in the ShadowCache
private <T extends ObjectType> boolean handleRepoObject(final Class<T> type, PrismObject<T> object,
Expand Down

0 comments on commit ed442ff

Please sign in to comment.