clean up REST API parameters usage around roles and permissions.

This commit is contained in:
Keith Woodlock
2012-11-12 12:12:42 +00:00
parent 2c92635ced
commit cd2e71ed75
7 changed files with 68 additions and 107 deletions
@@ -35,10 +35,10 @@ public class PermissionsApiResource {
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public String retrieveAllPermissions(@Context final UriInfo uriInfo) { public String retrieveAllPermissions(@Context final UriInfo uriInfo) {
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
Collection<PermissionData> permissions = this.permissionReadPlatformService.retrieveAllPermissions(); final Collection<PermissionData> permissions = this.permissionReadPlatformService.retrieveAllPermissions();
return this.apiJsonSerializerService.serializePermissionDataToJson(prettyPrint, responseParameters, permissions); return this.apiJsonSerializerService.serializePermissionDataToJson(prettyPrint, responseParameters, permissions);
} }
@@ -1,9 +1,7 @@
package org.mifosng.platform.api; package org.mifosng.platform.api;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
@@ -13,10 +11,8 @@ import javax.ws.rs.PUT;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.PathParam; import javax.ws.rs.PathParam;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context; import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.mifosng.platform.api.commands.RoleCommand; import org.mifosng.platform.api.commands.RoleCommand;
@@ -58,15 +54,10 @@ public class RolesApiResource {
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public String retrieveAllRoles(@Context final UriInfo uriInfo) { public String retrieveAllRoles(@Context final UriInfo uriInfo) {
Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "name", "description")); final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); final Collection<RoleData> roles = this.roleReadPlatformService.retrieveAllRoles();
if (responseParameters.isEmpty()) {
responseParameters.addAll(typicalResponseParameters);
}
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
Collection<RoleData> roles = this.roleReadPlatformService.retrieveAllRoles();
return this.apiJsonSerializerService.serializeRoleDataToJson(prettyPrint, responseParameters, roles); return this.apiJsonSerializerService.serializeRoleDataToJson(prettyPrint, responseParameters, roles);
} }
@@ -77,17 +68,12 @@ public class RolesApiResource {
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public String retrieveNewRoleDetails(@Context final UriInfo uriInfo) { public String retrieveNewRoleDetails(@Context final UriInfo uriInfo) {
Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "name", "description", "availablePermissions", "selectedPermissions")); final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); final Collection<PermissionData> allPermissions = this.permissionReadPlatformService.retrieveAllPermissions();
if (responseParameters.isEmpty()) {
responseParameters.addAll(typicalResponseParameters);
}
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
Collection<PermissionData> allPermissions = this.permissionReadPlatformService.retrieveAllPermissions(); final RoleData role = new RoleData(allPermissions, new ArrayList<PermissionData>());
RoleData role = new RoleData(allPermissions, new ArrayList<PermissionData>());
return this.apiJsonSerializerService.serializeRoleDataToJson(prettyPrint, responseParameters, role); return this.apiJsonSerializerService.serializeRoleDataToJson(prettyPrint, responseParameters, role);
} }
@@ -95,40 +81,36 @@ public class RolesApiResource {
@POST @POST
@Consumes({MediaType.APPLICATION_JSON}) @Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public Response createRole(final String jsonRequestBody) { public String createRole(final String jsonRequestBody) {
RoleCommand command = this.apiDataConversionService.convertJsonToRoleCommand(null, jsonRequestBody); final RoleCommand command = this.apiDataConversionService.convertJsonToRoleCommand(null, jsonRequestBody);
Long roleId = this.roleWritePlatformService.createRole(command); final Long roleId = this.roleWritePlatformService.createRole(command);
return Response.ok().entity(new EntityIdentifier(roleId)).build(); return this.apiJsonSerializerService.serializeEntityIdentifier(new EntityIdentifier(roleId));
} }
// TODO - General thing to fix about REST API is if use partial response approach of fields=id,name,selectedPermissions
// It will return just id,name parameters of RoleData and ignore description, however as PermissionData used in selectedPermissions collection
// also has a field called description it gets ignored also. This is because of the implementation of ParameterListExclusionStrategy which doesnt take
// into account the Object its looking at.
@GET @GET
@Path("{roleId}") @Path("{roleId}")
@Consumes({MediaType.APPLICATION_JSON}) @Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public String retrieveRole(@PathParam("roleId") final Long roleId, @Context final UriInfo uriInfo) { public String retrieveRole(@PathParam("roleId") final Long roleId, @Context final UriInfo uriInfo) {
Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "name", "description")); final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); final boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) {
responseParameters.addAll(typicalResponseParameters);
}
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters());
RoleData role = this.roleReadPlatformService.retrieveRole(roleId); RoleData role = this.roleReadPlatformService.retrieveRole(roleId);
if (template) { if (template) {
Collection<PermissionData> availablePermissions = this.permissionReadPlatformService.retrieveAllPermissions(); final Collection<PermissionData> availablePermissions = this.permissionReadPlatformService.retrieveAllPermissions();
availablePermissions.removeAll(role.getSelectedPermissions()); availablePermissions.removeAll(role.selectedPermissions());
role = new RoleData(role, availablePermissions); role = new RoleData(role, availablePermissions);
responseParameters.add("availablePermissions");
responseParameters.add("selectedPermissions");
} }
return this.apiJsonSerializerService.serializeRoleDataToJson(prettyPrint, responseParameters, role); return this.apiJsonSerializerService.serializeRoleDataToJson(prettyPrint, responseParameters, role);
} }
@@ -137,13 +119,13 @@ public class RolesApiResource {
@Path("{roleId}") @Path("{roleId}")
@Consumes({MediaType.APPLICATION_JSON}) @Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public Response updateRole(@PathParam("roleId") final Long roleId, final String jsonRequestBody) { public String updateRole(@PathParam("roleId") final Long roleId, final String jsonRequestBody) {
RoleCommand command = this.apiDataConversionService.convertJsonToRoleCommand(roleId, jsonRequestBody); final RoleCommand command = this.apiDataConversionService.convertJsonToRoleCommand(roleId, jsonRequestBody);
this.roleWritePlatformService.updateRole(command); this.roleWritePlatformService.updateRole(command);
return Response.ok().entity(new EntityIdentifier(roleId)).build(); return this.apiJsonSerializerService.serializeEntityIdentifier(new EntityIdentifier(roleId));
} }
/* /*
@@ -5,8 +5,11 @@ package org.mifosng.platform.api.data;
*/ */
public class PermissionData { public class PermissionData {
@SuppressWarnings("unused")
private final Long id; private final Long id;
@SuppressWarnings("unused")
private final String name; private final String name;
@SuppressWarnings("unused")
private final String description; private final String description;
private final String code; private final String code;
@@ -27,20 +30,4 @@ public class PermissionData {
public int hashCode() { public int hashCode() {
return this.code.hashCode(); return this.code.hashCode();
} }
public Long getId() {
return id;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public String getCode() {
return code;
}
} }
@@ -12,17 +12,25 @@ public class RoleData {
private final String name; private final String name;
private final String description; private final String description;
@SuppressWarnings("unused")
private final Collection<PermissionData> availablePermissions; private final Collection<PermissionData> availablePermissions;
private final Collection<PermissionData> selectedPermissions; private final Collection<PermissionData> selectedPermissions;
public RoleData(final Long id, final String name, final String description) {
this.id = id;
this.name = name;
this.description = description;
this.availablePermissions = null;
this.selectedPermissions = null;
}
public RoleData(final Long id, final String name, final String description, final Collection<PermissionData> selectedPermissions) { public RoleData(final Long id, final String name, final String description, final Collection<PermissionData> selectedPermissions) {
this.id = id; this.id = id;
this.name = name; this.name = name;
this.description = description; this.description = description;
this.availablePermissions = new ArrayList<PermissionData>(); this.availablePermissions = null;
this.selectedPermissions = new ArrayList<PermissionData>(selectedPermissions); this.selectedPermissions = selectedPermissions;
} }
public RoleData(final Collection<PermissionData> availablePermissions, final Collection<PermissionData> selectedPermissions) { public RoleData(final Collection<PermissionData> availablePermissions, final Collection<PermissionData> selectedPermissions) {
this.id = null; this.id = null;
this.name = null; this.name = null;
@@ -31,18 +39,18 @@ public class RoleData {
this.selectedPermissions = new ArrayList<PermissionData>(selectedPermissions); this.selectedPermissions = new ArrayList<PermissionData>(selectedPermissions);
} }
public RoleData(RoleData role, final Collection<PermissionData> availablePermissions) { public RoleData(final RoleData role, final Collection<PermissionData> availablePermissions) {
this.id = role.getId(); this.id = role.id;
this.name = role.getName(); this.name = role.name;
this.description = role.getDescription(); this.description = role.description;
this.availablePermissions = new ArrayList<PermissionData>(availablePermissions); this.availablePermissions = availablePermissions;
this.selectedPermissions = role.getSelectedPermissions(); this.selectedPermissions = role.selectedPermissions;
} }
@Override @Override
public boolean equals(final Object obj) { public boolean equals(final Object obj) {
RoleData role = (RoleData) obj; final RoleData role = (RoleData) obj;
return this.id.equals(role.getId()); return this.id.equals(role.id);
} }
@Override @Override
@@ -50,23 +58,7 @@ public class RoleData {
return this.id.hashCode(); return this.id.hashCode();
} }
public Long getId() { public Collection<PermissionData> selectedPermissions() {
return id; return this.selectedPermissions;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public Collection<PermissionData> getAvailablePermissions() {
return availablePermissions;
}
public Collection<PermissionData> getSelectedPermissions() {
return selectedPermissions;
} }
} }
@@ -5,6 +5,10 @@ import java.util.Set;
import com.google.gson.ExclusionStrategy; import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes; import com.google.gson.FieldAttributes;
// FIXME - KW - General thing to fix about REST API is if use partial response approach of fields=id,name,selectedPermissions
// It will return just id,name parameters of RoleData and ignore description, however as PermissionData used in selectedPermissions collection
// also has a field called description it gets ignored also. This is because of the implementation of ParameterListExclusionStrategy which doesnt take
// into account the Object its looking at.
public class ParameterListExclusionStrategy implements ExclusionStrategy { public class ParameterListExclusionStrategy implements ExclusionStrategy {
private final Set<String> parameterNamesToSkip; private final Set<String> parameterNamesToSkip;
@@ -23,5 +27,4 @@ public class ParameterListExclusionStrategy implements ExclusionStrategy {
public boolean shouldSkipClass(Class<?> clazz) { public boolean shouldSkipClass(Class<?> clazz) {
return false; return false;
} }
} }
@@ -30,8 +30,8 @@ public class PermissionReadPlatformServiceImpl implements PermissionReadPlatform
context.authenticatedUser(); context.authenticatedUser();
PermissionMapper mapper = new PermissionMapper(); final PermissionMapper mapper = new PermissionMapper();
String sql = "select " + mapper.schema() + " order by p.id"; final String sql = "select " + mapper.schema() + " order by p.id";
return this.jdbcTemplate.query(sql, mapper, new Object[] {}); return this.jdbcTemplate.query(sql, mapper, new Object[] {});
} }
@@ -41,10 +41,10 @@ public class PermissionReadPlatformServiceImpl implements PermissionReadPlatform
@Override @Override
public PermissionData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { public PermissionData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
Long id = JdbcSupport.getLong(rs, "id"); final Long id = JdbcSupport.getLong(rs, "id");
String name = rs.getString("name"); final String name = rs.getString("name");
String description = rs.getString("description"); final String description = rs.getString("description");
String code = rs.getString("code"); final String code = rs.getString("code");
return new PermissionData(id, name, description, code); return new PermissionData(id, name, description, code);
} }
@@ -2,10 +2,8 @@ package org.mifosng.platform.user.service;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import org.mifosng.platform.api.data.PermissionData;
import org.mifosng.platform.api.data.RoleData; import org.mifosng.platform.api.data.RoleData;
import org.mifosng.platform.exceptions.RoleNotFoundException; import org.mifosng.platform.exceptions.RoleNotFoundException;
import org.mifosng.platform.infrastructure.JdbcSupport; import org.mifosng.platform.infrastructure.JdbcSupport;
@@ -36,8 +34,8 @@ public class RoleReadPlatformServiceImpl implements RoleReadPlatformService {
public Collection<RoleData> retrieveAllRoles() { public Collection<RoleData> retrieveAllRoles() {
context.authenticatedUser(); context.authenticatedUser();
RoleMapper mapper = new RoleMapper(); final RoleMapper mapper = new RoleMapper();
String sql = "select " + mapper.schema() + " order by r.id"; final String sql = "select " + mapper.schema() + " order by r.id";
return this.jdbcTemplate.query(sql, mapper, new Object[] {}); return this.jdbcTemplate.query(sql, mapper, new Object[] {});
} }
@@ -46,7 +44,7 @@ public class RoleReadPlatformServiceImpl implements RoleReadPlatformService {
public RoleData retrieveRole(final Long id) { public RoleData retrieveRole(final Long id) {
context.authenticatedUser(); context.authenticatedUser();
Role role = this.roleRepository.findOne(id); final Role role = this.roleRepository.findOne(id);
if (role == null) { if (role == null) {
throw new RoleNotFoundException(id); throw new RoleNotFoundException(id);
} }
@@ -59,12 +57,11 @@ public class RoleReadPlatformServiceImpl implements RoleReadPlatformService {
public RoleData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) public RoleData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum)
throws SQLException { throws SQLException {
Long id = JdbcSupport.getLong(rs, "id"); final Long id = JdbcSupport.getLong(rs, "id");
String name = rs.getString("name"); final String name = rs.getString("name");
String description = rs.getString("description"); final String description = rs.getString("description");
Collection<PermissionData> selectedPermissions = new ArrayList<PermissionData>(0); return new RoleData(id, name, description);
return new RoleData(id, name, description, selectedPermissions);
} }
public String schema() { public String schema() {