mifosx-97 still refactoring audit/makerchecker bits

This commit is contained in:
John Woodlock
2013-04-02 18:49:58 +01:00
parent ec810d9485
commit a9eb946ecd
3 changed files with 183 additions and 90 deletions
@@ -28,6 +28,7 @@ import org.mifosplatform.commands.data.AuditSearchData;
import org.mifosplatform.commands.data.CommandSourceData;
import org.mifosplatform.commands.service.AuditReadPlatformService;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException;
@@ -44,45 +45,66 @@ import org.springframework.stereotype.Component;
public class MakercheckersApiResource {
private final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<String>(
Arrays.asList("id", "actionName", "entityName", "resourceId", "subresourceId",
"maker", "madeOnDate", "checker", "checkedOnDate", "processingResult",
"commandAsJson", "officeName", "groupLevelName", "groupName", "clientName", "loanAccountNo", "savingsAccountNo"));
private final String resourceNameForPermissions = "MAKERCHECKER";
Arrays.asList("id", "actionName", "entityName", "resourceId",
"subresourceId", "maker", "madeOnDate", "checker",
"checkedOnDate", "processingResult", "commandAsJson",
"officeName", "groupLevelName", "groupName", "clientName",
"loanAccountNo", "savingsAccountNo"));
private final String resourceNameForPermissions = "MAKERCHECKER";
private final PlatformSecurityContext context;
private final AuditReadPlatformService readPlatformService;
private final DefaultToApiJsonSerializer<CommandSourceData> toApiJsonSerializer;
private final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializerAudit;
private final PlatformSecurityContext context;
private final AuditReadPlatformService readPlatformService;
private final DefaultToApiJsonSerializer<CommandSourceData> toApiJsonSerializer;
private final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializerAudit;
private final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioCommandSourceWritePlatformService writePlatformService;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioCommandSourceWritePlatformService writePlatformService;
@Autowired
public MakercheckersApiResource(final PlatformSecurityContext context, final AuditReadPlatformService readPlatformService,
final DefaultToApiJsonSerializer<CommandSourceData> toApiJsonSerializer, final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializerAudit,
final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate,
final ApiRequestParameterHelper apiRequestParameterHelper, final PortfolioCommandSourceWritePlatformService writePlatformService) {
this.context = context;
this.readPlatformService = readPlatformService;
this.toApiJsonSerializer = toApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.toApiJsonSerializerAudit = toApiJsonSerializerAudit;
this.toApiJsonSerializerSearchTemplate = toApiJsonSerializerSearchTemplate;
this.writePlatformService = writePlatformService;
}
@Autowired
public MakercheckersApiResource(
final PlatformSecurityContext context,
final AuditReadPlatformService readPlatformService,
final DefaultToApiJsonSerializer<CommandSourceData> toApiJsonSerializer,
final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializerAudit,
final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate,
final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService writePlatformService) {
this.context = context;
this.readPlatformService = readPlatformService;
this.toApiJsonSerializer = toApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.toApiJsonSerializerAudit = toApiJsonSerializerAudit;
this.toApiJsonSerializerSearchTemplate = toApiJsonSerializerSearchTemplate;
this.writePlatformService = writePlatformService;
}
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveCommands(@Context final UriInfo uriInfo) {
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveCommands(@Context final UriInfo uriInfo,
@QueryParam("actionName") final String actionName,
@QueryParam("entityName") final String entityName,
@QueryParam("resourceId") final Long resourceId,
@QueryParam("makerId") final Long makerId,
@QueryParam("makerDateTimeFrom") final String makerDateTimeFrom,
@QueryParam("makerDateTimeTo") final String makerDateTimeTo) {
context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
context.authenticatedUser().validateHasReadPermission(
resourceNameForPermissions);
final Collection<AuditData> entries = this.readPlatformService.retrieveAllEntriesToBeChecked();
final String extraCriteria = getExtraCriteria(actionName, entityName,
resourceId, makerId, makerDateTimeFrom, makerDateTimeTo);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializerAudit.serialize(settings, entries, RESPONSE_DATA_PARAMETERS);
}
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper
.process(uriInfo.getQueryParameters());
final Collection<AuditData> entries = this.readPlatformService
.retrieveAllEntriesToBeChecked(extraCriteria,
settings.isIncludeJson());
return this.toApiJsonSerializerAudit.serialize(settings, entries,
RESPONSE_DATA_PARAMETERS);
}
@GET
@Path("/searchtemplate")
@@ -105,35 +127,77 @@ public class MakercheckersApiResource {
return this.toApiJsonSerializerSearchTemplate.serialize(settings,
auditSearchData, RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE);
}
@POST
@Path("{commandId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String approveMakerCheckerEntry(@PathParam("commandId") final Long commandId, @QueryParam("command") final String commandParam) {
CommandProcessingResult result = null;
if (is(commandParam, "approve")) {
result = this.writePlatformService.approveEntry(commandId);
} else {
throw new UnrecognizedQueryParamException("command", commandParam);
}
@POST
@Path("{commandId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String approveMakerCheckerEntry(
@PathParam("commandId") final Long commandId,
@QueryParam("command") final String commandParam) {
return this.toApiJsonSerializer.serialize(result);
}
CommandProcessingResult result = null;
if (is(commandParam, "approve")) {
result = this.writePlatformService.approveEntry(commandId);
} else {
throw new UnrecognizedQueryParamException("command", commandParam);
}
private boolean is(final String commandParam, final String commandValue) {
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
}
return this.toApiJsonSerializer.serialize(result);
}
@DELETE
@Path("{commandId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String deleteMakerCheckerEntry(@PathParam("commandId") final Long commandId) {
private boolean is(final String commandParam, final String commandValue) {
return StringUtils.isNotBlank(commandParam)
&& commandParam.trim().equalsIgnoreCase(commandValue);
}
final Long id = this.writePlatformService.deleteEntry(commandId);
@DELETE
@Path("{commandId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String deleteMakerCheckerEntry(
@PathParam("commandId") final Long commandId) {
return this.toApiJsonSerializer.serialize(CommandProcessingResult.commandOnlyResult(id));
}
final Long id = this.writePlatformService.deleteEntry(commandId);
return this.toApiJsonSerializer.serialize(CommandProcessingResult
.commandOnlyResult(id));
}
private String getExtraCriteria(final String actionName,
final String entityName, final Long resourceId, final Long makerId,
final String makerDateTimeFrom, final String makerDateTimeTo) {
String extraCriteria = "";
if (actionName != null) {
extraCriteria += " and aud.action_name = "
+ ApiParameterHelper.sqlEncodeString(actionName);
}
if (entityName != null) {
extraCriteria += " and aud.entity_name like "
+ ApiParameterHelper.sqlEncodeString(entityName + "%");
}
if (resourceId != null) {
extraCriteria += " and aud.resource_id = " + resourceId;
}
if (makerId != null) {
extraCriteria += " and aud.maker_id = " + makerId;
}
if (makerDateTimeFrom != null) {
extraCriteria += " and aud.made_on_date >= "
+ ApiParameterHelper.sqlEncodeString(makerDateTimeFrom);
}
if (makerDateTimeTo != null) {
extraCriteria += " and aud.made_on_date <= "
+ ApiParameterHelper.sqlEncodeString(makerDateTimeTo);
}
if (StringUtils.isNotBlank(extraCriteria)) {
extraCriteria = extraCriteria.substring(4);
}
return extraCriteria;
}
}
@@ -14,10 +14,10 @@ public interface AuditReadPlatformService {
Collection<AuditData> retrieveAuditEntries(String extraCriteria, boolean includeJson);
Collection<AuditData> retrieveAllEntriesToBeChecked(String extraCriteria, boolean includeJson);
AuditData retrieveAuditEntry(Long auditId);
AuditSearchData retrieveSearchTemplate(String useType);
Collection<AuditData> retrieveAllEntriesToBeChecked();
}
@@ -20,6 +20,7 @@ import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityExce
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.useradministration.data.AppUserData;
import org.mifosplatform.useradministration.domain.AppUser;
import org.mifosplatform.useradministration.service.AppUserReadPlatformService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -47,14 +48,14 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
}
private static final class AuditMapper implements RowMapper<AuditData> {
//TODO - jpw need to break this down, also data scope etc.
public String schema(boolean includeJson) {
public String schema(boolean includeJson, String hierarchy) {
String commandAsJsonString = "";
if (includeJson)
commandAsJsonString = ", aud.command_as_json as commandAsJson ";
return " aud.id as id, aud.action_name as actionName, aud.entity_name as entityName,"
String partSql = " aud.id as id, aud.action_name as actionName, aud.entity_name as entityName,"
+ " aud.resource_id as resourceId, aud.subresource_id as subresourceId,"
+ " mk.username as maker, aud.made_on_date as madeOnDate, "
+ "ck.username as checker, aud.checked_on_date as checkedOnDate, ev.enum_message_property as processingResult "
@@ -72,6 +73,15 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
+ " left join m_loan l on l.id = aud.loan_id"
+ " left join m_savings_account s on s.id = aud.savings_account_id"
+ " left join r_enum_value ev on ev.enum_name = 'processing_result_enum' and ev.enum_id = aud.processing_result_enum";
// data scoping: head office (hierarchy = ".") can see all audit
// entries
if (!(hierarchy.equals("."))) {
partSql += " join m_office o on o.id = aud.office_id and o.hierarchy like '"
+ hierarchy + "%' ";
}
return partSql;
}
@Override
@@ -117,25 +127,55 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
@Override
public Collection<AuditData> retrieveAuditEntries(String extraCriteria,
boolean includeJson) {
context.authenticatedUser();
String updatedExtraCriteria = "";
if (StringUtils.isNotBlank(extraCriteria))
updatedExtraCriteria = " where (" + extraCriteria + ")";
updatedExtraCriteria += " order by aud.id DESC";
return retrieveEntries(updatedExtraCriteria, includeJson);
}
@Override
public Collection<AuditData> retrieveAllEntriesToBeChecked(
String extraCriteria, boolean includeJson) {
String updatedExtraCriteria = "";
if (StringUtils.isNotBlank(extraCriteria))
updatedExtraCriteria = " where (" + extraCriteria + ")"
+ " and aud.processing_result_enum = 2";
else
updatedExtraCriteria = " where aud.processing_result_enum = 2";
updatedExtraCriteria += " order by aud.id";
//TODO - should only be pulling back makerchecker entries that the user has maker-checker permissions for
return retrieveEntries(updatedExtraCriteria, includeJson);
}
public Collection<AuditData> retrieveEntries(String extraCriteria,
boolean includeJson) {
AppUser currentUser = context.authenticatedUser();
String hierarchy = currentUser.getOffice().getHierarchy();
final AuditMapper rm = new AuditMapper();
String sql = "select " + rm.schema(includeJson);
if (StringUtils.isNotBlank(extraCriteria))
sql += " where (" + extraCriteria + ")";
sql += " order by aud.id DESC";
String sql = "select " + rm.schema(includeJson, hierarchy)
+ extraCriteria;
logger.info("sql: " + sql);
return this.jdbcTemplate.query(sql, rm, new Object[] {});
}
@Override
public AuditData retrieveAuditEntry(Long auditId) {
context.authenticatedUser();
AppUser currentUser = context.authenticatedUser();
String hierarchy = currentUser.getOffice().getHierarchy();
final AuditMapper rm = new AuditMapper();
String sql = "select " + rm.schema(true);
String sql = "select " + rm.schema(true, hierarchy);
sql += " where aud.id = " + auditId;
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {});
@@ -143,11 +183,13 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
@Override
public AuditSearchData retrieveSearchTemplate(String useType) {
if (!(useType.equals("audit") || useType.equals("makerchecker"))) {
throw new PlatformDataIntegrityException("error.msg.invalid.auditSearchTemplate.useType",
"Invalid Audit Search Template UseType: " + useType); }
if (!(useType.equals("audit") || useType.equals("makerchecker"))) {
throw new PlatformDataIntegrityException(
"error.msg.invalid.auditSearchTemplate.useType",
"Invalid Audit Search Template UseType: " + useType);
}
final Collection<AppUserData> appUsers = appUserReadPlatformService
.retrieveSearchTemplate();
@@ -162,27 +204,14 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
Collection<ProcessingResultLookup> processingResults = null;
if (useType.equals("audit")) {
ProcessingResultsMapper mapper3 = new ProcessingResultsMapper();
processingResults = this.jdbcTemplate.query(mapper3.schema(), mapper3, new Object[] {});
processingResults = this.jdbcTemplate.query(mapper3.schema(),
mapper3, new Object[] {});
}
return new AuditSearchData(appUsers, actionNames, entityNames,
processingResults);
}
@Override
public Collection<AuditData> retrieveAllEntriesToBeChecked() {
context.authenticatedUser();
final AuditMapper rm = new AuditMapper();
final String sql = "select " + rm.schema(false)
+ " where aud.checker_id is null and aud.processing_result_enum = 2 order by aud.id";
//+ " where mc.checker_id is null and mc.processing_result_enum = 2 order by mc.made_on_date DESC, mc.entity_name ASC, mc.action_name ASC";
logger.info("sql: " + sql);
return this.jdbcTemplate.query(sql, rm, new Object[] {});
}
private static final class ActionNamesMapper implements RowMapper<String> {
@Override