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 8750ae874 [#5619] feat(api): supports credential api for Gravitino 
(#5690)
8750ae874 is described below

commit 8750ae874111b0548eec2803b615043a160f586b
Author: FANNG <[email protected]>
AuthorDate: Wed Dec 4 10:07:07 2024 +0800

    [#5619] feat(api): supports credential api for Gravitino (#5690)
    
    ### What changes were proposed in this pull request?
    
    This is the first PR of credential vending for Gravitino server to add
    credential API , please refer to #5682 for the overall workflow.
    Examples to use the API:
    
    ```java
        Catalog catalog = metalake.loadCatalog(catalogName);
        Credential[] credentials =
            catalog.supportsCredentials().getCredentials();
    
        Credential credential =
            catalog.supportsCredentials().getCredential(“s3-token”);
    ```
    
    ```java
        Fileset fileset = catalog.asFilesetCatalog().loadFileset(filesetIdent);
        Credential[] credentials =
            fileset.supportsCredentials().getCredentials();
        Credential credential =
           fileset.supportsCredentials().getCredential(“s3-token”);
    
    ```
    
    
    ### Why are the changes needed?
    
    Fix: #5619
    
    ### Does this PR introduce _any_ user-facing change?
    no
    
    ### How was this patch tested?
    using draft PR to do E2E test
---
 .../main/java/org/apache/gravitino/Catalog.java    |  9 +++
 .../gravitino/credential/SupportsCredentials.java  | 77 ++++++++++++++++++++++
 .../exceptions/NoSuchCredentialException.java      | 38 +++++++++++
 .../java/org/apache/gravitino/file/Fileset.java    |  9 +++
 4 files changed, 133 insertions(+)

diff --git a/api/src/main/java/org/apache/gravitino/Catalog.java 
b/api/src/main/java/org/apache/gravitino/Catalog.java
index ba8cf28d2..ce3bcc95c 100644
--- a/api/src/main/java/org/apache/gravitino/Catalog.java
+++ b/api/src/main/java/org/apache/gravitino/Catalog.java
@@ -22,6 +22,7 @@ import java.util.Locale;
 import java.util.Map;
 import org.apache.gravitino.annotation.Evolving;
 import org.apache.gravitino.authorization.SupportsRoles;
+import org.apache.gravitino.credential.SupportsCredentials;
 import org.apache.gravitino.file.FilesetCatalog;
 import org.apache.gravitino.messaging.TopicCatalog;
 import org.apache.gravitino.model.ModelCatalog;
@@ -207,4 +208,12 @@ public interface Catalog extends Auditable {
   default SupportsRoles supportsRoles() throws UnsupportedOperationException {
     throw new UnsupportedOperationException("Catalog does not support role 
operations");
   }
+
+  /**
+   * @return the {@link SupportsCredentials} if the catalog supports 
credential operations.
+   * @throws UnsupportedOperationException if the catalog does not support 
credential operations.
+   */
+  default SupportsCredentials supportsCredentials() throws 
UnsupportedOperationException {
+    throw new UnsupportedOperationException("Catalog does not support 
credential operations");
+  }
 }
diff --git 
a/api/src/main/java/org/apache/gravitino/credential/SupportsCredentials.java 
b/api/src/main/java/org/apache/gravitino/credential/SupportsCredentials.java
new file mode 100644
index 000000000..678172c42
--- /dev/null
+++ b/api/src/main/java/org/apache/gravitino/credential/SupportsCredentials.java
@@ -0,0 +1,77 @@
+/*
+ *  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.credential;
+
+import com.google.common.base.Preconditions;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.gravitino.exceptions.NoSuchCredentialException;
+
+/** Interface to get credentials. */
+public interface SupportsCredentials {
+
+  /**
+   * Retrieves an array of {@link Credential} objects.
+   *
+   * @return An array of {@link Credential} objects. In most cases the array 
only contains one
+   *     credential. If the object like {@link 
org.apache.gravitino.file.Fileset} contains multiple
+   *     locations for different storages like HDFS, S3, the array will 
contain multiple
+   *     credentials. The array could be empty if you request a credential for 
a catalog but the
+   *     credential provider couldn't generate the credential for the catalog, 
like S3 token
+   *     credential provider only generate credential for the specific object 
like {@link
+   *     org.apache.gravitino.file.Fileset}, {@link 
org.apache.gravitino.rel.Table}. There will be
+   *     at most one credential for one credential type.
+   */
+  Credential[] getCredentials() throws NoSuchCredentialException;
+
+  /**
+   * Retrieves an {@link Credential} object based on the specified credential 
type.
+   *
+   * @param credentialType The type of the credential like s3-token, 
s3-secret-key which defined in
+   *     the specific credentials.
+   * @return An {@link Credential} object with the specified credential type.
+   * @throws NoSuchCredentialException If the specific credential cannot be 
found.
+   */
+  default Credential getCredential(String credentialType) throws 
NoSuchCredentialException {
+    Preconditions.checkArgument(
+        StringUtils.isNotBlank(credentialType), "Credential type should not be 
empty");
+    Credential[] credentials = getCredentials();
+    if (credentials.length == 0) {
+      throw new NoSuchCredentialException(
+          "No credential found for the credential type: %s", credentialType);
+    }
+
+    List<Credential> filteredCredentials =
+        Arrays.stream(credentials)
+            .filter(credential -> 
credentialType.equals(credential.credentialType()))
+            .collect(Collectors.toList());
+    if (filteredCredentials.isEmpty()) {
+      throw new NoSuchCredentialException(
+          "No credential found for the credential type: %s", credentialType);
+    } else if (credentials.length > 1) {
+      throw new IllegalStateException(
+          "Multiple credentials found for the credential type:" + 
credentialType);
+    }
+
+    return filteredCredentials.get(0);
+  }
+}
diff --git 
a/api/src/main/java/org/apache/gravitino/exceptions/NoSuchCredentialException.java
 
b/api/src/main/java/org/apache/gravitino/exceptions/NoSuchCredentialException.java
new file mode 100644
index 000000000..9869d1e72
--- /dev/null
+++ 
b/api/src/main/java/org/apache/gravitino/exceptions/NoSuchCredentialException.java
@@ -0,0 +1,38 @@
+/*
+ *  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 the request credential type is not found. */
+public class NoSuchCredentialException 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 NoSuchCredentialException(@FormatString String message, Object... 
args) {
+    super(message, args);
+  }
+}
diff --git a/api/src/main/java/org/apache/gravitino/file/Fileset.java 
b/api/src/main/java/org/apache/gravitino/file/Fileset.java
index 97afcc650..6ada5f8c4 100644
--- a/api/src/main/java/org/apache/gravitino/file/Fileset.java
+++ b/api/src/main/java/org/apache/gravitino/file/Fileset.java
@@ -25,6 +25,7 @@ import org.apache.gravitino.Auditable;
 import org.apache.gravitino.Namespace;
 import org.apache.gravitino.annotation.Evolving;
 import org.apache.gravitino.authorization.SupportsRoles;
+import org.apache.gravitino.credential.SupportsCredentials;
 import org.apache.gravitino.tag.SupportsTags;
 
 /**
@@ -123,4 +124,12 @@ public interface Fileset extends Auditable {
   default SupportsRoles supportsRoles() {
     throw new UnsupportedOperationException("Fileset does not support role 
operations.");
   }
+
+  /**
+   * @return The {@link SupportsCredentials} if the fileset supports 
credential operations.
+   * @throws UnsupportedOperationException If the fileset does not support 
credential operations.
+   */
+  default SupportsCredentials supportsCredentials() {
+    throw new UnsupportedOperationException("Fileset does not support 
credential operations.");
+  }
 }

Reply via email to