Skip to content

Commit e31592a

Browse files
committed
Enforce "compatVersion" set to "2" (Long) for lucene index definitions
This closes #39
1 parent 29bde1b commit e31592a

File tree

4 files changed

+35
-17
lines changed

4 files changed

+35
-17
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ Install hooks have no limitations when being used with the AEMaaCS SDK Quickstar
6767
Content packages of type `mixed` are allowed to have both mutable and immutable nodes. AEMaaCS will only ever install the immutable part of it. The mutable part won't be installed as that cannot be successful (due to missing write access at the time of installation).
6868
Further details at <https://experienceleague.adobe.com/docs/experience-manager-cloud-service/implementing/deploying/overview.html?lang=en#deploying-content-packages-via-cloud-manager-and-package-manager>.
6969

70-
## Enforce Oak index definitions of type `lucene`
70+
## Enforce Oak index definitions of type `lucene` with `compatVersion` set to 2
7171

72-
Currently only Oak index definitions of type `lucene` are supported in AEMaaCS. Further details in <https://experienceleague.adobe.com/docs/experience-manager-cloud-service/operations/indexing.html?lang=en#changes-in-aem-as-a-cloud-service>.
72+
Currently only Oak index definitions of type `lucene` with property `compatVersion` set to the (Long) value `2` are supported in AEMaaCS. Further details in <https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/operations/indexing#current-limitations>.
7373

7474
## Follow naming policy for Oak index definition node names
7575

pom.xml

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,11 @@
6969
<artifactId>slf4j-api</artifactId>
7070
<version>1.7.20</version>
7171
</dependency>
72-
72+
<dependency>
73+
<groupId>javax.jcr</groupId>
74+
<artifactId>jcr</artifactId>
75+
<version>2.0</version>
76+
</dependency>
7377
<!-- http://metainf-services.kohsuke.org/index.html -->
7478
<dependency>
7579
<groupId>org.kohsuke.metainf-services</groupId>
@@ -112,12 +116,6 @@
112116
<artifactId>jackrabbit-jcr-commons</artifactId>
113117
<version>${jackrabbit.version}</version>
114118
</dependency>
115-
<dependency>
116-
<groupId>javax.jcr</groupId>
117-
<artifactId>jcr</artifactId>
118-
<version>2.0</version>
119-
<scope>test</scope>
120-
</dependency>
121119
<dependency>
122120
<groupId>org.apache.jackrabbit</groupId>
123121
<artifactId>oak-jackrabbit-api</artifactId>

src/main/java/biz/netcentric/filevault/validator/aem/cloud/AemCloudValidator.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,19 @@
2020

2121
import java.util.Collection;
2222
import java.util.Collections;
23+
import java.util.Optional;
2324
import java.util.regex.Pattern;
2425

