diff --git a/config/alfresco/repository.properties b/config/alfresco/repository.properties
index 7ac609d102..e6f6bf44c3 100644
--- a/config/alfresco/repository.properties
+++ b/config/alfresco/repository.properties
@@ -42,6 +42,15 @@ system.workflow.deployservlet.enabled=false
# Sets the location for the JBPM Configuration File
system.workflow.jbpm.config.location=classpath:org/alfresco/repo/workflow/jbpm/jbpm.cfg.xml
+# Determines if the JBPM engine is enabled
+# NOTE: The JBPM engine is used by several parts of the system so it's recommended that
+# it remains enabled. Only change this setting if you have alternative solutions
+# for the affected areas i.e. site invitations, publishing and WCM
+system.workflow.engine.jbpm.enabled=true
+
+# Determines if the Activiti engine is enabled
+system.workflow.engine.activiti.enabled=true
+
index.subsystem.name=lucene
# ######################################### #
diff --git a/config/alfresco/workflow-context.xml b/config/alfresco/workflow-context.xml
index c1e7253624..f964351e08 100644
--- a/config/alfresco/workflow-context.xml
+++ b/config/alfresco/workflow-context.xml
@@ -11,6 +11,7 @@
+
@@ -60,6 +61,19 @@
+
+
+
+
+
+
+
+ ${system.workflow.engine.jbpm.enabled}
+
+
+ ${system.workflow.engine.activiti.enabled}
+
+
@@ -77,6 +91,7 @@
+
diff --git a/source/java/org/alfresco/repo/workflow/BPMEngineRegistry.java b/source/java/org/alfresco/repo/workflow/BPMEngineRegistry.java
index fe54d03fc1..49f6fa29f2 100644
--- a/source/java/org/alfresco/repo/workflow/BPMEngineRegistry.java
+++ b/source/java/org/alfresco/repo/workflow/BPMEngineRegistry.java
@@ -21,6 +21,7 @@ package org.alfresco.repo.workflow;
import java.util.HashMap;
import java.util.Map;
+import org.alfresco.service.cmr.workflow.WorkflowAdminService;
import org.alfresco.service.cmr.workflow.WorkflowException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -46,6 +47,8 @@ public class BPMEngineRegistry
/** Logging support */
private static Log logger = LogFactory.getLog("org.alfresco.repo.workflow");
+ private WorkflowAdminService workflowAdminService;
+
private Map workflowComponents;
private Map taskComponents;
@@ -58,6 +61,16 @@ public class BPMEngineRegistry
taskComponents = new HashMap();
}
+ /**
+ * Sets the workflow admin service
+ *
+ * @param workflowAdminService the workflow admin service
+ */
+ public void setWorkflowAdminService(WorkflowAdminService workflowAdminService)
+ {
+ this.workflowAdminService = workflowAdminService;
+ }
+
/**
* Register a BPM Engine Workflow Component
*
@@ -70,10 +83,19 @@ public class BPMEngineRegistry
{
throw new WorkflowException("Workflow Component already registered for engine id '" + engineId + "'");
}
- workflowComponents.put(engineId, engine);
- if (logger.isInfoEnabled())
- logger.info("Registered Workflow Component '" + engineId + "' (" + engine.getClass() + ")");
+ if (workflowAdminService.isEngineEnabled(engineId))
+ {
+ workflowComponents.put(engineId, engine);
+
+ if (logger.isDebugEnabled())
+ logger.debug("Registered Workflow Component '" + engineId + "' (" + engine.getClass() + ")");
+ }
+ else
+ {
+ if (logger.isWarnEnabled())
+ logger.warn("Ignoring Workflow Component '" + engineId + "' (" + engine.getClass() + ") as the engine is disabled");
+ }
}
/**
@@ -109,10 +131,19 @@ public class BPMEngineRegistry
{
throw new WorkflowException("Task Component already registered for engine id '" + engineId + "'");
}
- taskComponents.put(engineId, engine);
- if (logger.isInfoEnabled())
- logger.info("Registered Task Component '" + engineId + "' (" + engine.getClass() + ")");
+ if (workflowAdminService.isEngineEnabled(engineId))
+ {
+ taskComponents.put(engineId, engine);
+
+ if (logger.isDebugEnabled())
+ logger.debug("Registered Task Component '" + engineId + "' (" + engine.getClass() + ")");
+ }
+ else
+ {
+ if (logger.isWarnEnabled())
+ logger.warn("Ignoring Task Component '" + engineId + "' (" + engine.getClass() + ") as the engine is disabled");
+ }
}
/**
diff --git a/source/java/org/alfresco/repo/workflow/WorkflowAdminServiceImpl.java b/source/java/org/alfresco/repo/workflow/WorkflowAdminServiceImpl.java
new file mode 100644
index 0000000000..408e9eba6c
--- /dev/null
+++ b/source/java/org/alfresco/repo/workflow/WorkflowAdminServiceImpl.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2005-2011 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.repo.workflow;
+
+import org.alfresco.repo.workflow.activiti.ActivitiConstants;
+import org.alfresco.repo.workflow.jbpm.JBPMEngine;
+import org.alfresco.service.cmr.workflow.WorkflowAdminService;
+
+/**
+ * Default implementation of the workflow admin service.
+ *
+ * @author Gavin Cornwell
+ * @since 4.0
+ */
+public class WorkflowAdminServiceImpl implements WorkflowAdminService
+{
+ private boolean jbpmEngineEnabled = true;
+ private boolean activitiEngineEnabled = true;
+
+ public void setJbpmEngineEnabled(boolean jbpmEngineEnabled)
+ {
+ this.jbpmEngineEnabled = jbpmEngineEnabled;
+ }
+
+ public void setActivitiEngineEnabled(boolean activitiEngineEnabled)
+ {
+ this.activitiEngineEnabled = activitiEngineEnabled;
+ }
+
+ @Override
+ public boolean isEngineEnabled(String engineId)
+ {
+ if (JBPMEngine.ENGINE_ID.equals(engineId))
+ {
+ return jbpmEngineEnabled;
+ }
+ else if (ActivitiConstants.ENGINE_ID.equals(engineId))
+ {
+ return activitiEngineEnabled;
+ }
+ else
+ {
+ // if the engine id is not recognised it can't be enabled!
+ return false;
+ }
+ }
+}
diff --git a/source/java/org/alfresco/repo/workflow/WorkflowDeployer.java b/source/java/org/alfresco/repo/workflow/WorkflowDeployer.java
index 1d1303154e..1b98ad6545 100644
--- a/source/java/org/alfresco/repo/workflow/WorkflowDeployer.java
+++ b/source/java/org/alfresco/repo/workflow/WorkflowDeployer.java
@@ -40,6 +40,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.SearchService;
+import org.alfresco.service.cmr.workflow.WorkflowAdminService;
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowDeployment;
import org.alfresco.service.cmr.workflow.WorkflowException;
@@ -73,6 +74,7 @@ public class WorkflowDeployer extends AbstractLifecycleBean
// Dependencies
private TransactionService transactionService;
private WorkflowService workflowService;
+ private WorkflowAdminService workflowAdminService;
private AuthenticationContext authenticationContext;
private DictionaryDAO dictionaryDAO;
private List workflowDefinitions;
@@ -100,14 +102,24 @@ public class WorkflowDeployer extends AbstractLifecycleBean
}
/**
- * Sets the namespace service
+ * Sets the workflow service
*
- * @param namespaceService the namespace service
+ * @param workflowService the workflow service
*/
public void setWorkflowService(WorkflowService workflowService)
{
this.workflowService = workflowService;
}
+
+ /**
+ * Sets the workflow admin service
+ *
+ * @param workflowAdminService the workflow admin service
+ */
+ public void setWorkflowAdminService(WorkflowAdminService workflowAdminService)
+ {
+ this.workflowAdminService = workflowAdminService;
+ }
/**
* Set the authentication component
@@ -223,7 +235,9 @@ public class WorkflowDeployer extends AbstractLifecycleBean
}
if (!transactionService.getAllowWrite())
{
- logger.warn("Repository is in read-only mode; not deploying workflows.");
+ if (logger.isWarnEnabled())
+ logger.warn("Repository is in read-only mode; not deploying workflows.");
+
return;
}
@@ -235,12 +249,12 @@ public class WorkflowDeployer extends AbstractLifecycleBean
// bootstrap the workflow models and static labels (from classpath)
if (models != null && resourceBundles != null && ((models.size() > 0) || (resourceBundles.size() > 0)))
{
- DictionaryBootstrap dictionaryBootstrap = new DictionaryBootstrap();
- dictionaryBootstrap.setDictionaryDAO(dictionaryDAO);
+ DictionaryBootstrap dictionaryBootstrap = new DictionaryBootstrap();
+ dictionaryBootstrap.setDictionaryDAO(dictionaryDAO);
dictionaryBootstrap.setTenantService(tenantService);
- dictionaryBootstrap.setModels(models);
- dictionaryBootstrap.setLabels(resourceBundles);
- dictionaryBootstrap.bootstrap(); // also registers with dictionary
+ dictionaryBootstrap.setModels(models);
+ dictionaryBootstrap.setLabels(resourceBundles);
+ dictionaryBootstrap.bootstrap(); // also registers with dictionary
}
// bootstrap the workflow definitions (from classpath)
@@ -254,25 +268,22 @@ public class WorkflowDeployer extends AbstractLifecycleBean
{
throw new WorkflowException("Workflow Engine Id must be provided");
}
+
String location = workflowDefinition.getProperty(LOCATION);
if (location == null || location.length() == 0)
{
throw new WorkflowException("Workflow definition location must be provided");
}
- Boolean redeploy = Boolean.valueOf(workflowDefinition.getProperty(REDEPLOY));
- String mimetype = workflowDefinition.getProperty(MIMETYPE);
-
- // retrieve input stream on workflow definition
- ClassPathResource workflowResource = new ClassPathResource(location);
- // deploy workflow definition
- if (!redeploy && workflowService.isDefinitionDeployed(engineId, workflowResource.getInputStream(), mimetype))
- {
- if (logger.isDebugEnabled())
- logger.debug("Workflow deployer: Definition '" + location + "' already deployed");
- }
- else
+ if (workflowAdminService.isEngineEnabled(engineId))
{
+ Boolean redeploy = Boolean.valueOf(workflowDefinition.getProperty(REDEPLOY));
+ String mimetype = workflowDefinition.getProperty(MIMETYPE);
+
+ // retrieve input stream on workflow definition
+ ClassPathResource workflowResource = new ClassPathResource(location);
+
+ // deploy workflow definition
if (!redeploy && workflowService.isDefinitionDeployed(engineId, workflowResource.getInputStream(), mimetype))
{
if (logger.isDebugEnabled())
@@ -280,11 +291,24 @@ public class WorkflowDeployer extends AbstractLifecycleBean
}
else
{
- WorkflowDeployment deployment = workflowService.deployDefinition(engineId, workflowResource.getInputStream(),
- mimetype, workflowResource.getFilename());
- logDeployment(location, deployment);
+ if (!redeploy && workflowService.isDefinitionDeployed(engineId, workflowResource.getInputStream(), mimetype))
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Workflow deployer: Definition '" + location + "' already deployed");
+ }
+ else
+ {
+ WorkflowDeployment deployment = workflowService.deployDefinition(engineId, workflowResource.getInputStream(),
+ mimetype, workflowResource.getFilename());
+ logDeployment(location, deployment);
+ }
}
}
+ else
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Workflow deployer: Definition '" + location + "' not deployed as the '" + engineId + "' engine is disabled");
+ }
}
}
@@ -299,9 +323,9 @@ public class WorkflowDeployer extends AbstractLifecycleBean
{
for (NodeRef nodeRef : nodeRefs)
{
- deploy(nodeRef, false);
- }
- }
+ deploy(nodeRef, false);
+ }
+ }
}
userTransaction.commit();
@@ -328,59 +352,66 @@ public class WorkflowDeployer extends AbstractLifecycleBean
{
Boolean value = (Boolean)nodeService.getProperty(nodeRef, WorkflowModel.PROP_WORKFLOW_DEF_DEPLOYED);
if ((value != null) && (value.booleanValue() == true))
- {
- if (!redeploy && workflowService.isDefinitionDeployed(nodeRef))
- {
- if (logger.isDebugEnabled())
- {
- logger.debug("Workflow deployer: Definition '" + nodeRef + "' already deployed");
+ {
+ String engineId = (String) nodeService.getProperty(nodeRef, WorkflowModel.PROP_WORKFLOW_DEF_ENGINE_ID);
+
+ if (workflowAdminService.isEngineEnabled(engineId))
+ {
+ if (!redeploy && workflowService.isDefinitionDeployed(nodeRef))
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Workflow deployer: Definition '" + nodeRef + "' already deployed");
+ }
+ else
+ {
+ // deploy / re-deploy
+ WorkflowDeployment deployment = workflowService.deployDefinition(nodeRef);
+ logDeployment(nodeRef, deployment);
+ if (deployment != null)
+ {
+ WorkflowDefinition def = deployment.getDefinition();
+
+ // Update the meta data for the model
+ Map props = nodeService.getProperties(nodeRef);
+
+ props.put(WorkflowModel.PROP_WORKFLOW_DEF_NAME, def.getName());
+
+ // TODO - ability to return and handle deployment problems / warnings
+ if (deployment.getProblems().length > 0)
+ {
+ for (String problem : deployment.getProblems())
+ {
+ if (logger.isWarnEnabled())
+ logger.warn(problem);
+ }
+ }
+
+ nodeService.setProperties(nodeRef, props);
+ }
}
- }
- else
- {
- // deploy / re-deploy
- WorkflowDeployment deployment = workflowService.deployDefinition(nodeRef);
- logDeployment(nodeRef, deployment);
- if (deployment != null)
- {
- WorkflowDefinition def = deployment.getDefinition();
-
- // Update the meta data for the model
- Map props = nodeService.getProperties(nodeRef);
-
- props.put(WorkflowModel.PROP_WORKFLOW_DEF_NAME, def.getName());
-
- // TODO - ability to return and handle deployment problems / warnings
- if (deployment.getProblems().length > 0)
- {
- for (String problem : deployment.getProblems())
- {
- logger.warn(problem);
- }
- }
-
- nodeService.setProperties(nodeRef, props);
- }
- }
+ }
+ else
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Workflow deployer: Definition '" + nodeRef + "' not deployed as the '" + engineId + "' engine is disabled");
+ }
}
}
else
{
if (logger.isDebugEnabled())
- {
- logger.debug("Workflow deployer: Definition '" + nodeRef + "' not deployed since it is a working copy");
- }
+ logger.debug("Workflow deployer: Definition '" + nodeRef + "' not deployed since it is a working copy");
}
}
private void logDeployment(Object location, WorkflowDeployment deployment)
{
- if (logger.isInfoEnabled())
+ if (logger.isDebugEnabled())
{
String title = deployment.getDefinition().getTitle();
String version = deployment.getDefinition().getVersion();
int problemLength = deployment.getProblems().length;
- logger.info("Workflow deployer: Deployed process definition '" + title + "' (version " + version + ") from '" + location + "' with " + problemLength + " problems");
+ logger.debug("Workflow deployer: Deployed process definition '" + title + "' (version " + version + ") from '" + location + "' with " + problemLength + " problems");
}
}
@@ -396,24 +427,20 @@ public class WorkflowDeployer extends AbstractLifecycleBean
List defs = workflowService.getAllDefinitionsByName(defName);
for (WorkflowDefinition def: defs)
{
- if (logger.isInfoEnabled())
- {
- logger.info("Undeploying workflow '" + defName + "' ...");
- }
+ if (logger.isDebugEnabled())
+ logger.debug("Undeploying workflow '" + defName + "' ...");
+
workflowService.undeployDefinition(def.getId());
- if (logger.isInfoEnabled())
- {
- logger.info("... undeployed '" + def.getId() + "' v" + def.getVersion());
- }
+
+ if (logger.isDebugEnabled())
+ logger.debug("... undeployed '" + def.getId() + "' v" + def.getVersion());
}
}
}
else
{
if (logger.isDebugEnabled())
- {
- logger.debug("Workflow deployer: Definition '" + nodeRef + "' not undeployed since it is a working copy");
- }
+ logger.debug("Workflow deployer: Definition '" + nodeRef + "' not undeployed since it is a working copy");
}
}
@@ -424,10 +451,10 @@ public class WorkflowDeployer extends AbstractLifecycleBean
AuthenticationUtil.runAs(new RunAsWork