Skip to content

Commit ed14115

Browse files
Atharva JoshiAtharva Joshi
Atharva Joshi
authored and
Atharva Joshi
committed
subschema comparator
Signed-off-by: Atharva Joshi <[email protected]>
1 parent 619c081 commit ed14115

File tree

4 files changed

+138
-5
lines changed

4 files changed

+138
-5
lines changed

server/src/main/java/io/pravega/schemaregistry/rules/jsoncompatibility/BreakingChangesStore.java

+8-4
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,14 @@ protected enum BreakingChanges {
7070
// NOT TYPE
7171
NOT_TYPE_EXTENDED,
7272
// COMBINED
73-
COMBINED_TYPE_SUBSCHEMAS_CHANGED,
74-
COMPOSITION_METHOD_CHANGED,
75-
PRODUCT_TYPE_EXTENDED,
76-
SUM_TYPE_NARROWED
73+
SUBSCHEMA_TYPE_ADDED,
74+
SUBSCHEMA_TYPE_CHANGED,
75+
SUBSCHEMA_TYPE_ALL_OF_SCHEMAS_INCREASED,
76+
SUBSCHEMA_TYPE_ALL_OF_SCHEMAS_CHANGED,
77+
SUBSCHEMA_TYPE_ONE_OF_SCHEMAS_DECREASED,
78+
SUBSCHEMA_TYPE_ONE_OF_SCHEMAS_CHANGED,
79+
SUBSCHEMA_TYPE_ANY_OF_SCHEMAS_DECREASED,
80+
SUBSCHEMA_TYPE_ANYOF_SCHEMAS_CHANGED
7781
}
7882

7983
private List<BreakingChanges> breakingChangesList = new ArrayList<>();

