Skip to content

Commit

Permalink
Certification campaigns are now displayed faster (using countContaine…
Browse files Browse the repository at this point in the history
…rs).
  • Loading branch information
mederly committed Jun 28, 2017
1 parent 55f8f6c commit 96164a3
Show file tree
Hide file tree
Showing 28 changed files with 397 additions and 267 deletions.
Expand Up @@ -325,10 +325,7 @@ protected Integer load() {
AccessCertificationService acs = getCertificationService();
Task task = createSimpleTask(OPERATION_LOAD_CERT_WORK_ITEM_COUNT);
OperationResult result = task.getResult();
List<AccessCertificationWorkItemType> certWorkItems = acs.searchOpenWorkItems(new ObjectQuery(),
true, null, task, result);

return certWorkItems == null ? 0 : certWorkItems.size();
return acs.countOpenWorkItems(new ObjectQuery(), true, null, task, result);
} catch (SchemaException|SecurityViolationException|ObjectNotFoundException
|ConfigurationException|CommunicationException e) {
LoggingUtils.logExceptionAsWarning(LOGGER, "Couldn't load certification work item count", e);
Expand Down
Expand Up @@ -96,16 +96,14 @@ private void handleNotSuccessOrHandledErrorInIterator(OperationResult result){
throw new RestartResponseException(PageError.class);
}

// TODO replace searchCases with countCases (when it will be available)
@Override
protected int internalSize() {
LOGGER.trace("begin::internalSize()");
int count = 0;
OperationResult result = new OperationResult(OPERATION_COUNT_OBJECTS);
try {
Task task = getPage().createSimpleTask(OPERATION_COUNT_OBJECTS);
List<AccessCertificationCaseType> caseList = searchCases(campaignOid, null, null, task, result);
count = caseList.size();
count = countCases(campaignOid, null, task, result);
} catch (Exception ex) {
result.recordFatalError("Couldn't count objects.", ex);
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't count objects", ex);
Expand All @@ -132,8 +130,20 @@ public void setCampaignOid(String campaignOid) {
}

private List<AccessCertificationCaseType> searchCases(String campaignOid, ObjectPaging paging, Collection<SelectorOptions<GetOperationOptions>> options, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ConfigurationException, SecurityViolationException {
final InOidFilter inOidFilter = InOidFilter.createOwnerHasOidIn(campaignOid);
InOidFilter inOidFilter = InOidFilter.createOwnerHasOidIn(campaignOid);
ObjectQuery query = createFinalQuery(inOidFilter);
query.setPaging(paging);
return getModel().searchContainers(AccessCertificationCaseType.class, query, options, task, result);
}

private int countCases(String campaignOid, Collection<SelectorOptions<GetOperationOptions>> options, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ConfigurationException, SecurityViolationException {
InOidFilter inOidFilter = InOidFilter.createOwnerHasOidIn(campaignOid);
ObjectQuery query = createFinalQuery(inOidFilter);
return getModel().countContainers(AccessCertificationCaseType.class, query, options, task, result);
}

@NotNull
private ObjectQuery createFinalQuery(InOidFilter inOidFilter) {
ObjectQuery query = getQuery();
if (query != null) {
query = query.clone();
Expand All @@ -146,12 +156,10 @@ private List<AccessCertificationCaseType> searchCases(String campaignOid, Object
query = new ObjectQuery();
query.setFilter(inOidFilter);
}

query.setPaging(paging);
return getModel().searchContainers(AccessCertificationCaseType.class, query, options, task, result);
return query;
}

@NotNull
@NotNull
@Override
protected List<ObjectOrdering> createObjectOrderings(SortParam<String> sortParam) {
return SearchingUtils.createObjectOrderings(sortParam, false);
Expand Down
Expand Up @@ -104,7 +104,6 @@ private void handleNotSuccessOrHandledErrorInIterator(OperationResult result) {
throw new RestartResponseException(PageError.class);
}

// TODO replace searchDecisions with countDecisions (when it will be available)
@Override
protected int internalSize() {
LOGGER.trace("begin::internalSize()");
Expand All @@ -114,9 +113,7 @@ protected int internalSize() {
Task task = getPage().createSimpleTask(OPERATION_COUNT_OBJECTS);
AccessCertificationService acs = getPage().getCertificationService();
ObjectQuery query = getQuery().clone();
query.setPaging(null); // when counting decisions we need to exclude offset+size (and sorting info is irrelevant)
List<AccessCertificationWorkItemType> workItems = acs.searchOpenWorkItems(query, notDecidedOnly, null, task, result);
count = workItems.size();
count = acs.countOpenWorkItems(query, notDecidedOnly, null, task, result);
} catch (Exception ex) {
result.recordFatalError("Couldn't count objects.", ex);
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't count objects", ex);
Expand Down
Expand Up @@ -154,6 +154,10 @@ List<AccessCertificationWorkItemType> searchOpenWorkItems(ObjectQuery caseQuery,
Collection<SelectorOptions<GetOperationOptions>> options, Task task, OperationResult parentResult)
throws ObjectNotFoundException, SchemaException, SecurityViolationException;

int countOpenWorkItems(ObjectQuery caseQuery, boolean notDecidedOnly,
Collection<SelectorOptions<GetOperationOptions>> options, Task task, OperationResult parentResult)
throws ObjectNotFoundException, SchemaException, SecurityViolationException;

/**
* Records a particular decision of a reviewer.
* @param campaignOid OID of the campaign to which the decision belongs.
Expand Down
Expand Up @@ -89,50 +89,41 @@ private ObjectQuery replaceFilter(ObjectQuery query, ObjectFilter newFilter) {
public List<AccessCertificationWorkItemType> searchOpenWorkItems(ObjectQuery baseWorkItemsQuery, MidPointPrincipal principal,
boolean notDecidedOnly, Collection<SelectorOptions<GetOperationOptions>> options, OperationResult result)
throws SchemaException, ObjectNotFoundException {
ObjectQuery newQuery = createQueryForOpenWorkItems(baseWorkItemsQuery, principal, notDecidedOnly);

// enhance filter with reviewerRef + enabled
ObjectQuery newQuery;
// retrieve cases, filtered
return repositoryService.searchContainers(AccessCertificationWorkItemType.class, newQuery, options, result);
}

private ObjectQuery createQueryForOpenWorkItems(ObjectQuery baseWorkItemsQuery, MidPointPrincipal principal,
boolean notDecidedOnly) throws SchemaException {
// enhance filter with reviewerRef + enabled
ObjectQuery newQuery;

ObjectFilter reviewerAndEnabledFilter = getReviewerAndEnabledFilterForWI(principal);
ObjectFilter reviewerAndEnabledFilter = getReviewerAndEnabledFilterForWI(principal);

ObjectFilter filterToAdd;
if (notDecidedOnly) {
ObjectFilter noResponseFilter = QueryBuilder.queryFor(AccessCertificationWorkItemType.class, prismContext)
ObjectFilter filterToAdd;
if (notDecidedOnly) {
ObjectFilter noResponseFilter = QueryBuilder.queryFor(AccessCertificationWorkItemType.class, prismContext)
.item(F_OUTPUT, F_OUTCOME).isNull()
.buildFilter();
filterToAdd = AndFilter.createAnd(reviewerAndEnabledFilter, noResponseFilter);
} else {
filterToAdd = reviewerAndEnabledFilter;
}
newQuery = replaceFilter(baseWorkItemsQuery, filterToAdd);

// retrieve cases, filtered
List<AccessCertificationWorkItemType> workItems = repositoryService.searchContainers(AccessCertificationWorkItemType.class, newQuery, options, result);

// // campaigns already loaded
// Map<String,AccessCertificationCampaignType> campaigns = new HashMap<>();
//
// // add campaignRef
// for (AccessCertificationWorkItemType workItem : workItems) {
// if (workItem.getCampaignRef() == null) {
// LOGGER.warn("AccessCertificationCaseType {} has no campaignRef -- skipping it", workItem);
// continue;
// }
// // obtain campaign object
// String campaignOid = workItem.getCampaignRef().getOid();
// AccessCertificationCampaignType campaign = campaigns.get(campaignOid);
// if (campaign == null) {
// campaign = repositoryService.getObject(AccessCertificationCampaignType.class, campaignOid, null, result).asObjectable(); // TODO error checking
// campaigns.put(campaignOid, campaign);
// }
//
// PrismObject<AccessCertificationCampaignType> campaignObject = campaign.asPrismObject();
// ObjectReferenceType campaignRef = ObjectTypeUtil.createObjectRef(campaignObject);
// workItem.setCampaignRef(campaignRef);
// workItem.getCampaignRef().asReferenceValue().setObject(campaignObject); // has to be done AFTER setCampaignRef in order to preserve the value!
// }

return workItems;
filterToAdd = AndFilter.createAnd(reviewerAndEnabledFilter, noResponseFilter);
} else {
filterToAdd = reviewerAndEnabledFilter;
}
newQuery = replaceFilter(baseWorkItemsQuery, filterToAdd);
return newQuery;
}

// principal == null => take all work items
int countOpenWorkItems(ObjectQuery baseWorkItemsQuery, MidPointPrincipal principal,
boolean notDecidedOnly, Collection<SelectorOptions<GetOperationOptions>> options, OperationResult result)
throws SchemaException, ObjectNotFoundException {

// enhance filter with reviewerRef + enabled
ObjectQuery newQuery = createQueryForOpenWorkItems(baseWorkItemsQuery, principal, notDecidedOnly);

return repositoryService.countContainers(AccessCertificationWorkItemType.class, newQuery, options, result);
}

private ObjectFilter getReviewerAndEnabledFilter(String reviewerOid) throws SchemaException {
Expand Down
Expand Up @@ -93,6 +93,7 @@ public class CertificationManagerImpl implements CertificationManager {
public static final String OPERATION_CLOSE_CURRENT_STAGE = INTERFACE_DOT + "closeCurrentStage";
public static final String OPERATION_RECORD_DECISION = INTERFACE_DOT + "recordDecision";
public static final String OPERATION_SEARCH_OPEN_WORK_ITEMS = INTERFACE_DOT + "searchOpenWorkItems";
public static final String OPERATION_COUNT_OPEN_WORK_ITEMS = INTERFACE_DOT + "countOpenWorkItems";
public static final String OPERATION_CLOSE_CAMPAIGN = INTERFACE_DOT + "closeCampaign";
public static final String OPERATION_DELEGATE_WORK_ITEMS = INTERFACE_DOT + "delegateWorkItems";
public static final String OPERATION_GET_CAMPAIGN_STATISTICS = INTERFACE_DOT + "getCampaignStatistics";
Expand Down Expand Up @@ -383,6 +384,26 @@ public List<AccessCertificationWorkItemType> searchOpenWorkItems(ObjectQuery bas
}
}

@Override
public int countOpenWorkItems(ObjectQuery baseWorkItemsQuery, boolean notDecidedOnly,
Collection<SelectorOptions<GetOperationOptions>> options, Task task, OperationResult parentResult)
throws ObjectNotFoundException, SchemaException, SecurityViolationException {

OperationResult result = parentResult.createSubresult(OPERATION_COUNT_OPEN_WORK_ITEMS);

try {
securityEnforcer.authorize(ModelAuthorizationAction.READ_OWN_CERTIFICATION_DECISIONS.getUrl(), null,
null, null, null, null, result);

return queryHelper.countOpenWorkItems(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;
} finally {
result.computeStatusIfUnknown();
}
}

@Override
public void recordDecision(@NotNull String campaignOid, long caseId, long workItemId, @Nullable AccessCertificationResponseType response,
@Nullable String comment, Task task, OperationResult parentResult) throws ObjectNotFoundException, SchemaException,
Expand Down
Expand Up @@ -21,6 +21,8 @@
import com.evolveum.midpoint.model.api.AccessCertificationService;
import com.evolveum.midpoint.model.test.AbstractModelIntegrationTest;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.prism.query.builder.QueryBuilder;
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.SelectorOptions;
Expand Down Expand Up @@ -264,8 +266,8 @@ protected AccessCertificationCaseType checkWorkItem(Collection<AccessCertificati
}

protected AccessCertificationCaseType checkCase(Collection<AccessCertificationCaseType> caseList, String objectOid,
String targetOid, FocusType focus, String campaignOid,
String tenantOid, String orgOid, ActivationStatusType administrativeStatus) {
String targetOid, FocusType focus, String campaignOid, String tenantOid, String orgOid,
ActivationStatusType administrativeStatus) {
AccessCertificationCaseType aCase = checkCase(caseList, objectOid, targetOid, focus, campaignOid);
String realTenantOid = aCase.getTenantRef() != null ? aCase.getTenantRef().getOid() : null;
String realOrgOid = aCase.getOrgRef() != null ? aCase.getOrgRef().getOid() : null;
Expand Down Expand Up @@ -345,7 +347,9 @@ protected void assertAfterCampaignCreate(AccessCertificationCampaignType campaig
assertNull("Unexpected start time", campaign.getStartTimestamp());
assertNull("Unexpected end time", campaign.getEndTimestamp());
}
protected void assertAfterCampaignStart(AccessCertificationCampaignType campaign, AccessCertificationDefinitionType definition, int cases) throws ConfigurationException, ObjectNotFoundException, SchemaException, CommunicationException, SecurityViolationException {
protected void assertAfterCampaignStart(AccessCertificationCampaignType campaign, AccessCertificationDefinitionType definition, int cases)
throws ConfigurationException, ObjectNotFoundException, SchemaException, CommunicationException,
SecurityViolationException, ExpressionEvaluationException {
assertStateAndStage(campaign, IN_REVIEW_STAGE, 1);
assertDefinitionAndOwner(campaign, definition);
assertApproximateTime("start time", new Date(), campaign.getStartTimestamp());
Expand All @@ -362,6 +366,7 @@ protected void assertAfterCampaignStart(AccessCertificationCampaignType campaign
PrismObject<AccessCertificationDefinitionType> def = getObjectViaRepo(AccessCertificationDefinitionType.class, definition.getOid());
assertApproximateTime("last campaign started", new Date(), def.asObjectable().getLastCampaignStartedTimestamp());
assertNull("unexpected last campaign closed", def.asObjectable().getLastCampaignClosedTimestamp());
assertCases(campaign.getOid(), cases);
}

protected void assertAfterStageOpen(AccessCertificationCampaignType campaign, AccessCertificationDefinitionType definition, int stageNumber) throws ConfigurationException, ObjectNotFoundException, SchemaException, CommunicationException, SecurityViolationException {
Expand Down Expand Up @@ -543,7 +548,7 @@ protected void assertDecision2(AccessCertificationCaseType _case, AccessCertific
}

protected AccessCertificationCampaignType getCampaignWithCases(String campaignOid) throws ConfigurationException, ObjectNotFoundException, SchemaException, CommunicationException, SecurityViolationException, ExpressionEvaluationException {
Task task = taskManager.createTaskInstance(AbstractModelIntegrationTest.class.getName() + ".getObject");
Task task = taskManager.createTaskInstance(AbstractCertificationTest.class.getName() + ".getObject");
OperationResult result = task.getResult();
Collection<SelectorOptions<GetOperationOptions>> options =
Arrays.asList(SelectorOptions.create(F_CASE, GetOperationOptions.createRetrieve(INCLUDE)));
Expand All @@ -553,6 +558,17 @@ protected AccessCertificationCampaignType getCampaignWithCases(String campaignOi
return campaign;
}

private int countCampaignCases(String campaignOid) throws SchemaException, SecurityViolationException {
Task task = taskManager.createTaskInstance(AbstractCertificationTest.class.getName() + ".countCampaignCases");
OperationResult result = task.getResult();
ObjectQuery query = QueryBuilder.queryFor(AccessCertificationCaseType.class, prismContext)
.ownerId(campaignOid)
.build();
int rv = modelService.countContainers(AccessCertificationCaseType.class, query, null, task, result);
result.computeStatus();
TestUtil.assertSuccess(result);
return rv;
}

protected void assertAfterStageClose(AccessCertificationCampaignType campaign, AccessCertificationDefinitionType definition, int stageNumber) {
assertStateAndStage(campaign, REVIEW_STAGE_DONE, stageNumber);
Expand All @@ -561,8 +577,8 @@ protected void assertAfterStageClose(AccessCertificationCampaignType campaign, A
assertEquals("wrong # of stages", stageNumber, campaign.getStage().size());
AccessCertificationStageType stage = CertCampaignTypeUtil.getCurrentStage(campaign);
assertEquals("wrong stage #", stageNumber, stage.getNumber());
assertApproximateTime("stage 1 start", new Date(), stage.getStartTimestamp());
assertApproximateTime("stage 1 end", new Date(), stage.getStartTimestamp());
assertApproximateTime("stage start", new Date(), stage.getStartTimestamp());
assertApproximateTime("stage end", new Date(), stage.getStartTimestamp());

for (AccessCertificationCaseType aCase : campaign.getCase()) {
if (aCase.getStageNumber() != stageNumber) {
Expand All @@ -588,7 +604,7 @@ private AccessCertificationResponseType checkCaseStageOutcome(AccessCertificatio

// completedStage - if null, checks the stage outcome in the history list
protected void assertCaseOutcome(List<AccessCertificationCaseType> caseList, String subjectOid, String targetOid,
AccessCertificationResponseType stageOutcome, AccessCertificationResponseType overallOutcome, Integer completedStage) {
AccessCertificationResponseType stageOutcome, AccessCertificationResponseType overallOutcome, Integer completedStage) {
AccessCertificationCaseType ccase = findCase(caseList, subjectOid, targetOid);
assertEquals("Wrong stage outcome in " + ccase, OutcomeUtils.toUri(stageOutcome), ccase.getCurrentStageOutcome());
assertEquals("Wrong overall outcome in " + ccase, OutcomeUtils.toUri(overallOutcome), ccase.getOutcome());
Expand All @@ -598,11 +614,18 @@ protected void assertCaseOutcome(List<AccessCertificationCaseType> caseList, Str
}
}

protected void assertPercentComplete(String campaignOid, int expCasesComplete, int expCasesDecided, int expDecisionsDone) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
protected void assertPercentComplete(String campaignOid, int expCasesComplete, int expCasesDecided, int expDecisionsDone)
throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
AccessCertificationCampaignType campaign = getCampaignWithCases(campaignOid);
assertPercentComplete(campaign, expCasesComplete, expCasesDecided, expDecisionsDone);
}

protected void assertCases(String campaignOid, int expectedCases)
throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
int cases = countCampaignCases(campaignOid);
assertEquals("Wrong # of cases for campaign " + campaignOid, expectedCases, cases);
}

protected void assertPercentComplete(AccessCertificationCampaignType campaign, int expCasesComplete, int expCasesDecided, int expDecisionsDone) {
int casesCompletePercentage = Math.round(CertCampaignTypeUtil.getCasesCompletedPercentage(campaign));
System.out.println("Cases completed = " + casesCompletePercentage + " %");
Expand Down

0 comments on commit 96164a3

Please sign in to comment.