FIXED MIFOSX-13: Create basic API for @GET and @PUT of groups.

This commit is contained in:
Michal Dudzinski
2012-08-03 10:18:55 +01:00
committed by Keith Woodlock
parent 2bda0e8764
commit df13eb60da
12 changed files with 307 additions and 5 deletions
@@ -1,15 +1,28 @@
package org.mifosng.platform.api;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.mifosng.platform.api.commands.GroupCommand;
import org.mifosng.platform.api.data.EntityIdentifier;
import org.mifosng.platform.api.data.GroupData;
import org.mifosng.platform.api.infrastructure.ApiDataConversionService;
import org.mifosng.platform.api.infrastructure.ApiParameterHelper;
import org.mifosng.platform.group.service.GroupReadPlatformService;
import org.mifosng.platform.group.service.GroupWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
@@ -20,21 +33,79 @@ import org.springframework.stereotype.Component;
@Scope("singleton")
public class GroupsApiResource {
@Autowired
private GroupReadPlatformService groupReadPlatformService;
@Autowired
private GroupWritePlatformService groupWritePlatformService;
@Autowired
private ApiDataConversionService apiDataConversionService;
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAllGroups(@Context final UriInfo uriInfo){
Set<String> typicalResponseParameters = new HashSet<String>(
Arrays.asList("id", "name", "externalId")
);
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) {
responseParameters.addAll(typicalResponseParameters);
}
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
Collection<GroupData> groups = this.groupReadPlatformService.retrieveAllGroups();
return this.apiDataConversionService.convertGroupDataToJson(prettyPrint, responseParameters, groups.toArray(new GroupData[groups.size()]));
}
@GET
@Path("{groupId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveGroupData(@PathParam("groupId") final Long groupId, @Context final UriInfo uriInfo) {
Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "name", "externalId"));
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo
.getQueryParameters());
if (responseParameters.isEmpty()) {
responseParameters.addAll(typicalResponseParameters);
}
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
GroupData group = this.groupReadPlatformService.retrieveGroup(groupId);
return this.apiDataConversionService.convertGroupDataToJson(prettyPrint, responseParameters, group);
}
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public Response createGroup(final String jsonRequestBody) {
final GroupCommand command = this.apiDataConversionService.convertJsonToGroupCommand(null, jsonRequestBody);
EntityIdentifier entityIdentifier = this.groupWritePlatformService.createGroup(command);
return Response.ok().entity(entityIdentifier).build();
}
@PUT
@Path("{groupId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public Response updateGroup(@PathParam("groupId") final Long groupId, final String jsonRequestBody) {
final GroupCommand command = this.apiDataConversionService.convertJsonToGroupCommand(groupId, jsonRequestBody);
EntityIdentifier entityIdentifier = this.groupWritePlatformService.updateGroup(command);
return Response.ok().entity(entityIdentifier).build();
}
@@ -4,12 +4,14 @@ import java.util.Set;
public class GroupCommand {
private final Long id;
private final String externalId;
private final String name;
private final Set<String> modifiedParameters;
public GroupCommand(Set<String> modifiedParameters, String externalId, String name) {
public GroupCommand(Set<String> modifiedParameters, final Long id, String externalId, String name) {
this.id = id;
this.externalId = externalId;
this.name = name;
this.modifiedParameters = modifiedParameters;
@@ -23,4 +25,16 @@ public class GroupCommand {
return name;
}
public Long getId() {
return id;
}
public boolean isNameChanged() {
return this.modifiedParameters.contains("name");
}
public boolean isExternalIdChanged() {
return this.modifiedParameters.contains("externalId");
}
}
@@ -0,0 +1,28 @@
package org.mifosng.platform.api.data;
public class GroupData {
private final Long id;
private final String name;
private final String externalId;
public GroupData(Long id, String name, String externalId) {
super();
this.id = id;
this.name = name;
this.externalId = externalId;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public String getExternalId() {
return externalId;
}
}
@@ -25,6 +25,7 @@ import org.mifosng.platform.api.data.ClientLoanAccountSummaryCollectionData;
import org.mifosng.platform.api.data.ConfigurationData;
import org.mifosng.platform.api.data.FundData;
import org.mifosng.platform.api.data.GenericResultsetData;
import org.mifosng.platform.api.data.GroupData;
import org.mifosng.platform.api.data.LoanAccountData;
import org.mifosng.platform.api.data.LoanProductData;
import org.mifosng.platform.api.data.LoanTransactionData;
@@ -54,6 +55,8 @@ public interface ApiDataConversionService {
String convertClientLoanAccountSummaryCollectionDataToJson(boolean prettyPrint, Set<String> responseParameters,
ClientLoanAccountSummaryCollectionData clientAccountsData);
String convertGroupDataToJson(boolean prettyPrint, Set<String> responseParameters, GroupData... groups);
String convertNoteDataToJson(boolean prettyPrint, Set<String> responseParameters, NoteData... notes);
String convertLoanProductDataToJson(boolean prettyPrint, Set<String> responseParameters, LoanProductData... products);
@@ -42,6 +42,7 @@ import org.mifosng.platform.api.data.ClientLoanAccountSummaryCollectionData;
import org.mifosng.platform.api.data.ConfigurationData;
import org.mifosng.platform.api.data.FundData;
import org.mifosng.platform.api.data.GenericResultsetData;
import org.mifosng.platform.api.data.GroupData;
import org.mifosng.platform.api.data.LoanAccountData;
import org.mifosng.platform.api.data.LoanProductData;
import org.mifosng.platform.api.data.LoanTransactionData;
@@ -373,6 +374,40 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
}
@Override
public String convertGroupDataToJson(boolean prettyPrint, Set<String> responseParameters, GroupData... groups) {
final Set<String> supportedParameters = new HashSet<String>(
Arrays.asList("id", "name", "externalId")
);
final Set<String> parameterNamesToSkip = new HashSet<String>();
if (!responseParameters.isEmpty()) {
if (!supportedParameters.containsAll(responseParameters)) {
throw new UnsupportedParameterException(new ArrayList<String>(responseParameters));
}
parameterNamesToSkip.addAll(supportedParameters);
parameterNamesToSkip.removeAll(responseParameters);
}
ExclusionStrategy strategy = new ParameterListExclusionStrategy(parameterNamesToSkip);
GsonBuilder builder = new GsonBuilder().addSerializationExclusionStrategy(strategy);
if (prettyPrint) {
builder.setPrettyPrinting();
}
Gson gsonDeserializer = builder.create();
String json = "";
if (groups != null && groups.length == 1) {
json = gsonDeserializer.toJson(groups[0]);
} else {
json = gsonDeserializer.toJson(groups);
}
return json;
}
@Override
public String convertConfigurationDataToJson(final boolean prettyPrint, final Set<String> responseParameters, final ConfigurationData... configuration) {
final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("selectedCurrencyOptions", "currencyOptions"));
@@ -838,7 +873,7 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
String externalId = extractStringParameter("externalId", requestMap, modifiedParameters);
String name = extractStringParameter("name", requestMap, modifiedParameters);
return new GroupCommand(modifiedParameters, externalId, name);
return new GroupCommand(modifiedParameters, resourceIdentifier, externalId, name);
}
@Override
@@ -0,0 +1,12 @@
package org.mifosng.platform.exceptions;
/**
* A {@link RuntimeException} thrown when group resources are not found.
*/
public class GroupNotFoundException extends AbstractPlatformResourceNotFoundException {
public GroupNotFoundException(Long id){
super("error.msg.group.id.invalid", "Group with identifier " + id + " does not exist", id);
}
}
@@ -5,6 +5,7 @@ import javax.persistence.Entity;
import javax.persistence.Table;
import org.apache.commons.lang.StringUtils;
import org.mifosng.platform.api.commands.GroupCommand;
import org.mifosng.platform.infrastructure.AbstractAuditableCustom;
import org.mifosng.platform.user.domain.AppUser;
@@ -40,4 +41,14 @@ public class Group extends AbstractAuditableCustom<AppUser, Long> {
this.externalId = null;
}
}
public void update(GroupCommand command) {
if (command.isExternalIdChanged()) {
this.externalId = command.getExternalId();
}
if (command.isNameChanged()) {
this.name = command.getName();
}
}
}
@@ -30,4 +30,19 @@ public class GroupCommandValidator {
}
}
public void validateForUpdate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("group");
baseDataValidator.reset().parameter("id").value(command.getId()).notNull();
baseDataValidator.reset().parameter("name").value(command.getName()).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100);
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
}
}
}
@@ -0,0 +1,13 @@
package org.mifosng.platform.group.service;
import java.util.Collection;
import org.mifosng.platform.api.data.GroupData;
public interface GroupReadPlatformService {
Collection<GroupData> retrieveAllGroups();
GroupData retrieveGroup(Long groupId);
}
@@ -0,0 +1,76 @@
package org.mifosng.platform.group.service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import org.mifosng.platform.api.data.GroupData;
import org.mifosng.platform.exceptions.GroupNotFoundException;
import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource;
import org.mifosng.platform.security.PlatformSecurityContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
@Service
public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
private final JdbcTemplate jdbcTemplate;
private final PlatformSecurityContext context;
@Autowired
public GroupReadPlatformServiceImpl(final PlatformSecurityContext context,
final TenantAwareRoutingDataSource dataSource) {
this.context = context;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Override
public Collection<GroupData> retrieveAllGroups() {
this.context.authenticatedUser();
GroupMapper rm = new GroupMapper();
String sql = "select " + rm.groupSchema();
return this.jdbcTemplate.query(sql, rm, new Object[] {});
}
@Override
public GroupData retrieveGroup(Long groupId) {
try{
this.context.authenticatedUser();
GroupMapper rm = new GroupMapper();
String sql = "select " + rm.groupSchema() + " where g.id = ?";
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {groupId});
} catch (EmptyResultDataAccessException e){
throw new GroupNotFoundException(groupId);
}
}
private static final class GroupMapper implements RowMapper<GroupData> {
public String groupSchema() {
return "g.id as id, g.external_id as externalId, g.name as name from portfolio_group g";
}
@Override
public GroupData mapRow(ResultSet rs, int rowNum) throws SQLException {
Long id = rs.getLong("id");
String name = rs.getString("name");
String externalId = rs.getString("externalId");
return new GroupData(id, name, externalId);
}
}
}
@@ -9,4 +9,7 @@ public interface GroupWritePlatformService {
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE')")
EntityIdentifier createGroup(GroupCommand command);
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE')")
EntityIdentifier updateGroup(GroupCommand command);
}
@@ -2,6 +2,7 @@ package org.mifosng.platform.group.service;
import org.mifosng.platform.api.commands.GroupCommand;
import org.mifosng.platform.api.data.EntityIdentifier;
import org.mifosng.platform.exceptions.GroupNotFoundException;
import org.mifosng.platform.group.domain.Group;
import org.mifosng.platform.group.domain.GroupRepository;
import org.mifosng.platform.security.PlatformSecurityContext;
@@ -38,4 +39,24 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
return new EntityIdentifier(newGroup.getId());
}
@Transactional
@Override
public EntityIdentifier updateGroup(GroupCommand command) {
context.authenticatedUser();
GroupCommandValidator validator = new GroupCommandValidator(command);
validator.validateForUpdate();
Group groupForUpdate = this.groupRepository.findOne(command.getId());
if (groupForUpdate == null){
throw new GroupNotFoundException(command.getId());
}
groupForUpdate.update(command);
groupRepository.save(groupForUpdate);
return new EntityIdentifier(groupForUpdate.getId());
}
}