Skip to content

Commit

Permalink
Moved allowApproveOthersItems and processCheckInterval from config.xm…
Browse files Browse the repository at this point in the history
…l to system configuration object (and changed default interval from 10 to 30 seconds).
  • Loading branch information
mederly committed Apr 14, 2016
1 parent 45fc4de commit b23cc72
Show file tree
Hide file tree
Showing 10 changed files with 58 additions and 53 deletions.
Expand Up @@ -19,6 +19,7 @@
import com.evolveum.midpoint.schema.util.SystemConfigurationTypeUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationConfigurationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.WfConfigurationType;

/**
* This is a class that statically holds current system configuration.
Expand Down Expand Up @@ -49,4 +50,12 @@ public static AccessCertificationConfigurationType getCertificationConfiguration
return null;
}
}

public static WfConfigurationType getWorkflowConfiguration() {
if (currentConfiguration != null) {
return currentConfiguration.getWorkflowConfiguration();
} else {
return null;
}
}
}
Expand Up @@ -64,10 +64,9 @@ public class WfConfiguration implements BeanFactoryAware {
public static final String KEY_ALLOW_APPROVE_OTHERS_ITEMS = "allowApproveOthersItems";

public static final List<String> KNOWN_KEYS = Arrays.asList("midpoint.home", KEY_ENABLED, KEY_JDBC_DRIVER, KEY_JDBC_URL,
KEY_JDBC_USERNAME, KEY_JDBC_PASSWORD, KEY_DATA_SOURCE, KEY_ACTIVITI_SCHEMA_UPDATE, KEY_PROCESS_CHECK_INTERVAL,
KEY_AUTO_DEPLOYMENT_FROM, KEY_ALLOW_APPROVE_OTHERS_ITEMS);
KEY_JDBC_USERNAME, KEY_JDBC_PASSWORD, KEY_DATA_SOURCE, KEY_ACTIVITI_SCHEMA_UPDATE, KEY_AUTO_DEPLOYMENT_FROM);

public static final List<String> DEPRECATED_KEYS = Collections.singletonList(CHANGE_PROCESSORS_SECTION);
public static final List<String> DEPRECATED_KEYS = Arrays.asList(CHANGE_PROCESSORS_SECTION, KEY_PROCESS_CHECK_INTERVAL, KEY_ALLOW_APPROVE_OTHERS_ITEMS);

@Autowired
private MidpointConfiguration midpointConfiguration;
Expand All @@ -92,11 +91,8 @@ public void setBeanFactory(BeanFactory beanFactory) throws BeansException {

private String dataSource;

private boolean allowApproveOthersItems;

private List<ChangeProcessor> changeProcessors = new ArrayList<>();

private int processCheckInterval;
private String[] autoDeploymentFrom;

@PostConstruct
Expand Down Expand Up @@ -163,16 +159,10 @@ void initialize() {
jdbcUser = c.getString(KEY_JDBC_USERNAME, sqlConfig != null ? sqlConfig.getJdbcUsername() : null);
jdbcPassword = c.getString(KEY_JDBC_PASSWORD, sqlConfig != null ? sqlConfig.getJdbcPassword() : null);

processCheckInterval = c.getInt(KEY_PROCESS_CHECK_INTERVAL, 10); // todo set to bigger default for production use
autoDeploymentFrom = c.getStringArray(KEY_AUTO_DEPLOYMENT_FROM);
if (autoDeploymentFrom.length == 0) {
autoDeploymentFrom = new String[] { AUTO_DEPLOYMENT_FROM_DEFAULT };
}
allowApproveOthersItems = c.getBoolean(KEY_ALLOW_APPROVE_OTHERS_ITEMS, false);

if (allowApproveOthersItems) {
LOGGER.info("allowApproveOthersItems parameter is set to true, therefore authorized users CAN approve/reject work items assigned to other users.");
}

// hibernateDialect = sqlConfig != null ? sqlConfig.getHibernateDialect() : "";

Expand Down Expand Up @@ -258,18 +248,10 @@ public String getDataSource() {
return dataSource;
}

public int getProcessCheckInterval() {
return processCheckInterval;
}

public String[] getAutoDeploymentFrom() {
return autoDeploymentFrom;
}

public boolean isAllowApproveOthersItems() {
return allowApproveOthersItems;
}

public ChangeProcessor findChangeProcessor(String processorClassName) {
for (ChangeProcessor cp : changeProcessors) {
if (cp.getClass().getName().equals(processorClassName)) {
Expand Down
Expand Up @@ -33,6 +33,7 @@
import com.evolveum.midpoint.wf.impl.tasks.WfTaskUtil;
import com.evolveum.midpoint.wf.impl.util.MiscDataUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.WfConfigurationType;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -160,14 +161,16 @@ private PrismObject determineRootTaskObject(ModelContext context) {
*
* @param rootInstruction instruction to use
* @param taskFromModel (potential) parent task
* @param result
* @return reference to a newly created job
* @param wfConfigurationType
* @param result
* @return reference to a newly created job
* @throws SchemaException
* @throws ObjectNotFoundException
*/
public WfTask submitRootTask(WfTaskCreationInstruction rootInstruction, Task taskFromModel, OperationResult result)
public WfTask submitRootTask(WfTaskCreationInstruction rootInstruction, Task taskFromModel, WfConfigurationType wfConfigurationType,
OperationResult result)
throws SchemaException, ObjectNotFoundException, ObjectAlreadyExistsException {
WfTask rootWfTask = wfTaskController.submitWfTask(rootInstruction, determineParentTaskForRoot(taskFromModel), result);
WfTask rootWfTask = wfTaskController.submitWfTask(rootInstruction, determineParentTaskForRoot(taskFromModel), wfConfigurationType, result);
result.setBackgroundTaskOid(rootWfTask.getTask().getOid());
wfTaskUtil.setRootTaskOidImmediate(taskFromModel, rootWfTask.getTask().getOid(), result);
return rootWfTask;
Expand Down
Expand Up @@ -122,25 +122,26 @@ public HookOperationMode processModelInvocation(ModelContext context, WfConfigur
LOGGER.trace("scenarioBean decided to skip scenario named {}", scenarioType.getName());
} else {
LOGGER.trace("Applying scenario {} (process name {})", scenarioType.getName(), scenarioType.getProcessName());
return applyScenario(scenarioType, scenarioBean, context, taskFromModel, result);
return applyScenario(scenarioType, scenarioBean, context, taskFromModel, wfConfigurationType, result);
}
}
LOGGER.trace("No scenario found to be applicable, exiting the change processor.");
return null;
}

