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

Added group create/get/update/list and delete to REST

上级 168972a5
...@@ -26,6 +26,7 @@ import org.activiti.engine.history.HistoricProcessInstance; ...@@ -26,6 +26,7 @@ import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance; import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricVariableInstance; import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.history.HistoricVariableUpdate; import org.activiti.engine.history.HistoricVariableUpdate;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User; import org.activiti.engine.identity.User;
import org.activiti.engine.impl.bpmn.deployer.BpmnDeployer; import org.activiti.engine.impl.bpmn.deployer.BpmnDeployer;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity; import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
...@@ -58,6 +59,7 @@ import org.activiti.rest.api.history.HistoricDetailResponse; ...@@ -58,6 +59,7 @@ import org.activiti.rest.api.history.HistoricDetailResponse;
import org.activiti.rest.api.history.HistoricProcessInstanceResponse; import org.activiti.rest.api.history.HistoricProcessInstanceResponse;
import org.activiti.rest.api.history.HistoricTaskInstanceResponse; import org.activiti.rest.api.history.HistoricTaskInstanceResponse;
import org.activiti.rest.api.history.HistoricVariableInstanceResponse; import org.activiti.rest.api.history.HistoricVariableInstanceResponse;
import org.activiti.rest.api.identity.GroupResponse;
import org.activiti.rest.api.identity.UserInfoResponse; import org.activiti.rest.api.identity.UserInfoResponse;
import org.activiti.rest.api.identity.UserResponse; import org.activiti.rest.api.identity.UserResponse;
import org.activiti.rest.api.legacy.identity.LegacyRestIdentityLink; import org.activiti.rest.api.legacy.identity.LegacyRestIdentityLink;
...@@ -570,6 +572,16 @@ public class RestResponseFactory { ...@@ -570,6 +572,16 @@ public class RestResponseFactory {
return response; return response;
} }
public GroupResponse createGroupResponse(SecuredResource securedResource, Group group) {
GroupResponse response = new GroupResponse();
response.setId(group.getId());
response.setName(group.getName());
response.setType(group.getType());
response.setUrl(securedResource.createFullResourceUrl(RestUrls.URL_GROUP, group.getId()));
return response;
}
/** /**
* Called once when the converters need to be initialized. Override of custom conversion * Called once when the converters need to be initialized. Override of custom conversion
...@@ -584,4 +596,5 @@ public class RestResponseFactory { ...@@ -584,4 +596,5 @@ public class RestResponseFactory {
variableConverters.add(new BooleanRestVariableConverter()); variableConverters.add(new BooleanRestVariableConverter());
variableConverters.add(new DateRestVariableConverter()); variableConverters.add(new DateRestVariableConverter());
} }
} }
...@@ -368,6 +368,16 @@ public final class RestUrls { ...@@ -368,6 +368,16 @@ public final class RestUrls {
*/ */
public static final String[] URL_USER_INFO_COLLECTION = {SEGMENT_IDENTITY_RESOURCES, SEGMENT_USERS, "{0}", SEGMENT_INFO}; public static final String[] URL_USER_INFO_COLLECTION = {SEGMENT_IDENTITY_RESOURCES, SEGMENT_USERS, "{0}", SEGMENT_INFO};
/**
* URL template for the collection of groups: <i>identity/groups</i>
*/
public static final String[] URL_GROUP_COLLECTION = {SEGMENT_IDENTITY_RESOURCES, SEGMENT_GROUPS};
/**
* URL template for a single group: <i>identity/groups/{0:groupId}</i>
*/
public static final String[] URL_GROUP = {SEGMENT_IDENTITY_RESOURCES, SEGMENT_GROUPS, "{0}"};
/** /**
* Creates an url based on the passed fragments and replaces any placeholders with the given arguments. The * Creates an url based on the passed fragments and replaces any placeholders with the given arguments. The
* placeholders are folowing the {@link MessageFormat} convention * placeholders are folowing the {@link MessageFormat} convention
......
/* 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.identity;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.ActivitiObjectNotFoundException;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User;
import org.activiti.rest.api.ActivitiUtil;
import org.activiti.rest.api.SecuredResource;
/**
* @author Frederik Heremans
*/
public class BaseGroupResource extends SecuredResource {
protected Group getGroupFromRequest() {
String groupId = getAttribute("groupId");
if (groupId == null) {
throw new ActivitiIllegalArgumentException("The groupId cannot be null");
}
Group group = ActivitiUtil.getIdentityService().createGroupQuery().groupId(groupId).singleResult();
if (group == null) {
throw new ActivitiObjectNotFoundException("Could not find a group with id '" + groupId + "'.", User.class);
}
return group;
}
}
/* 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.identity;
import java.util.HashMap;
import java.util.Set;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.GroupQuery;
import org.activiti.engine.impl.GroupQueryProperty;
import org.activiti.engine.query.QueryProperty;
import org.activiti.rest.api.ActivitiUtil;
import org.activiti.rest.api.DataResponse;
import org.activiti.rest.api.SecuredResource;
import org.activiti.rest.application.ActivitiRestServicesApplication;
import org.restlet.data.Form;
import org.restlet.data.Status;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import org.restlet.resource.ResourceException;
/**
* @author Frederik Heremans
*/
public class GroupCollectionResource extends SecuredResource {
protected static HashMap<String, QueryProperty> properties = new HashMap<String, QueryProperty>();
static {
properties.put("id", GroupQueryProperty.GROUP_ID);
properties.put("name", GroupQueryProperty.NAME);
properties.put("type", GroupQueryProperty.TYPE);
}
@Get
public DataResponse getGroups() {
if(!authenticate())
return null;
GroupQuery query = ActivitiUtil.getIdentityService().createGroupQuery();
Form form = getQuery();
Set<String> names = form.getNames();
if(names.contains("id")) {
query.groupId(getQueryParameter("id", form));
}
if(names.contains("name")) {
query.groupName(getQueryParameter("name", form));
}
if(names.contains("nameLike")) {
query.groupNameLike(getQueryParameter("nameLike", form));
}
if(names.contains("type")) {
query.groupType(getQueryParameter("type", form));
}
if(names.contains("member")) {
query.groupMember(getQueryParameter("member", form));
}
if(names.contains("potentialStarter")) {
query.potentialStarter(getQueryParameter("potentialStarter", form));
}
return new GroupPaginateList(this).paginateList(form, query, "id", properties);
}
@Post
public GroupResponse createGroup(GroupRequest request) {
if(request.getId() == null) {
throw new ActivitiIllegalArgumentException("Id cannot be null.");
}
// Check if a user with the given ID already exists so we return a CONFLICT
if(ActivitiUtil.getIdentityService().createGroupQuery().groupId(request.getId()).count() > 0) {
throw new ResourceException(Status.CLIENT_ERROR_CONFLICT.getCode(), "A group with id '" + request.getId() + "' already exists.", null, null);
}
Group created = ActivitiUtil.getIdentityService().newGroup(request.getId());
created.setId(request.getId());
created.setName(request.getName());
created.setType(request.getType());
ActivitiUtil.getIdentityService().saveGroup(created);
setStatus(Status.SUCCESS_CREATED);
return getApplication(ActivitiRestServicesApplication.class).getRestResponseFactory()
.createGroupResponse(this, created);
}
}
/* 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.identity;
import java.util.ArrayList;
import java.util.List;
import org.activiti.engine.identity.Group;
import org.activiti.rest.api.AbstractPaginateList;
import org.activiti.rest.api.RestResponseFactory;
import org.activiti.rest.api.SecuredResource;
import org.activiti.rest.application.ActivitiRestServicesApplication;
/**
* @author Frederik Heremans
*/
public class GroupPaginateList extends AbstractPaginateList {
private SecuredResource resource;
public GroupPaginateList(SecuredResource resource) {
this.resource = resource;
}
@SuppressWarnings("rawtypes")
@Override
protected List processList(List list) {
List<GroupResponse> responseList = new ArrayList<GroupResponse>();
RestResponseFactory restResponseFactory = resource.getApplication(ActivitiRestServicesApplication.class).getRestResponseFactory();
for (Object entity : list) {
responseList.add(restResponseFactory.createGroupResponse(resource, (Group) entity));
}
return responseList;
}
}
/* 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.identity;
/**
* @author Frederik Heremans
*/
public class GroupRequest extends GroupResponse {
protected boolean isNameChanged = false;
protected boolean isTypeChanged = false;
@Override
public void setType(String type) {
super.setType(type);
isTypeChanged = true;
}
@Override
public void setName(String name) {
super.setName(name);
isNameChanged = true;
}
public boolean isNameChanged() {
return isNameChanged;
}
public boolean isTypeChanged() {
return isTypeChanged;
}
}
/* 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.identity;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.identity.Group;
import org.activiti.rest.api.ActivitiUtil;
import org.activiti.rest.application.ActivitiRestServicesApplication;
import org.restlet.data.Status;
import org.restlet.resource.Delete;
import org.restlet.resource.Get;
import org.restlet.resource.Put;
/**
* @author Frederik Heremans
*/
public class GroupResource extends BaseGroupResource {
@Get
public GroupResponse getUser() {
if(!authenticate())
return null;
return getApplication(ActivitiRestServicesApplication.class).getRestResponseFactory()
.createGroupResponse(this, getGroupFromRequest());
}
@Put
public GroupResponse updateGroup(GroupRequest request) {
Group group = getGroupFromRequest();
if(request.getId() == null || request.getId().equals(group.getId())) {
if(request.isNameChanged()) {
group.setName(request.getName());
}
if(request.isTypeChanged()) {
group.setType(request.getType());
}
ActivitiUtil.getIdentityService().saveGroup(group);
} else {
throw new ActivitiIllegalArgumentException("Key provided in request body doesn't match the key in the resource URL.");
}
return getApplication(ActivitiRestServicesApplication.class).getRestResponseFactory()
.createGroupResponse(this, group);
}
@Delete
public void deleteGroup() {
Group group = getGroupFromRequest();
ActivitiUtil.getIdentityService().deleteGroup(group.getId());
setStatus(Status.SUCCESS_NO_CONTENT);
}
}
/* 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.identity;
/**
* @author Frederik Heremans
*/
public class GroupResponse {
protected String id;
protected String url;
protected String name;
protected String type;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
...@@ -15,6 +15,8 @@ import org.activiti.rest.api.history.HistoricTaskInstanceQueryResource; ...@@ -15,6 +15,8 @@ import org.activiti.rest.api.history.HistoricTaskInstanceQueryResource;
import org.activiti.rest.api.history.HistoricTaskInstanceResource; import org.activiti.rest.api.history.HistoricTaskInstanceResource;
import org.activiti.rest.api.history.HistoricVariableInstanceCollectionResource; import org.activiti.rest.api.history.HistoricVariableInstanceCollectionResource;
import org.activiti.rest.api.history.HistoricVariableInstanceQueryResource; import org.activiti.rest.api.history.HistoricVariableInstanceQueryResource;
import org.activiti.rest.api.identity.GroupCollectionResource;
import org.activiti.rest.api.identity.GroupResource;
import org.activiti.rest.api.identity.UserCollectionResource; import org.activiti.rest.api.identity.UserCollectionResource;
import org.activiti.rest.api.identity.UserInfoCollectionResource; import org.activiti.rest.api.identity.UserInfoCollectionResource;
import org.activiti.rest.api.identity.UserInfoResource; import org.activiti.rest.api.identity.UserInfoResource;
...@@ -175,6 +177,8 @@ public class RestServicesInit { ...@@ -175,6 +177,8 @@ public class RestServicesInit {
router.attach("/identity/users/{userId}/picture", UserPictureResource.class); router.attach("/identity/users/{userId}/picture", UserPictureResource.class);
router.attach("/identity/users/{userId}/info/{key}", UserInfoResource.class); router.attach("/identity/users/{userId}/info/{key}", UserInfoResource.class);
router.attach("/identity/users/{userId}/info", UserInfoCollectionResource.class); router.attach("/identity/users/{userId}/info", UserInfoCollectionResource.class);
router.attach("/identity/groups", GroupCollectionResource.class);
router.attach("/identity/groups/{groupId}", GroupResource.class);
router.attach("/query/tasks", TaskQueryResource.class); router.attach("/query/tasks", TaskQueryResource.class);
......
/* 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.identity;
import java.util.ArrayList;
import java.util.List;
import org.activiti.engine.identity.Group;
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;
/**
* @author Frederik Heremans
*/
public class GroupCollectionResourceTest extends BaseRestTestCase {
/**
* Test getting all groups.
*/
@Deployment
public void testGetGroups() throws Exception {
List<Group> savedGroups = new ArrayList<Group>();
try {
Group group1 = identityService.newGroup("testgroup1");
group1.setName("Test group");
group1.setType("Test type");
identityService.saveGroup(group1);
savedGroups.add(group1);
Group group2 = identityService.newGroup("testgroup2");
group2.setName("Another group");
group2.setType("Another type");
identityService.saveGroup(group2);
savedGroups.add(group2);
Group group3 = identityService.createGroupQuery().groupId("admin").singleResult();
assertNotNull(group3);
// Test filter-less
String url = RestUrls.createRelativeResourceUrl(RestUrls.URL_GROUP_COLLECTION);
assertResultsPresentInDataResponse(url, group1.getId(), group2.getId(), group3.getId());
// Test based on name
url = RestUrls.createRelativeResourceUrl(RestUrls.URL_GROUP_COLLECTION) + "?name=Test group";
assertResultsPresentInDataResponse(url, group1.getId());
// Test based on name like
url = RestUrls.createRelativeResourceUrl(RestUrls.URL_GROUP_COLLECTION) +"?nameLike=" + encode("% group");
assertResultsPresentInDataResponse(url, group2.getId(), group1.getId());
// Test based on type
url = RestUrls.createRelativeResourceUrl(RestUrls.URL_GROUP_COLLECTION) +"?type=Another type";
assertResultsPresentInDataResponse(url, group2.getId());
// Test based on group member
url = RestUrls.createRelativeResourceUrl(RestUrls.URL_GROUP_COLLECTION) + "?member=kermit";
assertResultsPresentInDataResponse(url, group3.getId());
// Test based on potentialStarter
String processDefinitionId = repositoryService.createProcessDefinitionQuery().processDefinitionKey("simpleProcess")
.singleResult().getId();
repositoryService.addCandidateStarterGroup(processDefinitionId, "admin");
url = RestUrls.createRelativeResourceUrl(RestUrls.URL_GROUP_COLLECTION) + "?potentialStarter=" + processDefinitionId;
assertResultsPresentInDataResponse(url, group3.getId());
} finally {
// Delete groups after test passes or fails
if(savedGroups.size() > 0) {
for(Group group : savedGroups) {
identityService.deleteGroup(group.getId());
}
}
}
}
public void testCreateGroup() throws Exception {
try {
ObjectNode requestNode = objectMapper.createObjectNode();
requestNode.put("id", "testgroup");
requestNode.put("name", "Test group");
requestNode.put("type", "Test type");
ClientResource client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(RestUrls.URL_GROUP_COLLECTION));
Representation response = client.post(requestNode);
assertEquals(Status.SUCCESS_CREATED, client.getResponse().getStatus());
JsonNode responseNode = objectMapper.readTree(response.getStream());
assertNotNull(responseNode);
assertEquals("testgroup", responseNode.get("id").getTextValue());
assertEquals("Test group", responseNode.get("name").getTextValue());
assertEquals("Test type", responseNode.get("type").getTextValue());
assertTrue(responseNode.get("url").getTextValue().endsWith(RestUrls.createRelativeResourceUrl(RestUrls.URL_GROUP, "testgroup")));
assertNotNull(identityService.createGroupQuery().groupId("testgroup").singleResult());
} finally {
try {
identityService.deleteGroup("testgroup");
} catch(Throwable t) {
// Ignore, user might not have been created by test
}
}
}
public void testCreateGroupExceptions() throws Exception {
ClientResource client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(RestUrls.URL_GROUP_COLLECTION));
// Create without ID
ObjectNode requestNode = objectMapper.createObjectNode();
requestNode.put("name", "Test group");
requestNode.put("type", "Test type");
try {
client.post(requestNode);
fail("Exception expected");
} catch(ResourceException expected) {
assertEquals(Status.CLIENT_ERROR_BAD_REQUEST, expected.getStatus());
assertEquals("Id cannot be null.", expected.getStatus().getDescription());
}
// Create when group already exists
requestNode = objectMapper.createObjectNode();
requestNode.put("id", "admin");
try {
client.post(requestNode);
fail("Exception expected");
} catch(ResourceException expected) {
assertEquals(Status.CLIENT_ERROR_CONFLICT, expected.getStatus());
assertEquals("A group with id 'admin' already exists.", expected.getStatus().getDescription());
}
}
}
/* 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.identity;
import org.activiti.engine.identity.Group;
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;
/**
* @author Frederik Heremans
*/
public class GroupResourceTest extends BaseRestTestCase {
/**
* Test getting a single group.
*/
public void testGetGroup() throws Exception {
try {
Group testGroup = identityService.newGroup("testgroup");
testGroup.setName("Test group");
testGroup.setType("Test type");
identityService.saveGroup(testGroup);
ClientResource client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(RestUrls.URL_GROUP, "testgroup"));
Representation response = client.get();
assertEquals(Status.SUCCESS_OK, client.getResponse().getStatus());
JsonNode responseNode = objectMapper.readTree(response.getStream());
assertNotNull(responseNode);
assertEquals("testgroup", responseNode.get("id").getTextValue());
assertEquals("Test group", responseNode.get("name").getTextValue());
assertEquals("Test type", responseNode.get("type").getTextValue());
assertTrue(responseNode.get("url").getTextValue().endsWith(RestUrls.createRelativeResourceUrl(
RestUrls.URL_GROUP, testGroup.getId())));
Group createdGroup = identityService.createGroupQuery().groupId("testgroup").singleResult();
assertNotNull(createdGroup);
assertEquals("Test group", createdGroup.getName());
assertEquals("Test type", createdGroup.getType());
} finally {
try {
identityService.deleteGroup("testgroup");
} catch(Throwable ignore) {
// Ignore, since the group may not have been created in the test
// or already deleted
}
}
}
/**
* Test getting an unexisting group.
*/
public void testGetUnexistingGroup() throws Exception {
ClientResource client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(RestUrls.URL_GROUP, "unexisting"));
try {
client.get();
fail("Exception expected");
} catch(ResourceException expected) {
assertEquals(Status.CLIENT_ERROR_NOT_FOUND, expected.getStatus());
assertEquals("Could not find a group with id 'unexisting'.", expected.getStatus().getDescription());
}
}
/**
* Test deleting a single group.
*/
public void testDeleteGroup() throws Exception {
try {
Group testGroup = identityService.newGroup("testgroup");
testGroup.setName("Test group");
testGroup.setType("Test type");
identityService.saveGroup(testGroup);
ClientResource client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(RestUrls.URL_GROUP, "testgroup"));
Representation response = client.delete();
assertEquals(Status.SUCCESS_NO_CONTENT, client.getResponse().getStatus());
assertEquals(0, response.getSize());
assertNull(identityService.createGroupQuery().groupId("testgroup").singleResult());
} finally {
try {
identityService.deleteGroup("testgroup");
} catch(Throwable ignore) {
// Ignore, since the group may not have been created in the test
// or already deleted
}
}
}
/**
* Test deleting an unexisting group.
*/
public void testDeleteUnexistingGroup() throws Exception {
ClientResource client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(RestUrls.URL_GROUP, "unexisting"));
try {
client.delete();
fail("Exception expected");
} catch(ResourceException expected) {
assertEquals(Status.CLIENT_ERROR_NOT_FOUND, expected.getStatus());
assertEquals("Could not find a group with id 'unexisting'.", expected.getStatus().getDescription());
}
}
/**
* Test updating a single group.
*/
public void testUpdateGroup() throws Exception {
try {
Group testGroup = identityService.newGroup("testgroup");
testGroup.setName("Test group");
testGroup.setType("Test type");
identityService.saveGroup(testGroup);
ClientResource client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(RestUrls.URL_GROUP, "testgroup"));
ObjectNode requestNode = objectMapper.createObjectNode();
requestNode.put("name", "Updated group");
requestNode.put("type", "Updated type");
Representation response = client.put(requestNode);
assertEquals(Status.SUCCESS_OK, client.getResponse().getStatus());
JsonNode responseNode = objectMapper.readTree(response.getStream());
assertNotNull(responseNode);
assertEquals("testgroup", responseNode.get("id").getTextValue());
assertEquals("Updated group", responseNode.get("name").getTextValue());
assertEquals("Updated type", responseNode.get("type").getTextValue());
assertTrue(responseNode.get("url").getTextValue().endsWith(RestUrls.createRelativeResourceUrl(
RestUrls.URL_GROUP, testGroup.getId())));
Group createdGroup = identityService.createGroupQuery().groupId("testgroup").singleResult();
assertNotNull(createdGroup);
assertEquals("Updated group", createdGroup.getName());
assertEquals("Updated type", createdGroup.getType());
} finally {
try {
identityService.deleteGroup("testgroup");
} catch(Throwable ignore) {
// Ignore, since the group may not have been created in the test
// or already deleted
}
}
}
/**
* Test updating a single group passing in no fields in the json, user should remain unchanged.
*/
public void testUpdateGroupNoFields() throws Exception {
try {
Group testGroup = identityService.newGroup("testgroup");
testGroup.setName("Test group");
testGroup.setType("Test type");
identityService.saveGroup(testGroup);
ClientResource client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(RestUrls.URL_GROUP, "testgroup"));
ObjectNode requestNode = objectMapper.createObjectNode();
Representation response = client.put(requestNode);
assertEquals(Status.SUCCESS_OK, client.getResponse().getStatus());
JsonNode responseNode = objectMapper.readTree(response.getStream());
assertNotNull(responseNode);
assertEquals("testgroup", responseNode.get("id").getTextValue());
assertEquals("Test group", responseNode.get("name").getTextValue());
assertEquals("Test type", responseNode.get("type").getTextValue());
assertTrue(responseNode.get("url").getTextValue().endsWith(RestUrls.createRelativeResourceUrl(
RestUrls.URL_GROUP, testGroup.getId())));
Group createdGroup = identityService.createGroupQuery().groupId("testgroup").singleResult();
assertNotNull(createdGroup);
assertEquals("Test group", createdGroup.getName());
assertEquals("Test type", createdGroup.getType());
} finally {
try {
identityService.deleteGroup("testgroup");
} catch(Throwable ignore) {
// Ignore, since the group may not have been created in the test
// or already deleted
}
}
}
/**
* Test updating a single user passing in null-values.
*/
public void testUpdateGroupNullFields() throws Exception {
try {
Group testGroup = identityService.newGroup("testgroup");
testGroup.setName("Test group");
testGroup.setType("Test type");
identityService.saveGroup(testGroup);
ClientResource client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(RestUrls.URL_GROUP, "testgroup"));
ObjectNode requestNode = objectMapper.createObjectNode();
requestNode.put("name", (JsonNode) null);
requestNode.put("type",(JsonNode) null);
Representation response = client.put(requestNode);
assertEquals(Status.SUCCESS_OK, client.getResponse().getStatus());
JsonNode responseNode = objectMapper.readTree(response.getStream());
assertNotNull(responseNode);
assertEquals("testgroup", responseNode.get("id").getTextValue());
assertNull(responseNode.get("name").getTextValue());
assertNull(responseNode.get("type").getTextValue());
assertTrue(responseNode.get("url").getTextValue().endsWith(RestUrls.createRelativeResourceUrl(
RestUrls.URL_GROUP, testGroup.getId())));
Group createdGroup = identityService.createGroupQuery().groupId("testgroup").singleResult();
assertNotNull(createdGroup);
assertNull(createdGroup.getName());
assertNull(createdGroup.getType());
} finally {
try {
identityService.deleteGroup("testgroup");
} catch(Throwable ignore) {
// Ignore, since the group may not have been created in the test
// or already deleted
}
}
}
/**
* Test updating an unexisting group.
*/
public void testUpdateUnexistingGroup() throws Exception {
ClientResource client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(RestUrls.URL_GROUP, "unexisting"));
try {
client.put(objectMapper.createObjectNode());
fail("Exception expected");
} catch(ResourceException expected) {
assertEquals(Status.CLIENT_ERROR_NOT_FOUND, expected.getStatus());
assertEquals("Could not find a group with id 'unexisting'.", expected.getStatus().getDescription());
}
}
}
...@@ -133,6 +133,7 @@ public class UserCollectionResourceTest extends BaseRestTestCase { ...@@ -133,6 +133,7 @@ public class UserCollectionResourceTest extends BaseRestTestCase {
assertEquals("no-reply@activiti.org", responseNode.get("email").getTextValue()); assertEquals("no-reply@activiti.org", responseNode.get("email").getTextValue());
assertTrue(responseNode.get("url").getTextValue().endsWith(RestUrls.createRelativeResourceUrl(RestUrls.URL_USER, "testuser"))); assertTrue(responseNode.get("url").getTextValue().endsWith(RestUrls.createRelativeResourceUrl(RestUrls.URL_USER, "testuser")));
assertNotNull(identityService.createUserQuery().userId("testuser").singleResult());
} finally { } finally {
try { try {
identityService.deleteUser("testuser"); identityService.deleteUser("testuser");
......
<?xml version="1.0" encoding="UTF-8"?>
<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://www.activiti.org/test">
<process id="simpleProcess" name="Simple process" isExecutable="true">
<startEvent id="start" name="Start JUnit"></startEvent>
<sequenceFlow id="flow1" name="" sourceRef="start" targetRef="waitTask"></sequenceFlow>
<userTask id="waitTask" name="WaitTask" activiti:assignee="me" />
<sequenceFlow id="flow2" sourceRef="waitTask" targetRef="anotherTask"></sequenceFlow>
<userTask id="anotherTask" name="AnotherTask" activiti:assignee="me" />
<sequenceFlow id="flow3" sourceRef="anotherTask" targetRef="end"></sequenceFlow>
<endEvent id="end" name="End JUnit"></endEvent>
</process>
</definitions>
\ No newline at end of file
...@@ -4585,7 +4585,6 @@ Only the attachment name is required to create a new attachment. ...@@ -4585,7 +4585,6 @@ Only the attachment name is required to create a new attachment.
{ {
"firstName":"Tijs", "firstName":"Tijs",
"lastName":"Barrez", "lastName":"Barrez",
"url":"http://localhost:8182/identity/users/anotherUser",
"email":"no-reply@alfresco.org" "email":"no-reply@alfresco.org"
}</programlisting> }</programlisting>
All request values are optional. For example, you can only include the 'firstName' attribute in the request body JSON-object, only updating the firstName of the user, leaving all other fields unaffected. When an attribute is explicitly included and is set to null, the user-value will be updated to null. Example: <literal>{"firstName" : null}</literal> will clear the firstName of the user). All request values are optional. For example, you can only include the 'firstName' attribute in the request body JSON-object, only updating the firstName of the user, leaving all other fields unaffected. When an attribute is explicitly included and is set to null, the user-value will be updated to null. Example: <literal>{"firstName" : null}</literal> will clear the firstName of the user).
...@@ -4625,7 +4624,7 @@ Only the attachment name is required to create a new attachment. ...@@ -4625,7 +4624,7 @@ Only the attachment name is required to create a new attachment.
<section> <section>
<title>Create a user</title> <title>Create a user</title>
<para> <para>
<programlisting>POST identity/users/</programlisting> <programlisting>POST identity/users</programlisting>
</para> </para>
<para> <para>
<emphasis role="bold">Body JSON:</emphasis> <emphasis role="bold">Body JSON:</emphasis>
...@@ -4634,10 +4633,8 @@ Only the attachment name is required to create a new attachment. ...@@ -4634,10 +4633,8 @@ Only the attachment name is required to create a new attachment.
"id":"tijs", "id":"tijs",
"firstName":"Tijs", "firstName":"Tijs",
"lastName":"Barrez", "lastName":"Barrez",
"url":"http://localhost:8182/identity/users/anotherUser",
"email":"no-reply@alfresco.org" "email":"no-reply@alfresco.org"
}</programlisting> }</programlisting>
All request values are optional. For example, you can only include the 'firstName' attribute in the request body JSON-object, only updating the firstName of the user, leaving all other fields unaffected. When an attribute is explicitly included and is set to null, the user-value will be updated to null. Example: <literal>{"firstName" : null}</literal> will clear the firstName of the user).
</para> </para>
<para> <para>
<table> <table>
...@@ -5180,7 +5177,310 @@ Only the attachment name is required to create a new attachment. ...@@ -5180,7 +5177,310 @@ Only the attachment name is required to create a new attachment.
</section> </section>
</section> </section>
<section>
<title>Groups</title>
<section>
<title>Get a single group</title>
<para>
<programlisting>GET identity/groups/{groupId}</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>groupId</entry>
<entry>Yes</entry>
<entry>String</entry>
<entry>The id of the group to get.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<emphasis role="bold">Success response body:</emphasis>
<programlisting>
{
"id":"testgroup",
"url":"http://localhost:8182/identity/groups/testgroup",
"name":"Test group",
"type":"Test type"
}</programlisting>
<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 group exists and is returned.</entry>
</row>
<row>
<entry>404</entry>
<entry>Indicates the requested group does not exist.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
</section>
<section>
<title>Get a list of groups</title>
<para>
<programlisting>GET identity/groups</programlisting>
</para>
<para>
<table>
<title>URL query parameters</title>
<tgroup cols='2'>
<thead>
<row>
<entry>Parameter</entry>
<entry>Description</entry>
<entry>Type</entry>
</row>
</thead>
<tbody>
<row>
<entry>id</entry>
<entry>Only return group with the given id</entry>
<entry>String</entry>
</row>
<row>
<entry>name</entry>
<entry>Only return groups with the given name</entry>
<entry>String</entry>
</row>
<row>
<entry>type</entry>
<entry>Only return groups with the given type</entry>
<entry>String</entry>
</row>
<row>
<entry>nameLike</entry>
<entry>Only return groups with a name like the given value. Use <literal>%</literal> as wildcard-character.</entry>
<entry>String</entry>
</row>
<row>
<entry>member</entry>
<entry>Only return groups which have a member with the given username.</entry>
<entry>String</entry>
</row>
<row>
<entry>potentialStarter</entry>
<entry>Only return groups which members are potential starters for a process-definition with the given id.</entry>
<entry>String</entry>
</row>
<row>
<entry>sort</entry>
<entry>Field to sort results on, should be one of <literal>id</literal>, <literal>name</literal> or <literal>type</literal>.</entry>
<entry>String</entry>
</row>
<row>
<entry namest="c1" nameend="c3"><para>The general <link linkend="restPagingAndSort">paging and sorting query-parameters</link> can be used for this URL.</para></entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<emphasis role="bold">Success response body:</emphasis>
<programlisting>
{
"data":[
{
"id":"testgroup",
"url":"http://localhost:8182/identity/groups/testgroup",
"name":"Test group",
"type":"Test type"
},
...
],
"total":3,
"start":0,
"sort":"id",
"order":"asc",
"size":3
}</programlisting>
<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 requested groups were returned.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
</section>
<section>
<title>Update a group</title>
<para>
<programlisting>PUT identity/groups/{groupId}</programlisting>
</para>
<para>
<emphasis role="bold">Body JSON:</emphasis>
<programlisting>
{
"name":"Test group",
"type":"Test type"
}</programlisting>
All request values are optional. For example, you can only include the 'name' attribute in the request body JSON-object, only updating the name of the group, leaving all other fields unaffected. When an attribute is explicitly included and is set to null, the group-value will be updated to null.
</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 group was updated.</entry>
</row>
<row>
<entry>404</entry>
<entry>Indicates the requested group was not found.</entry>
</row>
<row>
<entry>409</entry>
<entry>Indicates the requested group was updated simultaneously.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<emphasis role="bold">Success response body:</emphasis> see response for <literal>identity/groups/{groupId}</literal>.
</para>
</section>
<section>
<title>Create a group</title>
<para>
<programlisting>POST identity/groups</programlisting>
</para>
<para>
<emphasis role="bold">Body JSON:</emphasis>
<programlisting>
{
"id":"testgroup",
"name":"Test group",
"type":"Test type"
}</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 group was created.</entry>
</row>
<row>
<entry>400</entry>
<entry>Indicates the id of the group was missing.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<emphasis role="bold">Success response body:</emphasis> see response for <literal>identity/groups/{groupId}</literal>.
</para>
</section>
<section>
<title>Delete a group</title>
<para>
<programlisting>DELETE identity/groups/{groupId}</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>groupId</entry>
<entry>Yes</entry>
<entry>String</entry>
<entry>The id of the group to delete.</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 group was found and has been deleted. Response-body is intentionally empty.</entry>
</row>
<row>
<entry>404</entry>
<entry>Indicates the requested group was not found.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
</section>
</section>
<!-- Legacy --> <!-- Legacy -->
<section> <section>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册