Skip to content

Commit

Permalink
Adapted XMLs to cert schema changes. Added overall outcome computation.
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Feb 5, 2016
1 parent 147fca7 commit 3ee0879
Show file tree
Hide file tree
Showing 13 changed files with 178 additions and 157 deletions.
Expand Up @@ -17,12 +17,9 @@
package com.evolveum.midpoint.certification.impl;

import com.evolveum.midpoint.certification.impl.handlers.CertificationHandler;
import com.evolveum.midpoint.model.api.ModelService;
import com.evolveum.midpoint.prism.PrismContainerDefinition;
import com.evolveum.midpoint.prism.PrismContainerValue;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.PrismPropertyValue;
import com.evolveum.midpoint.prism.PrismReference;
import com.evolveum.midpoint.prism.delta.ContainerDelta;
import com.evolveum.midpoint.prism.delta.ItemDelta;
Expand Down Expand Up @@ -85,6 +82,7 @@
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseType.F_CURRENT_STAGE_OUTCOME;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseType.F_CURRENT_STAGE_NUMBER;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseType.F_DECISION;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseType.F_OVERALL_OUTCOME;

/**
* @author mederly
Expand Down Expand Up @@ -247,7 +245,7 @@ List<ItemDelta> getDeltasToCreateCases(
public boolean handle(PrismObject<ObjectType> object, OperationResult parentResult) {
try {
caseList.addAll(handler.createCasesForObject(object, campaign, task, parentResult));
} catch (ExpressionEvaluationException |ObjectNotFoundException|SchemaException e) {
} catch (ExpressionEvaluationException|ObjectNotFoundException|SchemaException e) {
// TODO process the exception more intelligently
throw new SystemException("Cannot create certification case for object " + ObjectTypeUtil.toShortString(object.asObjectable()) + ": " + e.getMessage(), e);
}
Expand All @@ -263,27 +261,31 @@ public boolean handle(PrismObject<ObjectType> object, OperationResult parentResu
AccessCertificationCampaignType.class, prismContext);
for (int i = 0; i < caseList.size(); i++) {
final AccessCertificationCaseType _case = caseList.get(i);
_case.setCurrentReviewRequestedTimestamp(stage.getStart());
_case.setCurrentReviewDeadline(stage.getDeadline());
_case.setCurrentStageNumber(1);

_case.setCurrentStageNumber(1);
reviewersHelper.setupReviewersForCase(_case, campaign, reviewerSpec, task, result);
_case.setCurrentReviewRequestedTimestamp(stage.getStart());
_case.setCurrentReviewDeadline(stage.getDeadline());

List<AccessCertificationDecisionType> decisions = createEmptyDecisionsForCase(_case.getCurrentReviewerRef(), 1);
_case.getDecision().addAll(decisions);

_case.setCurrentStageOutcome(computationHelper.computeInitialResponseForStage(_case, campaign, 1));
_case.setOverallOutcome(null);

PrismContainerValue<AccessCertificationCaseType> caseCVal = _case.asPrismContainerValue();
//caseCVal.setId((long) (i + 1));
caseDelta.addValueToAdd(caseCVal);
_case.setCurrentStageOutcome(computationHelper.computeInitialResponseForStage(_case, campaign, 1));

if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Adding certification case:\n{}", caseCVal.debugDump());
}
}
rv.add(caseDelta);

LOGGER.trace("Prepared {} deltas to create {} cases for campaign {}", rv.size(), caseList.size(), campaignShortName);
LOGGER.trace("Created {} deltas to create {} cases for campaign {}", rv.size(), caseList.size(), campaignShortName);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Deltas: {}", DebugUtil.debugDump(rv));
}
return rv;
}

Expand All @@ -302,7 +304,8 @@ private List<AccessCertificationDecisionType> createEmptyDecisionsForCase(List<O
return decisions;
}

List<ItemDelta> getDeltasToAdvanceCases(AccessCertificationCampaignType campaign, AccessCertificationStageType stage, Task task, OperationResult result) throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException {
List<ItemDelta> getDeltasToAdvanceCases(AccessCertificationCampaignType campaign, AccessCertificationStageType stage, Task task, OperationResult result)
throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException {

LOGGER.trace("Advancing reviewers and timestamps for cases in {}", ObjectTypeUtil.toShortString(campaign));
final List<AccessCertificationCaseType> caseList = queryHelper.searchCases(campaign.getOid(), null, null, result);
Expand All @@ -314,6 +317,7 @@ List<ItemDelta> getDeltasToAdvanceCases(AccessCertificationCampaignType campaign

final AccessCertificationReviewerSpecificationType reviewerSpec =
reviewersHelper.findReviewersSpecification(campaign, stageToBe, task, result);

for (int i = 0; i < caseList.size(); i++) {
final AccessCertificationCaseType _case = caseList.get(i);

Expand All @@ -326,13 +330,13 @@ List<ItemDelta> getDeltasToAdvanceCases(AccessCertificationCampaignType campaign

reviewersHelper.setupReviewersForCase(_case, campaign, reviewerSpec, task, result);
final PrismReference reviewersRef = _case.asPrismContainerValue().findOrCreateReference(AccessCertificationCaseType.F_CURRENT_REVIEWER_REF);
final ReferenceDelta reviewerDelta = ReferenceDelta.createModificationReplace(
final ReferenceDelta reviewersDelta = ReferenceDelta.createModificationReplace(
new ItemPath(
new NameItemPathSegment(F_CASE),
new IdItemPathSegment(caseId),
new NameItemPathSegment(AccessCertificationCaseType.F_CURRENT_REVIEWER_REF)),
generalHelper.getCampaignObjectDefinition(), CloneUtil.cloneCollectionMembers(reviewersRef.getValues()));
rv.add(reviewerDelta);
rv.add(reviewersDelta);

final PropertyDelta reviewRequestedTimestampDelta = PropertyDelta.createModificationReplaceProperty(
new ItemPath(
Expand Down Expand Up @@ -365,7 +369,7 @@ List<ItemDelta> getDeltasToAdvanceCases(AccessCertificationCampaignType campaign
final PropertyDelta currentStageNumberDelta = PropertyDelta.createModificationReplaceProperty(
new ItemPath(
new NameItemPathSegment(F_CASE),
new IdItemPathSegment(caseId(_case)),
new IdItemPathSegment(caseId),
new NameItemPathSegment(F_CURRENT_STAGE_NUMBER)),
generalHelper.getCampaignObjectDefinition(),
stageToBe);
Expand All @@ -385,12 +389,8 @@ List<ItemDelta> getDeltasToAdvanceCases(AccessCertificationCampaignType campaign
return rv;
}

private Long caseId(AccessCertificationCaseType _case) {
return _case.asPrismContainerValue().getId();
}

// computes definitive outcome at stage close (and stores it to stage outcome container)
List<ItemDelta> createOutcomeDeltas(AccessCertificationCampaignType campaign, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException {
// computes outcomes at stage close (stage-level and overall) and creates appropriate deltas
List<ItemDelta> createOutcomeDeltas(AccessCertificationCampaignType campaign, OperationResult result) throws ObjectNotFoundException, SchemaException {
final List<ItemDelta> rv = new ArrayList<>();

LOGGER.trace("Updating current outcome for cases in {}", ObjectTypeUtil.toShortString(campaign));
Expand All @@ -401,24 +401,35 @@ List<ItemDelta> createOutcomeDeltas(AccessCertificationCampaignType campaign, Ta
if (_case.getCurrentStageNumber() != campaign.getStageNumber()) {
continue;
}
final AccessCertificationResponseType newOutcome = computationHelper.computeOutcomeForStage(_case, campaign);
if (newOutcome != _case.getCurrentStageOutcome()) {
if (newOutcome == null) {
throw new IllegalStateException("Computed currentOutcome is null for case id " + _case.asPrismContainerValue().getId());
final AccessCertificationResponseType newStageOutcome = computationHelper.computeOutcomeForStage(_case, campaign);
if (newStageOutcome != _case.getCurrentStageOutcome()) {
if (newStageOutcome == null) {
throw new IllegalStateException("Computed currentStateOutcome is null for case id " + _case.asPrismContainerValue().getId());
}
final ItemDelta currentResponseDelta = DeltaBuilder.deltaFor(AccessCertificationCampaignType.class, prismContext)
.item(F_CASE, _case.asPrismContainerValue().getId(), F_CURRENT_STAGE_OUTCOME).replace(newOutcome)
final ItemDelta currentStageOutcomeDelta = DeltaBuilder.deltaFor(AccessCertificationCampaignType.class, prismContext)
.item(F_CASE, _case.asPrismContainerValue().getId(), F_CURRENT_STAGE_OUTCOME).replace(newStageOutcome)
.asItemDelta();
rv.add(currentResponseDelta);
rv.add(currentStageOutcomeDelta);
}

AccessCertificationCaseStageOutcomeType stageOutcomeRecord = new AccessCertificationCaseStageOutcomeType(prismContext);
stageOutcomeRecord.setStageNumber(campaign.getStageNumber());
stageOutcomeRecord.setOutcome(newOutcome);
stageOutcomeRecord.setOutcome(newStageOutcome);
final ItemDelta stageOutcomeDelta = DeltaBuilder.deltaFor(AccessCertificationCampaignType.class, prismContext)
.item(F_CASE, _case.asPrismContainerValue().getId(), F_COMPLETED_STAGE_OUTCOME).add(stageOutcomeRecord)
.asItemDelta();
rv.add(stageOutcomeDelta);

final AccessCertificationResponseType newOverallOutcome = computationHelper.computeOverallOutcome(_case, campaign, stageOutcomeRecord);
if (newOverallOutcome != _case.getOverallOutcome()) {
if (newOverallOutcome == null) {
throw new IllegalStateException("Computed overallOutcome is null for case id " + _case.asPrismContainerValue().getId());
}
final ItemDelta overallOutcomeDelta = DeltaBuilder.deltaFor(AccessCertificationCampaignType.class, prismContext)
.item(F_CASE, _case.asPrismContainerValue().getId(), F_OVERALL_OUTCOME).replace(newOverallOutcome)
.asItemDelta();
rv.add(overallOutcomeDelta);
}
}
return rv;
}
Expand Down
Expand Up @@ -19,12 +19,12 @@
import com.evolveum.midpoint.certification.impl.outcomeStrategies.ResponsesSummary;
import com.evolveum.midpoint.certification.impl.outcomeStrategies.OutcomeStrategy;
import com.evolveum.midpoint.schema.util.CertCampaignTypeUtil;
import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseOutcomeStrategyType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCampaignType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseReviewStrategyType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseStageOutcomeType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationDecisionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationResponseType;
Expand Down Expand Up @@ -54,7 +54,7 @@ public class AccCertResponseComputationHelper {
private static final transient Trace LOGGER = TraceManager.getTrace(AccCertResponseComputationHelper.class);

public static final AccessCertificationCaseOutcomeStrategyType DEFAULT_CASE_STAGE_OUTCOME_STRATEGY = ONE_ACCEPT_ACCEPTS;
public static final AccessCertificationCaseOutcomeStrategyType DEFAULT_CASE_FINAL_OUTCOME_STRATEGY = ONE_DENY_DENIES;
public static final AccessCertificationCaseOutcomeStrategyType DEFAULT_CASE_OVERALL_OUTCOME_STRATEGY = ONE_DENY_DENIES;

Map<AccessCertificationCaseOutcomeStrategyType, OutcomeStrategy> outcomeStrategyMap = new HashMap<>();

Expand Down Expand Up @@ -94,7 +94,7 @@ public List<AccessCertificationResponseType> getOutcomesToStopOn(AccessCertifica
if (reviewStrategy != null && (!reviewStrategy.getStopReviewOn().isEmpty() || !reviewStrategy.getAdvanceToNextStageOn().isEmpty())) {
rv = getOutcomesToStopOn(reviewStrategy.getStopReviewOn(), reviewStrategy.getAdvanceToNextStageOn());
} else {
final OutcomeStrategy outcomeStrategy = getOutcomeStrategy(campaign);
final OutcomeStrategy outcomeStrategy = getOverallOutcomeStrategy(campaign);
rv = outcomeStrategy.getOutcomesToStopOn();
}
}
Expand All @@ -104,12 +104,12 @@ public List<AccessCertificationResponseType> getOutcomesToStopOn(AccessCertifica
return rv;
}

private OutcomeStrategy getOutcomeStrategy(AccessCertificationCampaignType campaign) {
private OutcomeStrategy getOverallOutcomeStrategy(AccessCertificationCampaignType campaign) {
final AccessCertificationCaseOutcomeStrategyType strategyName;
if (campaign.getReviewStrategy() != null && campaign.getReviewStrategy().getOutcomeStrategy() != null) {
strategyName = campaign.getReviewStrategy().getOutcomeStrategy();
} else {
strategyName = DEFAULT_CASE_FINAL_OUTCOME_STRATEGY;
strategyName = DEFAULT_CASE_OVERALL_OUTCOME_STRATEGY;
}
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Outcome strategy for {} is {}", toShortString(campaign), strategyName);
Expand Down Expand Up @@ -206,4 +206,15 @@ private ResponsesSummary summarize(List<AccessCertificationResponseType> respons
return summary;
}

// aCase contains outcomes from stages 1..N-1. Outcome from stage N is in currentStageOutcome
public AccessCertificationResponseType computeOverallOutcome(AccessCertificationCaseType aCase, AccessCertificationCampaignType campaign,
AccessCertificationCaseStageOutcomeType currentStageOutcome) {
final OutcomeStrategy strategy = getOverallOutcomeStrategy(campaign);
final List<AccessCertificationResponseType> stageOutcomes = new ArrayList<>();
for (AccessCertificationCaseStageOutcomeType stageOutcome : aCase.getCompletedStageOutcome()) {
stageOutcomes.add(stageOutcome.getOutcome());
}
stageOutcomes.add(currentStageOutcome.getOutcome());
return strategy.computeOutcome(summarize(stageOutcomes));
}
}
Expand Up @@ -347,7 +347,7 @@ void closeCampaign(AccessCertificationCampaignType campaign, Task task, Operatio
}

List<ItemDelta> getDeltasForStageClose(AccessCertificationCampaignType campaign, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException {
List<ItemDelta> rv = caseHelper.createOutcomeDeltas(campaign, task, result);
List<ItemDelta> rv = caseHelper.createOutcomeDeltas(campaign, result);

PropertyDelta<AccessCertificationCampaignStateType> stateDelta = createStateDelta(REVIEW_STAGE_DONE);
rv.add(stateDelta);
Expand Down
Expand Up @@ -61,7 +61,7 @@ guybrush->COO cheese elaine
</remediationDefinition>
<stageDefinition>
<number>1</number>
<days>7</days>
<duration>P7D</duration>
<reviewerSpecification>
<useObjectManager>
<orgType>functional</orgType>
Expand All @@ -71,7 +71,7 @@ guybrush->COO cheese elaine
</stageDefinition>
<stageDefinition>
<number>2</number>
<days>14</days>
<duration>P14D</duration>
<reviewerSpecification>
<defaultReviewerRef oid="c0c010c0-d34d-b33f-f00d-11111111111e" type="UserType" /> <!-- elaine -->
</reviewerSpecification>
Expand Down
Expand Up @@ -39,7 +39,7 @@
</remediationDefinition>
<stageDefinition>
<number>1</number>
<days>14</days>
<duration>P14D</duration>
<reviewerSpecification>
<defaultReviewerRef oid="00000000-0000-0000-0000-000000000002" type="UserType" /> <!-- administrator -->
</reviewerSpecification>
Expand Down
Expand Up @@ -61,7 +61,7 @@ Superuser-Dummy: - jack,administrator
</remediationDefinition>
<stageDefinition>
<number>1</number>
<days>14</days>
<duration>P14D</duration>
<reviewerSpecification>
<useObjectOwner>true</useObjectOwner>
</reviewerSpecification>
Expand All @@ -70,7 +70,7 @@ Superuser-Dummy: - jack,administrator
</stageDefinition>
<stageDefinition>
<number>2</number>
<days>7</days>
<duration>P7D</duration>
<reviewerSpecification>
<useTargetOwner>true</useTargetOwner>
<additionalReviewerRef oid="00000000-0000-0000-0000-000000000002" type="UserType" /> <!-- administrator -->
Expand Down
Expand Up @@ -19,24 +19,24 @@
oid="33333333-0000-0000-0000-000000000002">
<name>User Assignment Cert (more reviewers)</name>
<handlerUri>http://midpoint.evolveum.com/xml/ns/public/certification/certification-3#user-assignment-basic</handlerUri>
<stage>
<stageDefinition>
<number>1</number>
<days>14</days>
<duration>P14D</duration>
<reviewerSpecification>
<useTargetObjectOwner>true</useTargetObjectOwner>
<useTargetOwner>true</useTargetOwner>
<defaultReviewerRef oid="00000000-0000-0000-0000-000000000002" type="UserType" /> <!-- administrator -->
<additionalReviewerRef oid="c0c010c0-d34d-b33f-f00d-111111111111" type="UserType" /> <!-- jack -->
<approvalStrategy>oneApprovalApproves</approvalStrategy>
</reviewerSpecification>
</stage>
<stage>
<outcomeStrategy>oneAcceptAccepts</outcomeStrategy>
</stageDefinition>
<stageDefinition>
<number>2</number>
<days>7</days>
<duration>P7D</duration>
<reviewerSpecification>
<useTargetObjectApprover>true</useTargetObjectApprover>
<useTargetApprover>true</useTargetApprover>
<additionalReviewerRef oid="c0c010c0-d34d-b33f-f00d-222222222222" type="UserType" /> <!-- chief reviewer -->
<approvalStrategy>allMustApprove</approvalStrategy>
</reviewerSpecification>
</stage>
<outcomeStrategy>allMustAccept</outcomeStrategy>
</stageDefinition>

</accessCertificationDefinition>

0 comments on commit 3ee0879

Please sign in to comment.