Skip to content

Commit

Permalink
New option for LiveSync task: retryLiveSyncErrors
Browse files Browse the repository at this point in the history
  • Loading branch information
martin-lizner committed Feb 18, 2017
1 parent 7de586f commit 321f3cd
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 8 deletions.
Expand Up @@ -23,6 +23,14 @@
<td><wicket:message key="pageTaskEdit.token"/></td>
<td><span wicket:id="token"/> <div wicket:id="deleteToken"/></td>
</tr>
<tr wicket:id="retryUnhandledErrContainer">
<td><wicket:message key="pageTaskEdit.retryUnhandledErr"/></td>
<td>
<label class="col-lg-2 checkbox-inline" wicket:id="retryUnhandledErrCheckboxContainer">
<input type="checkbox" wicket:id="retryUnhandledErrCheckbox">
</label>
</td>
</tr>
</wicket:extend>
</body>
</html>
Expand Up @@ -20,9 +20,11 @@
import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour;
import com.evolveum.midpoint.web.page.admin.server.PageTaskEdit;
import com.evolveum.midpoint.web.page.admin.server.handlers.dto.LiveSyncHandlerDto;
import com.evolveum.midpoint.web.page.admin.server.handlers.dto.ResourceRelatedHandlerDto;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
Expand All @@ -37,7 +39,11 @@ public class LiveSyncHandlerPanel extends ResourceRelatedHandlerPanel<LiveSyncHa
private static final String ID_TOKEN_CONTAINER = "tokenContainer";
private static final String ID_TOKEN = "token";
private static final String ID_DELETE_TOKEN = "deleteToken";


private static final String ID_TOKEN_RETRY_CONTAINER = "retryUnhandledErrContainer";
private static final String ID_TOKEN_RETRY_CHECKBOX_CONTAINER = "retryUnhandledErrCheckboxContainer";
private static final String ID_TOKEN_RETRY_CHECKBOX = "retryUnhandledErrCheckbox";

public LiveSyncHandlerPanel(String id, IModel<LiveSyncHandlerDto> handlerDtoModel, PageTaskEdit parentPage) {
super(id, handlerDtoModel, parentPage);
initLayout(parentPage);
Expand Down Expand Up @@ -68,6 +74,14 @@ public boolean isVisible() {
deleteTokenPanel.setRenderBodyOnly(true);
tokenContainer.add(deleteTokenPanel);
add(tokenContainer);

WebMarkupContainer retryContainer = new WebMarkupContainer(ID_TOKEN_RETRY_CONTAINER);
add(retryContainer);
WebMarkupContainer retryCheckboxContainer = new WebMarkupContainer(ID_TOKEN_RETRY_CHECKBOX_CONTAINER);
retryContainer.add(retryCheckboxContainer);
CheckBox retryCheckbox = new CheckBox(ID_TOKEN_RETRY_CHECKBOX, new PropertyModel<Boolean>(getModel(), ResourceRelatedHandlerDto.F_TOKEN_RETRY_UNHANDLED_ERR));
retryCheckbox.add(enabledIfEdit);
retryCheckboxContainer.add(retryCheckbox);
}

}
Expand Up @@ -85,6 +85,7 @@ public class ResourceRelatedHandlerPanel<D extends ResourceRelatedHandlerDto> ex
private static final String ID_DRY_RUN = "dryRun";

private PageTaskEdit parentPage;
protected VisibleEnableBehaviour enabledIfEdit;

