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 2024/09/17 16:39:54 UTC

(fineract) branch develop updated (1cb9a3686 -> e0071715d)

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

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


    from 1cb9a3686 FINERACT-2114: show interest rate change in business events
     new df1b6b363 Update all non-major dependencies
     new e0071715d Fixed caching request body

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 build.gradle                                       |  2 +-
 buildSrc/build.gradle                              |  2 +-
 .../groovy/org.apache.fineract.dependencies.gradle | 28 ++++++-------
 fineract-provider/dependencies.gradle              |  2 +-
 .../http/BodyCachingHttpServletRequestWrapper.java | 12 ++++--
 .../jobs/filter/LoanCOBApiFilter.java              |  4 +-
 .../jobs/filter/LoanCOBFilterHelper.java           | 14 ++++---
 .../jobs/filter/LoanCOBApiFilterTest.java          | 49 ++++++++++++++++------
 .../jobs/filter/LoanCOBFilterHelperTest.java       |  6 +--
 9 files changed, 76 insertions(+), 43 deletions(-)


(fineract) 01/02: Update all non-major dependencies

Posted by ar...@apache.org.
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

commit df1b6b36322bd284a235550d7440bc0861024741
Author: Renovate <bo...@renovateapp.com>
AuthorDate: Tue Sep 17 07:42:32 2024 +0000

    Update all non-major dependencies
---
 build.gradle                                       |  2 +-
 buildSrc/build.gradle                              |  2 +-
 .../groovy/org.apache.fineract.dependencies.gradle | 28 +++++++++++-----------
 3 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/build.gradle b/build.gradle
