Skip to content
Permalink
Browse files
OAK-9715 - Fixing IndexDefMergerUtils to set latest product index ver…
…sion for merges property on merged indexes
  • Loading branch information
klcodanr committed Mar 7, 2022
1 parent 8fe0b13 commit 511d8f74970c6b1632791221f3d93ab0bac56575
Showing 12 changed files with 625 additions and 16 deletions.
@@ -49,21 +49,21 @@ public class IndexDefMergerUtils {
* Merge index definition changes.
*
* @param path the path of the change itself (e.g. /oak:index/lucene-1/indexRules/acme)
* @param ancestorName the name of the node of the ancestor index (e.g. /oak:index/lucene-1)
* @param ancestor the common ancestor (the old product index, e.g. lucene)
* @param customName the name of the node of the customized index (e.g. /oak:index/lucene-1-custom-1)
* @param custom the latest customized version (e.g. lucene-1-custom-1)
* @param product the latest product index (e.g. lucene-2)
* @param productName the name of the node of the latest product index (e.g. /oak:index/lucene-2)
* @return the merged index definition (e.g. lucene-2-custom-1)
*/
public static JsonObject merge(String path, String ancestorName, JsonObject ancestor, String customName, JsonObject custom, JsonObject product) {
public static JsonObject merge(String path, JsonObject ancestor, String customName, JsonObject custom, JsonObject product, String productName) {
ArrayList<String> conflicts = new ArrayList<>();
JsonObject merged = merge(path, 0, ancestor, custom, product, conflicts);
if (!conflicts.isEmpty()) {
throw new UnsupportedOperationException("Conflicts detected: " + conflicts);
}
merged.getProperties().put("merges", "[" +
JsopBuilder.encode(ancestorName) + ", " +
JsopBuilder.encode(productName) + ", " +
JsopBuilder.encode(customName) + "]");
return merged;
}
@@ -220,10 +220,9 @@ public static void merge(JsonObject newIndexes, JsonObject allIndexes) {
JsonObject newProduct = newIndexes.getChildren().get(n.getNodeName());
try {
JsonObject merged = merge(
"",
ancestor.getNodeName(), latestAncestor,
"", latestAncestor,
latest.getNodeName(), latestCustomized,
newProduct);
newProduct, n.getNodeName());
mergedMap.put(n.nextCustomizedName(), merged);
} catch (UnsupportedOperationException e) {
throw new UnsupportedOperationException("Index: " + n.getNodeName() + ": " + e.getMessage(), e);
@@ -158,10 +158,9 @@ static void mergeIndex(String oldIndexFile, String newIndexFile, String targetDi

try {
JsonObject merged = IndexDefMergerUtils.merge(
"",
ancestor.getNodeName(), latestAncestor,
"", latestAncestor,
latest.getNodeName(), latestCustomized,
newProduct);
newProduct, n.getNodeName());
fileName = PathUtils.getName(n.nextCustomizedName());
writeFile(Paths.get(targetDirectory, fileName + ".json"),
addParent(n.nextCustomizedName(), merged));
@@ -0,0 +1,74 @@
/*
* 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.jackrabbit.oak.index.merge;

import static org.junit.Assert.assertEquals;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;

import org.apache.jackrabbit.oak.commons.json.JsonObject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/**
* Test merging index definitions.
*/
@RunWith(Parameterized.class)
public class IndexDefMergerScenariosTest {
@Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {
testCase("should use the latest base version for the base in merges", "merges-base"),
testCase("should use the latest base version for the base in merges when updating multiple version numbers", "merges-multi-version")
});
}

public static Object[] testCase(String name, String baseName) {
return new Object[] {
name,
baseName + "_build.json",
baseName + "_run.json",
baseName + "_expected.json"
};
}

private final String name;
private final JsonObject buildIndexes;
private final JsonObject runIndexes;
private final JsonObject expectedIndexes;

public IndexDefMergerScenariosTest(String name, String buildFile, String runFile, String expectedFile)
throws IOException {
this.name = name;
this.buildIndexes = JsonObject.fromJson(IndexDefMergerTest.readFromResource(buildFile), true);
this.runIndexes = JsonObject.fromJson(IndexDefMergerTest.readFromResource(runFile), true);
this.expectedIndexes = JsonObject.fromJson(IndexDefMergerTest.readFromResource(expectedFile), true);
}

@Test
public void testMerge() {
IndexDefMergerUtils.merge(buildIndexes, runIndexes);
assertEquals("Failed to execute test: " + name, expectedIndexes.toString(), buildIndexes.toString());
}

}
@@ -69,10 +69,9 @@ private void merge(JsonObject e) {
JsonObject product = e.getChildren().get("product");
try {
JsonObject got = IndexDefMergerUtils.merge(
"",
"/oak:index/test-1", ancestor,
"", ancestor,
"/oak:index/test-1-custom-1", custom,
product);
product, "/oak:index/test-2");
JsonObject expected = e.getChildren().get("expected");
assertEquals(expected.toString(), got.toString());
} catch (UnsupportedOperationException e2) {
@@ -4,14 +4,14 @@
"ancestor": {"value": 1, "a-old": 0},
"custom": {"value": 2, "b-new": 3},
"product": {"value": 1, "c-new": 4},
"expected": {"value": 2, "b-new": 3, "c-new": 4, "merges": ["/oak:index/test-1", "/oak:index/test-1-custom-1"]
"expected": {"value": 2, "b-new": 3, "c-new": 4, "merges": ["/oak:index/test-2", "/oak:index/test-1-custom-1"]
}
},
{
"ancestor": {"o": {"a": 1}},
"custom": {"o": {"a": 2, "c": 10}},
"product": {"o": {"a": 1, "p": 20}},
"expected": {"merges": ["/oak:index/test-1", "/oak:index/test-1-custom-1"], "o": {"a": 2, "c": 10, "p": 20 }}
"expected": {"merges": ["/oak:index/test-2", "/oak:index/test-1-custom-1"], "o": {"a": 2, "c": 10, "p": 20 }}
},
{
"ancestor": {"o": {"a": 1}},
@@ -192,7 +192,7 @@
}
}
},
"merges": ["/oak:index/test-1", "/oak:index/test-1-custom-1"]
"merges": ["/oak:index/test-2", "/oak:index/test-1-custom-1"]
}

}
@@ -10,7 +10,7 @@
},
"expectedNew": {
"/oak:index/lucene-2": { "a": 1, "b": 11, "d": 100, "z": 2 },
"/oak:index/lucene-2-custom-1": { "a": 2, "b": 11, "c": 1, "d": 100, "merges": ["/oak:index/lucene", "/oak:index/lucene-custom-1"] }
"/oak:index/lucene-2-custom-1": { "a": 2, "b": 11, "c": 1, "d": 100, "merges": ["/oak:index/lucene-2", "/oak:index/lucene-custom-1"] }
}
}
]
@@ -0,0 +1,55 @@
{
"/oak:index/lucene-2": {
"jcr:primaryType": "nam:oak:QueryIndexDefinition",
":version": 2,
"includePropertyTypes": ["String", "Binary"],
"type": "lucene",
"async": "async",
"reindex": false,
"reindexCount": 1,
"indexRules": {
"jcr:primaryType": "nam:nt:unstructured",
"nt:base": {
"jcr:primaryType": "nam:nt:unstructured",
"includePropertyTypes": ["String", "Binary"],
"properties": {
"jcr:primaryType": "nam:nt:unstructured",
"sling:alias": {
"jcr:primaryType": "nam:nt:unstructured",
"name": "sling:alias",
"index": false
},
"jcr:lastmodifiedby": {
"jcr:primaryType": "nam:nt:unstructured",
"name": "str:jcr:lastmodifiedby",
"index": false
},
"sling:resourcetype": {
"jcr:primaryType": "nam:nt:unstructured",
"name": "sling:resourcetype",
"index": false
},
"jcr:createdby": {
"jcr:primaryType": "nam:nt:unstructured",
"name": "str:jcr:createdby",
"index": false
},
"sling:vanitypath": {
"jcr:primaryType": "nam:nt:unstructured",
"name": "sling:vanitypath",
"index": false
},
"prop0": {
"jcr:primaryType": "nam:nt:unstructured",
"nodeScopeIndex": true,
"propertyIndex": false,
"analyzed": true,
"useInExcerpt": true,
"isRegexp": true,
"name": "^[^\\/]*$"
}
}
}
}
}
}
@@ -0,0 +1,111 @@
{
"/oak:index/lucene-2": {
"jcr:primaryType": "nam:oak:QueryIndexDefinition",
":version": 2,
"includePropertyTypes": ["String", "Binary"],
"type": "lucene",
"async": "async",
"reindex": false,
"reindexCount": 1,
"indexRules": {
"jcr:primaryType": "nam:nt:unstructured",
"nt:base": {
"jcr:primaryType": "nam:nt:unstructured",
"includePropertyTypes": ["String", "Binary"],
"properties": {
"jcr:primaryType": "nam:nt:unstructured",
"sling:alias": {
"jcr:primaryType": "nam:nt:unstructured",
"name": "sling:alias",
"index": false
},
"jcr:lastmodifiedby": {
"jcr:primaryType": "nam:nt:unstructured",
"name": "str:jcr:lastmodifiedby",
"index": false
},
"sling:resourcetype": {
"jcr:primaryType": "nam:nt:unstructured",
"name": "sling:resourcetype",
"index": false
},
"jcr:createdby": {
"jcr:primaryType": "nam:nt:unstructured",
"name": "str:jcr:createdby",
"index": false
},
"sling:vanitypath": {
"jcr:primaryType": "nam:nt:unstructured",
"name": "sling:vanitypath",
"index": false
},
"prop0": {
"jcr:primaryType": "nam:nt:unstructured",
"nodeScopeIndex": true,
"propertyIndex": false,
"analyzed": true,
"useInExcerpt": true,
"isRegexp": true,
"name": "^[^\\/]*$"
}
}
}
}
},
"/oak:index/lucene-2-custom-1": {
"jcr:primaryType": "nam:oak:QueryIndexDefinition",
"includePropertyTypes": ["String", "Binary"],
"type": "lucene",
"async": "async",
"merges": ["/oak:index/lucene-2", "/oak:index/lucene-1-custom-1"],
"indexRules": {
"jcr:primaryType": "nam:nt:unstructured",
"nt:base": {
"jcr:primaryType": "nam:nt:unstructured",
"includePropertyTypes": ["String", "Binary"],
"properties": {
"jcr:primaryType": "nam:nt:unstructured",
"sling:alias": {
"jcr:primaryType": "nam:nt:unstructured",
"name": "sling:alias",
"index": false
},
"jcr:lastmodifiedby": {
"jcr:primaryType": "nam:nt:unstructured",
"name": "str:jcr:lastmodifiedby",
"index": false
},
"sling:resourcetype": {
"jcr:primaryType": "nam:nt:unstructured",
"name": "sling:resourcetype",
"index": false
},
"jcr:createdby": {
"jcr:primaryType": "nam:nt:unstructured",
"name": "str:jcr:createdby",
"index": false
},
"sling:vanitypath": {
"jcr:primaryType": "nam:nt:unstructured",
"name": "sling:vanitypath",
"index": false
},
"prop0": {
"jcr:primaryType": "nam:nt:unstructured",
"nodeScopeIndex": true,
"propertyIndex": false,
"analyzed": true,
"useInExcerpt": true,
"isRegexp": true,
"name": "^[^\\/]*$"
},
"myco:myProperty": {
"jcr:primaryType": "nam:nt:unstructured",
"name": "myco:myProperty",
"index": false
}
}
}
}
}
}

0 comments on commit 511d8f7

Please sign in to comment.