提交 fe7cb41a 编写于 作者: F Frederik Heremans

Added identitylinks to process-definitions in REST (candidate starter)

上级 0fd1b51c
......@@ -202,6 +202,11 @@ public class IdentityLinkEntity implements Serializable, IdentityLink, Persisten
this.processDef = processDef;
this.processDefId = processDef.getId();
}
@Override
public String getProcessDefinitionId() {
return this.processDefId;
}
@Override
public String toString() {
......
......@@ -50,5 +50,15 @@ public interface IdentityLink {
* The id of the task associated with this identity link.
*/
String getTaskId();
/**
* The process definition id associated with this identity link.
*/
String getProcessDefinitionId();
/**
* The process instance id associated with this identity link.
*/
String getProcessInstanceId();
}
......@@ -39,7 +39,7 @@
<result property="groupId" column="GROUP_ID_" jdbcType="VARCHAR" />
<result property="taskId" column="TASK_ID_" jdbcType="VARCHAR" />
<result property="processInstanceId" column="PROC_INST_ID_" jdbcType="VARCHAR" />
<result property="processDefId" column="PROCESS_DEF_ID_" jdbcType="VARCHAR" />
<result property="processDefId" column="PROC_DEF_ID_" jdbcType="VARCHAR" />
</resultMap>
<!-- IDENTITY LINK SELECT -->
......
......@@ -43,6 +43,7 @@ import org.activiti.engine.task.Task;
import org.activiti.rest.api.engine.AttachmentResponse;
import org.activiti.rest.api.engine.CommentResponse;
import org.activiti.rest.api.engine.EventResponse;
import org.activiti.rest.api.engine.RestIdentityLink;
import org.activiti.rest.api.engine.variable.BooleanRestVariableConverter;
import org.activiti.rest.api.engine.variable.DateRestVariableConverter;
import org.activiti.rest.api.engine.variable.DoubleRestVariableConverter;
......@@ -63,7 +64,6 @@ import org.activiti.rest.api.identity.GroupResponse;
import org.activiti.rest.api.identity.MembershipResponse;
import org.activiti.rest.api.identity.UserInfoResponse;
import org.activiti.rest.api.identity.UserResponse;
import org.activiti.rest.api.legacy.identity.LegacyRestIdentityLink;
import org.activiti.rest.api.management.JobResponse;
import org.activiti.rest.api.management.TableResponse;
import org.activiti.rest.api.repository.DeploymentResourceResponse;
......@@ -300,12 +300,12 @@ public class RestResponseFactory {
return value;
}
public LegacyRestIdentityLink createRestIdentityLink(SecuredResource securedResource, IdentityLink link) {
return createRestIdentityLink(securedResource, link.getType(), link.getUserId(), link.getGroupId(), link.getTaskId());
public RestIdentityLink createRestIdentityLink(SecuredResource securedResource, IdentityLink link) {
return createRestIdentityLink(securedResource, link.getType(), link.getUserId(), link.getGroupId(), link.getTaskId(), link.getProcessDefinitionId());
}
public LegacyRestIdentityLink createRestIdentityLink(SecuredResource securedResource, String type, String userId, String groupId, String taskId) {
LegacyRestIdentityLink result = new LegacyRestIdentityLink();
public RestIdentityLink createRestIdentityLink(SecuredResource securedResource, String type, String userId, String groupId, String taskId, String processDefinitionId) {
RestIdentityLink result = new RestIdentityLink();
result.setUser(userId);
result.setGroup(groupId);
result.setType(type);
......@@ -316,7 +316,11 @@ public class RestResponseFactory {
} else {
family = RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_GROUPS;
}
result.setUrl(securedResource.createFullResourceUrl(RestUrls.URL_TASK_IDENTITYLINK, taskId, family, (userId != null ? userId : groupId), type));
if(processDefinitionId != null) {
result.setUrl(securedResource.createFullResourceUrl(RestUrls.URL_PROCESS_DEFINITION_IDENTITYLINK, processDefinitionId, family, (userId != null ? userId : groupId)));
} else {
result.setUrl(securedResource.createFullResourceUrl(RestUrls.URL_TASK_IDENTITYLINK, taskId, family, (userId != null ? userId : groupId), type));
}
return result;
}
......
......@@ -103,6 +103,15 @@ public final class RestUrls {
*/
public static final String[] URL_PROCESS_DEFINITION = {SEGMENT_REPOSITORY_RESOURCES, SEGMENT_PROCESS_DEFINITION_RESOURCE, "{0}"};
/**
* URL template for a process definition's identity links: <i>repository/process-definitions/{0:processDefinitionId}/identitylinks</i>
*/
public static final String[] URL_PROCESS_DEFINITION_IDENTITYLINKS_COLLECTION = {SEGMENT_REPOSITORY_RESOURCES, SEGMENT_PROCESS_DEFINITION_RESOURCE, "{0}", SEGMENT_IDENTITYLINKS};
/**
* URL template for an identitylink on a process definition: <i>repository/process-definitions/{0:processDefinitionId}/identitylinks/{1:family}/{2:identityId}</i>
*/
public static final String[] URL_PROCESS_DEFINITION_IDENTITYLINK = {SEGMENT_REPOSITORY_RESOURCES, SEGMENT_PROCESS_DEFINITION_RESOURCE, "{0}", SEGMENT_IDENTITYLINKS, "{1}", "{2}"};
/**
* URL template for task collection: <i>runtime/tasks/{0:taskId}</i>
......
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.activiti.rest.api.engine;
/**
* @author Frederik Heremans
*/
public class RestIdentityLink {
private String url;
private String user;
private String group;
private String type;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.activiti.rest.api.repository;
import java.util.ArrayList;
import java.util.List;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.ActivitiObjectNotFoundException;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.IdentityLinkType;
import org.activiti.rest.api.ActivitiUtil;
import org.activiti.rest.api.RestResponseFactory;
import org.activiti.rest.api.SecuredResource;
import org.activiti.rest.api.engine.RestIdentityLink;
import org.activiti.rest.application.ActivitiRestServicesApplication;
import org.restlet.data.Status;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
/**
* @author Frederik Heremans
*/
public class ProcessDefinitionIdentityLinkCollectionResource extends SecuredResource {
@Get
public List<RestIdentityLink> getIdentityLinks() {
if(!authenticate())
return null;
List<RestIdentityLink> result = new ArrayList<RestIdentityLink>();
ProcessDefinition processDefinition = getProcessDefinitionFromRequest();
List<IdentityLink> identityLinks = ActivitiUtil.getRepositoryService().getIdentityLinksForProcessDefinition(processDefinition.getId());
RestResponseFactory responseFactory = getApplication(ActivitiRestServicesApplication.class).getRestResponseFactory();
for(IdentityLink link : identityLinks) {
result.add(responseFactory.createRestIdentityLink(this, link));
}
return result;
}
@Post
public RestIdentityLink createIdentityLink(RestIdentityLink identityLink) {
if(!authenticate())
return null;
ProcessDefinition processDefinition = getProcessDefinitionFromRequest();
if(identityLink.getGroup() == null && identityLink.getUser() == null) {
throw new ActivitiIllegalArgumentException("A group or a user is required to create an identity link.");
}
if(identityLink.getGroup() != null && identityLink.getUser() != null) {
throw new ActivitiIllegalArgumentException("Only one of user or group can be used to create an identity link.");
}
if(identityLink.getGroup() != null) {
ActivitiUtil.getRepositoryService().addCandidateStarterGroup(processDefinition.getId(), identityLink.getGroup());
} else {
ActivitiUtil.getRepositoryService().addCandidateStarterUser(processDefinition.getId(), identityLink.getUser());
}
// Always candidate for process-definition. User-provided value is ignored
identityLink.setType(IdentityLinkType.CANDIDATE);
setStatus(Status.SUCCESS_CREATED);
return getApplication(ActivitiRestServicesApplication.class).getRestResponseFactory()
.createRestIdentityLink(this, identityLink.getType(), identityLink.getUser(), identityLink.getGroup(), null, processDefinition.getId());
}
/**
* Returns the {@link ProcessDefinition} that is requested. Throws the right exceptions
* when bad request was made or definition is not found.
*/
protected ProcessDefinition getProcessDefinitionFromRequest() {
String processDefinitionId = getAttribute("processDefinitionId");
if(processDefinitionId == null) {
throw new ActivitiIllegalArgumentException("The processDefinitionId cannot be null");
}
ProcessDefinition processDefinition = ActivitiUtil.getRepositoryService().createProcessDefinitionQuery()
.processDefinitionId(processDefinitionId).singleResult();
if(processDefinition == null) {
throw new ActivitiObjectNotFoundException("Could not find a process definition with id '" + processDefinitionId + "'.", ProcessDefinition.class);
}
return processDefinition;
}
}
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.activiti.rest.api.repository;
import java.util.List;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.ActivitiObjectNotFoundException;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.IdentityLinkType;
import org.activiti.rest.api.ActivitiUtil;
import org.activiti.rest.api.RestUrls;
import org.activiti.rest.api.SecuredResource;
import org.activiti.rest.api.engine.RestIdentityLink;
import org.activiti.rest.application.ActivitiRestServicesApplication;
import org.restlet.data.Status;
import org.restlet.resource.Delete;
import org.restlet.resource.Get;
/**
* @author Frederik Heremans
*/
public class ProcessDefinitionIdentityLinkResource extends SecuredResource {
@Get
public RestIdentityLink getIdentityLink() {
if (!authenticate())
return null;
ProcessDefinition processDefinition = getProcessDefinitionFromRequest();
// Extract and validate identity link from URL
String family = getAttribute("family");
String identityId = getAttribute("identityId");
validateIdentityLinkArguments(family, identityId);
// Check if identitylink to get exists
IdentityLink link = getIdentityLink(family, identityId, processDefinition.getId());
return getApplication(ActivitiRestServicesApplication.class).getRestResponseFactory().createRestIdentityLink(this, link);
}
@Delete
public void deleteIdentityLink() {
if (!authenticate())
return;
ProcessDefinition processDefinition = getProcessDefinitionFromRequest();
// Extract and validate identity link from URL
String family = getAttribute("family");
String identityId = getAttribute("identityId");
validateIdentityLinkArguments(family, identityId);
// Check if identitylink to delete exists
IdentityLink link = getIdentityLink(family, identityId, processDefinition.getId());
if(link.getUserId() != null) {
ActivitiUtil.getRepositoryService().deleteCandidateStarterUser(processDefinition.getId(), link.getUserId());
} else {
ActivitiUtil.getRepositoryService().deleteCandidateStarterGroup(processDefinition.getId(), link.getGroupId());
}
setStatus(Status.SUCCESS_NO_CONTENT);
}
protected void validateIdentityLinkArguments(String family, String identityId) {
if (family == null || (!RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_GROUPS.equals(family) && !RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS.equals(family))) {
throw new ActivitiIllegalArgumentException("Identity link family should be 'users' or 'groups'.");
}
if (identityId == null) {
throw new ActivitiIllegalArgumentException("IdentityId is required.");
}
}
protected IdentityLink getIdentityLink(String family, String identityId, String processDefinitionId) {
boolean isUser = family.equals(RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS);
// Perhaps it would be better to offer getting a single identitylink from
// the API
List<IdentityLink> allLinks = ActivitiUtil.getRepositoryService().getIdentityLinksForProcessDefinition(processDefinitionId);
for (IdentityLink link : allLinks) {
boolean rightIdentity = false;
if (isUser) {
rightIdentity = identityId.equals(link.getUserId());
} else {
rightIdentity = identityId.equals(link.getGroupId());
}
if (rightIdentity && link.getType().equals(IdentityLinkType.CANDIDATE)) {
return link;
}
}
throw new ActivitiObjectNotFoundException("Could not find the requested identity link.", IdentityLink.class);
}
/**
* Returns the {@link ProcessDefinition} that is requested. Throws the right
* exceptions when bad request was made or definition is not found.
*/
protected ProcessDefinition getProcessDefinitionFromRequest() {
String processDefinitionId = getAttribute("processDefinitionId");
if (processDefinitionId == null) {
throw new ActivitiIllegalArgumentException("The processDefinitionId cannot be null");
}
ProcessDefinition processDefinition = ActivitiUtil.getRepositoryService().createProcessDefinitionQuery().processDefinitionId(processDefinitionId)
.singleResult();
if (processDefinition == null) {
throw new ActivitiObjectNotFoundException("Could not find a process definition with id '" + processDefinitionId + "'.", ProcessDefinition.class);
}
return processDefinition;
}
}
......@@ -21,7 +21,7 @@ import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.Task;
import org.activiti.rest.api.ActivitiUtil;
import org.activiti.rest.api.RestResponseFactory;
import org.activiti.rest.api.legacy.identity.LegacyRestIdentityLink;
import org.activiti.rest.api.engine.RestIdentityLink;
import org.activiti.rest.application.ActivitiRestServicesApplication;
import org.restlet.data.Status;
import org.restlet.resource.Get;
......@@ -34,11 +34,11 @@ import org.restlet.resource.Post;
public class TaskIdentityLinkCollectionResource extends TaskBaseResource {
@Get
public List<LegacyRestIdentityLink> getIdentityLinks() {
public List<RestIdentityLink> getIdentityLinks() {
if(!authenticate())
return null;
List<LegacyRestIdentityLink> result = new ArrayList<LegacyRestIdentityLink>();
List<RestIdentityLink> result = new ArrayList<RestIdentityLink>();
Task task = getTaskFromRequest();
List<IdentityLink> identityLinks = ActivitiUtil.getTaskService().getIdentityLinksForTask(task.getId());
......@@ -50,7 +50,7 @@ public class TaskIdentityLinkCollectionResource extends TaskBaseResource {
}
@Post
public LegacyRestIdentityLink createIdentityLink(LegacyRestIdentityLink identityLink) {
public RestIdentityLink createIdentityLink(RestIdentityLink identityLink) {
if(!authenticate())
return null;
......@@ -76,6 +76,6 @@ public class TaskIdentityLinkCollectionResource extends TaskBaseResource {
setStatus(Status.SUCCESS_CREATED);
return getApplication(ActivitiRestServicesApplication.class).getRestResponseFactory()
.createRestIdentityLink(this, identityLink.getType(), identityLink.getUser(), identityLink.getGroup(), task.getId());
.createRestIdentityLink(this, identityLink.getType(), identityLink.getUser(), identityLink.getGroup(), task.getId(), null);
}
}
......@@ -23,7 +23,7 @@ import org.activiti.engine.task.Task;
import org.activiti.rest.api.ActivitiUtil;
import org.activiti.rest.api.RestResponseFactory;
import org.activiti.rest.api.RestUrls;
import org.activiti.rest.api.legacy.identity.LegacyRestIdentityLink;
import org.activiti.rest.api.engine.RestIdentityLink;
import org.activiti.rest.application.ActivitiRestServicesApplication;
import org.restlet.data.Status;
import org.restlet.resource.Delete;
......@@ -36,7 +36,7 @@ import org.restlet.resource.Get;
public class TaskIdentityLinkFamilyResource extends TaskBaseResource {
@Get
public List<LegacyRestIdentityLink> getIdentityLinksForFamily() {
public List<RestIdentityLink> getIdentityLinksForFamily() {
if(!authenticate())
return null;
......@@ -51,7 +51,7 @@ public class TaskIdentityLinkFamilyResource extends TaskBaseResource {
}
boolean isUser = family.equals(RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS);
List<LegacyRestIdentityLink> results = new ArrayList<LegacyRestIdentityLink>();
List<RestIdentityLink> results = new ArrayList<RestIdentityLink>();
RestResponseFactory responseFactory = getApplication(ActivitiRestServicesApplication.class).getRestResponseFactory();
List<IdentityLink> allLinks = ActivitiUtil.getTaskService().getIdentityLinksForTask(task.getId());
......
......@@ -21,7 +21,7 @@ import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.Task;
import org.activiti.rest.api.ActivitiUtil;
import org.activiti.rest.api.RestUrls;
import org.activiti.rest.api.legacy.identity.LegacyRestIdentityLink;
import org.activiti.rest.api.engine.RestIdentityLink;
import org.activiti.rest.application.ActivitiRestServicesApplication;
import org.restlet.data.Status;
import org.restlet.resource.Delete;
......@@ -34,7 +34,7 @@ import org.restlet.resource.Get;
public class TaskIdentityLinkResource extends TaskBaseResource {
@Get
public LegacyRestIdentityLink getIdentityLink() {
public RestIdentityLink getIdentityLink() {
if(!authenticate())
return null;
......
......@@ -74,6 +74,8 @@ import org.activiti.rest.api.repository.DeploymentResourceCollectionResource;
import org.activiti.rest.api.repository.DeploymentResourceDataResource;
import org.activiti.rest.api.repository.DeploymentResourceResource;
import org.activiti.rest.api.repository.ProcessDefinitionCollectionResource;
import org.activiti.rest.api.repository.ProcessDefinitionIdentityLinkCollectionResource;
import org.activiti.rest.api.repository.ProcessDefinitionIdentityLinkResource;
import org.activiti.rest.api.repository.ProcessDefinitionResource;
import org.activiti.rest.api.repository.SimpleWorkflowResource;
import org.activiti.rest.api.runtime.process.ExecutionCollectionResource;
......@@ -128,6 +130,8 @@ public class RestServicesInit {
router.attach("/repository/process-definitions", ProcessDefinitionCollectionResource.class);
router.attach("/repository/process-definitions/{processDefinitionId}", ProcessDefinitionResource.class);
router.attach("/repository/process-definitions/{processDefinitionId}/identitylinks", ProcessDefinitionIdentityLinkCollectionResource.class);
router.attach("/repository/process-definitions/{processDefinitionId}/identitylinks/{family}/{identityId}", ProcessDefinitionIdentityLinkResource.class);
router.attach("/runtime/tasks", TaskCollectionResource.class);
router.attach("/runtime/tasks/{taskId}", TaskResource.class);
......
package org.activiti.rest.api.repository;
import java.util.List;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.test.Deployment;
import org.activiti.rest.BaseRestTestCase;
import org.activiti.rest.api.RestUrls;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.node.ObjectNode;
import org.restlet.data.Status;
import org.restlet.representation.Representation;
import org.restlet.resource.ClientResource;
import org.restlet.resource.ResourceException;
/**
* Test for all REST-operations related to single a Process Definition resource.
*
* @author Frederik Heremans
*/
public class ProcessDefinitionIdentityLinksResourceTest extends BaseRestTestCase {
/**
* Test getting identitylinks for a process definition.
*/
@Deployment(resources={"org/activiti/rest/api/repository/oneTaskProcess.bpmn20.xml"})
public void testGetIdentityLinksForProcessDefinition() throws Exception {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
repositoryService.addCandidateStarterGroup(processDefinition.getId(), "admin");
repositoryService.addCandidateStarterUser(processDefinition.getId(), "kermit");
ClientResource client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(
RestUrls.URL_PROCESS_DEFINITION_IDENTITYLINKS_COLLECTION, processDefinition.getId()));
Representation response = client.get();
// Check "OK" status
assertEquals(Status.SUCCESS_OK, client.getResponse().getStatus());
JsonNode responseNode = objectMapper.readTree(response.getStream());
assertNotNull(responseNode);
assertTrue(responseNode.isArray());
assertEquals(2, responseNode.size());
boolean groupCandidateFound = false;
boolean userCandidateFound = false;
for(int i=0; i < responseNode.size(); i++) {
ObjectNode link = (ObjectNode) responseNode.get(i);
assertNotNull(link);
if(!link.get("user").isNull()) {
assertEquals("kermit", link.get("user").getTextValue());
assertEquals("candidate", link.get("type").getTextValue());
assertTrue(link.get("group").isNull());
assertTrue(link.get("url").getTextValue().endsWith(RestUrls.createRelativeResourceUrl(RestUrls.URL_PROCESS_DEFINITION_IDENTITYLINK,
encode(processDefinition.getId()), "users", "kermit")));
userCandidateFound = true;
} else if(!link.get("group").isNull()) {
assertEquals("admin", link.get("group").getTextValue());
assertEquals("candidate", link.get("type").getTextValue());
assertTrue(link.get("user").isNull());
assertTrue(link.get("url").getTextValue().endsWith(RestUrls.createRelativeResourceUrl(RestUrls.URL_PROCESS_DEFINITION_IDENTITYLINK,
encode(processDefinition.getId()), "groups", "admin")));
groupCandidateFound = true;
}
}
assertTrue(groupCandidateFound);
assertTrue(userCandidateFound);
}
public void testGetIdentityLinksForUnexistingProcessDefinition() throws Exception {
ClientResource client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(RestUrls.URL_PROCESS_DEFINITION_IDENTITYLINKS_COLLECTION, "unexisting"));
try {
client.get();
fail("404 expected, but was: " + client.getResponse().getStatus());
} catch(ResourceException expected) {
assertEquals(Status.CLIENT_ERROR_NOT_FOUND, client.getResponse().getStatus());
assertEquals("Could not find a process definition with id 'unexisting'.", client.getResponse().getStatus().getDescription());
}
}
@Deployment(resources={"org/activiti/rest/api/repository/oneTaskProcess.bpmn20.xml"})
public void testAddCandidateStarterToProcessDefinition() throws Exception {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
ClientResource client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(RestUrls.URL_PROCESS_DEFINITION_IDENTITYLINKS_COLLECTION, processDefinition.getId()));
// Create user candidate
ObjectNode requestNode = objectMapper.createObjectNode();
requestNode.put("user", "kermit");
Representation response = client.post(requestNode);
assertEquals(Status.SUCCESS_CREATED, client.getResponse().getStatus());
JsonNode responseNode = objectMapper.readTree(response.getStream());
assertNotNull(responseNode);
assertEquals("kermit", responseNode.get("user").getTextValue());
assertEquals("candidate", responseNode.get("type").getTextValue());
assertTrue(responseNode.get("group").isNull());
assertTrue(responseNode.get("url").getTextValue().endsWith(RestUrls.createRelativeResourceUrl(RestUrls.URL_PROCESS_DEFINITION_IDENTITYLINK,
encode(processDefinition.getId()), "users", "kermit")));
List<IdentityLink> createdLinks = repositoryService.getIdentityLinksForProcessDefinition(processDefinition.getId());
assertEquals(1, createdLinks.size());
assertEquals("kermit", createdLinks.get(0).getUserId());
assertEquals("candidate", createdLinks.get(0).getType());
repositoryService.deleteCandidateStarterUser(processDefinition.getId(), "kermit");
// Create group candidate
requestNode = objectMapper.createObjectNode();
requestNode.put("group", "admin");
response = client.post(requestNode);
assertEquals(Status.SUCCESS_CREATED, client.getResponse().getStatus());
responseNode = objectMapper.readTree(response.getStream());
assertNotNull(responseNode);
assertEquals("admin", responseNode.get("group").getTextValue());
assertEquals("candidate", responseNode.get("type").getTextValue());
assertTrue(responseNode.get("user").isNull());
assertTrue(responseNode.get("url").getTextValue().endsWith(RestUrls.createRelativeResourceUrl(RestUrls.URL_PROCESS_DEFINITION_IDENTITYLINK,
encode(processDefinition.getId()), "groups", "admin")));
createdLinks = repositoryService.getIdentityLinksForProcessDefinition(processDefinition.getId());
assertEquals(1, createdLinks.size());
assertEquals("admin", createdLinks.get(0).getGroupId());
assertEquals("candidate", createdLinks.get(0).getType());
repositoryService.deleteCandidateStarterUser(processDefinition.getId(), "admin");
}
public void testAddCandidateStarterToUnexistingProcessDefinition() throws Exception {
ClientResource client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(RestUrls.URL_PROCESS_DEFINITION_IDENTITYLINKS_COLLECTION, "unexisting"));
// Create user candidate
ObjectNode requestNode = objectMapper.createObjectNode();
requestNode.put("user", "kermit");
try {
client.post(requestNode);
fail("404 expected, but was: " + client.getResponse().getStatus());
} catch(ResourceException expected) {
assertEquals(Status.CLIENT_ERROR_NOT_FOUND, client.getResponse().getStatus());
assertEquals("Could not find a process definition with id 'unexisting'.", client.getResponse().getStatus().getDescription());
}
}
@Deployment(resources={"org/activiti/rest/api/repository/oneTaskProcess.bpmn20.xml"})
public void testGetCandidateStarterFromProcessDefinition() throws Exception {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
repositoryService.addCandidateStarterGroup(processDefinition.getId(), "admin");
repositoryService.addCandidateStarterUser(processDefinition.getId(), "kermit");
// Get user candidate
ClientResource client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(RestUrls.URL_PROCESS_DEFINITION_IDENTITYLINK, processDefinition.getId(), "users", "kermit"));
Representation response = client.get();
assertEquals(Status.SUCCESS_OK, client.getResponse().getStatus());
JsonNode responseNode = objectMapper.readTree(response.getStream());
assertNotNull(responseNode);
assertEquals("kermit", responseNode.get("user").getTextValue());
assertEquals("candidate", responseNode.get("type").getTextValue());
assertTrue(responseNode.get("group").isNull());
assertTrue(responseNode.get("url").getTextValue().endsWith(RestUrls.createRelativeResourceUrl(RestUrls.URL_PROCESS_DEFINITION_IDENTITYLINK,
encode(processDefinition.getId()), "users", "kermit")));
// Get group candidate
client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(RestUrls.URL_PROCESS_DEFINITION_IDENTITYLINK, processDefinition.getId(), "groups", "admin"));
response = client.get();
assertEquals(Status.SUCCESS_OK, client.getResponse().getStatus());
responseNode = objectMapper.readTree(response.getStream());
assertNotNull(responseNode);
assertEquals("admin", responseNode.get("group").getTextValue());
assertEquals("candidate", responseNode.get("type").getTextValue());
assertTrue(responseNode.get("user").isNull());
assertTrue(responseNode.get("url").getTextValue().endsWith(RestUrls.createRelativeResourceUrl(RestUrls.URL_PROCESS_DEFINITION_IDENTITYLINK,
encode(processDefinition.getId()), "groups", "admin")));
}
@Deployment(resources={"org/activiti/rest/api/repository/oneTaskProcess.bpmn20.xml"})
public void testDeleteCandidateStarterFromProcessDefinition() throws Exception {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
repositoryService.addCandidateStarterGroup(processDefinition.getId(), "admin");
repositoryService.addCandidateStarterUser(processDefinition.getId(), "kermit");
// Get user candidate
ClientResource client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(RestUrls.URL_PROCESS_DEFINITION_IDENTITYLINK, processDefinition.getId(), "users", "kermit"));
Representation response = client.delete();
assertEquals(Status.SUCCESS_NO_CONTENT, client.getResponse().getStatus());
assertEquals(0, response.getSize());
// Check if group-link remains
List<IdentityLink> remainingLinks = repositoryService.getIdentityLinksForProcessDefinition(processDefinition.getId());
assertEquals(1, remainingLinks.size());
assertEquals("admin", remainingLinks.get(0).getGroupId());
// Delete group candidate
client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(RestUrls.URL_PROCESS_DEFINITION_IDENTITYLINK, processDefinition.getId(), "groups", "admin"));
response = client.delete();
assertEquals(Status.SUCCESS_NO_CONTENT, client.getResponse().getStatus());
assertEquals(0, response.getSize());
// Check if all links are removed
remainingLinks = repositoryService.getIdentityLinksForProcessDefinition(processDefinition.getId());
assertEquals(0, remainingLinks.size());
}
public void testDeleteCandidateStarterFromUnexistingProcessDefinition() throws Exception {
ClientResource client = getAuthenticatedClient(
RestUrls.createRelativeResourceUrl(RestUrls.URL_PROCESS_DEFINITION_IDENTITYLINK, "unexisting", "groups", "admin"));
try {
client.delete();
fail("404 expected, but was: " + client.getResponse().getStatus());
} catch(ResourceException expected) {
assertEquals(Status.CLIENT_ERROR_NOT_FOUND, client.getResponse().getStatus());
assertEquals("Could not find a process definition with id 'unexisting'.", client.getResponse().getStatus().getDescription());
}
}
public void testGetCandidateStarterFromUnexistingProcessDefinition() throws Exception {
ClientResource client = getAuthenticatedClient(
RestUrls.createRelativeResourceUrl(RestUrls.URL_PROCESS_DEFINITION_IDENTITYLINK, "unexisting", "groups", "admin"));
try {
client.get();
fail("404 expected, but was: " + client.getResponse().getStatus());
} catch(ResourceException expected) {
assertEquals(Status.CLIENT_ERROR_NOT_FOUND, client.getResponse().getStatus());
assertEquals("Could not find a process definition with id 'unexisting'.", client.getResponse().getStatus().getDescription());
}
}
}
......@@ -1299,6 +1299,303 @@
</para>
</section>
<section>
<title>Get all candidate starters for a process-definition</title>
<para>
<programlisting>GET repository/process-definitions/{processDefinitionId}/identitylinks</programlisting>
</para>
<para>
<table>
<title>URL parameters</title>
<tgroup cols='3'>
<thead>
<row>
<entry>Parameter</entry>
<entry>Required</entry>
<entry>Value</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>processDefinitionId</entry>
<entry>Yes</entry>
<entry>String</entry>
<entry>The id of the process definition to get the identity links for.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<table>
<title>Response codes</title>
<tgroup cols='2'>
<thead>
<row>
<entry>Response code</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>200</entry>
<entry>Indicates the process definition was found and the requested identity links are returned.</entry>
</row>
<row>
<entry>404</entry>
<entry>Indicates the requested process definition was not found.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<emphasis role="bold">Success response body:</emphasis>
<programlisting>
[
{
"url":"http://localhost:8182/repository/process-definitions/oneTaskProcess%3A1%3A4/identitylinks/groups/admin",
"user":null,
"group":"admin",
"type":"candidate"
},
{
"url":"http://localhost:8182/repository/process-definitions/oneTaskProcess%3A1%3A4/identitylinks/users/kermit",
"user":"kermit",
"group":null,
"type":"candidate"
}
]</programlisting>
</para>
</section>
<section>
<title>Add a candidate starter to a process definition</title>
<para>
<programlisting>POST repository/process-definitions/{processDefinitionId}/identitylinks</programlisting>
</para>
<para>
<table>
<title>URL parameters</title>
<tgroup cols='3'>
<thead>
<row>
<entry>Parameter</entry>
<entry>Required</entry>
<entry>Value</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>processDefinitionId</entry>
<entry>Yes</entry>
<entry>String</entry>
<entry>The id of the process definition.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<emphasis role="bold">Request body (user):</emphasis>
<programlisting>
{
"userId" : "kermit"
}</programlisting>
</para>
<para>
<emphasis role="bold">Request body (group):</emphasis>
<programlisting>
{
"groupId" : "sales"
}</programlisting>
</para>
<para>
<table>
<title>Response codes</title>
<tgroup cols='2'>
<thead>
<row>
<entry>Response code</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>201</entry>
<entry>Indicates the process definition was found and the identity link was created.</entry>
</row>
<row>
<entry>404</entry>
<entry>Indicates the requested process definition was not found.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<emphasis role="bold">Success response body:</emphasis>
<programlisting>
{
"url":"http://localhost:8182/repository/process-definitions/oneTaskProcess%3A1%3A4/identitylinks/users/kermit",
"user":"kermit",
"group":null,
"type":"candidate"
}</programlisting>
</para>
</section>
<section>
<title>Delete a candidate starter from a process definition</title>
<para>
<programlisting>DELETE repository/process-definitions/{processDefinitionId}/identitylinks/{family}/{identityId}</programlisting>
</para>
<para>
<table>
<title>URL parameters</title>
<tgroup cols='3'>
<thead>
<row>
<entry>Parameter</entry>
<entry>Required</entry>
<entry>Value</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>processDefinitionId</entry>
<entry>Yes</entry>
<entry>String</entry>
<entry>The id of the process definition.</entry>
</row>
<row>
<entry>family</entry>
<entry>Yes</entry>
<entry>String</entry>
<entry>Either <literal>users</literal> or <literal>groups</literal>, depending on the type of identity link.</entry>
</row>
<row>
<entry>identityId</entry>
<entry>Yes</entry>
<entry>String</entry>
<entry>Either the userId or groupId of the identity to remove as candidate starter.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<table>
<title>Response codes</title>
<tgroup cols='2'>
<thead>
<row>
<entry>Response code</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>204</entry>
<entry>Indicates the process definition was found and the identity link was removed. The response body is intentionally empty.</entry>
</row>
<row>
<entry>404</entry>
<entry>Indicates the requested process definition was not found or the process definition doesn't have an identity-link that matches the url.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<emphasis role="bold">Success response body:</emphasis>
<programlisting>
{
"url":"http://localhost:8182/repository/process-definitions/oneTaskProcess%3A1%3A4/identitylinks/users/kermit",
"user":"kermit",
"group":null,
"type":"candidate"
}</programlisting>
</para>
</section>
<section>
<title>Get a candidate starter from a process definition</title>
<para>
<programlisting>GET repository/process-definitions/{processDefinitionId}/identitylinks/{family}/{identityId}</programlisting>
</para>
<para>
<table>
<title>URL parameters</title>
<tgroup cols='3'>
<thead>
<row>
<entry>Parameter</entry>
<entry>Required</entry>
<entry>Value</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>processDefinitionId</entry>
<entry>Yes</entry>
<entry>String</entry>
<entry>The id of the process definition.</entry>
</row>
<row>
<entry>family</entry>
<entry>Yes</entry>
<entry>String</entry>
<entry>Either <literal>users</literal> or <literal>groups</literal>, depending on the type of identity link.</entry>
</row>
<row>
<entry>identityId</entry>
<entry>Yes</entry>
<entry>String</entry>
<entry>Either the userId or groupId of the identity to get as candidate starter.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<table>
<title>Response codes</title>
<tgroup cols='2'>
<thead>
<row>
<entry>Response code</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>200</entry>
<entry>Indicates the process definition was found and the identity link was returned.</entry>
</row>
<row>
<entry>404</entry>
<entry>Indicates the requested process definition was not found or the process definition doesn't have an identity-link that matches the url.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<emphasis role="bold">Success response body:</emphasis>
<programlisting>
{
"url":"http://localhost:8182/repository/process-definitions/oneTaskProcess%3A1%3A4/identitylinks/users/kermit",
"user":"kermit",
"group":null,
"type":"candidate"
}</programlisting>
</para>
</section>
</section>
<section>
......@@ -2785,6 +3082,85 @@ GET runtime/tasks/{taskId}/identitylinks/groups</programlisting>
"groupId" : "sales",
"type" : "candidate",
"url" : "http://localhost:8081/activiti-rest/service/runtime/tasks/100/identitylinks/groups/sales/candidate"
}</programlisting>
</para>
</section>
<section>
<title>Create a single identity link on a task</title>
<para>
<programlisting>POST runtime/tasks/{taskId}/identitylinks</programlisting>
</para>
<para>
<table>
<title>URL parameters</title>
<tgroup cols='3'>
<thead>
<row>
<entry>Parameter</entry>
<entry>Required</entry>
<entry>Value</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>taskId</entry>
<entry>Yes</entry>
<entry>String</entry>
<entry>The id of the task .</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<emphasis role="bold">Request body (user):</emphasis>
<programlisting>
{
"userId" : "kermit",
"type" : "candidate",
}</programlisting>
</para>
<para>
<emphasis role="bold">Request body (group):</emphasis>
<programlisting>
{
"groupId" : "sales",
"type" : "candidate",
}</programlisting>
</para>
<para>
<table>
<title>Response codes</title>
<tgroup cols='2'>
<thead>
<row>
<entry>Response code</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>201</entry>
<entry>Indicates the task was found and the identity link was created.</entry>
</row>
<row>
<entry>404</entry>
<entry>Indicates the requested task was not found or the task doesn't have the requested identityLink. The status contains additional information about this error.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<emphasis role="bold">Success response body:</emphasis>
<programlisting>
{
"userId" : null,
"groupId" : "sales",
"type" : "candidate",
"url" : "http://localhost:8081/activiti-rest/service/runtime/tasks/100/identitylinks/groups/sales/candidate"
}</programlisting>
</para>
</section>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册