Skip to content

Commit

Permalink
Manual connector integration test (in progress)
Browse files Browse the repository at this point in the history
  • Loading branch information
semancik committed Apr 26, 2017
1 parent 4984ceb commit 2891037
Show file tree
Hide file tree
Showing 23 changed files with 3,057 additions and 232 deletions.
Expand Up @@ -616,6 +616,9 @@ public void computeStatusComposite() {
} else {
message = message + ", " + sub.getMessage();
}
if (asynchronousOperationReference == null) {
asynchronousOperationReference = sub.getAsynchronousOperationReference();
}
}
if (sub.getStatus() == OperationResultStatus.WARNING) {
hasWarning = true;
Expand Down
Expand Up @@ -312,6 +312,7 @@ public <O extends ObjectType> boolean executeChanges(LensContext<O> context, Tas

}

subResult.computeStatus();
if (focusContext != null) {
updateLinks(focusContext, projCtx, task, subResult);
}
Expand Down Expand Up @@ -520,9 +521,29 @@ private <O extends ObjectType, F extends FocusType> void updateLinks(
throw new IllegalStateException("Shadow has null OID, this should not happen");
}

if (projCtx.getSynchronizationPolicyDecision() == SynchronizationPolicyDecision.UNLINK
|| projCtx.getSynchronizationPolicyDecision() == SynchronizationPolicyDecision.DELETE
|| projCtx.isDelete() || isEmptyThombstone(projCtx)) {
if (linkShouldExist(projCtx, result)) {
// Link should exist

PrismObject<F> objectCurrent = focusContext.getObjectCurrent();
if (objectCurrent != null) {
for (ObjectReferenceType linkRef : objectCurrent.asObjectable().getLinkRef()) {
if (projOid.equals(linkRef.getOid())) {
// Already linked, nothing to do, only be sure, the
// situation is set with the good value
LOGGER.trace("Updating situation in already linked shadow.");
updateSituationInShadow(task, SynchronizationSituationType.LINKED, focusObjectContext,
projCtx, result);
return;
}
}
}
// Not linked, need to link
linkShadow(focusContext.getOid(), projOid, focusObjectContext, projCtx, task, result);
// be sure, that the situation is set correctly
LOGGER.trace("Updating situation after shadow was linked.");
updateSituationInShadow(task, SynchronizationSituationType.LINKED, focusObjectContext, projCtx,
result);
} else {
// Link should NOT exist

if (!focusContext.isDelete()) {
Expand Down Expand Up @@ -563,31 +584,30 @@ private <O extends ObjectType, F extends FocusType> void updateLinks(
projOid);
updateSituationInShadow(task, null, focusObjectContext, projCtx, result);
}
// Not linked, that's OK

} else {
// Link should exist
// Not linked, that's OK
}
}

PrismObject<F> objectCurrent = focusContext.getObjectCurrent();
if (objectCurrent != null) {
for (ObjectReferenceType linkRef : objectCurrent.asObjectable().getLinkRef()) {
if (projOid.equals(linkRef.getOid())) {
// Already linked, nothing to do, only be sure, the
// situation is set with the good value
LOGGER.trace("Updating situation in already linked shadow.");
updateSituationInShadow(task, SynchronizationSituationType.LINKED, focusObjectContext,
projCtx, result);
return;
}
}
private boolean linkShouldExist(LensProjectionContext projCtx, OperationResult result) {
if (projCtx.getSynchronizationPolicyDecision() == SynchronizationPolicyDecision.UNLINK) {
return false;
}
if (isEmptyThombstone(projCtx)) {
return false;
}
if (projCtx.hasPendingOperations()) {
return true;
}
if (projCtx.getSynchronizationPolicyDecision() == SynchronizationPolicyDecision.DELETE
|| projCtx.isDelete()) {
if (result.isInProgress()) {
// Keep the link until operation is finished
return true;
} else {
return false;
}
// Not linked, need to link
linkShadow(focusContext.getOid(), projOid, focusObjectContext, projCtx, task, result);
// be sure, that the situation is set correctly
LOGGER.trace("Updating situation after shadow was linked.");
updateSituationInShadow(task, SynchronizationSituationType.LINKED, focusObjectContext, projCtx,
result);
}
return true;
}

/**
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2016 Evolveum
* Copyright (c) 2010-2017 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 @@ -1395,4 +1395,12 @@ public ResourceObjectVolatilityType getVolatility() throws SchemaException {
}
return structuralObjectClassDefinition.getVolatility();
}

public boolean hasPendingOperations() {
PrismObject<ShadowType> current = getObjectCurrent();
if (current == null) {
return false;
}
return !current.asObjectable().getPendingOperation().isEmpty();
}
}
Expand Up @@ -129,34 +129,43 @@ private <F extends FocusType> void processActivationFocal(LensContext<F> context
public <F extends FocusType> void processActivationUserCurrent(LensContext<F> context, LensProjectionContext projCtx,
XMLGregorianCalendar now, Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, PolicyViolationException, CommunicationException, ConfigurationException, SecurityViolationException {

String accCtxDesc = projCtx.toHumanReadableString();
String projCtxDesc = projCtx.toHumanReadableString();
SynchronizationPolicyDecision decision = projCtx.getSynchronizationPolicyDecision();
SynchronizationIntent synchronizationIntent = projCtx.getSynchronizationIntent();

if (decision == SynchronizationPolicyDecision.BROKEN) {
LOGGER.trace("Broken projection {}, skipping further activation processing", accCtxDesc);
LOGGER.trace("Broken projection {}, skipping further activation processing", projCtxDesc);
return;
}
if (decision != null) {
throw new IllegalStateException("Decision "+decision+" already present for projection "+accCtxDesc);
throw new IllegalStateException("Decision "+decision+" already present for projection "+projCtxDesc);
}

if (projCtx.isThombstone()) {
// Let's keep thombstones linked until they expire. So we do not have shadows without owners.
// This is also needed for async delete operations.
// TODO: thombsotne expiration
projCtx.setSynchronizationPolicyDecision(SynchronizationPolicyDecision.KEEP);
LOGGER.trace("Evaluated decision for {} to {} because it is thombstone, skipping further activation processing", projCtxDesc, SynchronizationPolicyDecision.KEEP);
return;
}

if (projCtx.isThombstone() || synchronizationIntent == SynchronizationIntent.UNLINK) {
projCtx.setSynchronizationPolicyDecision(SynchronizationPolicyDecision.UNLINK);
LOGGER.trace("Evaluated decision for {} to {}, skipping further activation processing", accCtxDesc, SynchronizationPolicyDecision.UNLINK);
LOGGER.trace("Evaluated decision for {} to {} because of unlink synchronization intent, skipping further activation processing", projCtxDesc, SynchronizationPolicyDecision.UNLINK);
return;
}

if (synchronizationIntent == SynchronizationIntent.DELETE || projCtx.isDelete()) {
// TODO: is this OK?
projCtx.setSynchronizationPolicyDecision(SynchronizationPolicyDecision.DELETE);
LOGGER.trace("Evaluated decision for {} to {}, skipping further activation processing", accCtxDesc, SynchronizationPolicyDecision.DELETE);
LOGGER.trace("Evaluated decision for {} to {}, skipping further activation processing", projCtxDesc, SynchronizationPolicyDecision.DELETE);
return;
}

boolean shadowShouldExist = evaluateExistenceMapping(context, projCtx, now, true, task, result);

LOGGER.trace("Evaluated intended existence of projection {} to {}", accCtxDesc, shadowShouldExist);
LOGGER.trace("Evaluated intended existence of projection {} to {}", projCtxDesc, shadowShouldExist);

// Let's reconcile the existence intent (shadowShouldExist) and the synchronization intent in the context

Expand Down Expand Up @@ -210,7 +219,7 @@ public <F extends FocusType> void processActivationUserCurrent(LensContext<F> co
decision = SynchronizationPolicyDecision.ADD;
}
} else {
throw new PolicyViolationException("Request to add projection "+accCtxDesc+" but the activation policy decided that it should not exist");
throw new PolicyViolationException("Request to add projection "+projCtxDesc+" but the activation policy decided that it should not exist");
}

} else if (synchronizationIntent == SynchronizationIntent.KEEP) {
Expand All @@ -222,37 +231,37 @@ public <F extends FocusType> void processActivationUserCurrent(LensContext<F> co
decision = SynchronizationPolicyDecision.ADD;
}
} else {
throw new PolicyViolationException("Request to keep projection "+accCtxDesc+" but the activation policy decided that it should not exist");
throw new PolicyViolationException("Request to keep projection "+projCtxDesc+" but the activation policy decided that it should not exist");
}

} else {
throw new IllegalStateException("Unknown sync intent "+synchronizationIntent);
}

LOGGER.trace("Evaluated decision for projection {} to {}", accCtxDesc, decision);
LOGGER.trace("Evaluated decision for projection {} to {}", projCtxDesc, decision);

projCtx.setSynchronizationPolicyDecision(decision);

PrismObject<F> focusNew = context.getFocusContext().getObjectNew();
if (focusNew == null) {
// This must be a user delete or something similar. No point in proceeding
LOGGER.trace("focusNew is null, skipping activation processing of {}", accCtxDesc);
LOGGER.trace("focusNew is null, skipping activation processing of {}", projCtxDesc);
return;
}

if (decision == SynchronizationPolicyDecision.UNLINK || decision == SynchronizationPolicyDecision.DELETE) {
LOGGER.trace("Decision is {}, skipping activation properties processing for {}", decision, accCtxDesc);
LOGGER.trace("Decision is {}, skipping activation properties processing for {}", decision, projCtxDesc);
return;
}

ResourceObjectTypeDefinitionType resourceAccountDefType = projCtx.getResourceObjectTypeDefinitionType();
if (resourceAccountDefType == null) {
LOGGER.trace("No refined object definition, therefore also no activation outbound definition, skipping activation processing for account " + accCtxDesc);
LOGGER.trace("No refined object definition, therefore also no activation outbound definition, skipping activation processing for account " + projCtxDesc);
return;
}
ResourceActivationDefinitionType activationType = resourceAccountDefType.getActivation();
if (activationType == null) {
LOGGER.trace("No activation definition in projection {}, skipping activation properties processing", accCtxDesc);
LOGGER.trace("No activation definition in projection {}, skipping activation properties processing", projCtxDesc);
return;
}

Expand Down
Expand Up @@ -26,6 +26,7 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
Expand Down Expand Up @@ -822,7 +823,11 @@ private <F extends FocusType> LensProjectionContext getOrCreateAccountContext(Le
ShadowKindType kind = ShadowUtil.getKind(accountType);
ResourceType resource = LensUtil.getResourceReadOnly(context, resourceOid, provisioningService, task, result);
intent = LensUtil.refineProjectionIntent(kind, intent, resource, prismContext);
ResourceShadowDiscriminator rsd = new ResourceShadowDiscriminator(resourceOid, kind, intent);
boolean thombstone = false;
if (ShadowUtil.isDead(accountType)) {
thombstone = true;
}
ResourceShadowDiscriminator rsd = new ResourceShadowDiscriminator(resourceOid, kind, intent, thombstone);
projectionContext = LensUtil.getOrCreateProjectionContext(context, rsd);

if (projectionContext.getOid() == null) {
Expand Down Expand Up @@ -1014,6 +1019,7 @@ private <F extends ObjectType> void finishLoadOfProjectionContext(LensContext<F>
}
}
}
Validate.notNull(objectOld.getOid());
if (InternalsConfig.consistencyChecks) {
String resourceOid = projContext.getResourceOid();
if (resourceOid != null && !resourceOid.equals(objectOld.asObjectable().getResourceRef().getOid())) {
Expand Down Expand Up @@ -1217,6 +1223,7 @@ public <F extends ObjectType> void loadFullShadow(LensContext<F> context, LensPr
applyAttributesToGet(projCtx, options);
PrismObject<ShadowType> objectCurrent = provisioningService.getObject(ShadowType.class,
projCtx.getOid(), options, task, result);
Validate.notNull(objectCurrent.getOid());
// TODO: use setLoadedObject() instead?
projCtx.setObjectCurrent(objectCurrent);
ShadowType oldShadow = objectCurrent.asObjectable();
Expand Down

0 comments on commit 2891037

Please sign in to comment.