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

Enforce creation of /var/groovyconsole with the right node type #50

Closed
kwin opened this issue Jan 22, 2024 · 4 comments · Fixed by #51
Closed

Enforce creation of /var/groovyconsole with the right node type #50

kwin opened this issue Jan 22, 2024 · 4 comments · Fixed by #51

Comments

@kwin
Copy link
Contributor

kwin commented Jan 22, 2024

Right now in https://github.com/orbinson/aem-groovy-console/blob/main/ui.config/src/main/content/jcr_root/apps/groovyconsole-config/osgiconfig/config/org.apache.sling.jcr.repoinit.RepositoryInitializer-groovyconsole.config you enforce creation of subnodes within /var/groovyconsole which require that to be a lenient type (e.g. sling:Folder). If for some reason the node /var/groovyconsole is of type nt:folder starting the repository fails with the following exception:

javax.jcr.RepositoryException: Applying repoinit operation failed despite retry; set loglevel to DEBUG to see all exceptions. Last exception message was: Session.save failed: javax.jcr.nodetype.ConstraintViolationException: OakConstraint0001: /var/groovyconsole[[nt:folder]]: No matching definition found for child node audit with effective type [nt:unstructured]
	at org.apache.sling.jcr.repoinit.impl.RepositoryInitializerFactory.applyOperations(RepositoryInitializerFactory.java:176) [org.apache.sling.jcr.repoinit:1.1.38]
	at org.apache.sling.jcr.repoinit.impl.RepositoryInitializerFactory.processRepository(RepositoryInitializerFactory.java:129) [org.apache.sling.jcr.repoinit:1.1.38]
	at org.apache.sling.jcr.base.AbstractSlingRepositoryManager.executeRepositoryInitializers(AbstractSlingRepositoryManager.java:627) [org.apache.sling.jcr.base:3.1.14]
	at org.apache.sling.jcr.base.AbstractSlingRepositoryManager.initializeAndRegisterRepositoryService(AbstractSlingRepositoryManager.java:575) [org.apache.sling.jcr.base:3.1.14]
	at org.apache.sling.jcr.base.AbstractSlingRepositoryManager.access$300(AbstractSlingRepositoryManager.java:96) [org.apache.sling.jcr.base:3.1.14]
	at org.apache.sling.jcr.base.AbstractSlingRepositoryManager$4.run(AbstractSlingRepositoryManager.java:544) [org.apache.sling.jcr.base:3.1.14]
Caused by: org.apache.sling.jcr.repoinit.impl.RepoInitException: Session.save failed: javax.jcr.nodetype.ConstraintViolationException: OakConstraint0001: /var/groovyconsole[[nt:folder]]: No matching definition found for child node audit with effective type [nt:unstructured]
	at org.apache.sling.jcr.repoinit.impl.DoNothingVisitor.report(DoNothingVisitor.java:66) [org.apache.sling.jcr.repoinit:1.1.38]
	at org.apache.sling.jcr.repoinit.impl.AclVisitor.visitCreatePath(AclVisitor.java:207) [org.apache.sling.jcr.repoinit:1.1.38]
	at org.apache.sling.repoinit.parser.operations.CreatePath.accept(CreatePath.java:71) [org.apache.sling.repoinit.parser:1.6.14]
	at org.apache.sling.jcr.repoinit.impl.JcrRepoInitOpsProcessorImpl.apply(JcrRepoInitOpsProcessorImpl.java:56) [org.apache.sling.jcr.repoinit:1.1.38]
	at org.apache.sling.jcr.repoinit.impl.RepositoryInitializerFactory.lambda$applyOperations$0(RepositoryInitializerFactory.java:151) [org.apache.sling.jcr.repoinit:1.1.38]
	at org.apache.sling.jcr.repoinit.impl.RetryableOperation.apply(RetryableOperation.java:57) [org.apache.sling.jcr.repoinit:1.1.38]
	at org.apache.sling.jcr.repoinit.impl.RepositoryInitializerFactory.applyOperations(RepositoryInitializerFactory.java:149) [org.apache.sling.jcr.repoinit:1.1.38]
	... 5 common frames omitted
