Skip to content

ACL supporting dry run mode and batching - #309

Merged
krystian-panek-vmltech merged 6 commits into
mainfrom
acl-batching
Jul 28, 2026
Merged

ACL supporting dry run mode and batching #309
krystian-panek-vmltech merged 6 commits into
mainfrom
acl-batching

Conversation

@krystian-panek-vmltech

@krystian-panek-vmltech krystian-panek-vmltech commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

🎉 ACL now respects repo transaction control (dryRun / batch / autoCommit)

Until now, ACM's acl operations (users, groups, permissions) always saved to the
repository immediately, ignoring repo transaction settings. That's fixed — acl now
goes through the same commit policy as repo, so you can preview and batch ACL changes.

What you can do now:

• Dry-run your ACL setup — preview everything, commit nothing:

    repo.dryRun(inputs.value("dryRun")) {
        def johnDoe = acl.createUser { id = "john.doe"; ... }.tap {
            allow { path = "/content"; permissions = ["jcr:read"] }
        }
        acl.createGroup { id = "acme-authors" }.tap { addMember(johnDoe); ... }
    }

• Batch large ACL scripts into a single commit via repo.batch { ... } instead of a
save after every operation.
• Plain scripts still auto-commit per operation (default), so nothing changes unless you opt in.

Proof (dry-run vs real runs):
# dry run ON -> created + applied, then "Changes reverted" (nothing persisted)
Created user 'alice.doe'
Applied allow permissions for authorizable 'alice.doe' at path '/content'
Dry run completed. Changes reverted.

# real run #1 -> actually creates & commits
Created user 'alice.doe'
Applied allow permissions for authorizable 'alice.doe' at path '/content'

# real run #2 -> idempotent, proving #1 committed and dry-run left no trace
Skipped creating user 'alice.doe' (already exists)
Skipped setting allow permissions for authorizable 'alice.doe' at path '/content' (already set)

Under the hood: introduced a small CommitPolicy seam shared by repo, acl and the
locker, so a single auto-commit flag governs the whole session. Backward compatible. ✅

@krystian-panek-vmltech krystian-panek-vmltech changed the title ACL with no auto-commit ACL supporting dry run mode and batching Jul 28, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a shared CommitPolicy seam so ACL-related operations (users/groups/permissions) and locking respect repository transaction control (dry-run, batching, and auto-commit) instead of always persisting immediately.

Changes:

  • Added CommitPolicy interface and wired Repo to implement it, so auto-commit decisions can be shared.
  • Updated ACL internals to commit via the provided CommitPolicy rather than always calling session.save().
  • Updated Locker to consult CommitPolicy.isAutoCommit() when deciding whether to persist lock changes.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
core/src/main/java/dev/vml/es/acm/core/repo/Repo.java Makes Repo the shared commit policy owner and adds batch(...) support.
core/src/main/java/dev/vml/es/acm/core/repo/Locker.java Uses a commit policy (auto-commit flag) when committing lock/unlock operations.
core/src/main/java/dev/vml/es/acm/core/repo/CommitPolicy.java New commit-policy abstraction used by repo/acl/locker.
core/src/main/java/dev/vml/es/acm/core/code/CodeContext.java Passes Repo into Acl so ACL respects repo transaction settings.
core/src/main/java/dev/vml/es/acm/core/acl/utils/PermissionsManager.java Switches persistence to CommitPolicy.commit(context) with contextual commit messages.
core/src/main/java/dev/vml/es/acm/core/acl/utils/AuthorizableManager.java Switches persistence to CommitPolicy.commit(context) and improves one error message.
core/src/main/java/dev/vml/es/acm/core/acl/AclContext.java Plumbs CommitPolicy into ACL managers.
core/src/main/java/dev/vml/es/acm/core/acl/Acl.java Adds constructor overload to accept a CommitPolicy.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread core/src/main/java/dev/vml/es/acm/core/repo/Repo.java

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (5)

core/src/main/java/dev/vml/es/acm/core/acl/utils/AuthorizableManager.java:241

  • commitPolicy.commit(...) can throw RepoException (runtime) which will currently escape as a non-AclException, unlike other failure paths in this class that consistently wrap errors in AclException. Consider translating commit failures to AclException to keep the ACL API’s exception surface consistent.
    private void save(String context) {
        commitPolicy.commit(context);
    }

core/src/main/java/dev/vml/es/acm/core/acl/utils/PermissionsManager.java:65

  • commitPolicy.commit(...) may throw RepoException which currently bubbles up as a non-AclException. Wrapping commit failures here would make error handling consistent with the rest of PermissionsManager (which uses AclException for failures).
    private void save(String context) {
        commitPolicy.commit(context);
    }

core/src/main/java/dev/vml/es/acm/core/repo/Repo.java:146

  • Repo.batch restores autoCommit in finally but does not revert transient changes when operation.run() or the final commit() fails. That can leave uncommitted changes in the shared session, and subsequent operations (with auto-commit re-enabled) may accidentally persist a partial batch. Revert on failure (and consider suppressing revert failures onto the original exception).
    public void batch(Runnable operation) {
        if (!autoCommit) {
            throw new RepoException("Cannot start a batch: already inside a batch or dry run scope.");
        }
        this.autoCommit = false;
        getLogger().info("Batch started. Changes will be committed once at the end.");
        try {
            operation.run();
            commit();
            getLogger().info("Batch completed. Changes committed.");
        } finally {
            this.autoCommit = true;
        }
    }

ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/repo/dry_run.yml:17

  • Docs say autoCommit applies only to repo and acl, but the PR also wires the policy into the locker (via Repo.getLocker()), and explicit commits like repo.commit() / resourceResolver.commit() / session.save() can still persist changes and defeat dry-run. Please clarify to avoid giving a false sense of safety.
  The `autoCommit` control applies only to operations performed via the `repo` and `acl` services.
  Since everything shares the same session, calling vanilla Sling/AEM/JCR APIs directly (e.g. `session.save()`)
  may trigger an accidental commit of the pending changes and defeat the dry run.

ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/repo/batch.yml:19

  • Docs say autoCommit applies only to repo and acl, but the PR also shares the commit policy with the locker (via Repo.getLocker()), and explicit commits like repo.commit() / resourceResolver.commit() / session.save() can still persist changes mid-batch. Consider clarifying this so the “commit at the end” guarantee isn’t overstated.
  The `autoCommit` control applies only to operations performed via the `repo` and `acl` services.
  Since everything shares the same session, calling vanilla Sling/AEM/JCR APIs directly (e.g. `session.save()`)
  may trigger an accidental commit of the pending changes and break the "commit at the end" guarantee.

@jakub-berlinski-wttech jakub-berlinski-wttech left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this change

@krystian-panek-vmltech
krystian-panek-vmltech merged commit 7794649 into main Jul 28, 2026
2 checks passed
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 this pull request may close these issues.

3 participants