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

adamsaghy 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 634814071 FINERACT-2081: Fix "resolve dependent variable" logic of 
Batch request resolver
634814071 is described below

commit 6348140716d3b7f3903483d1a383f8e9857ae04b
Author: Adam Saghy <[email protected]>
AuthorDate: Thu Jan 9 20:13:17 2025 +0100

    FINERACT-2081: Fix "resolve dependent variable" logic of Batch request 
resolver
---
 .../fineract/batch/service/ResolutionHelper.java   |  43 ++++-----
 .../batch/service/ResolutionHelperTest.java        | 107 +++++++++++++++++++++
 2 files changed, 127 insertions(+), 23 deletions(-)

diff --git 
a/fineract-core/src/main/java/org/apache/fineract/batch/service/ResolutionHelper.java
 
b/fineract-core/src/main/java/org/apache/fineract/batch/service/ResolutionHelper.java
index f27e0afbf..332041706 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/batch/service/ResolutionHelper.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/batch/service/ResolutionHelper.java
@@ -22,6 +22,7 @@ import com.google.common.base.Splitter;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
 import com.jayway.jsonpath.JsonPath;
 import com.jayway.jsonpath.ReadContext;
 import java.util.ArrayList;
@@ -133,7 +134,7 @@ public class ResolutionHelper {
             // parameter
             for (Map.Entry<String, JsonElement> element : 
jsonRequestBody.entrySet()) {
                 final String key = element.getKey();
-                final JsonElement value = resolveDependentVariables(element, 
responseCtx);
+                final JsonElement value = 
resolveDependentVariables(element.getValue(), responseCtx);
                 jsonResultBody.add(key, value);
             }
             // Set the body after dependency resolution
@@ -162,20 +163,19 @@ public class ResolutionHelper {
         return request;
     }
 
-    private JsonElement resolveDependentVariables(final Map.Entry<String, 
JsonElement> entryElement, final ReadContext responseCtx) {
+    private JsonElement resolveDependentVariables(final JsonElement 
jsonElement, final ReadContext responseCtx) {
         JsonElement value;
-        final JsonElement element = entryElement.getValue();
-        if (element.isJsonObject()) {
-            final JsonObject jsObject = element.getAsJsonObject();
+        if (jsonElement.isJsonObject()) {
+            final JsonObject jsObject = jsonElement.getAsJsonObject();
             value = processJsonObject(jsObject, responseCtx);
-        } else if (element.isJsonArray()) {
-            final JsonArray jsElementArray = element.getAsJsonArray();
+        } else if (jsonElement.isJsonArray()) {
+            final JsonArray jsElementArray = jsonElement.getAsJsonArray();
             value = processJsonArray(jsElementArray, responseCtx);
-        } else if (element.isJsonNull()) {
+        } else if (jsonElement.isJsonNull()) {
             // No further processing of null values
-            value = element;
+            value = jsonElement;
         } else {
-            value = resolveDependentVariable(element, responseCtx);
+            value = processJsonPrimitive(jsonElement, responseCtx);
         }
         return value;
     }
@@ -183,9 +183,7 @@ public class ResolutionHelper {
     private JsonElement processJsonObject(final JsonObject jsObject, final 
ReadContext responseCtx) {
         JsonObject valueObj = new JsonObject();
         for (Map.Entry<String, JsonElement> element : jsObject.entrySet()) {
-            final String key = element.getKey();
-            final JsonElement value = 
resolveDependentVariable(element.getValue(), responseCtx);
-            valueObj.add(key, value);
+            valueObj.add(element.getKey(), 
resolveDependentVariables(element.getValue(), responseCtx));
         }
         return valueObj;
     }
@@ -193,21 +191,20 @@ public class ResolutionHelper {
     private JsonArray processJsonArray(final JsonArray elementArray, final 
ReadContext responseCtx) {
         JsonArray valueArr = new JsonArray();
         for (JsonElement element : elementArray) {
-            if (element.isJsonObject()) {
-                final JsonObject jsObject = element.getAsJsonObject();
-                valueArr.add(processJsonObject(jsObject, responseCtx));
-            }
+            valueArr.add(resolveDependentVariables(element, responseCtx));
         }
         return valueArr;
     }
 
-    private JsonElement resolveDependentVariable(final JsonElement element, 
final ReadContext responseCtx) {
+    private JsonElement processJsonPrimitive(final JsonElement element, final 
ReadContext responseCtx) {
         JsonElement value = element;
-        String paramVal = element.getAsString();
-        if (paramVal.contains("$.")) {
-            // Get the value of the parameter from parent response
-            final String resParamValue = responseCtx.read(paramVal).toString();
-            value = this.fromJsonHelper.parse(resParamValue);
+        if (element instanceof JsonPrimitive) {
+            String paramVal = element.getAsString();
+            if (paramVal.contains("$.")) {
+                // Get the value of the parameter from parent response
+                final String resParamValue = 
responseCtx.read(paramVal).toString();
+                value = this.fromJsonHelper.parse(resParamValue);
+            }
         }
         return value;
     }
diff --git 
a/fineract-core/src/test/java/org/apache/fineract/batch/service/ResolutionHelperTest.java
 
b/fineract-core/src/test/java/org/apache/fineract/batch/service/ResolutionHelperTest.java
new file mode 100644
index 000000000..1a735b9d6
--- /dev/null
+++ 
b/fineract-core/src/test/java/org/apache/fineract/batch/service/ResolutionHelperTest.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.batch.service;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.jayway.jsonpath.ReadContext;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.fineract.batch.domain.BatchRequest;
+import org.apache.fineract.batch.domain.BatchResponse;
+import org.apache.fineract.batch.exception.BatchReferenceInvalidException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.junit.jupiter.api.Test;
+
+public class ResolutionHelperTest {
+
+    private final FromJsonHelper fromJsonHelper = new FromJsonHelper();
+    private final ResolutionHelper resolutionHelper = new 
ResolutionHelper(fromJsonHelper);
+
+    @Test
+    void testBuildNodesTreeWithValidRequests() {
+        List<BatchRequest> requests = new ArrayList<>();
+        BatchRequest firstRequest = new BatchRequest();
+        firstRequest.setRequestId(1L);
+        firstRequest.setBody("{\"key1\": \"value1\", \"key2\": 12, \"key3\": 
null, \"key4\": false}");
+        firstRequest.setRelativeUrl("/resource/id");
+        requests.add(firstRequest);
+        BatchRequest secondRequest = new BatchRequest();
+        secondRequest.setRequestId(2L);
+        secondRequest.setReference(1L);
+        secondRequest.setRelativeUrl("/resource/id");
+        secondRequest.setBody("{\"key1\": { \"subKey\": false }, \"key2\": 
[1,2,3]}");
+        requests.add(secondRequest);
+        BatchRequest thirdRequest = new BatchRequest();
+        thirdRequest.setRequestId(3L);
+        thirdRequest.setReference(2L);
+        requests.add(thirdRequest);
+        List<ResolutionHelper.BatchRequestNode> nodes = 
resolutionHelper.buildNodesTree(requests);
+        assertEquals(1, nodes.size());
+        assertEquals(1, nodes.get(0).getRequest().getRequestId());
+        assertEquals("{\"key1\": \"value1\", \"key2\": 12, \"key3\": null, 
\"key4\": false}", nodes.get(0).getRequest().getBody());
+        assertEquals(1, nodes.get(0).getChildNodes().size());
+        assertEquals(2, 
nodes.get(0).getChildNodes().get(0).getRequest().getRequestId());
+        assertEquals("{\"key1\": { \"subKey\": false }, \"key2\": [1,2,3]}", 
nodes.get(0).getChildNodes().get(0).getRequest().getBody());
+    }
+
+    @Test
+    void testBuildNodesTreeWithInvalidReference() {
+        List<BatchRequest> requests = new ArrayList<>();
+        BatchRequest invalidRequest = new BatchRequest();
+        invalidRequest.setRequestId(2L);
+        // Not existing reference
+        invalidRequest.setReference(1L);
+        requests.add(invalidRequest);
+        assertThrows(BatchReferenceInvalidException.class, () -> 
resolutionHelper.buildNodesTree(requests));
+    }
+
+    @Test
+    void testResolveRequestWithValidDependenciesResolveParameterFromResponse() 
{
+        BatchRequest batchRequest = new BatchRequest();
+        batchRequest.setBody("{\"key1\": \"$.value1\"}");
+        batchRequest.setRelativeUrl("/resource/$.id?key=value");
+        BatchResponse parentResponse = new BatchResponse();
+        parentResponse.setBody("{\"value1\": \"resolvedValue\", \"id\": 
\"123\"}");
+        ReadContext readContext = mock(ReadContext.class);
+        when(readContext.read("$.value1")).thenReturn("resolvedValue");
+        when(readContext.read("$.id")).thenReturn("123");
+        BatchRequest resolvedRequest = 
resolutionHelper.resolveRequest(batchRequest, parentResponse);
+        assertNotNull(resolvedRequest);
+        assertEquals("{\"key1\":\"resolvedValue\"}", 
resolvedRequest.getBody());
+        assertEquals("/resource/123?key=value", 
resolvedRequest.getRelativeUrl());
+    }
+
+    @Test
+    void testResolveRequestWithNoDependencies() {
+        BatchRequest batchRequest = new BatchRequest();
+        batchRequest.setBody("{\"key1\": \"value1\",\"key2\": { \"subKey\": 
false }, \"key3\": [1,2,3], \"key4\": null}");
+        batchRequest.setRelativeUrl("/resource/id");
+        BatchResponse parentResponse = new BatchResponse();
+        parentResponse.setBody("{\"value2\": \"not used\"}");
+        BatchRequest resolvedRequest = 
resolutionHelper.resolveRequest(batchRequest, parentResponse);
+        assertNotNull(resolvedRequest);
+        
assertEquals("{\"key1\":\"value1\",\"key2\":{\"subKey\":false},\"key3\":[1,2,3],\"key4\":null}",
 resolvedRequest.getBody());
+        assertEquals("/resource/id", resolvedRequest.getRelativeUrl());
+    }
+}

Reply via email to