This is an automated email from the ASF dual-hosted git repository.
jshao 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 8f3296cade [#7141] feat(api): add APIs for policy operations (#7187)
8f3296cade is described below
commit 8f3296cadec208ff82a4de6e3a99e9b9ee6e8ebd
Author: mchades <[email protected]>
AuthorDate: Fri May 30 16:40:08 2025 +0800
[#7141] feat(api): add APIs for policy operations (#7187)
### What changes were proposed in this pull request?
add APIs for policy operations
### Why are the changes needed?
Fix: #7141
### Does this PR introduce _any_ user-facing change?
no
### How was this patch tested?
no need
---
.../exceptions/IllegalPolicyException.java | 37 ++++
.../exceptions/NoSuchPolicyException.java | 49 ++++++
.../PolicyAlreadyAssociatedException.java | 50 ++++++
.../exceptions/PolicyAlreadyExistsException.java | 50 ++++++
.../java/org/apache/gravitino/policy/Policy.java | 141 +++++++++++++++
.../org/apache/gravitino/policy/PolicyChange.java | 195 +++++++++++++++++++++
.../apache/gravitino/policy/PolicyOperations.java | 144 +++++++++++++++
.../apache/gravitino/policy/SupportsPolicies.java | 65 +++++++
8 files changed, 731 insertions(+)
diff --git
a/api/src/main/java/org/apache/gravitino/exceptions/IllegalPolicyException.java
b/api/src/main/java/org/apache/gravitino/exceptions/IllegalPolicyException.java
new file mode 100644
index 0000000000..027ad4bee9
--- /dev/null
+++
b/api/src/main/java/org/apache/gravitino/exceptions/IllegalPolicyException.java
@@ -0,0 +1,37 @@
+/*
+ * 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.gravitino.exceptions;
+
+import com.google.errorprone.annotations.FormatMethod;
+import com.google.errorprone.annotations.FormatString;
+
+/** An exception thrown when a policy is invalid. */
+public class IllegalPolicyException extends IllegalArgumentException {
+
+ /**
+ * Constructs a new exception with the specified detail message.
+ *
+ * @param message the detail message.
+ * @param args the arguments to the message.
+ */
+ @FormatMethod
+ public IllegalPolicyException(@FormatString String message, Object... args) {
+ super(String.format(message, args));
+ }
+}
diff --git
a/api/src/main/java/org/apache/gravitino/exceptions/NoSuchPolicyException.java
b/api/src/main/java/org/apache/gravitino/exceptions/NoSuchPolicyException.java
new file mode 100644
index 0000000000..761860581a
--- /dev/null
+++
b/api/src/main/java/org/apache/gravitino/exceptions/NoSuchPolicyException.java
@@ -0,0 +1,49 @@
+/*
+ * 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.gravitino.exceptions;
+
+import com.google.errorprone.annotations.FormatMethod;
+import com.google.errorprone.annotations.FormatString;
+
+/** Exception thrown when a policy with specified name is not existed. */
+public class NoSuchPolicyException extends NotFoundException {
+
+ /**
+ * Constructs a new exception with the specified detail message.
+ *
+ * @param message the detail message.
+ * @param args the arguments to the message.
+ */
+ @FormatMethod
+ public NoSuchPolicyException(@FormatString String message, Object... args) {
+ super(message, args);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and cause.
+ *
+ * @param cause the cause.
+ * @param message the detail message.
+ * @param args the arguments to the message.
+ */
+ @FormatMethod
+ public NoSuchPolicyException(Throwable cause, String message, Object...
args) {
+ super(cause, message, args);
+ }
+}
diff --git
a/api/src/main/java/org/apache/gravitino/exceptions/PolicyAlreadyAssociatedException.java
b/api/src/main/java/org/apache/gravitino/exceptions/PolicyAlreadyAssociatedException.java
new file mode 100644
index 0000000000..96f3d36582
--- /dev/null
+++
b/api/src/main/java/org/apache/gravitino/exceptions/PolicyAlreadyAssociatedException.java
@@ -0,0 +1,50 @@
+/*
+ * 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.gravitino.exceptions;
+
+import com.google.errorprone.annotations.FormatMethod;
+
+/**
+ * Exception thrown when a policy with specified name is already associated
with a metadata object.
+ */
+public class PolicyAlreadyAssociatedException extends AlreadyExistsException {
+
+ /**
+ * Constructs a new exception with the specified detail message.
+ *
+ * @param message the detail message.
+ * @param args the arguments to the message.
+ */
+ @FormatMethod
+ public PolicyAlreadyAssociatedException(String message, Object... args) {
+ super(message, args);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and cause.
+ *
+ * @param cause the cause.
+ * @param message the detail message.
+ * @param args the arguments to the message.
+ */
+ @FormatMethod
+ public PolicyAlreadyAssociatedException(Throwable cause, String message,
Object... args) {
+ super(cause, message, args);
+ }
+}
diff --git
a/api/src/main/java/org/apache/gravitino/exceptions/PolicyAlreadyExistsException.java
b/api/src/main/java/org/apache/gravitino/exceptions/PolicyAlreadyExistsException.java
new file mode 100644
index 0000000000..16908f6e82
--- /dev/null
+++
b/api/src/main/java/org/apache/gravitino/exceptions/PolicyAlreadyExistsException.java
@@ -0,0 +1,50 @@
+/*
+ * 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.gravitino.exceptions;
+
+import com.google.errorprone.annotations.FormatMethod;
+import com.google.errorprone.annotations.FormatString;
+
+/** Exception thrown when a policy with specified name already exists. */
+public class PolicyAlreadyExistsException extends AlreadyExistsException {
+
+ /**
+ * Constructs a new exception with the specified detail message.
+ *
+ * @param message the detail message.
+ * @param args the arguments to the message.
+ */
+ @FormatMethod
+ public PolicyAlreadyExistsException(@FormatString String message, Object...
args) {
+ super(message, args);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and cause.
+ *
+ * @param cause the cause.
+ * @param message the detail message.
+ * @param args the arguments to the message.
+ */
+ @FormatMethod
+ public PolicyAlreadyExistsException(
+ Throwable cause, @FormatString String message, Object... args) {
+ super(cause, message, args);
+ }
+}
diff --git a/api/src/main/java/org/apache/gravitino/policy/Policy.java
b/api/src/main/java/org/apache/gravitino/policy/Policy.java
new file mode 100644
index 0000000000..d8c9b6fd38
--- /dev/null
+++ b/api/src/main/java/org/apache/gravitino/policy/Policy.java
@@ -0,0 +1,141 @@
+/*
+ * 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.gravitino.policy;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import org.apache.gravitino.Auditable;
+import org.apache.gravitino.MetadataObject;
+import org.apache.gravitino.annotation.Evolving;
+import org.apache.gravitino.exceptions.IllegalPolicyException;
+
+/**
+ * The interface of the policy. The policy is a set of rules that can be
associated with a metadata
+ * object. The policy can be used for data governance and so on.
+ */
+@Evolving
+public interface Policy extends Auditable {
+
+ /**
+ * Get the name of the policy.
+ *
+ * @return The name of the policy.
+ */
+ String name();
+
+ /**
+ * Get the type of the policy.
+ *
+ * @return The type of the policy.
+ */
+ String type();
+
+ /**
+ * Get the comment of the policy.
+ *
+ * @return The comment of the policy.
+ */
+ String comment();
+
+ /**
+ * Whether the policy is enabled or not.
+ *
+ * @return True if the policy is enabled, false otherwise.
+ */
+ boolean enabled();
+
+ /**
+ * Whether the policy is exclusive or not. If the policy is exclusive, only
one of the same type
+ * policy can be associated with the same object. If the policy is not
exclusive, multiple
+ * policies of the same type can be associated with the same object.
+ *
+ * @return True if the policy is exclusive, false otherwise.
+ */
+ boolean exclusive();
+
+ /**
+ * Whether the policy is inheritable or not. If the policy is inheritable,
it can be inherited by
+ * child objects. If the policy is not inheritable, it can only be
associated with the metadata
+ * object itself.
+ *
+ * @return True if the policy is inheritable, false otherwise.
+ */
+ boolean inheritable();
+
+ /**
+ * Get the set of the metadata object types that the policy can be
associated with.
+ *
+ * @return The set of the metadata object types that the policy can be
associated with.
+ */
+ Set<MetadataObject.Type> supportedObjectTypes();
+
+ /**
+ * Get the content of the policy.
+ *
+ * @return The content of the policy.
+ */
+ Content content();
+
+ /**
+ * Check if the policy is inherited from a parent object or not.
+ *
+ * <p>Note: The return value is optional, Only when the policy is associated
with a metadata
+ * object, and called from the metadata object, the return value will be
present. Otherwise, it
+ * will be empty.
+ *
+ * @return True if the policy is inherited, false if it is owned by the
object itself. Empty if
+ * the policy is not associated with any object.
+ */
+ Optional<Boolean> inherited();
+
+ /**
+ * Validate the policy. This method should be called when the policy is
created or updated. It
+ * will check if the policy is valid or not. If the policy is not valid, it
will throw an
+ * IllegalPolicyException.
+ *
+ * @throws IllegalPolicyException if the policy is not valid.
+ */
+ void validate() throws IllegalPolicyException;
+
+ /** @return The associated objects of the policy. */
+ default AssociatedObjects associatedObjects() {
+ throw new UnsupportedOperationException("The associatedObjects method is
not supported.");
+ }
+
+ /** The interface of the content of the policy. */
+ interface Content {
+
+ /** @return The additional properties of the policy. */
+ Map<String, String> properties();
+ }
+
+ /** The interface of the associated objects of the policy. */
+ interface AssociatedObjects {
+
+ /** @return The number of objects that are associated with this policy */
+ default int count() {
+ MetadataObject[] objects = objects();
+ return objects == null ? 0 : objects.length;
+ }
+
+ /** @return The list of objects that are associated with this policy. */
+ MetadataObject[] objects();
+ }
+}
diff --git a/api/src/main/java/org/apache/gravitino/policy/PolicyChange.java
b/api/src/main/java/org/apache/gravitino/policy/PolicyChange.java
new file mode 100644
index 0000000000..db4199aa23
--- /dev/null
+++ b/api/src/main/java/org/apache/gravitino/policy/PolicyChange.java
@@ -0,0 +1,195 @@
+/*
+ * 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.gravitino.policy;
+
+import java.util.Objects;
+import org.apache.gravitino.annotation.Evolving;
+
+/**
+ * Interface for supporting policy changes. This interface will be used to
provide policy
+ * modification operations for each policy.
+ */
+@Evolving
+public interface PolicyChange {
+
+ /**
+ * Creates a new policy change to rename the policy.
+ *
+ * @param newName The new name of the policy.
+ * @return The policy change.
+ */
+ static PolicyChange rename(String newName) {
+ return new RenamePolicy(newName);
+ }
+
+ /**
+ * Creates a new policy change to update the policy comment.
+ *
+ * @param newComment The new comment for the policy.
+ * @return The policy change.
+ */
+ static PolicyChange updateComment(String newComment) {
+ return new UpdatePolicyComment(newComment);
+ }
+
+ /**
+ * Creates a new policy change to update the content of the policy.
+ *
+ * @param content The new content for the policy.
+ * @return The policy change.
+ */
+ static PolicyChange updateContent(Policy.Content content) {
+ return new UpdateContent(content);
+ }
+
+ /** A policy change to rename the policy. */
+ final class RenamePolicy implements PolicyChange {
+ private final String newName;
+
+ private RenamePolicy(String newName) {
+ this.newName = newName;
+ }
+
+ /**
+ * Get the new name of the policy.
+ *
+ * @return The new name of the policy.
+ */
+ public String getNewName() {
+ return newName;
+ }
+
+ /**
+ * Get the type of the policy change.
+ *
+ * @return The type of the policy change.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || getClass() != o.getClass()) return false;
+ RenamePolicy that = (RenamePolicy) o;
+ return Objects.equals(newName, that.newName);
+ }
+
+ /**
+ * Get the hash code of the policy change.
+ *
+ * @return The hash code of the policy change.
+ */
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(newName);
+ }
+
+ /**
+ * Get the string representation of the policy change.
+ *
+ * @return The string representation of the policy change.
+ */
+ @Override
+ public String toString() {
+ return "RENAME POLICY " + newName;
+ }
+ }
+
+ /** Creates a new policy change to update the comment of the policy. */
+ final class UpdatePolicyComment implements PolicyChange {
+ private final String newComment;
+
+ private UpdatePolicyComment(String newComment) {
+ this.newComment = newComment;
+ }
+
+ /**
+ * Get the new comment of the policy.
+ *
+ * @return The new comment of the policy.
+ */
+ public String getNewComment() {
+ return newComment;
+ }
+
+ /**
+ * Get the type of the policy change.
+ *
+ * @return The type of the policy change.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || getClass() != o.getClass()) return false;
+ UpdatePolicyComment that = (UpdatePolicyComment) o;
+ return Objects.equals(newComment, that.newComment);
+ }
+
+ /**
+ * Get the hash code of the policy change.
+ *
+ * @return The hash code of the policy change.
+ */
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(newComment);
+ }
+
+ /**
+ * Get the string representation of the policy change.
+ *
+ * @return The string representation of the policy change.
+ */
+ @Override
+ public String toString() {
+ return "UPDATE POLICY COMMENT " + newComment;
+ }
+ }
+
+ /** A policy change to update the content of the policy. */
+ final class UpdateContent implements PolicyChange {
+ private final Policy.Content content;
+
+ private UpdateContent(Policy.Content content) {
+ this.content = content;
+ }
+
+ /**
+ * Get the content of the policy change.
+ *
+ * @return The content of the policy change.
+ */
+ public Policy.Content getContent() {
+ return content;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || getClass() != o.getClass()) return false;
+ UpdateContent that = (UpdateContent) o;
+ return Objects.equals(content, that.content);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(content);
+ }
+
+ @Override
+ public String toString() {
+ return "UPDATE CONTENT " + content;
+ }
+ }
+}
diff --git
a/api/src/main/java/org/apache/gravitino/policy/PolicyOperations.java
b/api/src/main/java/org/apache/gravitino/policy/PolicyOperations.java
new file mode 100644
index 0000000000..22cc51dab3
--- /dev/null
+++ b/api/src/main/java/org/apache/gravitino/policy/PolicyOperations.java
@@ -0,0 +1,144 @@
+/*
+ * 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.gravitino.policy;
+
+import java.util.Set;
+import org.apache.gravitino.MetadataObject;
+import org.apache.gravitino.annotation.Evolving;
+import org.apache.gravitino.exceptions.NoSuchMetalakeException;
+import org.apache.gravitino.exceptions.NoSuchPolicyException;
+import org.apache.gravitino.exceptions.PolicyAlreadyExistsException;
+
+/**
+ * The interface of the policy operations. The policy operations are used to
manage policies under a
+ * metalake. This interface will be mixed with GravitinoMetalake or
GravitinoClient to provide
+ * policy operations.
+ */
+@Evolving
+public interface PolicyOperations {
+
+ /**
+ * List all the policy names under a metalake.
+ *
+ * @return The list of policy names.
+ * @throws NoSuchMetalakeException If the metalake does not exist.
+ */
+ String[] listPolicies() throws NoSuchMetalakeException;
+
+ /**
+ * List all the policies with detailed information under a metalake.
+ *
+ * @return The list of policies.
+ * @throws NoSuchMetalakeException If the metalake does not exist.
+ */
+ Policy[] listPolicyInfos() throws NoSuchMetalakeException;
+
+ /**
+ * Get a policy by its name under a metalake.
+ *
+ * @param name The name of the policy.
+ * @return The policy.
+ * @throws NoSuchPolicyException If the policy does not exist.
+ */
+ Policy getPolicy(String name) throws NoSuchPolicyException;
+
+ /**
+ * Create a built-in type policy under a metalake. The exclusive,
inheritable, and supported
+ * object types parameters attributes are determined by the type of the
policy.
+ *
+ * @param name The name of the policy.
+ * @param type The type of the policy.
+ * @param comment The comment of the policy.
+ * @param enabled Whether the policy is enabled or not.
+ * @param content The content of the policy.
+ * @return The created policy.
+ * @throws PolicyAlreadyExistsException If the policy already exists.
+ */
+ Policy createPolicy(
+ String name, String type, String comment, boolean enabled,
Policy.Content content)
+ throws PolicyAlreadyExistsException;
+
+ /**
+ * Create a new policy under a metalake.
+ *
+ * @param name The name of the policy.
+ * @param type The type of the policy.
+ * @param comment The comment of the policy.
+ * @param enabled Whether the policy is enabled or not.
+ * @param exclusive Whether the policy is exclusive or not. If the policy is
exclusive, only one
+ * of the same type policy can be associated with the same object, and
the same type of policy
+ * on a metadata object will override the one inherited from the parent
object. If the policy
+ * is not exclusive, multiple policies of the same type can be
associated with the same
+ * object.
+ * @param inheritable Whether the policy is inheritable or not. If the
policy is inheritable, it
+ * will be inherited automatically by child objects. If the policy is
not inheritable, it can
+ * only be associated with the metadata object itself.
+ * @param supportedObjectTypes The set of the metadata object types that the
policy can be
+ * associated with
+ * @param content The content of the policy.
+ * @return The created policy.
+ * @throws PolicyAlreadyExistsException If the policy already exists.
+ */
+ Policy createPolicy(
+ String name,
+ String type,
+ String comment,
+ boolean enabled,
+ boolean exclusive,
+ boolean inheritable,
+ Set<MetadataObject.Type> supportedObjectTypes,
+ Policy.Content content)
+ throws PolicyAlreadyExistsException;
+
+ /**
+ * Enable a policy under a metalake. If the policy is already enabled, this
method does nothing.
+ *
+ * @param name The name of the policy to enable.
+ * @throws NoSuchPolicyException If the policy does not exist.
+ */
+ void enablePolicy(String name) throws NoSuchPolicyException;
+
+ /**
+ * Disable a policy under a metalake. If the policy is already disabled,
this method does nothing.
+ *
+ * @param name The name of the policy to disable.
+ * @throws NoSuchPolicyException If the policy does not exist.
+ */
+ void disablePolicy(String name) throws NoSuchPolicyException;
+
+ /**
+ * Alter a policy under a metalake.
+ *
+ * @param name The name of the policy.
+ * @param changes The changes to apply to the policy.
+ * @return The altered policy.
+ * @throws NoSuchPolicyException If the policy does not exist.
+ * @throws IllegalArgumentException If the changes cannot be associated with
the policy.
+ */
+ Policy alterPolicy(String name, PolicyChange... changes)
+ throws NoSuchPolicyException, IllegalArgumentException;
+
+ /**
+ * Delete a policy under a metalake.
+ *
+ * @param name The name of the policy.
+ * @return True if the policy is deleted, false if the policy does not exist.
+ */
+ boolean deletePolicy(String name);
+}
diff --git
a/api/src/main/java/org/apache/gravitino/policy/SupportsPolicies.java
b/api/src/main/java/org/apache/gravitino/policy/SupportsPolicies.java
new file mode 100644
index 0000000000..eb5bd327f1
--- /dev/null
+++ b/api/src/main/java/org/apache/gravitino/policy/SupportsPolicies.java
@@ -0,0 +1,65 @@
+/*
+ * 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.gravitino.policy;
+
+import org.apache.gravitino.annotation.Evolving;
+import org.apache.gravitino.exceptions.NoSuchPolicyException;
+import org.apache.gravitino.exceptions.PolicyAlreadyAssociatedException;
+
+/**
+ * The interface for supporting getting or associating policies with a
metadata object. This
+ * interface will be mixed with metadata objects to provide policy operations.
+ */
+@Evolving
+public interface SupportsPolicies {
+ /** @return List all the policy names for the specific object. */
+ String[] listPolicies();
+
+ /** @return List all the policies with details for the specific object. */
+ Policy[] listPolicyInfos();
+
+ /**
+ * Get a policy by its name for the specific object.
+ *
+ * @param name The name of the policy.
+ * @return The policy.
+ * @throws NoSuchPolicyException If the policy does not associate with the
object.
+ */
+ Policy getPolicy(String name) throws NoSuchPolicyException;
+
+ /**
+ * Associate policies to the specific object. The policiesToAdd will be
applied to the object and
+ * the policiesToRemove will be removed from the object. Note that:
+ *
+ * <ol>
+ * <li>Adding or removing policies that are not existed will be ignored.
+ * <li>If the same name policy is in both policiesToAdd and
policiesToRemove, it will be
+ * ignored.
+ * <li>If the policy is already applied to the object, it will throw {@link
+ * PolicyAlreadyAssociatedException}
+ * </ol>
+ *
+ * @param policiesToAdd The policies to be added to the object.
+ * @param policiesToRemove The policies to remove.
+ * @return The list of applied policies.
+ * @throws PolicyAlreadyAssociatedException If the policy is already applied
to the object.
+ */
+ String[] associatePolicies(String[] policiesToAdd, String[] policiesToRemove)
+ throws PolicyAlreadyAssociatedException;
+}