Consolidate/fix bootstrap import (MT & ST) of repo-sourced workflow defs

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@8087 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Jan Vonka
2008-01-24 16:10:35 +00:00
parent f3b4ed76dd
commit d27f0b557e
10 changed files with 207 additions and 183 deletions

View File

@@ -302,6 +302,7 @@
<value>alfresco/workflow/wcm-workflow-messages</value> <value>alfresco/workflow/wcm-workflow-messages</value>
</list> </list>
</property> </property>
<property name="repositoryWorkflowDefsLocations" ref="customWorkflowDefsRepositoryLocation"/>
</bean> </bean>
<!-- Bootstrap any extensions --> <!-- Bootstrap any extensions -->

View File

@@ -24,10 +24,7 @@
<property name="workflowService" ref="WorkflowService"/> <property name="workflowService" ref="WorkflowService"/>
<property name="repositoryExporterService" ref="repositoryExporterComponent"/> <property name="repositoryExporterService" ref="repositoryExporterComponent"/>
<property name="namespaceService" ref="NamespaceService"/> <property name="workflowDeployer" ref="workflowBootstrap"/>
<property name="searchService" ref="SearchService"/>
<property name="workflowDefinitionType" ref="workflowDefinitionType"/>
<property name="repositoryWorkflowDefsLocations" ref="customWorkflowDefsRepositoryLocation"/>
</bean> </bean>

View File

@@ -14,7 +14,10 @@
<property name="dictionaryDAO" ref="dictionaryDAO"/> <property name="dictionaryDAO" ref="dictionaryDAO"/>
<property name="allowWrite"> <property name="allowWrite">
<value>${server.transaction.allow-writes}</value> <value>${server.transaction.allow-writes}</value>
</property> </property>
<property name="nodeService" ref="NodeService"/>
<property name="searchService" ref="SearchService"/>
<property name="namespaceService" ref="NamespaceService"/>
</bean> </bean>
<bean id="workflowServiceImpl" class="org.alfresco.repo.workflow.WorkflowServiceImpl"> <bean id="workflowServiceImpl" class="org.alfresco.repo.workflow.WorkflowServiceImpl">
@@ -109,8 +112,8 @@
<!-- Workflow Patch Deployer --> <!-- Workflow Patch Deployer -->
<bean id="workflowPatchDeployer" parent="workflowDeployer" singleton="false"/> <bean id="workflowPatchDeployer" parent="workflowDeployer" singleton="false"/>
<!-- Deploy any additional workflows definitions from repo (used by MT import) --> <!-- Deploy any additional workflows definitions from repo -->
<!-- note: needs to match bootstrap-context.xml locations ( customWorkflowDefsSpace.xml) --> <!-- note: needs to match bootstrap-context.xml locations (customWorkflowDefsSpace.xml) -->
<bean id="customWorkflowDefsRepositoryLocation" class="org.alfresco.repo.dictionary.RepositoryLocation"> <bean id="customWorkflowDefsRepositoryLocation" class="org.alfresco.repo.dictionary.RepositoryLocation">
<!-- other properties will be defaulted, but can be overriden here --> <!-- other properties will be defaulted, but can be overriden here -->
<property name="path"> <property name="path">
@@ -120,9 +123,8 @@
<!-- Workflow Definition Type (bpm:workflowDefinition) --> <!-- Workflow Definition Type (bpm:workflowDefinition) -->
<bean id="workflowDefinitionType" class="org.alfresco.repo.workflow.WorkflowDefinitionType" init-method="init"> <bean id="workflowDefinitionType" class="org.alfresco.repo.workflow.WorkflowDefinitionType" init-method="init">
<property name="nodeService" ref="NodeService"/>
<property name="policyComponent" ref="policyComponent"/> <property name="policyComponent" ref="policyComponent"/>
<property name="workflowService" ref="WorkflowService"/> <property name="workflowDeployer" ref="workflowBootstrap"/>
</bean> </bean>
</beans> </beans>

View File

