diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/instancemode/filter/FineractInstanceModeApiFilter.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/instancemode/filter/FineractInstanceModeApiFilter.java index 6b366d3f6..3ff84bafa 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/instancemode/filter/FineractInstanceModeApiFilter.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/instancemode/filter/FineractInstanceModeApiFilter.java @@ -41,12 +41,16 @@ import org.springframework.web.filter.OncePerRequestFilter; @RequiredArgsConstructor public class FineractInstanceModeApiFilter extends OncePerRequestFilter { - private static final List EXCEPTION_LIST = List.of( - item(FineractProperties.FineractModeProperties::isBatchManagerEnabled, pi -> pi.startsWith("/jobs")), - item(p -> true, pi -> pi.startsWith("/instance-mode")), - // Batches with all GET requests need to be allowed in read-only instances, hence this check will be moved - // under the Api Resource. - item(p -> true, pi -> pi.startsWith("/batches"))); + private static final List EXCEPTION_LIST = List + .of(item(FineractProperties.FineractModeProperties::isBatchManagerEnabled, pi -> pi.startsWith("/jobs")), + item(FineractProperties.FineractModeProperties::isBatchManagerEnabled, pi -> pi.startsWith("/loans/catch-up")), + item(FineractProperties.FineractModeProperties::isBatchManagerEnabled, + pi -> pi.startsWith("/loans/is-catch-up-running")), + item(p -> true, pi -> pi.startsWith("/instance-mode")), + // Batches with all GET requests need to be allowed in read-only instances, hence this check will be + // moved + // under the Api Resource. + item(p -> true, pi -> pi.startsWith("/batches"))); private final FineractProperties fineractProperties; diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/instancemode/filter/FineractInstanceModeApiFilterTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/instancemode/filter/FineractInstanceModeApiFilterTest.java index a071dc5c8..bc395d2ed 100644 --- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/instancemode/filter/FineractInstanceModeApiFilterTest.java +++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/instancemode/filter/FineractInstanceModeApiFilterTest.java @@ -284,4 +284,88 @@ class FineractInstanceModeApiFilterTest { verify(filterChain).doFilter(request, response); } + @Test + void testDoFilterInternal_ShouldLetLoanCOBCatchUpApiThrough_WhenFineractIsInBatchManagerMode() throws ServletException, IOException { + // given + FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(false, false, false, true); + given(fineractProperties.getMode()).willReturn(modeProperties); + given(request.getMethod()).willReturn(HttpMethod.POST.name()); + given(request.getPathInfo()).willReturn("/loans/catch-up"); + // when + underTest.doFilterInternal(request, response, filterChain); + // then + verify(filterChain).doFilter(request, response); + } + + @Test + void testDoFilterInternal_ShouldNotLetLoanCOBCatchUpApiThrough_WhenFineractIsNotInBatchManagerMode() + throws ServletException, IOException { + // given + FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(false, false, true, false); + given(fineractProperties.getMode()).willReturn(modeProperties); + given(request.getMethod()).willReturn(HttpMethod.POST.name()); + given(request.getPathInfo()).willReturn("/loans/catch-up"); + // when + underTest.doFilterInternal(request, response, filterChain); + // then + verifyNoInteractions(filterChain); + verify(response).setStatus(HttpStatus.SC_METHOD_NOT_ALLOWED); + } + + @Test + void testDoFilterInternal_ShouldLetLoanCOBCatchUpStatusApiThrough_WhenFineractIsInBatchManagerMode() + throws ServletException, IOException { + // given + FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(false, false, false, true); + given(fineractProperties.getMode()).willReturn(modeProperties); + given(request.getMethod()).willReturn(HttpMethod.POST.name()); + given(request.getPathInfo()).willReturn("/loans/is-catch-up-running"); + // when + underTest.doFilterInternal(request, response, filterChain); + // then + verify(filterChain).doFilter(request, response); + } + + @Test + void testDoFilterInternal_ShouldNotLetLoanCOBCatchUpStatusApiThrough_WhenFineractIsNotInBatchManagerMode() + throws ServletException, IOException { + // given + FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(false, false, true, false); + given(fineractProperties.getMode()).willReturn(modeProperties); + given(request.getMethod()).willReturn(HttpMethod.POST.name()); + given(request.getPathInfo()).willReturn("/loans/is-catch-up-running"); + // when + underTest.doFilterInternal(request, response, filterChain); + // then + verifyNoInteractions(filterChain); + verify(response).setStatus(HttpStatus.SC_METHOD_NOT_ALLOWED); + } + + @Test + void testDoFilterInternal_ShouldLetOtherLoanCatchUpApisThrough_WhenFineractIsInBatchManagerAndReadModeAndIsGetApi() + throws ServletException, IOException { + // given + FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(true, false, false, true); + given(fineractProperties.getMode()).willReturn(modeProperties); + given(request.getMethod()).willReturn(HttpMethod.GET.name()); + given(request.getPathInfo()).willReturn("/loans/oldest-cob-closed"); + // when + underTest.doFilterInternal(request, response, filterChain); + // then + verify(filterChain).doFilter(request, response); + } + + @Test + void testDoFilterInternal_ShouldLetOtherLoanCatchUpApisThrough_WhenFineractIsInReadModeAndIsGetApi() + throws ServletException, IOException { + // given + FineractProperties.FineractModeProperties modeProperties = InstanceModeMock.createModeProps(true, false, false, false); + given(fineractProperties.getMode()).willReturn(modeProperties); + given(request.getMethod()).willReturn(HttpMethod.GET.name()); + given(request.getPathInfo()).willReturn("/loans/oldest-cob-closed"); + // when + underTest.doFilterInternal(request, response, filterChain); + // then + verify(filterChain).doFilter(request, response); + } } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanCOBCatchUpInstanceModeIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanCOBCatchUpInstanceModeIntegrationTest.java new file mode 100644 index 000000000..eeff29972 --- /dev/null +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanCOBCatchUpInstanceModeIntegrationTest.java @@ -0,0 +1,107 @@ +/** + * 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.integrationtests; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import io.restassured.builder.RequestSpecBuilder; +import io.restassured.builder.ResponseSpecBuilder; +import io.restassured.http.ContentType; +import io.restassured.specification.RequestSpecification; +import io.restassured.specification.ResponseSpecification; +import java.time.LocalDate; +import org.apache.fineract.client.util.CallFailedRuntimeException; +import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType; +import org.apache.fineract.integrationtests.common.BusinessDateHelper; +import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper; +import org.apache.fineract.integrationtests.common.Utils; +import org.apache.fineract.integrationtests.common.loans.LoanCOBCatchUpHelper; +import org.apache.fineract.integrationtests.support.instancemode.ConfigureInstanceMode; +import org.apache.fineract.integrationtests.support.instancemode.InstanceModeSupportExtension; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +@ExtendWith(InstanceModeSupportExtension.class) +public class LoanCOBCatchUpInstanceModeIntegrationTest { + + private LoanCOBCatchUpHelper loanCOBCatchUpHelper; + private ResponseSpecification responseSpec; + private RequestSpecification requestSpec; + + @BeforeEach + public void setup() throws InterruptedException { + Utils.initializeRESTAssured(); + loanCOBCatchUpHelper = new LoanCOBCatchUpHelper(); + this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build(); + this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build(); + this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey()); + final LocalDate todaysDate = Utils.getLocalDateOfTenant(); + GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE); + BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, todaysDate); + } + + @ConfigureInstanceMode(readEnabled = false, writeEnabled = false, batchWorkerEnabled = false, batchManagerEnabled = true) + @Test + public void testLoanCOBCatchUpWorksWhenInBatchManagerMode() { + loanCOBCatchUpHelper.executeLoanCOBCatchUp(); + } + + @ConfigureInstanceMode(readEnabled = false, writeEnabled = false, batchWorkerEnabled = true, batchManagerEnabled = false) + @Test + public void testLoanCOBCatchUpDoesNotWorksWhenNotInBatchManagerMode() { + CallFailedRuntimeException exception = assertThrows(CallFailedRuntimeException.class, + () -> loanCOBCatchUpHelper.executeLoanCOBCatchUp()); + assertEquals(405, exception.getResponse().code()); + } + + @ConfigureInstanceMode(readEnabled = false, writeEnabled = false, batchWorkerEnabled = false, batchManagerEnabled = true) + @Test + public void testLoanCOBCatchUpGetStatusWorksWhenInBatchManagerMode() { + loanCOBCatchUpHelper.executeGetLoanCatchUpStatus(); + } + + @ConfigureInstanceMode(readEnabled = false, writeEnabled = false, batchWorkerEnabled = true, batchManagerEnabled = false) + @Test + public void testLoanCOBCatchUpGetStatusDoesNotWorksWhenNotInBatchManagerMode() { + CallFailedRuntimeException exception = assertThrows(CallFailedRuntimeException.class, + () -> loanCOBCatchUpHelper.executeGetLoanCatchUpStatus()); + assertEquals(405, exception.getResponse().code()); + } + + @ConfigureInstanceMode(readEnabled = true, writeEnabled = false, batchWorkerEnabled = false, batchManagerEnabled = true) + @Test + public void testLoanCOBCatchUpOtherGetApisWorksWhenInBatchManagerAndReadMode() { + loanCOBCatchUpHelper.executeRetrieveOldestCOBProcessedLoan(); + } + + @ConfigureInstanceMode(readEnabled = true, writeEnabled = false, batchWorkerEnabled = false, batchManagerEnabled = false) + @Test + public void testLoanCOBCatchUpOtherGetApisWorksWhenInReadOnlyMode() { + loanCOBCatchUpHelper.executeRetrieveOldestCOBProcessedLoan(); + } + + @AfterEach + public void tearDown() throws InterruptedException { + GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE); + } + +} diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanCOBCatchUpHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanCOBCatchUpHelper.java new file mode 100644 index 000000000..5a253ec04 --- /dev/null +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanCOBCatchUpHelper.java @@ -0,0 +1,41 @@ +/** + * 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.integrationtests.common.loans; + +import org.apache.fineract.client.models.GetOldestCOBProcessedLoanResponse; +import org.apache.fineract.client.models.IsCatchUpRunningResponse; +import org.apache.fineract.integrationtests.client.IntegrationTest; +import retrofit2.Response; + +public class LoanCOBCatchUpHelper extends IntegrationTest { + + public LoanCOBCatchUpHelper() {} + + public Response executeLoanCOBCatchUp() { + return okR(fineract().loanCobCatchUpApi.executeLoanCOBCatchUp()); + } + + public GetOldestCOBProcessedLoanResponse executeRetrieveOldestCOBProcessedLoan() { + return ok(fineract().loanCobCatchUpApi.getOldestCOBProcessedLoan()); + } + + public Response executeGetLoanCatchUpStatus() { + return okR(fineract().loanCobCatchUpApi.isCatchUpRunning()); + } +} diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/support/instancemode/InstanceModeSupportExtension.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/support/instancemode/InstanceModeSupportExtension.java index bd8928b85..259544526 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/support/instancemode/InstanceModeSupportExtension.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/support/instancemode/InstanceModeSupportExtension.java @@ -43,7 +43,7 @@ public class InstanceModeSupportExtension implements BeforeTestExecutionCallback boolean readEnabled = annotation.readEnabled(); boolean writeEnabled = annotation.writeEnabled(); boolean batchWorkerEnabled = annotation.batchWorkerEnabled(); - boolean batchManagerEnabled = annotation.batchWorkerEnabled(); + boolean batchManagerEnabled = annotation.batchManagerEnabled(); changeInstanceMode(context, readEnabled, writeEnabled, batchWorkerEnabled, batchManagerEnabled); } });