FINERACT-1724: Limiting query result for search API to prevent OOMs and support for loanId parameter for retrieving loan reschedule requests
This commit is contained in:
committed by
Arnold Gálovics
parent
0f1559cc7a
commit
5b6f334379
+3
-22
@@ -198,7 +198,8 @@ public class RescheduleLoansApiResource {
|
|||||||
@Operation(summary = "Retrieve all reschedule requests", description = "Retrieve all reschedule requests.")
|
@Operation(summary = "Retrieve all reschedule requests", description = "Retrieve all reschedule requests.")
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = RescheduleLoansApiResourceSwagger.GetLoanRescheduleRequestResponse.class)))) })
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = RescheduleLoansApiResourceSwagger.GetLoanRescheduleRequestResponse.class)))) })
|
||||||
public String retrieveAllRescheduleRequest(@Context final UriInfo uriInfo, @QueryParam("command") final String command) {
|
public String retrieveAllRescheduleRequest(@Context final UriInfo uriInfo, @QueryParam("command") final String command,
|
||||||
|
@QueryParam("loanId") Long loanId) {
|
||||||
|
|
||||||
this.platformSecurityContext.authenticatedUser().validateHasReadPermission(RescheduleLoansApiConstants.ENTITY_NAME);
|
this.platformSecurityContext.authenticatedUser().validateHasReadPermission(RescheduleLoansApiConstants.ENTITY_NAME);
|
||||||
|
|
||||||
@@ -209,28 +210,8 @@ public class RescheduleLoansApiResource {
|
|||||||
RescheduleLoansApiConstants.rejectCommandParamName);
|
RescheduleLoansApiConstants.rejectCommandParamName);
|
||||||
}
|
}
|
||||||
final List<LoanRescheduleRequestData> loanRescheduleRequestsData = this.loanRescheduleRequestReadPlatformService
|
final List<LoanRescheduleRequestData> loanRescheduleRequestsData = this.loanRescheduleRequestReadPlatformService
|
||||||
.retrieveAllRescheduleRequests(command);
|
.retrieveAllRescheduleRequests(command, loanId);
|
||||||
|
|
||||||
return this.loanRescheduleRequestToApiJsonSerializer.serialize(settings, loanRescheduleRequestsData);
|
return this.loanRescheduleRequestToApiJsonSerializer.serialize(settings, loanRescheduleRequestsData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @GET
|
|
||||||
*
|
|
||||||
* @Path("{scheduleId}")
|
|
||||||
*
|
|
||||||
* @Consumes({ MediaType.APPLICATION_JSON })
|
|
||||||
*
|
|
||||||
* @Produces({ MediaType.APPLICATION_JSON }) public String retrieveTemplate(@Context final UriInfo uriInfo) {
|
|
||||||
*
|
|
||||||
* this.platformSecurityContext.authenticatedUser().
|
|
||||||
* validateHasReadPermission(RescheduleLoansApiConstants.ENTITY_NAME); final ApiRequestJsonSerializationSettings
|
|
||||||
* settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
|
||||||
*
|
|
||||||
* LoanRescheduleRequestData loanRescheduleReasons = null; loanRescheduleReasons =
|
|
||||||
* this.loanRescheduleRequestReadPlatformService .retrieveAllRescheduleReasons(RescheduleLoansApiConstants.
|
|
||||||
* LOAN_RESCHEDULE_REASON);
|
|
||||||
*
|
|
||||||
* return this.loanRescheduleRequestToApiJsonSerializer.serialize(settings, loanRescheduleReasons); }
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -67,5 +67,5 @@ public interface LoanRescheduleRequestReadPlatformService {
|
|||||||
* pending for approval reject - give all rejected requests
|
* pending for approval reject - give all rejected requests
|
||||||
* @return list of LoanRescheduleRequestData objects
|
* @return list of LoanRescheduleRequestData objects
|
||||||
**/
|
**/
|
||||||
List<LoanRescheduleRequestData> retrieveAllRescheduleRequests(String command);
|
List<LoanRescheduleRequestData> retrieveAllRescheduleRequests(String command, Long loanId);
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-5
@@ -18,6 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.portfolio.loanaccount.rescheduleloan.service;
|
package org.apache.fineract.portfolio.loanaccount.rescheduleloan.service;
|
||||||
|
|
||||||
|
import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
@@ -271,19 +273,32 @@ public class LoanRescheduleRequestReadPlatformServiceImpl implements LoanResched
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<LoanRescheduleRequestData> retrieveAllRescheduleRequests(String command) {
|
public List<LoanRescheduleRequestData> retrieveAllRescheduleRequests(String command, Long loanId) {
|
||||||
LoanRescheduleRequestRowMapperForBulkApproval loanRescheduleRequestRowMapperForBulkApproval = new LoanRescheduleRequestRowMapperForBulkApproval();
|
LoanRescheduleRequestRowMapperForBulkApproval loanRescheduleRequestRowMapperForBulkApproval = new LoanRescheduleRequestRowMapperForBulkApproval();
|
||||||
String sql = "select " + loanRescheduleRequestRowMapperForBulkApproval.schema();
|
String sql = "select " + loanRescheduleRequestRowMapperForBulkApproval.schema();
|
||||||
|
List<String> extraFilters = new ArrayList<>();
|
||||||
|
List<Object> extraParams = new ArrayList<>();
|
||||||
|
|
||||||
if (!StringUtils.isEmpty(command) && !command.equalsIgnoreCase(RescheduleLoansApiConstants.allCommandParamName)) {
|
if (!StringUtils.isEmpty(command) && !command.equalsIgnoreCase(RescheduleLoansApiConstants.allCommandParamName)) {
|
||||||
sql = sql + " where lrr.status_enum = ? ";
|
int statusParam = 100;
|
||||||
Integer statusParam = 100;
|
|
||||||
if (command.equalsIgnoreCase(RescheduleLoansApiConstants.approveCommandParamName)) {
|
if (command.equalsIgnoreCase(RescheduleLoansApiConstants.approveCommandParamName)) {
|
||||||
statusParam = 200;
|
statusParam = 200;
|
||||||
} else if (command.equalsIgnoreCase(RescheduleLoansApiConstants.rejectCommandParamName)) {
|
} else if (command.equalsIgnoreCase(RescheduleLoansApiConstants.rejectCommandParamName)) {
|
||||||
statusParam = 300;
|
statusParam = 300;
|
||||||
}
|
}
|
||||||
return this.jdbcTemplate.query(sql, loanRescheduleRequestRowMapperForBulkApproval, statusParam); // NOSONAR
|
|
||||||
|
extraFilters.add("lrr.status_enum = ?");
|
||||||
|
extraParams.add(statusParam);
|
||||||
}
|
}
|
||||||
return this.jdbcTemplate.query(sql, loanRescheduleRequestRowMapperForBulkApproval); // NOSONAR
|
|
||||||
|
if (loanId != null) {
|
||||||
|
extraFilters.add("loan.id = ?");
|
||||||
|
extraParams.add(loanId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNotEmpty(extraFilters)) {
|
||||||
|
sql += " where " + String.join(" AND ", extraFilters);
|
||||||
|
}
|
||||||
|
return jdbcTemplate.query(sql, loanRescheduleRequestRowMapperForBulkApproval, extraParams.toArray()); // NOSONAR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-28
@@ -23,9 +23,11 @@ import java.math.RoundingMode;
|
|||||||
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 lombok.RequiredArgsConstructor;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||||
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
|
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
||||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
import org.apache.fineract.organisation.office.data.OfficeData;
|
import org.apache.fineract.organisation.office.data.OfficeData;
|
||||||
import org.apache.fineract.organisation.office.service.OfficeReadPlatformService;
|
import org.apache.fineract.organisation.office.service.OfficeReadPlatformService;
|
||||||
@@ -42,33 +44,24 @@ import org.apache.fineract.portfolio.search.data.AdHocSearchQueryData;
|
|||||||
import org.apache.fineract.portfolio.search.data.SearchConditions;
|
import org.apache.fineract.portfolio.search.data.SearchConditions;
|
||||||
import org.apache.fineract.portfolio.search.data.SearchData;
|
import org.apache.fineract.portfolio.search.data.SearchData;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.jdbc.core.RowMapper;
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
||||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class SearchReadPlatformServiceImpl implements SearchReadPlatformService {
|
public class SearchReadPlatformServiceImpl implements SearchReadPlatformService {
|
||||||
|
|
||||||
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
|
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
private final LoanProductReadPlatformService loanProductReadPlatformService;
|
private final LoanProductReadPlatformService loanProductReadPlatformService;
|
||||||
private final OfficeReadPlatformService officeReadPlatformService;
|
private final OfficeReadPlatformService officeReadPlatformService;
|
||||||
|
private final DatabaseSpecificSQLGenerator sqlGenerator;
|
||||||
@Autowired
|
|
||||||
public SearchReadPlatformServiceImpl(final PlatformSecurityContext context, final NamedParameterJdbcTemplate namedParameterJdbcTemplate,
|
|
||||||
final LoanProductReadPlatformService loanProductReadPlatformService,
|
|
||||||
final OfficeReadPlatformService officeReadPlatformService) {
|
|
||||||
this.context = context;
|
|
||||||
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
|
|
||||||
this.loanProductReadPlatformService = loanProductReadPlatformService;
|
|
||||||
this.officeReadPlatformService = officeReadPlatformService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<SearchData> retriveMatchingData(final SearchConditions searchConditions) {
|
public Collection<SearchData> retriveMatchingData(final SearchConditions searchConditions) {
|
||||||
final AppUser currentUser = this.context.authenticatedUser();
|
final AppUser currentUser = context.authenticatedUser();
|
||||||
final String hierarchy = currentUser.getOffice().getHierarchy();
|
final String hierarchy = currentUser.getOffice().getHierarchy();
|
||||||
|
|
||||||
final SearchMapper rm = new SearchMapper();
|
final SearchMapper rm = new SearchMapper();
|
||||||
@@ -80,11 +73,9 @@ public class SearchReadPlatformServiceImpl implements SearchReadPlatformService
|
|||||||
} else {
|
} else {
|
||||||
params.addValue("search", "%" + searchConditions.getSearchQuery() + "%");
|
params.addValue("search", "%" + searchConditions.getSearchQuery() + "%");
|
||||||
}
|
}
|
||||||
return this.namedParameterJdbcTemplate.query(rm.searchSchema(searchConditions), params, rm);
|
return namedParameterJdbcTemplate.query(searchSchema(searchConditions), params, rm);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class SearchMapper implements RowMapper<SearchData> {
|
|
||||||
|
|
||||||
public String searchSchema(final SearchConditions searchConditions) {
|
public String searchSchema(final SearchConditions searchConditions) {
|
||||||
|
|
||||||
final String union = " union ";
|
final String union = " union ";
|
||||||
@@ -144,9 +135,13 @@ public class SearchReadPlatformServiceImpl implements SearchReadPlatformService
|
|||||||
// remove last occurrence of "union all" string
|
// remove last occurrence of "union all" string
|
||||||
sql.replace(sql.lastIndexOf(union), sql.length(), "");
|
sql.replace(sql.lastIndexOf(union), sql.length(), "");
|
||||||
|
|
||||||
|
// only get the first 50 rows in case of searcing
|
||||||
|
sql.append(" ").append(sqlGenerator.limit(50, 0));
|
||||||
return sql.toString();
|
return sql.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class SearchMapper implements RowMapper<SearchData> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SearchData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
public SearchData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||||
final Long entityId = JdbcSupport.getLong(rs, "entityId");
|
final Long entityId = JdbcSupport.getLong(rs, "entityId");
|
||||||
@@ -187,10 +182,10 @@ public class SearchReadPlatformServiceImpl implements SearchReadPlatformService
|
|||||||
@Override
|
@Override
|
||||||
public AdHocSearchQueryData retrieveAdHocQueryTemplate() {
|
public AdHocSearchQueryData retrieveAdHocQueryTemplate() {
|
||||||
|
|
||||||
this.context.authenticatedUser();
|
context.authenticatedUser();
|
||||||
|
|
||||||
final Collection<LoanProductData> loanProducts = this.loanProductReadPlatformService.retrieveAllLoanProductsForLookup();
|
final Collection<LoanProductData> loanProducts = loanProductReadPlatformService.retrieveAllLoanProductsForLookup();
|
||||||
final Collection<OfficeData> offices = this.officeReadPlatformService.retrieveAllOfficesForDropdown();
|
final Collection<OfficeData> offices = officeReadPlatformService.retrieveAllOfficesForDropdown();
|
||||||
|
|
||||||
return AdHocSearchQueryData.template(loanProducts, offices);
|
return AdHocSearchQueryData.template(loanProducts, offices);
|
||||||
}
|
}
|
||||||
@@ -198,12 +193,12 @@ public class SearchReadPlatformServiceImpl implements SearchReadPlatformService
|
|||||||
@Override
|
@Override
|
||||||
public Collection<AdHocSearchQueryData> retrieveAdHocQueryMatchingData(final AdHocQuerySearchConditions searchConditions) {
|
public Collection<AdHocSearchQueryData> retrieveAdHocQueryMatchingData(final AdHocQuerySearchConditions searchConditions) {
|
||||||
|
|
||||||
this.context.authenticatedUser();
|
context.authenticatedUser();
|
||||||
|
|
||||||
final AdHocQuerySearchMapper rm = new AdHocQuerySearchMapper();
|
final AdHocQuerySearchMapper rm = new AdHocQuerySearchMapper();
|
||||||
final MapSqlParameterSource params = new MapSqlParameterSource();
|
final MapSqlParameterSource params = new MapSqlParameterSource();
|
||||||
|
|
||||||
return this.namedParameterJdbcTemplate.query(rm.schema(searchConditions, params), params, rm);
|
return namedParameterJdbcTemplate.query(rm.schema(searchConditions, params), params, rm);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class AdHocQuerySearchMapper implements RowMapper<AdHocSearchQueryData> {
|
private static final class AdHocQuerySearchMapper implements RowMapper<AdHocSearchQueryData> {
|
||||||
@@ -272,15 +267,11 @@ public class SearchReadPlatformServiceImpl implements SearchReadPlatformService
|
|||||||
if (searchConditions.getIncludeOutStandingAmountPercentage()) {
|
if (searchConditions.getIncludeOutStandingAmountPercentage()) {
|
||||||
if (searchConditions.getOutStandingAmountPercentageCondition().equals("between")) {
|
if (searchConditions.getOutStandingAmountPercentageCondition().equals("between")) {
|
||||||
checkAndUpdateWhereClause(sql);
|
checkAndUpdateWhereClause(sql);
|
||||||
// params.addValue("outStandingAmountPercentageCondition",
|
|
||||||
// searchConditions.getOutStandingAmountPercentageCondition());
|
|
||||||
params.addValue("minOutStandingAmountPercentage", searchConditions.getMinOutStandingAmountPercentage());
|
params.addValue("minOutStandingAmountPercentage", searchConditions.getMinOutStandingAmountPercentage());
|
||||||
params.addValue("maxOutStandingAmountPercentage", searchConditions.getMaxOutStandingAmountPercentage());
|
params.addValue("maxOutStandingAmountPercentage", searchConditions.getMaxOutStandingAmountPercentage());
|
||||||
sql.append(" ( a.percentOut between :minOutStandingAmountPercentage and :maxOutStandingAmountPercentage ) ");
|
sql.append(" ( a.percentOut between :minOutStandingAmountPercentage and :maxOutStandingAmountPercentage ) ");
|
||||||
} else {
|
} else {
|
||||||
checkAndUpdateWhereClause(sql);
|
checkAndUpdateWhereClause(sql);
|
||||||
// params.addValue("outStandingAmountPercentageCondition",
|
|
||||||
// searchConditions.getOutStandingAmountPercentageCondition());
|
|
||||||
params.addValue("outStandingAmountPercentage", searchConditions.getOutStandingAmountPercentage());
|
params.addValue("outStandingAmountPercentage", searchConditions.getOutStandingAmountPercentage());
|
||||||
sql.append(" a.percentOut ").append(searchConditions.getOutStandingAmountPercentageCondition())
|
sql.append(" a.percentOut ").append(searchConditions.getOutStandingAmountPercentageCondition())
|
||||||
.append(" :outStandingAmountPercentage ");
|
.append(" :outStandingAmountPercentage ");
|
||||||
@@ -290,15 +281,11 @@ public class SearchReadPlatformServiceImpl implements SearchReadPlatformService
|
|||||||
if (searchConditions.getIncludeOutstandingAmount()) {
|
if (searchConditions.getIncludeOutstandingAmount()) {
|
||||||
if (searchConditions.getOutstandingAmountCondition().equals("between")) {
|
if (searchConditions.getOutstandingAmountCondition().equals("between")) {
|
||||||
checkAndUpdateWhereClause(sql);
|
checkAndUpdateWhereClause(sql);
|
||||||
// params.addValue("outstandingAmountCondition",
|
|
||||||
// searchConditions.getOutstandingAmountCondition());
|
|
||||||
params.addValue("minOutstandingAmount", searchConditions.getMinOutstandingAmount());
|
params.addValue("minOutstandingAmount", searchConditions.getMinOutstandingAmount());
|
||||||
params.addValue("maxOutstandingAmount", searchConditions.getMaxOutstandingAmount());
|
params.addValue("maxOutstandingAmount", searchConditions.getMaxOutstandingAmount());
|
||||||
sql.append(" ( a.outstandingAmt between :minOutstandingAmount and :maxOutstandingAmount ) ");
|
sql.append(" ( a.outstandingAmt between :minOutstandingAmount and :maxOutstandingAmount ) ");
|
||||||
} else {
|
} else {
|
||||||
checkAndUpdateWhereClause(sql);
|
checkAndUpdateWhereClause(sql);
|
||||||
// params.addValue("outstandingAmountCondition",
|
|
||||||
// searchConditions.getOutstandingAmountCondition());
|
|
||||||
params.addValue("outstandingAmount", searchConditions.getOutstandingAmount());
|
params.addValue("outstandingAmount", searchConditions.getOutstandingAmount());
|
||||||
sql.append(" a.outstandingAmt ").append(searchConditions.getOutstandingAmountCondition())
|
sql.append(" a.outstandingAmt ").append(searchConditions.getOutstandingAmountCondition())
|
||||||
.append(" :outstandingAmount ");
|
.append(" :outstandingAmount ");
|
||||||
|
|||||||
Reference in New Issue
Block a user