Merge pull request #694 from ashok-conflux/MIFOSX-824
Added pagination support to audit API
This commit is contained in:
+90
-2
@@ -10657,8 +10657,8 @@ Content-Type: application/json
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>List Audits</h4>
|
||||
<p>Get a list of audits that match the criteria supplied,
|
||||
and are within the requestors' data scope.</p>
|
||||
<p>Get a 200 list of audits that match the criteria supplied and sorted by audit id in descending order,
|
||||
and are within the requestors' data scope. Also it supports pagination and sorting</p>
|
||||
<h5>Arguments</h5>
|
||||
<dl class="argument-list">
|
||||
<dt>actionName</dt>
|
||||
@@ -10749,6 +10749,35 @@ Content-Type: application/json
|
||||
<dd>optional, <span>
|
||||
Values are true, false. Default is false.</span>
|
||||
</dd>
|
||||
<dt>paged</dt>
|
||||
<dd>
|
||||
Boolean <span>optional</span>, defaults to false
|
||||
</dd>
|
||||
<dd>If paged is true then results will be paginated.</dd>
|
||||
|
||||
<dt>offset</dt>
|
||||
<dd>
|
||||
Integer <span>optional</span>, defaults to 0
|
||||
</dd>
|
||||
<dd>Indicates from what result to start from.</dd>
|
||||
|
||||
<dt>limit</dt>
|
||||
<dd>
|
||||
Integer <span>optional</span>, defaults to 200
|
||||
</dd>
|
||||
<dd>Restricts the size of results returned. To override the default and return all entries you must explicitly pass a non-positive integer value for limit e.g. limit=0, or limit=-1</dd>
|
||||
|
||||
<dt>orderBy</dt>
|
||||
<dd>
|
||||
String <span>optional</span>, one of <span>id, actionName, entityName, resourceId, subresourceId, madeOnDate, checkedOnDate, officeName, groupName, clientName, loanAccountNo, savingsAccountNo</span>
|
||||
</dd>
|
||||
<dd>Orders the results by the field indicated.</dd>
|
||||
|
||||
<dt>sortBy</dt>
|
||||
<dd>
|
||||
String <span>optional</span>, one of <span>ASC, DESC</span>
|
||||
</dd>
|
||||
<dd>Indicates what way to order results if <i>orderBy</i> is used.</dd>
|
||||
|
||||
</dl>
|
||||
<p>Example Requests:</p>
|
||||
@@ -10842,6 +10871,65 @@ GET https://DomainName/api/v1/audits
|
||||
},...
|
||||
]
|
||||
</code>
|
||||
<code class="method-declaration">
|
||||
GET https://DomainName/api/v1/audits?paged=true&limit=5
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"totalFilteredRecords": 30,
|
||||
"pageItems": [
|
||||
{
|
||||
"id": 671,
|
||||
"actionName": "PERMISSIONS",
|
||||
"entityName": "ROLE",
|
||||
"resourceId": 6,
|
||||
"maker": "keithwoodlock",
|
||||
"madeOnDate": 1365014262000,
|
||||
"processingResult": "processed"
|
||||
},
|
||||
{
|
||||
"id": 670,
|
||||
"actionName": "CREATE",
|
||||
"entityName": "CLIENTNOTE",
|
||||
"resourceId": 287,
|
||||
"maker": "keithwoodlock",
|
||||
"madeOnDate": 1365014204000,
|
||||
"processingResult": "awaiting.approval",
|
||||
"officeName": "my office",
|
||||
"clientName": "gg ggg"
|
||||
},
|
||||
{
|
||||
"id": 668,
|
||||
"actionName": "UPDATE",
|
||||
"entityName": "PERMISSION",
|
||||
"maker": "keithwoodlock",
|
||||
"madeOnDate": 1365014186000,
|
||||
"processingResult": "processed"
|
||||
},
|
||||
{
|
||||
"id": 667,
|
||||
"actionName": "CREATE",
|
||||
"entityName": "CLIENTNOTE",
|
||||
"resourceId": 286,
|
||||
"maker": "keithwoodlock",
|
||||
"madeOnDate": 1365014169000,
|
||||
"processingResult": "processed",
|
||||
"officeName": "my office name",
|
||||
"clientName": "gg ggg"
|
||||
},
|
||||
{
|
||||
"id": 666,
|
||||
"actionName": "CREATE",
|
||||
"entityName": "CLIENT",
|
||||
"resourceId": 363,
|
||||
"maker": "keithwoodlock",
|
||||
"madeOnDate": 1365012843000,
|
||||
"processingResult": "awaiting.approval",
|
||||
"officeName": "my office name"
|
||||
}
|
||||
]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
+11
-2
@@ -26,8 +26,10 @@ import org.mifosplatform.commands.data.AuditSearchData;
|
||||
import org.mifosplatform.commands.service.AuditReadPlatformService;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.data.PaginationParameters;
|
||||
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
||||
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.mifosplatform.infrastructure.core.service.Page;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
@@ -72,15 +74,22 @@ public class AuditsApiResource {
|
||||
@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) {
|
||||
@QueryParam("loanid") final Integer loanId, @QueryParam("savingsAccountId") final Integer savingsAccountId,
|
||||
@QueryParam("paged") final Boolean paged, @QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit,
|
||||
@QueryParam("orderBy") final String orderBy, @QueryParam("sortOrder") final String sortOrder) {
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
|
||||
|
||||
final PaginationParameters parameters = PaginationParameters.instance(paged, offset, limit, orderBy, sortOrder);
|
||||
final String extraCriteria = getExtraCriteria(actionName, entityName, resourceId, makerId, makerDateTimeFrom, makerDateTimeTo,
|
||||
checkerId, checkerDateTimeFrom, checkerDateTimeTo, processingResult, officeId, groupId, clientId, loanId, savingsAccountId);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
if (parameters.isPaged()){
|
||||
final Page<AuditData> auditEntries = this.auditReadPlatformService.retrievePaginatedAuditEntries(extraCriteria, settings.isIncludeJson(), parameters);
|
||||
return this.toApiJsonSerializer.serialize(settings, auditEntries, this.RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
final Collection<AuditData> auditEntries = this.auditReadPlatformService.retrieveAuditEntries(extraCriteria,
|
||||
settings.isIncludeJson());
|
||||
|
||||
|
||||
+4
@@ -9,10 +9,14 @@ import java.util.Collection;
|
||||
|
||||
import org.mifosplatform.commands.data.AuditData;
|
||||
import org.mifosplatform.commands.data.AuditSearchData;
|
||||
import org.mifosplatform.infrastructure.core.data.PaginationParameters;
|
||||
import org.mifosplatform.infrastructure.core.service.Page;
|
||||
|
||||
public interface AuditReadPlatformService {
|
||||
|
||||
Collection<AuditData> retrieveAuditEntries(String extraCriteria, boolean includeJson);
|
||||
|
||||
Page<AuditData> retrievePaginatedAuditEntries(String extraCriteria, boolean includeJson, PaginationParameters parameters);
|
||||
|
||||
Collection<AuditData> retrieveAllEntriesToBeChecked(String extraCriteria, boolean includeJson);
|
||||
|
||||
|
||||
+52
-4
@@ -8,18 +8,25 @@ package org.mifosplatform.commands.service;
|
||||
import java.lang.reflect.Type;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.mifosplatform.commands.data.AuditData;
|
||||
import org.mifosplatform.commands.data.AuditSearchData;
|
||||
import org.mifosplatform.commands.data.ProcessingResultLookup;
|
||||
import org.mifosplatform.infrastructure.core.data.PaginationParameters;
|
||||
import org.mifosplatform.infrastructure.core.data.PaginationParametersDataValidator;
|
||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.infrastructure.core.service.Page;
|
||||
import org.mifosplatform.infrastructure.core.service.PaginationHelper;
|
||||
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.office.data.OfficeData;
|
||||
@@ -49,6 +56,9 @@ import com.google.gson.JsonObject;
|
||||
public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(AuditReadPlatformServiceImpl.class);
|
||||
private final static Set<String> supportedOrderByValues = new HashSet<String>(Arrays.asList("id", "actionName", "entityName",
|
||||
"resourceId", "subresourceId", "madeOnDate", "checkedOnDate", "officeName", "groupName", "clientName", "loanAccountNo",
|
||||
"savingsAccountNo"));
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final PlatformSecurityContext context;
|
||||
@@ -58,12 +68,15 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
|
||||
private final ClientReadPlatformService clientReadPlatformService;
|
||||
private final LoanProductReadPlatformService loanProductReadPlatformService;
|
||||
private final StaffReadPlatformService staffReadPlatformService;
|
||||
private final PaginationHelper<AuditData> paginationHelper = new PaginationHelper<AuditData>();
|
||||
private final PaginationParametersDataValidator paginationParametersDataValidator;
|
||||
|
||||
@Autowired
|
||||
public AuditReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
|
||||
final FromJsonHelper fromApiJsonHelper, final AppUserReadPlatformService appUserReadPlatformService,
|
||||
final OfficeReadPlatformService officeReadPlatformService, final ClientReadPlatformService clientReadPlatformService,
|
||||
final LoanProductReadPlatformService loanProductReadPlatformService, final StaffReadPlatformService staffReadPlatformService) {
|
||||
final LoanProductReadPlatformService loanProductReadPlatformService, final StaffReadPlatformService staffReadPlatformService,
|
||||
final PaginationParametersDataValidator paginationParametersDataValidator) {
|
||||
this.context = context;
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
@@ -72,6 +85,7 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
|
||||
this.clientReadPlatformService = clientReadPlatformService;
|
||||
this.loanProductReadPlatformService = loanProductReadPlatformService;
|
||||
this.staffReadPlatformService = staffReadPlatformService;
|
||||
this.paginationParametersDataValidator = paginationParametersDataValidator;
|
||||
}
|
||||
|
||||
private static final class AuditMapper implements RowMapper<AuditData> {
|
||||
@@ -145,10 +159,44 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
|
||||
if (StringUtils.isNotBlank(extraCriteria)) {
|
||||
updatedExtraCriteria = " where (" + extraCriteria + ")";
|
||||
}
|
||||
|
||||
updatedExtraCriteria += " order by aud.id DESC";
|
||||
|
||||
updatedExtraCriteria += " order by aud.id DESC limit " + PaginationParameters.getCheckedLimit(null);
|
||||
return retrieveEntries("audit", updatedExtraCriteria, includeJson);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<AuditData> retrievePaginatedAuditEntries(final String extraCriteria, final boolean includeJson, final PaginationParameters parameters) {
|
||||
|
||||
this.paginationParametersDataValidator.validateParameterValues(parameters, supportedOrderByValues, "audits");
|
||||
final AppUser currentUser = this.context.authenticatedUser();
|
||||
final String hierarchy = currentUser.getOffice().getHierarchy();
|
||||
|
||||
String updatedExtraCriteria = "";
|
||||
if (StringUtils.isNotBlank(extraCriteria)) {
|
||||
updatedExtraCriteria = " where (" + extraCriteria + ")";
|
||||
}
|
||||
|
||||
final AuditMapper rm = new AuditMapper();
|
||||
final StringBuilder sqlBuilder = new StringBuilder(200);
|
||||
sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
|
||||
sqlBuilder.append(rm.schema(includeJson, hierarchy));
|
||||
sqlBuilder.append(' ').append(updatedExtraCriteria);
|
||||
|
||||
if (parameters.isOrderByRequested()) {
|
||||
sqlBuilder.append(' ').append(parameters.orderBySql());
|
||||
}else {
|
||||
sqlBuilder.append(' ').append(' ').append(" order by aud.id DESC");
|
||||
}
|
||||
|
||||
if (parameters.isLimited()) {
|
||||
sqlBuilder.append(' ').append(parameters.limitSql());
|
||||
}
|
||||
|
||||
logger.info("sql: " + sqlBuilder.toString());
|
||||
|
||||
final String sqlCountRows = "SELECT FOUND_ROWS()";
|
||||
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), new Object[] {}, rm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<AuditData> retrieveAllEntriesToBeChecked(final String extraCriteria, final boolean includeJson) {
|
||||
@@ -195,7 +243,7 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
|
||||
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] {});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AuditData retrieveAuditEntry(final Long auditId) {
|
||||
|
||||
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.infrastructure.core.data;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Immutable data object representing pagination parameter values.
|
||||
* </p>
|
||||
*/
|
||||
public class PaginationParameters {
|
||||
|
||||
private final boolean paged;
|
||||
private final Integer offset;
|
||||
private final Integer limit;
|
||||
private final String orderBy;
|
||||
private final String sortOrder;
|
||||
|
||||
public static PaginationParameters instance (Boolean paged, Integer offset, Integer limit, String orderBy, String sortOrder){
|
||||
if( null == paged) {
|
||||
paged = false;
|
||||
}
|
||||
|
||||
final Integer maxLimitAllowed = getCheckedLimit(limit);
|
||||
|
||||
return new PaginationParameters(paged, offset, maxLimitAllowed, orderBy, sortOrder);
|
||||
}
|
||||
|
||||
private PaginationParameters(boolean paged, Integer offset, Integer limit, String orderBy, String sortOrder) {
|
||||
this.paged = paged;
|
||||
this.offset = offset;
|
||||
this.limit = limit;
|
||||
this.orderBy = orderBy;
|
||||
this.sortOrder = sortOrder;
|
||||
}
|
||||
|
||||
public static Integer getCheckedLimit(final Integer limit) {
|
||||
|
||||
final Integer maxLimitAllowed = 200;
|
||||
// default to max limit first off
|
||||
Integer checkedLimit = maxLimitAllowed;
|
||||
|
||||
if (limit != null && limit > 0) {
|
||||
checkedLimit = limit;
|
||||
} else if (limit != null) {
|
||||
// unlimited case: limit provided and 0 or less
|
||||
checkedLimit = null;
|
||||
}
|
||||
|
||||
return checkedLimit;
|
||||
}
|
||||
|
||||
public boolean isPaged() {
|
||||
return this.paged;
|
||||
}
|
||||
|
||||
public Integer getOffset() {
|
||||
return this.offset;
|
||||
}
|
||||
|
||||
public Integer getLimit() {
|
||||
return this.limit;
|
||||
}
|
||||
|
||||
public String getOrderBy() {
|
||||
return this.orderBy;
|
||||
}
|
||||
|
||||
public String getSortOrder() {
|
||||
return this.sortOrder;
|
||||
}
|
||||
|
||||
public boolean isOrderByRequested() {
|
||||
return StringUtils.isNotBlank(this.orderBy);
|
||||
}
|
||||
|
||||
public boolean isSortOrderProvided() {
|
||||
return StringUtils.isNotBlank(this.sortOrder);
|
||||
}
|
||||
|
||||
public boolean isLimited() {
|
||||
return this.limit != null && this.limit.intValue() > 0;
|
||||
}
|
||||
|
||||
public boolean isOffset() {
|
||||
return this.offset != null;
|
||||
}
|
||||
|
||||
public String orderBySql(){
|
||||
final StringBuffer sql = new StringBuffer();
|
||||
|
||||
if (this.isOrderByRequested()) {
|
||||
sql.append(" order by ").append(this.getOrderBy());
|
||||
if (this.isSortOrderProvided()) {
|
||||
sql.append(' ').append(this.getSortOrder());
|
||||
}
|
||||
}
|
||||
return sql.toString();
|
||||
}
|
||||
|
||||
public String limitSql(){
|
||||
final StringBuffer sql = new StringBuffer();
|
||||
if (this.isLimited()) {
|
||||
sql.append(" limit ").append(this.getLimit());
|
||||
if (this.isOffset()) {
|
||||
sql.append(" offset ").append(this.getOffset());
|
||||
}
|
||||
}
|
||||
return sql.toString();
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.infrastructure.core.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class PaginationParametersDataValidator {
|
||||
public static Set<String> sortOrderValues = new HashSet<String>(Arrays.asList("ASC", "DESC"));
|
||||
public void validateParameterValues(PaginationParameters parameters, final Set<String> supportedOrdeByValues, final String resourceName) {
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
|
||||
if (parameters.isOrderByRequested() && !supportedOrdeByValues.contains(parameters.getOrderBy())){
|
||||
final String defaultUserMessage = "The orderBy value '" + parameters.getOrderBy() + "' is not supported. The supported orderBy values are " + supportedOrdeByValues.toString();
|
||||
final ApiParameterError error = ApiParameterError.parameterError("validation.msg."+resourceName+".orderBy.value.is.not.supported",
|
||||
defaultUserMessage, "orderBy", parameters.getOrderBy(), supportedOrdeByValues.toString());
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
if (parameters.isSortOrderProvided() && !sortOrderValues.contains(parameters.getSortOrder().toUpperCase())){
|
||||
final String defaultUserMessage = "The sortOrder value '" + parameters.getSortOrder() + "' is not supported. The supported sortOrder values are " + sortOrderValues.toString();
|
||||
final ApiParameterError error = ApiParameterError.parameterError("validation.msg."+resourceName+".sortOrder.value.is.not.supported",
|
||||
defaultUserMessage, "sortOrder", parameters.getSortOrder(), sortOrderValues.toString());
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user