private HookOperationMode applyScenario(GeneralChangeProcessorScenarioType scenarioType, GcpScenarioBean scenarioBean, ModelContext context, Task taskFromModel, OperationResult result) {
private HookOperationMode applyScenario(GeneralChangeProcessorScenarioType scenarioType, GcpScenarioBean scenarioBean, ModelContext context,
Task taskFromModel, WfConfigurationType wfConfigurationType, OperationResult result) {

try {
// ========== preparing root task ===========

WfTaskCreationInstruction rootInstruction = baseModelInvocationProcessingHelper.createInstructionForRoot(this, context, taskFromModel, result);
WfTask rootWfTask = baseModelInvocationProcessingHelper.submitRootTask(rootInstruction, taskFromModel, result);
WfTask rootWfTask = baseModelInvocationProcessingHelper.submitRootTask(rootInstruction, taskFromModel, wfConfigurationType, result);

// ========== preparing child task, starting WF process ===========

WfTaskCreationInstruction instruction = scenarioBean.prepareJobCreationInstruction(scenarioType, (LensContext<?>) context, rootWfTask, taskFromModel, result);
wfTaskController.submitWfTask(instruction, rootWfTask, result);
wfTaskController.submitWfTask(instruction, rootWfTask, wfConfigurationType, result);

// ========== complete the action ===========

Expand Down
Expand Up @@ -147,7 +147,7 @@ public HookOperationMode processModelInvocation(ModelContext context, WfConfigur
LOGGER.trace("There are no workflow processes to be started, exiting.");
return null;
}
return submitTasks(childTaskInstructions, context, changesBeingDecomposed, taskFromModel, result);
return submitTasks(childTaskInstructions, context, changesBeingDecomposed, taskFromModel, wfConfigurationType, result);
}

private List<PcpChildWfTaskCreationInstruction> gatherStartInstructions(ModelContext<? extends ObjectType> context,
Expand Down Expand Up @@ -190,15 +190,16 @@ private void logAspectResult(PrimaryChangeAspect aspect, List<? extends WfTaskCr
}
}

private HookOperationMode submitTasks(List<PcpChildWfTaskCreationInstruction> instructions, final ModelContext context, final ObjectTreeDeltas changesWithoutApproval, Task taskFromModel, OperationResult result) {
private HookOperationMode submitTasks(List<PcpChildWfTaskCreationInstruction> instructions, final ModelContext context,
final ObjectTreeDeltas changesWithoutApproval, Task taskFromModel, WfConfigurationType wfConfigurationType, OperationResult result) {

try {

ExecutionMode executionMode = determineExecutionMode(instructions);

// prepare root task and task0
WfTask rootWfTask = submitRootTask(context, changesWithoutApproval, taskFromModel, executionMode, result);
WfTask wfTask0 = submitTask0(context, changesWithoutApproval, rootWfTask, executionMode, result);
WfTask rootWfTask = submitRootTask(context, changesWithoutApproval, taskFromModel, executionMode, wfConfigurationType, result);
WfTask wfTask0 = submitTask0(context, changesWithoutApproval, rootWfTask, executionMode, wfConfigurationType, result);

// start the jobs
List<WfTask> wfTasks = new ArrayList<>(instructions.size());
Expand All @@ -209,7 +210,7 @@ private HookOperationMode submitTasks(List<PcpChildWfTaskCreationInstruction> in
// TODO CONSIDER THIS... when OID is no longer transferred
instruction.addHandlersAfterWfProcessAtEnd(WfTaskUtil.WAIT_FOR_TASKS_HANDLER_URI, WfPrepareChildOperationTaskHandler.HANDLER_URI);
}
WfTask wfTask = wfTaskController.submitWfTask(instruction, rootWfTask.getTask(), result);
WfTask wfTask = wfTaskController.submitWfTask(instruction, rootWfTask.getTask(), wfConfigurationType, result);
wfTasks.add(wfTask);
}

Expand All @@ -235,23 +236,24 @@ private HookOperationMode submitTasks(List<PcpChildWfTaskCreationInstruction> in
}

private WfTask submitRootTask(ModelContext context, ObjectTreeDeltas changesWithoutApproval, Task taskFromModel, ExecutionMode executionMode,
OperationResult result)
WfConfigurationType wfConfigurationType, OperationResult result)
throws SchemaException, ObjectNotFoundException, ObjectAlreadyExistsException {
LensContext lensContextForRootTask = determineLensContextForRootTask(context, changesWithoutApproval, executionMode);
WfTaskCreationInstruction instructionForRoot = baseModelInvocationProcessingHelper.createInstructionForRoot(this, context, taskFromModel, lensContextForRootTask, result);
if (executionMode != ALL_IMMEDIATELY) {
instructionForRoot.setHandlersBeforeModelOperation(WfPrepareRootOperationTaskHandler.HANDLER_URI); // gather all deltas from child objects
}
return baseModelInvocationProcessingHelper.submitRootTask(instructionForRoot, taskFromModel, result);
return baseModelInvocationProcessingHelper.submitRootTask(instructionForRoot, taskFromModel, wfConfigurationType, result);
}

// Child task0 - in modes 2, 3 we have to prepare first child that executes all changes that do not require approval
private WfTask submitTask0(ModelContext context, ObjectTreeDeltas changesWithoutApproval, WfTask rootWfTask, ExecutionMode executionMode, OperationResult result) throws SchemaException, ObjectNotFoundException {
private WfTask submitTask0(ModelContext context, ObjectTreeDeltas changesWithoutApproval, WfTask rootWfTask, ExecutionMode executionMode,
WfConfigurationType wfConfigurationType, OperationResult result) throws SchemaException, ObjectNotFoundException {
if (changesWithoutApproval != null && !changesWithoutApproval.isEmpty() && executionMode != ALL_AFTERWARDS) {
ModelContext task0context = contextCopyWithDeltasReplaced(context, changesWithoutApproval);
WfTaskCreationInstruction instruction0 = WfTaskCreationInstruction.createModelOnly(rootWfTask.getChangeProcessor(), task0context);
instruction0.setTaskName("Executing changes that do not require approval");
return wfTaskController.submitWfTask(instruction0, rootWfTask, result);
return wfTaskController.submitWfTask(instruction0, rootWfTask, wfConfigurationType, result);
} else {
return null;
}
Expand Down
Expand Up @@ -45,6 +45,7 @@
import com.evolveum.midpoint.wf.impl.processors.primary.PrimaryChangeProcessor;
import com.evolveum.midpoint.wf.impl.util.MiscDataUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.WfConfigurationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemType;
import org.apache.commons.lang.Validate;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -103,26 +104,28 @@ public class WfTaskController {
//region Job creation & re-creation
/**
* Creates a background task, just as prescribed by the task creation instruction.
*
* @param instruction the job creation instruction
* @param instruction the job creation instruction
* @param parentWfTask the job that will be the parent of newly created one; it may be null
*/
* @param wfConfigurationType
*/

public WfTask submitWfTask(WfTaskCreationInstruction instruction, WfTask parentWfTask, OperationResult result) throws SchemaException, ObjectNotFoundException {
return submitWfTask(instruction, parentWfTask.getTask(), result);
public WfTask submitWfTask(WfTaskCreationInstruction instruction, WfTask parentWfTask, WfConfigurationType wfConfigurationType,
OperationResult result) throws SchemaException, ObjectNotFoundException {
return submitWfTask(instruction, parentWfTask.getTask(), wfConfigurationType, result);
}

/**
* As before, but this time we know only the parent task (not a job).
*
* @param instruction the job creation instruction
* @param instruction the job creation instruction
* @param parentTask the task that will be the parent of the task of newly created job; it may be null
*/
public WfTask submitWfTask(WfTaskCreationInstruction instruction, Task parentTask, OperationResult result) throws SchemaException, ObjectNotFoundException {
* @param wfConfigurationType
*/
public WfTask submitWfTask(WfTaskCreationInstruction instruction, Task parentTask, WfConfigurationType wfConfigurationType,
OperationResult result) throws SchemaException, ObjectNotFoundException {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Processing start instruction:\n{}", instruction.debugDump());
}
Task task = submitTask(instruction, parentTask, result);
Task task = submitTask(instruction, parentTask, wfConfigurationType, result);
WfTask wfTask = recreateWfTask(task, instruction.getChangeProcessor());
if (!instruction.isNoProcess()) {
startWorkflowProcessInstance(wfTask, instruction, result);
Expand Down Expand Up @@ -170,8 +173,8 @@ public WfTask recreateRootWfTask(Task task) {

//region Working with midPoint tasks

private Task submitTask(WfTaskCreationInstruction instruction, Task parentTask, OperationResult result) throws SchemaException, ObjectNotFoundException {
Task wfTask = instruction.createTask(this, parentTask);
private Task submitTask(WfTaskCreationInstruction instruction, Task parentTask, WfConfigurationType wfConfigurationType, OperationResult result) throws SchemaException, ObjectNotFoundException {
Task wfTask = instruction.createTask(this, parentTask, wfConfigurationType);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Switching workflow root or child task to background:\n{}", wfTask.debugDump());
}
Expand Down
Expand Up @@ -55,6 +55,7 @@
public class WfTaskCreationInstruction<PRC extends ProcessorSpecificContent, PCS extends ProcessSpecificContent> implements DebugDumpable {

private static final Trace LOGGER = TraceManager.getTrace(WfTaskCreationInstruction.class);
private static final Integer DEFAULT_PROCESS_CHECK_INTERVAL = 30;

private final ChangeProcessor changeProcessor;

Expand Down Expand Up @@ -312,7 +313,7 @@ public String debugDump(int indent) {
//endregion

//region "Output" methods
public Task createTask(WfTaskController taskController, Task parentTask) throws SchemaException {
public Task createTask(WfTaskController taskController, Task parentTask, WfConfigurationType wfConfigurationType) throws SchemaException {

LOGGER.trace("createTask starting; parent task = {}", parentTask);

Expand Down Expand Up @@ -351,7 +352,8 @@ public Task createTask(WfTaskController taskController, Task parentTask) throws
if (!noProcess) {
if (simple) {
ScheduleType schedule = new ScheduleType();
schedule.setInterval(taskController.getWfConfiguration().getProcessCheckInterval());
Integer processCheckInterval = wfConfigurationType != null ? wfConfigurationType.getProcessCheckInterval() : null;
schedule.setInterval(processCheckInterval != null ? processCheckInterval : DEFAULT_PROCESS_CHECK_INTERVAL);
schedule.setEarliestStartTime(MiscUtil.asXMLGregorianCalendar(new Date(System.currentTimeMillis() + WfTaskController.TASK_START_DELAY)));
task.pushHandlerUri(WfProcessInstanceShadowTaskHandler.HANDLER_URI, schedule, TaskBinding.LOOSE);
} else {
Expand Down
Expand Up @@ -16,6 +16,7 @@

package com.evolveum.midpoint.wf.impl.util;

import com.evolveum.midpoint.common.SystemConfigurationHolder;
import com.evolveum.midpoint.model.api.ModelInteractionService;
import com.evolveum.midpoint.model.api.context.ModelContext;
import com.evolveum.midpoint.model.api.context.ModelElementContext;
Expand Down Expand Up @@ -279,7 +280,9 @@ public boolean isAuthorizedToSubmit(String taskId, String assigneeOid) {
}
// 2) is the current user allowed to approve any item?
try {
if (wfConfiguration.isAllowApproveOthersItems()
WfConfigurationType wfConfig = SystemConfigurationHolder.getWorkflowConfiguration();
boolean allowedOthersItemsApproval = wfConfig != null ? wfConfig.isAllowApproveOthersItems() : false;
if (allowedOthersItemsApproval
&& securityEnforcer.isAuthorized(AuthorizationConstants.AUTZ_UI_WORK_ITEMS_APPROVE_OTHERS_ITEMS_URL, null, null, null, null, null)) {
return true;
}
Expand Down
Expand Up @@ -65,6 +65,7 @@
</mail>
</notificationConfiguration>
<workflowConfiguration>
<allowApproveOthersItems>true</allowApproveOthersItems>
<primaryChangeProcessor>
<enabled>true</enabled>
<addAbstractRoleAspect>
Expand Down
1 change: 0 additions & 1 deletion model/workflow-impl/src/test/resources/test-config.xml
Expand Up @@ -28,7 +28,6 @@
</repository>
<workflow>
<enabled>true</enabled>
<allowApproveOthersItems>true</allowApproveOthersItems>
<jdbcUrl>jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000</jdbcUrl>
<jdbcDriver>org.h2.Driver</jdbcDriver>
<jdbcUsername>sa</jdbcUsername>
Expand Down

0 comments on commit b23cc72

Please sign in to comment.