Merged SHA-SIMP-1 (5.1.0) to HEAD (5.1)

105016: SHA-935: Repository Invite Flow Changes
     - Added new invitation-add-direct.bpmn20.xml workflow
     - Added bootstrapping of new workflow
     - Changed InvitationServiceImpl to allow setting of workflows used
     - Added configuration of workflows used in invitationService bean
     - Added repository properties for default workflows
     - Changed InvitationServiceImpl.getWorkflowDefinition to take an enum argument
     - Changed abstract testNominatedInvitationExistingUser to accommodate both current and new invite flows
     - Added test of new flow to Activiti test


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@110788 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Ray Gauss
2015-08-25 14:00:26 +00:00
parent e3191842c8
commit aee14f6158
8 changed files with 271 additions and 103 deletions

View File

@@ -201,6 +201,14 @@
<prop key="mimetype">text/xml</prop>
<prop key="redeploy">false</prop>
</props>
<!-- Activiti add site users service workflow definition -->
<props>
<prop key="engineId">activiti</prop>
<prop key="location">alfresco/workflow/invitation-add-direct.bpmn20.xml</prop>
<prop key="mimetype">text/xml</prop>
<prop key="redeploy">false</prop>
</props>
</list>
</property>
<property name="models">

View File

@@ -21,6 +21,9 @@
<ref bean="policyComponent" />
</property>
<property name="sysAdminParams" ref="sysAdminParams"/>
<property name="nominatedInvitationWorkflowId" value="${site.invite.nominated.workflowId}"/>
<property name="nominatedInvitationExternalWorkflowId" value="${site.invite.nominatedExternal.workflowId}"/>
<property name="moderatedInvitationWorkflowId" value="${site.invite.moderated.workflowId}"/>
</bean>
<!-- Site service security bean -->

View File

@@ -769,6 +769,12 @@ deployment.service.targetLockTimeout=3600000
#Invitation Service
# Should send emails as part of invitation process.
notification.email.siteinvite=true
# Moderated invite Activiti workflow
site.invite.moderated.workflowId=activiti$activitiInvitationModerated
# Add intneral users Activiti workflow (use activiti$activitiInvitationNominated to revert to requiring accept of invite for internal users)
site.invite.nominated.workflowId=activiti$activitiInvitationNominatedAddDirect
# Add external users Activiti workflow
site.invite.nominatedExternal.workflowId=activiti$activitiInvitationNominated
# Replication Service
replication.enabled=false

View File

@@ -0,0 +1,44 @@
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema"
expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://alfresco.org/workflows/internal">
<process isExecutable="true" id="activitiInvitationNominatedAddDirect" name="Add user activiti invitation process">
<startEvent id="start" activiti:formKey="inwf:inviteToSiteTask" />
<!-- TODO: SHA-944: Change Order of Email Send to Be After Adding Site -->
<sequenceFlow id="flow1" sourceRef="start" targetRef="sendInvite" />
<serviceTask id="sendInvite" name="Send Invite" activiti:delegateExpression="${SendNominatedInviteDelegate}" />
<sequenceFlow id="flow2" sourceRef="sendInvite" targetRef="accepted" />
<serviceTask id="accepted" name="Accepted" activiti:delegateExpression="${AcceptNominatedInviteDelegate}" />
<sequenceFlow id="flow3" sourceRef="accepted" targetRef="inviteAccepted" />
<userTask id="inviteAccepted" name="Invitation Accepted"
activiti:formKey="inwf:acceptInviteTask" >
<extensionElements>
<activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string>
if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
</activiti:string>
</activiti:field>
</activiti:taskListener>
</extensionElements>
<humanPerformer>
<resourceAssignmentExpression>
<formalExpression>${initiator.exists() ? initiator.properties.userName : 'admin'}</formalExpression>
</resourceAssignmentExpression>
</humanPerformer>
</userTask>
<sequenceFlow id="flow4" sourceRef="inviteAccepted" targetRef="end" />
<endEvent id="end" />
</process>
</definitions>

