You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ar...@apache.org on 2022/06/22 12:44:02 UTC

[fineract] branch develop updated: Specify query parameters for LoanTransactionsApi retrieveTransaction

This is an automated email from the ASF dual-hosted git repository.

arnold pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new 470ff9a74 Specify query parameters for LoanTransactionsApi retrieveTransaction
470ff9a74 is described below

commit 470ff9a745801688e22311836e6142076b9ee2ad
Author: Jose Alberto Hernandez <al...@MacBook-Pro.local>
AuthorDate: Sat Jun 18 00:43:00 2022 -0500

    Specify query parameters for LoanTransactionsApi retrieveTransaction
---
 .../batch/command/CommandStrategyUtils.java        | 64 ++++++++++++++++++++++
 .../GetTransactionByIdCommandStrategy.java         | 38 +++++++++++--
 .../api/LoanTransactionsApiResource.java           |  2 +
 .../self/loanaccount/api/SelfLoansApiResource.java |  5 +-
 .../GetTransactionByIdCommandStrategyTest.java     | 36 ++++++++----
 5 files changed, 126 insertions(+), 19 deletions(-)

diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/command/CommandStrategyUtils.java b/fineract-provider/src/main/java/org/apache/fineract/batch/command/CommandStrategyUtils.java
new file mode 100644
index 000000000..3510392d1
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/batch/command/CommandStrategyUtils.java
@@ -0,0 +1,64 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.batch.command;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.fineract.infrastructure.core.api.MutableUriInfo;
+
+public final class CommandStrategyUtils {
+
+    private CommandStrategyUtils() {
+
+    }
+
+    /**
+     * Get query parameters from relative URL.
+     *
+     * @param relativeUrl
+     *            the relative URL
+     * @return the query parameters in a map
+     */
+    public static Map<String, String> getQueryParameters(final String relativeUrl) {
+        final String queryParameterStr = StringUtils.substringAfter(relativeUrl, "?");
+        final String[] queryParametersArray = StringUtils.split(queryParameterStr, "&");
+        final Map<String, String> queryParametersMap = new HashMap<>();
+        for (String parameterStr : queryParametersArray) {
+            String[] keyValue = StringUtils.split(parameterStr, "=");
+            queryParametersMap.put(keyValue[0], keyValue[1]);
+        }
+        return queryParametersMap;
+    }
+
+    /**
+     * Add query parameters(received in the relative URL) to URI info query parameters.
+     *
+     * @param uriInfo
+     *            the URI info
+     * @param queryParameters
+     *            the query parameters
+     */
+    public static void addQueryParametersToUriInfo(final MutableUriInfo uriInfo, final Map<String, String> queryParameters) {
+        for (Map.Entry<String, String> entry : queryParameters.entrySet()) {
+            uriInfo.addAdditionalQueryParameter(entry.getKey(), entry.getValue());
+        }
+    }
+
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/GetTransactionByIdCommandStrategy.java b/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/GetTransactionByIdCommandStrategy.java
index e736c6a54..dad95e275 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/GetTransactionByIdCommandStrategy.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/GetTransactionByIdCommandStrategy.java
@@ -19,14 +19,19 @@
 package org.apache.fineract.batch.command.internal;
 
 import com.google.common.base.Splitter;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import javax.ws.rs.core.UriInfo;
+import liquibase.repackaged.org.apache.commons.lang3.StringUtils;
 import lombok.RequiredArgsConstructor;
 import org.apache.fineract.batch.command.CommandStrategy;
+import org.apache.fineract.batch.command.CommandStrategyUtils;
 import org.apache.fineract.batch.domain.BatchRequest;
 import org.apache.fineract.batch.domain.BatchResponse;
 import org.apache.fineract.batch.exception.ErrorHandler;
 import org.apache.fineract.batch.exception.ErrorInfo;
+import org.apache.fineract.infrastructure.core.api.MutableUriInfo;
 import org.apache.fineract.portfolio.loanaccount.api.LoanTransactionsApiResource;
 import org.apache.http.HttpStatus;
 import org.springframework.stereotype.Component;
@@ -48,6 +53,7 @@ public class GetTransactionByIdCommandStrategy implements CommandStrategy {
 
     @Override
     public BatchResponse execute(final BatchRequest request, UriInfo uriInfo) {
+        final MutableUriInfo parameterizedUriInfo = new MutableUriInfo(uriInfo);
 
         final BatchResponse response = new BatchResponse();
         final String responseBody;
@@ -55,16 +61,37 @@ public class GetTransactionByIdCommandStrategy implements CommandStrategy {
         response.setRequestId(request.getRequestId());
         response.setHeaders(request.getHeaders());
 
+        final String relativeUrl = request.getRelativeUrl();
+
         // Get the loan and transaction ids for use in loanTransactionsApiResource
-        final List<String> pathParameters = Splitter.on('/').splitToList(request.getRelativeUrl());
-        final Long loanId = Long.parseLong(pathParameters.get(1));
-        final Long transactionId = Long.parseLong(pathParameters.get(3));
+        final List<String> pathParameters = Splitter.on('/').splitToList(relativeUrl);
+        Long loanId = Long.parseLong(pathParameters.get(1));
+        Long transactionId;
+        if (relativeUrl.indexOf('?') > 0) {
+            transactionId = Long.parseLong(StringUtils.substringBeforeLast(pathParameters.get(3), "?"));
+        } else {
+            transactionId = Long.parseLong(pathParameters.get(3));
+        }
+
+        Map<String, String> queryParameters = new HashMap<>();
+        if (relativeUrl.indexOf('?') > 0) {
+            queryParameters = CommandStrategyUtils.getQueryParameters(relativeUrl);
+
+            // Add the query parameters sent in the relative URL to UriInfo
+            CommandStrategyUtils.addQueryParametersToUriInfo(parameterizedUriInfo, queryParameters);
+        }
+
+        String fields = null;
+        if (!queryParameters.isEmpty()) {
+            if (queryParameters.containsKey("fields")) {
+                fields = queryParameters.get("fields");
+            }
+        }
 
         // Try-catch blocks to map exceptions to appropriate status codes
         try {
-
             // Calls 'retrieveTransaction' function from 'loanTransactionsApiResource'
-            responseBody = loanTransactionsApiResource.retrieveTransaction(loanId, transactionId, uriInfo);
+            responseBody = loanTransactionsApiResource.retrieveTransaction(loanId, transactionId, fields, uriInfo);
 
             response.setStatusCode(HttpStatus.SC_OK);
 
@@ -83,5 +110,4 @@ public class GetTransactionByIdCommandStrategy implements CommandStrategy {
 
         return response;
     }
-
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanTransactionsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanTransactionsApiResource.java
index 985566905..f23cd5fce 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanTransactionsApiResource.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanTransactionsApiResource.java
@@ -20,6 +20,7 @@ package org.apache.fineract.portfolio.loanaccount.api;
 
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.enums.ParameterIn;
 import io.swagger.v3.oas.annotations.media.Content;
 import io.swagger.v3.oas.annotations.media.Schema;
 import io.swagger.v3.oas.annotations.parameters.RequestBody;
@@ -206,6 +207,7 @@ public class LoanTransactionsApiResource {
             @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoanTransactionsApiResourceSwagger.GetLoansLoanIdTransactionsTransactionIdResponse.class))) })
     public String retrieveTransaction(@PathParam("loanId") @Parameter(description = "loanId") final Long loanId,
             @PathParam("transactionId") @Parameter(description = "transactionId") final Long transactionId,
+            @QueryParam("fields") @Parameter(in = ParameterIn.QUERY, name = "fields", description = "Optional Loan Transaction attribute list to be in the response", required = false, example = "id,date,amount") final String fields,
             @Context final UriInfo uriInfo) {
 
         this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/loanaccount/api/SelfLoansApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/loanaccount/api/SelfLoansApiResource.java
index 6fc70e4b7..2e9c104a4 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/loanaccount/api/SelfLoansApiResource.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/loanaccount/api/SelfLoansApiResource.java
@@ -20,6 +20,7 @@ package org.apache.fineract.portfolio.self.loanaccount.api;
 
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.enums.ParameterIn;
 import io.swagger.v3.oas.annotations.media.ArraySchema;
 import io.swagger.v3.oas.annotations.media.Content;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -62,7 +63,6 @@ import org.springframework.stereotype.Component;
 @Path("/self/loans")
 @Component
 @Scope("singleton")
-
 @Tag(name = "Self Loans", description = "")
 public class SelfLoansApiResource {
 
@@ -123,13 +123,14 @@ public class SelfLoansApiResource {
             @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = SelfLoansApiResourceSwagger.GetSelfLoansLoanIdTransactionsTransactionIdResponse.class))) })
     public String retrieveTransaction(@PathParam("loanId") @Parameter(description = "loanId") final Long loanId,
             @PathParam("transactionId") @Parameter(description = "transactionId") final Long transactionId,
+            @QueryParam("fields") @Parameter(in = ParameterIn.QUERY, name = "fields", description = "Optional Loan Transaction attribute list to be in the response", required = false, example = "id,date,amount") final String fields,
             @Context final UriInfo uriInfo) {
 
         this.dataValidator.validateRetrieveTransaction(uriInfo);
 
         validateAppuserLoanMapping(loanId);
 
-        return this.loanTransactionsApiResource.retrieveTransaction(loanId, transactionId, uriInfo);
+        return this.loanTransactionsApiResource.retrieveTransaction(loanId, transactionId, fields, uriInfo);
     }
 
     @GET