Caused by: javax.jcr.nodetype.ConstraintViolationException: OakConstraint0001: /var/groovyconsole[[nt:folder]]: No matching definition found for child node audit with effective type [nt:unstructured]
	at org.apache.jackrabbit.oak.api.CommitFailedException.asRepositoryException(CommitFailedException.java:226) [org.apache.jackrabbit.oak-api:1.22.17]
	at org.apache.jackrabbit.oak.api.CommitFailedException.asRepositoryException(CommitFailedException.java:213) [org.apache.jackrabbit.oak-api:1.22.17]
	at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.newRepositoryException(SessionDelegate.java:669) [org.apache.jackrabbit.oak-jcr:1.22.17]
	at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.save(SessionDelegate.java:495) [org.apache.jackrabbit.oak-jcr:1.22.17]
	at org.apache.jackrabbit.oak.jcr.session.SessionImpl$9.performVoid(SessionImpl.java:453) [org.apache.jackrabbit.oak-jcr:1.22.17]
	at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.performVoid(SessionDelegate.java:273) [org.apache.jackrabbit.oak-jcr:1.22.17]
	at org.apache.jackrabbit.oak.jcr.session.SessionImpl.save(SessionImpl.java:450) [org.apache.jackrabbit.oak-jcr:1.22.17]
	at com.adobe.granite.repository.impl.CRX3SessionImpl.save(CRX3SessionImpl.java:208) [com.adobe.granite.repository:1.6.28.CQ650-B0001]
	at org.apache.sling.jcr.repoinit.impl.AclVisitor.visitCreatePath(AclVisitor.java:205) [org.apache.sling.jcr.repoinit:1.1.38]
	... 10 common frames omitted
Caused by: org.apache.jackrabbit.oak.api.CommitFailedException: OakConstraint0001: /var/groovyconsole[[nt:folder]]: No matching definition found for child node audit with effective type [nt:unstructured]
	at org.apache.jackrabbit.oak.plugins.nodetype.TypeEditor$1.onConstraintViolation(TypeEditor.java:109) [org.apache.jackrabbit.oak-core:1.22.17]
	at org.apache.jackrabbit.oak.plugins.nodetype.TypeEditor.constraintViolation(TypeEditor.java:234) [org.apache.jackrabbit.oak-core:1.22.17]
	at org.apache.jackrabbit.oak.plugins.nodetype.TypeEditor.childNodeChanged(TypeEditor.java:312) [org.apache.jackrabbit.oak-core:1.22.17]
	at org.apache.jackrabbit.oak.plugins.nodetype.TypeEditor.childNodeAdded(TypeEditor.java:285) [org.apache.jackrabbit.oak-core:1.22.17]
	at org.apache.jackrabbit.oak.spi.commit.VisibleEditor.childNodeAdded(VisibleEditor.java:89) [org.apache.jackrabbit.oak-store-spi:1.22.17]
	at org.apache.jackrabbit.oak.spi.commit.CompositeEditor.childNodeAdded(CompositeEditor.java:107) [org.apache.jackrabbit.oak-store-spi:1.22.17]
	at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeAdded(EditorDiff.java:115) [org.apache.jackrabbit.oak-store-spi:1.22.17]
	at org.apache.jackrabbit.oak.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:639) [org.apache.jackrabbit.oak-segment-tar:1.22.17]
	at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:147) [org.apache.jackrabbit.oak-store-spi:1.22.17]
	at org.apache.jackrabbit.oak.segment.MapRecord$4.childNodeChanged(MapRecord.java:471) [org.apache.jackrabbit.oak-segment-tar:1.22.17]
	at org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:517) [org.apache.jackrabbit.oak-segment-tar:1.22.17]
	at org.apache.jackrabbit.oak.segment.MapRecord.compareBranch(MapRecord.java:595) [org.apache.jackrabbit.oak-segment-tar:1.22.17]
	at org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:496) [org.apache.jackrabbit.oak-segment-tar:1.22.17]
	at org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:462) [org.apache.jackrabbit.oak-segment-tar:1.22.17]
	at org.apache.jackrabbit.oak.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:651) [org.apache.jackrabbit.oak-segment-tar:1.22.17]
	at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:147) [org.apache.jackrabbit.oak-store-spi:1.22.17]
	at org.apache.jackrabbit.oak.segment.MapRecord$4.childNodeChanged(MapRecord.java:471) [org.apache.jackrabbit.oak-segment-tar:1.22.17]
	at org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:517) [org.apache.jackrabbit.oak-segment-tar:1.22.17]
	at org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:462) [org.apache.jackrabbit.oak-segment-tar:1.22.17]
	at org.apache.jackrabbit.oak.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:651) [org.apache.jackrabbit.oak-segment-tar:1.22.17]
	at org.apache.jackrabbit.oak.spi.commit.EditorDiff.process(EditorDiff.java:51) [org.apache.jackrabbit.oak-store-spi:1.22.17]
	at org.apache.jackrabbit.oak.spi.commit.EditorHook.processCommit(EditorHook.java:54) [org.apache.jackrabbit.oak-store-spi:1.22.17]
	at org.apache.jackrabbit.oak.spi.commit.CompositeHook.processCommit(CompositeHook.java:60) [org.apache.jackrabbit.oak-store-spi:1.22.17]
	at org.apache.jackrabbit.oak.spi.commit.CompositeHook.processCommit(CompositeHook.java:60) [org.apache.jackrabbit.oak-store-spi:1.22.17]
	at org.apache.jackrabbit.oak.segment.scheduler.Commit.apply(Commit.java:99) [org.apache.jackrabbit.oak-segment-tar:1.22.17]
	at org.apache.jackrabbit.oak.segment.scheduler.LockBasedScheduler.execute(LockBasedScheduler.java:299) [org.apache.jackrabbit.oak-segment-tar:1.22.17]
	at org.apache.jackrabbit.oak.segment.scheduler.LockBasedScheduler.schedule(LockBasedScheduler.java:270) [org.apache.jackrabbit.oak-segment-tar:1.22.17]
	at org.apache.jackrabbit.oak.segment.SegmentNodeStore.merge(SegmentNodeStore.java:211) [org.apache.jackrabbit.oak-segment-tar:1.22.17]
	at org.apache.jackrabbit.oak.core.MutableRoot.commit(MutableRoot.java:251) [org.apache.jackrabbit.oak-core:1.22.17]
	at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.commit(SessionDelegate.java:346) [org.apache.jackrabbit.oak-jcr:1.22.17]
	at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.save(SessionDelegate.java:493) [org.apache.jackrabbit.oak-jcr:1.22.17]
	... 15 common frames omitted