View File

@@ -126,6 +126,19 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli
// Property determining whether emails should be sent.
private boolean sendEmails = true;
private enum InvitationWorkflowType { NOMINATED, NOMINATED_EXTERNAL, MODERATED };
// The nominated invite workflow definition to use for internal users
private String nominatedInvitationWorkflowId =
WorkflowModelNominatedInvitation.WORKFLOW_DEFINITION_NAME_ACTIVITI_ADD_DIRECT;
// The nominated invite workflow definition to use for external users
private String nominatedInvitationExternalWorkflowId =
WorkflowModelNominatedInvitation.WORKFLOW_DEFINITION_NAME_ACTIVITI_INVITE;
// The nominated invite workflow definition to use for internal users
private String moderatedInvitationWorkflowId =
WorkflowModelModeratedInvitation.WORKFLOW_DEFINITION_NAME_ACTIVITI;
/**
* Set the policy component
*
@@ -136,6 +149,36 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli
this.policyComponent = policyComponent;
}
/**
* Sets the nominated invite activiti workflow definition for internal users
*
* @param nominatedInvitationWorkflowId
*/
public void setNominatedInvitationWorkflowId(String nominatedInvitationWorkflowId)
{
this.nominatedInvitationWorkflowId = nominatedInvitationWorkflowId;
}
/**
* Sets the nominated invite activiti workflow definition for external users
*
* @param nominatedInvitationExternalWorkflowId
*/
public void setNominatedInvitationExternalWorkflowId(String nominatedInvitationExternalWorkflowId)
{
this.nominatedInvitationExternalWorkflowId = nominatedInvitationExternalWorkflowId;
}
/**
* Sets the moderated invite activiti workflow definition
*
* @param moderatedInvitationWorkflowId
*/
public void setModeratedInvitationWorkflowId(String moderatedInvitationWorkflowId)
{
this.moderatedInvitationWorkflowId = moderatedInvitationWorkflowId;
}
/**
* Checks that all necessary properties and services have been provided.
*/
@@ -170,7 +213,8 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli
{
List<String> ret = new ArrayList<String>(3);
ret.add(WorkflowModelNominatedInvitation.WORKFLOW_DEFINITION_NAME);
ret.add(WorkflowModelNominatedInvitation.WORKFLOW_DEFINITION_NAME_ACTIVITI);
ret.add(WorkflowModelNominatedInvitation.WORKFLOW_DEFINITION_NAME_ACTIVITI_ADD_DIRECT);
ret.add(WorkflowModelNominatedInvitation.WORKFLOW_DEFINITION_NAME_ACTIVITI_INVITE);
ret.add(WorkflowModelModeratedInvitation.WORKFLOW_DEFINITION_NAME);
ret.add(WorkflowModelModeratedInvitation.WORKFLOW_DEFINITION_NAME_ACTIVITI);
// old deprecated invitation workflow.
@@ -1214,7 +1258,7 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli
// get the moderated workflow
WorkflowDefinition wfDefinition = getWorkflowDefinition(false);
WorkflowDefinition wfDefinition = getWorkflowDefinition(InvitationWorkflowType.MODERATED);
return (ModeratedInvitation) startWorkflow(wfDefinition, workflowProps);
}
@@ -1376,7 +1420,9 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli
// Start the invite workflow with inviter, invitee and site properties
//
WorkflowDefinition wfDefinition = getWorkflowDefinition(true);
InvitationWorkflowType type =
created ? InvitationWorkflowType.NOMINATED_EXTERNAL : InvitationWorkflowType.NOMINATED;
WorkflowDefinition wfDefinition = getWorkflowDefinition(type);
// Get invitee person NodeRef to add as assignee
NodeRef inviteeNodeRef = personService.getPerson(inviteeUserName);
@@ -1489,12 +1535,24 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli
/**
* Return Activiti workflow definition unless Activiti engine is disabled.
* @param isNominated TODO
* @param type the workflow type
* @return WorkflowDefinition
*/
private WorkflowDefinition getWorkflowDefinition(boolean isNominated)
private WorkflowDefinition getWorkflowDefinition(InvitationWorkflowType type)
{
String workflowName = isNominated ? getNominatedDefinitionName() : getModeratedDefinitionName();
String workflowName = null;
if (type == InvitationWorkflowType.MODERATED)
{
workflowName = getModeratedDefinitionName();
}
else if (type == InvitationWorkflowType.NOMINATED_EXTERNAL)
{
workflowName = getNominatedExternalDefinitionName();
}
else
{
workflowName = getNominatedDefinitionName();
}
WorkflowDefinition definition = workflowService.getDefinitionByName(workflowName);
if (definition == null)
{
@@ -1509,26 +1567,39 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli
{
if(workflowAdminService.isEngineEnabled(ActivitiConstants.ENGINE_ID))
{
return WorkflowModelNominatedInvitation.WORKFLOW_DEFINITION_NAME_ACTIVITI;
return nominatedInvitationWorkflowId;
}
else if(workflowAdminService.isEngineEnabled(JBPMEngine.ENGINE_ID))
{
return WorkflowModelNominatedInvitation.WORKFLOW_DEFINITION_NAME;
}
throw new IllegalStateException("None of the Workflow engines supported by teh InvitationService are currently enabled!");
throw new IllegalStateException("None of the Workflow engines supported by the InvitationService are currently enabled!");
}
private String getNominatedExternalDefinitionName()
{
if(workflowAdminService.isEngineEnabled(ActivitiConstants.ENGINE_ID))
{
return nominatedInvitationExternalWorkflowId;
}
else if(workflowAdminService.isEngineEnabled(JBPMEngine.ENGINE_ID))
{
return WorkflowModelNominatedInvitation.WORKFLOW_DEFINITION_NAME;
}
throw new IllegalStateException("None of the Workflow engines supported by the InvitationService are currently enabled!");
}
private String getModeratedDefinitionName()
{
if(workflowAdminService.isEngineEnabled(ActivitiConstants.ENGINE_ID))
{
return WorkflowModelModeratedInvitation.WORKFLOW_DEFINITION_NAME_ACTIVITI;
return moderatedInvitationWorkflowId;
}
else if(workflowAdminService.isEngineEnabled(JBPMEngine.ENGINE_ID))
{
return WorkflowModelModeratedInvitation.WORKFLOW_DEFINITION_NAME;
}
throw new IllegalStateException("None of the Workflow engines supported by teh InvitationService are currently enabled!");
throw new IllegalStateException("None of the Workflow engines supported by the InvitationService are currently enabled!");
}
/**

View File

@@ -34,7 +34,8 @@ public interface WorkflowModelNominatedInvitation
// workflow definition name
public static final String WORKFLOW_DEFINITION_NAME = "jbpm$inwf:invitation-nominated";
public static final String WORKFLOW_DEFINITION_NAME_ACTIVITI = "activiti$activitiInvitationNominated";
public static final String WORKFLOW_DEFINITION_NAME_ACTIVITI_INVITE = "activiti$activitiInvitationNominated";
public static final String WORKFLOW_DEFINITION_NAME_ACTIVITI_ADD_DIRECT = "activiti$activitiInvitationNominatedAddDirect";
// tasks
public static final QName WF_TASK_INVITE_TO_SITE = QName.createQName(NAMESPACE_URI, "inviteToSiteTask");

View File

@@ -704,12 +704,28 @@ public abstract class AbstractInvitationServiceImplTest extends BaseAlfrescoSpri
}
/**
* Create a Nominated Invitation (for existing user, USER_ONE) read it.
* search for it cancel it search for it again (and fail to find it) Create
* a Nominated Invitation read it. search for it reject it Create a
* Nominated Invitation read it. accept it
* If requireAcceptance=true skip to C1
*
* A1. Create a Nominated Invitation (for existing user, USER_ONE)
* A2. Read it
* A3. Search for it.
* A4. Cancel it
* A5. Search for it again (and fail to find it)
*
* B1. Create a Nominated Invitation
* B2. Read it
* B3. Search for it
* B4. Reject it
*
* C1. Create a Nominated Invitation
* C2. Read it
* C3. Accept it
* C4. Verify ACL
*
* @param requireAcceptance true if a workflow requiring acceptance is being used
* @throws Exception
*/
public void testNominatedInvitationExistingUser() throws Exception
protected void testNominatedInvitationExistingUser(boolean requireAcceptance) throws Exception
{
String inviteeUserName = USER_ONE;
String inviteeEmail = USER_ONE_EMAIL;
@@ -725,6 +741,8 @@ public abstract class AbstractInvitationServiceImplTest extends BaseAlfrescoSpri
authenticationComponent.setCurrentUser(USER_MANAGER);
if (requireAcceptance)
{
NominatedInvitation nominatedInvitation = invitationService.inviteNominated(inviteeUserName, resourceType,
resourceName, inviteeRole, serverPath, acceptUrl, rejectUrl);
@@ -804,19 +822,22 @@ public abstract class AbstractInvitationServiceImplTest extends BaseAlfrescoSpri
List<Invitation> it3 = invitationService.listPendingInvitationsForResource(resourceType, resourceName);
assertTrue("invitations is not empty", it3.isEmpty());
}
/**
* Now invite and accept
*/
NominatedInvitation thirdInvite = invitationService.inviteNominated(inviteeUserName, resourceType,
resourceName, inviteeRole, serverPath, acceptUrl, rejectUrl);
if (requireAcceptance)
{
NominatedInvitation acceptedInvitation = (NominatedInvitation) invitationService.accept(thirdInvite
.getInviteId(), thirdInvite.getTicket());
assertEquals("invite id wrong", thirdInvite.getInviteId(), acceptedInvitation.getInviteId());
assertEquals("first name wrong", inviteeFirstName, acceptedInvitation.getInviteeFirstName());
assertEquals("last name wrong", inviteeLastName, acceptedInvitation.getInviteeLastName());
assertEquals("user name wrong", inviteeUserName, acceptedInvitation.getInviteeUserName());
}
List<Invitation> it4 = invitationService.listPendingInvitationsForResource(resourceType, resourceName);
assertTrue("invitations is not empty", it4.isEmpty());
@@ -829,6 +850,13 @@ public abstract class AbstractInvitationServiceImplTest extends BaseAlfrescoSpri
siteService.removeMembership(resourceName, inviteeUserName);
}
public void testNominatedInvitationExistingUser() throws Exception
{
this.invitationServiceImpl.setNominatedInvitationWorkflowId(
WorkflowModelNominatedInvitation.WORKFLOW_DEFINITION_NAME_ACTIVITI_INVITE);
testNominatedInvitationExistingUser(true);
}
/**
* Create a moderated invitation Get it Search for it Cancel it Create a
* moderated invitation Reject the invitation Create a moderated invitation

View File

@@ -116,4 +116,11 @@ public class ActivitiInvitationServiceImplTests extends AbstractInvitationServic
// Disable Jbpm and enable Activiti
workflowAdminService.setEnabledEngines(Arrays.asList(ActivitiConstants.ENGINE_ID));
}
public void testAddExistingUser() throws Exception
{
this.invitationServiceImpl.setNominatedInvitationWorkflowId(
WorkflowModelNominatedInvitation.WORKFLOW_DEFINITION_NAME_ACTIVITI_ADD_DIRECT);
testNominatedInvitationExistingUser(false);
}
}