diff --git a/fineract-provider/src/test/java/org/apache/fineract/batch/command/internal/GetTransactionByIdCommandStrategyTest.java b/fineract-provider/src/test/java/org/apache/fineract/batch/command/internal/GetTransactionByIdCommandStrategyTest.java
index bec2cfdc0..fe92be9dc 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/batch/command/internal/GetTransactionByIdCommandStrategyTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/batch/command/internal/GetTransactionByIdCommandStrategyTest.java
@@ -20,9 +20,12 @@ package org.apache.fineract.batch.command.internal;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.BDDMockito.given;
 import static org.mockito.Mockito.when;
 
+import java.util.stream.Stream;
 import javax.ws.rs.HttpMethod;
 import javax.ws.rs.core.UriInfo;
 import org.apache.commons.lang3.RandomStringUtils;
@@ -33,22 +36,30 @@ import org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException
 import org.apache.fineract.portfolio.loanaccount.exception.LoanTransactionNotFoundException;
 import org.apache.http.HttpStatus;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
 public class GetTransactionByIdCommandStrategyTest {
 
+    private static Stream<Arguments> provideQueryParameters() {
+        return Stream.of(Arguments.of(null, 0), Arguments.of("id,date,amount", 1));
+    }
+
     /**
      * Test {@link GetTransactionByIdCommandStrategy#execute} happy path scenario.
      */
-    @Test
-    public void testExecuteSuccessScenario() {
+    @ParameterizedTest
+    @MethodSource("provideQueryParameters")
+    public void testExecuteSuccessScenario(final String fields, final int noOfQueryParams) {
         // given
         final TestContext testContext = new TestContext();
 
         final Long loanId = Long.valueOf(RandomStringUtils.randomNumeric(4));
         final Long transactionId = Long.valueOf(RandomStringUtils.randomNumeric(4));
-        final BatchRequest request = getBatchRequest(loanId, transactionId);
+        final BatchRequest request = getBatchRequest(loanId, transactionId, fields);
         final String responseBody = "{\"id\":12,\"officeId\":1,\"officeName\":\"Head Office\",\"type\":{\"id\":10,\"code\":"
                 + "\"loanTransactionType.accrual\",\"value\":\"Accrual\",\"disbursement\":false,\"repaymentAtDisbursement\":false,"
                 + "\"repayment\":false,\"contra\":false,\"waiveInterest\":false,\"waiveCharges\":false,\"accrual\":true,\"writeOff\":false,"
@@ -60,7 +71,7 @@ public class GetTransactionByIdCommandStrategyTest {
                 + "\"unrecognizedIncomePortion\":0,\"outstandingLoanBalance\":0,\"submittedOnDate\":[2022,3,29],\"manuallyReversed\":false,"
                 + "\"loanChargePaidByList\":[],\"numberOfRepayments\":0}";
 
-        given(testContext.loanTransactionsApiResource.retrieveTransaction(loanId, transactionId, testContext.uriInfo))
+        given(testContext.loanTransactionsApiResource.retrieveTransaction(eq(loanId), eq(transactionId), eq(fields), any(UriInfo.class)))
                 .willReturn(responseBody);
 
         // when
@@ -82,9 +93,9 @@ public class GetTransactionByIdCommandStrategyTest {
         final TestContext testContext = new TestContext();
         final Long loanId = Long.valueOf(RandomStringUtils.randomNumeric(4));
         final Long transactionId = Long.valueOf(RandomStringUtils.randomNumeric(4));
-        final BatchRequest request = getBatchRequest(loanId, transactionId);
+        final BatchRequest request = getBatchRequest(loanId, transactionId, null);
 
-        given(testContext.loanTransactionsApiResource.retrieveTransaction(loanId, transactionId, testContext.uriInfo))
+        given(testContext.loanTransactionsApiResource.retrieveTransaction(loanId, transactionId, null, testContext.uriInfo))
                 .willThrow(new RuntimeException("Some error"));
 
         // when
@@ -106,9 +117,9 @@ public class GetTransactionByIdCommandStrategyTest {
         final TestContext testContext = new TestContext();
         final Long loanId = Long.valueOf(RandomStringUtils.randomNumeric(4));
         final Long transactionId = Long.valueOf(RandomStringUtils.randomNumeric(4));
-        final BatchRequest request = getBatchRequest(loanId, transactionId);
+        final BatchRequest request = getBatchRequest(loanId, transactionId, null);
 
-        given(testContext.loanTransactionsApiResource.retrieveTransaction(loanId, transactionId, testContext.uriInfo))
+        given(testContext.loanTransactionsApiResource.retrieveTransaction(loanId, transactionId, null, testContext.uriInfo))
                 .willThrow(new LoanNotFoundException(loanId));
 
         // when
@@ -129,9 +140,9 @@ public class GetTransactionByIdCommandStrategyTest {
         final TestContext testContext = new TestContext();
         final Long loanId = Long.valueOf(RandomStringUtils.randomNumeric(4));
         final Long transactionId = Long.valueOf(RandomStringUtils.randomNumeric(4));
-        final BatchRequest request = getBatchRequest(loanId, transactionId);
+        final BatchRequest request = getBatchRequest(loanId, transactionId, null);
 
-        when(testContext.loanTransactionsApiResource.retrieveTransaction(loanId, transactionId, testContext.uriInfo))
+        when(testContext.loanTransactionsApiResource.retrieveTransaction(loanId, transactionId, null, testContext.uriInfo))
                 .thenThrow(new LoanTransactionNotFoundException(transactionId));
 
         final BatchResponse response = testContext.subjectToTest.execute(request, testContext.uriInfo);
@@ -151,10 +162,13 @@ public class GetTransactionByIdCommandStrategyTest {
      *            the transaction id
      * @return BatchRequest
      */
-    private BatchRequest getBatchRequest(final Long loanId, final Long transactionId) {
+    private BatchRequest getBatchRequest(final Long loanId, final Long transactionId, final String fields) {
 
         final BatchRequest br = new BatchRequest();
         String relativeUrl = "loans/" + loanId + "/transactions/" + transactionId;
+        if (fields != null) {
+            relativeUrl = relativeUrl + "?fields=" + fields;
+        }
 
         br.setRequestId(Long.valueOf(RandomStringUtils.randomNumeric(5)));
         br.setRelativeUrl(relativeUrl);