This is an automated email from the ASF dual-hosted git repository.

jerryshao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/main by this push:
     new 9a8a847e40 [#13397] fix(core): notify the authorizer when setOwners 
sets the first owner (#13398)
9a8a847e40 is described below

commit 9a8a847e403802216919b1f8379e042802768462
Author: YangJie <[email protected]>
AuthorDate: Thu Sep 24 02:11:59 2026 -0400

    [#13397] fix(core): notify the authorizer when setOwners sets the first 
owner (#13398)
    
    ### What changes were proposed in this pull request?
    
    `OwnerManager.setOwners` now calls
    `notifyOwnerChange(originOwner.orElse(null), metalake, mo)`
    unconditionally, instead of only when a previous owner exists. This
    aligns the batch path with the single-object `setOwner` path.
    
    ### Why are the changes needed?
    
    The batch path skipped the authorizer notification when setting the
    first owner on an ownerless object, for example the automatic owner
    assignment when a schema is created, so a custom `GravitinoAuthorizer`
    never received `handleMetadataOwnerChange` for that case. The SPI
    contract documents `oldOwnerId` as `null` on the first owner, and the
    single-object path already behaves that way.
    
    Fix: #13397
    
    ### Does this PR introduce _any_ user-facing change?
    
    No.
    
    ### How was this patch tested?
    
    Added `TestOwnerManager.testInitialOwnerSetByBatchNotifiesAuthorizer`,
    which pins that a first-owner assignment through `setOwners` notifies
    the authorizer with a `null` old owner. It fails against the pre-fix
    code.
    
    Co-authored-by: Jerry Shao <[email protected]>
---
 .../gravitino/authorization/OwnerManager.java      |  2 +-
 .../gravitino/authorization/TestOwnerManager.java  | 39 ++++++++++++++++++++++
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git 
a/core/src/main/java/org/apache/gravitino/authorization/OwnerManager.java 
b/core/src/main/java/org/apache/gravitino/authorization/OwnerManager.java
index af83b65806..fc27c94718 100644
--- a/core/src/main/java/org/apache/gravitino/authorization/OwnerManager.java
+++ b/core/src/main/java/org/apache/gravitino/authorization/OwnerManager.java
@@ -210,7 +210,7 @@ public class OwnerManager implements OwnerDispatcher {
               mo,
               authorizationPlugin ->
                   authorizationPlugin.onOwnerSet(mo, originOwner.orElse(null), 
newOwner));
-          originOwner.ifPresent(owner -> notifyOwnerChange(owner, metalake, 
mo));
+          notifyOwnerChange(originOwner.orElse(null), metalake, mo);
         } catch (RuntimeException re) {
           LOG.warn(
               "Failed to notify authorization plugin for metadata object {} 
during batch setOwners",
diff --git 
a/core/src/test/java/org/apache/gravitino/authorization/TestOwnerManager.java 
b/core/src/test/java/org/apache/gravitino/authorization/TestOwnerManager.java
index 9bdb976327..832b00c993 100644
--- 
a/core/src/test/java/org/apache/gravitino/authorization/TestOwnerManager.java
+++ 
b/core/src/test/java/org/apache/gravitino/authorization/TestOwnerManager.java
@@ -290,4 +290,43 @@ public class TestOwnerManager {
           GravitinoEnv.getInstance(), "gravitinoAuthorizer", 
originalAuthorizer, true);
     }
   }
+
+  @Test
+  @Order(5)
+  public void testInitialOwnerSetByBatchNotifiesAuthorizer()
+      throws IllegalAccessException, IOException {
+    String catalogName = "catalog_initial_owner_notify_batch";
+    AuditInfo audit = 
AuditInfo.builder().withCreator("test").withCreateTime(Instant.now()).build();
+    CatalogEntity catalog =
+        CatalogEntity.builder()
+            .withId(idGenerator.nextId())
+            .withName(catalogName)
+            .withNamespace(Namespace.of(METALAKE))
+            .withType(Catalog.Type.RELATIONAL)
+            .withProvider("test")
+            .withAuditInfo(audit)
+            .build();
+    entityStore.put(catalog, false);
+
+    GravitinoAuthorizer authorizer = Mockito.mock(GravitinoAuthorizer.class);
+    GravitinoAuthorizer originalAuthorizer = 
GravitinoEnv.getInstance().gravitinoAuthorizer();
+    FieldUtils.writeField(GravitinoEnv.getInstance(), "gravitinoAuthorizer", 
authorizer, true);
+    try {
+      MetadataObject catalogObject =
+          MetadataObjects.of(Lists.newArrayList(catalogName), 
MetadataObject.Type.CATALOG);
+
+      ownerManager.setOwners(
+          METALAKE, Collections.singletonList(catalogObject), USER, 
Owner.Type.USER);
+
+      Mockito.verify(authorizer)
+          .handleMetadataOwnerChange(
+              Mockito.eq(METALAKE),
+              Mockito.isNull(),
+              Mockito.eq(NameIdentifier.of(METALAKE, catalogName)),
+              Mockito.eq(Entity.EntityType.CATALOG));
+    } finally {
+      FieldUtils.writeField(
+          GravitinoEnv.getInstance(), "gravitinoAuthorizer", 
originalAuthorizer, true);
+    }
+  }
 }

Reply via email to