@@ -25,7 +25,6 @@
package org.alfresco.repo.tenant; package org.alfresco.repo.tenant;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.ArrayList; import java.util.ArrayList;
@@ -46,30 +45,24 @@ import org.alfresco.repo.attributes.MapAttributeValue;
import org.alfresco.repo.attributes.StringAttributeValue; import org.alfresco.repo.attributes.StringAttributeValue;
import org.alfresco.repo.content.TenantRoutingFileContentStore; import org.alfresco.repo.content.TenantRoutingFileContentStore;
import org.alfresco.repo.dictionary.DictionaryComponent; import org.alfresco.repo.dictionary.DictionaryComponent;
import org.alfresco.repo.dictionary.RepositoryLocation;
import org.alfresco.repo.importer.ImporterBootstrap; import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.repo.node.db.DbNodeServiceImpl; import org.alfresco.repo.node.db.DbNodeServiceImpl;
import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.workflow.WorkflowDefinitionType;
import org.alfresco.repo.workflow.WorkflowDeployer; import org.alfresco.repo.workflow.WorkflowDeployer;
import org.alfresco.service.cmr.admin.RepoAdminService; import org.alfresco.service.cmr.admin.RepoAdminService;
import org.alfresco.service.cmr.attributes.AttributeService; import org.alfresco.service.cmr.attributes.AttributeService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.view.RepositoryExporterService; import org.alfresco.service.cmr.view.RepositoryExporterService;
import org.alfresco.service.cmr.workflow.WorkflowDefinition; import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowService; import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.AbstractLifecycleBean; import org.alfresco.util.AbstractLifecycleBean;
import org.alfresco.util.ParameterCheck; import org.alfresco.util.ParameterCheck;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEvent;
import org.springframework.core.io.ClassPathResource;
/** /**
* MT Admin Service Implementation. * MT Admin Service Implementation.
@@ -93,10 +86,7 @@ public class MultiTAdminServiceImpl extends AbstractLifecycleBean implements Ten
private TenantRoutingFileContentStore tenantFileContentStore; private TenantRoutingFileContentStore tenantFileContentStore;
private WorkflowService workflowService; private WorkflowService workflowService;
private RepositoryExporterService repositoryExporterService; private RepositoryExporterService repositoryExporterService;
private NamespaceService namespaceService; private WorkflowDeployer workflowDeployer;
private SearchService searchService;
private RepositoryLocation repoWorkflowDefsLocation;
private WorkflowDefinitionType workflowDefinitionType;
protected final static String REGEX_VALID_TENANT_NAME = "^[a-zA-Z0-9]([a-zA-Z0-9]|.[a-zA-Z0-9])*$"; // note: must also be a valid filename protected final static String REGEX_VALID_TENANT_NAME = "^[a-zA-Z0-9]([a-zA-Z0-9]|.[a-zA-Z0-9])*$"; // note: must also be a valid filename
@@ -156,24 +146,9 @@ public class MultiTAdminServiceImpl extends AbstractLifecycleBean implements Ten
this.repositoryExporterService = repositoryExporterService; this.repositoryExporterService = repositoryExporterService;
} }
public void setNamespaceService(NamespaceService namespaceService) public void setWorkflowDeployer(WorkflowDeployer workflowDeployer)
{ {
this.namespaceService = namespaceService; this.workflowDeployer = workflowDeployer;
}
public void setSearchService(SearchService searchService)
{
this.searchService = searchService;
}
public void setRepositoryWorkflowDefsLocations(RepositoryLocation repoWorkflowDefsLocation)
{
this.repoWorkflowDefsLocation = repoWorkflowDefsLocation;
}
public void setWorkflowDefinitionType(WorkflowDefinitionType workflowDefinitionType)
{
this.workflowDefinitionType = workflowDefinitionType;
} }
@@ -192,9 +167,6 @@ public class MultiTAdminServiceImpl extends AbstractLifecycleBean implements Ten
private static final String TENANT_ROOT_CONTENT_STORE_DIR = "rootContentStoreDir"; private static final String TENANT_ROOT_CONTENT_STORE_DIR = "rootContentStoreDir";
private static final String ADMIN_BASENAME = TenantService.ADMIN_BASENAME; private static final String ADMIN_BASENAME = TenantService.ADMIN_BASENAME;
public final static String CRITERIA_ALL = "/*"; // immediate children only
public final static String defaultSubtypeOfWorkflowDefinitionType = "subtypeOf('bpm:workflowDefinition')";
private List<TenantDeployer> tenantDeployers = new ArrayList<TenantDeployer>(); private List<TenantDeployer> tenantDeployers = new ArrayList<TenantDeployer>();
@@ -577,48 +549,18 @@ public class MultiTAdminServiceImpl extends AbstractLifecycleBean implements Ten
return new Tenant(tenantDomain, isEnabledTenant(tenantDomain), getRootContentStoreDir(tenantDomain)); return new Tenant(tenantDomain, isEnabledTenant(tenantDomain), getRootContentStoreDir(tenantDomain));
} }
public void bootstrapWorkflows() public void bootstrapWorkflows(String tenantDomain)
{ {
// use this to deploy standard workflow process defs to the JBPM engine AuthenticationUtil.runAs(new RunAsWork<Object>()
WorkflowDeployer workflowBootstrap = (WorkflowDeployer)getApplicationContext().getBean("workflowBootstrap");
String resourceClasspath = null;
// Workflow process definitions
try
{
List<Properties> workflowDefs = workflowBootstrap.getWorkflowDefinitions();
if (workflowDefs != null)
{
for (Properties workflowDefProps : workflowDefs)
{ {
resourceClasspath = workflowDefProps.getProperty(WorkflowDeployer.LOCATION); public Object doWork()
ClassPathResource resource = new ClassPathResource(resourceClasspath); {
workflowService.deployDefinition(workflowDefProps.getProperty(WorkflowDeployer.ENGINE_ID), resource.getInputStream(), workflowDefProps.getProperty(WorkflowDeployer.MIMETYPE)); workflowDeployer.init();
} return null;
} }
} }, getTenantAdminUser(tenantDomain));
catch (IOException ioe)
{
throw new AlfrescoRuntimeException("Failed to find workflow process def: " + resourceClasspath);
}
// in case of import, also deploy any custom workflow definitions defined in the repo logger.info("Tenant workflows bootstrapped: " + tenantDomain);
// TODO refactor/review repository bootstrap order of undeployed workflow definitions
StoreRef storeRef = repoWorkflowDefsLocation.getStoreRef();
NodeRef rootNode = nodeService.getRootNode(storeRef);
List<NodeRef> nodeRefs = searchService.selectNodes(rootNode, repoWorkflowDefsLocation.getPath()+CRITERIA_ALL+"["+defaultSubtypeOfWorkflowDefinitionType+"]", null, namespaceService, false);
if (nodeRefs.size() > 0)
{
for (NodeRef nodeRef : nodeRefs)
{
workflowDefinitionType.deploy(nodeRef);
}
}
logger.info("Tenant workflows bootstrapped: " + tenantService.getCurrentUserDomain());
} }
/** /**

View File

@@ -47,7 +47,7 @@ public interface TenantAdminService extends TenantDeployerService
public boolean existsTenant(String tenantDomain); public boolean existsTenant(String tenantDomain);
public void bootstrapWorkflows(); public void bootstrapWorkflows(String tenantDomain);
public void deleteTenant(String tenantDomain); public void deleteTenant(String tenantDomain);

View File

@@ -239,16 +239,8 @@ public class TenantInterpreter extends BaseInterpreter
} }
String newTenant = new String(command[1]).toLowerCase(); String newTenant = new String(command[1]).toLowerCase();
String tenantAdminUsername = tenantService.getDomainUser(TenantService.ADMIN_BASENAME, newTenant); tenantAdminService.bootstrapWorkflows(newTenant);
AuthenticationUtil.runAs(new RunAsWork<Object>()
{
public Object doWork() throws Exception
{
tenantAdminService.bootstrapWorkflows();
return null;
}
}, tenantAdminUsername);
out.println("bootstrap workflows deployed for tenant: " + newTenant); out.println("bootstrap workflows deployed for tenant: " + newTenant);
} }

View File

@@ -25,23 +25,15 @@
package org.alfresco.repo.workflow; package org.alfresco.repo.workflow;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.ContentServicePolicies; import org.alfresco.repo.content.ContentServicePolicies;
import org.alfresco.repo.node.NodeServicePolicies; import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.JavaBehaviour; import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent; import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowDeployment;
import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/** /**
* Workflow Definition type behaviour. * Workflow Definition type behaviour.
@@ -52,29 +44,11 @@ public class WorkflowDefinitionType implements ContentServicePolicies.OnContentU
NodeServicePolicies.OnUpdatePropertiesPolicy, NodeServicePolicies.OnUpdatePropertiesPolicy,
NodeServicePolicies.BeforeDeleteNodePolicy NodeServicePolicies.BeforeDeleteNodePolicy
{ {
// logger
private static Log logger = LogFactory.getLog(WorkflowDefinitionType.class);
/** The node service */
private NodeService nodeService;
/** The policy component */ /** The policy component */
private PolicyComponent policyComponent; private PolicyComponent policyComponent;
/** The workflow service */
private WorkflowService workflowService;
/** The workflow deployer / undeployer */
private WorkflowDeployer workflowDeployer;
/**
* Set the node service
*
* @param nodeService the node service
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/** /**
* Set the policy component * Set the policy component
@@ -87,16 +61,15 @@ public class WorkflowDefinitionType implements ContentServicePolicies.OnContentU
} }
/** /**
* Set the workflow service * Set the workflow deployer / undeployer
* *
* @param workflowService the workflow service * @param workflowDeployer the workflow deployer / undeployer
*/ */
public void setWorkflowService(WorkflowService workflowService) public void setWorkflowDeployer(WorkflowDeployer workflowDeployer)
{ {
this.workflowService = workflowService; this.workflowDeployer = workflowDeployer;
} }
/** /**
* The initialise method * The initialise method
*/ */
@@ -128,7 +101,7 @@ public class WorkflowDefinitionType implements ContentServicePolicies.OnContentU
*/ */
public void onContentUpdate(NodeRef nodeRef, boolean newContent) public void onContentUpdate(NodeRef nodeRef, boolean newContent)
{ {
deploy(nodeRef); workflowDeployer.deploy(nodeRef, true);
} }
/** /**
@@ -151,78 +124,23 @@ public class WorkflowDefinitionType implements ContentServicePolicies.OnContentU
{ {
if (afterValue.booleanValue() == true) if (afterValue.booleanValue() == true)
{ {
deploy(nodeRef); workflowDeployer.deploy(nodeRef, true);
} }
else else
{ {
undeploy(nodeRef); workflowDeployer.undeploy(nodeRef);
} }
} }
else if (afterValue == null && beforeValue != null) else if (afterValue == null && beforeValue != null)
{ {
// Undeploy the definition since the value has been cleared // Undeploy the definition since the value has been cleared
undeploy(nodeRef); workflowDeployer.undeploy(nodeRef);
} }
} }
public void beforeDeleteNode(NodeRef nodeRef) public void beforeDeleteNode(NodeRef nodeRef)
{ {
undeploy(nodeRef); workflowDeployer.undeploy(nodeRef);
}
public void deploy(NodeRef nodeRef)
{
// Ignore if the node is a working copy
if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY) == false)
{
Boolean value = (Boolean)nodeService.getProperty(nodeRef, WorkflowModel.PROP_WORKFLOW_DEF_DEPLOYED);
if ((value != null) && (value.booleanValue() == true))
{
// deploy / re-deploy
WorkflowDeployment deployment = workflowService.deployDefinition(nodeRef);
if (deployment != null)
{
WorkflowDefinition def = deployment.definition;
// Update the meta data for the model
Map<QName, Serializable> props = nodeService.getProperties(nodeRef);
props.put(WorkflowModel.PROP_WORKFLOW_DEF_NAME, def.getName());
// TODO - ability to return and handle deployment problems / warnings
if (deployment.problems.length > 0)
{
for (String problem : deployment.problems)
{
logger.warn(problem);
}
}
nodeService.setProperties(nodeRef, props);
}
}
}
}
private void undeploy(NodeRef nodeRef)
{
// Ignore if the node is a working copy
if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY) == false)
{
String defName = (String)nodeService.getProperty(nodeRef, WorkflowModel.PROP_WORKFLOW_DEF_NAME);
if (defName != null)
{
// Undeploy the workflow definition - all versions in JBPM
List<WorkflowDefinition> defs = workflowService.getAllDefinitionsByName(defName);
for (WorkflowDefinition def: defs)
{
logger.info("Undeploying workflow '" + defName + "' ...");
workflowService.undeployDefinition(def.getId());
logger.info("... undeployed '" + def.getId() + "' v" + def.getVersion());
}
}
}
} }
} }

View File

@@ -24,23 +24,34 @@
*/ */
package org.alfresco.repo.workflow; package org.alfresco.repo.workflow;
import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import javax.transaction.UserTransaction; import javax.transaction.UserTransaction;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.dictionary.DictionaryBootstrap; import org.alfresco.repo.dictionary.DictionaryBootstrap;
import org.alfresco.repo.dictionary.DictionaryDAO; import org.alfresco.repo.dictionary.DictionaryDAO;
import org.alfresco.repo.dictionary.RepositoryLocation;
import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.tenant.TenantService; import org.alfresco.repo.tenant.TenantService;
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.view.ImporterException; import org.alfresco.service.cmr.view.ImporterException;
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowDeployment; import org.alfresco.service.cmr.workflow.WorkflowDeployment;
import org.alfresco.service.cmr.workflow.WorkflowException; import org.alfresco.service.cmr.workflow.WorkflowException;
import org.alfresco.service.cmr.workflow.WorkflowService; import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.AbstractLifecycleBean; import org.alfresco.util.AbstractLifecycleBean;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@@ -75,7 +86,14 @@ public class WorkflowDeployer extends AbstractLifecycleBean
private List<String> models = new ArrayList<String>(); private List<String> models = new ArrayList<String>();
private List<String> resourceBundles = new ArrayList<String>(); private List<String> resourceBundles = new ArrayList<String>();
private TenantService tenantService; private TenantService tenantService;
private NodeService nodeService;
private NamespaceService namespaceService;
private SearchService searchService;
private RepositoryLocation repoWorkflowDefsLocation;
public final static String CRITERIA_ALL = "/*"; // immediate children only
public final static String defaultSubtypeOfWorkflowDefinitionType = "subtypeOf('bpm:workflowDefinition')";
/** /**
* Set whether we write or not * Set whether we write or not
@@ -172,6 +190,28 @@ public class WorkflowDeployer extends AbstractLifecycleBean
{ {
return this.workflowDefinitions; return this.workflowDefinitions;
} }
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setSearchService(SearchService searchService)
{
this.searchService = searchService;
}
public void setNamespaceService(NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
public void setRepositoryWorkflowDefsLocations(RepositoryLocation repoWorkflowDefsLocation)
{
this.repoWorkflowDefsLocation = repoWorkflowDefsLocation;
}
/** /**
* Deploy the Workflow Definitions * Deploy the Workflow Definitions
@@ -258,6 +298,22 @@ public class WorkflowDeployer extends AbstractLifecycleBean
} }
} }
} }
// deploy workflow definitions from repository (if any)
if (repoWorkflowDefsLocation != null)
{
StoreRef storeRef = repoWorkflowDefsLocation.getStoreRef();
NodeRef rootNode = nodeService.getRootNode(storeRef);
List<NodeRef> nodeRefs = searchService.selectNodes(rootNode, repoWorkflowDefsLocation.getPath()+CRITERIA_ALL+"["+defaultSubtypeOfWorkflowDefinitionType+"]", null, namespaceService, false);
if (nodeRefs.size() > 0)
{
for (NodeRef nodeRef : nodeRefs)
{
deploy(nodeRef, false);
}
}
}
userTransaction.commit(); userTransaction.commit();
} }
@@ -276,6 +332,94 @@ public class WorkflowDeployer extends AbstractLifecycleBean
} }
} }
public void deploy(NodeRef nodeRef, boolean redeploy)
{
// Ignore if the node is a working copy
if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY) == false)
{
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");
}
}
else
{
// deploy / re-deploy
WorkflowDeployment deployment = workflowService.deployDefinition(nodeRef);
if (logger.isInfoEnabled())
{
logger.info("Workflow deployer: Deployed process definition '" + deployment.definition.title + "' (version " + deployment.definition.version + ") from '" + nodeRef + "' with " + deployment.problems.length + " problems");
}
if (deployment != null)
{
WorkflowDefinition def = deployment.definition;
// Update the meta data for the model
Map<QName, Serializable> props = nodeService.getProperties(nodeRef);
props.put(WorkflowModel.PROP_WORKFLOW_DEF_NAME, def.getName());
// TODO - ability to return and handle deployment problems / warnings
if (deployment.problems.length > 0)
{
for (String problem : deployment.problems)
{
logger.warn(problem);
}
}
nodeService.setProperties(nodeRef, props);
}
}
}
}
else
{
if (logger.isDebugEnabled())
{
logger.debug("Workflow deployer: Definition '" + nodeRef + "' not deployed since it is a working copy");
}
}
}
public void undeploy(NodeRef nodeRef)
{
// Ignore if the node is a working copy
if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY) == false)
{
String defName = (String)nodeService.getProperty(nodeRef, WorkflowModel.PROP_WORKFLOW_DEF_NAME);
if (defName != null)
{
// Undeploy the workflow definition - all versions in JBPM
List<WorkflowDefinition> defs = workflowService.getAllDefinitionsByName(defName);
for (WorkflowDefinition def: defs)
{
if (logger.isInfoEnabled())
{
logger.info("Undeploying workflow '" + defName + "' ...");
}
workflowService.undeployDefinition(def.getId());
if (logger.isInfoEnabled())
{
logger.info("... undeployed '" + def.getId() + "' v" + def.getVersion());
}
}
}
}
else
{
if (logger.isDebugEnabled())
{
logger.debug("Workflow deployer: Definition '" + nodeRef + "' not undeployed since it is a working copy");
}
}
}
@Override @Override
protected void onBootstrap(ApplicationEvent event) protected void onBootstrap(ApplicationEvent event)
{ {

View File

@@ -143,7 +143,23 @@ public class WorkflowServiceImpl implements WorkflowService
return deployment; return deployment;
} }
/* (non-Javadoc)
* @see org.alfresco.service.cmr.workflow.WorkflowService#isDefinitionDeployed(org.alfresco.service.cmr.repository.NodeRef)
*/
public boolean isDefinitionDeployed(NodeRef workflowDefinition)
{
if (! nodeService.getType(workflowDefinition).equals(WorkflowModel.TYPE_WORKFLOW_DEF))
{
throw new WorkflowException("Node " + workflowDefinition + " is not of type 'bpm:workflowDefinition'");
}
String engineId = (String)nodeService.getProperty(workflowDefinition, WorkflowModel.PROP_WORKFLOW_DEF_ENGINE_ID);
ContentReader contentReader = contentService.getReader(workflowDefinition, ContentModel.PROP_CONTENT);
return isDefinitionDeployed(engineId, contentReader.getContentInputStream(), contentReader.getMimetype());
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.workflow.WorkflowService#isDefinitionDeployed(java.lang.String, java.io.InputStream, java.lang.String) * @see org.alfresco.service.cmr.workflow.WorkflowService#isDefinitionDeployed(java.lang.String, java.io.InputStream, java.lang.String)
*/ */

View File

@@ -72,6 +72,18 @@ public interface WorkflowService
@Auditable(key = Auditable.Key.ARG_0, parameters = {"workflowDefinition"}) @Auditable(key = Auditable.Key.ARG_0, parameters = {"workflowDefinition"})
public WorkflowDeployment deployDefinition(NodeRef workflowDefinition); public WorkflowDeployment deployDefinition(NodeRef workflowDefinition);
/**
* Is the specified Workflow Definition already deployed?
*
* Note: the notion of "already deployed" may differ between bpm engines. For example,
* different versions of the same process may be considered equal.
*
* @param workflowDefinition the content object containing the definition
* @return true => already deployed
*/
@Auditable(parameters = {"definitionContent"})
public boolean isDefinitionDeployed(NodeRef workflowDefinition);
/** /**
* Is the specified Workflow Definition already deployed? * Is the specified Workflow Definition already deployed?
* *