private void assertNoExistingCases(AccessCertificationCampaignType campaign, OperationResult result) throws SchemaException { List<AccessCertificationCaseType> existingCases = queryHelper.searchCases(campaign.getOid(), null, null, result); if (!existingCases.isEmpty()) { throw new IllegalStateException("Unexpected " + existingCases.size() + " certification case(s) in campaign object " + toShortString(campaign) + ". At this time there should be none."); } }
private void executeDelegateAction(AccessCertificationCampaignType campaign, DelegateWorkItemActionType delegateAction, Task task, OperationResult result) throws SecurityViolationException, ObjectNotFoundException, SchemaException, ExpressionEvaluationException, ObjectAlreadyExistsException, ConfigurationException, CommunicationException { List<AccessCertificationWorkItemType> workItems = queryHelper.searchOpenWorkItems( CertCampaignTypeUtil.createWorkItemsForCampaignQuery(campaign.getOid(), prismContext), null, true, null, result); certManager.delegateWorkItems(campaign.getOid(), workItems, delegateAction, task, result); }
void closeStage(AccessCertificationCampaignType campaign, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ObjectAlreadyExistsException { ModificationsToExecute modifications = getDeltasForStageClose(campaign, result); updateHelper.modifyCampaignPreAuthorized(campaign.getOid(), modifications, task, result); afterStageClose(campaign.getOid(), task, result); }
AccessCertificationCampaignType refreshCampaign(AccessCertificationCampaignType campaign, OperationResult result) throws ObjectNotFoundException, SchemaException { return repositoryService.getObject(AccessCertificationCampaignType.class, campaign.getOid(), null, result).asObjectable(); } //endregion
public String getCampaignNameAndOid(AccessCertificationEvent event) { return event.getCampaignName() + " (oid " + event.getCampaign().getOid() + ")"; }
public void appendStatistics(StringBuilder sb, AccessCertificationCampaignType campaign, Task task, OperationResult result) { AccessCertificationCasesStatisticsType stat; try { stat = certificationManager.getCampaignStatistics(campaign.getOid(), false, task, result); } catch (ObjectNotFoundException | SchemaException | SecurityViolationException | ObjectAlreadyExistsException | ExpressionEvaluationException | RuntimeException | CommunicationException | ConfigurationException e) { LoggingUtils.logUnexpectedException(LOGGER, "Couldn't get campaign statistics", e); sb.append("Couldn't get campaign statistics because of ").append(e); return; } int all = stat.getMarkedAsAccept() + stat.getMarkedAsRevoke() + stat.getMarkedAsReduce() + stat.getMarkedAsNotDecide() + stat.getWithoutResponse(); sb.append("Number of cases:\t").append(all); sb.append("\nMarked as ACCEPT:\t").append(stat.getMarkedAsAccept()); sb.append("\nMarked as REVOKE:\t").append(stat.getMarkedAsRevoke()) .append(" (remedied: ").append(stat.getMarkedAsRevokeAndRemedied()).append(")"); sb.append("\nMarked as REDUCE:\t").append(stat.getMarkedAsReduce()) .append(" (remedied: ").append(stat.getMarkedAsReduceAndRemedied()).append(")"); sb.append("\nMarked as NOT DECIDED:\t").append(stat.getMarkedAsNotDecide()); sb.append("\nNo response:\t\t").append(stat.getWithoutResponse()); } }
List<AccessCertificationCaseType> getOpenCasesForReviewer(AccessCertificationCampaignType campaign, String reviewerOid, OperationResult result) throws SchemaException { // note: this is OK w.r.t. iterations, as we are looking for cases with non-closed work items here ObjectFilter filter = getReviewerAndEnabledFilter(reviewerOid); return searchCases(campaign.getOid(), prismContext.queryFactory().createQuery(filter), null, result); }
private <O extends ObjectType> void startAdHocCertification(PrismObject<O> focus, String definitionOid, Task task, OperationResult result) { try { AccessCertificationDefinitionType definition = repositoryService.getObject(AccessCertificationDefinitionType.class, definitionOid, null, result).asObjectable(); AccessCertificationCampaignType newCampaign = openerHelper.createAdHocCampaignObject(definition, focus, task, result); updateHelper.addObjectPreAuthorized(newCampaign, task, result); openNextStage(newCampaign.getOid(), task, result); result.computeStatus(); } catch (RuntimeException|SchemaException|ObjectNotFoundException|SecurityViolationException|ObjectAlreadyExistsException|ExpressionEvaluationException | CommunicationException | ConfigurationException e) { result.recordFatalError("Couldn't create ad-hoc certification campaign: " + e.getMessage(), e); throw new SystemException("Couldn't create ad-hoc certification campaign: " + e.getMessage(), e); } }
private void executeCompleteAction(AccessCertificationCampaignType campaign, CompleteWorkItemActionType completeAction, Task task, OperationResult result) throws SchemaException, SecurityViolationException, ObjectNotFoundException, ObjectAlreadyExistsException, ExpressionEvaluationException, CommunicationException, ConfigurationException { List<AccessCertificationWorkItemType> workItems = queryHelper.searchOpenWorkItems( CertCampaignTypeUtil.createWorkItemsForCampaignQuery(campaign.getOid(), prismContext), null, true, null, result); for (AccessCertificationWorkItemType workItem : workItems) { AccessCertificationCaseType aCase = CertCampaignTypeUtil.getCase(workItem); if (aCase == null || aCase.getId() == null || workItem.getId() == null) { LOGGER.error("Couldn't auto-complete work item {} in case {}: some identifiers are missing", aCase, workItem); // shouldn't occur } else { certManager.recordDecision(campaign.getOid(), aCase.getId(), workItem.getId(), OutcomeUtils.fromUri(completeAction.getOutcome()), null, task, result); } } }
void notifyReviewers(AccessCertificationCampaignType campaign, boolean unansweredOnly, Task task, OperationResult result) throws SchemaException { List<AccessCertificationCaseType> caseList = queryHelper.getAllCurrentIterationCases(campaign.getOid(), norm(campaign.getIteration()), null, result); Collection<String> reviewers = CertCampaignTypeUtil.getActiveReviewers(caseList); for (String reviewerOid : reviewers) { List<AccessCertificationCaseType> cases = queryHelper.getOpenCasesForReviewer(campaign, reviewerOid, result); boolean notify = !unansweredOnly || cases.stream() .flatMap(c -> c.getWorkItem().stream()) .anyMatch(wi -> ObjectTypeUtil.containsOid(wi.getAssigneeRef(), reviewerOid) && (wi.getOutput() == null || wi.getOutput().getOutcome() == null)); if (notify) { ObjectReferenceType actualReviewerRef = ObjectTypeUtil.createObjectRef(reviewerOid, ObjectTypes.USER); for (ObjectReferenceType reviewerOrDeputyRef : getReviewerAndDeputies(actualReviewerRef, task, result)) { eventHelper.onReviewRequested(reviewerOrDeputyRef, actualReviewerRef, cases, campaign, task, result); } } } }
private void executeEscalateAction(AccessCertificationCampaignType campaign, EscalateWorkItemActionType escalateAction, Task task, OperationResult result) throws SecurityViolationException, ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException { WorkItemEventCauseInformationType causeInformation = new WorkItemEventCauseInformationType() .type(WorkItemEventCauseTypeType.TIMED_ACTION) .name(escalateAction.getName()) .displayName(escalateAction.getDisplayName()); operationsHelper.escalateCampaign(campaign.getOid(), escalateAction, causeInformation, task, result); }
void openNextStage(AccessCertificationCampaignType campaign, CertificationHandler handler, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ObjectAlreadyExistsException { boolean skipEmptyStages = norm(campaign.getIteration()) > 1; // TODO make configurable int requestedStageNumber = campaign.getStageNumber() + 1; for (;;) { OpeningContext openingContext = new OpeningContext(); AccessCertificationStageType stage = createStage(campaign, requestedStageNumber); ModificationsToExecute modifications = getDeltasForStageOpen(campaign, stage, handler, openingContext, task, result); if (!skipEmptyStages || openingContext.casesEnteringStage > 0) { updateHelper.modifyCampaignPreAuthorized(campaign.getOid(), modifications, task, result); afterStageOpen(campaign.getOid(), stage, task, result); // notifications, bookkeeping, ... return; } LOGGER.debug("No work items created, skipping to the next stage"); requestedStageNumber++; if (requestedStageNumber > CertCampaignTypeUtil.getNumberOfStages(campaign)) { result.recordWarning("No more (non-empty) stages available"); return; } } }
@NotNull private Collection<TriggerType> createTriggersForCampaignClose(AccessCertificationCampaignType campaign, OperationResult result) { if (campaign.getReiterationDefinition() == null || campaign.getReiterationDefinition().getStartsAfter() == null) { return emptySet(); } if (limitReached(campaign, campaign.getReiterationDefinition().getLimitWhenAutomatic()) || limitReached(campaign, campaign.getReiterationDefinition().getLimit())) { return emptySet(); } if (queryHelper.hasNoResponseCases(campaign.getOid(), result)) { TriggerType trigger = new TriggerType(prismContext); XMLGregorianCalendar triggerTime = clock.currentTimeXMLGregorianCalendar(); triggerTime.add(campaign.getReiterationDefinition().getStartsAfter()); trigger.setTimestamp(triggerTime); trigger.setHandlerUri(AccessCertificationCampaignReiterationTriggerHandler.HANDLER_URI); return singleton(trigger); } else { LOGGER.debug("Campaign {} has no no-response cases, skipping creation of reiteration trigger", toShortStringLazy(campaign)); return emptySet(); } }
private void createWorkItemsCloseDeltas(AccessCertificationCampaignType campaign, ModificationsToExecute modifications, XMLGregorianCalendar now, OperationResult result) throws SchemaException { 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)); for (AccessCertificationWorkItemType workItem : openWorkItems) { AccessCertificationCaseType aCase = CertCampaignTypeUtil.getCaseChecked(workItem); modifications.add( prismContext.deltaFor(AccessCertificationCampaignType.class) .item(F_CASE, aCase.getId(), F_WORK_ITEM, workItem.getId(), F_CLOSE_TIMESTAMP) .replace(now) .asItemDelta()); } }
private void addUnansweredActiveCases(List<AccessCertificationCaseType> expectedCases, List<AccessCertificationCaseType> caseList, AccessCertificationCampaignType campaign) { for (AccessCertificationCaseType aCase : caseList) { if (aCase.getStageNumber() != campaign.getStageNumber()) { continue; } if (campaign.getState() != IN_REVIEW_STAGE) { continue; } boolean emptyDecisionFound = false; for (AccessCertificationWorkItemType workItem : aCase.getWorkItem()) { if (WorkItemTypeUtil.getOutcome(workItem) == null) { emptyDecisionFound = true; break; } } if (emptyDecisionFound) { LOGGER.info("Expecting case of {}:{}", campaign.getOid(), aCase.getId()); expectedCases.add(aCase); } } }
@Test public void test010CreateCampaign() throws Exception { final String TEST_NAME = "test010CreateCampaign"; TestUtil.displayTestTitle(this, TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestEscalation.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN TestUtil.displayWhen(TEST_NAME); AccessCertificationCampaignType campaign = certificationService.createCampaign(certificationDefinition.getOid(), task, result); // THEN TestUtil.displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); assertNotNull("Created campaign is null", campaign); campaignOid = campaign.getOid(); campaign = getObject(AccessCertificationCampaignType.class, campaignOid).asObjectable(); display("campaign", campaign); assertSanityAfterCampaignCreate(campaign, certificationDefinition); assertPercentCompleteAll(campaign, 100, 100, 100); // no cases, no problems }
public void launch(AccessCertificationCampaignType campaign, OperationResult parentResult) throws SchemaException, ObjectNotFoundException { LOGGER.debug("Launching closing task handler for campaign {} as asynchronous task", toShortString(campaign)); OperationResult result = parentResult.createSubresult(CLASS_DOT + "launch"); result.addParam("campaignOid", campaign.getOid()); Task task = taskManager.createTaskInstance(); task.setHandlerUri(HANDLER_URI); task.setName(new PolyStringType("Closing " + campaign.getName())); task.setObjectRef(ObjectTypeUtil.createObjectRef(campaign, prismContext)); task.setOwner(repositoryService.getObject(UserType.class, SystemObjectsType.USER_ADMINISTRATOR.value(), null, result)); taskManager.switchToBackground(task, result); result.setBackgroundTaskOid(task.getOid()); if (result.isInProgress()) { result.recordStatus(OperationResultStatus.IN_PROGRESS, "Closing task "+task+" was successfully started, please use Server Tasks to see its status."); } LOGGER.trace("Closing task for {} switched to background, control thread returning with task {}", toShortString(campaign), task); }
public void launch(AccessCertificationCampaignType campaign, OperationResult parentResult) throws SchemaException, ObjectNotFoundException { LOGGER.info("Launching remediation task handler for campaign {} as asynchronous task", ObjectTypeUtil.toShortString(campaign)); OperationResult result = parentResult.createSubresult(CLASS_DOT + "launch"); result.addParam("campaignOid", campaign.getOid()); Task task = taskManager.createTaskInstance(); // Set handler URI so we will be called back task.setHandlerUri(HANDLER_URI); // Readable task name PolyStringType polyString = new PolyStringType("Remediation for " + campaign.getName()); task.setName(polyString); // Set reference to the resource task.setObjectRef(ObjectTypeUtil.createObjectRef(campaign, prismContext)); task.setOwner(repositoryService.getObject(UserType.class, SystemObjectsType.USER_ADMINISTRATOR.value(), null, result)); taskManager.switchToBackground(task, result); result.setBackgroundTaskOid(task.getOid()); if (result.isInProgress()) { result.recordStatus(OperationResultStatus.IN_PROGRESS, "Remediation task "+task+" was successfully started, please use Server Tasks to see its status."); } LOGGER.trace("Remediation for {} switched to background, control thread returning with task {}", ObjectTypeUtil.toShortString(campaign), task); }
private void createCasesReiterationDeltas(AccessCertificationCampaignType campaign, int newIteration, ModificationsToExecute modifications, OperationResult result) throws SchemaException { ObjectQuery unresolvedCasesQuery = prismContext.queryFor(AccessCertificationCaseType.class) .item(AccessCertificationCaseType.F_OUTCOME).eq(SchemaConstants.MODEL_CERTIFICATION_OUTCOME_NO_RESPONSE) .build(); List<AccessCertificationCaseType> unresolvedCases = queryHelper .searchCases(campaign.getOid(), unresolvedCasesQuery, null, result); for (AccessCertificationCaseType aCase : unresolvedCases) { modifications.add( prismContext.deltaFor(AccessCertificationCampaignType.class) .item(F_CASE, aCase.getId(), F_ITERATION).replace(newIteration) .item(F_CASE, aCase.getId(), F_STAGE_NUMBER).replace(0) .item(F_CASE, aCase.getId(), F_CURRENT_STAGE_OUTCOME).replace() .item(F_CASE, aCase.getId(), F_CURRENT_STAGE_DEADLINE).replace() .item(F_CASE, aCase.getId(), F_CURRENT_STAGE_CREATE_TIMESTAMP).replace() .item(F_CASE, aCase.getId(), F_REVIEW_FINISHED_TIMESTAMP).replace() .asItemDeltas()); } }
void closeCampaign(AccessCertificationCampaignType campaign, Task task, OperationResult result) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException { LOGGER.info("Closing campaign {}", ObjectTypeUtil.toShortString(campaign)); XMLGregorianCalendar now = clock.currentTimeXMLGregorianCalendar(); int lastStageNumber = CertCampaignTypeUtil.getNumberOfStages(campaign); // TODO issue a warning if we are not in a correct state ModificationsToExecute modifications = new ModificationsToExecute(); modifications.add(updateHelper.createStageNumberDelta(lastStageNumber + 1)); modifications.add(updateHelper.createStateDelta(CLOSED)); modifications.add(updateHelper.createTriggerReplaceDelta(createTriggersForCampaignClose(campaign, result))); modifications.add(updateHelper.createEndTimeDelta(now)); createWorkItemsCloseDeltas(campaign, modifications, now, result); updateHelper.modifyCampaignPreAuthorized(campaign.getOid(), modifications, task, result); AccessCertificationCampaignType updatedCampaign = updateHelper.refreshCampaign(campaign, result); eventHelper.onCampaignEnd(updatedCampaign, task, result); if (campaign.getDefinitionRef() != null) { List<ItemDelta<?,?>> definitionDeltas = prismContext.deltaFor(AccessCertificationDefinitionType.class) .item(F_LAST_CAMPAIGN_CLOSED_TIMESTAMP).replace(now) .asItemDeltas(); updateHelper.modifyObjectPreAuthorized(AccessCertificationDefinitionType.class, campaign.getDefinitionRef().getOid(), definitionDeltas, task, result); } }