mifosx-97 still refactoring audit/makerchecker bits
This commit is contained in:
+120
-56
@@ -28,6 +28,7 @@ import org.mifosplatform.commands.data.AuditSearchData;
|
|||||||
import org.mifosplatform.commands.data.CommandSourceData;
|
import org.mifosplatform.commands.data.CommandSourceData;
|
||||||
import org.mifosplatform.commands.service.AuditReadPlatformService;
|
import org.mifosplatform.commands.service.AuditReadPlatformService;
|
||||||
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
|
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.api.ApiRequestParameterHelper;
|
||||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||||
import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException;
|
import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException;
|
||||||
@@ -44,45 +45,66 @@ import org.springframework.stereotype.Component;
|
|||||||
public class MakercheckersApiResource {
|
public class MakercheckersApiResource {
|
||||||
|
|
||||||
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", "subresourceId",
|
Arrays.asList("id", "actionName", "entityName", "resourceId",
|
||||||
"maker", "madeOnDate", "checker", "checkedOnDate", "processingResult",
|
"subresourceId", "maker", "madeOnDate", "checker",
|
||||||
"commandAsJson", "officeName", "groupLevelName", "groupName", "clientName", "loanAccountNo", "savingsAccountNo"));
|
"checkedOnDate", "processingResult", "commandAsJson",
|
||||||
private final String resourceNameForPermissions = "MAKERCHECKER";
|
"officeName", "groupLevelName", "groupName", "clientName",
|
||||||
|
"loanAccountNo", "savingsAccountNo"));
|
||||||
|
private final String resourceNameForPermissions = "MAKERCHECKER";
|
||||||
|
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
private final AuditReadPlatformService readPlatformService;
|
private final AuditReadPlatformService readPlatformService;
|
||||||
private final DefaultToApiJsonSerializer<CommandSourceData> toApiJsonSerializer;
|
private final DefaultToApiJsonSerializer<CommandSourceData> toApiJsonSerializer;
|
||||||
private final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializerAudit;
|
private final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializerAudit;
|
||||||
private final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate;
|
private final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate;
|
||||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||||
private final PortfolioCommandSourceWritePlatformService writePlatformService;
|
private final PortfolioCommandSourceWritePlatformService writePlatformService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public MakercheckersApiResource(final PlatformSecurityContext context, final AuditReadPlatformService readPlatformService,
|
public MakercheckersApiResource(
|
||||||
final DefaultToApiJsonSerializer<CommandSourceData> toApiJsonSerializer, final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializerAudit,
|
final PlatformSecurityContext context,
|
||||||
final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate,
|
final AuditReadPlatformService readPlatformService,
|
||||||
final ApiRequestParameterHelper apiRequestParameterHelper, final PortfolioCommandSourceWritePlatformService writePlatformService) {
|
final DefaultToApiJsonSerializer<CommandSourceData> toApiJsonSerializer,
|
||||||
this.context = context;
|
final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializerAudit,
|
||||||
this.readPlatformService = readPlatformService;
|
final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate,
|
||||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
final PortfolioCommandSourceWritePlatformService writePlatformService) {
|
||||||
this.toApiJsonSerializerAudit = toApiJsonSerializerAudit;
|
this.context = context;
|
||||||
this.toApiJsonSerializerSearchTemplate = toApiJsonSerializerSearchTemplate;
|
this.readPlatformService = readPlatformService;
|
||||||
this.writePlatformService = writePlatformService;
|
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||||
}
|
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||||
|
this.toApiJsonSerializerAudit = toApiJsonSerializerAudit;
|
||||||
|
this.toApiJsonSerializerSearchTemplate = toApiJsonSerializerSearchTemplate;
|
||||||
|
this.writePlatformService = writePlatformService;
|
||||||
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
public String retrieveCommands(@Context final UriInfo uriInfo) {
|
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());
|
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper
|
||||||
return this.toApiJsonSerializerAudit.serialize(settings, entries, RESPONSE_DATA_PARAMETERS);
|
.process(uriInfo.getQueryParameters());
|
||||||
}
|
|
||||||
|
final Collection<AuditData> entries = this.readPlatformService
|
||||||
|
.retrieveAllEntriesToBeChecked(extraCriteria,
|
||||||
|
settings.isIncludeJson());
|
||||||
|
|
||||||
|
return this.toApiJsonSerializerAudit.serialize(settings, entries,
|
||||||
|
RESPONSE_DATA_PARAMETERS);
|
||||||
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("/searchtemplate")
|
@Path("/searchtemplate")
|
||||||
@@ -106,34 +128,76 @@ public class MakercheckersApiResource {
|
|||||||
auditSearchData, RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE);
|
auditSearchData, RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Path("{commandId}")
|
@Path("{commandId}")
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
public String approveMakerCheckerEntry(@PathParam("commandId") final Long commandId, @QueryParam("command") final String commandParam) {
|
public String approveMakerCheckerEntry(
|
||||||
|
@PathParam("commandId") final Long commandId,
|
||||||
|
@QueryParam("command") final String commandParam) {
|
||||||
|
|
||||||
CommandProcessingResult result = null;
|
CommandProcessingResult result = null;
|
||||||
if (is(commandParam, "approve")) {
|
if (is(commandParam, "approve")) {
|
||||||
result = this.writePlatformService.approveEntry(commandId);
|
result = this.writePlatformService.approveEntry(commandId);
|
||||||
} else {
|
} else {
|
||||||
throw new UnrecognizedQueryParamException("command", commandParam);
|
throw new UnrecognizedQueryParamException("command", commandParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.toApiJsonSerializer.serialize(result);
|
return this.toApiJsonSerializer.serialize(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean is(final String commandParam, final String commandValue) {
|
private boolean is(final String commandParam, final String commandValue) {
|
||||||
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
|
return StringUtils.isNotBlank(commandParam)
|
||||||
}
|
&& commandParam.trim().equalsIgnoreCase(commandValue);
|
||||||
|
}
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
@Path("{commandId}")
|
@Path("{commandId}")
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
public String deleteMakerCheckerEntry(@PathParam("commandId") final Long commandId) {
|
public String deleteMakerCheckerEntry(
|
||||||
|
@PathParam("commandId") final Long commandId) {
|
||||||
|
|
||||||
final Long id = this.writePlatformService.deleteEntry(commandId);
|
final Long id = this.writePlatformService.deleteEntry(commandId);
|
||||||
|
|
||||||
return this.toApiJsonSerializer.serialize(CommandProcessingResult.commandOnlyResult(id));
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -14,10 +14,10 @@ public interface AuditReadPlatformService {
|
|||||||
|
|
||||||
Collection<AuditData> retrieveAuditEntries(String extraCriteria, boolean includeJson);
|
Collection<AuditData> retrieveAuditEntries(String extraCriteria, boolean includeJson);
|
||||||
|
|
||||||
|
Collection<AuditData> retrieveAllEntriesToBeChecked(String extraCriteria, boolean includeJson);
|
||||||
|
|
||||||
AuditData retrieveAuditEntry(Long auditId);
|
AuditData retrieveAuditEntry(Long auditId);
|
||||||
|
|
||||||
AuditSearchData retrieveSearchTemplate(String useType);
|
AuditSearchData retrieveSearchTemplate(String useType);
|
||||||
|
|
||||||
Collection<AuditData> retrieveAllEntriesToBeChecked();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
+57
-28
@@ -20,6 +20,7 @@ import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityExce
|
|||||||
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.useradministration.data.AppUserData;
|
import org.mifosplatform.useradministration.data.AppUserData;
|
||||||
|
import org.mifosplatform.useradministration.domain.AppUser;
|
||||||
import org.mifosplatform.useradministration.service.AppUserReadPlatformService;
|
import org.mifosplatform.useradministration.service.AppUserReadPlatformService;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -47,14 +48,14 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final class AuditMapper implements RowMapper<AuditData> {
|
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 = "";
|
String commandAsJsonString = "";
|
||||||
if (includeJson)
|
if (includeJson)
|
||||||
commandAsJsonString = ", aud.command_as_json as commandAsJson ";
|
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,"
|
+ " aud.resource_id as resourceId, aud.subresource_id as subresourceId,"
|
||||||
+ " mk.username as maker, aud.made_on_date as madeOnDate, "
|
+ " 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 "
|
+ "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_loan l on l.id = aud.loan_id"
|
||||||
+ " left join m_savings_account s on s.id = aud.savings_account_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";
|
+ " 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
|
@Override
|
||||||
@@ -117,25 +127,55 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
|
|||||||
@Override
|
@Override
|
||||||
public Collection<AuditData> retrieveAuditEntries(String extraCriteria,
|
public Collection<AuditData> retrieveAuditEntries(String extraCriteria,
|
||||||
boolean includeJson) {
|
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();
|
final AuditMapper rm = new AuditMapper();
|
||||||
|
|
||||||
String sql = "select " + rm.schema(includeJson);
|
String sql = "select " + rm.schema(includeJson, hierarchy)
|
||||||
if (StringUtils.isNotBlank(extraCriteria))
|
+ extraCriteria;
|
||||||
sql += " where (" + extraCriteria + ")";
|
|
||||||
sql += " order by aud.id DESC";
|
|
||||||
logger.info("sql: " + sql);
|
logger.info("sql: " + sql);
|
||||||
|
|
||||||
return this.jdbcTemplate.query(sql, rm, new Object[] {});
|
return this.jdbcTemplate.query(sql, rm, new Object[] {});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuditData retrieveAuditEntry(Long auditId) {
|
public AuditData retrieveAuditEntry(Long auditId) {
|
||||||
context.authenticatedUser();
|
|
||||||
|
AppUser currentUser = context.authenticatedUser();
|
||||||
|
String hierarchy = currentUser.getOffice().getHierarchy();
|
||||||
|
|
||||||
final AuditMapper rm = new AuditMapper();
|
final AuditMapper rm = new AuditMapper();
|
||||||
|
|
||||||
String sql = "select " + rm.schema(true);
|
String sql = "select " + rm.schema(true, hierarchy);
|
||||||
sql += " where aud.id = " + auditId;
|
sql += " where aud.id = " + auditId;
|
||||||
|
|
||||||
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {});
|
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {});
|
||||||
@@ -144,9 +184,11 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
|
|||||||
@Override
|
@Override
|
||||||
public AuditSearchData retrieveSearchTemplate(String useType) {
|
public AuditSearchData retrieveSearchTemplate(String useType) {
|
||||||
|
|
||||||
if (!(useType.equals("audit") || useType.equals("makerchecker"))) {
|
if (!(useType.equals("audit") || useType.equals("makerchecker"))) {
|
||||||
throw new PlatformDataIntegrityException("error.msg.invalid.auditSearchTemplate.useType",
|
throw new PlatformDataIntegrityException(
|
||||||
"Invalid Audit Search Template UseType: " + useType); }
|
"error.msg.invalid.auditSearchTemplate.useType",
|
||||||
|
"Invalid Audit Search Template UseType: " + useType);
|
||||||
|
}
|
||||||
|
|
||||||
final Collection<AppUserData> appUsers = appUserReadPlatformService
|
final Collection<AppUserData> appUsers = appUserReadPlatformService
|
||||||
.retrieveSearchTemplate();
|
.retrieveSearchTemplate();
|
||||||
@@ -162,27 +204,14 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
|
|||||||
Collection<ProcessingResultLookup> processingResults = null;
|
Collection<ProcessingResultLookup> processingResults = null;
|
||||||
if (useType.equals("audit")) {
|
if (useType.equals("audit")) {
|
||||||
ProcessingResultsMapper mapper3 = new ProcessingResultsMapper();
|
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,
|
return new AuditSearchData(appUsers, actionNames, entityNames,
|
||||||
processingResults);
|
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> {
|
private static final class ActionNamesMapper implements RowMapper<String> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user