Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add array element ignore, fix "arex_" prefix issue, and support select list #61

Merged
merged 7 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion arex-compare-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>arex-compare-parent</artifactId>
<groupId>com.arextest</groupId>
<version>0.2.16</version>
<version>0.2.17</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.arextest.diff.handler.log.register.LogRegister;
import com.arextest.diff.model.compare.CompareContext;
import com.arextest.diff.model.compare.IndexPair;
import com.arextest.diff.model.enumeration.ParentNodeType;
import com.arextest.diff.model.log.NodeEntity;
import com.arextest.diff.utils.ListUti;
import com.fasterxml.jackson.databind.node.ArrayNode;
Expand Down Expand Up @@ -55,7 +56,8 @@ public static void arrayCompare(Object obj1, Object obj2, CompareContext compare
boolean rightExist = false;

if (correspondRightIndex == -1) {
LogRegister.register(element1, element2, LogMarker.RIGHT_ARRAY_MISSING_KEY, compareContext);
compareContext.parentNodeType = ParentNodeType.ARRAY;
GenericCompare.jsonCompare(element1, element2, compareContext);
} else {
element2 = obj2Array.get(correspondRightIndex);
rightExist = true;
Expand All @@ -70,6 +72,7 @@ public static void arrayCompare(Object obj1, Object obj2, CompareContext compare
compareContext.pkListIndexPair,
compareContext.currentNodeLeft);
if (needCompare && element1 != null && element2 != null) {
compareContext.parentNodeType = ParentNodeType.ARRAY;
GenericCompare.jsonCompare(element1, element2, compareContext);
}
}
Expand Down Expand Up @@ -98,7 +101,8 @@ public static void arrayCompare(Object obj1, Object obj2, CompareContext compare
Object element2 = obj2Array.get(i);
boolean leftExist = false;
if (correspondLeftIndex == -1) {
LogRegister.register(element1, element2, LogMarker.LEFT_ARRAY_MISSING_KEY, compareContext);
compareContext.parentNodeType = ParentNodeType.ARRAY;
GenericCompare.jsonCompare(element1, element2, compareContext);
} else {
element1 = obj1Array.get(correspondLeftIndex);
leftExist = true;
Expand All @@ -111,6 +115,7 @@ public static void arrayCompare(Object obj1, Object obj2, CompareContext compare
compareContext.pkListIndexPair,
compareContext.currentNodeRight);
if (needCompare && element1 != null && element2 != null) {
compareContext.parentNodeType = ParentNodeType.ARRAY;
GenericCompare.jsonCompare(element1, element2, compareContext);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
import com.arextest.diff.handler.log.LogMarker;
import com.arextest.diff.handler.log.register.LogRegister;
import com.arextest.diff.model.compare.CompareContext;
import com.arextest.diff.model.enumeration.ParentNodeType;
import com.arextest.diff.model.log.NodeEntity;
import com.arextest.diff.utils.IgnoreUtil;
import com.arextest.diff.utils.ListUti;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.NullNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.List;
import java.util.Objects;

public class GenericCompare {

Expand All @@ -34,19 +36,26 @@ public static void jsonCompare(Object obj1, Object obj2, CompareContext compareC
}

// not compare by exclusions
if (IgnoreUtil.ignoreProcessor(fuzzyPath, currentNode, compareContext.exclusions,
compareContext.expressionExclusions, compareContext.ignoreNodeSet)) {
if (IgnoreUtil.ignoreProcessor(fuzzyPath, compareContext.currentNodeLeft,
compareContext.currentNodeRight, compareContext.exclusions,
compareContext.conditionExclusions, compareContext.ignoreNodeSet)) {
return;
}

// field missing
if (obj1 == null && obj2 == null) {
return;
} else if (obj1 == null) {
LogRegister.register(obj1, obj2, LogMarker.LEFT_OBJECT_MISSING, compareContext);
LogRegister.register(obj1, obj2,
Objects.equals(compareContext.parentNodeType, ParentNodeType.OBJECT)
? LogMarker.LEFT_OBJECT_MISSING
: LogMarker.LEFT_ARRAY_MISSING, compareContext);
return;
} else if (obj2 == null) {
LogRegister.register(obj1, obj2, LogMarker.RIGHT_OBJECT_MISSING, compareContext);
LogRegister.register(obj1, obj2,
Objects.equals(compareContext.parentNodeType, ParentNodeType.OBJECT)
? LogMarker.LEFT_OBJECT_MISSING
: LogMarker.RIGHT_ARRAY_MISSING, compareContext);
return;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.arextest.diff.compare;

import com.arextest.diff.model.compare.CompareContext;
import com.arextest.diff.model.enumeration.ParentNodeType;
import com.arextest.diff.model.log.NodeEntity;
import com.arextest.diff.utils.JacksonHelperUtil;
import com.arextest.diff.utils.ListUti;
Expand Down Expand Up @@ -34,6 +35,7 @@ public static void objectCompare(Object obj1, Object obj2, CompareContext compar
compareContext.currentNodeRight.add(new NodeEntity(fieldName, 0));
}

compareContext.parentNodeType = ParentNodeType.OBJECT;
GenericCompare.jsonCompare(obj1FieldValue, obj2FieldValue, compareContext);

ListUti.removeLast(compareContext.currentNodeLeft);
Expand All @@ -57,6 +59,7 @@ public static void objectCompare(Object obj1, Object obj2, CompareContext compar
compareContext.currentNodeLeft.add(new NodeEntity(fieldName, 0));
}

compareContext.parentNodeType = ParentNodeType.OBJECT;
GenericCompare.jsonCompare(obj1FieldValue, obj2FieldValue, compareContext);

if (leftExist) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
import com.arextest.diff.model.pathparse.ExpressionNodeEntity;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

public class EigenHandler {
Expand Down Expand Up @@ -41,13 +42,13 @@ public EigenResult doHandler(RulesConfig rulesConfig) {
obj = null;
}

LinkedList<LinkedList<ExpressionNodeEntity>> expressionExclusions =
jsonPathExpressionHandler.doMultiExpressionParse(rulesConfig.getExpressionExclusions(),
List<List<ExpressionNodeEntity>> expressionExclusions = new LinkedList<>();
Map<List<ExpressionNodeEntity>, LinkedList<LinkedList<ExpressionNodeEntity>>> listLinkedListMap =
jsonPathExpressionHandler.doMultiExpressionParse(
rulesConfig.getExpressionExclusions(),
obj);
if (expressionExclusions != null) {
rulesConfig.setExpressionExclusions(new ArrayList<>(expressionExclusions));
}

listLinkedListMap.values().forEach(expressionExclusions::addAll);
rulesConfig.setExpressionExclusions(expressionExclusions);
return eigenMapCalculate.doCalculate(obj, rulesConfig, new HashMap<>());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
Expand Down Expand Up @@ -54,7 +53,8 @@ private void doCalculateJsonNode(Object obj, CalculateContext calculateContext,
Map<Integer, Long> eigenMap) {

// ignore by node name and node path
if (IgnoreUtil.ignoreProcessor(calculateContext.nodePath, calculateContext.currentNodeEntity,
if (IgnoreUtil.ignoreProcessorEngine(calculateContext.nodePath,
calculateContext.currentNodeEntity,
calculateContext.exclusions, calculateContext.expressionExclusions,
calculateContext.ignoreNodeSet)) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public List<LogEntity> doHandler(RulesConfig rulesConfig, KeyComputeResponse key
compareContext.setResponseReferences(keyComputeResponse.getAllReferenceEntities());

compareContext.exclusions = rulesConfig.getExclusions();
compareContext.expressionExclusions = rulesConfig.getExpressionExclusions();
compareContext.conditionExclusions = rulesConfig.getConditionExclusions();
compareContext.ignoreNodeSet = rulesConfig.getIgnoreNodeSet();

compareContext.notDistinguishNullAndEmpty = rulesConfig.isNullEqualsEmpty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ public ParsedResult sqlParse(ObjectNode jsonObj, boolean nameToLower) {
return new ParsedResult(null, false);
}

// additional: Handling multiple selections
databaseBody = processMultipleSelect(databaseBody);

boolean successParse = true;
ArrayNode parsedSql = JacksonHelperUtil.getArrayNode();
List<Boolean> isSelect = new ArrayList<>();
Expand Down Expand Up @@ -245,6 +248,41 @@ private void fillOriginalSql(ObjectNode objectNode, JsonNode databaseBody) {
objectNode.set(DbParseConstants.PARSED_SQL, parsedSql);
}

private JsonNode processMultipleSelect(JsonNode databaseBody) {
JsonNode result = databaseBody;
if (databaseBody instanceof TextNode) {
String sql = databaseBody.asText();
if (sql.contains(";")) {
String[] sqls = sql.split(";");
ArrayNode arrayNode = JacksonHelperUtil.getArrayNode();
for (String s : sqls) {
if (!startsWithSelect(s)) {
break;
}
arrayNode.add(s);
}
result = arrayNode;
}

}
return result;
}

public static boolean startsWithSelect(String str) {
if (str == null) {
return false;
}
int len = str.length();
int i = 0;
// Skip leading whitespace
while (i < len && Character.isWhitespace(str.charAt(i))) {
i++;
}
// Check if the remaining string starts with "select" or "SELECT"
return str.regionMatches(true, i, "select", 0, 6);
}


private static class ParsedResult {

private List<Boolean> isSelect;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
Expand All @@ -29,36 +32,41 @@ public class JsonPathExpressionHandler {
public void doExpressionParse(RulesConfig rulesConfig,
Object baseObj, Object testObj) throws ExecutionException, InterruptedException {

Set<List<ExpressionNodeEntity>> result = new HashSet<>();
Map<LinkedList<LinkedList<ExpressionNodeEntity>>, LinkedList<LinkedList<ExpressionNodeEntity>>>
conditionExclusions = null;

try {
List<List<ExpressionNodeEntity>> expressionExclusions = rulesConfig.getExpressionExclusions();

CompletableFuture<LinkedList<LinkedList<ExpressionNodeEntity>>> future1 = CompletableFuture.supplyAsync(
CompletableFuture<Map<List<ExpressionNodeEntity>, LinkedList<LinkedList<ExpressionNodeEntity>>>>
future1 = CompletableFuture.supplyAsync(
() -> doMultiExpressionParse(expressionExclusions, baseObj),
TaskThreadFactory.jsonObjectThreadPool
);

CompletableFuture<LinkedList<LinkedList<ExpressionNodeEntity>>> future2 = CompletableFuture.supplyAsync(
CompletableFuture<Map<List<ExpressionNodeEntity>, LinkedList<LinkedList<ExpressionNodeEntity>>>>
future2 = CompletableFuture.supplyAsync(
() -> doMultiExpressionParse(expressionExclusions, testObj),
TaskThreadFactory.jsonObjectThreadPool
);

CompletableFuture<Void> voidCompletableFuture = CompletableFuture.allOf(future1, future2);
voidCompletableFuture.get(Constant.JSON_PATH_PARSE_MINUTES_TIME, TimeUnit.MINUTES);

result.addAll(future1.get());
result.addAll(future2.get());
Map<List<ExpressionNodeEntity>, LinkedList<LinkedList<ExpressionNodeEntity>>> baseExpression = future1.get();
Map<List<ExpressionNodeEntity>, LinkedList<LinkedList<ExpressionNodeEntity>>> testExpression = future2.get();
conditionExclusions = mergeExpression(baseExpression, testExpression);

} catch (RuntimeException | TimeoutException e) {
LOGGER.warning("doExpressionParse error: " + e.getMessage());
}
rulesConfig.setExpressionExclusions(new LinkedList<>(result));
rulesConfig.setConditionExclusions(conditionExclusions);
}

public LinkedList<LinkedList<ExpressionNodeEntity>> doMultiExpressionParse(
public Map<List<ExpressionNodeEntity>, LinkedList<LinkedList<ExpressionNodeEntity>>> doMultiExpressionParse(
List<List<ExpressionNodeEntity>> expressionExclusions, Object object) {

LinkedList<LinkedList<ExpressionNodeEntity>> result = new LinkedList<>();
Map<List<ExpressionNodeEntity>, LinkedList<LinkedList<ExpressionNodeEntity>>> result =
new HashMap<>();

try {
if (ListUti.isEmpty(expressionExclusions)) {
Expand All @@ -69,7 +77,7 @@ public LinkedList<LinkedList<ExpressionNodeEntity>> doMultiExpressionParse(
LinkedList<LinkedList<ExpressionNodeEntity>> linkedLists = doSinglePathExpressionParse(
coryhh marked this conversation as resolved.
Show resolved Hide resolved
expressionNodeEntityList, 0, expressionNodeEntityList.size(), object, false);
if (linkedLists != null) {
result.addAll(linkedLists);
result.put(expressionNodeEntityList, linkedLists);
}
}
} catch (RuntimeException exception) {
Expand Down Expand Up @@ -279,5 +287,40 @@ private String getValueFormPath(Object objectNode, List<String> pathList) {
return null;
}


private Map<LinkedList<LinkedList<ExpressionNodeEntity>>, LinkedList<LinkedList<ExpressionNodeEntity>>> mergeExpression(
Map<List<ExpressionNodeEntity>, LinkedList<LinkedList<ExpressionNodeEntity>>> baseExpression,
Map<List<ExpressionNodeEntity>, LinkedList<LinkedList<ExpressionNodeEntity>>> testExpression) {

Map<LinkedList<LinkedList<ExpressionNodeEntity>>, LinkedList<LinkedList<ExpressionNodeEntity>>> result = new HashMap<>();

Set<List<ExpressionNodeEntity>> baseExpressionKeySet = baseExpression.keySet();
Set<List<ExpressionNodeEntity>> testExpresssionKeyset = testExpression.keySet();

// get the intersection of the two sets
Set<List<ExpressionNodeEntity>> temp = new HashSet<>(baseExpressionKeySet);
temp.retainAll(testExpresssionKeyset);

for (Entry<List<ExpressionNodeEntity>, LinkedList<LinkedList<ExpressionNodeEntity>>> entry : baseExpression.entrySet()) {
List<ExpressionNodeEntity> key = entry.getKey();
LinkedList<LinkedList<ExpressionNodeEntity>> baseValue = entry.getValue();
if (temp.contains(key)) {
LinkedList<LinkedList<ExpressionNodeEntity>> testValue = testExpression.get(key);
result.put(baseValue, testValue);
} else {
result.put(baseValue, null);
}
}

for (Entry<List<ExpressionNodeEntity>, LinkedList<LinkedList<ExpressionNodeEntity>>> entry : testExpression.entrySet()) {
List<ExpressionNodeEntity> key = entry.getKey();
LinkedList<LinkedList<ExpressionNodeEntity>> testValue = entry.getValue();
if (!temp.contains(key)) {
result.put(null, testValue);
}
}
return result;
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
import com.arextest.diff.model.key.ReferenceEntity;
import com.arextest.diff.model.pathparse.ExpressionNodeEntity;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.tuple.Pair;

public class RulesConfig {

Expand Down Expand Up @@ -60,6 +62,8 @@ public class RulesConfig {
//region: inner processed class
private List<List<ExpressionNodeEntity>> expressionExclusions;

private Map<LinkedList<LinkedList<ExpressionNodeEntity>>, LinkedList<LinkedList<ExpressionNodeEntity>>> conditionExclusions;

//endregion

public RulesConfig() {
Expand Down Expand Up @@ -231,8 +235,16 @@ public List<List<ExpressionNodeEntity>> getExpressionExclusions() {
return expressionExclusions;
}

public void setExpressionExclusions(
List<List<ExpressionNodeEntity>> expressionExclusions) {
public void setExpressionExclusions(List<List<ExpressionNodeEntity>> expressionExclusions) {
this.expressionExclusions = expressionExclusions;
}

public Map<LinkedList<LinkedList<ExpressionNodeEntity>>, LinkedList<LinkedList<ExpressionNodeEntity>>> getConditionExclusions() {
return conditionExclusions;
}

public void setConditionExclusions(
Map<LinkedList<LinkedList<ExpressionNodeEntity>>, LinkedList<LinkedList<ExpressionNodeEntity>>> conditionExclusions) {
this.conditionExclusions = conditionExclusions;
}
}
Loading
Loading