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.");
+ }
}