diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/DeltaConvertor.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/DeltaConvertor.java
index 2c7f5872782..6bd8eb40cc4 100644
--- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/DeltaConvertor.java
+++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/DeltaConvertor.java
@@ -102,7 +102,9 @@ public static ObjectDelta createObjectDelta(ObjectDelt
ObjectType objectToAddElement = objectDeltaType.getObjectToAdd();
// PrismObject objectToAdd = prismContext.getXnodeProcessor().parseObject(objectToAddElement.getXnode());
// PrismObject objectToAdd = prismContext.getJaxbDomHack().parseObjectFromJaxb(objectToAddElement);
- objectDelta.setObjectToAdd(objectToAddElement.asPrismObject());
+ if (objectToAddElement != null) {
+ objectDelta.setObjectToAdd(objectToAddElement.asPrismObject());
+ }
return objectDelta;
} else if (objectDeltaType.getChangeType() == ChangeTypeType.MODIFY) {
ObjectDelta objectDelta = new ObjectDelta(type, ChangeType.MODIFY, prismContext);
diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-3.xsd
index a4ee90f91b3..938f43a2412 100644
--- a/infra/schema/src/main/resources/xml/ns/public/common/common-3.xsd
+++ b/infra/schema/src/main/resources/xml/ns/public/common/common-3.xsd
@@ -6513,6 +6513,9 @@
For explicitness, only one of approverRef(s)/approverExpression(s),
approvalSchema and approvalProcess should be specified.
+
+ THIS PROPERTY (approvalProcess) IS NOT SUPPORTED YET.
+
@@ -10027,6 +10030,7 @@
Order in which the change processor should be invoked. (Unspecified means "at the end".)
+ NOT IMPLEMENTED YET.
@@ -10111,8 +10115,9 @@
-
-
+
+
+
@@ -10132,6 +10137,12 @@
They take all the approver information directly from the object (role or resource) being assigned.
However, there are some others (namely, role/resource/user/whatever add/modify aspects) that need
the explicit information about approver(s) in order to know where to route the request.
+
+ For the former aspects, the approver information specified here takes precedence over
+ approver information derived from the objects being used (e.g. role or resource).
+ More specifically, if any approver information is here, no approver information is
+ taken from the objects. This could be changed (e.g. by allowing to tune this behavior)
+ in the future.
@@ -10180,6 +10191,8 @@
For explicitness, only one of approverRef(s)/approverExpression(s),
approvalSchema and approvalProcess should be specified.
+
+ THIS PROPERTY (approvalProcess) IS NOT SUPPORTED YET.
diff --git a/infra/schema/src/main/resources/xml/ns/public/model/workflow/common-forms-3.xsd b/infra/schema/src/main/resources/xml/ns/public/model/workflow/common-forms-3.xsd
index 0b0be9a7456..114d2fa4c9f 100644
--- a/infra/schema/src/main/resources/xml/ns/public/model/workflow/common-forms-3.xsd
+++ b/infra/schema/src/main/resources/xml/ns/public/model/workflow/common-forms-3.xsd
@@ -417,4 +417,45 @@
+
+
+
+ TODO
+
+
+
+
+
+
+
+
+ Object to be added
+ 100
+ read
+
+
+
+
+
+
+ Requester's comment
+ 110
+ read
+
+
+
+
+
+
+ Your comment
+ 120
+
+
+
+
+
+
+
+
+
diff --git a/infra/test-util/src/main/java/com/evolveum/midpoint/test/ldap/OpenDJController.java b/infra/test-util/src/main/java/com/evolveum/midpoint/test/ldap/OpenDJController.java
index 3837305499a..07ffb26f9e5 100755
--- a/infra/test-util/src/main/java/com/evolveum/midpoint/test/ldap/OpenDJController.java
+++ b/infra/test-util/src/main/java/com/evolveum/midpoint/test/ldap/OpenDJController.java
@@ -236,6 +236,7 @@ private void extractTemplate(File dst, String templateName) throws IOException,
}
templateRoot = new File(DATA_TEMPLATE_DIR, templateName);
+ String templateRootPath = DATA_TEMPLATE_DIR + "/" + templateName; // templateRoot.getPath does not work on Windows, as it puts "\" into the path name (leading to problems with getSystemResource)
// Determing if we need to extract from JAR or directory
if (templateRoot.isDirectory()) {
@@ -244,7 +245,6 @@ private void extractTemplate(File dst, String templateName) throws IOException,
return;
}
- String templateRootPath = templateRoot.getPath();
LOGGER.debug("Try to localize OpenDJ Template in JARs as " + templateRootPath);
URL srcUrl = ClassLoader.getSystemResource(templateRootPath);
diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/ModelContext.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/ModelContext.java
index ae0146a9a8c..121e3b3f017 100644
--- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/ModelContext.java
+++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/ModelContext.java
@@ -21,9 +21,11 @@
import com.evolveum.midpoint.common.refinery.ResourceShadowDiscriminator;
import com.evolveum.midpoint.model.api.ProgressInformation;
import com.evolveum.midpoint.prism.PrismContext;
+import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.delta.DeltaSetTriple;
import com.evolveum.midpoint.util.DebugDumpable;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType;
/**
* @author semancik
@@ -46,4 +48,6 @@ public interface ModelContext extends Serializable, DebugD
DeltaSetTriple extends EvaluatedAssignment> getEvaluatedAssignmentTriple();
PrismContext getPrismContext(); // use with care
+
+ PrismObject getSystemConfiguration(); // beware, may be null - use only as a performance optimization
}
diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/WorkflowListener.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/WorkflowListener.java
index bc2210b2b08..795fbe92891 100644
--- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/WorkflowListener.java
+++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/WorkflowListener.java
@@ -99,7 +99,7 @@ private void processEvent(WorkflowEvent event, OperationResult result) {
notificationManager.processEvent(event);
} catch (RuntimeException e) {
result.recordFatalError("An unexpected exception occurred when preparing and sending notifications: " + e.getMessage(), e);
- LoggingUtils.logException(LOGGER, "An unexpected exception occurred when preparing and sending notifications: " + e.getMessage(), e);
+ LoggingUtils.logUnexpectedException(LOGGER, "An unexpected exception occurred when preparing and sending notifications: " + e.getMessage(), e);
}
// todo work correctly with operationResult (in whole notification module)
@@ -113,7 +113,7 @@ private void processEvent(WorkflowEvent event) {
try {
notificationManager.processEvent(event);
} catch (RuntimeException e) {
- LoggingUtils.logException(LOGGER, "An unexpected exception occurred when preparing and sending notifications: " + e.getMessage(), e);
+ LoggingUtils.logUnexpectedException(LOGGER, "An unexpected exception occurred when preparing and sending notifications: " + e.getMessage(), e);
}
}
}
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/WfConfiguration.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/WfConfiguration.java
index b36296b7509..a655db0fb5a 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/WfConfiguration.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/WfConfiguration.java
@@ -24,6 +24,7 @@
import com.evolveum.midpoint.util.logging.LoggingUtils;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
+import com.evolveum.midpoint.wf.impl.processors.BaseChangeProcessor;
import com.evolveum.midpoint.wf.impl.processors.ChangeProcessor;
import org.apache.commons.configuration.Configuration;
@@ -53,7 +54,7 @@ public class WfConfiguration implements BeanFactoryAware {
private static final transient Trace LOGGER = TraceManager.getTrace(WfConfiguration.class);
private static final String WF_CONFIG_SECTION = "midpoint.workflow";
- private static final String CHANGE_PROCESSORS_SECTION = "changeProcessors";
+ private static final String CHANGE_PROCESSORS_SECTION = "changeProcessors"; // deprecated
public static final String KEY_ENABLED = "enabled";
public static final String KEY_JDBC_DRIVER = "jdbcDriver";
@@ -68,9 +69,11 @@ public class WfConfiguration implements BeanFactoryAware {
public static final List 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, CHANGE_PROCESSORS_SECTION);
+ KEY_AUTO_DEPLOYMENT_FROM, KEY_ALLOW_APPROVE_OTHERS_ITEMS);
- @Autowired(required = true)
+ public static final List DEPRECATED_KEYS = Arrays.asList(CHANGE_PROCESSORS_SECTION);
+
+ @Autowired
private MidpointConfiguration midpointConfiguration;
private BeanFactory beanFactory;
@@ -95,7 +98,7 @@ public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
private boolean allowApproveOthersItems;
- private List changeProcessors = null;
+ private List changeProcessors = new ArrayList<>();
private int processCheckInterval;
private String[] autoDeploymentFrom;
@@ -105,7 +108,7 @@ void initialize() {
Configuration c = midpointConfiguration.getConfiguration(WF_CONFIG_SECTION);
- checkAllowedKeys(c, KNOWN_KEYS);
+ checkAllowedKeys(c, KNOWN_KEYS, DEPRECATED_KEYS);
enabled = c.getBoolean(KEY_ENABLED, true);
if (!enabled) {
@@ -180,8 +183,9 @@ void initialize() {
validate();
}
- public void checkAllowedKeys(Configuration c, List knownKeys) {
- Set knownKeysSet = new HashSet(knownKeys);
+ public void checkAllowedKeys(Configuration c, List knownKeys, List deprecatedKeys) {
+ Set knownKeysSet = new HashSet<>(knownKeys);
+ Set deprecatedKeysSet = new HashSet<>(deprecatedKeys);
Iterator keyIterator = c.getKeys();
while (keyIterator.hasNext()) {
@@ -192,6 +196,9 @@ public void checkAllowedKeys(Configuration c, List knownKeys) {
if (colon != -1) {
normalizedKeyName = normalizedKeyName.substring(colon + 1);
}
+ if (deprecatedKeysSet.contains(keyName) || deprecatedKeysSet.contains(normalizedKeyName)) {
+ throw new SystemException("Deprecated key " + keyName + " in workflow configuration. Please see https://wiki.evolveum.com/display/midPoint/Workflow+configuration.");
+ }
if (!knownKeysSet.contains(keyName) && !knownKeysSet.contains(normalizedKeyName)) { // ...we need to test both because of keys like 'midpoint.home'
throw new SystemException("Unknown key " + keyName + " in workflow configuration");
}
@@ -267,46 +274,8 @@ public boolean isAllowApproveOthersItems() {
return allowApproveOthersItems;
}
- public synchronized List getChangeProcessors() {
- if (changeProcessors != null) {
- return changeProcessors;
- }
-
- changeProcessors = new ArrayList();
-
- if (!enabled) {
- return changeProcessors;
- }
-
- List changeProcessorNames = new ArrayList(); // list - to preserve order
-
- Iterator cpIterator = getChangeProcessorsConfig().getKeys(); // returns 'processor-name' but also 'other-processor-name.aspect-name' etc.
- while (cpIterator.hasNext()) {
- String keyName = cpIterator.next();
- String processorName = StringUtils.substringBefore(keyName, ".");
- if (!changeProcessorNames.contains(processorName)) {
- changeProcessorNames.add(processorName);
- }
- }
-
- LOGGER.trace("Resolving change processors: {}", changeProcessorNames);
-
- for (String processorName : changeProcessorNames) {
- LOGGER.trace("Searching for change processor {}", processorName);
- try {
- ChangeProcessor processor = (ChangeProcessor) beanFactory.getBean(processorName);
- changeProcessors.add(processor);
- } catch(BeansException e) {
- throw new SystemException("Change processor " + processorName + " could not be found.", e);
- }
- }
-
- LOGGER.debug("Resolved " + changeProcessors.size() + " change processors.");
- return changeProcessors;
- }
-
public ChangeProcessor findChangeProcessor(String processorClassName) {
- for (ChangeProcessor cp : getChangeProcessors()) {
+ for (ChangeProcessor cp : changeProcessors) {
if (processorClassName.equals(cp.getClass().getName())) {
return cp;
}
@@ -314,4 +283,12 @@ public ChangeProcessor findChangeProcessor(String processorClassName) {
throw new IllegalStateException("Change processor " + processorClassName + " is not registered.");
}
+
+ public void registerProcessor(ChangeProcessor changeProcessor) {
+ changeProcessors.add(changeProcessor);
+ }
+
+ public List getChangeProcessors() {
+ return changeProcessors;
+ }
}
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/WfHook.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/WfHook.java
index 29890572dff..3d432d95151 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/WfHook.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/WfHook.java
@@ -30,8 +30,11 @@
import com.evolveum.midpoint.util.logging.LoggingUtils;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
+import com.evolveum.midpoint.wf.impl.processors.BaseConfigurationHelper;
import com.evolveum.midpoint.wf.impl.processors.ChangeProcessor;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.WfConfigurationType;
import org.apache.commons.lang.Validate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -57,6 +60,9 @@ public class WfHook implements ChangeHook {
@Autowired
private WfConfiguration wfConfiguration;
+ @Autowired
+ private BaseConfigurationHelper baseConfigurationHelper;
+
@Autowired
private HookRegistry hookRegistry;
@@ -84,11 +90,30 @@ public HookOperationMode invoke(ModelContext context, Task task, OperationResult
result.addParam("taskFromModel", task.toString());
result.addContext("model state", context.getState());
+ WfConfigurationType wfConfigurationType = baseConfigurationHelper.getWorkflowConfiguration(context, result);
+ if (wfConfigurationType == null) { // should not occur, but ... (e.g. when initially loading objects into repository; if done in non-raw mode)
+ LOGGER.warn("No system configuration. Workflow approvals are disabled. Proceeding with operation execution as if everything is approved.");
+ result.recordSuccess();
+ return HookOperationMode.FOREGROUND;
+ }
+ if (Boolean.FALSE.equals(wfConfigurationType.isModelHookEnabled())) {
+ LOGGER.info("Workflow model hook is disabled. Proceeding with operation execution as if everything is approved.");
+ result.recordSuccess();
+ return HookOperationMode.FOREGROUND;
+ }
+
logOperationInformation(context);
- HookOperationMode retval = processModelInvocation(context, task, result);
- result.recordSuccessIfUnknown();
- return retval;
+ try {
+ HookOperationMode retval = processModelInvocation(context, wfConfigurationType, task, result);
+ result.recordSuccessIfUnknown();
+ return retval;
+ } catch (RuntimeException e) {
+ if (result.isUnknown()) {
+ result.recordFatalError("Couldn't process model invocation in workflow module: " + e.getMessage(), e);
+ }
+ throw e;
+ }
}
@Override
@@ -123,7 +148,7 @@ private void logOperationInformation(ModelContext context) {
}
}
- HookOperationMode processModelInvocation(ModelContext context, Task taskFromModel, OperationResult result) {
+ HookOperationMode processModelInvocation(ModelContext extends ObjectType> context, WfConfigurationType wfConfigurationType, Task taskFromModel, OperationResult result) {
try {
@@ -133,12 +158,8 @@ HookOperationMode processModelInvocation(ModelContext context, Task taskFromMode
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Trying change processor: " + changeProcessor.getClass().getName());
}
- if (!changeProcessor.isEnabled()) {
- LOGGER.trace("It is disabled, continuing with next one.");
- continue;
- }
try {
- HookOperationMode hookOperationMode = changeProcessor.processModelInvocation(context, taskFromModel, result);
+ HookOperationMode hookOperationMode = changeProcessor.processModelInvocation(context, wfConfigurationType, taskFromModel, result);
if (hookOperationMode != null) {
return hookOperationMode;
}
@@ -168,5 +189,4 @@ HookOperationMode processModelInvocation(ModelContext context, Task taskFromMode
return HookOperationMode.FOREGROUND;
}
-
}
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/jobs/WfTaskUtil.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/jobs/WfTaskUtil.java
index 8e2378abd5b..7494644db04 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/jobs/WfTaskUtil.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/jobs/WfTaskUtil.java
@@ -243,7 +243,7 @@ public void setPrimaryChangeAspect(Task task, PrimaryChangeAspect aspect) throws
task.setExtensionProperty(w);
}
- public PrimaryChangeAspect getPrimaryChangeAspect(Task task, List aspects) {
+ public PrimaryChangeAspect getPrimaryChangeAspect(Task task, Collection aspects) {
String aspectClassName = getExtensionValue(String.class, task, PcpTaskExtensionItemsNames.WFPRIMARY_CHANGE_ASPECT_NAME);
if (aspectClassName == null) {
throw new IllegalStateException("No wf primary change aspect defined in task " + task);
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/ApprovalRequestImpl.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/ApprovalRequestImpl.java
index d12583e2e78..e25c41c35b1 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/ApprovalRequestImpl.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/ApprovalRequestImpl.java
@@ -40,11 +40,32 @@ public class ApprovalRequestImpl implements ApprovalRequ
private ApprovalSchema approvalSchema;
- public ApprovalRequestImpl(I itemToApprove, ApprovalSchemaType approvalSchema, List approverRef, List approverExpression, ExpressionType automaticallyApproved, PrismContext prismContext) {
-
+ private ApprovalRequestImpl(I itemToApprove, PrismContext prismContext) {
setPrismContext(prismContext);
setItemToApprove(itemToApprove);
- setApprovalSchema(new ApprovalSchemaImpl(approvalSchema, approverRef, approverExpression, automaticallyApproved, prismContext));
+ }
+
+ public ApprovalRequestImpl(I itemToApprove, PcpAspectConfigurationType config, PrismContext prismContext) {
+ this(itemToApprove, prismContext);
+ if (config != null) {
+ setApprovalSchema(new ApprovalSchemaImpl(config.getApprovalSchema(), config.getApproverRef(),
+ config.getApproverExpression(), config.getAutomaticallyApproved(), prismContext));
+ }
+ }
+
+ public ApprovalRequestImpl(I itemToApprove, PcpAspectConfigurationType config, ApprovalSchemaType approvalSchema, List approverRef, List approverExpression, ExpressionType automaticallyApproved, PrismContext prismContext) {
+ this(itemToApprove, prismContext);
+ if (config != null &&
+ (!config.getApproverRef().isEmpty() ||
+ config.getApprovalSchema() != null ||
+ !config.getApproverExpression().isEmpty() ||
+ config.getAutomaticallyApproved() != null)) {
+ setApprovalSchema(new ApprovalSchemaImpl(config.getApprovalSchema(), config.getApproverRef(),
+ config.getApproverExpression(), config.getAutomaticallyApproved(), prismContext));
+ } else {
+ setApprovalSchema(new ApprovalSchemaImpl(approvalSchema, approverRef,
+ approverExpression, automaticallyApproved, prismContext));
+ }
}
@Override
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseChangeProcessor.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseChangeProcessor.java
index dcb63aba6db..33a26e92197 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseChangeProcessor.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseChangeProcessor.java
@@ -58,11 +58,6 @@ public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
- @Override
- public boolean isEnabled() {
- return enabled;
- }
-
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseConfigurationHelper.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseConfigurationHelper.java
index 7923dd2c5d8..b70c7a23e6b 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseConfigurationHelper.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseConfigurationHelper.java
@@ -17,16 +17,25 @@
package com.evolveum.midpoint.wf.impl.processors;
import com.evolveum.midpoint.common.validator.Validator;
+import com.evolveum.midpoint.model.api.context.ModelContext;
+import com.evolveum.midpoint.model.impl.util.Utils;
import com.evolveum.midpoint.prism.PrismContext;
+import com.evolveum.midpoint.prism.PrismObject;
+import com.evolveum.midpoint.repo.api.RepositoryService;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.util.exception.SchemaException;
+import com.evolveum.midpoint.util.exception.SystemException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.wf.impl.WfConfiguration;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.WfConfigurationType;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.lang.Validate;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.w3c.dom.Element;
@@ -55,40 +64,29 @@ public class BaseConfigurationHelper {
@Autowired
private PrismContext prismContext;
- public void configureProcessor(BaseChangeProcessor changeProcessor, List locallyKnownKeys) {
-
- String beanName = changeProcessor.getBeanName();
+ @Autowired
+ @Qualifier("cacheRepositoryService")
+ private RepositoryService repositoryService;
- Validate.notNull(beanName, "Bean name was not set correctly.");
+ public void registerProcessor(BaseChangeProcessor changeProcessor) {
+ wfConfiguration.registerProcessor(changeProcessor);
+ }
- Configuration c = wfConfiguration.getChangeProcessorsConfig().subset(beanName);
- if (c.isEmpty()) {
- LOGGER.info("Skipping reading configuration of " + beanName + ", as it is not on the list of change processors or is empty.");
- return;
+ public WfConfigurationType getWorkflowConfiguration(ModelContext extends ObjectType> context, OperationResult result) {
+ if (context != null && context.getSystemConfiguration() != null) {
+ SystemConfigurationType systemConfigurationType = context.getSystemConfiguration().asObjectable();
+ return systemConfigurationType.getWorkflowConfiguration();
}
-
- List allKnownKeys = new ArrayList<>(KNOWN_KEYS);
- if (locallyKnownKeys != null) {
- allKnownKeys.addAll(locallyKnownKeys);
+ PrismObject systemConfigurationTypePrismObject = null;
+ try {
+ systemConfigurationTypePrismObject = Utils.getSystemConfiguration(repositoryService, result);
+ } catch (SchemaException e) {
+ throw new SystemException("Couldn't get system configuration because of schema exception - cannot continue", e);
}
- wfConfiguration.checkAllowedKeys(c, allKnownKeys);
-
- boolean enabled = c.getBoolean(KEY_ENABLED, true);
- if (!enabled) {
- LOGGER.info("Change processor " + beanName + " is DISABLED.");
+ if (systemConfigurationTypePrismObject == null) {
+ // this is possible e.g. when importing initial objects; warning is already issued by Utils.getSystemConfiguration method
+ return null;
}
- changeProcessor.setEnabled(enabled);
- changeProcessor.setProcessorConfiguration(c);
+ return systemConfigurationTypePrismObject.asObjectable().getWorkflowConfiguration();
}
-
- public void validateElement(Element element) throws SchemaException {
- OperationResult result = new OperationResult("validateElement");
- Validator validator = new Validator(prismContext);
- validator.validateSchema(element, result);
- result.computeStatus();
- if (!result.isSuccess()) {
- throw new SchemaException(result.getMessage(), result.getCause());
- }
- }
-
}
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/ChangeProcessor.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/ChangeProcessor.java
index c62f1c0f872..0429d480215 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/ChangeProcessor.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/ChangeProcessor.java
@@ -31,6 +31,7 @@
import com.evolveum.midpoint.wf.impl.jobs.Job;
import com.evolveum.midpoint.wf.impl.messages.ProcessEvent;
import com.evolveum.midpoint.wf.impl.messages.TaskEvent;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.WfConfigurationType;
import com.evolveum.midpoint.xml.ns.model.workflow.common_forms_3.WorkItemContents;
import com.evolveum.midpoint.xml.ns.model.workflow.process_instance_state_3.ProcessInstanceState;
@@ -67,9 +68,9 @@ public interface ChangeProcessor {
* and arranges everything to carry out that interaction.
*
* @param context Model context of the operation.
- * @param taskFromModel Task in context of which the operation is carried out.
- * @param result Where to put information on operation execution.
- * @return non-null value if it processed the request;
+ * @param wfConfigurationType
+ *@param taskFromModel Task in context of which the operation is carried out.
+ * @param result Where to put information on operation execution. @return non-null value if it processed the request;
* BACKGROUND = the process was "caught" by the processor, and continues in background,
* FOREGROUND = nothing was left on background, the model operation should continue in foreground,
* ERROR = something wrong has happened, there's no point in continuing with this operation.
@@ -78,7 +79,7 @@ public interface ChangeProcessor {
* Actually, the FOREGROUND return value is quite unusual, because the change processor cannot
* know in advance whether other processors would not want to process the invocation from the model.
*/
- HookOperationMode processModelInvocation(ModelContext context, Task taskFromModel, OperationResult result) throws SchemaException;
+ HookOperationMode processModelInvocation(ModelContext context, WfConfigurationType wfConfigurationType, Task taskFromModel, OperationResult result) throws SchemaException;
/**
* Handles an event from WfMS that indicates finishing of the workflow process instance.
@@ -93,12 +94,6 @@ public interface ChangeProcessor {
*/
void onProcessEnd(ProcessEvent event, Job job, OperationResult result) throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException;
- /**
- * Checks whether this change processor is enabled (typically, using the midpoint configuration file).
- * @return true if enabled, false if not
- */
- boolean isEnabled();
-
/**
* Externalizes internal state of the process instance. Typically, uninteresting (auxiliary) data elements
* are thrown away, internal representation suitable for workflow processing is replaced by "clean" prism
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/GcpConfigurationHelper.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/GcpConfigurationHelper.java
index f2b8d64a0ab..25a22f2ef39 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/GcpConfigurationHelper.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/GcpConfigurationHelper.java
@@ -50,9 +50,6 @@ public class GcpConfigurationHelper {
private static final Trace LOGGER = TraceManager.getTrace(GcpConfigurationHelper.class);
- private static final String KEY_GENERAL_CHANGE_PROCESSOR_CONFIGURATION = "generalChangeProcessorConfiguration";
- private static final List LOCALLY_KNOWN_KEYS = Arrays.asList(KEY_GENERAL_CHANGE_PROCESSOR_CONFIGURATION);
-
@Autowired
private BaseConfigurationHelper baseConfigurationHelper;
@@ -62,51 +59,4 @@ public class GcpConfigurationHelper {
@Autowired
private PrismContext prismContext;
- GeneralChangeProcessorConfigurationType configure(GeneralChangeProcessor generalChangeProcessor) {
- baseConfigurationHelper.configureProcessor(generalChangeProcessor, LOCALLY_KNOWN_KEYS);
- if (generalChangeProcessor.isEnabled()) {
- return readConfiguration(generalChangeProcessor);
- } else {
- return null;
- }
- }
-
- private GeneralChangeProcessorConfigurationType readConfiguration(GeneralChangeProcessor generalChangeProcessor) {
- String beanName = generalChangeProcessor.getBeanName();
-
- String path = determineConfigurationPath(generalChangeProcessor);
- LOGGER.info("Configuration path: " + path);
-
- Document midpointConfig = midpointConfiguration.getXmlConfigAsDocument();
- Validate.notNull(midpointConfig, "XML version of midPoint configuration couldn't be found");
-
- XPath xpath = XPathFactory.newInstance().newXPath();
- try {
- Element processorConfig = (Element) xpath.evaluate(path + "/*[local-name()='" + KEY_GENERAL_CHANGE_PROCESSOR_CONFIGURATION + "']", midpointConfig, XPathConstants.NODE);
- if (processorConfig == null) {
- throw new SystemException("There's no " + KEY_GENERAL_CHANGE_PROCESSOR_CONFIGURATION + " element in " + beanName + " configuration.");
- }
- if (LOGGER.isTraceEnabled()) {
- LOGGER.trace("processor configuration = {}", DOMUtil.printDom(processorConfig));
- }
- try {
- baseConfigurationHelper.validateElement(processorConfig);
- } catch (SchemaException e) {
- throw new SystemException("Schema validation failed for " + KEY_GENERAL_CHANGE_PROCESSOR_CONFIGURATION + " element in " + beanName + " configuration: " + e.getMessage(), e);
- }
- return prismContext.parseAnyValue(processorConfig);
- } catch (XPathExpressionException|SchemaException e) {
- throw new SystemException("Couldn't read general workflow processor configuration in " + beanName, e);
- }
- }
-
- // if this would not work, use simply "/configuration/midpoint/workflow/changeProcessors/generalChangeProcessor/" :)
- private String determineConfigurationPath(GeneralChangeProcessor generalChangeProcessor) {
- Configuration c = generalChangeProcessor.getProcessorConfiguration();
- if (!(c instanceof SubsetConfiguration)) {
- throw new IllegalStateException(generalChangeProcessor.getBeanName() + " configuration is not a subset configuration, it is " + c.getClass());
- }
- SubsetConfiguration sc = (SubsetConfiguration) c;
- return "/*/" + sc.getPrefix().replace(".", "/");
- }
}
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/GeneralChangeProcessor.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/GeneralChangeProcessor.java
index d34d961b764..03a35f52a11 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/GeneralChangeProcessor.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/GeneralChangeProcessor.java
@@ -28,14 +28,15 @@
import com.evolveum.midpoint.wf.impl.messages.TaskEvent;
import com.evolveum.midpoint.wf.impl.processors.BaseAuditHelper;
import com.evolveum.midpoint.wf.impl.processors.BaseChangeProcessor;
+import com.evolveum.midpoint.wf.impl.processors.BaseConfigurationHelper;
import com.evolveum.midpoint.wf.impl.processors.BaseExternalizationHelper;
import com.evolveum.midpoint.wf.impl.processors.BaseModelInvocationProcessingHelper;
import com.evolveum.midpoint.wf.impl.processors.general.scenarios.DefaultGcpScenarioBean;
import com.evolveum.midpoint.wf.impl.processors.general.scenarios.GcpScenarioBean;
-import com.evolveum.midpoint.wf.impl.util.JaxbValueContainer;
import com.evolveum.midpoint.wf.impl.util.SerializationSafeContainer;
import com.evolveum.midpoint.xml.ns._public.common.common_3.GeneralChangeProcessorConfigurationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.GeneralChangeProcessorScenarioType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.WfConfigurationType;
import com.evolveum.midpoint.xml.ns._public.model.model_context_3.LensContextType;
import com.evolveum.midpoint.xml.ns.model.workflow.common_forms_3.WorkItemContents;
import com.evolveum.midpoint.xml.ns.model.workflow.process_instance_state_3.ProcessInstanceState;
@@ -73,6 +74,9 @@ public class GeneralChangeProcessor extends BaseChangeProcessor {
@Autowired
private BaseExternalizationHelper baseExternalizationHelper;
+ @Autowired
+ private BaseConfigurationHelper baseConfigurationHelper;
+
@Autowired
private BaseAuditHelper baseAuditHelper;
@@ -85,30 +89,10 @@ public class GeneralChangeProcessor extends BaseChangeProcessor {
@Autowired
private GcpExternalizationHelper gcpExternalizationHelper;
- private GeneralChangeProcessorConfigurationType processorConfigurationType;
-
//region Initialization and Configuration
@PostConstruct
public void init() {
- processorConfigurationType = gcpConfigurationHelper.configure(this);
- if (isEnabled()) {
- // print startup message
- int scenarios = processorConfigurationType.getScenario().size();
- if (scenarios > 0) {
- LOGGER.info(getBeanName() + " initialized correctly (number of scenarios: " + scenarios + ")");
- } else {
- LOGGER.warn(getBeanName() + " initialized correctly, but there are no scenarios - so it will never be invoked");
- }
- }
- }
-
- private GeneralChangeProcessorScenarioType findScenario(String scenarioName) {
- for (GeneralChangeProcessorScenarioType scenario : processorConfigurationType.getScenario()) {
- if (scenarioName.equals(scenario.getName())) {
- return scenario;
- }
- }
- throw new SystemException("Scenario named " + scenarioName + " couldn't be found");
+ baseConfigurationHelper.registerProcessor(this);
}
private GcpScenarioBean getScenarioBean(Map variables) {
@@ -131,23 +115,23 @@ private String lowerFirstChar(String name) {
return Character.toLowerCase(name.charAt(0)) + name.substring(1);
}
- public void disableScenario(String scenarioName) {
- findScenario(scenarioName).setEnabled(false);
- }
-
- public void enableScenario(String scenarioName) {
- findScenario(scenarioName).setEnabled(true);
- }
//endregion
//region Processing model invocation
@Override
- public HookOperationMode processModelInvocation(ModelContext context, Task taskFromModel, OperationResult result) throws SchemaException {
+ public HookOperationMode processModelInvocation(ModelContext context, WfConfigurationType wfConfigurationType, Task taskFromModel, OperationResult result) throws SchemaException {
+
+ if (wfConfigurationType.getGeneralChangeProcessor() != null && Boolean.FALSE.equals(wfConfigurationType.getGeneralChangeProcessor().isEnabled())) {
+ LOGGER.trace("{} is disabled", getBeanName());
+ return null;
+ }
- if (processorConfigurationType.getScenario().isEmpty()) {
- LOGGER.warn("No scenarios for " + getBeanName());
+ if (wfConfigurationType.getGeneralChangeProcessor() == null || wfConfigurationType.getGeneralChangeProcessor().getScenario().isEmpty()) {
+ LOGGER.trace("No scenarios for {}", getBeanName());
+ return null;
}
+ GeneralChangeProcessorConfigurationType processorConfigurationType = wfConfigurationType.getGeneralChangeProcessor();
for (GeneralChangeProcessorScenarioType scenarioType : processorConfigurationType.getScenario()) {
GcpScenarioBean scenarioBean = findScenarioBean(scenarioType.getBeanName());
if (Boolean.FALSE.equals(scenarioType.isEnabled())) {
@@ -162,7 +146,7 @@ public HookOperationMode processModelInvocation(ModelContext context, Task taskF
}
}
LOGGER.trace("No scenario found to be applicable, exiting the change processor.");
- return HookOperationMode.FOREGROUND;
+ return null;
}
private HookOperationMode applyScenario(GeneralChangeProcessorScenarioType scenarioType, GcpScenarioBean scenarioBean, ModelContext context, Task taskFromModel, OperationResult result) {
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PcpConfigurationHelper.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PcpConfigurationHelper.java
index 0dfb80c5a5a..f6a96000863 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PcpConfigurationHelper.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PcpConfigurationHelper.java
@@ -16,22 +16,15 @@
package com.evolveum.midpoint.wf.impl.processors.primary;
-import com.evolveum.midpoint.util.exception.SystemException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.wf.impl.processors.BaseConfigurationHelper;
-import com.evolveum.midpoint.wf.impl.processors.primary.aspect.PrimaryChangeAspect;
-
-import org.apache.commons.configuration.Configuration;
-import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
/**
+ * Temporarily no responsibilities here.
+ *
* @author mederly
*/
@Component
@@ -41,38 +34,4 @@ public class PcpConfigurationHelper {
@Autowired
private BaseConfigurationHelper baseConfigurationHelper;
- // configuration
- private static final String KEY_ASPECT = "aspect";
- private static final List LOCALLY_KNOWN_KEYS = Arrays.asList(KEY_ASPECT);
-
- public void configure(PrimaryChangeProcessor primaryChangeProcessor) {
- baseConfigurationHelper.configureProcessor(primaryChangeProcessor, LOCALLY_KNOWN_KEYS);
- setPrimaryChangeProcessorAspects(primaryChangeProcessor);
- }
-
- private void setPrimaryChangeProcessorAspects(PrimaryChangeProcessor primaryChangeProcessor) {
-
- List aspects = new ArrayList<>();
-
- Configuration c = primaryChangeProcessor.getProcessorConfiguration();
- if (c != null) {
- String[] aspectNames = c.getStringArray(KEY_ASPECT);
- if (aspectNames == null || aspectNames.length == 0) {
- LOGGER.warn("No aspects defined for primary change processor " + primaryChangeProcessor.getBeanName());
- } else {
- for (String aspectName : aspectNames) {
- LOGGER.trace("Searching for aspect " + aspectName);
- try {
- PrimaryChangeAspect aspect = (PrimaryChangeAspect) primaryChangeProcessor.getBeanFactory().getBean(aspectName);
- aspects.add(aspect);
- } catch (BeansException e) {
- throw new SystemException("Change aspect " + aspectName + " could not be found.", e);
- }
- }
- LOGGER.debug("Resolved " + aspects.size() + " process aspects for primary change processor " + primaryChangeProcessor.getBeanName());
- }
- }
- primaryChangeProcessor.setChangeAspects(aspects);
- }
-
}
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PcpJob.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PcpJob.java
index 6d1c6dd44d9..5da446326c0 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PcpJob.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PcpJob.java
@@ -22,7 +22,7 @@ public class PcpJob extends Job {
}
public PrimaryChangeAspect getChangeAspect() {
- return getWfTaskUtil().getPrimaryChangeAspect(getTask(), getPcp().getChangeAspects());
+ return getWfTaskUtil().getPrimaryChangeAspect(getTask(), getPcp().getAllChangeAspects());
}
private PrimaryChangeProcessor getPcp() {
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PcpRepoAccessHelper.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PcpRepoAccessHelper.java
index 46f35c0b8de..b9ed3b865f9 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PcpRepoAccessHelper.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PcpRepoAccessHelper.java
@@ -120,10 +120,23 @@ public PrismObject extends ObjectType> getObjectAfter(Map vari
return null;
}
- PrismObject extends ObjectType> objectAfter = objectBefore.clone();
- delta.applyTo(objectAfter);
+ PrismObject extends ObjectType> objectAfter;
+ if (delta.isAdd()) {
+ if (delta.getObjectToAdd() != null) {
+ objectAfter = delta.getObjectToAdd().clone();
+ } else {
+ return null;
+ }
+ } else if (delta.isModify()) {
+ objectAfter = objectBefore.clone();
+ delta.applyTo(objectAfter);
+ } else if (delta.isDelete()) {
+ return null;
+ } else {
+ return null; // should not occur
+ }
- if (objectAfter.asObjectable() instanceof UserType) {
+ if (objectAfter.asObjectable() instanceof UserType) { // quite a hack
miscDataUtil.resolveAssignmentTargetReferences((PrismObject) objectAfter, result);
}
return objectAfter;
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PrimaryChangeProcessor.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PrimaryChangeProcessor.java
index 693158b528c..a2a545702b9 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PrimaryChangeProcessor.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PrimaryChangeProcessor.java
@@ -48,32 +48,43 @@
import com.evolveum.midpoint.wf.impl.processes.ProcessInterfaceFinder;
import com.evolveum.midpoint.wf.impl.processors.BaseAuditHelper;
import com.evolveum.midpoint.wf.impl.processors.BaseChangeProcessor;
+import com.evolveum.midpoint.wf.impl.processors.BaseConfigurationHelper;
import com.evolveum.midpoint.wf.impl.processors.BaseExternalizationHelper;
import com.evolveum.midpoint.wf.impl.processors.BaseModelInvocationProcessingHelper;
import com.evolveum.midpoint.wf.impl.processors.primary.aspect.PrimaryChangeAspect;
import com.evolveum.midpoint.wf.impl.util.MiscDataUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.PrimaryChangeProcessorConfigurationType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.WfConfigurationType;
import com.evolveum.midpoint.xml.ns.model.workflow.common_forms_3.WorkItemContents;
import com.evolveum.midpoint.xml.ns.model.workflow.process_instance_state_3.ProcessInstanceState;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.xml.bind.JAXBException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* @author mederly
*/
-public abstract class PrimaryChangeProcessor extends BaseChangeProcessor {
+@Component
+public class PrimaryChangeProcessor extends BaseChangeProcessor {
private static final Trace LOGGER = TraceManager.getTrace(PrimaryChangeProcessor.class);
@Autowired
private PcpConfigurationHelper pcpConfigurationHelper;
+ @Autowired
+ private BaseConfigurationHelper baseConfigurationHelper;
+
@Autowired
private BaseModelInvocationProcessingHelper baseModelInvocationProcessingHelper;
@@ -100,7 +111,7 @@ public abstract class PrimaryChangeProcessor extends BaseChangeProcessor {
public static final String UNKNOWN_OID = "?";
- List changeAspects;
+ Set allChangeAspects = new HashSet<>();
public enum ExecutionMode {
ALL_AFTERWARDS, ALL_IMMEDIATELY, MIXED;
@@ -110,11 +121,7 @@ public enum ExecutionMode {
// =================================================================================== Configuration
@PostConstruct
public void init() {
- pcpConfigurationHelper.configure(this);
- }
-
- public void setChangeAspects(List changeAspects) {
- this.changeAspects = changeAspects;
+ baseConfigurationHelper.registerProcessor(this);
}
//endregion
@@ -122,7 +129,7 @@ public void setChangeAspects(List changeAspects) {
// =================================================================================== Processing model invocation
@Override
- public HookOperationMode processModelInvocation(ModelContext context, Task taskFromModel, OperationResult result) throws SchemaException {
+ public HookOperationMode processModelInvocation(ModelContext context, WfConfigurationType wfConfigurationType, Task taskFromModel, OperationResult result) throws SchemaException {
if (context.getState() != ModelState.PRIMARY || context.getFocusContext() == null) {
return null;
@@ -136,7 +143,7 @@ public HookOperationMode processModelInvocation(ModelContext context, Task taskF
// examine the request using process aspects
ObjectDelta extends ObjectType> changeBeingDecomposed = change.clone();
- List jobCreationInstructions = gatherStartInstructions(context, changeBeingDecomposed, taskFromModel, result);
+ List jobCreationInstructions = gatherStartInstructions(context, wfConfigurationType, changeBeingDecomposed, taskFromModel, result);
// start the process(es)
@@ -148,11 +155,26 @@ public HookOperationMode processModelInvocation(ModelContext context, Task taskF
}
}
- private List gatherStartInstructions(ModelContext context, ObjectDelta extends ObjectType> changeBeingDecomposed, Task taskFromModel, OperationResult result) throws SchemaException {
+ private List gatherStartInstructions(ModelContext extends ObjectType> context,
+ WfConfigurationType wfConfigurationType,
+ ObjectDelta extends ObjectType> changeBeingDecomposed,
+ Task taskFromModel, OperationResult result) throws SchemaException {
List startProcessInstructions = new ArrayList<>();
- for (PrimaryChangeAspect aspect : changeAspects) {
- List instructions = aspect.prepareJobCreationInstructions(context, changeBeingDecomposed, taskFromModel, result);
+ PrimaryChangeProcessorConfigurationType processorConfigurationType =
+ wfConfigurationType.getPrimaryChangeProcessor();
+
+ if (processorConfigurationType != null && Boolean.FALSE.equals(processorConfigurationType.isEnabled())) {
+ LOGGER.debug("Primary change processor is disabled.");
+ return startProcessInstructions;
+ }
+
+ for (PrimaryChangeAspect aspect : getActiveChangeAspects(processorConfigurationType)) {
+ if (changeBeingDecomposed.isEmpty()) { // nothing left
+ break;
+ }
+ List instructions = aspect.prepareJobCreationInstructions(
+ context, wfConfigurationType, changeBeingDecomposed, taskFromModel, result);
logAspectResult(aspect, instructions);
if (instructions != null) {
startProcessInstructions.addAll(instructions);
@@ -162,7 +184,7 @@ private List gatherStartInstructions(ModelContex
// tweaking the instructions returned from aspects a bit...
// if we are adding a new object, we have to set OBJECT_TO_BE_ADDED variable in all instructions
- if (changeBeingDecomposed.isAdd()) {
+ if (changeBeingDecomposed.isAdd() && changeBeingDecomposed.getObjectToAdd() != null) {
String objectToBeAdded;
try {
objectToBeAdded = MiscDataUtil.serializeObjectToXml(changeBeingDecomposed.getObjectToAdd());
@@ -185,6 +207,16 @@ private List gatherStartInstructions(ModelContex
return startProcessInstructions;
}
+ private Collection getActiveChangeAspects(PrimaryChangeProcessorConfigurationType processorConfigurationType) {
+ Collection rv = new HashSet<>();
+ for (PrimaryChangeAspect aspect : getAllChangeAspects()) {
+ if (aspect.isEnabled(processorConfigurationType)) {
+ rv.add(aspect);
+ }
+ }
+ return rv;
+ }
+
private void logAspectResult(PrimaryChangeAspect aspect, List extends JobCreationInstruction> instructions) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Aspect " + aspect.getClass() + " returned the following process start instructions (count: " + (instructions == null ? "(null)" : instructions.size()) + "):");
@@ -250,7 +282,7 @@ private Job createRootJob(ModelContext context, ObjectDelta extends ObjectType
// Child job0 - in modes 2, 3 we have to prepare first child that executes all changes that do not require approval
private Job createJob0(ModelContext context, ObjectDelta extends ObjectType> changeWithoutApproval, Job rootJob, ExecutionMode executionMode, OperationResult result) throws SchemaException, ObjectNotFoundException {
- if (!changeWithoutApproval.isEmpty() && executionMode != ExecutionMode.ALL_AFTERWARDS) {
+ if (changeWithoutApproval != null && !changeWithoutApproval.isEmpty() && executionMode != ExecutionMode.ALL_AFTERWARDS) {
ModelContext modelContext = contextCopyWithDeltaReplaced(context, changeWithoutApproval);
JobCreationInstruction instruction0 = JobCreationInstruction.createModelOperationChildJob(rootJob, modelContext);
instruction0.setTaskName("Executing changes that do not require approval");
@@ -279,7 +311,11 @@ private LensContext determineContextForRootTask(ModelContext context, ObjectDelt
private LensContext contextCopyWithDeltaReplaced(ModelContext context, ObjectDelta extends ObjectType> change) throws SchemaException {
LensContext contextCopy = ((LensContext) context).clone();
- contextCopy.replacePrimaryFocusDeltas(Arrays.asList(change));
+ if (change != null) {
+ contextCopy.replacePrimaryFocusDeltas(Arrays.asList(change));
+ } else {
+ contextCopy.replacePrimaryFocusDeltas(null);
+ }
return contextCopy;
}
@@ -399,8 +435,8 @@ public AuditEventRecord prepareWorkItemAuditRecord(TaskEvent taskEvent, AuditEve
//endregion
//region Getters and setters
- public List getChangeAspects() {
- return changeAspects;
+ public Collection getAllChangeAspects() {
+ return allChangeAspects;
}
PrimaryChangeAspect getChangeAspect(Map variables) {
@@ -414,7 +450,7 @@ public PrimaryChangeAspect findPrimaryChangeAspect(String name) {
if (getBeanFactory().containsBean(name)) {
return getBeanFactory().getBean(name, PrimaryChangeAspect.class);
}
- for (PrimaryChangeAspect w : changeAspects) {
+ for (PrimaryChangeAspect w : allChangeAspects) {
if (name.equals(w.getClass().getName())) {
return w;
}
@@ -422,6 +458,10 @@ public PrimaryChangeAspect findPrimaryChangeAspect(String name) {
throw new IllegalStateException("Aspect " + name + " is not registered.");
}
+ public void registerChangeAspect(PrimaryChangeAspect changeAspect) {
+ allChangeAspects.add(changeAspect);
+ }
+
WfTaskUtil getWfTaskUtil() { // ugly hack - used in PcpJob
return wfTaskUtil;
}
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/WfPrepareRootOperationTaskHandler.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/WfPrepareRootOperationTaskHandler.java
index cbdd21285ab..0249884c4fd 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/WfPrepareRootOperationTaskHandler.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/WfPrepareRootOperationTaskHandler.java
@@ -17,6 +17,7 @@
package com.evolveum.midpoint.wf.impl.processors.primary;
import com.evolveum.midpoint.model.impl.lens.LensContext;
+import com.evolveum.midpoint.model.impl.lens.LensFocusContext;
import com.evolveum.midpoint.prism.Objectable;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.schema.result.OperationResult;
@@ -96,16 +97,26 @@ public TaskRunResult run(Task task) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Child job {} returned {} deltas", child, deltas.size());
}
+ LensFocusContext focusContext = rootContext.getFocusContext();
for (ObjectDelta delta : deltas) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Adding delta from job {} to root model context; delta = {}", child, delta.debugDump(0));
}
- rootContext.getFocusContext().addPrimaryDelta(delta);
+ if (focusContext.getPrimaryDelta() != null && !focusContext.getPrimaryDelta().isEmpty()) {
+ focusContext.addPrimaryDelta(delta);
+ } else {
+ focusContext.setPrimaryDelta(delta);
+ }
changed = true;
}
}
}
+ if (rootContext.getFocusContext().getPrimaryDelta() == null || rootContext.getFocusContext().getPrimaryDelta().isEmpty()) {
+ rootJob.setSkipModelContextProcessingProperty(true, result);
+ changed = true; // regardless of whether rootContext was changed or not
+ }
+
if (changed) {
rootJob.storeModelContext(rootContext);
rootJob.commitChanges(result);
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/aspect/BasePrimaryChangeAspect.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/aspect/BasePrimaryChangeAspect.java
index a56dbbf8868..4ee567d19ed 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/aspect/BasePrimaryChangeAspect.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/aspect/BasePrimaryChangeAspect.java
@@ -17,6 +17,7 @@
package com.evolveum.midpoint.wf.impl.processors.primary.aspect;
import com.evolveum.midpoint.prism.Objectable;
+import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.repo.api.RepositoryService;
import com.evolveum.midpoint.schema.result.OperationResult;
@@ -26,23 +27,30 @@
import com.evolveum.midpoint.wf.impl.jobs.WfTaskUtil;
import com.evolveum.midpoint.wf.impl.messages.ProcessEvent;
import com.evolveum.midpoint.wf.impl.processes.ProcessInterfaceFinder;
+import com.evolveum.midpoint.wf.impl.processes.itemApproval.ItemApprovalProcessInterface;
+import com.evolveum.midpoint.wf.impl.processors.BaseConfigurationHelper;
import com.evolveum.midpoint.wf.impl.processors.primary.PcpJob;
import com.evolveum.midpoint.wf.impl.processors.primary.PrimaryChangeProcessor;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.PrimaryChangeProcessorConfigurationType;
import com.evolveum.midpoint.xml.ns.model.workflow.process_instance_state_3.ProcessSpecificState;
+import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.annotation.Autowired;
+import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
/**
* @author mederly
*/
-public abstract class BasePrimaryChangeAspect implements PrimaryChangeAspect {
+public abstract class BasePrimaryChangeAspect implements PrimaryChangeAspect, BeanNameAware {
private static final Trace LOGGER = TraceManager.getTrace(BasePrimaryChangeAspect.class);
+ private String beanName;
+
@Autowired
protected RepositoryService repositoryService;
@@ -58,6 +66,29 @@ public abstract class BasePrimaryChangeAspect implements PrimaryChangeAspect {
@Autowired
protected ProcessInterfaceFinder processInterfaceFinder;
+ @Autowired
+ protected BaseConfigurationHelper baseConfigurationHelper;
+
+ @Autowired
+ protected PrismContext prismContext;
+
+ @Autowired
+ protected ItemApprovalProcessInterface itemApprovalProcessInterface;
+
+ @PostConstruct
+ public void init() {
+ changeProcessor.registerChangeAspect(this);
+ }
+
+ @Override
+ public String getBeanName() {
+ return beanName;
+ }
+
+ public void setBeanName(String name) {
+ this.beanName = name;
+ }
+
@Override
public List> prepareDeltaOut(ProcessEvent event, PcpJob pcpJob, OperationResult result) throws SchemaException {
return primaryChangeAspectHelper.prepareDeltaOut(event, pcpJob, result);
@@ -76,4 +107,15 @@ public ProcessSpecificState externalizeProcessInstanceState(Map
public PrimaryChangeProcessor getChangeProcessor() {
return changeProcessor;
}
+
+ @Override
+ public boolean isEnabledByDefault() {
+ return false; // overriden in selected aspects
+ }
+
+ @Override
+ public boolean isEnabled(PrimaryChangeProcessorConfigurationType processorConfigurationType) {
+ return primaryChangeAspectHelper.isEnabled(processorConfigurationType, this);
+ }
+
}
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/aspect/PrimaryChangeAspect.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/aspect/PrimaryChangeAspect.java
index ea872d09501..1ea539a6294 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/aspect/PrimaryChangeAspect.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/aspect/PrimaryChangeAspect.java
@@ -29,6 +29,8 @@
import com.evolveum.midpoint.wf.impl.processors.primary.PcpJob;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.PrimaryChangeProcessorConfigurationType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.WfConfigurationType;
import com.evolveum.midpoint.xml.ns.model.workflow.common_forms_3.QuestionFormType;
import com.evolveum.midpoint.xml.ns.model.workflow.process_instance_state_3.ProcessSpecificState;
@@ -64,13 +66,13 @@ public interface PrimaryChangeAspect {
* If yes, it takes these deltas out of the original change and prepares instruction(s) to start wf process(es).
*
* @param modelContext Original model context (e.g. to be able to get information about whole context of the operation)
+ * @param wfConfigurationType
* @param change Change to be examined and modified by implementation of this method
* @param taskFromModel General context of the operation - the method should not modify the task.
- * @param result Operation result - the method should report any errors here (TODO what about creating subresults?)
- * @return list of start process instructions
+ * @param result Operation result - the method should report any errors here (TODO what about creating subresults?) @return list of start process instructions
* @see com.evolveum.midpoint.wf.impl.jobs.JobCreationInstruction
*/
- List prepareJobCreationInstructions(ModelContext> modelContext, ObjectDelta extends ObjectType> change, Task taskFromModel, OperationResult result) throws SchemaException;
+ List prepareJobCreationInstructions(ModelContext> modelContext, WfConfigurationType wfConfigurationType, ObjectDelta extends ObjectType> change, Task taskFromModel, OperationResult result) throws SchemaException;
/**
* On process instance end, prepares deltaOut based in deltaIn and information gathered during approval process.
@@ -138,4 +140,13 @@ public interface PrimaryChangeAspect {
* @return external representation
*/
ProcessSpecificState externalizeProcessInstanceState(Map variables);
+
+ /**
+ * Returns true if this aspect is enabled by default, i.e. even if not listed in primary change processor configuration.
+ */
+ boolean isEnabledByDefault();
+
+ boolean isEnabled(PrimaryChangeProcessorConfigurationType processorConfigurationType);
+
+ String getBeanName();
}
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/aspect/PrimaryChangeAspectHelper.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/aspect/PrimaryChangeAspectHelper.java
index 02c643259a3..751b8113e1c 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/aspect/PrimaryChangeAspectHelper.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/aspect/PrimaryChangeAspectHelper.java
@@ -18,6 +18,7 @@
import com.evolveum.midpoint.model.api.context.ModelContext;
import com.evolveum.midpoint.model.api.context.ModelElementContext;
+import com.evolveum.midpoint.model.api.context.ModelState;
import com.evolveum.midpoint.prism.Objectable;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismObject;
@@ -40,16 +41,23 @@
import com.evolveum.midpoint.wf.impl.processors.primary.PcpJob;
import com.evolveum.midpoint.wf.util.ApprovalUtils;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.GenericPcpAspectConfigurationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.PcpAspectConfigurationType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.PrimaryChangeProcessorConfigurationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.WfConfigurationType;
+import org.apache.velocity.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.xml.namespace.QName;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
@@ -214,6 +222,79 @@ public void resolveRolesAndOrgUnits(PrismObject user, OperationResult
}
}
}
+
+ public boolean isEnabled(PrimaryChangeProcessorConfigurationType processorConfigurationType, PrimaryChangeAspect aspect) {
+ if (processorConfigurationType == null) {
+ return aspect.isEnabledByDefault();
+ }
+ PcpAspectConfigurationType aspectConfigurationType = getPcpAspectConfigurationType(processorConfigurationType, aspect); // result may be null
+ return isEnabled(aspectConfigurationType, aspect.isEnabledByDefault());
+ }
+
+ public PcpAspectConfigurationType getPcpAspectConfigurationType(WfConfigurationType wfConfigurationType, PrimaryChangeAspect aspect) {
+ if (wfConfigurationType == null) {
+ return null;
+ }
+ return getPcpAspectConfigurationType(wfConfigurationType.getPrimaryChangeProcessor(), aspect);
+ }
+
+ public PcpAspectConfigurationType getPcpAspectConfigurationType(PrimaryChangeProcessorConfigurationType processorConfigurationType, PrimaryChangeAspect aspect) {
+ if (processorConfigurationType == null) {
+ return null;
+ }
+ String aspectName = aspect.getBeanName();
+ String getterName = "get" + StringUtils.capitalizeFirstLetter(aspectName);
+ Object aspectConfigurationObject;
+ try {
+ Method getter = processorConfigurationType.getClass().getDeclaredMethod(getterName);
+ try {
+ aspectConfigurationObject = getter.invoke(processorConfigurationType);
+ } catch (IllegalAccessException|InvocationTargetException e) {
+ throw new SystemException("Couldn't obtain configuration for aspect " + aspectName + " from the workflow configuration.", e);
+ }
+ if (aspectConfigurationObject != null) {
+ return (PcpAspectConfigurationType) aspectConfigurationObject;
+ }
+ LOGGER.trace("Specific configuration for {} not found, trying generic configuration", aspectName);
+ } catch (NoSuchMethodException e) {
+ // nothing wrong with this, let's try generic configuration
+ LOGGER.trace("Configuration getter method for {} not found, trying generic configuration", aspectName);
+ }
+
+ for (GenericPcpAspectConfigurationType genericConfig : processorConfigurationType.getOtherAspect()) {
+ if (aspectName.equals(genericConfig.getName())) {
+ return genericConfig;
+ }
+ }
+ return null;
+ }
+
+ private boolean isEnabled(PcpAspectConfigurationType configurationType, boolean enabledByDefault) {
+ if (configurationType == null) {
+ return enabledByDefault;
+ } else if (Boolean.FALSE.equals(configurationType.isEnabled())) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ public boolean isUserRelated(ModelContext extends ObjectType> context) {
+ return isRelatedToType(context, UserType.class);
+ }
+
+ public boolean isRelatedToType(ModelContext extends ObjectType> context, Class> type) {
+ if (context.getFocusContext() == null) {
+ return false;
+ }
+
+ ObjectDelta extends ObjectType> change = context.getFocusContext().getPrimaryDelta();
+ if (change == null) {
+ return false;
+ }
+
+ return type.isAssignableFrom(change.getObjectTypeClass());
+ }
//endregion
}
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/other/AddAbstractRoleAspect.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/other/AddAbstractRoleAspect.java
new file mode 100644
index 00000000000..c007fd62817
--- /dev/null
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/other/AddAbstractRoleAspect.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010-2015 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.wf.impl.processors.primary.other;
+
+import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType;
+import org.apache.commons.lang3.Validate;
+import org.springframework.stereotype.Component;
+
+/**
+ * Change aspect that manages abstract role (i.e. Role or Org) addition.
+ *
+ * @author mederly
+ */
+@Component
+public class AddAbstractRoleAspect extends AddObjectAspect {
+
+ @Override
+ protected Class getObjectClass() {
+ return AbstractRoleType.class;
+ }
+
+ @Override
+ protected String getObjectLabel(AbstractRoleType object) {
+ Validate.notNull(object);
+ if (object instanceof RoleType) {
+ return "role " + object.getName();
+ } else if (object instanceof OrgType) {
+ return "org " + object.getName();
+ } else {
+ // should not occur
+ return object.getClass().getSimpleName() + " " + object.getName();
+ }
+ }
+}
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/other/AddObjectAspect.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/other/AddObjectAspect.java
new file mode 100644
index 00000000000..44e2c4a9653
--- /dev/null
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/other/AddObjectAspect.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2010-2015 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.wf.impl.processors.primary.other;
+
+import com.evolveum.midpoint.model.api.context.ModelContext;
+import com.evolveum.midpoint.prism.PrismObject;
+import com.evolveum.midpoint.prism.PrismObjectDefinition;
+import com.evolveum.midpoint.prism.delta.ChangeType;
+import com.evolveum.midpoint.prism.delta.ObjectDelta;
+import com.evolveum.midpoint.schema.result.OperationResult;
+import com.evolveum.midpoint.task.api.Task;
+import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
+import com.evolveum.midpoint.util.exception.SchemaException;
+import com.evolveum.midpoint.util.logging.Trace;
+import com.evolveum.midpoint.util.logging.TraceManager;
+import com.evolveum.midpoint.wf.impl.processes.itemApproval.ApprovalRequest;
+import com.evolveum.midpoint.wf.impl.processes.itemApproval.ApprovalRequestImpl;
+import com.evolveum.midpoint.wf.impl.processes.itemApproval.ProcessVariableNames;
+import com.evolveum.midpoint.wf.impl.processors.primary.PcpChildJobCreationInstruction;
+import com.evolveum.midpoint.wf.impl.processors.primary.aspect.BasePrimaryChangeAspect;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.PcpAspectConfigurationType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.WfConfigurationType;
+import com.evolveum.midpoint.xml.ns.model.workflow.common_forms_3.AddObjectApprovalFormType;
+import com.evolveum.midpoint.xml.ns.model.workflow.common_forms_3.QuestionFormType;
+import org.apache.commons.lang.Validate;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Change aspect that manages addition of an object.
+ *
+ * @author mederly
+ */
+public abstract class AddObjectAspect extends BasePrimaryChangeAspect {
+
+ private static final Trace LOGGER = TraceManager.getTrace(AddObjectAspect.class);
+
+ //region ------------------------------------------------------------ Things that execute on request arrival
+
+ protected abstract Class getObjectClass();
+ protected abstract String getObjectLabel(T object);
+
+ @Override
+ public List prepareJobCreationInstructions(ModelContext> modelContext,
+ WfConfigurationType wfConfigurationType,
+ ObjectDelta extends ObjectType> change,
+ Task taskFromModel, OperationResult result) throws SchemaException {
+ PcpAspectConfigurationType config = primaryChangeAspectHelper.getPcpAspectConfigurationType(wfConfigurationType, this);
+ if (config == null) {
+ return null; // this should not occur (because this aspect is not enabled by default), but check it just to be sure
+ }
+ if (!primaryChangeAspectHelper.isRelatedToType(modelContext, getObjectClass())) {
+ return null;
+ }
+ List> approvalRequestList = getApprovalRequests(modelContext, config, change, result);
+ if (approvalRequestList == null || approvalRequestList.isEmpty()) {
+ return null;
+ }
+ return prepareJobCreateInstructions(modelContext, taskFromModel, result, approvalRequestList);
+ }
+
+ private List> getApprovalRequests(ModelContext> modelContext, PcpAspectConfigurationType config,
+ ObjectDelta extends ObjectType> change, OperationResult result) {
+ if (change.getChangeType() != ChangeType.ADD) {
+ return null;
+ }
+ T objectType = (T) change.getObjectToAdd().asObjectable().clone();
+ change.setObjectToAdd(null); // make the change empty
+ return Arrays.asList(createApprovalRequest(config, objectType));
+ }
+
+ // creates an approval request for a given role create request
+ private ApprovalRequest createApprovalRequest(PcpAspectConfigurationType config, T objectType) {
+
+ return new ApprovalRequestImpl(objectType, config, prismContext);
+ }
+
+ private List prepareJobCreateInstructions(ModelContext> modelContext, Task taskFromModel, OperationResult result,
+ List> approvalRequestList) throws SchemaException {
+ List instructions = new ArrayList<>();
+
+ for (ApprovalRequest approvalRequest : approvalRequestList) { // there should be just one
+
+ assert approvalRequest.getPrismContext() != null;
+
+ LOGGER.trace("Approval request = {}", approvalRequest);
+
+ T objectToAdd = approvalRequest.getItemToApprove();
+ Validate.notNull(objectToAdd);
+ String objectLabel = getObjectLabel(objectToAdd);
+
+ PrismObject requester = primaryChangeAspectHelper.getRequester(taskFromModel, result);
+
+ // create a JobCreateInstruction for a given change processor (primaryChangeProcessor in this case)
+ PcpChildJobCreationInstruction instruction =
+ PcpChildJobCreationInstruction.createInstruction(getChangeProcessor());
+
+ // set some common task/process attributes
+ instruction.prepareCommonAttributes(this, modelContext, null, requester); // objectOid is null (because object does not exist yet)
+
+ // prepare and set the delta that has to be approved
+ ObjectDelta extends ObjectType> delta = assignmentToDelta(modelContext);
+ instruction.setDeltaProcessAndTaskVariables(delta);
+
+ // set the names of midPoint task and activiti process instance
+ String andExecuting = instruction.isExecuteApprovedChangeImmediately() ? "and executing " : "";
+ instruction.setTaskName("Workflow for approving " + andExecuting + "creation of " + objectLabel);
+ instruction.setProcessInstanceName("Creating " + objectLabel);
+
+ // setup general item approval process
+ String approvalTaskName = "Approve creating " + objectLabel;
+ itemApprovalProcessInterface.prepareStartInstruction(instruction, approvalRequest, approvalTaskName);
+
+ instructions.add(instruction);
+ }
+ return instructions;
+ }
+
+ private ObjectDelta extends ObjectType> assignmentToDelta(ModelContext> modelContext) {
+ return modelContext.getFocusContext().getPrimaryDelta();
+ }
+
+ //endregion
+
+ //region ------------------------------------------------------------ Things that execute when item is being approved
+
+ @Override
+ public PrismObject extends QuestionFormType> prepareQuestionForm(org.activiti.engine.task.Task task, Map variables, OperationResult result) throws SchemaException, ObjectNotFoundException {
+
+ if (LOGGER.isTraceEnabled()) {
+ LOGGER.trace("getRequestSpecific starting: execution id {}, pid {}, variables = {}", task.getExecutionId(), task.getProcessInstanceId(), variables);
+ }
+
+ PrismObjectDefinition formDefinition = prismContext.getSchemaRegistry().findObjectDefinitionByType(AddObjectApprovalFormType.COMPLEX_TYPE);
+ PrismObject formPrism = formDefinition.instantiate();
+ AddObjectApprovalFormType form = formPrism.asObjectable();
+
+ ApprovalRequest request = (ApprovalRequest) variables.get(ProcessVariableNames.APPROVAL_REQUEST);
+ request.setPrismContext(prismContext);
+ Validate.notNull(request, "Approval request is not present among process variables");
+ form.setObjectToAdd(getObjectLabel(request.getItemToApprove()));
+
+ form.setRequesterComment(null); // TODO
+
+ if (LOGGER.isTraceEnabled()) {
+ LOGGER.trace("Resulting prism object instance = {}", formPrism.debugDump());
+ }
+ return formPrism;
+ }
+
+ @Override
+ public PrismObject extends ObjectType> prepareRelatedObject(org.activiti.engine.task.Task task, Map variables, OperationResult result) throws SchemaException, ObjectNotFoundException {
+
+ ApprovalRequest request = (ApprovalRequest) variables.get(ProcessVariableNames.APPROVAL_REQUEST);
+ request.setPrismContext(prismContext);
+ Validate.notNull(request, "Approval request is not present among process variables");
+ return request.getItemToApprove().asPrismObject();
+ }
+
+ //endregion
+}
\ No newline at end of file
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/other/AddResourceAspect.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/other/AddResourceAspect.java
new file mode 100644
index 00000000000..2ae58222a6a
--- /dev/null
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/other/AddResourceAspect.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2010-2015 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.wf.impl.processors.primary.other;
+
+import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType;
+import org.apache.commons.lang3.Validate;
+import org.springframework.stereotype.Component;
+
+/**
+ * Change aspect that manages resource addition.
+ *
+ * @author mederly
+ */
+@Component
+public class AddResourceAspect extends AddObjectAspect {
+
+ @Override
+ protected Class getObjectClass() {
+ return ResourceType.class;
+ }
+
+ @Override
+ protected String getObjectLabel(ResourceType object) {
+ Validate.notNull(object);
+ return "resource " + object.getName();
+ }
+}
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/other/AddUserAspect.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/other/AddUserAspect.java
new file mode 100644
index 00000000000..cba26fccf2d
--- /dev/null
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/other/AddUserAspect.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010-2015 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.wf.impl.processors.primary.other;
+
+import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
+import org.apache.commons.lang3.Validate;
+import org.springframework.stereotype.Component;
+
+/**
+ * Change aspect that manages user addition.
+ *
+ * @author mederly
+ */
+@Component
+public class AddUserAspect extends AddObjectAspect {
+
+ @Override
+ protected Class getObjectClass() {
+ return UserType.class;
+ }
+
+ @Override
+ protected String getObjectLabel(UserType object) {
+ Validate.notNull(object);
+ return "user " + object.getName();
+ }
+}
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/AddResourceAssignmentAspect.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/AddResourceAssignmentAspect.java
index b45fc1a6101..a121454233e 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/AddResourceAssignmentAspect.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/AddResourceAssignmentAspect.java
@@ -43,22 +43,20 @@
import com.evolveum.midpoint.wf.impl.processors.primary.PrimaryChangeProcessor;
import com.evolveum.midpoint.wf.impl.processors.primary.aspect.BasePrimaryChangeAspect;
import com.evolveum.midpoint.wf.impl.util.MiscDataUtil;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ConstructionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.PcpAspectConfigurationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
-import com.evolveum.midpoint.xml.ns.model.workflow.common_forms_3.AbstractRoleAssignmentApprovalFormType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.WfConfigurationType;
import com.evolveum.midpoint.xml.ns.model.workflow.common_forms_3.QuestionFormType;
import com.evolveum.midpoint.xml.ns.model.workflow.common_forms_3.ResourceAssignmentApprovalFormType;
import org.apache.commons.lang.Validate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
-import javax.xml.datatype.XMLGregorianCalendar;
-import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -81,29 +79,39 @@ public class AddResourceAssignmentAspect extends BasePrimaryChangeAspect {
@Autowired
private ItemApprovalProcessInterface itemApprovalProcessInterface;
+ @Override
+ public boolean isEnabledByDefault() {
+ return true;
+ }
+
//region ------------------------------------------------------------ Things that execute on request arrival
@Override
- public List prepareJobCreationInstructions(ModelContext> modelContext, ObjectDelta extends ObjectType> change, Task taskFromModel, OperationResult result) throws SchemaException {
+ public List prepareJobCreationInstructions(ModelContext> modelContext, WfConfigurationType wfConfigurationType, ObjectDelta extends ObjectType> change, Task taskFromModel, OperationResult result) throws SchemaException {
- List> approvalRequestList = getApprovalRequests(modelContext, change, result);
+ if (!primaryChangeAspectHelper.isUserRelated(modelContext)) {
+ return null;
+ }
+ List> approvalRequestList = getApprovalRequests(modelContext, wfConfigurationType, change, result);
if (approvalRequestList == null || approvalRequestList.isEmpty()) {
return null;
}
return prepareJobCreateInstructions(modelContext, taskFromModel, result, approvalRequestList);
}
- private List> getApprovalRequests(ModelContext> modelContext, ObjectDelta extends ObjectType> change, OperationResult result) {
+ private List> getApprovalRequests(ModelContext> modelContext, WfConfigurationType wfConfigurationType, ObjectDelta extends ObjectType> change, OperationResult result) {
if (change.getChangeType() == ChangeType.ADD) {
- return getApprovalRequestsFromUserAdd(change, result);
+ return getApprovalRequestsFromUserAdd(wfConfigurationType, change, result);
} else if (change.getChangeType() == ChangeType.MODIFY) {
- return getApprovalRequestsFromUserModify(modelContext.getFocusContext().getObjectOld(), change, result);
+ return getApprovalRequestsFromUserModify(wfConfigurationType, modelContext.getFocusContext().getObjectOld(), change, result);
}
return null;
}
// we look for assignments of resources that should be approved
- private List> getApprovalRequestsFromUserAdd(ObjectDelta extends ObjectType> change, OperationResult result) {
+ private List> getApprovalRequestsFromUserAdd(WfConfigurationType wfConfigurationType,
+ ObjectDelta extends ObjectType> change,
+ OperationResult result) {
List> approvalRequestList = new ArrayList<>();
UserType user = (UserType) change.getObjectToAdd().asObjectable();
@@ -130,7 +138,7 @@ private List> getApprovalRequestsFromUserAdd(Obj
continue;
}
AssignmentType assignmentClone = cloneAndCanonicalizeAssignment(assignmentType);
- approvalRequestList.add(createApprovalRequest(assignmentClone, resourceType));
+ approvalRequestList.add(createApprovalRequest(wfConfigurationType, assignmentClone, resourceType));
assignmentTypeIterator.remove();
}
return approvalRequestList;
@@ -149,7 +157,10 @@ private AssignmentType cloneAndCanonicalizeAssignment(AssignmentType assignmentT
return assignmentClone;
}
- private List> getApprovalRequestsFromUserModify(PrismObject extends ObjectType> userOld, ObjectDelta extends ObjectType> change, OperationResult result) {
+ private List> getApprovalRequestsFromUserModify(WfConfigurationType wfConfigurationType,
+ PrismObject extends ObjectType> userOld,
+ ObjectDelta extends ObjectType> change,
+ OperationResult result) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Resource-related assignments in user modify delta: ");
@@ -173,7 +184,7 @@ private List> getApprovalRequestsFromUserModify(
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Assignment to add = {}", assignmentValue.debugDump());
}
- ApprovalRequest req = processAssignmentToAdd(assignmentValue, result);
+ ApprovalRequest req = processAssignmentToAdd(wfConfigurationType, assignmentValue, result);
if (req != null) {
approvalRequestList.add(req);
valueIterator.remove();
@@ -190,7 +201,7 @@ private List> getApprovalRequestsFromUserModify(
if (existsEquivalentValue(userOld, assignmentValue)) {
continue;
}
- ApprovalRequest req = processAssignmentToAdd(assignmentValue, result);
+ ApprovalRequest req = processAssignmentToAdd(wfConfigurationType, assignmentValue, result);
if (req != null) {
approvalRequestList.add(req);
valueIterator.remove();
@@ -218,7 +229,7 @@ private boolean existsEquivalentValue(PrismObject extends ObjectType> userOld,
return false;
}
- private ApprovalRequest processAssignmentToAdd(PrismContainerValue assignmentCVal, OperationResult result) {
+ private ApprovalRequest processAssignmentToAdd(WfConfigurationType wfConfigurationType, PrismContainerValue assignmentCVal, OperationResult result) {
if (assignmentCVal == null) {
return null;
}
@@ -240,13 +251,15 @@ private ApprovalRequest processAssignmentToAdd(PrismContainerVal
}
AssignmentType assignmentClone = assignmentType.clone();
PrismContainerValue.copyDefinition(assignmentClone, assignmentType);
- return createApprovalRequest(assignmentClone, resourceType);
+ return createApprovalRequest(wfConfigurationType, assignmentClone, resourceType);
}
// creates an approval request for a given resource assignment
// @pre there are approvers defined
- private ApprovalRequest createApprovalRequest(AssignmentType a, ResourceType resourceType) {
- return new ApprovalRequestImpl(a, null, resourceType.getBusiness().getApproverRef(), null, null, prismContext);
+ private ApprovalRequest createApprovalRequest(WfConfigurationType wfConfigurationType, AssignmentType a, ResourceType resourceType) {
+ PcpAspectConfigurationType config = primaryChangeAspectHelper.getPcpAspectConfigurationType(
+ wfConfigurationType, this);
+ return new ApprovalRequestImpl(a, config, null, resourceType.getBusiness().getApproverRef(), null, null, prismContext);
}
// @pre there is a construction with a resource ref
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/AddRoleAssignmentAspect.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/AddRoleAssignmentAspect.java
index 4b5c1a38c69..f4d695d57cf 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/AddRoleAssignmentAspect.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/AddRoleAssignmentAspect.java
@@ -47,8 +47,9 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.PcpAspectConfigurationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.WfConfigurationType;
import com.evolveum.midpoint.xml.ns.model.workflow.common_forms_3.AbstractRoleAssignmentApprovalFormType;
import com.evolveum.midpoint.xml.ns.model.workflow.common_forms_3.QuestionFormType;
@@ -90,29 +91,37 @@ public class AddRoleAssignmentAspect extends BasePrimaryChangeAspect {
@Autowired
private ItemApprovalProcessInterface itemApprovalProcessInterface;
+ @Override
+ public boolean isEnabledByDefault() {
+ return true;
+ }
+
//region ------------------------------------------------------------ Things that execute on request arrival
@Override
- public List prepareJobCreationInstructions(ModelContext> modelContext, ObjectDelta extends ObjectType> change, Task taskFromModel, OperationResult result) throws SchemaException {
+ public List prepareJobCreationInstructions(ModelContext> modelContext, WfConfigurationType wfConfigurationType, ObjectDelta extends ObjectType> change, Task taskFromModel, OperationResult result) throws SchemaException {
- List> approvalRequestList = getApprovalRequests(modelContext, change, result);
+ if (!primaryChangeAspectHelper.isUserRelated(modelContext)) {
+ return null;
+ }
+ List> approvalRequestList = getApprovalRequests(modelContext, wfConfigurationType, change, result);
if (approvalRequestList == null || approvalRequestList.isEmpty()) {
return null;
}
return prepareJobCreateInstructions(modelContext, taskFromModel, result, approvalRequestList);
}
- private List> getApprovalRequests(ModelContext> modelContext, ObjectDelta extends ObjectType> change, OperationResult result) {
+ private List> getApprovalRequests(ModelContext> modelContext, WfConfigurationType wfConfigurationType, ObjectDelta extends ObjectType> change, OperationResult result) {
if (change.getChangeType() == ChangeType.ADD) {
- return getApprovalRequestsFromUserAdd(change, result);
+ return getApprovalRequestsFromUserAdd(wfConfigurationType, change, result);
} else if (change.getChangeType() == ChangeType.MODIFY) {
- return getApprovalRequestsFromUserModify(modelContext.getFocusContext().getObjectOld(), change, result);
+ return getApprovalRequestsFromUserModify(wfConfigurationType, modelContext.getFocusContext().getObjectOld(), change, result);
}
return null;
}
// we look for assignments of roles that should be approved
- private List> getApprovalRequestsFromUserAdd(ObjectDelta extends ObjectType> change, OperationResult result) {
+ private List> getApprovalRequestsFromUserAdd(WfConfigurationType wfConfigurationType, ObjectDelta extends ObjectType> change, OperationResult result) {
List> approvalRequestList = new ArrayList<>();
UserType user = (UserType) change.getObjectToAdd().asObjectable();
@@ -134,7 +143,7 @@ private List> getApprovalRequestsFromUserAdd(Obj
AssignmentType aCopy = a.clone();
PrismContainerValue.copyDefinition(aCopy, a);
aCopy.setTarget(role);
- approvalRequestList.add(createApprovalRequest(aCopy, role));
+ approvalRequestList.add(createApprovalRequest(wfConfigurationType, aCopy, role));
assignmentTypeIterator.remove();
}
}
@@ -142,7 +151,7 @@ private List> getApprovalRequestsFromUserAdd(Obj
return approvalRequestList;
}
- private List> getApprovalRequestsFromUserModify(PrismObject extends ObjectType> userOld, ObjectDelta extends ObjectType> change, OperationResult result) {
+ private List> getApprovalRequestsFromUserModify(WfConfigurationType wfConfigurationType, PrismObject extends ObjectType> userOld, ObjectDelta extends ObjectType> change, OperationResult result) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("AbstractRole-related assignments in user modify delta: ");
@@ -166,7 +175,7 @@ private List> getApprovalRequestsFromUserModify(
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Assignment to add = {}", assignmentValue.debugDump());
}
- ApprovalRequest req = processAssignmentToAdd(assignmentValue, result);
+ ApprovalRequest req = processAssignmentToAdd(wfConfigurationType, assignmentValue, result);
if (req != null) {
approvalRequestList.add(req);
valueIterator.remove();
@@ -183,7 +192,7 @@ private List> getApprovalRequestsFromUserModify(
if (existsEquivalentValue(userOld, assignmentValue)) {
continue;
}
- ApprovalRequest req = processAssignmentToAdd(assignmentValue, result);
+ ApprovalRequest req = processAssignmentToAdd(wfConfigurationType, assignmentValue, result);
if (req != null) {
approvalRequestList.add(req);
valueIterator.remove();
@@ -211,7 +220,7 @@ private boolean existsEquivalentValue(PrismObject extends ObjectType> userOld,
return false;
}
- private ApprovalRequest processAssignmentToAdd(PrismContainerValue o, OperationResult result) {
+ private ApprovalRequest processAssignmentToAdd(WfConfigurationType wfConfigurationType, PrismContainerValue o, OperationResult result) {
PrismContainerValue at = o;
ObjectType objectType = primaryChangeAspectHelper.resolveObjectRef(at.getValue(), result);
if (objectType instanceof AbstractRoleType) {
@@ -223,15 +232,17 @@ private ApprovalRequest processAssignmentToAdd(PrismContainerVal
if (approvalRequired) {
AssignmentType aCopy = at.asContainerable().clone();
PrismContainerValue.copyDefinition(aCopy, at.asContainerable());
- return createApprovalRequest(aCopy, role);
+ return createApprovalRequest(wfConfigurationType, aCopy, role);
}
}
return null;
}
// creates an approval request for a given role assignment
- private ApprovalRequest createApprovalRequest(AssignmentType a, AbstractRoleType role) {
- return new ApprovalRequestImpl(a, role.getApprovalSchema(), role.getApproverRef(), role.getApproverExpression(), role.getAutomaticallyApproved(), prismContext);
+ private ApprovalRequest createApprovalRequest(WfConfigurationType wfConfigurationType, AssignmentType a, AbstractRoleType role) {
+ PcpAspectConfigurationType config = primaryChangeAspectHelper.getPcpAspectConfigurationType(
+ wfConfigurationType, this);
+ return new ApprovalRequestImpl(a, config, role.getApprovalSchema(), role.getApproverRef(), role.getApproverExpression(), role.getAutomaticallyApproved(), prismContext);
}
// approvalRequestList should contain de-referenced roles and approvalRequests that have prismContext set
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/ChangePasswordAspect.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/ChangePasswordAspect.java
index 8cb077c5d39..c1eed389728 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/ChangePasswordAspect.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/ChangePasswordAspect.java
@@ -42,6 +42,7 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.PasswordType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemObjectsType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.WfConfigurationType;
import com.evolveum.midpoint.xml.ns.model.workflow.common_forms_3.QuestionFormType;
import org.springframework.beans.factory.annotation.Autowired;
@@ -76,7 +77,7 @@ public class ChangePasswordAspect extends BasePrimaryChangeAspect {
private ItemApprovalProcessInterface itemApprovalProcessInterface;
@Override
- public List prepareJobCreationInstructions(ModelContext> modelContext, ObjectDelta extends ObjectType> change, Task taskFromModel, OperationResult result) throws SchemaException {
+ public List prepareJobCreationInstructions(ModelContext> modelContext, WfConfigurationType wfConfigurationType, ObjectDelta extends ObjectType> change, Task taskFromModel, OperationResult result) throws SchemaException {
List> approvalRequestList = new ArrayList>();
List instructions = new ArrayList<>();
@@ -125,7 +126,7 @@ private ApprovalRequest createApprovalRequest(ItemDelta delta) {
List approvers = new ArrayList();
approvers.add(approverRef);
- return new ApprovalRequestImpl("Password change", null, approvers, null, null, prismContext);
+ return new ApprovalRequestImpl("Password change", null, null, approvers, null, null, prismContext);
}
private PcpChildJobCreationInstruction createStartProcessInstruction(ModelContext> modelContext, ItemDelta delta, ApprovalRequest approvalRequest, Task taskFromModel, OperationResult result) throws SchemaException {
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/ModifyResourceAssignmentAspect.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/ModifyResourceAssignmentAspect.java
index d40e590522f..912d10e856c 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/ModifyResourceAssignmentAspect.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/ModifyResourceAssignmentAspect.java
@@ -26,9 +26,7 @@
import com.evolveum.midpoint.prism.delta.ChangeType;
import com.evolveum.midpoint.prism.delta.ItemDelta;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
-import com.evolveum.midpoint.prism.path.IdItemPathSegment;
import com.evolveum.midpoint.prism.path.ItemPath;
-import com.evolveum.midpoint.prism.path.ItemPathSegment;
import com.evolveum.midpoint.schema.DeltaConvertor;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
@@ -42,16 +40,15 @@
import com.evolveum.midpoint.wf.impl.processes.itemApproval.ItemApprovalProcessInterface;
import com.evolveum.midpoint.wf.impl.processes.itemApproval.ProcessVariableNames;
import com.evolveum.midpoint.wf.impl.processes.modifyResourceAssignment.ResourceAssignmentModification;
-import com.evolveum.midpoint.wf.impl.processes.modifyRoleAssignment.AbstractRoleAssignmentModification;
import com.evolveum.midpoint.wf.impl.processors.primary.PcpChildJobCreationInstruction;
import com.evolveum.midpoint.wf.impl.processors.primary.aspect.BasePrimaryChangeAspect;
import com.evolveum.midpoint.wf.impl.util.MiscDataUtil;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.PcpAspectConfigurationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
-import com.evolveum.midpoint.xml.ns.model.workflow.common_forms_3.AbstractRoleAssignmentModificationApprovalFormType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.WfConfigurationType;
import com.evolveum.midpoint.xml.ns.model.workflow.common_forms_3.QuestionFormType;
import com.evolveum.midpoint.xml.ns.model.workflow.common_forms_3.ResourceAssignmentModificationApprovalFormType;
import com.evolveum.prism.xml.ns._public.types_3.ChangeTypeType;
@@ -85,24 +82,35 @@ public class ModifyResourceAssignmentAspect extends BasePrimaryChangeAspect {
@Autowired
private ItemApprovalProcessInterface itemApprovalProcessInterface;
+ @Override
+ public boolean isEnabledByDefault() {
+ return true;
+ }
+
//region ------------------------------------------------------------ Things that execute on request arrival
@Override
- public List prepareJobCreationInstructions(ModelContext> modelContext, ObjectDelta extends ObjectType> change, Task taskFromModel, OperationResult result) throws SchemaException {
+ public List prepareJobCreationInstructions(ModelContext> modelContext, WfConfigurationType wfConfigurationType, ObjectDelta extends ObjectType> change, Task taskFromModel, OperationResult result) throws SchemaException {
- List> approvalRequestList = getApprovalRequests(modelContext, change, result);
+ if (!primaryChangeAspectHelper.isUserRelated(modelContext)) {
+ return null;
+ }
+ List> approvalRequestList = getApprovalRequests(modelContext, wfConfigurationType, change, result);
if (approvalRequestList == null || approvalRequestList.isEmpty()) {
return null;
}
return prepareJobCreateInstructions(modelContext, taskFromModel, result, approvalRequestList);
}
- private List> getApprovalRequests(ModelContext> modelContext, ObjectDelta extends ObjectType> change, OperationResult result) throws SchemaException {
+ private List> getApprovalRequests(ModelContext> modelContext, WfConfigurationType wfConfigurationType, ObjectDelta extends ObjectType> change, OperationResult result) throws SchemaException {
if (change.getChangeType() != ChangeType.MODIFY) {
return null;
}
PrismObject userOld = (PrismObject) modelContext.getFocusContext().getObjectOld();
+ PcpAspectConfigurationType config = primaryChangeAspectHelper.getPcpAspectConfigurationType(
+ wfConfigurationType, this);
+
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Resource-related assignments in user modify delta: ");
}
@@ -145,7 +153,7 @@ private List> getApprovalRequest
PrismContainerValue.copyDefinition(aCopy, assignmentType);
ResourceType resourceType = primaryChangeAspectHelper.resolveResourceRef(assignmentType, result); // todo eliminate redundant fetch
ResourceAssignmentModification itemToApprove = new ResourceAssignmentModification(aCopy, resourceType, entry.getValue());
- ApprovalRequest approvalRequest = new ApprovalRequestImpl(itemToApprove, null, resourceType.getBusiness().getApproverRef(), null, null, prismContext);
+ ApprovalRequest approvalRequest = new ApprovalRequestImpl(itemToApprove, config, null, resourceType.getBusiness().getApproverRef(), null, null, prismContext);
approvalRequestList.add(approvalRequest);
}
}
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/ModifyRoleAssignmentAspect.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/ModifyRoleAssignmentAspect.java
index 51d7c570148..afa9bf8b22a 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/ModifyRoleAssignmentAspect.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/ModifyRoleAssignmentAspect.java
@@ -48,7 +48,9 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.PcpAspectConfigurationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.WfConfigurationType;
import com.evolveum.midpoint.xml.ns.model.workflow.common_forms_3.AbstractRoleAssignmentModificationApprovalFormType;
import com.evolveum.midpoint.xml.ns.model.workflow.common_forms_3.QuestionFormType;
import com.evolveum.prism.xml.ns._public.types_3.ChangeTypeType;
@@ -82,25 +84,36 @@ public class ModifyRoleAssignmentAspect extends BasePrimaryChangeAspect {
@Autowired
private ItemApprovalProcessInterface itemApprovalProcessInterface;
+ @Override
+ public boolean isEnabledByDefault() {
+ return true;
+ }
+
//region ------------------------------------------------------------ Things that execute on request arrival
@Override
- public List prepareJobCreationInstructions(ModelContext> modelContext, ObjectDelta extends ObjectType> change, Task taskFromModel, OperationResult result) throws SchemaException {
+ public List prepareJobCreationInstructions(ModelContext> modelContext, WfConfigurationType wfConfigurationType, ObjectDelta extends ObjectType> change, Task taskFromModel, OperationResult result) throws SchemaException {
- List> approvalRequestList = getApprovalRequests(modelContext, change, result);
+ if (!primaryChangeAspectHelper.isUserRelated(modelContext)) {
+ return null;
+ }
+ List> approvalRequestList = getApprovalRequests(modelContext, wfConfigurationType, change, result);
if (approvalRequestList == null || approvalRequestList.isEmpty()) {
return null;
}
return prepareJobCreateInstructions(modelContext, taskFromModel, result, approvalRequestList);
}
- private List> getApprovalRequests(ModelContext> modelContext, ObjectDelta extends ObjectType> change, OperationResult result) throws SchemaException {
+ private List> getApprovalRequests(ModelContext> modelContext, WfConfigurationType wfConfigurationType, ObjectDelta extends ObjectType> change, OperationResult result) throws SchemaException {
if (change.getChangeType() != ChangeType.MODIFY) {
return null;
}
PrismObject userOld = (PrismObject) modelContext.getFocusContext().getObjectOld();
UserType userTypeOld = userOld.asObjectable();
+ PcpAspectConfigurationType config = primaryChangeAspectHelper.getPcpAspectConfigurationType(
+ wfConfigurationType, this);
+
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Role-related assignments in user modify delta: ");
}
@@ -145,7 +158,7 @@ private List> getApprovalReq
PrismContainerValue.copyDefinition(aCopy, assignmentType);
AbstractRoleType role = (AbstractRoleType) primaryChangeAspectHelper.resolveObjectRef(assignmentType, result);
AbstractRoleAssignmentModification itemToApprove = new AbstractRoleAssignmentModification(aCopy, role, entry.getValue());
- ApprovalRequest approvalRequest = new ApprovalRequestImpl(itemToApprove, role.getApprovalSchema(), role.getApproverRef(), role.getApproverExpression(), role.getAutomaticallyApproved(), prismContext);
+ ApprovalRequest approvalRequest = new ApprovalRequestImpl(itemToApprove, config, role.getApprovalSchema(), role.getApproverRef(), role.getApproverExpression(), role.getAutomaticallyApproved(), prismContext);
approvalRequestList.add(approvalRequest);
}
}
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/PrimaryUserChangeProcessor.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/PrimaryUserChangeProcessor.java
deleted file mode 100644
index be1edbce3a3..00000000000
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/user/PrimaryUserChangeProcessor.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2010-2013 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.wf.impl.processors.primary.user;
-
-import com.evolveum.midpoint.model.api.context.ModelContext;
-import com.evolveum.midpoint.model.api.context.ModelState;
-import com.evolveum.midpoint.model.api.hooks.HookOperationMode;
-import com.evolveum.midpoint.prism.Objectable;
-import com.evolveum.midpoint.prism.delta.ObjectDelta;
-import com.evolveum.midpoint.schema.result.OperationResult;
-import com.evolveum.midpoint.task.api.Task;
-import com.evolveum.midpoint.util.exception.SchemaException;
-import com.evolveum.midpoint.util.logging.Trace;
-import com.evolveum.midpoint.util.logging.TraceManager;
-import com.evolveum.midpoint.wf.impl.processors.primary.PrimaryChangeProcessor;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
-
-import org.springframework.stereotype.Component;
-
-/**
- * Deals with approving primary changes related to a user. Typical such changes are adding of a role or an account.
- *
- * @author mederly
- */
-
-@Component("primaryUserChangeProcessor")
-public class PrimaryUserChangeProcessor extends PrimaryChangeProcessor {
-
- private static final Trace LOGGER = TraceManager.getTrace(PrimaryUserChangeProcessor.class);
-
- @Override
- public HookOperationMode processModelInvocation(ModelContext context, Task taskFromModel, OperationResult result) throws SchemaException {
-
- if (context.getState() != ModelState.PRIMARY || context.getFocusContext() == null) {
- return null;
- }
-
- ObjectDelta change = context.getFocusContext().getPrimaryDelta();
- if (change == null) {
- return null;
- }
-
- // let's check whether we deal with a user
-
- if (!UserType.class.isAssignableFrom(change.getObjectTypeClass())) {
- if (LOGGER.isTraceEnabled()) {
- LOGGER.trace("change object type class is not a UserType (it is " + change.getObjectTypeClass() + "), exiting " + this.getClass().getSimpleName());
- }
- return null;
- }
-
- // the rest is quite generic
- return super.processModelInvocation(context, taskFromModel, result);
- }
-
-
-}
diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/AbstractWfTest.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/AbstractWfTest.java
index a71dd4731ed..d94dc6ad4cd 100644
--- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/AbstractWfTest.java
+++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/AbstractWfTest.java
@@ -41,7 +41,6 @@
import com.evolveum.midpoint.prism.util.PrismTestUtil;
import com.evolveum.midpoint.schema.DeltaConvertor;
import com.evolveum.midpoint.schema.result.OperationResult;
-import com.evolveum.midpoint.schema.util.MiscSchemaUtil;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.task.api.TaskExecutionStatus;
import com.evolveum.midpoint.task.api.TaskManager;
@@ -178,22 +177,24 @@ public void initSystem(Task initTask, OperationResult initResult)
ObjectReferenceType approver = role2.getApprovalSchema().getLevel().get(0).getApproverRef().get(0);
assertEquals("Wrong OID of Role2's approver", R2BOSS_OID, approver.getOid());
-
- primaryChangeProcessor.setEnabled(true);
- generalChangeProcessor.setEnabled(false);
}
protected void checkUserApprovers(String oid, List expectedApprovers, OperationResult result) throws SchemaException, ObjectNotFoundException {
PrismObject user = repositoryService.getObject(UserType.class, oid, null, result);
- checkUserApprovers(user, expectedApprovers, user.asObjectable().getMetadata().getModifyApproverRef(), result);
+ checkApprovers(user, expectedApprovers, user.asObjectable().getMetadata().getModifyApproverRef(), result);
}
protected void checkUserApproversForCreate(String oid, List expectedApprovers, OperationResult result) throws SchemaException, ObjectNotFoundException {
PrismObject user = repositoryService.getObject(UserType.class, oid, null, result);
- checkUserApprovers(user, expectedApprovers, user.asObjectable().getMetadata().getCreateApproverRef(), result);
+ checkApprovers(user, expectedApprovers, user.asObjectable().getMetadata().getCreateApproverRef(), result);
+ }
+
+ protected void checkApproversForCreate(Class extends ObjectType> clazz, String oid, List expectedApprovers, OperationResult result) throws SchemaException, ObjectNotFoundException {
+ PrismObject extends ObjectType> object = repositoryService.getObject(clazz, oid, null, result);
+ checkApprovers(object, expectedApprovers, object.asObjectable().getMetadata().getCreateApproverRef(), result);
}
- protected void checkUserApprovers(PrismObject user, List expectedApprovers, List realApprovers, OperationResult result) throws SchemaException, ObjectNotFoundException {
+ protected void checkApprovers(PrismObject extends ObjectType> object, List expectedApprovers, List realApprovers, OperationResult result) throws SchemaException, ObjectNotFoundException {
HashSet realApproversSet = new HashSet();
for (ObjectReferenceType approver : realApprovers) {
realApproversSet.add(approver.getOid());
diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/TestCreateOrg.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/TestCreateOrg.java
new file mode 100644
index 00000000000..4a9435741b7
--- /dev/null
+++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/TestCreateOrg.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2010-2015 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.wf.impl;
+
+import com.evolveum.midpoint.model.api.context.ModelContext;
+import com.evolveum.midpoint.model.impl.lens.LensContext;
+import com.evolveum.midpoint.prism.delta.ObjectDelta;
+import com.evolveum.midpoint.prism.util.PrismTestUtil;
+import com.evolveum.midpoint.schema.result.OperationResult;
+import com.evolveum.midpoint.task.api.Task;
+import com.evolveum.midpoint.test.util.TestUtil;
+import com.evolveum.midpoint.util.logging.Trace;
+import com.evolveum.midpoint.util.logging.TraceManager;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.annotation.DirtiesContext.ClassMode;
+import org.springframework.test.context.ContextConfiguration;
+import org.testng.annotations.Test;
+
+import javax.xml.bind.JAXBException;
+import java.io.File;
+import java.util.Arrays;
+
+import static org.testng.AssertJUnit.assertTrue;
+
+/**
+ * @author mederly
+ */
+@ContextConfiguration(locations = {"classpath:ctx-workflow-test-main.xml"})
+@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
+public class TestCreateOrg extends AbstractWfTest {
+
+ protected static final Trace LOGGER = TraceManager.getTrace(TestCreateOrg.class);
+
+ private static final File TEST1_FILE = new File(TEST_RESOURCE_DIR, "org-test1.xml");
+ private static final String ORG_TEST1_OID = "00000000-1345-3213-4321-432435432034";
+
+ public TestCreateOrg() throws JAXBException {
+ super();
+ }
+
+ /**
+ * Create org test1 - rejected
+ */
+ @Test(enabled = true)
+ public void test010CreateTest1Rejected() throws Exception {
+ TestUtil.displayTestTile(this, "test010CreateTest1Rejected");
+ executeTest("test010CreateTest1Rejected", ORG_TEST1_OID, new TestDetails() {
+ @Override
+ int subtaskCount() {
+ return 1;
+ }
+
+ @Override
+ boolean immediate() {
+ return false;
+ }
+
+ @Override
+ boolean checkObjectOnSubtasks() {
+ return true;
+ }
+
+ @Override
+ boolean removeAssignmentsBeforeTest() {
+ return false;
+ }
+
+ @Override
+ public LensContext createModelContext(OperationResult result) throws Exception {
+ LensContext context = createLensContext(OrgType.class);
+ addFocusDeltaToContext(context, (ObjectDelta) ObjectDelta.createAddDelta(PrismTestUtil.parseObject(TEST1_FILE)));
+ return context;
+ }
+
+ @Override
+ public void assertsAfterClockworkRun(Task task, OperationResult result) throws Exception {
+ ModelContext taskModelContext = wfTaskUtil.retrieveModelContext(task, result);
+ assertTrue("Primary focus delta is not empty", taskModelContext.getFocusContext().getPrimaryDelta().isEmpty());
+ assertNoObject(OrgType.class, ORG_TEST1_OID, task, result);
+ }
+
+ @Override
+ void assertsRootTaskFinishes(Task task, OperationResult result) throws Exception {
+ //checkDummyTransportMessages("simpleUserNotifier", 1);
+ //checkWorkItemAuditRecords(createResultMap(ROLE_R1_OID, WorkflowResult.APPROVED));
+ assertNoObject(OrgType.class, ORG_TEST1_OID, task, result);
+ }
+
+ @Override
+ boolean decideOnApproval(String executionId) throws Exception {
+ return false;
+ }
+ });
+ }
+
+ /**
+ * Create org test1 - this time approved
+ */
+ @Test(enabled = true)
+ public void test020CreateTest1Approved() throws Exception {
+ TestUtil.displayTestTile(this, "test020CreateTest1Approved");
+ executeTest("test020CreateTest1Approved", ORG_TEST1_OID, new TestDetails() {
+ @Override int subtaskCount() { return 1; }
+ @Override boolean immediate() { return false; }
+ @Override boolean checkObjectOnSubtasks() { return true; }
+ @Override boolean removeAssignmentsBeforeTest() { return false; }
+
+ @Override
+ public LensContext createModelContext(OperationResult result) throws Exception {
+ LensContext context = createLensContext(OrgType.class);
+ addFocusDeltaToContext(context, (ObjectDelta) ObjectDelta.createAddDelta(PrismTestUtil.parseObject(TEST1_FILE)));
+ return context;
+ }
+
+ @Override
+ public void assertsAfterClockworkRun(Task task, OperationResult result) throws Exception {
+ ModelContext taskModelContext = wfTaskUtil.retrieveModelContext(task, result);
+ assertTrue("Primary focus delta is not empty", taskModelContext.getFocusContext().getPrimaryDelta().isEmpty());
+ assertNoObject(OrgType.class, ORG_TEST1_OID, task, result);
+ }
+
+ @Override
+ void assertsRootTaskFinishes(Task task, OperationResult result) throws Exception {
+ //checkDummyTransportMessages("simpleUserNotifier", 1);
+ //checkWorkItemAuditRecords(createResultMap(ROLE_R1_OID, WorkflowResult.APPROVED));
+ checkApproversForCreate(OrgType.class, ORG_TEST1_OID, Arrays.asList(USER_ADMINISTRATOR_OID), result);
+ }
+
+ @Override
+ boolean decideOnApproval(String executionId) throws Exception {
+ return true;
+ }
+ });
+ }
+}
diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/TestUserChangeApproval.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/TestUserChangeApproval.java
index 2266482b7d7..cacdfed3506 100644
--- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/TestUserChangeApproval.java
+++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/TestUserChangeApproval.java
@@ -31,7 +31,6 @@
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.path.NameItemPathSegment;
import com.evolveum.midpoint.prism.polystring.PolyString;
-import com.evolveum.midpoint.prism.util.JavaTypeConverter;
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.prism.xnode.PrimitiveXNode;
import com.evolveum.midpoint.schema.result.OperationResult;
diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/general/TestGeneralChangeProcessor.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/general/TestGeneralChangeProcessor.java
index 45a0c027d08..9a14da6a321 100644
--- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/general/TestGeneralChangeProcessor.java
+++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/general/TestGeneralChangeProcessor.java
@@ -25,6 +25,7 @@
import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.schema.DeltaConvertor;
+import com.evolveum.midpoint.schema.constants.MidPointConstants;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
@@ -134,10 +135,21 @@ public void initSystem(Task initTask, OperationResult initResult)
throws Exception {
super.initSystem(initTask, initResult);
importObjectFromFile(AbstractWfTest.USERS_AND_ROLES_FILENAME, initResult);
-
+ modifyObjectReplaceProperty(SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(),
+ new ItemPath(SystemConfigurationType.F_WORKFLOW_CONFIGURATION,
+ WfConfigurationType.F_PRIMARY_CHANGE_PROCESSOR,
+ PrimaryChangeProcessorConfigurationType.F_ENABLED),
+ initTask, initResult,
+ false);
+ modifyObjectReplaceProperty(SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(),
+ new ItemPath(SystemConfigurationType.F_WORKFLOW_CONFIGURATION,
+ WfConfigurationType.F_GENERAL_CHANGE_PROCESSOR,
+ GeneralChangeProcessorConfigurationType.F_ENABLED),
+ initTask, initResult,
+ true);
}
- @Test(enabled = true)
+ @Test
public void test010AddRole1() throws Exception {
TestUtil.displayTestTile(this, "test010UserModifyAddRole");
executeTest("test010UserModifyAddRole", USER_JACK_OID, 1, false, true, new ContextCreator() {
@@ -192,14 +204,11 @@ void assertsRootTaskFinishes(Task task, OperationResult result) throws Exception
});
}
- @Test(enabled = true)
+ @Test
public void test020AddAccountRejected() throws Exception {
TestUtil.displayTestTile(this, "test020AddAccountRejected");
- primaryChangeProcessor.setEnabled(false);
- generalChangeProcessor.setEnabled(true);
- generalChangeProcessor.disableScenario("primaryScenario");
- generalChangeProcessor.enableScenario("secondaryScenario");
+ enableDisableScenarios(false, true);
executeTest("test020AddAccountRejected", USER_JACK_OID, 1, false, true, new ContextCreator() {
@Override
@@ -252,6 +261,21 @@ void assertsRootTaskFinishes(Task task, OperationResult result) throws Exception
});
}
+ protected void enableDisableScenarios(boolean... values) throws ObjectNotFoundException, SchemaException, com.evolveum.midpoint.util.exception.ExpressionEvaluationException, com.evolveum.midpoint.util.exception.CommunicationException, com.evolveum.midpoint.util.exception.ConfigurationException, com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException, com.evolveum.midpoint.model.api.PolicyViolationException, com.evolveum.midpoint.util.exception.SecurityViolationException {
+ OperationResult result = new OperationResult("execution");
+ Task task = taskManager.createTaskInstance("execution");
+ GeneralChangeProcessorConfigurationType gcpConfig = getSystemConfiguration().getWorkflowConfiguration().getGeneralChangeProcessor();
+ for (int i = 0; i < values.length; i++) {
+ gcpConfig.getScenario().get(i).setEnabled(values[i]);
+ }
+ modifyObjectReplaceProperty(SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(),
+ new ItemPath(SystemConfigurationType.F_WORKFLOW_CONFIGURATION,
+ WfConfigurationType.F_GENERAL_CHANGE_PROCESSOR,
+ GeneralChangeProcessorConfigurationType.F_ENABLED),
+ task, result,
+ gcpConfig);
+ }
+
// @Test(enabled = false)
// public void test028CurrentRepo() throws Exception {
// TestUtil.displayTestTile(this, "test029NewRepo");
@@ -280,14 +304,11 @@ void assertsRootTaskFinishes(Task task, OperationResult result) throws Exception
// LOGGER.info("Parsed:\n{}", o.debugDump());
// }
- @Test(enabled = true)
+ @Test
public void test030AddAccountApproved() throws Exception {
TestUtil.displayTestTile(this, "test030AddAccountApproved");
- primaryChangeProcessor.setEnabled(false);
- generalChangeProcessor.setEnabled(true);
- generalChangeProcessor.disableScenario("primaryScenario");
- generalChangeProcessor.enableScenario("secondaryScenario");
+ enableDisableScenarios(false, true);
executeTest("test030AddAccountApproved", USER_JACK_OID, 1, false, true, new ContextCreator() {
@Override
diff --git a/model/workflow-impl/src/test/resources/common/system-configuration.xml b/model/workflow-impl/src/test/resources/common/system-configuration.xml
index 332c7aa685a..02dee95da92 100644
--- a/model/workflow-impl/src/test/resources/common/system-configuration.xml
+++ b/model/workflow-impl/src/test/resources/common/system-configuration.xml
@@ -64,4 +64,38 @@
target/mail-notifications.log
+
+
+ true
+
+
+
+
+ changePasswordAspect
+
+
+
+ false
+
+ primaryScenario
+
+
+
+ MyGreatPrimaryProcess
+
+
+ secondaryScenario
+
+
+
+ ApprovingDummyResourceChangesProcess
+ approvingDummyResourceChangesScenarioBean
+
+
+
diff --git a/model/workflow-impl/src/test/resources/org-test1.xml b/model/workflow-impl/src/test/resources/org-test1.xml
new file mode 100644
index 00000000000..caa57eab884
--- /dev/null
+++ b/model/workflow-impl/src/test/resources/org-test1.xml
@@ -0,0 +1,24 @@
+
+
+
+
+ test1
+ Test 1
+ functional
+
diff --git a/model/workflow-impl/src/test/resources/test-config.xml b/model/workflow-impl/src/test/resources/test-config.xml
index 4ec01b9719a..cd93eff0750 100644
--- a/model/workflow-impl/src/test/resources/test-config.xml
+++ b/model/workflow-impl/src/test/resources/test-config.xml
@@ -34,41 +34,6 @@
sa
-
-
- true
-
-
- primaryScenario
-
- context.getState() == com.evolveum.midpoint.model.api.context.ModelState.PRIMARY
-
- MyGreatPrimaryProcess
-
-
- secondaryScenario
-
-
-
-
-
- ApprovingDummyResourceChangesProcess
- approvingDummyResourceChangesScenarioBean
-
-
-
-
- true
- addRoleAssignmentAspect
- modifyRoleAssignmentAspect
- addResourceAssignmentAspect
- modifyResourceAssignmentAspect
- changePasswordAspect
-
-
diff --git a/model/workflow-impl/testng.xml b/model/workflow-impl/testng.xml
index 052328b8528..b5084b0f31f 100644
--- a/model/workflow-impl/testng.xml
+++ b/model/workflow-impl/testng.xml
@@ -20,6 +20,7 @@
+