MIFOSX-329: refactor audit work for replacing ids of offices and clients for better display.

This commit is contained in:
Keith Woodlock
2013-05-07 22:34:15 +01:00
parent c99d2f6114
commit 052eb845c9
15 changed files with 354 additions and 410 deletions
@@ -38,192 +38,151 @@ import org.springframework.stereotype.Component;
@Scope("singleton") @Scope("singleton")
public class AuditsApiResource { public class AuditsApiResource {
private final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<String>( private final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "actionName", "entityName", "resourceId",
Arrays.asList("id", "actionName", "entityName", "resourceId", "subresourceId", "maker", "madeOnDate", "checker", "checkedOnDate", "processingResult", "commandAsJson", "officeName",
"subresourceId", "maker", "madeOnDate", "checker", "groupLevelName", "groupName", "clientName", "loanAccountNo", "savingsAccountNo"));
"checkedOnDate", "processingResult", "commandAsJson",
"officeName", "groupLevelName", "groupName", "clientName",
"loanAccountNo", "savingsAccountNo"));
private final String resourceNameForPermissions = "AUDIT"; private final String resourceNameForPermissions = "AUDIT";
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final AuditReadPlatformService auditReadPlatformService; private final AuditReadPlatformService auditReadPlatformService;
private final ApiRequestParameterHelper apiRequestParameterHelper; private final ApiRequestParameterHelper apiRequestParameterHelper;
private final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializer; private final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializer;
private final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate; private final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate;
@Autowired @Autowired
public AuditsApiResource( public AuditsApiResource(final PlatformSecurityContext context, final AuditReadPlatformService auditReadPlatformService,
final PlatformSecurityContext context, final ApiRequestParameterHelper apiRequestParameterHelper, final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializer,
final AuditReadPlatformService auditReadPlatformService, final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate) {
final ApiRequestParameterHelper apiRequestParameterHelper, this.context = context;
final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializer, this.auditReadPlatformService = auditReadPlatformService;
final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate) { this.apiRequestParameterHelper = apiRequestParameterHelper;
this.context = context; this.toApiJsonSerializer = toApiJsonSerializer;
this.auditReadPlatformService = auditReadPlatformService; this.toApiJsonSerializerSearchTemplate = toApiJsonSerializerSearchTemplate;
this.apiRequestParameterHelper = apiRequestParameterHelper; }
this.toApiJsonSerializer = toApiJsonSerializer;
this.toApiJsonSerializerSearchTemplate = toApiJsonSerializerSearchTemplate;
}
@GET @GET
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveAuditEntries( public String retrieveAuditEntries(@Context final UriInfo uriInfo, @QueryParam("actionName") final String actionName,
@Context final UriInfo uriInfo, @QueryParam("entityName") final String entityName, @QueryParam("resourceId") final Long resourceId,
@QueryParam("actionName") final String actionName, @QueryParam("makerId") final Long makerId, @QueryParam("makerDateTimeFrom") final String makerDateTimeFrom,
@QueryParam("entityName") final String entityName, @QueryParam("makerDateTimeTo") final String makerDateTimeTo, @QueryParam("checkerId") final Long checkerId,
@QueryParam("resourceId") final Long resourceId, @QueryParam("checkerDateTimeFrom") final String checkerDateTimeFrom,
@QueryParam("makerId") final Long makerId, @QueryParam("checkerDateTimeTo") final String checkerDateTimeTo,
@QueryParam("makerDateTimeFrom") final String makerDateTimeFrom, @QueryParam("processingResult") final Integer processingResult, @QueryParam("officeId") final Integer officeId,
@QueryParam("makerDateTimeTo") final String makerDateTimeTo, @QueryParam("groupId") final Integer groupId, @QueryParam("clientId") final Integer clientId,
@QueryParam("checkerId") final Long checkerId, @QueryParam("loanid") final Integer loanId, @QueryParam("savingsAccountId") final Integer savingsAccountId) {
@QueryParam("checkerDateTimeFrom") final String checkerDateTimeFrom,
@QueryParam("checkerDateTimeTo") final String checkerDateTimeTo,
@QueryParam("processingResult") final Integer processingResult,
@QueryParam("officeId") final Integer officeId,
@QueryParam("groupId") final Integer groupId,
@QueryParam("clientId") final Integer clientId,
@QueryParam("loanid") final Integer loanId,
@QueryParam("savingsAccountId") final Integer savingsAccountId) {
context.authenticatedUser().validateHasReadPermission( context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
resourceNameForPermissions);
final String extraCriteria = getExtraCriteria(actionName, entityName, final String extraCriteria = getExtraCriteria(actionName, entityName, resourceId, makerId, makerDateTimeFrom, makerDateTimeTo,
resourceId, makerId, makerDateTimeFrom, makerDateTimeTo, checkerId, checkerDateTimeFrom, checkerDateTimeTo, processingResult, officeId, groupId, clientId, loanId, savingsAccountId);
checkerId, checkerDateTimeFrom, checkerDateTimeTo,
processingResult, officeId, groupId, clientId, loanId,
savingsAccountId);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
.process(uriInfo.getQueryParameters());
final Collection<AuditData> auditEntries = this.auditReadPlatformService final Collection<AuditData> auditEntries = this.auditReadPlatformService.retrieveAuditEntries(extraCriteria,
.retrieveAuditEntries(extraCriteria, settings.isIncludeJson()); settings.isIncludeJson());
return this.toApiJsonSerializer.serialize(settings, auditEntries, return this.toApiJsonSerializer.serialize(settings, auditEntries, RESPONSE_DATA_PARAMETERS);
RESPONSE_DATA_PARAMETERS); }
}
@GET @GET
@Path("{auditId}") @Path("{auditId}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveAuditEntry(@PathParam("auditId") final Long auditId, public String retrieveAuditEntry(@PathParam("auditId") final Long auditId, @Context final UriInfo uriInfo) {
@Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission( context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
resourceNameForPermissions);
final AuditData auditEntry = this.auditReadPlatformService final AuditData auditEntry = this.auditReadPlatformService.retrieveAuditEntry(auditId);
.retrieveAuditEntry(auditId);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
.process(uriInfo.getQueryParameters()); return this.toApiJsonSerializer.serialize(settings, auditEntry, RESPONSE_DATA_PARAMETERS);
return this.toApiJsonSerializer.serialize(settings, auditEntry, }
RESPONSE_DATA_PARAMETERS);
}
@GET @GET
@Path("/searchtemplate") @Path("/searchtemplate")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveAuditSearchTemplate(@Context final UriInfo uriInfo) { public String retrieveAuditSearchTemplate(@Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission( context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
resourceNameForPermissions);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
.process(uriInfo.getQueryParameters());
final AuditSearchData auditSearchData = this.auditReadPlatformService final AuditSearchData auditSearchData = this.auditReadPlatformService.retrieveSearchTemplate("audit");
.retrieveSearchTemplate("audit");
final Set<String> RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE = new HashSet<String>( final Set<String> RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE = new HashSet<String>(Arrays.asList("appUsers", "actionNames",
Arrays.asList("appUsers", "actionNames", "entityNames", "entityNames", "processingResults"));
"processingResults"));
return this.toApiJsonSerializerSearchTemplate.serialize(settings, return this.toApiJsonSerializerSearchTemplate.serialize(settings, auditSearchData, RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE);
auditSearchData, RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE); }
}
private String getExtraCriteria(final String actionName, private String getExtraCriteria(final String actionName, final String entityName, final Long resourceId, final Long makerId,
final String entityName, final Long resourceId, final Long makerId, final String makerDateTimeFrom, final String makerDateTimeTo, final Long checkerId, final String checkerDateTimeFrom,
final String makerDateTimeFrom, final String makerDateTimeTo, final String checkerDateTimeTo, final Integer processingResult, final Integer officeId, final Integer groupId,
final Long checkerId, final String checkerDateTimeFrom, final Integer clientId, final Integer loanId, final Integer savingsAccountId) {
final String checkerDateTimeTo, final Integer processingResult,
final Integer officeId, final Integer groupId,
final Integer clientId, final Integer loanId,
final Integer savingsAccountId) {
String extraCriteria = ""; String extraCriteria = "";
if (actionName != null) { if (actionName != null) {
extraCriteria += " and aud.action_name = " extraCriteria += " and aud.action_name = " + ApiParameterHelper.sqlEncodeString(actionName);
+ ApiParameterHelper.sqlEncodeString(actionName); }
} if (entityName != null) {
if (entityName != null) { extraCriteria += " and aud.entity_name like " + ApiParameterHelper.sqlEncodeString(entityName + "%");
extraCriteria += " and aud.entity_name like " }
+ ApiParameterHelper.sqlEncodeString(entityName + "%");
}
if (resourceId != null) { if (resourceId != null) {
extraCriteria += " and aud.resource_id = " + resourceId; extraCriteria += " and aud.resource_id = " + resourceId;
} }
if (makerId != null) { if (makerId != null) {
extraCriteria += " and aud.maker_id = " + makerId; extraCriteria += " and aud.maker_id = " + makerId;
} }
if (checkerId != null) { if (checkerId != null) {
extraCriteria += " and aud.checker_id = " + checkerId; extraCriteria += " and aud.checker_id = " + checkerId;
} }
if (makerDateTimeFrom != null) { if (makerDateTimeFrom != null) {
extraCriteria += " and aud.made_on_date >= " extraCriteria += " and aud.made_on_date >= " + ApiParameterHelper.sqlEncodeString(makerDateTimeFrom);
+ ApiParameterHelper.sqlEncodeString(makerDateTimeFrom); }
} if (makerDateTimeTo != null) {
if (makerDateTimeTo != null) { extraCriteria += " and aud.made_on_date <= " + ApiParameterHelper.sqlEncodeString(makerDateTimeTo);
extraCriteria += " and aud.made_on_date <= " }
+ ApiParameterHelper.sqlEncodeString(makerDateTimeTo); if (checkerDateTimeFrom != null) {
} extraCriteria += " and aud.checked_on_date >= " + ApiParameterHelper.sqlEncodeString(checkerDateTimeFrom);
if (checkerDateTimeFrom != null) { }
extraCriteria += " and aud.checked_on_date >= " if (checkerDateTimeTo != null) {
+ ApiParameterHelper.sqlEncodeString(checkerDateTimeFrom); extraCriteria += " and aud.checked_on_date <= " + ApiParameterHelper.sqlEncodeString(checkerDateTimeTo);
} }
if (checkerDateTimeTo != null) {
extraCriteria += " and aud.checked_on_date <= "
+ ApiParameterHelper.sqlEncodeString(checkerDateTimeTo);
}
if (processingResult != null) { if (processingResult != null) {
extraCriteria += " and aud.processing_result_enum = " extraCriteria += " and aud.processing_result_enum = " + processingResult;
+ processingResult; }
}
if (officeId != null) { if (officeId != null) {
extraCriteria += " and aud.office_id = " + officeId; extraCriteria += " and aud.office_id = " + officeId;
} }
if (groupId != null) { if (groupId != null) {
extraCriteria += " and aud.group_id = " + groupId; extraCriteria += " and aud.group_id = " + groupId;
} }
if (clientId != null) { if (clientId != null) {
extraCriteria += " and aud.client_id = " + clientId; extraCriteria += " and aud.client_id = " + clientId;
} }
if (loanId != null) { if (loanId != null) {
extraCriteria += " and aud.loan_id = " + loanId; extraCriteria += " and aud.loan_id = " + loanId;
} }
if (savingsAccountId != null) { if (savingsAccountId != null) {
extraCriteria += " and aud.savings_account_id = " + savingsAccountId; extraCriteria += " and aud.savings_account_id = " + savingsAccountId;
} }
if (StringUtils.isNotBlank(extraCriteria)) { if (StringUtils.isNotBlank(extraCriteria)) {
extraCriteria = extraCriteria.substring(4); extraCriteria = extraCriteria.substring(4);
} }
return extraCriteria; return extraCriteria;
} }
} }
@@ -12,75 +12,70 @@ import org.joda.time.DateTime;
*/ */
public final class AuditData { public final class AuditData {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final Long id; private final Long id;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String actionName; private final String actionName;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String entityName; private final String entityName;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final Long resourceId; private final Long resourceId;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final Long subresourceId; private final Long subresourceId;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String maker; private final String maker;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final DateTime madeOnDate; private final DateTime madeOnDate;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String checker; private final String checker;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final DateTime checkedOnDate; private final DateTime checkedOnDate;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String processingResult; private final String processingResult;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private String commandAsJson; private String commandAsJson;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String officeName; private final String officeName;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String groupLevelName; private final String groupLevelName;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String groupName; private final String groupName;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String clientName; private final String clientName;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String loanAccountNo; private final String loanAccountNo;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String savingsAccountNo; private final String savingsAccountNo;
public AuditData(final Long id, final String actionName, public AuditData(final Long id, final String actionName, final String entityName, final Long resourceId, final Long subresourceId,
final String entityName, final Long resourceId, final String maker, final DateTime madeOnDate, final String checker, final DateTime checkedOnDate,
final Long subresourceId, final String maker, final String processingResult, final String commandAsJson, final String officeName, final String groupLevelName,
final DateTime madeOnDate, final String checker, final String groupName, final String clientName, final String loanAccountNo, final String savingsAccountNo) {
final DateTime checkedOnDate, final String processingResult,
final String commandAsJson, final String officeName,
final String groupLevelName, final String groupName,
final String clientName, final String loanAccountNo,
final String savingsAccountNo) {
this.id = id; this.id = id;
this.actionName = actionName; this.actionName = actionName;
this.entityName = entityName; this.entityName = entityName;
this.resourceId = resourceId; this.resourceId = resourceId;
this.subresourceId = subresourceId; this.subresourceId = subresourceId;
this.maker = maker; this.maker = maker;
this.madeOnDate = madeOnDate; this.madeOnDate = madeOnDate;
this.checker = checker; this.checker = checker;
this.checkedOnDate = checkedOnDate; this.checkedOnDate = checkedOnDate;
this.commandAsJson = commandAsJson; this.commandAsJson = commandAsJson;
this.processingResult = processingResult; this.processingResult = processingResult;
this.officeName = officeName; this.officeName = officeName;
this.groupLevelName = groupLevelName; this.groupLevelName = groupLevelName;
this.groupName = groupName; this.groupName = groupName;
this.clientName = clientName; this.clientName = clientName;
this.loanAccountNo = loanAccountNo; this.loanAccountNo = loanAccountNo;
this.savingsAccountNo = savingsAccountNo; this.savingsAccountNo = savingsAccountNo;
} }
public void setCommandAsJson(String commandAsJson) { public void setCommandAsJson(final String commandAsJson) {
this.commandAsJson = commandAsJson; this.commandAsJson = commandAsJson;
} }
public String getCommandAsJson() { public String getCommandAsJson() {
return this.commandAsJson; return this.commandAsJson;
} }
} }
@@ -59,8 +59,7 @@ public class CommandWrapper {
public CommandWrapper(final Long officeId, final Long groupId, final Long clientId, final Long loanId, final Long savingsId, public CommandWrapper(final Long officeId, final Long groupId, final Long clientId, final Long loanId, final Long savingsId,
final String actionName, final String entityName, final Long entityId, final Long subentityId, final Long codeId, final String actionName, final String entityName, final Long entityId, final Long subentityId, final Long codeId,
final String supportedEntityType, final Long supportedEntityId, final String href, final String json, final String transactionId final String supportedEntityType, final Long supportedEntityId, final String href, final String json, final String transactionId) {
) {
this.commandId = null; this.commandId = null;
this.officeId = officeId; this.officeId = officeId;
this.groupId = groupId; this.groupId = groupId;
@@ -129,7 +128,6 @@ public class CommandWrapper {
return this.transactionId; return this.transactionId;
} }
public String getEntityName() { public String getEntityName() {
return this.entityName; return this.entityName;
} }
@@ -499,11 +497,11 @@ public class CommandWrapper {
return this.entityName.equalsIgnoreCase("REPORT"); return this.entityName.equalsIgnoreCase("REPORT");
} }
public boolean isAssociateClients(){ public boolean isAssociateClients() {
return this.actionName.equalsIgnoreCase("ASSOCIATECLIENTS"); return this.actionName.equalsIgnoreCase("ASSOCIATECLIENTS");
} }
public boolean isDisassociateClients(){ public boolean isDisassociateClients() {
return this.actionName.equalsIgnoreCase("DISASSOCIATECLIENTS"); return this.actionName.equalsIgnoreCase("DISASSOCIATECLIENTS");
} }
} }
@@ -12,7 +12,7 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceN
*/ */
public class CommandNotAwaitingApprovalException extends AbstractPlatformResourceNotFoundException { public class CommandNotAwaitingApprovalException extends AbstractPlatformResourceNotFoundException {
public CommandNotAwaitingApprovalException(Long id) { public CommandNotAwaitingApprovalException(final Long id) {
super("error.msg.command.id.not.awaiting.approval", "Audit with identifier " + id + " is Not Awaiting Approval", id); super("error.msg.command.id.not.awaiting.approval", "Audit with identifier " + id + " is Not Awaiting Approval", id);
} }
} }
@@ -12,7 +12,7 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceN
*/ */
public class CommandNotFoundException extends AbstractPlatformResourceNotFoundException { public class CommandNotFoundException extends AbstractPlatformResourceNotFoundException {
public CommandNotFoundException(Long id) { public CommandNotFoundException(final Long id) {
super("error.msg.command.id.invalid", "Audit with identifier " + id + " does not exist", id); super("error.msg.command.id.invalid", "Audit with identifier " + id + " does not exist", id);
} }
} }
@@ -7,28 +7,26 @@ package org.mifosplatform.commands.exception;
import org.mifosplatform.commands.domain.CommandSource; import org.mifosplatform.commands.domain.CommandSource;
public class RollbackTransactionAsCommandIsNotApprovedByCheckerException extends public class RollbackTransactionAsCommandIsNotApprovedByCheckerException extends RuntimeException {
RuntimeException {
/** /**
* When maker-checker is configured globally and also for the current * When maker-checker is configured globally and also for the current
* transaction. * transaction.
* *
* An initial save determines if there are any integrity rule or data * An initial save determines if there are any integrity rule or data
* problems. * problems.
* *
* If there isn't... and the transaction is from a maker... then this roll * If there isn't... and the transaction is from a maker... then this roll
* back is issued and the commandSourceResult is used to write the audit * back is issued and the commandSourceResult is used to write the audit
* entry. * entry.
*/ */
private final CommandSource commandSourceResult; private final CommandSource commandSourceResult;
public RollbackTransactionAsCommandIsNotApprovedByCheckerException( public RollbackTransactionAsCommandIsNotApprovedByCheckerException(final CommandSource commandSourceResult) {
final CommandSource commandSourceResult) { this.commandSourceResult = commandSourceResult;
this.commandSourceResult = commandSourceResult; }
}
public CommandSource getCommandSourceResult() { public CommandSource getCommandSourceResult() {
return this.commandSourceResult; return this.commandSourceResult;
} }
} }
@@ -19,5 +19,4 @@ public interface AuditReadPlatformService {
AuditData retrieveAuditEntry(Long auditId); AuditData retrieveAuditEntry(Long auditId);
AuditSearchData retrieveSearchTemplate(String useType); AuditSearchData retrieveSearchTemplate(String useType);
} }
@@ -5,10 +5,10 @@
*/ */
package org.mifosplatform.commands.service; package org.mifosplatform.commands.service;
import java.lang.reflect.Type;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -19,8 +19,13 @@ import org.mifosplatform.commands.data.AuditSearchData;
import org.mifosplatform.commands.data.ProcessingResultLookup; import org.mifosplatform.commands.data.ProcessingResultLookup;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport; import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.office.data.OfficeData;
import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
import org.mifosplatform.portfolio.client.data.ClientData;
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
import org.mifosplatform.useradministration.data.AppUserData; import org.mifosplatform.useradministration.data.AppUserData;
import org.mifosplatform.useradministration.domain.AppUser; import org.mifosplatform.useradministration.domain.AppUser;
import org.mifosplatform.useradministration.service.AppUserReadPlatformService; import org.mifosplatform.useradministration.service.AppUserReadPlatformService;
@@ -31,22 +36,30 @@ import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.google.gson.Gson; import com.google.gson.reflect.TypeToken;
@Service @Service
public class AuditReadPlatformServiceImpl implements AuditReadPlatformService { public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
private final static Logger logger = LoggerFactory.getLogger(AuditReadPlatformServiceImpl.class); private final static Logger logger = LoggerFactory.getLogger(AuditReadPlatformServiceImpl.class);
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final FromJsonHelper fromApiJsonHelper;
private final AppUserReadPlatformService appUserReadPlatformService; private final AppUserReadPlatformService appUserReadPlatformService;
private final OfficeReadPlatformService officeReadPlatformService;
private final ClientReadPlatformService clientReadPlatformService;
@Autowired @Autowired
public AuditReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource, public AuditReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource,
final AppUserReadPlatformService appUserReadPlatformService) { final FromJsonHelper fromApiJsonHelper, final AppUserReadPlatformService appUserReadPlatformService,
final OfficeReadPlatformService officeReadPlatformService, final ClientReadPlatformService clientReadPlatformService) {
this.context = context; this.context = context;
this.jdbcTemplate = new JdbcTemplate(dataSource); this.jdbcTemplate = new JdbcTemplate(dataSource);
this.fromApiJsonHelper = fromApiJsonHelper;
this.appUserReadPlatformService = appUserReadPlatformService; this.appUserReadPlatformService = appUserReadPlatformService;
this.officeReadPlatformService = officeReadPlatformService;
this.clientReadPlatformService = clientReadPlatformService;
} }
private static final class AuditMapper implements RowMapper<AuditData> { private static final class AuditMapper implements RowMapper<AuditData> {
@@ -166,8 +179,7 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
return this.jdbcTemplate.query(sql, rm, new Object[] {}); return this.jdbcTemplate.query(sql, rm, new Object[] {});
} }
@SuppressWarnings("unchecked") @Override
@Override
public AuditData retrieveAuditEntry(final Long auditId) { public AuditData retrieveAuditEntry(final Long auditId) {
AppUser currentUser = context.authenticatedUser(); AppUser currentUser = context.authenticatedUser();
@@ -175,49 +187,46 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
final AuditMapper rm = new AuditMapper(); final AuditMapper rm = new AuditMapper();
String sql = "select " + rm.schema(true, hierarchy); String sql = "select " + rm.schema(true, hierarchy);
sql += " where aud.id = " + auditId; sql += " where aud.id = " + auditId;
AuditData auditResult = this.jdbcTemplate.queryForObject(sql, rm, new Object[] {}); AuditData auditResult = this.jdbcTemplate.queryForObject(sql, rm, new Object[] {});
String commandAsJson = auditResult.getCommandAsJson(); String auditAsJson = auditResult.getCommandAsJson();
Map<String,Object> commandAsJsonMap = new HashMap<String,Object>(); final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
commandAsJsonMap = new Gson().fromJson(commandAsJson, commandAsJsonMap.getClass()); final Map<String, Object> commandAsJsonMap = this.fromApiJsonHelper.extractObjectMap(typeOfMap, auditAsJson);
if (commandAsJsonMap.containsKey("officeId")) { if (commandAsJsonMap.containsKey("officeId")) {
Object officeIdObj = commandAsJsonMap.get("officeId"); final Object officeIdObj = commandAsJsonMap.get("officeId");
Integer officeId = -1; if (officeIdObj != null && StringUtils.isNotBlank(officeIdObj.toString())) {
if (officeIdObj instanceof Integer) { final Long officeId = Long.valueOf(officeIdObj.toString());
officeId = (Integer)officeIdObj;
} else if (officeIdObj instanceof Double) { OfficeData office = this.officeReadPlatformService.retrieveOffice(officeId);
officeId = ((Double) officeIdObj).intValue();
} commandAsJsonMap.remove("officeId");
if (officeId > -1) { commandAsJsonMap.put("officeName", office.name());
sql = " SELECT name FROM m_office WHERE id = " + officeId;
String officeName = this.jdbcTemplate.queryForObject(sql, String.class); auditAsJson = this.fromApiJsonHelper.toJson(commandAsJsonMap);
String regex = "\"officeId\":\\s\\d+"; }
commandAsJson = commandAsJson.replaceAll(regex, "\"officeName\": \""+officeName+"\"");
}
} }
if (commandAsJsonMap.containsKey("clientId")) { if (commandAsJsonMap.containsKey("clientId")) {
Object clientIdObj = commandAsJsonMap.get("clientId"); final Object clientIdObj = commandAsJsonMap.get("clientId");
Integer clientId = -1; if (clientIdObj != null && StringUtils.isNotBlank(clientIdObj.toString())) {
if (clientIdObj instanceof Integer) { final Long clientId = Long.valueOf(clientIdObj.toString());
clientId = (Integer)clientIdObj;
} else if (clientIdObj instanceof Double) { ClientData client = this.clientReadPlatformService.retrieveOne(clientId);
clientId = ((Double) clientIdObj).intValue();
} commandAsJsonMap.remove("clientId");
if (clientId > -1) { commandAsJsonMap.put("clientName", client.displayName());
sql = " SELECT display_name FROM m_client WHERE id = " + clientId;
String clientName = this.jdbcTemplate.queryForObject(sql, String.class); auditAsJson = this.fromApiJsonHelper.toJson(commandAsJsonMap);
String regex = "\"clientId\":\\s\\d+"; }
commandAsJson = commandAsJson.replaceAll(regex, "\"clientName\": \""+clientName+"\"");
}
} }
auditResult.setCommandAsJson(commandAsJson);
auditResult.setCommandAsJson(auditAsJson);
return auditResult; return auditResult;
} }
@@ -12,9 +12,8 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
public interface CommandProcessingService { public interface CommandProcessingService {
CommandProcessingResult processAndLogCommand(CommandWrapper wrapper, CommandProcessingResult processAndLogCommand(CommandWrapper wrapper, JsonCommand command, boolean isApprovedByChecker);
JsonCommand command, boolean isApprovedByChecker);
CommandProcessingResult logCommand(CommandSource commandSourceResult); CommandProcessingResult logCommand(CommandSource commandSourceResult);
} }
@@ -28,7 +28,7 @@ public class CommandWrapperBuilder {
public CommandWrapper build() { public CommandWrapper build() {
return new CommandWrapper(this.officeId, this.groupId, this.clientId, this.loanId, this.savingsId, this.actionName, return new CommandWrapper(this.officeId, this.groupId, this.clientId, this.loanId, this.savingsId, this.actionName,
this.entityName, this.entityId, this.subentityId, this.codeId, this.supportedEntityType, this.supportedEntityId, this.href, this.entityName, this.entityId, this.subentityId, this.codeId, this.supportedEntityType, this.supportedEntityId, this.href,
this.json, this.transactionId ); this.json, this.transactionId);
} }
public CommandWrapperBuilder withLoanId(final Long withLoanId) { public CommandWrapperBuilder withLoanId(final Long withLoanId) {
@@ -22,120 +22,95 @@ import org.springframework.transaction.annotation.Transactional;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
@Service @Service
public class PortfolioCommandSourceWritePlatformServiceImpl implements public class PortfolioCommandSourceWritePlatformServiceImpl implements PortfolioCommandSourceWritePlatformService {
PortfolioCommandSourceWritePlatformService {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final CommandSourceRepository commandSourceRepository; private final CommandSourceRepository commandSourceRepository;
private final FromJsonHelper fromApiJsonHelper; private final FromJsonHelper fromApiJsonHelper;
private final CommandProcessingService processAndLogCommandService; private final CommandProcessingService processAndLogCommandService;
@Autowired @Autowired
public PortfolioCommandSourceWritePlatformServiceImpl( public PortfolioCommandSourceWritePlatformServiceImpl(final PlatformSecurityContext context,
final PlatformSecurityContext context, final CommandSourceRepository commandSourceRepository, final FromJsonHelper fromApiJsonHelper,
final CommandSourceRepository commandSourceRepository, final CommandProcessingService processAndLogCommandService) {
final FromJsonHelper fromApiJsonHelper, this.context = context;
final CommandProcessingService processAndLogCommandService) { this.commandSourceRepository = commandSourceRepository;
this.context = context; this.fromApiJsonHelper = fromApiJsonHelper;
this.commandSourceRepository = commandSourceRepository; this.processAndLogCommandService = processAndLogCommandService;
this.fromApiJsonHelper = fromApiJsonHelper; }
this.processAndLogCommandService = processAndLogCommandService;
}
@Override @Override
public CommandProcessingResult logCommandSource(final CommandWrapper wrapper) { public CommandProcessingResult logCommandSource(final CommandWrapper wrapper) {
boolean isApprovedByChecker = false; boolean isApprovedByChecker = false;
// check if is update of own account details // check if is update of own account details
if (wrapper.isUpdateOfOwnUserDetails(context.authenticatedUser() if (wrapper.isUpdateOfOwnUserDetails(context.authenticatedUser().getId())) {
.getId())) { // then allow this operation to proceed.
// then allow this operation to proceed. // maker checker doesnt mean anything here.
// maker checker doesnt mean anything here. isApprovedByChecker = true; // set to true in case permissions have
isApprovedByChecker = true; // set to true in case permissions have // been maker-checker enabled by
// been maker-checker enabled by // accident.
// accident. } else {
} else { // if not user changing their own details - check user has
// if not user changing their own details - check user has // permission to perform specific task.
// permission to perform specific task. context.authenticatedUser().validateHasPermissionTo(wrapper.getTaskPermissionName());
context.authenticatedUser().validateHasPermissionTo( }
wrapper.getTaskPermissionName());
}
final String json = wrapper.getJson(); final String json = wrapper.getJson();
CommandProcessingResult result = null; CommandProcessingResult result = null;
try { try {
final JsonElement parsedCommand = this.fromApiJsonHelper final JsonElement parsedCommand = this.fromApiJsonHelper.parse(json);
.parse(json); final JsonCommand command = JsonCommand.from(json, parsedCommand, this.fromApiJsonHelper, wrapper.getEntityName(),
final JsonCommand command = JsonCommand.from(json, parsedCommand, wrapper.getEntityId(), wrapper.getSubentityId(), wrapper.getGroupId(), wrapper.getClientId(), wrapper.getLoanId(),
this.fromApiJsonHelper, wrapper.getEntityName(), wrapper.getSavingsId(), wrapper.getCodeId(), wrapper.getSupportedEntityType(), wrapper.getSupportedEntityId(),
wrapper.getEntityId(), wrapper.getSubentityId(), wrapper.getTransactionId());
wrapper.getGroupId(), wrapper.getClientId(),
wrapper.getLoanId(), wrapper.getSavingsId(),
wrapper.getCodeId(), wrapper.getSupportedEntityType(),
wrapper.getSupportedEntityId(), wrapper.getTransactionId());
result = this.processAndLogCommandService.processAndLogCommand( result = this.processAndLogCommandService.processAndLogCommand(wrapper, command, isApprovedByChecker);
wrapper, command, isApprovedByChecker); } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
result = this.processAndLogCommandService.logCommand(e result = this.processAndLogCommandService.logCommand(e.getCommandSourceResult());
.getCommandSourceResult()); }
}
return result; return result;
} }
@Override @Override
public CommandProcessingResult approveEntry(final Long makerCheckerId) { public CommandProcessingResult approveEntry(final Long makerCheckerId) {
CommandSource commandSourceInput = validateMakerCheckerTransaction(makerCheckerId); CommandSource commandSourceInput = validateMakerCheckerTransaction(makerCheckerId);
final CommandWrapper wrapper = CommandWrapper.fromExistingCommand( final CommandWrapper wrapper = CommandWrapper.fromExistingCommand(makerCheckerId, commandSourceInput.getActionName(),
makerCheckerId, commandSourceInput.getActionName(), commandSourceInput.getEntityName(), commandSourceInput.resourceId(), commandSourceInput.subresourceId(),
commandSourceInput.getEntityName(), commandSourceInput.getResourceGetUrl());
commandSourceInput.resourceId(),
commandSourceInput.subresourceId(),
commandSourceInput.getResourceGetUrl());
final JsonElement parsedCommand = this.fromApiJsonHelper final JsonElement parsedCommand = this.fromApiJsonHelper.parse(commandSourceInput.json());
.parse(commandSourceInput.json()); final JsonCommand command = JsonCommand.fromExistingCommand(makerCheckerId, commandSourceInput.json(), parsedCommand,
final JsonCommand command = JsonCommand.fromExistingCommand( this.fromApiJsonHelper, commandSourceInput.getEntityName(), commandSourceInput.resourceId(),
makerCheckerId, commandSourceInput.json(), parsedCommand, commandSourceInput.subresourceId());
this.fromApiJsonHelper, commandSourceInput.getEntityName(),
commandSourceInput.resourceId(),
commandSourceInput.subresourceId());
final boolean makerCheckerApproval = true; final boolean makerCheckerApproval = true;
return this.processAndLogCommandService.processAndLogCommand(wrapper, return this.processAndLogCommandService.processAndLogCommand(wrapper, command, makerCheckerApproval);
command, makerCheckerApproval); }
}
@Transactional @Transactional
@Override @Override
public Long deleteEntry(final Long makerCheckerId) { public Long deleteEntry(final Long makerCheckerId) {
validateMakerCheckerTransaction(makerCheckerId); validateMakerCheckerTransaction(makerCheckerId);
this.commandSourceRepository.delete(makerCheckerId); this.commandSourceRepository.delete(makerCheckerId);
return makerCheckerId; return makerCheckerId;
} }
private CommandSource validateMakerCheckerTransaction( private CommandSource validateMakerCheckerTransaction(final Long makerCheckerId) {
final Long makerCheckerId) {
final CommandSource commandSourceInput = this.commandSourceRepository final CommandSource commandSourceInput = this.commandSourceRepository.findOne(makerCheckerId);
.findOne(makerCheckerId); if (commandSourceInput == null) { throw new CommandNotFoundException(makerCheckerId); }
if (commandSourceInput == null) { if (!(commandSourceInput.isMarkedAsAwaitingApproval())) { throw new CommandNotAwaitingApprovalException(makerCheckerId); }
throw new CommandNotFoundException(makerCheckerId);
}
if (!(commandSourceInput.isMarkedAsAwaitingApproval())) {
throw new CommandNotAwaitingApprovalException(makerCheckerId);
}
context.authenticatedUser().validateHasCheckerPermissionTo( context.authenticatedUser().validateHasCheckerPermissionTo(commandSourceInput.getPermissionCode());
commandSourceInput.getPermissionCode());
return commandSourceInput; return commandSourceInput;
} }
} }
@@ -98,8 +98,8 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
commandSourceResult.markAsAwaitingApproval(); commandSourceResult.markAsAwaitingApproval();
commandSourceRepository.save(commandSourceResult); commandSourceRepository.save(commandSourceResult);
return new CommandProcessingResultBuilder().withCommandId(commandSourceResult.getId()).withEntityId(commandSourceResult.getResourceId()) return new CommandProcessingResultBuilder().withCommandId(commandSourceResult.getId())
.build(); .withEntityId(commandSourceResult.getResourceId()).build();
} }
private NewCommandSourceHandler findCommandHandler(final CommandWrapper wrapper) { private NewCommandSourceHandler findCommandHandler(final CommandWrapper wrapper) {
@@ -48,6 +48,10 @@ public class FromJsonHelper {
return this.gsonConverter.fromJson(json, typeOfMap); return this.gsonConverter.fromJson(json, typeOfMap);
} }
public Map<String, Object> extractObjectMap(final Type typeOfMap, final String json) {
return this.gsonConverter.fromJson(json, typeOfMap);
}
public <T> T fromJson(final String json, final Class<T> classOfT) { public <T> T fromJson(final String json, final Class<T> classOfT) {
return this.gsonConverter.fromJson(json, classOfT); return this.gsonConverter.fromJson(json, classOfT);
} }
@@ -56,6 +60,10 @@ public class FromJsonHelper {
return this.gsonConverter.toJson(jsonElement); return this.gsonConverter.toJson(jsonElement);
} }
public String toJson(final Object object) {
return this.gsonConverter.toJson(object);
}
public void checkForUnsupportedParameters(final Type typeOfMap, final String json, final Set<String> supportedParams) { public void checkForUnsupportedParameters(final Type typeOfMap, final String json, final Set<String> supportedParams) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
@@ -55,4 +55,8 @@ public class OfficeData {
public boolean hasIdentifyOf(final Long officeId) { public boolean hasIdentifyOf(final Long officeId) {
return this.id.equals(officeId); return this.id.equals(officeId);
} }
public String name() {
return this.name;
}
} }