26+
import javax.jcr.PropertyType;
27+
2528
import org.apache.jackrabbit.spi.Name;
2629
import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;
2730
import org.apache.jackrabbit.util.Text;
2831
import org.apache.jackrabbit.vault.packaging.PackageProperties;
2932
import org.apache.jackrabbit.vault.packaging.PackageType;
3033
import org.apache.jackrabbit.vault.util.Constants;
3134
import org.apache.jackrabbit.vault.util.DocViewNode2;
35+
import org.apache.jackrabbit.vault.util.DocViewProperty2;
3236
import org.apache.jackrabbit.vault.validation.spi.DocumentViewXmlValidator;
3337
import org.apache.jackrabbit.vault.validation.spi.MetaInfPathValidator;
3438
import org.apache.jackrabbit.vault.validation.spi.NodeContext;
@@ -48,8 +52,9 @@ public class AemCloudValidator implements NodePathValidator, MetaInfPathValidato
4852
static final String VIOLATION_MESSAGE_LIBS_NODES = "Nodes below '/libs' may be overwritten by future product upgrades. Rather use '/apps'. Further details at https://experienceleague.adobe.com/docs/experience-manager-cloud-service/implementing/developing/full-stack/overlays.html?lang=en#developing";
4953
static final String VIOLATION_MESSAGE_MUTABLE_NODES_IN_MIXED_PACKAGE = "Mutable nodes in mixed package types are not installed!";
5054
static final String VIOLATION_MESSAGE_MUTABLE_NODES_AND_IMMUTABLE_NODES_IN_SAME_PACKAGE = "Mutable and immutable nodes must not be mixed in the same package. You must separate those into two packages and give them both a dedicated package type!";
51-
static final String VIOLATION_MESSAGE_NON_LUCENE_TYPE_INDEX_DEFINITION = "Only oak:QueryIndexDefinitions of type='lucene' are supported in AEMaaCS but found type='%s'. Compare with https://experienceleague.adobe.com/docs/experience-manager-cloud-service/operations/indexing.html?lang=en#changes-in-aem-as-a-cloud-service";
52-
55+
static final String VIOLATION_MESSAGE_NON_LUCENE_TYPE_INDEX_DEFINITION = "Only oak:QueryIndexDefinitions of type='lucene' are supported in AEMaaCS but found type='%s'. Compare with https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/operations/indexing#current-limitations";
56+
static final String VIOLATION_MESSAGE_INVALID_COMPAT_VERSION_IN_INDEX_DEFINITION = "The compatVersion property of an oak:QueryIndexDefinition must be set to the Long value '2' but found '%s'. Compare with https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/operations/indexing#current-limitations";
57+
5358
// this path is relative to META-INF
5459
private static final Path INSTALL_HOOK_PATH = Paths.get(Constants.VAULT_DIR, Constants.HOOKS_DIR);
5560
/**
@@ -78,6 +83,7 @@ public class AemCloudValidator implements NodePathValidator, MetaInfPathValidato
7883

7984
private static final int MAX_NUM_VIOLATIONS_PER_TYPE = 5;
8085
private static final Name PN_TYPE = NameFactoryImpl.getInstance().create(Name.NS_DEFAULT_URI, "type");
86+
private static final Name PN_COMPAT_VERSION = NameFactoryImpl.getInstance().create(Name.NS_DEFAULT_URI, "compatVersion");
8187
private int numVarNodeViolations = 0;
8288
private int numLibNodeViolations = 0;
8389
private int numMutableNodeViolations = 0;
@@ -212,6 +218,12 @@ static boolean isPackagePathInstalledConditionally(String runMode, Path packageR
212218
if (!"lucene".equals(indexType)) {
213219
messages.add(new ValidationMessage(defaultSeverity,
214220
String.format(VIOLATION_MESSAGE_NON_LUCENE_TYPE_INDEX_DEFINITION, indexType)));
221+
} else {
222+
Optional<DocViewProperty2> compatVersionProperty = node.getProperty(PN_COMPAT_VERSION);
223+
if (!compatVersionProperty.isPresent() || compatVersionProperty.get().getType() != PropertyType.LONG || !compatVersionProperty.get().getStringValue().orElse("").equals("2")) {
224+
messages.add(new ValidationMessage(defaultSeverity,
225+
String.format(VIOLATION_MESSAGE_INVALID_COMPAT_VERSION_IN_INDEX_DEFINITION, compatVersionProperty.map(p -> p.formatValue()).orElse("not set"))));
226+
}
215227
}
216228
// check node name (jcr qualified name as contained in the path)
217229
String qualifiedName = Text.getName(nodeContext.getNodePath());

src/test/java/biz/netcentric/filevault/validator/aem/cloud/AemCloudValidatorTest.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package biz.netcentric.filevault.validator.aem.cloud;
22

3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
35
/*-
46
* #%L
57
* AEM Cloud Validator
@@ -20,6 +22,8 @@
2022
import java.util.List;
2123
import java.util.Optional;
2224

25+
import javax.jcr.PropertyType;
26+
2327
import org.apache.jackrabbit.spi.Name;
2428
import org.apache.jackrabbit.spi.commons.name.NameConstants;
2529
import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;
@@ -30,11 +34,11 @@
3034
import org.apache.jackrabbit.vault.validation.spi.ValidationMessage;
3135
import org.apache.jackrabbit.vault.validation.spi.ValidationMessageSeverity;
3236
import org.apache.jackrabbit.vault.validation.spi.util.NodeContextImpl;
37+
import org.hamcrest.MatcherAssert;
38+
import org.hamcrest.Matchers;
3339
import org.junit.jupiter.api.Assertions;
3440
import org.junit.jupiter.api.Test;
3541

36-
import static org.junit.jupiter.api.Assertions.assertEquals;
37-
3842
class AemCloudValidatorTest {
3943

4044
@Test
@@ -99,12 +103,13 @@ void testValidIndexDefinitions() {
99103
Collection<ValidationMessage> messages = new ArrayList<>();
100104
List<DocViewProperty2> properties = Arrays.asList(
101105
new DocViewProperty2(NameConstants.JCR_PRIMARYTYPE, "oak:QueryIndexDefinition"),
102-
new DocViewProperty2(NameFactoryImpl.getInstance().create(Name.NS_DEFAULT_URI, "type"), "lucene"));
106+
new DocViewProperty2(NameFactoryImpl.getInstance().create(Name.NS_DEFAULT_URI, "type"), "lucene"),
107+
new DocViewProperty2(NameFactoryImpl.getInstance().create(Name.NS_DEFAULT_URI, "compatVersion"), "2", PropertyType.LONG));
103108
// valid lucene index definition
104109
NodeContext context = new NodeContextImpl("/oak:index/prefix.myindex-1-custom-1", Paths.get("_oak_index/test"),Paths.get("./jcr_root"));
105110
DocViewNode2 node = new DocViewNode2(NameConstants.JCR_ROOT, properties);
106111
Optional.ofNullable(validator.validate(node, context, true)).ifPresent(messages::addAll);
107-
Assertions.assertTrue(messages.isEmpty());
112+
MatcherAssert.assertThat(messages, Matchers.empty());
108113
context = new NodeContextImpl("/oak:index/productindex-1-custom-1", Paths.get("_oak_index/test"),Paths.get("./jcr_root"));
109114
Optional.ofNullable(validator.validate(node, context, true)).ifPresent(messages::addAll);
110115
Assertions.assertTrue(messages.isEmpty());
@@ -117,11 +122,14 @@ void testInvalidLuceneIndexDefinitions() {
117122
List<DocViewProperty2> properties = Arrays.asList(
118123
new DocViewProperty2(NameConstants.JCR_PRIMARYTYPE, "oak:QueryIndexDefinition"),
119124
new DocViewProperty2(NameFactoryImpl.getInstance().create(Name.NS_DEFAULT_URI, "type"), "lucene"));
125+
// invalid name and also compatVersion not set
120126
NodeContext context = new NodeContextImpl("/oak:index/myindex", Paths.get("_oak_index/test"),Paths.get("./jcr_root"));
121127
DocViewNode2 node = new DocViewNode2(NameConstants.JCR_ROOT, properties);
122128
Optional.ofNullable(validator.validate(node, context, true)).ifPresent(messages::addAll);
123-
assertEquals(1, messages.size());
124-
assertEquals(String.format(AemCloudValidator.VIOLATION_MESSAGE_INVALID_INDEX_DEFINITION_NODE_NAME, "myindex"), messages.iterator().next().getMessage());
129+
MatcherAssert.assertThat(messages, Matchers.containsInAnyOrder(
130+
new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(AemCloudValidator.VIOLATION_MESSAGE_INVALID_INDEX_DEFINITION_NODE_NAME, "myindex")),
131+
new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(AemCloudValidator.VIOLATION_MESSAGE_INVALID_COMPAT_VERSION_IN_INDEX_DEFINITION, "not set"))
132+
));
125133
}
126134

127135
@Test

0 commit comments

Comments
 (0)