index 7d41f43b1..5b8f8b394 100644
--- a/build.gradle
+++ b/build.gradle
@@ -95,7 +95,7 @@ plugins {
     id 'com.github.hierynomus.license' version '0.16.1' apply false
     id 'com.github.jk1.dependency-license-report' version '2.9' apply false
     id 'org.zeroturnaround.gradle.jrebel' version '1.2.0' apply false
-    id 'org.springframework.boot' version '3.2.6' apply false
+    id 'org.springframework.boot' version '3.3.3' apply false
     id 'net.ltgt.errorprone' version '3.1.0' apply false
     id 'io.swagger.core.v3.swagger-gradle-plugin' version '2.2.23' apply false
     id 'com.gorylenko.gradle-git-properties' version '2.4.2' apply false
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
index 6f413c4e8..226b07166 100644
--- a/buildSrc/build.gradle
+++ b/buildSrc/build.gradle
@@ -20,7 +20,7 @@
 import static org.slf4j.LoggerFactory.*
 
 plugins {
-    id 'io.spring.dependency-management' version '1.1.4'
+    id 'io.spring.dependency-management' version '1.1.6'
     id 'groovy'
     id 'java-gradle-plugin'
     id 'groovy-gradle-plugin'
diff --git a/buildSrc/src/main/groovy/org.apache.fineract.dependencies.gradle b/buildSrc/src/main/groovy/org.apache.fineract.dependencies.gradle
index 5f6e7fff7..f607336b7 100644
--- a/buildSrc/src/main/groovy/org.apache.fineract.dependencies.gradle
+++ b/buildSrc/src/main/groovy/org.apache.fineract.dependencies.gradle
@@ -23,11 +23,11 @@ apply plugin: 'io.spring.dependency-management'
 dependencyManagement {
     imports {
         mavenBom 'com.squareup.okhttp3:okhttp-bom:4.12.0'
-        mavenBom 'org.slf4j:slf4j-bom:2.0.12'
+        mavenBom 'org.slf4j:slf4j-bom:2.0.16'
         mavenBom 'io.micrometer:micrometer-bom:1.13.4'
-        mavenBom 'org.springframework:spring-framework-bom:6.1.3'
-        mavenBom 'org.springframework.boot:spring-boot-dependencies:3.2.6'
-        mavenBom 'io.awspring.cloud:spring-cloud-aws-dependencies:3.1.0'
+        mavenBom 'org.springframework:spring-framework-bom:6.1.13'
+        mavenBom 'org.springframework.boot:spring-boot-dependencies:3.3.3'
+        mavenBom 'io.awspring.cloud:spring-cloud-aws-dependencies:3.2.0'
         mavenBom 'io.opentelemetry:opentelemetry-bom:1.42.1'
         mavenBom 'org.jetbrains.kotlin:kotlin-bom:1.9.25'
         mavenBom 'org.junit:junit-bom:5.11.0'
@@ -35,7 +35,7 @@ dependencyManagement {
         mavenBom 'io.cucumber:cucumber-bom:7.18.1'
         mavenBom 'io.netty:netty-bom:4.1.113.Final'
         mavenBom 'org.mockito:mockito-bom:5.13.0'
-        mavenBom 'software.amazon.awssdk:bom:2.27.23'
+        mavenBom 'software.amazon.awssdk:bom:2.28.2'
         mavenBom 'io.github.resilience4j:resilience4j-bom:2.2.0'
     }
 
@@ -44,11 +44,11 @@ dependencyManagement {
         // We do not use :+ to get the latest available version available on Maven Central, as that could suddenly break things.
         // We use the Renovate Bot to automatically propose Pull Requests (PRs) when upgrades for all of these versions are available.
 
-        dependency 'ch.qos.logback:logback-core:1.5.3'
-        dependency 'ch.qos.logback:logback-classic:1.5.3'
+        dependency 'ch.qos.logback:logback-core:1.5.8'
+        dependency 'ch.qos.logback:logback-classic:1.5.8'
         dependency 'ch.qos.logback.contrib:logback-json-classic:0.1.5'
         dependency 'ch.qos.logback.contrib:logback-jackson:0.1.5'
-        dependency 'org.codehaus.janino:janino:3.1.11'
+        dependency 'org.codehaus.janino:janino:3.1.12'
 
 
         dependency 'org.eclipse.persistence:org.eclipse.persistence.jpa:4.0.2'
@@ -117,10 +117,10 @@ dependencyManagement {
         dependency 'jakarta.management.j2ee:jakarta.management.j2ee-api:1.1.4'
         dependency 'jakarta.jms:jakarta.jms-api:3.1.0'
         dependency 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0'
-        dependency 'org.glassfish.jersey.media:jersey-media-multipart:3.1.5'
+        dependency 'org.glassfish.jersey.media:jersey-media-multipart:3.1.8'
         dependency 'org.glassfish.jaxb:jaxb-runtime:2.3.6' // Swagger needs exactly this version
         dependency 'org.apache.bval:org.apache.bval.bundle:3.0.1'
-        dependency 'joda-time:joda-time:2.12.7'
+        dependency 'joda-time:joda-time:2.13.0'
 
         dependency 'io.github.classgraph:classgraph:4.8.175'
         dependency 'org.awaitility:awaitility:4.2.2'
@@ -222,11 +222,11 @@ dependencyManagement {
             entry 'json-path'
             entry 'xml-path'
         }
-        dependency 'org.apache.groovy:groovy-xml:4.0.22'
-        dependency 'org.apache.groovy:groovy-json:4.0.22'
+        dependency 'org.apache.groovy:groovy-xml:4.0.23'
+        dependency 'org.apache.groovy:groovy-json:4.0.23'
 
-        dependency 'org.mapstruct:mapstruct:1.6.0'
-        dependency 'org.mapstruct:mapstruct-processor:1.6.0'
+        dependency 'org.mapstruct:mapstruct:1.6.2'
+        dependency 'org.mapstruct:mapstruct-processor:1.6.2'
 
         dependency "org.apache.avro:avro:1.12.0"
 


(fineract) 02/02: Fixed caching request body

Posted by ar...@apache.org.
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

commit e0071715d25f784470e9b01819811c28396d5a3a
Author: Arnold Galovics <ga...@gmail.com>
AuthorDate: Tue Sep 17 13:08:29 2024 +0200

    Fixed caching request body
---
 fineract-provider/dependencies.gradle              |  2 +-
 .../http/BodyCachingHttpServletRequestWrapper.java | 12 ++++--
 .../jobs/filter/LoanCOBApiFilter.java              |  4 +-
 .../jobs/filter/LoanCOBFilterHelper.java           | 14 ++++---
 .../jobs/filter/LoanCOBApiFilterTest.java          | 49 ++++++++++++++++------
 .../jobs/filter/LoanCOBFilterHelperTest.java       |  6 +--
 6 files changed, 60 insertions(+), 27 deletions(-)

diff --git a/fineract-provider/dependencies.gradle b/fineract-provider/dependencies.gradle
index 67d6736e3..7af3a5998 100644
--- a/fineract-provider/dependencies.gradle
+++ b/fineract-provider/dependencies.gradle
@@ -136,7 +136,7 @@ dependencies {
     implementation ('jakarta.xml.bind:jakarta.xml.bind-api') {
         exclude group: 'jakarta.activation'
     }
-    implementation ('org.apache.activemq:activemq-client-jakarta') {
+    implementation ('org.apache.activemq:activemq-client') {
         exclude group: 'org.apache.geronimo.specs'
         exclude group: 'javax.annotation', module: 'javax.annotation-api'
     }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/http/BodyCachingHttpServletRequestWrapper.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/http/BodyCachingHttpServletRequestWrapper.java
index 862d2620e..23a9ad9b0 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/http/BodyCachingHttpServletRequestWrapper.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/http/BodyCachingHttpServletRequestWrapper.java
@@ -35,16 +35,18 @@ import org.apache.commons.io.IOUtils;
 public class BodyCachingHttpServletRequestWrapper extends HttpServletRequestWrapper {
 
     private final byte[] cachedBody;
+    private ByteArrayInputStream inputStream;
 
     @SuppressFBWarnings(value = "CT_CONSTRUCTOR_THROW")
     public BodyCachingHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
         super(request);
         this.cachedBody = IOUtils.toByteArray(request.getInputStream());
+        this.inputStream = new ByteArrayInputStream(cachedBody);
     }
 
     @Override
     public ServletInputStream getInputStream() throws IOException {
-        return new CachedBodyServletInputStream(cachedBody);
+        return new CachedBodyServletInputStream(inputStream);
     }
 
     @Override
@@ -53,12 +55,16 @@ public class BodyCachingHttpServletRequestWrapper extends HttpServletRequestWrap
         return new BufferedReader(new InputStreamReader(byteArrayInputStream, UTF_8));
     }
 
+    public void resetStream() {
+        inputStream = new ByteArrayInputStream(cachedBody);
+    }
+
     public static class CachedBodyServletInputStream extends ServletInputStream {
 
         private final InputStream inputStream;
 
-        public CachedBodyServletInputStream(byte[] cachedBody) {
-            this.inputStream = new ByteArrayInputStream(cachedBody);
+        public CachedBodyServletInputStream(ByteArrayInputStream inputStream) {
+            this.inputStream = inputStream;
         }
 
         @Override
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBApiFilter.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBApiFilter.java
index 56a0be0c1..9bfffb582 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBApiFilter.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBApiFilter.java
@@ -65,7 +65,7 @@ public class LoanCOBApiFilter extends OncePerRequestFilter {
             throws ServletException, IOException {
         request = new BodyCachingHttpServletRequestWrapper(request);
 
-        if (!helper.isOnApiList(request)) {
+        if (!helper.isOnApiList((BodyCachingHttpServletRequestWrapper) request)) {
             proceed(filterChain, request, response);
         } else {
             try {
@@ -74,7 +74,7 @@ public class LoanCOBApiFilter extends OncePerRequestFilter {
                     proceed(filterChain, request, response);
                 } else {
                     try {
-                        List<Long> loanIds = helper.calculateRelevantLoanIds(request);
+                        List<Long> loanIds = helper.calculateRelevantLoanIds((BodyCachingHttpServletRequestWrapper) request);
                         if (!loanIds.isEmpty() && helper.isLoanBehind(loanIds)) {
                             helper.executeInlineCob(loanIds);
                         }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBFilterHelper.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBFilterHelper.java
index 92b282208..40c0a2c42 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBFilterHelper.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBFilterHelper.java
@@ -26,7 +26,6 @@ import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.collect.Lists;
-import jakarta.servlet.http.HttpServletRequest;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
@@ -47,6 +46,7 @@ import org.apache.fineract.cob.service.LoanAccountLockService;
 import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
 import org.apache.fineract.infrastructure.core.config.FineractProperties;
 import org.apache.fineract.infrastructure.core.domain.ExternalId;
+import org.apache.fineract.infrastructure.core.http.BodyCachingHttpServletRequestWrapper;
 import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
 import org.apache.fineract.infrastructure.jobs.exception.LoanIdsHardLockedException;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
@@ -113,7 +113,7 @@ public class LoanCOBFilterHelper implements InitializingBean {
         return LOAN_PATH_PATTERN.matcher(pathInfo).matches() && pathInfo.contains("/v1/rescheduleloans/");
     }
 
-    public boolean isOnApiList(HttpServletRequest request) throws IOException {
+    public boolean isOnApiList(BodyCachingHttpServletRequestWrapper request) throws IOException {
         String pathInfo = request.getPathInfo();
         String method = request.getMethod();
         if (StringUtils.isBlank(pathInfo)) {
@@ -126,7 +126,7 @@ public class LoanCOBFilterHelper implements InitializingBean {
         }
     }
 
-    private boolean isBatchApiMatching(HttpServletRequest request) throws IOException {
+    private boolean isBatchApiMatching(BodyCachingHttpServletRequestWrapper request) throws IOException {
         for (BatchRequest batchRequest : getBatchRequests(request)) {
             String method = batchRequest.getMethod();
             String pathInfo = batchRequest.getRelativeUrl();
@@ -137,8 +137,10 @@ public class LoanCOBFilterHelper implements InitializingBean {
         return false;
     }
 
-    private List<BatchRequest> getBatchRequests(HttpServletRequest request) throws IOException {
+    private List<BatchRequest> getBatchRequests(BodyCachingHttpServletRequestWrapper request) throws IOException {
         List<BatchRequest> batchRequests = objectMapper.readValue(request.getInputStream(), new TypeReference<>() {});
+        // since we read body, we have to reset so the upcoming readings are successful
+        request.resetStream();
         for (BatchRequest batchRequest : batchRequests) {
             String pathInfo = "/" + batchRequest.getRelativeUrl();
             if (!isRelativeUrlVersioned(batchRequest.getRelativeUrl())) {
@@ -192,7 +194,7 @@ public class LoanCOBFilterHelper implements InitializingBean {
         return CollectionUtils.isNotEmpty(loanIdAndLastClosedBusinessDates);
     }
 
-    public List<Long> calculateRelevantLoanIds(HttpServletRequest request) throws IOException {
+    public List<Long> calculateRelevantLoanIds(BodyCachingHttpServletRequestWrapper request) throws IOException {
         String pathInfo = request.getPathInfo();
         if (isBatchApi(pathInfo)) {
             return getLoanIdsFromBatchApi(request);
@@ -201,7 +203,7 @@ public class LoanCOBFilterHelper implements InitializingBean {
         }
     }
 
-    private List<Long> getLoanIdsFromBatchApi(HttpServletRequest request) throws IOException {
+    private List<Long> getLoanIdsFromBatchApi(BodyCachingHttpServletRequestWrapper request) throws IOException {
         List<Long> loanIds = new ArrayList<>();
         for (BatchRequest batchRequest : getBatchRequests(request)) {
             // check the URL for Loan related ID
diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBApiFilterTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBApiFilterTest.java
index e4ad8e63d..ff78d092d 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBApiFilterTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBApiFilterTest.java
@@ -32,6 +32,7 @@ import com.sun.research.ws.wadl.HTTPMethods;
 import jakarta.servlet.FilterChain;
 import jakarta.servlet.ServletException;
 import jakarta.servlet.http.HttpServletRequest;
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.math.BigDecimal;
@@ -144,7 +145,9 @@ class LoanCOBApiFilterTest {
 
         given(request.getPathInfo()).willReturn("/v1/jobs/2/inline");
         given(request.getMethod()).willReturn(HTTPMethods.POST.value());
-        given(request.getInputStream()).willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new byte[0]));
+        final byte[] cachedBody = new byte[0];
+        given(request.getInputStream())
+                .willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new ByteArrayInputStream(cachedBody)));
 
         testObj.doFilterInternal(request, response, filterChain);
         verify(filterChain, times(1)).doFilter(any(HttpServletRequest.class), eq(response));
@@ -165,7 +168,9 @@ class LoanCOBApiFilterTest {
 
         given(request.getPathInfo()).willReturn("/v1/loans/invalid2LoanId/charges");
         given(request.getMethod()).willReturn(HTTPMethods.POST.value());
-        given(request.getInputStream()).willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new byte[0]));
+        final byte[] cachedBody = new byte[0];
+        given(request.getInputStream())
+                .willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new ByteArrayInputStream(cachedBody)));
         given(context.authenticatedUser()).willReturn(appUser);
         given(fineractProperties.getQuery()).willReturn(fineractQueryProperties);
         given(fineractQueryProperties.getInClauseParameterSizeLimit()).willReturn(65000);
@@ -185,7 +190,9 @@ class LoanCOBApiFilterTest {
 
         given(request.getPathInfo()).willReturn("/v1/jobs/2/inline");
         given(request.getMethod()).willReturn(HTTPMethods.POST.value());
-        given(request.getInputStream()).willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new byte[0]));
+        final byte[] cachedBody = new byte[0];
+        given(request.getInputStream())
+                .willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new ByteArrayInputStream(cachedBody)));
         given(context.authenticatedUser()).willReturn(appUser);
         given(appUser.isBypassUser()).willReturn(true);
 
@@ -208,7 +215,9 @@ class LoanCOBApiFilterTest {
 
         given(request.getPathInfo()).willReturn("/v1/loans/2/charges");
         given(request.getMethod()).willReturn(HTTPMethods.POST.value());
-        given(request.getInputStream()).willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new byte[0]));
+        final byte[] cachedBody = new byte[0];
+        given(request.getInputStream())
+                .willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new ByteArrayInputStream(cachedBody)));
         given(loanAccountLockService.isLoanHardLocked(2L)).willReturn(false);
         given(context.authenticatedUser()).willReturn(appUser);
         given(fineractProperties.getQuery()).willReturn(fineractQueryProperties);
@@ -235,7 +244,9 @@ class LoanCOBApiFilterTest {
         String uuid = UUID.randomUUID().toString();
         given(request.getPathInfo()).willReturn("/v1/loans/external-id/" + uuid + "/charges");
         given(request.getMethod()).willReturn(HTTPMethods.POST.value());
-        given(request.getInputStream()).willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new byte[0]));
+        final byte[] cachedBody = new byte[0];
+        given(request.getInputStream())
+                .willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new ByteArrayInputStream(cachedBody)));
         given(loanAccountLockService.isLoanHardLocked(2L)).willReturn(false);
         given(context.authenticatedUser()).willReturn(appUser);
         given(loanRepository.findIdByExternalId(any())).willReturn(2L);
@@ -263,7 +274,9 @@ class LoanCOBApiFilterTest {
         Long resourceId = 123L;
         given(request.getPathInfo()).willReturn("/v1/rescheduleloans/" + resourceId + "/charges");
         given(request.getMethod()).willReturn(HTTPMethods.POST.value());
-        given(request.getInputStream()).willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new byte[0]));
+        final byte[] cachedBody = new byte[0];
+        given(request.getInputStream())
+                .willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new ByteArrayInputStream(cachedBody)));
         given(loanAccountLockService.isLoanHardLocked(2L)).willReturn(false);
         given(fineractProperties.getQuery()).willReturn(fineractQueryProperties);
         given(fineractQueryProperties.getInClauseParameterSizeLimit()).willReturn(65000);
@@ -296,7 +309,9 @@ class LoanCOBApiFilterTest {
         given(result.getLastClosedBusinessDate()).willReturn(businessDate.minusDays(2));
         given(request.getPathInfo()).willReturn("/v1/loans/2?command=approve");
         given(request.getMethod()).willReturn(HTTPMethods.POST.value());
-        given(request.getInputStream()).willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new byte[0]));
+        final byte[] cachedBody = new byte[0];
+        given(request.getInputStream())
+                .willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new ByteArrayInputStream(cachedBody)));
         given(loanAccountLockService.isLoanHardLocked(2L)).willReturn(false);
         given(fineractProperties.getQuery()).willReturn(fineractQueryProperties);
         given(fineractQueryProperties.getInClauseParameterSizeLimit()).willReturn(65000);
@@ -327,7 +342,9 @@ class LoanCOBApiFilterTest {
         given(result.getId()).willReturn(2L);
         given(request.getPathInfo()).willReturn("/v1/loans/2?command=approve");
         given(request.getMethod()).willReturn(HTTPMethods.POST.value());
-        given(request.getInputStream()).willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new byte[0]));
+        final byte[] cachedBody = new byte[0];
+        given(request.getInputStream())
+                .willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new ByteArrayInputStream(cachedBody)));
         given(loanAccountLockService.isLoanHardLocked(2L)).willReturn(false);
         given(fineractProperties.getQuery()).willReturn(fineractQueryProperties);
         given(fineractQueryProperties.getInClauseParameterSizeLimit()).willReturn(65000);
@@ -350,7 +367,9 @@ class LoanCOBApiFilterTest {
 
         given(request.getPathInfo()).willReturn("/v1/loans");
         given(request.getMethod()).willReturn(HTTPMethods.POST.value());
-        given(request.getInputStream()).willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new byte[0]));
+        final byte[] cachedBody = new byte[0];
+        given(request.getInputStream())
+                .willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new ByteArrayInputStream(cachedBody)));
 
         given(context.authenticatedUser()).willReturn(appUser);
 
@@ -368,7 +387,9 @@ class LoanCOBApiFilterTest {
 
         given(request.getPathInfo()).willReturn("/v1/loans/catch-up");
         given(request.getMethod()).willReturn(HTTPMethods.POST.value());
-        given(request.getInputStream()).willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new byte[0]));
+        final byte[] cachedBody = new byte[0];
+        given(request.getInputStream())
+                .willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new ByteArrayInputStream(cachedBody)));
 
         given(context.authenticatedUser()).willReturn(appUser);
 
