Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Evolveum/midpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
KaterynaHonchar committed Apr 23, 2017
2 parents 2bfac23 + 74465db commit 1ea2490
Show file tree
Hide file tree
Showing 19 changed files with 392 additions and 56 deletions.
Expand Up @@ -362,8 +362,8 @@ protected String debugDump(int indent, StringBuilder sb) {
sb.append("\n");
DebugUtil.indentDebugDump(sb, indent+1);
sb.append("VALUE:");
sb.append("\n");
for (PrismValue val : getValues()) {
sb.append("\n");
sb.append(DebugUtil.debugDump(val, indent + 2));
}
}
Expand Down
Expand Up @@ -161,6 +161,7 @@ public static int getActiveCases(List<AccessCertificationCaseType> caseList, int

// unanswered cases = cases where one or more answers from reviewers are missing
// "no reviewers" cases are treated as answered, because no answer can be provided
// closeTimestamp is not checked here: we are NOT interested in "answerable" cases; we are interested in how many cases has an answer
public static int getUnansweredCases(List<AccessCertificationCaseType> caseList, int campaignStageNumber, AccessCertificationCampaignStateType state) {
int unansweredCases = 0;
if (state == AccessCertificationCampaignStateType.IN_REMEDIATION || state == AccessCertificationCampaignStateType.CLOSED) {
Expand All @@ -169,7 +170,6 @@ public static int getUnansweredCases(List<AccessCertificationCaseType> caseList,
for (AccessCertificationCaseType aCase : caseList) {
for (AccessCertificationWorkItemType workItem : aCase.getWorkItem()) {
if (workItem.getStageNumber() == campaignStageNumber
&& workItem.getCloseTimestamp() == null
&& WorkItemTypeUtil.getOutcome(workItem) == null) {
unansweredCases++;
break;
Expand Down Expand Up @@ -318,6 +318,15 @@ public static ObjectQuery createWorkItemsForCampaignQuery(String campaignOid, Pr
.build();
}

// some methods, like searchOpenWorkItems, engage their own "openness" filter
public static ObjectQuery createOpenWorkItemsForCampaignQuery(String campaignOid, PrismContext prismContext) throws SchemaException {
return QueryBuilder.queryFor(AccessCertificationWorkItemType.class, prismContext)
.item(AccessCertificationWorkItemType.F_CLOSE_TIMESTAMP).isNull()
.and().exists(PrismConstants.T_PARENT)
.ownerId(campaignOid)
.build();
}

public static String getStageOutcome(AccessCertificationCaseType aCase, int stageNumber) {
StageCompletionEventType event = aCase.getEvent().stream()
.filter(e -> e instanceof StageCompletionEventType && e.getStageNumber() == stageNumber)
Expand All @@ -340,7 +349,7 @@ public static List<AccessCertificationResponseType> getOutcomesToStopOn(List<Acc
public static Set<ObjectReferenceType> getCurrentReviewers(AccessCertificationCaseType aCase) {
return aCase.getWorkItem().stream()
// TODO check also with campaign stage?
.filter(wi -> wi.getStageNumber() == aCase.getStageNumber() && wi.getCloseTimestamp() == null)
.filter(wi -> wi.getStageNumber() == aCase.getStageNumber())
.flatMap(wi -> wi.getAssigneeRef().stream())
.collect(Collectors.toSet());
}
Expand Down
Expand Up @@ -86,8 +86,8 @@ private ObjectQuery replaceFilter(ObjectQuery query, ObjectFilter newFilter) {

// public because of testing
// principal == null => take all work items
public List<AccessCertificationWorkItemType> searchWorkItems(ObjectQuery baseWorkItemsQuery, MidPointPrincipal principal, boolean notDecidedOnly,
Collection<SelectorOptions<GetOperationOptions>> options, Task task, OperationResult result)
public List<AccessCertificationWorkItemType> searchOpenWorkItems(ObjectQuery baseWorkItemsQuery, MidPointPrincipal principal,
boolean notDecidedOnly, Collection<SelectorOptions<GetOperationOptions>> options, OperationResult result)
throws SchemaException, ObjectNotFoundException {

// enhance filter with reviewerRef + enabled
Expand Down
Expand Up @@ -126,9 +126,9 @@ private void executeActions(WorkItemActionsType actions, AccessCertificationCamp
private void executeCompleteAction(AccessCertificationCampaignType campaign, CompleteWorkItemActionType completeAction,
Task task, OperationResult result)
throws SchemaException, SecurityViolationException, ObjectNotFoundException, ObjectAlreadyExistsException {
List<AccessCertificationWorkItemType> workItems = queryHelper.searchWorkItems(
List<AccessCertificationWorkItemType> workItems = queryHelper.searchOpenWorkItems(
CertCampaignTypeUtil.createWorkItemsForCampaignQuery(campaign.getOid(), prismContext),
null, true, null, task, result);
null, true, null, result);
for (AccessCertificationWorkItemType workItem : workItems) {
AccessCertificationCaseType aCase = CertCampaignTypeUtil.getCase(workItem);
if (aCase == null || aCase.getId() == null || workItem.getId() == null) {
Expand All @@ -144,9 +144,9 @@ private void executeDelegateAction(AccessCertificationCampaignType campaign, Del
Task task, OperationResult result)
throws SecurityViolationException, ObjectNotFoundException, SchemaException, ExpressionEvaluationException,
ObjectAlreadyExistsException {
List<AccessCertificationWorkItemType> workItems = queryHelper.searchWorkItems(
List<AccessCertificationWorkItemType> workItems = queryHelper.searchOpenWorkItems(
CertCampaignTypeUtil.createWorkItemsForCampaignQuery(campaign.getOid(), prismContext),
null, true, null, task, result);
null, true, null, result);
certManager.delegateWorkItems(campaign.getOid(), workItems, delegateAction, task, result);
}

Expand Down
Expand Up @@ -74,14 +74,17 @@

import static com.evolveum.midpoint.schema.util.ObjectTypeUtil.toShortString;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractWorkItemType.F_ASSIGNEE_REF;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractWorkItemType.F_CLOSE_TIMESTAMP;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractWorkItemType.F_ESCALATION_LEVEL;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCampaignStateType.*;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCampaignType.F_CASE;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCampaignType.F_STAGE;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseType.F_EVENT;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseType.F_WORK_ITEM;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationDefinitionType.F_LAST_CAMPAIGN_CLOSED_TIMESTAMP;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationDefinitionType.F_LAST_CAMPAIGN_ID_USED;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationDefinitionType.F_LAST_CAMPAIGN_STARTED_TIMESTAMP;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationStageType.F_END_TIMESTAMP;

/**
* @author mederly
Expand Down Expand Up @@ -409,9 +412,9 @@ public void escalateCampaign(String campaignOid, EscalateWorkItemActionType esca
result.addContext("user", toShortString(principal.getUser()));
ObjectReferenceType initiator = ObjectTypeUtil.createObjectRef(principal.getUser());

List<AccessCertificationWorkItemType> workItems = queryHelper.searchWorkItems(
List<AccessCertificationWorkItemType> workItems = queryHelper.searchOpenWorkItems(
CertCampaignTypeUtil.createWorkItemsForCampaignQuery(campaignOid, prismContext),
null, false, null, task, result);
null, false, null, result);

if (workItems.isEmpty()) {
LOGGER.debug("No work items, no escalation (campaign: {})", campaignOid);
Expand Down Expand Up @@ -482,7 +485,7 @@ public void escalateCampaign(String campaignOid, EscalateWorkItemActionType esca
Long stageId = stage.asPrismContainerValue().getId();
assert stageId != null;
deltas.add(DeltaBuilder.deltaFor(AccessCertificationCampaignType.class, prismContext)
.item(AccessCertificationCampaignType.F_STAGE, stageId, AccessCertificationStageType.F_ESCALATION_LEVEL).replace(newEscalationLevel)
.item(F_STAGE, stageId, AccessCertificationStageType.F_ESCALATION_LEVEL).replace(newEscalationLevel)
.asItemDelta());
AccessCertificationStageDefinitionType stageDefinition = CertCampaignTypeUtil.getCurrentStageDefinition(campaign);
deltas.addAll(createTriggersForTimedActions(campaignOid, newStageEscalationLevelNumber,
Expand Down Expand Up @@ -562,44 +565,62 @@ private List<ObjectReferenceType> computeDelegateTo(DelegateWorkItemActionType d

void closeCampaign(AccessCertificationCampaignType campaign, Task task, OperationResult result) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, SecurityViolationException {
LOGGER.info("Closing campaign {}", ObjectTypeUtil.toShortString(campaign));
XMLGregorianCalendar now = XmlTypeConverter.createXMLGregorianCalendar(new Date());
int lastStageNumber = CertCampaignTypeUtil.getNumberOfStages(campaign);
// TODO issue a warning if we are not in a correct state
PropertyDelta<Integer> stageNumberDelta = createStageNumberDelta(lastStageNumber + 1);
PropertyDelta<AccessCertificationCampaignStateType> stateDelta = createStateDelta(CLOSED);
ContainerDelta<TriggerType> triggerDelta = createTriggerDeleteDelta();
PropertyDelta<XMLGregorianCalendar> endDelta = createEndTimeDelta(XmlTypeConverter.createXMLGregorianCalendar(new Date()));
modifyObjectViaModel(AccessCertificationCampaignType.class, campaign.getOid(),
Arrays.asList(stateDelta, stageNumberDelta, triggerDelta, endDelta), task, result);
List<ItemDelta<?, ?>> deltas = new ArrayList<>();
deltas.add(createStageNumberDelta(lastStageNumber + 1));
deltas.add(createStateDelta(CLOSED));
deltas.add(createTriggerDeleteDelta());
deltas.add(createEndTimeDelta(now));
deltas.addAll(createWorkItemsCloseDeltas(campaign, now, result));
modifyObjectViaModel(AccessCertificationCampaignType.class, campaign.getOid(), deltas, task, result);

AccessCertificationCampaignType updatedCampaign = refreshCampaign(campaign, result);
LOGGER.info("Updated campaign state: {}", updatedCampaign.getState());
eventHelper.onCampaignEnd(updatedCampaign, task, result);

if (campaign.getDefinitionRef() != null) {
List<ItemDelta<?,?>> deltas = DeltaBuilder.deltaFor(AccessCertificationDefinitionType.class, prismContext)
.item(F_LAST_CAMPAIGN_CLOSED_TIMESTAMP).replace(XmlTypeConverter.createXMLGregorianCalendar(new Date()))
List<ItemDelta<?,?>> definitionDeltas = DeltaBuilder.deltaFor(AccessCertificationDefinitionType.class, prismContext)
.item(F_LAST_CAMPAIGN_CLOSED_TIMESTAMP).replace(now)
.asItemDeltas();
modifyObjectViaModel(AccessCertificationDefinitionType.class, campaign.getDefinitionRef().getOid(), deltas, task, result);
modifyObjectViaModel(AccessCertificationDefinitionType.class, campaign.getDefinitionRef().getOid(), definitionDeltas, task, result);
}
}

List<ItemDelta<?,?>> getDeltasForStageClose(AccessCertificationCampaignType campaign, OperationResult result) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException {
List<ItemDelta<?,?>> rv = caseHelper.createOutcomeDeltas(campaign, result);
private Collection<ItemDelta<?, ?>> createWorkItemsCloseDeltas(AccessCertificationCampaignType campaign,
XMLGregorianCalendar now, OperationResult result) throws SchemaException, ObjectNotFoundException {
ObjectQuery query = CertCampaignTypeUtil.createWorkItemsForCampaignQuery(campaign.getOid(), prismContext);
List<AccessCertificationWorkItemType> openWorkItems = queryHelper.searchOpenWorkItems(query, null, false, null, result);
LOGGER.debug("There are {} open work items for {}", openWorkItems.size(), ObjectTypeUtil.toShortString(campaign));
Collection<ItemDelta<?, ?>> deltas = new ArrayList<>();
for (AccessCertificationWorkItemType workItem : openWorkItems) {
AccessCertificationCaseType aCase = CertCampaignTypeUtil.getCaseChecked(workItem);
deltas.add(
DeltaBuilder.deltaFor(AccessCertificationCampaignType.class, prismContext)
.item(F_CASE, aCase.getId(), F_WORK_ITEM, workItem.getId(), F_CLOSE_TIMESTAMP)
.replace(now)
.asItemDelta());
}
return deltas;
}

List<ItemDelta<?,?>> getDeltasForStageClose(AccessCertificationCampaignType campaign, OperationResult result) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException {
XMLGregorianCalendar now = XmlTypeConverter.createXMLGregorianCalendar(new Date());
List<ItemDelta<?,?>> rv = caseHelper.createOutcomeDeltas(campaign, result);
rv.add(createStateDelta(REVIEW_STAGE_DONE));
rv.add(createStageEndTimeDelta(campaign));
rv.add(createStageEndTimeDelta(campaign, now));
rv.add(createTriggerDeleteDelta());

rv.addAll(createWorkItemsCloseDeltas(campaign, now, result));
return rv;
}

private ItemDelta createStageEndTimeDelta(AccessCertificationCampaignType campaign) throws SchemaException {
private ItemDelta createStageEndTimeDelta(AccessCertificationCampaignType campaign, XMLGregorianCalendar now) throws SchemaException {
AccessCertificationStageType stage = CertCampaignTypeUtil.findStage(campaign, campaign.getStageNumber());
Long stageId = stage.asPrismContainerValue().getId();
assert stageId != null;
XMLGregorianCalendar currentTime = XmlTypeConverter.createXMLGregorianCalendar(new Date());
return DeltaBuilder.deltaFor(AccessCertificationCampaignType.class, prismContext)
.item(AccessCertificationCampaignType.F_STAGE, stageId, AccessCertificationStageType.F_END_TIMESTAMP).replace(currentTime)
.item(F_STAGE, stageId, F_END_TIMESTAMP).replace(now)
.asItemDelta();
}

Expand Down Expand Up @@ -640,7 +661,7 @@ private ContainerDelta createTriggerDeleteDelta() {
}

private ItemDelta createStageAddDelta(AccessCertificationStageType stage) {
ContainerDelta<AccessCertificationStageType> stageDelta = ContainerDelta.createDelta(AccessCertificationCampaignType.F_STAGE,
ContainerDelta<AccessCertificationStageType> stageDelta = ContainerDelta.createDelta(F_STAGE,
AccessCertificationCampaignType.class, prismContext);
stageDelta.addValueToAdd(stage.asPrismContainerValue());
return stageDelta;
Expand Down
Expand Up @@ -320,7 +320,7 @@ public List<AccessCertificationWorkItemType> searchOpenWorkItems(ObjectQuery bas
securityEnforcer.authorize(ModelAuthorizationAction.READ_OWN_CERTIFICATION_DECISIONS.getUrl(), null,
null, null, null, null, result);

return queryHelper.searchWorkItems(baseWorkItemsQuery, SecurityUtil.getPrincipal(), notDecidedOnly, options, task, result);
return queryHelper.searchOpenWorkItems(baseWorkItemsQuery, SecurityUtil.getPrincipal(), notDecidedOnly, options, result);
} catch (RuntimeException e) {
result.recordFatalError("Couldn't search for certification work items: unexpected exception: " + e.getMessage(), e);
throw e;
Expand Down
Expand Up @@ -65,6 +65,12 @@ public class AbstractCertificationTest extends AbstractModelIntegrationTest {
public static final String SYSTEM_CONFIGURATION_OID = SystemObjectsType.SYSTEM_CONFIGURATION.value();

protected static final File ORGS_AND_USERS_FILE = new File(COMMON_DIR, "orgs-and-users.xml");
protected static final File USER_BOB_FILE = new File(COMMON_DIR, "user-bob.xml");
protected static final File USER_BOB_DEPUTY_FULL_FILE = new File(COMMON_DIR, "user-bob-deputy-full.xml");
protected static final File USER_BOB_DEPUTY_NO_ASSIGNMENTS_FILE = new File(COMMON_DIR, "user-bob-deputy-no-assignments.xml");
protected static final File USER_BOB_DEPUTY_NO_PRIVILEGES_FILE = new File(COMMON_DIR, "user-bob-deputy-no-privileges.xml");
protected static final File USER_ADMINISTRATOR_DEPUTY_NO_ASSIGNMENTS_FILE = new File(COMMON_DIR, "user-administrator-deputy-no-assignments.xml");
protected static final File USER_ADMINISTRATOR_DEPUTY_NONE_FILE = new File(COMMON_DIR, "user-administrator-deputy-none.xml");

protected static final String ORG_GOVERNOR_OFFICE_OID = "00000000-8888-6666-0000-100000000001";
protected static final String ORG_SCUMM_BAR_OID = "00000000-8888-6666-0000-100000000006";
Expand All @@ -84,6 +90,11 @@ public class AbstractCertificationTest extends AbstractModelIntegrationTest {
protected static final String USER_BARKEEPER_OID = "c0c010c0-d34d-b33f-f00d-111111111132";
protected static final String USER_CARLA_OID = "c0c010c0-d34d-b33f-f00d-111111111133";
protected static final String USER_BOB_OID = "c0c010c0-d34d-b33f-f00d-111111111134";
protected static final String USER_BOB_DEPUTY_FULL_OID = "71d27191-df8c-4513-836e-ed01c68a4ab4";
protected static final String USER_BOB_DEPUTY_NO_ASSIGNMENTS_OID = "afc1c45d-fdb8-48cf-860b-b305f96a07e3";
protected static final String USER_BOB_DEPUTY_NO_PRIVILEGES_OID = "ad371f45-352d-4c1f-80f3-2e279af399ae";
protected static final String USER_ADMINISTRATOR_DEPUTY_NO_ASSIGNMENTS_OID = "0b88d83f-1722-4b13-b7cc-a2d500470d7f";
protected static final String USER_ADMINISTRATOR_DEPUTY_NONE_OID = "e38df3fc-3510-45c2-a379-2b4a1406d4b6";

public static final File USER_ADMINISTRATOR_FILE = new File(COMMON_DIR, "user-administrator.xml");
protected static final String USER_ADMINISTRATOR_OID = "00000000-0000-0000-0000-000000000002";
Expand Down Expand Up @@ -175,6 +186,12 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti
}

repoAddObjectsFromFile(ORGS_AND_USERS_FILE, RoleType.class, initResult);
repoAddObjectFromFile(USER_BOB_FILE, UserType.class, initResult);
repoAddObjectFromFile(USER_BOB_DEPUTY_FULL_FILE, UserType.class, initResult);
repoAddObjectFromFile(USER_BOB_DEPUTY_NO_ASSIGNMENTS_FILE, UserType.class, initResult);
repoAddObjectFromFile(USER_BOB_DEPUTY_NO_PRIVILEGES_FILE, UserType.class, initResult);
repoAddObjectFromFile(USER_ADMINISTRATOR_DEPUTY_NO_ASSIGNMENTS_FILE, UserType.class, initResult);
repoAddObjectFromFile(USER_ADMINISTRATOR_DEPUTY_NONE_FILE, UserType.class, initResult);

// roles
repoAddObjectFromFile(METAROLE_CXO_FILE, RoleType.class, initResult);
Expand Down Expand Up @@ -472,13 +489,14 @@ protected void assertCaseHistoricOutcomes(AccessCertificationCaseType aCase, Acc
}


// we return also closed ones (TODO: what is meant by 'current' work items?)
public List<AccessCertificationWorkItemType> getCurrentWorkItems(AccessCertificationCaseType _case, int stageNumber, boolean decidedOnly) {
List<AccessCertificationWorkItemType> rv = new ArrayList<>();
for (AccessCertificationWorkItemType workItem : _case.getWorkItem()) {
if (decidedOnly && WorkItemTypeUtil.getOutcome(workItem) == null) {
continue;
}
if (workItem.getStageNumber() == stageNumber && workItem.getCloseTimestamp() == null) {
if (workItem.getStageNumber() == stageNumber) {
rv.add(workItem.clone());
}
}
Expand Down

0 comments on commit 1ea2490

Please sign in to comment.