use of com.evolveum.midpoint.provisioning.api.LiveSyncEvent in project midpoint by Evolveum.
the class MockLiveSyncTaskHandler method synchronize.
public void synchronize(ResourceShadowDiscriminator coords, LiveSyncTokenStorage tokenStorage, Task task, OperationResult result) throws ObjectNotFoundException, CommunicationException, SchemaException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException, PolicyViolationException, PreconditionViolationException {
provisioningService.synchronize(coords, null, tokenStorage, new LiveSyncEventHandler() {
@Override
public boolean handle(LiveSyncEvent event, OperationResult hResult) {
if (event.isComplete()) {
syncServiceMock.notifyChange(event.getChangeDescription(), task, hResult);
event.acknowledge(true, hResult);
return true;
} else if (event.isNotApplicable()) {
hResult.recordNotApplicable();
event.acknowledge(true, hResult);
return true;
} else {
// TODO
LOGGER.error("Event is not complete:\n{}", event.debugDump());
event.acknowledge(false, hResult);
return false;
}
}
@Override
public void allEventsSubmitted(OperationResult result) {
}
}, task, result);
}
use of com.evolveum.midpoint.provisioning.api.LiveSyncEvent in project midpoint by Evolveum.
the class LiveSynchronizer method synchronize.
@NotNull
public SynchronizationOperationResult synchronize(ResourceShadowDiscriminator shadowCoordinates, LiveSyncOptions options, LiveSyncTokenStorage tokenStorage, LiveSyncEventHandler handler, Task task, OperationResult gResult) throws ObjectNotFoundException, CommunicationException, GenericFrameworkException, SchemaException, ConfigurationException, SecurityViolationException, ObjectAlreadyExistsException, ExpressionEvaluationException {
LiveSyncCtx ctx = new LiveSyncCtx(shadowCoordinates, task, options, tokenStorage, gResult);
InternalMonitor.recordCount(InternalCounters.PROVISIONING_ALL_EXT_OPERATION_COUNT);
setupInitialToken(ctx);
if (!ctx.hasInitialToken()) {
// see comment in the called method
fetchAndRememberCurrentToken(ctx, gResult);
return ctx.syncResult;
}
IndividualEventsAcknowledgeGate<LiveSyncEvent> acknowledgeGate = new IndividualEventsAcknowledgeGate<>();
ResourceObjectLiveSyncChangeListener listener = (resourceObjectChange, lResult) -> {
int sequentialNumber = ctx.oldestTokenWatcher.changeArrived(resourceObjectChange.getToken());
ShadowedLiveSyncChange change = new ShadowedLiveSyncChange(resourceObjectChange, beans);
change.initialize(task, lResult);
LiveSyncEvent event = new LiveSyncEventImpl(change) {
@Override
public void acknowledge(boolean release, OperationResult aResult) {
LOGGER.trace("Acknowledgement (release={}) sent for {}", release, this);
if (release) {
ctx.oldestTokenWatcher.changeProcessed(sequentialNumber);
}
acknowledgeGate.acknowledgeIssuedEvent(this);
}
};
acknowledgeGate.registerIssuedEvent(event);
try {
return handler.handle(event, lResult);
} catch (Throwable t) {
// We assume the event was not acknowledged yet. Note that serious handler should never throw an exception!
LoggingUtils.logUnexpectedException(LOGGER, "Got unexpected exception while handling a live sync event", t);
acknowledgeGate.acknowledgeIssuedEvent(event);
return false;
}
};
UcfFetchChangesResult fetchChangesResult;
try {
fetchChangesResult = resourceObjectConverter.fetchChanges(ctx.context, ctx.getInitialToken(), ctx.getBatchSize(), listener, gResult);
} finally {
handler.allEventsSubmitted(gResult);
}
if (fetchChangesResult.isAllChangesFetched()) {
ctx.syncResult.setAllChangesFetched();
ctx.finalToken = TokenUtil.fromUcf(fetchChangesResult.getFinalToken());
}
acknowledgeGate.waitForIssuedEventsAcknowledge(gResult);
if (ctx.oldestTokenWatcher.isEverythingProcessed()) {
ctx.syncResult.setAllFetchedChangesProcessed();
}
updateTokenValue(ctx, gResult);
return ctx.syncResult;
}
use of com.evolveum.midpoint.provisioning.api.LiveSyncEvent in project midpoint by Evolveum.
the class TestDummyNegative method test270LiveSyncBrokenAccountsExternalUid.
@Test
public void test270LiveSyncBrokenAccountsExternalUid() throws Exception {
given();
Task task = getTestTask();
OperationResult result = task.getResult();
DummyTokenStorageImpl tokenStorage = new DummyTokenStorageImpl();
cleanupAccounts(RESOURCE_DUMMY_BROKEN_ACCOUNTS_EXTERNAL_UID, result);
RESOURCE_DUMMY_BROKEN_ACCOUNTS_EXTERNAL_UID.controller.setSyncStyle(DummySyncStyle.SMART);
ResourceShadowDiscriminator coords = new ResourceShadowDiscriminator(RESOURCE_DUMMY_BROKEN_ACCOUNTS_EXTERNAL_UID.oid, SchemaConstants.RI_ACCOUNT_OBJECT_CLASS);
List<LiveSyncEvent> events = new ArrayList<>();
LiveSyncEventHandler handler = new LiveSyncEventHandler() {
@Override
public void allEventsSubmitted(OperationResult result) {
}
@Override
public boolean handle(LiveSyncEvent event, OperationResult opResult) {
events.add(event);
event.acknowledge(true, opResult);
return true;
}
};
provisioningService.synchronize(coords, null, tokenStorage, handler, task, result);
assertThat(events).isEmpty();
createAccountExternalUid(GOOD_ACCOUNT, 1, null);
createAccountExternalUid(INCONVERTIBLE_ACCOUNT, 2, "WRONG");
createAccountExternalUid(UNSTORABLE_ACCOUNT, "WRONG", null);
createAccountExternalUid(TOTALLY_UNSTORABLE_ACCOUNT, 4, null);
when();
provisioningService.synchronize(coords, null, tokenStorage, handler, task, result);
then();
display("events", events);
assertThat(events.size()).as("events found").isEqualTo(4);
List<PrismObject<ShadowType>> objects = events.stream().filter(event -> event.getChangeDescription() != null).map(event -> event.getChangeDescription().getShadowedResourceObject()).collect(Collectors.toList());
assertSelectedAccountByName(objects, GOOD_ACCOUNT).assertOid().assertKind(ShadowKindType.ACCOUNT).assertPrimaryIdentifierValue(GOOD_ACCOUNT_UID).assertName(GOOD_ACCOUNT).attributes().assertSize(3).end().assertSuccessOrNoFetchResult();
PrismObject<ShadowType> goodAfter = findShadowByPrismName(GOOD_ACCOUNT, RESOURCE_DUMMY_BROKEN_ACCOUNTS_EXTERNAL_UID.object, result);
assertShadow(goodAfter, GOOD_ACCOUNT).display().assertOid().assertKind(ShadowKindType.ACCOUNT).assertPrimaryIdentifierValue(GOOD_ACCOUNT_UID).attributes().assertSize(3).end();
assertSelectedAccountByName(objects, INCONVERTIBLE_ACCOUNT_UID).assertOid().assertKind(ShadowKindType.ACCOUNT).assertPrimaryIdentifierValue(INCONVERTIBLE_ACCOUNT_UID).assertName(INCONVERTIBLE_ACCOUNT_UID).attributes().assertSize(// uid=uid:inconvertible (for some reason number=2 is not there)
1).end();
// name is now derived from UID
PrismObject<ShadowType> inconvertibleAfter = findShadowByPrismName(INCONVERTIBLE_ACCOUNT_UID, RESOURCE_DUMMY_BROKEN_ACCOUNTS_EXTERNAL_UID.object, result);
assertShadow(inconvertibleAfter, INCONVERTIBLE_ACCOUNT).display().assertOid().assertKind(ShadowKindType.ACCOUNT).assertPrimaryIdentifierValue(INCONVERTIBLE_ACCOUNT_UID).attributes().assertSize(1).end();
assertSelectedAccountByName(objects, UNSTORABLE_ACCOUNT_UID).assertOid().assertKind(ShadowKindType.ACCOUNT).assertPrimaryIdentifierValue(UNSTORABLE_ACCOUNT_UID).assertName(UNSTORABLE_ACCOUNT_UID).attributes().assertSize(// uid=unstorable
1).end();
// name is now derived from UID
PrismObject<ShadowType> unstorableAfter = findShadowByPrismName(UNSTORABLE_ACCOUNT_UID, RESOURCE_DUMMY_BROKEN_ACCOUNTS_EXTERNAL_UID.object, result);
assertShadow(unstorableAfter, UNSTORABLE_ACCOUNT).display().assertOid().assertKind(ShadowKindType.ACCOUNT).assertPrimaryIdentifierValue(UNSTORABLE_ACCOUNT_UID).attributes().assertSize(1).end();
// The fetch result is not in the shadows. The exception is recorded in events.
List<LiveSyncEvent> noChangeEvents = events.stream().filter(event -> event.getChangeDescription() == null).collect(Collectors.toList());
if (isSqaleRepository()) {
// Totally unstorable account is storable
return;
}
assertThat(noChangeEvents).hasSize(1);
LiveSyncEvent failedEvent = noChangeEvents.get(0);
displayDumpable("failed event", failedEvent);
assertThat(failedEvent.isError()).isTrue();
}
Aggregations