mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
[MNT-21638] Script task execution (#1210)
* [MNT-21638] Script task execution based on workflow deloyment category. Javadoc. Unit tests.
This commit is contained in:
@@ -35,10 +35,11 @@ public class GetDeploymentsSanityTests extends RestTest
|
|||||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||||
deployments.assertThat().entriesListIsNotEmpty();
|
deployments.assertThat().entriesListIsNotEmpty();
|
||||||
deployments.getOneRandomEntry().onModel().assertThat()
|
deployments.getOneRandomEntry().onModel().assertThat()
|
||||||
.fieldsCount().is(3).and()
|
.fieldsCount().is(4).and()
|
||||||
.field("id").isNotEmpty().and()
|
.field("id").isNotEmpty().and()
|
||||||
.field("deployedAt").isNotEmpty().and()
|
.field("deployedAt").isNotEmpty().and()
|
||||||
.field("name").isNotEmpty();
|
.field("name").isNotEmpty().and()
|
||||||
|
.field("category").isNotEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -38,6 +38,7 @@ import java.util.Map;
|
|||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.tenant.TenantUtil;
|
import org.alfresco.repo.tenant.TenantUtil;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||||
|
import org.alfresco.repo.workflow.WorkflowDeployer;
|
||||||
import org.alfresco.rest.api.tests.AbstractTestFixture;
|
import org.alfresco.rest.api.tests.AbstractTestFixture;
|
||||||
import org.alfresco.rest.api.tests.RepoService.TestNetwork;
|
import org.alfresco.rest.api.tests.RepoService.TestNetwork;
|
||||||
import org.alfresco.rest.api.tests.client.PublicApiClient.ListResponse;
|
import org.alfresco.rest.api.tests.client.PublicApiClient.ListResponse;
|
||||||
@@ -128,7 +129,7 @@ public class DeploymentWorkflowApiTest extends EnterpriseWorkflowTestApi
|
|||||||
Deployment adhocDeployment = deploymentMap.get("adhoc.bpmn20.xml");
|
Deployment adhocDeployment = deploymentMap.get("adhoc.bpmn20.xml");
|
||||||
|
|
||||||
assertEquals(activitiDeployment.getId(), adhocDeployment.getId());
|
assertEquals(activitiDeployment.getId(), adhocDeployment.getId());
|
||||||
assertEquals(activitiDeployment.getCategory(), adhocDeployment.getCategory());
|
assertEquals(activitiDeployment.getCategory(), WorkflowDeployer.CATEGORY_FULL_ACCESS);
|
||||||
assertEquals(activitiDeployment.getName(), adhocDeployment.getName());
|
assertEquals(activitiDeployment.getName(), adhocDeployment.getName());
|
||||||
assertEquals(activitiDeployment.getDeploymentTime(), adhocDeployment.getDeployedAt());
|
assertEquals(activitiDeployment.getDeploymentTime(), adhocDeployment.getDeployedAt());
|
||||||
|
|
||||||
@@ -251,7 +252,7 @@ public class DeploymentWorkflowApiTest extends EnterpriseWorkflowTestApi
|
|||||||
assertNotNull(deployment);
|
assertNotNull(deployment);
|
||||||
|
|
||||||
assertEquals(activitiDeployment.getId(), deployment.getId());
|
assertEquals(activitiDeployment.getId(), deployment.getId());
|
||||||
assertEquals(activitiDeployment.getCategory(), deployment.getCategory());
|
assertEquals(activitiDeployment.getCategory(), WorkflowDeployer.CATEGORY_FULL_ACCESS);
|
||||||
assertEquals(activitiDeployment.getName(), deployment.getName());
|
assertEquals(activitiDeployment.getName(), deployment.getName());
|
||||||
assertEquals(activitiDeployment.getDeploymentTime(), deployment.getDeployedAt());
|
assertEquals(activitiDeployment.getDeploymentTime(), deployment.getDeployedAt());
|
||||||
|
|
||||||
|
@@ -270,25 +270,33 @@ public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcess
|
|||||||
*/
|
*/
|
||||||
public Object executeString(String source, Map<String, Object> model)
|
public Object executeString(String source, Map<String, Object> model)
|
||||||
{
|
{
|
||||||
try
|
return executeString(source, model, false);
|
||||||
{
|
}
|
||||||
// compile the script based on the node content
|
|
||||||
Script script;
|
/**
|
||||||
Context cx = Context.enter();
|
* @see org.alfresco.service.cmr.repository.ScriptProcessor#executeString(java.lang.String, java.util.Map, boolean)
|
||||||
try
|
*/
|
||||||
{
|
public Object executeString(String source, Map<String, Object> model, boolean secure)
|
||||||
script = cx.compileString(resolveScriptImports(source), "AlfrescoJS", 1, null);
|
{
|
||||||
}
|
try
|
||||||
finally
|
{
|
||||||
{
|
// compile the script based on the node content
|
||||||
Context.exit();
|
Script script;
|
||||||
}
|
Context cx = Context.enter();
|
||||||
return executeScriptImpl(script, model, true, "string script");
|
try
|
||||||
}
|
{
|
||||||
catch (Throwable err)
|
script = cx.compileString(resolveScriptImports(source), "AlfrescoJS", 1, null);
|
||||||
{
|
}
|
||||||
throw new ScriptException("Failed to execute supplied script: " + err.getMessage(), err);
|
finally
|
||||||
}
|
{
|
||||||
|
Context.exit();
|
||||||
|
}
|
||||||
|
return executeScriptImpl(script, model, secure, "string script");
|
||||||
|
}
|
||||||
|
catch (Throwable err)
|
||||||
|
{
|
||||||
|
throw new ScriptException("Failed to execute supplied script: " + err.getMessage(), err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -188,6 +188,15 @@ public class ScriptServiceImpl implements ScriptService
|
|||||||
throws ScriptException
|
throws ScriptException
|
||||||
{
|
{
|
||||||
return executeScriptString(this.defaultScriptProcessor, script, model);
|
return executeScriptString(this.defaultScriptProcessor, script, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.alfresco.service.cmr.repository.ScriptService#executeScriptString(java.lang.String, java.util.Map, boolean)
|
||||||
|
*/
|
||||||
|
public Object executeScriptString(String script, Map<String, Object> model, boolean secure)
|
||||||
|
throws ScriptException
|
||||||
|
{
|
||||||
|
return executeScriptString(this.defaultScriptProcessor, script, model, secure);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -197,12 +206,23 @@ public class ScriptServiceImpl implements ScriptService
|
|||||||
throws ScriptException
|
throws ScriptException
|
||||||
{
|
{
|
||||||
ScriptProcessor scriptProcessor = lookupScriptProcessor(engine);
|
ScriptProcessor scriptProcessor = lookupScriptProcessor(engine);
|
||||||
return executeString(scriptProcessor, script, model);
|
return executeString(scriptProcessor, script, model, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.alfresco.service.cmr.repository.ScriptService#executeScriptString(java.lang.String, java.util.Map, boolean)
|
||||||
|
*/
|
||||||
|
public Object executeScriptString(String engine, String script, Map<String, Object> model, boolean secure)
|
||||||
|
throws ScriptException
|
||||||
|
{
|
||||||
|
ScriptProcessor scriptProcessor = lookupScriptProcessor(engine);
|
||||||
|
return executeString(scriptProcessor, script, model, secure);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute script
|
* Execute script
|
||||||
*
|
*
|
||||||
|
* @param processor the script processor that will be responsible for supplied script execution
|
||||||
* @param location the location of the script
|
* @param location the location of the script
|
||||||
* @param model context model
|
* @param model context model
|
||||||
* @return Object the result of the script
|
* @return Object the result of the script
|
||||||
@@ -227,6 +247,7 @@ public class ScriptServiceImpl implements ScriptService
|
|||||||
/**
|
/**
|
||||||
* Execute script
|
* Execute script
|
||||||
*
|
*
|
||||||
|
* @param processor the script processor that will be responsible for supplied script execution
|
||||||
* @param scriptRef the script node reference
|
* @param scriptRef the script node reference
|
||||||
* @param contentProp the content property of the script
|
* @param contentProp the content property of the script
|
||||||
* @param model the context model
|
* @param model the context model
|
||||||
@@ -251,7 +272,8 @@ public class ScriptServiceImpl implements ScriptService
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute script
|
* Execute script
|
||||||
*
|
*
|
||||||
|
* @param processor the script processor that will be responsible for supplied script execution
|
||||||
* @param location the classpath string locating the script
|
* @param location the classpath string locating the script
|
||||||
* @param model the context model
|
* @param model the context model
|
||||||
* @return Object the result of the script
|
* @return Object the result of the script
|
||||||
@@ -275,12 +297,15 @@ public class ScriptServiceImpl implements ScriptService
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute script string
|
* Execute script string
|
||||||
*
|
*
|
||||||
|
* @param processor the script processor that will be responsible for supplied script execution
|
||||||
* @param script the script string
|
* @param script the script string
|
||||||
* @param model the context model
|
* @param model the context model
|
||||||
|
* @param secure the flag indicating if string script is considered secure (e.g., if it comes from classpath)
|
||||||
|
* if true it will have access to the full execution context, if false the script will be executed in a sandbox context
|
||||||
* @return Object the result of the script
|
* @return Object the result of the script
|
||||||
*/
|
*/
|
||||||
protected Object executeString(ScriptProcessor processor, String script, Map<String, Object> model)
|
protected Object executeString(ScriptProcessor processor, String script, Map<String, Object> model, boolean secure)
|
||||||
{
|
{
|
||||||
ParameterCheck.mandatoryString("script", script);
|
ParameterCheck.mandatoryString("script", script);
|
||||||
|
|
||||||
@@ -290,7 +315,7 @@ public class ScriptServiceImpl implements ScriptService
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return processor.executeString(script, model);
|
return processor.executeString(script, model, secure);
|
||||||
}
|
}
|
||||||
catch (Throwable err)
|
catch (Throwable err)
|
||||||
{
|
{
|
||||||
|
@@ -74,6 +74,18 @@ public interface WorkflowComponent
|
|||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
public WorkflowDeployment deployDefinition(InputStream workflowDefinition, String mimetype, String name);
|
public WorkflowDeployment deployDefinition(InputStream workflowDefinition, String mimetype, String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deploy a Workflow Definition
|
||||||
|
*
|
||||||
|
* @param workflowDefinition the content object containing the definition
|
||||||
|
* @param mimetype (optional) the mime type of the workflow definition
|
||||||
|
* @param name (optional) a name to represent the deployment
|
||||||
|
* @param fullAccess true if category should be defined in order to consider the deployment secure
|
||||||
|
* @return workflow deployment descriptor
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
public WorkflowDeployment deployDefinition(InputStream workflowDefinition, String mimetype, String name, boolean fullAccess);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is the specified Workflow Definition already deployed?
|
* Is the specified Workflow Definition already deployed?
|
||||||
@@ -86,7 +98,14 @@ public interface WorkflowComponent
|
|||||||
* @return true => already deployed
|
* @return true => already deployed
|
||||||
*/
|
*/
|
||||||
public boolean isDefinitionDeployed(InputStream workflowDefinition, String mimetype);
|
public boolean isDefinitionDeployed(InputStream workflowDefinition, String mimetype);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the deployment category if applicable to allow the workflow to have full access
|
||||||
|
*
|
||||||
|
* @param workflowDefinition the definition to check
|
||||||
|
*/
|
||||||
|
public void checkDeploymentCategory(InputStream workflowDefinition);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Undeploy an exisiting Workflow Definition
|
* Undeploy an exisiting Workflow Definition
|
||||||
*
|
*
|
||||||
|
@@ -85,6 +85,7 @@ public class WorkflowDeployer extends AbstractLifecycleBean
|
|||||||
public static final String REDEPLOY = "redeploy";
|
public static final String REDEPLOY = "redeploy";
|
||||||
|
|
||||||
public static final String CATEGORY_ALFRESCO_INTERNAL = "http://alfresco.org/workflows/internal";
|
public static final String CATEGORY_ALFRESCO_INTERNAL = "http://alfresco.org/workflows/internal";
|
||||||
|
public static final String CATEGORY_FULL_ACCESS = "http://alfresco.org/workflows/fullAccess";
|
||||||
|
|
||||||
// Dependencies
|
// Dependencies
|
||||||
private TransactionService transactionService;
|
private TransactionService transactionService;
|
||||||
@@ -306,12 +307,14 @@ public class WorkflowDeployer extends AbstractLifecycleBean
|
|||||||
if (!redeploy && workflowService.isDefinitionDeployed(engineId, workflowResource.getInputStream(), mimetype))
|
if (!redeploy && workflowService.isDefinitionDeployed(engineId, workflowResource.getInputStream(), mimetype))
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Workflow deployer: Definition '" + location + "' already deployed");
|
{
|
||||||
|
logger.debug("Workflow deployer: Definition '" + location + "' already deployed. Checking deploymentcategory...");
|
||||||
|
}
|
||||||
|
workflowService.checkDeploymentCategory(engineId, workflowResource.getInputStream());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WorkflowDeployment deployment = workflowService.deployDefinition(engineId, workflowResource.getInputStream(),
|
WorkflowDeployment deployment = workflowService.deployDefinition(engineId, workflowResource.getInputStream(), mimetype, workflowResource.getFilename(), true);
|
||||||
mimetype, workflowResource.getFilename());
|
|
||||||
logDeployment(location, deployment);
|
logDeployment(location, deployment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -232,9 +232,20 @@ public class WorkflowServiceImpl implements WorkflowService
|
|||||||
* .lang.String, java.io.InputStream, java.lang.String, java.lang.String)
|
* .lang.String, java.io.InputStream, java.lang.String, java.lang.String)
|
||||||
*/
|
*/
|
||||||
public WorkflowDeployment deployDefinition(String engineId, InputStream workflowDefinition, String mimetype, String name)
|
public WorkflowDeployment deployDefinition(String engineId, InputStream workflowDefinition, String mimetype, String name)
|
||||||
|
{
|
||||||
|
return deployDefinition(engineId, workflowDefinition, mimetype, name, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see
|
||||||
|
* org.alfresco.service.cmr.workflow.WorkflowService#deployDefinition(java
|
||||||
|
* .lang.String, java.io.InputStream, java.lang.String, java.lang.String, boolean)
|
||||||
|
*/
|
||||||
|
public WorkflowDeployment deployDefinition(String engineId, InputStream workflowDefinition, String mimetype, String name, boolean fullAccess)
|
||||||
{
|
{
|
||||||
WorkflowComponent component = getWorkflowComponent(engineId);
|
WorkflowComponent component = getWorkflowComponent(engineId);
|
||||||
WorkflowDeployment deployment = component.deployDefinition(workflowDefinition, mimetype, name);
|
WorkflowDeployment deployment = component.deployDefinition(workflowDefinition, mimetype, name, fullAccess);
|
||||||
|
|
||||||
if (logger.isDebugEnabled() && deployment.getProblems().length > 0)
|
if (logger.isDebugEnabled() && deployment.getProblems().length > 0)
|
||||||
{
|
{
|
||||||
@@ -277,6 +288,18 @@ public class WorkflowServiceImpl implements WorkflowService
|
|||||||
return component.isDefinitionDeployed(workflowDefinition, mimetype);
|
return component.isDefinitionDeployed(workflowDefinition, mimetype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see
|
||||||
|
* org.alfresco.service.cmr.workflow.WorkflowService#checkDeploymentCategory
|
||||||
|
* (java.lang.String, java.io.InputStream)
|
||||||
|
*/
|
||||||
|
public void checkDeploymentCategory(String engineId, InputStream workflowDefinition)
|
||||||
|
{
|
||||||
|
WorkflowComponent component = getWorkflowComponent(engineId);
|
||||||
|
component.checkDeploymentCategory(workflowDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see
|
* @see
|
||||||
|
@@ -1,28 +1,28 @@
|
|||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
* the paid license agreement will prevail. Otherwise, the software is
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
* provided under the following open source license terms:
|
* provided under the following open source license terms:
|
||||||
*
|
*
|
||||||
* Alfresco is free software: you can redistribute it and/or modify
|
* 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
|
* 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
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Alfresco is distributed in the hope that it will be useful,
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Lesser General Public License for more details.
|
* GNU Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.alfresco.repo.workflow.activiti;
|
package org.alfresco.repo.workflow.activiti;
|
||||||
|
|
||||||
@@ -242,45 +242,45 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine
|
|||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public WorkflowInstance cancelWorkflow(String workflowId)
|
public WorkflowInstance cancelWorkflow(String workflowId)
|
||||||
{
|
{
|
||||||
String localId = createLocalId(workflowId);
|
String localId = createLocalId(workflowId);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(localId).singleResult();
|
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(localId).singleResult();
|
||||||
if (processInstance == null)
|
if (processInstance == null)
|
||||||
{
|
{
|
||||||
throw new WorkflowException(messageService.getMessage(ERR_CANCEL_UNEXISTING_WORKFLOW));
|
throw new WorkflowException(messageService.getMessage(ERR_CANCEL_UNEXISTING_WORKFLOW));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Cancel VS delete?
|
// TODO: Cancel VS delete?
|
||||||
// Delete the process instance
|
// Delete the process instance
|
||||||
runtimeService.deleteProcessInstance(processInstance.getId(), WorkflowConstants.PROP_CANCELLED);
|
runtimeService.deleteProcessInstance(processInstance.getId(), WorkflowConstants.PROP_CANCELLED);
|
||||||
|
|
||||||
// Convert historic process instance
|
// Convert historic process instance
|
||||||
HistoricProcessInstance deletedInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstance.getId())
|
HistoricProcessInstance deletedInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstance.getId())
|
||||||
.singleResult();
|
.singleResult();
|
||||||
WorkflowInstance result = typeConverter.convert(deletedInstance);
|
WorkflowInstance result = typeConverter.convert(deletedInstance);
|
||||||
|
|
||||||
// Delete the historic process instance
|
// Delete the historic process instance
|
||||||
// MNT-15498
|
// MNT-15498
|
||||||
if (!activitiUtil.isRetentionHistoricProcessInstanceEnabled())
|
if (!activitiUtil.isRetentionHistoricProcessInstanceEnabled())
|
||||||
{
|
{
|
||||||
historyService.deleteHistoricProcessInstance(deletedInstance.getId());
|
historyService.deleteHistoricProcessInstance(deletedInstance.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
catch (ActivitiException ae)
|
catch (ActivitiException ae)
|
||||||
{
|
{
|
||||||
String msg = messageService.getMessage(ERR_CANCEL_WORKFLOW);
|
String msg = messageService.getMessage(ERR_CANCEL_WORKFLOW);
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
logger.debug(msg, ae);
|
logger.debug(msg, ae);
|
||||||
}
|
}
|
||||||
throw new WorkflowException(msg, ae);
|
throw new WorkflowException(msg, ae);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
@@ -336,6 +336,14 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public WorkflowDeployment deployDefinition(InputStream workflowDefinition, String mimetype, String name)
|
public WorkflowDeployment deployDefinition(InputStream workflowDefinition, String mimetype, String name)
|
||||||
|
{
|
||||||
|
return deployDefinition(workflowDefinition, mimetype, name, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public WorkflowDeployment deployDefinition(InputStream workflowDefinition, String mimetype, String name, boolean fullAccess)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -363,6 +371,10 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine
|
|||||||
{
|
{
|
||||||
repoService.setDeploymentCategory(deployment.getId(), WorkflowDeployer.CATEGORY_ALFRESCO_INTERNAL);
|
repoService.setDeploymentCategory(deployment.getId(), WorkflowDeployer.CATEGORY_ALFRESCO_INTERNAL);
|
||||||
}
|
}
|
||||||
|
else if (fullAccess)
|
||||||
|
{
|
||||||
|
repoService.setDeploymentCategory(deployment.getId(), WorkflowDeployer.CATEGORY_FULL_ACCESS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// No problems can be added to the WorkflowDeployment, warnings are
|
// No problems can be added to the WorkflowDeployment, warnings are
|
||||||
@@ -1005,6 +1017,46 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void checkDeploymentCategory(InputStream workflowDefinition)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String key = getProcessKey(workflowDefinition);
|
||||||
|
ProcessDefinition pd = activitiUtil.getProcessDefinitionByKey(key);
|
||||||
|
String deploymentId = pd.getDeploymentId();
|
||||||
|
|
||||||
|
List<ProcessDefinition> definitionList = repoService.createProcessDefinitionQuery().deploymentId(deploymentId).list();
|
||||||
|
if (definitionList != null && definitionList.size() > 0)
|
||||||
|
{
|
||||||
|
boolean internalCategory = true;
|
||||||
|
for (ProcessDefinition processDefinition : definitionList)
|
||||||
|
{
|
||||||
|
if (WorkflowDeployer.CATEGORY_ALFRESCO_INTERNAL.equals(processDefinition.getCategory()) == false)
|
||||||
|
{
|
||||||
|
internalCategory = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!internalCategory)
|
||||||
|
{
|
||||||
|
repoService.setDeploymentCategory(deploymentId, WorkflowDeployer.CATEGORY_FULL_ACCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Category was not set: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private String getProcessKey(InputStream workflowDefinition) throws Exception
|
private String getProcessKey(InputStream workflowDefinition) throws Exception
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@@ -32,8 +32,10 @@ import org.activiti.engine.delegate.VariableScope;
|
|||||||
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||||
import org.activiti.engine.impl.context.Context;
|
import org.activiti.engine.impl.context.Context;
|
||||||
import org.activiti.engine.impl.el.Expression;
|
import org.activiti.engine.impl.el.Expression;
|
||||||
|
import org.activiti.engine.impl.persistence.entity.DeploymentEntity;
|
||||||
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.WorkflowDeployer;
|
||||||
import org.alfresco.repo.workflow.activiti.ActivitiConstants;
|
import org.alfresco.repo.workflow.activiti.ActivitiConstants;
|
||||||
import org.alfresco.repo.workflow.activiti.ActivitiScriptNode;
|
import org.alfresco.repo.workflow.activiti.ActivitiScriptNode;
|
||||||
import org.alfresco.service.ServiceRegistry;
|
import org.alfresco.service.ServiceRegistry;
|
||||||
@@ -102,14 +104,18 @@ public class ActivitiScriptBase
|
|||||||
{
|
{
|
||||||
// Execute the script using the appropriate processor
|
// Execute the script using the appropriate processor
|
||||||
Object scriptResult = null;
|
Object scriptResult = null;
|
||||||
|
|
||||||
|
// Checks if current workflow is secure
|
||||||
|
boolean secure = isSecure();
|
||||||
|
|
||||||
if (scriptProcessorName != null)
|
if (scriptProcessorName != null)
|
||||||
{
|
{
|
||||||
scriptResult = getServiceRegistry().getScriptService().executeScriptString(scriptProcessorName, theScript, model);
|
scriptResult = getServiceRegistry().getScriptService().executeScriptString(scriptProcessorName, theScript, model, secure);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Use default script-processor
|
// Use default script-processor
|
||||||
scriptResult = getServiceRegistry().getScriptService().executeScriptString(theScript, model);
|
scriptResult = getServiceRegistry().getScriptService().executeScriptString(theScript, model, secure);
|
||||||
}
|
}
|
||||||
|
|
||||||
return scriptResult;
|
return scriptResult;
|
||||||
@@ -142,6 +148,32 @@ public class ActivitiScriptBase
|
|||||||
throw new IllegalStateException("No ProcessEngineCOnfiguration found in active context");
|
throw new IllegalStateException("No ProcessEngineCOnfiguration found in active context");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the workflow must be considered secure or not - based on {@link DeploymentEntity} category.
|
||||||
|
* If it is not considered secure, the workflow will be executed in sandbox context with more restrictions
|
||||||
|
*
|
||||||
|
* @return true if workflow is considered secure, false otherwise
|
||||||
|
*/
|
||||||
|
private boolean isSecure()
|
||||||
|
{
|
||||||
|
String category = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (Context.isExecutionContextActive())
|
||||||
|
{
|
||||||
|
category = Context.getExecutionContext().getDeployment().getCategory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// No action required
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the workflow is considered secure, the deployment entity category matches the condition (either internal or full access)
|
||||||
|
return category != null && (WorkflowDeployer.CATEGORY_ALFRESCO_INTERNAL.equals(category) || WorkflowDeployer.CATEGORY_FULL_ACCESS.equals(category));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks that the specified 'runAs' field
|
* Checks that the specified 'runAs' field
|
||||||
* specifies a valid username.
|
* specifies a valid username.
|
||||||
|
@@ -70,10 +70,21 @@ public interface ScriptProcessor extends Processor
|
|||||||
*
|
*
|
||||||
* @param script the script string
|
* @param script the script string
|
||||||
* @param model the context model
|
* @param model the context model
|
||||||
* @return Obejct the result of the script
|
* @return Object the result of the script
|
||||||
*/
|
*/
|
||||||
public Object executeString(String script, Map<String, Object> model);
|
public Object executeString(String script, Map<String, Object> model);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute script string
|
||||||
|
*
|
||||||
|
* @param script the script string
|
||||||
|
* @param model the context model
|
||||||
|
* @param secure the flag that indicates if string is considered secure to be executed, i.e., it will have
|
||||||
|
* access to the full execution context instead of being executed in a sandbox context
|
||||||
|
* @return Object the result of the script
|
||||||
|
*/
|
||||||
|
public Object executeString(String script, Map<String, Object> model, boolean secure);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset the processor - such as clearing any internal caches etc.
|
* Reset the processor - such as clearing any internal caches etc.
|
||||||
*/
|
*/
|
||||||
|
@@ -160,7 +160,22 @@ public interface ScriptService
|
|||||||
@Auditable(parameters = {"script", "model"})
|
@Auditable(parameters = {"script", "model"})
|
||||||
public Object executeScriptString(String script, Map<String, Object> model)
|
public Object executeScriptString(String script, Map<String, Object> model)
|
||||||
throws ScriptException;
|
throws ScriptException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a script against the supplied data model. Uses the default script engine.
|
||||||
|
*
|
||||||
|
* @param script Script content as a String.
|
||||||
|
* @param model Object model to process script against
|
||||||
|
* @param secure A flag indicating if string script is considered secure (e.g., if it comes from the classpath)
|
||||||
|
* If true it will have access to the full execution context, if false the script will be executed in a sandbox context (more restricted)
|
||||||
|
* @return output of the script (may be null or any valid wrapped JavaScript object)
|
||||||
|
*
|
||||||
|
* @throws ScriptException
|
||||||
|
*/
|
||||||
|
@Auditable(parameters = {"script", "model", "secure"})
|
||||||
|
public Object executeScriptString(String script, Map<String, Object> model, boolean secure)
|
||||||
|
throws ScriptException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process a script against the supplied data model.
|
* Process a script against the supplied data model.
|
||||||
*
|
*
|
||||||
@@ -175,7 +190,23 @@ public interface ScriptService
|
|||||||
@Auditable(parameters = {"engine", "script", "model"})
|
@Auditable(parameters = {"engine", "script", "model"})
|
||||||
public Object executeScriptString(String engine, String script, Map<String, Object> model)
|
public Object executeScriptString(String engine, String script, Map<String, Object> model)
|
||||||
throws ScriptException;
|
throws ScriptException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a script against the supplied data model.
|
||||||
|
*
|
||||||
|
* @param engine the script engine to use
|
||||||
|
* @param script Script content as a String.
|
||||||
|
* @param model Object model to process script against
|
||||||
|
* @param secure A flag indicating if string script is considered secure
|
||||||
|
*
|
||||||
|
* @return output of the script (may be null or any valid wrapped JavaScript object)
|
||||||
|
*
|
||||||
|
* @throws ScriptException
|
||||||
|
*/
|
||||||
|
@Auditable(parameters = {"engine", "script", "model", "secure"})
|
||||||
|
public Object executeScriptString(String engine, String script, Map<String, Object> model, boolean secure)
|
||||||
|
throws ScriptException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a script processor with the script service
|
* Registers a script processor with the script service
|
||||||
*
|
*
|
||||||
|
@@ -77,7 +77,24 @@ public interface WorkflowService
|
|||||||
parameters = {"engineId", "workflowDefinition", "mimetype", "name"},
|
parameters = {"engineId", "workflowDefinition", "mimetype", "name"},
|
||||||
recordable = {true, false, true, true})
|
recordable = {true, false, true, true})
|
||||||
public WorkflowDeployment deployDefinition(String engineId, InputStream workflowDefinition, String mimetype, String name);
|
public WorkflowDeployment deployDefinition(String engineId, InputStream workflowDefinition, String mimetype, String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deploy a Workflow Definition to the Alfresco Repository
|
||||||
|
*
|
||||||
|
* @param engineId the bpm engine id
|
||||||
|
* @param workflowDefinition the workflow definition
|
||||||
|
* @param mimetype the mimetype of the workflow definition
|
||||||
|
* @param name a name representing the deployment
|
||||||
|
* @parm fullAccess true if workflow should be considered secure (e.g., if it is deployed in classpath) and should have full access to the execution context,
|
||||||
|
* false if it should be executed in a sandbox context (more restricted)
|
||||||
|
* @return workflow deployment descriptor
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
@Auditable(
|
||||||
|
parameters = {"engineId", "workflowDefinition", "mimetype", "name", "fullAccess"},
|
||||||
|
recordable = {true, false, true, true, true})
|
||||||
|
public WorkflowDeployment deployDefinition(String engineId, InputStream workflowDefinition, String mimetype, String name, boolean fullAccess);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deploy a Workflow Definition to the Alfresco Repository
|
* Deploy a Workflow Definition to the Alfresco Repository
|
||||||
*
|
*
|
||||||
@@ -117,6 +134,17 @@ public interface WorkflowService
|
|||||||
parameters = {"engineId", "workflowDefinition", "mimetype"},
|
parameters = {"engineId", "workflowDefinition", "mimetype"},
|
||||||
recordable = {true, false, true})
|
recordable = {true, false, true})
|
||||||
public boolean isDefinitionDeployed(String engineId, InputStream workflowDefinition, String mimetype);
|
public boolean isDefinitionDeployed(String engineId, InputStream workflowDefinition, String mimetype);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the deployment for supplied workflow definition has the proper category
|
||||||
|
*
|
||||||
|
* @param engineId the bpm engine id
|
||||||
|
* @param workflowDefinition the definition to check
|
||||||
|
*/
|
||||||
|
@Auditable(
|
||||||
|
parameters = {"engineId", "workflowDefinition"},
|
||||||
|
recordable = {true, false})
|
||||||
|
public void checkDeploymentCategory(String engineId, InputStream workflowDefinition);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Undeploy an exisiting Workflow Definition
|
* Undeploy an exisiting Workflow Definition
|
||||||
|
@@ -25,42 +25,39 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.jscript;
|
package org.alfresco.repo.jscript;
|
||||||
|
|
||||||
import static org.junit.Assert.fail;
|
import java.io.InputStream;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.io.IOException;
|
import java.util.List;
|
||||||
import java.io.InputStream;
|
import java.util.Map;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.dictionary.DictionaryComponent;
|
import org.alfresco.repo.dictionary.DictionaryComponent;
|
||||||
import org.alfresco.repo.dictionary.DictionaryDAO;
|
import org.alfresco.repo.dictionary.DictionaryDAO;
|
||||||
import org.alfresco.repo.dictionary.M2Model;
|
import org.alfresco.repo.dictionary.M2Model;
|
||||||
import org.alfresco.repo.node.BaseNodeServiceTest;
|
import org.alfresco.repo.node.BaseNodeServiceTest;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
import org.alfresco.service.ServiceRegistry;
|
||||||
import org.alfresco.service.ServiceRegistry;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ContentService;
|
||||||
import org.alfresco.service.cmr.repository.ContentService;
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
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.repository.NodeService;
|
import org.alfresco.service.cmr.repository.ScriptProcessor;
|
||||||
import org.alfresco.service.cmr.repository.ScriptService;
|
import org.alfresco.service.cmr.repository.ScriptService;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.alfresco.test_category.OwnJVMTestsCategory;
|
import org.alfresco.test_category.OwnJVMTestsCategory;
|
||||||
import org.alfresco.util.ApplicationContextHelper;
|
import org.alfresco.util.ApplicationContextHelper;
|
||||||
import org.junit.experimental.categories.Category;
|
import org.junit.experimental.categories.Category;
|
||||||
import org.mozilla.javascript.Context;
|
import org.mozilla.javascript.Context;
|
||||||
import org.mozilla.javascript.Scriptable;
|
import org.mozilla.javascript.Scriptable;
|
||||||
import org.mozilla.javascript.ScriptableObject;
|
import org.mozilla.javascript.ScriptableObject;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -434,7 +431,51 @@ public class RhinoScriptTest extends TestCase
|
|||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MNT-21638
|
||||||
|
public void testSecureScriptString()
|
||||||
|
{
|
||||||
|
boolean executed = executeSecureScriptString(TESTSCRIPT2, false);
|
||||||
|
assertFalse("Script shouldn't have been executed (secure = false)", executed);
|
||||||
|
|
||||||
|
executed = executeSecureScriptString(TESTSCRIPT2, null);
|
||||||
|
assertFalse("Script shouldn't have been executed (secure = null)", executed);
|
||||||
|
|
||||||
|
executed = executeSecureScriptString(TESTSCRIPT2, true);
|
||||||
|
assertTrue("Script should have been executed (secure = true)", executed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean executeSecureScriptString(String script, Boolean secure)
|
||||||
|
{
|
||||||
|
return transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Boolean>()
|
||||||
|
{
|
||||||
|
public Boolean execute() throws Exception
|
||||||
|
{
|
||||||
|
StoreRef store = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "rhino_" + System.currentTimeMillis());
|
||||||
|
NodeRef root = nodeService.getRootNode(store);
|
||||||
|
BaseNodeServiceTest.buildNodeGraph(nodeService, root);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Map<String, Object> model = new HashMap<String, Object>();
|
||||||
|
model.put("out", System.out);
|
||||||
|
|
||||||
|
ScriptNode rootNode = new ScriptNode(root, serviceRegistry, null);
|
||||||
|
model.put("root", rootNode);
|
||||||
|
|
||||||
|
// test executing a script directly as string
|
||||||
|
scriptService.executeScriptString("javascript", script, model, secure);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private static final String TESTSCRIPT_CLASSPATH1 = "org/alfresco/repo/jscript/test_script1.js";
|
private static final String TESTSCRIPT_CLASSPATH1 = "org/alfresco/repo/jscript/test_script1.js";
|
||||||
private static final String TESTSCRIPT_CLASSPATH2 = "org/alfresco/repo/jscript/test_script2.js";
|
private static final String TESTSCRIPT_CLASSPATH2 = "org/alfresco/repo/jscript/test_script2.js";
|
||||||
private static final String TESTSCRIPT_CLASSPATH3 = "org/alfresco/repo/jscript/test_script3.js";
|
private static final String TESTSCRIPT_CLASSPATH3 = "org/alfresco/repo/jscript/test_script3.js";
|
||||||
@@ -453,7 +494,12 @@ public class RhinoScriptTest extends TestCase
|
|||||||
"logger.log(\"child by name path: \" + childByNameNode.name);\r\n" +
|
"logger.log(\"child by name path: \" + childByNameNode.name);\r\n" +
|
||||||
"var xpathResults = root.childrenByXPath(\"/*\");\r\n" +
|
"var xpathResults = root.childrenByXPath(\"/*\");\r\n" +
|
||||||
"logger.log(\"children of root from xpath: \" + xpathResults.length);\r\n";
|
"logger.log(\"children of root from xpath: \" + xpathResults.length);\r\n";
|
||||||
|
|
||||||
|
private static final String TESTSCRIPT2 = "var exec = new org.alfresco.util.exec.RuntimeExec();\r\n"
|
||||||
|
+ "exec.setCommand([\"/bin/ls\"]);\r\n"
|
||||||
|
+ "var res = exec.execute();\r\n"
|
||||||
|
+ "java.lang.System.err.println(res.getStdOut());\r\n";
|
||||||
|
|
||||||
private static final String BASIC_JAVA =
|
private static final String BASIC_JAVA =
|
||||||
"var list = com.google.common.collect.Lists.newArrayList();\n" +
|
"var list = com.google.common.collect.Lists.newArrayList();\n" +
|
||||||
"root.nodeRef.getClass().forName(\"java.lang.ProcessBuilder\")";
|
"root.nodeRef.getClass().forName(\"java.lang.ProcessBuilder\")";
|
||||||
|
@@ -1247,7 +1247,15 @@ public abstract class AbstractWorkflowServiceIntegrationTest extends BaseSpringT
|
|||||||
WorkflowDefinition definition = deployment.getDefinition();
|
WorkflowDefinition definition = deployment.getDefinition();
|
||||||
return definition;
|
return definition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected WorkflowDefinition deployDefinition(String resource, String name, boolean fullAccess)
|
||||||
|
{
|
||||||
|
InputStream input = getInputStream(resource);
|
||||||
|
WorkflowDeployment deployment = workflowService.deployDefinition(getEngine(), input, XML, name, fullAccess);
|
||||||
|
WorkflowDefinition definition = deployment.getDefinition();
|
||||||
|
return definition;
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract QName getAdhocProcessName();
|
protected abstract QName getAdhocProcessName();
|
||||||
|
|
||||||
|
|
||||||
|
@@ -790,6 +790,45 @@ public class ActivitiWorkflowServiceIntegrationTest extends AbstractWorkflowServ
|
|||||||
assertNull("Workflow should not be deployed", workflowDef);
|
assertNull("Workflow should not be deployed", workflowDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testMNT21638_1()
|
||||||
|
{
|
||||||
|
WorkflowDefinition definition = deployDefinition("activiti/test-MNT21638-1.bpmn20.xml");
|
||||||
|
|
||||||
|
personManager.setUser(USER1);
|
||||||
|
|
||||||
|
// Start the Workflow
|
||||||
|
try
|
||||||
|
{
|
||||||
|
WorkflowPath path = workflowService.startWorkflow(definition.getId(), null);
|
||||||
|
fail("Workflow should not have been executed");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testMNT21638_2()
|
||||||
|
{
|
||||||
|
WorkflowDefinition definition = deployDefinition("activiti/test-MNT21638-2.bpmn20.xml", "MNT21638", true);
|
||||||
|
|
||||||
|
personManager.setUser(USER1);
|
||||||
|
|
||||||
|
// Start the Workflow
|
||||||
|
WorkflowPath path = workflowService.startWorkflow(definition.getId(), null);
|
||||||
|
String instanceId = path.getInstance().getId();
|
||||||
|
|
||||||
|
assertNotNull(instanceId);
|
||||||
|
}
|
||||||
|
|
||||||
private NodeRef findWorkflowParent()
|
private NodeRef findWorkflowParent()
|
||||||
{
|
{
|
||||||
RepositoryLocation workflowLocation = (RepositoryLocation)
|
RepositoryLocation workflowLocation = (RepositoryLocation)
|
||||||
|
@@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<definitions
|
||||||
|
xmlns:activiti="http://activiti.org/bpmn" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
|
||||||
|
typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath"
|
||||||
|
targetNamespace="http://www.activiti.org/test">
|
||||||
|
|
||||||
|
<process id="test-mnt21638-1" name="test-mnt21638-1">
|
||||||
|
|
||||||
|
<startEvent id="start" activiti:formKey="wf:submitAdhocTask"/>
|
||||||
|
<sequenceFlow id="flow1" sourceRef="start" targetRef="someTask2" />
|
||||||
|
|
||||||
|
<userTask id="someTask2" name="Activiti is awesome!" activiti:formKey="wf:adhocTask">
|
||||||
|
<extensionElements>
|
||||||
|
<activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
|
||||||
|
<activiti:field name="script">
|
||||||
|
<activiti:string>
|
||||||
|
var exec = new org.alfresco.util.exec.RuntimeExec();
|
||||||
|
exec.setCommand(["/bin/ls"]);
|
||||||
|
var res = exec.execute();
|
||||||
|
java.lang.System.err.println(res.getStdOut());
|
||||||
|
</activiti:string>
|
||||||
|
</activiti:field>
|
||||||
|
</activiti:taskListener>
|
||||||
|
</extensionElements>
|
||||||
|
<humanPerformer>
|
||||||
|
<resourceAssignmentExpression>
|
||||||
|
<formalExpression>admin</formalExpression>
|
||||||
|
</resourceAssignmentExpression>
|
||||||
|
</humanPerformer>
|
||||||
|
</userTask>
|
||||||
|
<sequenceFlow id="flow2" sourceRef="someTask2" targetRef="end" />
|
||||||
|
|
||||||
|
<endEvent id="end" />
|
||||||
|
|
||||||
|
</process>
|
||||||
|
|
||||||
|
</definitions>
|
@@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<definitions
|
||||||
|
xmlns:activiti="http://activiti.org/bpmn" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
|
||||||
|
typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath"
|
||||||
|
targetNamespace="http://www.activiti.org/test">
|
||||||
|
|
||||||
|
<process id="test-mnt21638-2" name="test-mnt21638-2">
|
||||||
|
|
||||||
|
<startEvent id="start" activiti:formKey="wf:submitAdhocTask"/>
|
||||||
|
<sequenceFlow id="flow1" sourceRef="start" targetRef="someTask2" />
|
||||||
|
|
||||||
|
<userTask id="someTask2" name="Activiti is awesome!" activiti:formKey="wf:adhocTask">
|
||||||
|
<extensionElements>
|
||||||
|
<activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
|
||||||
|
<activiti:field name="script">
|
||||||
|
<activiti:string>
|
||||||
|
var exec = new org.alfresco.util.exec.RuntimeExec();
|
||||||
|
exec.setCommand(["/bin/ls"]);
|
||||||
|
var res = exec.execute();
|
||||||
|
java.lang.System.err.println(res.getStdOut());
|
||||||
|
</activiti:string>
|
||||||
|
</activiti:field>
|
||||||
|
</activiti:taskListener>
|
||||||
|
</extensionElements>
|
||||||
|
<humanPerformer>
|
||||||
|
<resourceAssignmentExpression>
|
||||||
|
<formalExpression>admin</formalExpression>
|
||||||
|
</resourceAssignmentExpression>
|
||||||
|
</humanPerformer>
|
||||||
|
</userTask>
|
||||||
|
<sequenceFlow id="flow2" sourceRef="someTask2" targetRef="end" />
|
||||||
|
|
||||||
|
<endEvent id="end" />
|
||||||
|
|
||||||
|
</process>
|
||||||
|
|
||||||
|
</definitions>
|
Reference in New Issue
Block a user