server/src/main/java/io/pravega/schemaregistry/rules/jsoncompatibility/JsonCompatibilityChecker.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,16 @@ public class JsonCompatibilityChecker implements CompatibilityChecker {
1919
NumberComparator numberComparator;
2020
StringComparator stringComparator;
2121
ArrayTypeComparator arrayTypeComparator;
22-
22+
SubSchemaComparator subSchemaComparator;
23+
2324
public JsonCompatibilityChecker() {
2425
this.enumComparator = new EnumComparator();
2526
this.jsonCompatibilityCheckerUtils = new JsonCompatibilityCheckerUtils();
2627
this.objectTypeComparator = new ObjectTypeComparator();
2728
this.numberComparator = new NumberComparator();
2829
this.stringComparator = new StringComparator();
2930
this.arrayTypeComparator = new ArrayTypeComparator();
31+
this.subSchemaComparator = new SubSchemaComparator();
3032
}
3133

3234
@Override
@@ -67,6 +69,12 @@ private boolean canReadChecker(SchemaInfo toValidate, List<SchemaInfo> toValidat
6769
}
6870

6971
protected BreakingChanges checkNodeType(JsonNode toCheck, JsonNode toCheckAgainst) {
72+
if(jsonCompatibilityCheckerUtils.hasSubSchema(toCheck)) {
73+
subSchemaComparator.setJsonCompatibilityChecker();
74+
BreakingChanges subSchemaChanges = subSchemaComparator.checkSubSchemas(toCheck, toCheckAgainst);
75+
if(subSchemaChanges != null)
76+
return subSchemaChanges;
77+
}
7078
if (toCheck.has("enum") || toCheckAgainst.has("enum")) {
7179
BreakingChanges enumChanges = enumComparator.enumComparator(toCheck, toCheckAgainst);
7280
if (enumChanges != null)

server/src/main/java/io/pravega/schemaregistry/rules/jsoncompatibility/JsonCompatibilityCheckerUtils.java

+7
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,11 @@ public boolean arrayComparisionOnlyAddition(ArrayNode toCheck, ArrayNode toCheck
7979
}
8080
return true;
8181
}
82+
83+
public boolean hasSubSchema(JsonNode toCheck) {
84+
if(toCheck.has("anyOf") || toCheck.has("allOf") || toCheck.has("oneOf")) {
85+
return true;
86+
}
87+
return false;
88+
}
8289
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package io.pravega.schemaregistry.rules.jsoncompatibility;
2+
3+
import com.fasterxml.jackson.databind.JsonNode;
4+
import com.fasterxml.jackson.databind.node.ArrayNode;
5+
6+
import static io.pravega.schemaregistry.rules.jsoncompatibility.BreakingChangesStore.*;
7+
8+
public class SubSchemaComparator {
9+
JsonCompatibilityChecker jsonCompatibilityChecker = new JsonCompatibilityChecker();
10+
11+
public void setJsonCompatibilityChecker() {
12+
this.jsonCompatibilityChecker = new JsonCompatibilityChecker();
13+
}
14+
15+
public BreakingChanges checkSubSchemas(JsonNode toCheck, JsonNode toCheckAgainst) {
16+
if(toCheck.has("anyOf")) {
17+
if(toCheckAgainst.has("oneOf") || toCheckAgainst.has("allOf"))
18+
return BreakingChanges.SUBSCHEMA_TYPE_CHANGED;
19+
else {
20+
if(toCheckAgainst.has("anyOf"))
21+
return nonAllOfComparator(toCheck, toCheckAgainst);
22+
else
23+
return BreakingChanges.SUBSCHEMA_TYPE_ADDED;
24+
}
25+
}
26+
else if(toCheck.has("oneOf")) {
27+
if(toCheckAgainst.has("anyOf") || toCheckAgainst.has("allOf"))
28+
return BreakingChanges.SUBSCHEMA_TYPE_CHANGED;
29+
else {
30+
if(toCheckAgainst.has("oneOf"))
31+
return nonAllOfComparator(toCheck, toCheckAgainst);
32+
else
33+
return BreakingChanges.SUBSCHEMA_TYPE_ADDED;
34+
}
35+
}
36+
else if(toCheck.has("allOf")) {
37+
if(toCheckAgainst.has("anyOf") || toCheckAgainst.has("oneOf"))
38+
return BreakingChanges.SUBSCHEMA_TYPE_CHANGED;
39+
else {
40+
if(toCheckAgainst.has("allOf"))
41+
return allOfComparator(toCheck, toCheckAgainst);
42+
else
43+
return BreakingChanges.SUBSCHEMA_TYPE_ADDED;
44+
}
45+
}
46+
return null;
47+
}
48+
49+
private BreakingChanges nonAllOfComparator(JsonNode toCheck, JsonNode toCheckAgainst) {
50+
if(toCheck.has("oneOf")) {
51+
ArrayNode toCheckArray = (ArrayNode) toCheck.get("oneOf");
52+
ArrayNode toCheckAgainstArray = (ArrayNode) toCheckAgainst.get("oneOf");
53+
if(toCheckArray.size() < toCheckAgainstArray.size())
54+
return BreakingChanges.SUBSCHEMA_TYPE_ONE_OF_SCHEMAS_DECREASED;
55+
else {
56+
if (!nonAllOfCompatibilityComputation(toCheckArray, toCheckAgainstArray))
57+
return BreakingChanges.SUBSCHEMA_TYPE_ONE_OF_SCHEMAS_CHANGED;
58+
}
59+
}
60+
else {
61+
ArrayNode toCheckArray = (ArrayNode) toCheck.get("anyOf");
62+
ArrayNode toCheckAgainstArray = (ArrayNode) toCheckAgainst.get("anyOf");
63+
if(toCheckArray.size() < toCheckAgainstArray.size())
64+
return BreakingChanges.SUBSCHEMA_TYPE_ANY_OF_SCHEMAS_DECREASED;
65+
else {
66+
if (!nonAllOfCompatibilityComputation(toCheckArray, toCheckAgainstArray))
67+
return BreakingChanges.SUBSCHEMA_TYPE_ANYOF_SCHEMAS_CHANGED;
68+
}
69+
}
70+
return null;
71+
}
72+
73+
private BreakingChanges allOfComparator(JsonNode toCheck, JsonNode toCheckAgainst) {
74+
ArrayNode toCheckArray = (ArrayNode) toCheck.get("allOf");
75+
ArrayNode toCheckAgainstArray = (ArrayNode) toCheckAgainst.get("allOf");
76+
if(!(toCheckArray.size() <= toCheckAgainstArray.size()))
77+
return BreakingChanges.SUBSCHEMA_TYPE_ALL_OF_SCHEMAS_INCREASED;
78+
else {
79+
if (!allOfCompatibilityComputation(toCheckArray, toCheckAgainstArray))
80+
return BreakingChanges.SUBSCHEMA_TYPE_ALL_OF_SCHEMAS_CHANGED;
81+
}
82+
return null;
83+
}
84+
85+
private boolean allOfCompatibilityComputation(ArrayNode toCheckArray, ArrayNode toCheckAgainstArray) {
86+
for(int i=0;i<toCheckArray.size();i++) {
87+
int flag = 0;
88+
for(int j=0;j<toCheckAgainstArray.size();j++) {
89+
if(jsonCompatibilityChecker.checkNodeType(toCheckArray.get(i), toCheckAgainstArray.get(j))==null) {
90+
flag=1;
91+
break;
92+
}
93+
}
94+
if(flag==0)
95+
return false;
96+
}
97+
return true;
98+
}
99+
100+
private boolean nonAllOfCompatibilityComputation(ArrayNode toCheckArray, ArrayNode toCheckAgainstArray) {
101+
for(int i=0;i<toCheckAgainstArray.size();i++) {
102+
int flag = 0;
103+
for(int j=0;j<toCheckArray.size();j++) {
104+
if(jsonCompatibilityChecker.checkNodeType(toCheckAgainstArray.get(i), toCheckArray.get(j))==null) {
105+
flag=1;
106+
break;
107+
}
108+
}
109+
if(flag==0)
110+
return false;
111+
}
112+
return true;
113+
}
114+
}

0 commit comments

Comments
 (0)