/* * 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. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.evolveum.midpoint.certification.impl; import com.evolveum.midpoint.certification.api.OutcomeUtils; import com.evolveum.midpoint.model.impl.trigger.TriggerHandler; import com.evolveum.midpoint.model.impl.trigger.TriggerHandlerRegistry; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.CertCampaignTypeUtil; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.schema.util.WfContextUtil; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.exception.*; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.xml.datatype.Duration; import java.util.List; /** * @author mederly */ @Component public class AccCertTimedActionTriggerHandler implements TriggerHandler { public static final String HANDLER_URI = AccessCertificationConstants.NS_CERTIFICATION_TRIGGER_PREFIX + "/timed-action/handler-3"; private static final transient Trace LOGGER = TraceManager.getTrace(AccCertTimedActionTriggerHandler.class); @Autowired private TriggerHandlerRegistry triggerHandlerRegistry; @Autowired private AccCertQueryHelper queryHelper; @Autowired private AccCertUpdateHelper updateHelper; @Autowired private CertificationManagerImpl certManager; @Autowired private PrismContext prismContext; @PostConstruct private void initialize() { triggerHandlerRegistry.register(HANDLER_URI, this); } @Override public <O extends ObjectType> void handle(PrismObject<O> object, TriggerType trigger, Task triggerScannerTask, OperationResult parentResult) { if (!(object.asObjectable() instanceof AccessCertificationCampaignType)) { throw new IllegalArgumentException("Unexpected object type: should be AccessCertificationCampaignType: " + object); } AccessCertificationCampaignType campaign = (AccessCertificationCampaignType) object.asObjectable(); OperationResult result = parentResult.createSubresult(AccCertTimedActionTriggerHandler.class.getName() + ".handle"); try { Duration timeBeforeAction = ObjectTypeUtil.getExtensionItemRealValue(trigger.getExtension(), SchemaConstants.MODEL_EXTENSION_TIME_BEFORE_ACTION); if (timeBeforeAction != null) { AbstractWorkItemActionType action = ObjectTypeUtil.getExtensionItemRealValue(trigger.getExtension(), SchemaConstants.MODEL_EXTENSION_WORK_ITEM_ACTION); if (action == null) { LOGGER.warn("Notification trigger without workItemAction; ignoring it: {}", trigger); return; } executeNotifications(timeBeforeAction, action, campaign, triggerScannerTask, result); } else { WorkItemActionsType actions = ObjectTypeUtil.getExtensionItemRealValue(trigger.getExtension(), SchemaConstants.MODEL_EXTENSION_WORK_ITEM_ACTIONS); if (actions == null) { LOGGER.warn("Trigger without workItemActions; ignoring it: {}", trigger); return; } executeActions(actions, campaign, triggerScannerTask, result); } } catch (RuntimeException|ObjectNotFoundException|ObjectAlreadyExistsException|SchemaException|SecurityViolationException|ExpressionEvaluationException e) { String message = "Exception while handling campaign trigger for " + campaign + ": " + e.getMessage(); result.recordFatalError(message, e); throw new SystemException(message, e); } finally { result.computeStatusIfUnknown(); } } private void executeNotifications(Duration timeBeforeAction, AbstractWorkItemActionType action, AccessCertificationCampaignType campaign, Task wfTask, OperationResult result) throws SchemaException { WorkItemOperationKindType operationKind = WfContextUtil.getOperationKind(action); WorkItemEventCauseInformationType cause = WfContextUtil.createCause(action); // TODO notifications before throw new UnsupportedOperationException("Custom notifications are not implemented yet."); // WorkItemAllocationChangeOperationInfo operationInfo = // new WorkItemAllocationChangeOperationInfo(operationKind, workItem.getAssigneeRef(), null); // WorkItemOperationSourceInfo sourceInfo = new WorkItemOperationSourceInfo(null, cause, action); // wfTaskController.notifyWorkItemAllocationChangeCurrentActors(workItem, operationInfo, sourceInfo, timeBeforeAction, wfTask, result); } private void executeActions(WorkItemActionsType actions, AccessCertificationCampaignType campaign, Task triggerScannerTask, OperationResult result) throws SchemaException, SecurityViolationException, ObjectNotFoundException, ExpressionEvaluationException, ObjectAlreadyExistsException { for (WorkItemNotificationActionType notificationAction : actions.getNotify()) { executeNotificationAction(campaign, notificationAction, result); } if (actions.getDelegate() != null) { executeDelegateAction(campaign, actions.getDelegate(), triggerScannerTask, result); } if (actions.getEscalate() != null) { executeEscalateAction(campaign, actions.getEscalate(), triggerScannerTask, result); } if (actions.getComplete() != null) { executeCompleteAction(campaign, actions.getComplete(), triggerScannerTask, result); } } private void executeCompleteAction(AccessCertificationCampaignType campaign, CompleteWorkItemActionType completeAction, Task task, OperationResult result) throws SchemaException, SecurityViolationException, ObjectNotFoundException, ObjectAlreadyExistsException { 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); } } } private void executeDelegateAction(AccessCertificationCampaignType campaign, DelegateWorkItemActionType delegateAction, Task task, OperationResult result) throws SecurityViolationException, ObjectNotFoundException, SchemaException, ExpressionEvaluationException, ObjectAlreadyExistsException { List<AccessCertificationWorkItemType> workItems = queryHelper.searchOpenWorkItems( CertCampaignTypeUtil.createWorkItemsForCampaignQuery(campaign.getOid(), prismContext), null, true, null, result); certManager.delegateWorkItems(campaign.getOid(), workItems, delegateAction, task, result); } private void executeEscalateAction(AccessCertificationCampaignType campaign, EscalateWorkItemActionType escalateAction, Task task, OperationResult result) throws SecurityViolationException, ObjectNotFoundException, SchemaException, ExpressionEvaluationException, ObjectAlreadyExistsException { WorkItemEventCauseInformationType causeInformation = new WorkItemEventCauseInformationType() .type(WorkItemEventCauseTypeType.TIMED_ACTION) .name(escalateAction.getName()) .displayName(escalateAction.getDisplayName()); updateHelper.escalateCampaign(campaign.getOid(), escalateAction, causeInformation, task, result); } private void executeNotificationAction(AccessCertificationCampaignType campaign, @NotNull WorkItemNotificationActionType notificationAction, OperationResult result) throws SchemaException { // WorkItemEventCauseInformationType cause = createCauseInformation(notificationAction); // if (BooleanUtils.isNotFalse(notificationAction.isPerAssignee())) { // for (ObjectReferenceType assignee : campaign.getAssigneeRef()) { // wfTaskController.notifyWorkItemCustom(assignee, campaign, cause, wfTask, notificationAction, result); // } // } else { // wfTaskController.notifyWorkItemCustom(null, campaign, cause, wfTask, notificationAction, result); // } // TODO implement throw new UnsupportedOperationException("Not implemented yet."); } }