public ResourceRelatedHandlerPanel(String id, IModel<D> handlerDtoModel, PageTaskEdit parentPage) {
super(id, handlerDtoModel);
Expand All @@ -106,7 +107,7 @@ public boolean isVisible() {
return !parentPage.isEdit();
}
};
final VisibleEnableBehaviour enabledIfEdit = new VisibleEnableBehaviour() {
enabledIfEdit = new VisibleEnableBehaviour() {

@Override
public boolean isEnabled() {
Expand Down
Expand Up @@ -41,6 +41,7 @@ public class ResourceRelatedHandlerDto extends HandlerDto implements HandlerDtoE
public static final String F_INTENT = "intent";
public static final String F_OBJECT_CLASS = "objectClass";
public static final String F_RESOURCE_REFERENCE = "resourceRef";
public static final String F_TOKEN_RETRY_UNHANDLED_ERR = "retryUnhandledErr";

private static final String CLASS_DOT = ResourceRelatedHandlerDto.class.getName() + ".";
private static final String OPERATION_LOAD_RESOURCE = CLASS_DOT + "loadResource";
Expand All @@ -53,6 +54,7 @@ public class ResourceRelatedHandlerDto extends HandlerDto implements HandlerDtoE
private String objectClass;
private List<QName> objectClassList;
private TaskAddResourcesDto resourceRef;
private boolean retryUnhandledErr;

private ResourceRelatedHandlerDto(TaskDto taskDto) {
super(taskDto);
Expand Down Expand Up @@ -93,6 +95,13 @@ private void fillFromExtension(TaskType taskType) {
if(objectClassItem != null && objectClassItem.getRealValue() != null){
objectClass = objectClassItem.getRealValue().getLocalPart();
}

PrismProperty<Boolean> retrySyncItem = task.getExtension().findProperty(SchemaConstants.SYNC_TOKEN_RETRY_UNHANDLED);
if (retrySyncItem == null || retrySyncItem.getRealValue() == null) {
retryUnhandledErr = true;
} else {
retryUnhandledErr = retrySyncItem.getRealValue();
}
}

public boolean isDryRun() {
Expand All @@ -102,6 +111,14 @@ public boolean isDryRun() {
public void setDryRun(boolean dryRun) {
this.dryRun = dryRun;
}

public boolean isRetryUnhandledErr() {
return retryUnhandledErr;
}

public void setRetryUnhandledErr(boolean retryUnhandledErr) {
this.retryUnhandledErr = retryUnhandledErr;
}

public String getIntent() {
return intent;
Expand Down Expand Up @@ -198,12 +215,16 @@ public void setResource(TaskAddResourcesDto resource) {
resourceObjectRef.setType(ResourceType.COMPLEX_TYPE);
rv.add(DeltaBuilder.deltaFor(TaskType.class, prismContext)
.item(TaskType.F_OBJECT_REF).replace(resourceObjectRef.asReferenceValue()).asItemDelta());
}

}
if (orig.isDryRun() != curr.isDryRun()) {
addExtensionDelta(rv, SchemaConstants.MODEL_EXTENSION_DRY_RUN, curr.isDryRun(), prismContext);
}

}

if (orig.isRetryUnhandledErr() != curr.isRetryUnhandledErr()) {
addExtensionDelta(rv, SchemaConstants.SYNC_TOKEN_RETRY_UNHANDLED, curr.isRetryUnhandledErr(), prismContext);
}

if (orig.getKind() != curr.getKind()) {
addExtensionDelta(rv, SchemaConstants.MODEL_EXTENSION_KIND, curr.getKind(), prismContext);
}
Expand Down Expand Up @@ -240,6 +261,7 @@ public HandlerDtoEditableState getEditableState() {
public ResourceRelatedHandlerDto clone() {
ResourceRelatedHandlerDto clone = new ResourceRelatedHandlerDto(taskDto);
clone.dryRun = dryRun;
clone.retryUnhandledErr = retryUnhandledErr;
clone.kind = kind;
clone.intent = intent;
clone.objectClass = objectClass;
Expand Down
Expand Up @@ -1944,6 +1944,7 @@ pageTaskEdit.objectType=Object type
pageTaskEdit.objectQuery=Object query
pageTaskEdit.objectRef=Object reference
pageTaskEdit.token=Synchronization token
pageTaskEdit.retryUnhandledErr=Retry unhandled errors
pageTaskEdit.resourceRef=Resource reference
pageTaskEdit.oid=OID
pageTaskEdit.opResult.message=Message
Expand Down
Expand Up @@ -219,6 +219,7 @@ public abstract class SchemaConstants {
public static final String NS_PROVISIONING = NS_MIDPOINT_PUBLIC + "/provisioning";
public static final String NS_PROVISIONING_LIVE_SYNC = NS_PROVISIONING + "/liveSync-3";
public static final QName SYNC_TOKEN = new QName(NS_PROVISIONING_LIVE_SYNC, "token");

// Synchronization constants
public static final String NS_PROVISIONING_CHANNEL = NS_PROVISIONING + "/channels-3";
public static final QName CHANGE_CHANNEL_LIVE_SYNC = new QName(NS_PROVISIONING_CHANNEL, "liveSync");
Expand Down Expand Up @@ -253,6 +254,7 @@ public abstract class SchemaConstants {
NS_MODEL_EXTENSION, "freshnessInterval"); // unused? TODO consider
// removing
public static final QName MODEL_EXTENSION_DRY_RUN = new QName(NS_MODEL_EXTENSION, "dryRun");
public static final QName SYNC_TOKEN_RETRY_UNHANDLED = new QName(NS_MODEL_EXTENSION, "retryLiveSyncErrors");
public static final QName MODEL_EXTENSION_FINISH_OPERATIONS_ONLY = new QName(NS_MODEL_EXTENSION, "finishOperationsOnly");
public static final QName MODEL_EXTENSION_KIND = new QName(NS_MODEL_EXTENSION, "kind");
public static final QName MODEL_EXTENSION_INTENT = new QName(NS_MODEL_EXTENSION, "intent");
Expand Down
Expand Up @@ -81,6 +81,22 @@
</xsd:appinfo>
</xsd:annotation>
</xsd:element>

<xsd:element name="retryLiveSyncErrors" type="xsd:boolean">
<xsd:annotation>
<xsd:documentation>
Indicates if the LiveSync retries non-handled errors in the next run. Handled-errors are always treated as success and never retried.
Retry is implemented by not refreshing LiveSync token to the new value. If set to false, sync token is always refreshed to the last processed entry.
This is true by default.
</xsd:documentation>
<xsd:appinfo>
<a:displayName>Dry run</a:displayName>
<a:displayOrder>800</a:displayOrder>
<a:minOccurs>0</a:minOccurs>
<a:maxOccurs>1</a:maxOccurs>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>

<xsd:element name="finishOperationsOnly" type="xsd:boolean">
<xsd:annotation>
Expand Down
Expand Up @@ -1288,8 +1288,17 @@ public int synchronize(ResourceShadowDiscriminator shadowCoordinates, PrismPrope
continue;
}
boolean isSuccess = processSynchronization(shadowCtx, change, parentResult);

if (isSuccess) {

boolean retryUnhandledError = true;
if (task.getExtension() != null) {
PrismProperty tokenRetryUnhandledErrProperty = task.getExtensionProperty(SchemaConstants.SYNC_TOKEN_RETRY_UNHANDLED);

if (tokenRetryUnhandledErrProperty != null) {
retryUnhandledError = (boolean) tokenRetryUnhandledErrProperty.getRealValue();
}
}

if (!retryUnhandledError || isSuccess) {
// // get updated token from change,
// // create property modification from new token
// // and replace old token with the new one
Expand Down

0 comments on commit 321f3cd

Please sign in to comment.