@@ -387,7 +408,9 @@ class LoanCOBApiFilterTest {
 
         given(request.getPathInfo()).willReturn("/v1/loans/2/charges");
         given(request.getMethod()).willReturn(HTTPMethods.POST.value());
-        given(request.getInputStream()).willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new byte[0]));
+        final byte[] cachedBody = new byte[0];
+        given(request.getInputStream())
+                .willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new ByteArrayInputStream(cachedBody)));
         given(loanAccountLockService.isLoanHardLocked(2L)).willReturn(true);
         given(response.getWriter()).willReturn(writer);
         given(context.authenticatedUser()).willReturn(appUser);
@@ -409,7 +432,9 @@ class LoanCOBApiFilterTest {
 
         given(request.getPathInfo()).willReturn("/v1/loans/glimAccount/2");
         given(request.getMethod()).willReturn(HTTPMethods.POST.value());
-        given(request.getInputStream()).willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new byte[0]));
+        final byte[] cachedBody = new byte[0];
+        given(request.getInputStream())
+                .willReturn(new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(new ByteArrayInputStream(cachedBody)));
         given(glimAccountInfoRepository.findOneByIsAcceptingChildAndApplicationId(true, BigDecimal.valueOf(2))).willReturn(glimAccount);
         given(glimAccount.getChildLoan()).willReturn(Collections.singleton(loan));
         given(loan.getId()).willReturn(loanId);
diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBFilterHelperTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBFilterHelperTest.java
index edadf4dcb..9c9a38fe6 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBFilterHelperTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBFilterHelperTest.java
@@ -18,7 +18,7 @@
  */
 package org.apache.fineract.infrastructure.jobs.filter;
 
-import jakarta.servlet.http.HttpServletRequest;
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.nio.charset.Charset;
 import java.util.List;
@@ -116,10 +116,10 @@ public class LoanCOBFilterHelperTest {
                 ]
                 """;
 
-        HttpServletRequest httpServletRequest = Mockito.mock(HttpServletRequest.class);
+        BodyCachingHttpServletRequestWrapper httpServletRequest = Mockito.mock(BodyCachingHttpServletRequestWrapper.class);
         Mockito.when(httpServletRequest.getPathInfo()).thenReturn("/v1/batches/endpoint");
         BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream inputStream = new BodyCachingHttpServletRequestWrapper.CachedBodyServletInputStream(
-                json.getBytes(Charset.forName("UTF-8")));
+                new ByteArrayInputStream(json.getBytes(Charset.forName("UTF-8"))));
         Mockito.when(httpServletRequest.getInputStream()).thenReturn(inputStream);
         List<Long> loanIds = helper.calculateRelevantLoanIds(httpServletRequest);
         Assertions.assertEquals(0, loanIds.size());