use of com.evolveum.midpoint.provisioning.api.LiveSyncToken in project midpoint by Evolveum.
the class LiveSynchronizer method updateTokenValue.
private void updateTokenValue(LiveSyncCtx ctx, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, ConfigurationException, CommunicationException, ObjectAlreadyExistsException {
LiveSyncCapabilityType capability = ctx.context.getEffectiveCapability(LiveSyncCapabilityType.class);
boolean preciseTokenValue = capability != null && isTrue(capability.isPreciseTokenValue());
boolean isDryRun = ctx.isDryRun();
boolean updateTokenInDryRun = ctx.isUpdateLiveSyncTokenInDryRun();
LiveSyncToken initialToken = ctx.getInitialToken();
LiveSyncToken oldestTokenProcessed = ctx.oldestTokenWatcher.getOldestTokenProcessed();
LOGGER.trace("oldestTokenProcessed = {}, synchronization result = {}", oldestTokenProcessed, ctx.syncResult);
LiveSyncToken tokenToSet;
if (ctx.isPreview()) {
LOGGER.trace("Preview mode -> token will not be updated.");
tokenToSet = null;
} else if (isDryRun && !updateTokenInDryRun) {
LOGGER.trace("Dry run mode with updateTokenInDryRun=false -> token will not be updated.");
tokenToSet = null;
} else if (ctx.canRun() && ctx.syncResult.isAllChangesFetched() && ctx.syncResult.isAllFetchedChangesProcessed()) {
tokenToSet = ctx.finalToken != null ? ctx.finalToken : oldestTokenProcessed;
LOGGER.trace("All changes fetched and processed (positively acknowledged). " + "Task is not suspended. Updating token to {}", tokenToSet);
// Note that it is theoretically possible that tokenToSet is null here: it happens when no changes are fetched from
// the resource and the connector returns null from .sync() method. But in this case nothing wrong happens: the
// token in task will simply stay as it is. That's the correct behavior for such a case.
} else if (preciseTokenValue) {
LOGGER.trace("Processing is not complete but we can count on precise token values.");
tokenToSet = oldestTokenProcessed;
LOGGER.info("Capability of providing precise token values is present. Token in task is updated so the processing will " + "continue where it was stopped. New token value is '{}' (initial value was '{}')", SchemaDebugUtil.prettyPrint(tokenToSet), SchemaDebugUtil.prettyPrint(initialToken));
} else {
LOGGER.trace("Processing is not complete and we cannot count on precise token values. So we'll not update the token");
tokenToSet = null;
LOGGER.info("Capability of providing precise token values is NOT present. Token will not be updated so the " + "processing will restart from the beginning at next task run. So token value stays as it was: '{}'", SchemaDebugUtil.prettyPrint(initialToken));
}
if (tokenToSet != null) {
LOGGER.trace("Setting token value of {}", SchemaDebugUtil.prettyPrintLazily(tokenToSet));
ctx.tokenStorage.setToken(tokenToSet, result);
ctx.syncResult.setTokenUpdatedTo(tokenToSet);
}
}
use of com.evolveum.midpoint.provisioning.api.LiveSyncToken in project midpoint by Evolveum.
the class OldestTokenWatcher method getOldestTokenProcessed.
synchronized LiveSyncToken getOldestTokenProcessed() {
Iterator<Map.Entry<Integer, TokenInfo>> iterator = tokenInfoMap.entrySet().iterator();
Map.Entry<Integer, TokenInfo> first = iterator.hasNext() ? iterator.next() : null;
if (first != null && first.getValue().processed) {
LiveSyncToken token = first.getValue().token;
if (token == null) {
// This is quite unfortunate situation. It should not occur in any reasonable conditions.
LOGGER.warn("Restart point is a null token!");
dumpTokenInfoMap();
}
LOGGER.trace("Oldest token processed: {}", token);
return token;
} else {
return null;
}
}
use of com.evolveum.midpoint.provisioning.api.LiveSyncToken in project midpoint by Evolveum.
the class ResourceObjectConverter method fetchChanges.
public UcfFetchChangesResult fetchChanges(ProvisioningContext ctx, @NotNull LiveSyncToken initialToken, @Nullable Integer maxChangesConfigured, ResourceObjectLiveSyncChangeListener outerListener, OperationResult gResult) throws SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, GenericFrameworkException, ObjectNotFoundException, ExpressionEvaluationException {
LOGGER.trace("START fetch changes from {}, objectClass: {}", initialToken, ctx.getObjectClassDefinition());
AttributesToReturn attrsToReturn;
if (ctx.isWildcard()) {
attrsToReturn = null;
} else {
attrsToReturn = ProvisioningUtil.createAttributesToReturn(ctx);
}
ConnectorInstance connector = ctx.getConnector(LiveSyncCapabilityType.class, gResult);
Integer maxChanges = getMaxChanges(maxChangesConfigured, ctx);
AtomicInteger processed = new AtomicInteger(0);
UcfLiveSyncChangeListener localListener = (ucfChange, lParentResult) -> {
int changeNumber = processed.getAndIncrement();
Task task = ctx.getTask();
OperationResult lResult = lParentResult.subresult(OPERATION_HANDLE_CHANGE).setMinor().addParam("number", changeNumber).addParam("localSequenceNumber", ucfChange.getLocalSequenceNumber()).addArbitraryObjectAsParam("primaryIdentifier", ucfChange.getPrimaryIdentifierRealValue()).addArbitraryObjectAsParam("token", ucfChange.getToken()).build();
try {
ResourceObjectLiveSyncChange change = new ResourceObjectLiveSyncChange(ucfChange, null, ResourceObjectConverter.this, ctx, attrsToReturn);
change.initialize(task, lResult);
return outerListener.onChange(change, lResult);
} catch (Throwable t) {
lResult.recordFatalError(t);
throw t;
} finally {
lResult.computeStatusIfUnknown();
}
};
// get changes from the connector
UcfFetchChangesResult fetchChangesResult = connector.fetchChanges(ctx.getObjectDefinition(), TokenUtil.toUcf(initialToken), attrsToReturn, maxChanges, ctx.getUcfExecutionContext(), localListener, gResult);
computeResultStatus(gResult);
LOGGER.trace("END fetch changes ({} changes); interrupted = {}; all fetched = {}, final token = {}", processed.get(), !ctx.canRun(), fetchChangesResult.isAllChangesFetched(), fetchChangesResult.getFinalToken());
return fetchChangesResult;
}
Aggregations