@kwin
Copy link
Contributor Author

kwin commented Jan 22, 2024

To me it is not clear which code is supposed to create/creating the parent node /var/groovyconsole in the first place. Any idea @bdhoine or @royteeuwen?

Update: So repoinit itself creates non-existing ancestors with default type (and in case that fails with sling:Folder): https://github.com/apache/sling-org-apache-sling-jcr-repoinit/blob/41509793b720eac9328bef47c61745d6f94e197b/src/main/java/org/apache/sling/jcr/repoinit/impl/NodeVisitor.java#L182-L186. The real solution is to switch to enforce path (https://issues.apache.org/jira/browse/SLING-11736). Unfortunately that is not available in AEM 6.5.x. We face a race condition in our packages when we deploy from scratch our all container package which contains both

  1. https://github.com/valtech/aem-easy-content-upgrade/tree/develop/complete (including aem-groovy-console) and
  2. A custom package containing only the child /var/groovyconsole/customer/script with no .content.xml for uncovered ancestor nodes

on AEM 6.5.x (still shipping with a very outdated JR FileVault version). In case Groovy Console's OSGi configuration for repoinit kicks in first, everything is fine, but in case our package is installed first /var/groovyconsole is created as nt:folder and never modified afterwards. Restarting such an AEM instance leads to the repository not starting fully with the exception message from above.

@royteeuwen
Copy link
Contributor

@kwin didn't even know that create path was deprecated, thanks for that!

This does indeed make it a hard case to fix in AEM 6.5 though... (or any AEM instance where you use an all package through installation of the package manager, you always get race conditions)

What I could do is rewrite this to BundleActivator code, this way we can change the primary type of /var/groovyconsole even in AEM 6.5.

The only other alternative I can think of is putting package dependencies between the config package of aem-groovy-console and your customer scripts, but even then you aren't certain the OSGi config will actually be executed before installing the depending package :/

Do you have any other suggestions?

@kwin
Copy link
Contributor Author

kwin commented Jan 22, 2024

I don’t have a good idea either. The proper solution is „enforce path“ but only available in AEMaaCS unfortunately. Maybe the node /var/groovyconsole/audit can be converted to sling:Folder as that is allowed in the pretty restricted nt:folder as well. WDYT?

kwin added a commit to kwin/aem-groovy-console that referenced this issue Jan 22, 2024
less likely

Only create those nodes via repoinit which are not created implicitly
through packages.

This closes orbinson#50
@royteeuwen
Copy link
Contributor

@kwin sorry for the long wait, we had issues with releasing this repo because of GPG issues. This is now released.

FYI, I'm planning to release a version 20.x in the upcoming weeks with the changes from Barry and to upgrade groovy to JDK 22 support (Groovy 4.0.18) and a new feature inspired from Jenkins pipeline libraries where you can do @Library('path/in/crx') to load in extra groovy "snippets" that you'd like to share over multiple groovy files at runtime instead of having to do a code deploy to add extra functionality

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants