Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* 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 com.google.common.collect.ImmutableMap;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;

/** Tencent Cloud COS secret key credential. */
public class COSSecretKeyCredential implements Credential {

/** COS secret key credential type. */
public static final String COS_SECRET_KEY_CREDENTIAL_TYPE = "cos-secret-key";
/** The static access key ID (a.k.a. SecretId in Tencent Cloud) used to access COS data. */
public static final String GRAVITINO_COS_STATIC_ACCESS_KEY_ID = "cos-access-key-id";
/** The static secret access key (a.k.a. SecretKey in Tencent Cloud) used to access COS data. */
public static final String GRAVITINO_COS_STATIC_SECRET_ACCESS_KEY = "cos-secret-access-key";

private String accessKeyId;
private String secretAccessKey;

/**
* Constructs an instance of {@link COSSecretKeyCredential} with the static COS access key ID and
* secret access key.
*
* @param accessKeyId The COS static access key ID.
* @param secretAccessKey The COS static secret access key.
*/
public COSSecretKeyCredential(String accessKeyId, String secretAccessKey) {
validate(accessKeyId, secretAccessKey, 0);
this.accessKeyId = accessKeyId;
this.secretAccessKey = secretAccessKey;
}

/**
* This is the constructor that is used by credential factory to create an instance of credential
* according to the credential information.
*/
public COSSecretKeyCredential() {}

@Override
public String credentialType() {
return COS_SECRET_KEY_CREDENTIAL_TYPE;
}

@Override
public long expireTimeInMs() {
return 0;
}

@Override
public Map<String, String> credentialInfo() {
return (new ImmutableMap.Builder<String, String>())
.put(GRAVITINO_COS_STATIC_ACCESS_KEY_ID, accessKeyId)
.put(GRAVITINO_COS_STATIC_SECRET_ACCESS_KEY, secretAccessKey)
.build();
}

/**
* Initialize the credential with the credential information.
*
* <p>This method is invoked to deserialize the credential in client side.
*
* @param credentialInfo The credential information from {@link #credentialInfo}.
* @param expireTimeInMs The expire-time from {@link #expireTimeInMs()}.
*/
@Override
public void initialize(Map<String, String> credentialInfo, long expireTimeInMs) {
String accessKeyId = credentialInfo.get(GRAVITINO_COS_STATIC_ACCESS_KEY_ID);
String secretAccessKey = credentialInfo.get(GRAVITINO_COS_STATIC_SECRET_ACCESS_KEY);
validate(accessKeyId, secretAccessKey, expireTimeInMs);
this.accessKeyId = accessKeyId;
this.secretAccessKey = secretAccessKey;
}

/**
* Get COS static access key ID.
*
* @return The COS access key ID.
*/
public String accessKeyId() {
return accessKeyId;
}

/**
* Get COS static secret access key.
*
* @return The COS secret access key.
*/
public String secretAccessKey() {
return secretAccessKey;
}

private void validate(String accessKeyId, String secretAccessKey, long expireTimeInMs) {
Preconditions.checkArgument(
StringUtils.isNotBlank(accessKeyId), "COS access key Id should not empty");
Preconditions.checkArgument(
StringUtils.isNotBlank(secretAccessKey), "COS secret access key should not empty");
Comment on lines +113 to +116
Preconditions.checkArgument(
expireTimeInMs == 0, "The expiration time of COSSecretKeyCredential is not 0");
}
}
78 changes: 78 additions & 0 deletions bundles/tencent-bundle/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* 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.
*/
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar

plugins {
`maven-publish`
id("java")
alias(libs.plugins.shadow)
}

dependencies {
implementation(project(":bundles:tencent"))

implementation(libs.commons.collections3)
implementation(libs.commons.io)
implementation(libs.hadoop3.client.api)
implementation(libs.hadoop3.client.runtime)
implementation(libs.hadoop3.cos)
implementation(libs.httpclient)
}

tasks.withType(ShadowJar::class.java) {
isZip64 = true
configurations = listOf(project.configurations.runtimeClasspath.get())
archiveClassifier.set("")
mergeServiceFiles()

dependencies {
exclude(dependency("org.slf4j:slf4j-api"))

// Exclude Gravitino modules to prevent class duplication and "Split Packages" issues.
// These modules (api, common, catalogs) are already provided by the Gravitino server and gravitino-filesystem-hadoop3-runtime.
// Including them here would cause the Relocation rules below to incorrectly modify
// method signatures (e.g., JsonUtils.anyFieldMapper returning a shaded ObjectMapper),
// leading to java.lang.NoSuchMethodError at runtime.
exclude(project(":api"))
exclude(project(":common"))
exclude(project(":catalogs:catalog-common"))
exclude(project(":catalogs:hadoop-common"))
}

// Relocate dependencies to avoid conflicts.
// hadoop-cos (from com.qcloud.cos:hadoop-cos) bundles the qcloud-cos SDK and a few common
// libraries; relocate them under "org.apache.gravitino.tencent.shaded.*" following the
// same pattern as the aws/aliyun/azure/gcp bundles.
relocate("com.fasterxml.jackson", "org.apache.gravitino.tencent.shaded.com.fasterxml.jackson")
relocate("com.google", "org.apache.gravitino.tencent.shaded.com.google")
relocate("com.qcloud", "org.apache.gravitino.tencent.shaded.com.qcloud")
relocate("org.apache.commons", "org.apache.gravitino.tencent.shaded.org.apache.commons")
relocate("org.apache.http", "org.apache.gravitino.tencent.shaded.org.apache.http")
relocate("org.checkerframework", "org.apache.gravitino.tencent.shaded.org.checkerframework")
relocate("org.jacoco.agent.rt", "org.apache.gravitino.tencent.shaded.org.jacoco.agent.rt")
}

tasks.jar {
dependsOn(tasks.named("shadowJar"))
archiveClassifier.set("empty")
}

tasks.compileJava {
dependsOn(":catalogs:catalog-fileset:runtimeJars")
}
58 changes: 58 additions & 0 deletions bundles/tencent/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* 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.
*/

plugins {
`maven-publish`
id("java")
}

dependencies {
implementation(project(":api")) {
exclude("*")
}
implementation(project(":catalogs:catalog-common")) {
exclude("*")
}
implementation(project(":catalogs:hadoop-common")) {
exclude("*")
}
implementation(project(":common")) {
exclude("*")
}

implementation(libs.commons.lang3)
implementation(libs.guava)
implementation(libs.jackson.databind)

compileOnly(libs.hadoop3.client.api)
compileOnly(libs.hadoop3.cos)
compileOnly(libs.lombok)

testImplementation(libs.hadoop3.client.api)
testImplementation(libs.hadoop3.client.runtime)
testImplementation(libs.hadoop3.cos)
testImplementation(libs.junit.jupiter.api)
testImplementation(libs.junit.jupiter.params)
testRuntimeOnly(libs.junit.jupiter.engine)
testRuntimeOnly(libs.bundles.log4j)
}

tasks.compileJava {
dependsOn(":catalogs:catalog-fileset:runtimeJars")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* 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.cos.credential;

import java.util.Map;
import org.apache.gravitino.credential.COSSecretKeyCredential;
import org.apache.gravitino.credential.Credential;
import org.apache.gravitino.credential.CredentialContext;
import org.apache.gravitino.credential.CredentialProvider;
import org.apache.gravitino.credential.config.COSCredentialConfig;

/** Generate COS access key and secret key to access Tencent Cloud COS data. */
public class COSSecretKeyProvider implements CredentialProvider {

private String accessKey;
private String secretKey;

@Override
public void initialize(Map<String, String> properties) {
COSCredentialConfig cosCredentialConfig = new COSCredentialConfig(properties);
this.accessKey = cosCredentialConfig.accessKeyID();
this.secretKey = cosCredentialConfig.secretAccessKey();
}

@Override
public void close() {}

@Override
public boolean supportsScheme(String scheme) {
// hadoop-cos exposes the `cosn://` scheme, matching `COSFileSystemProvider#scheme()`.
return "cosn".equalsIgnoreCase(scheme);
}

@Override
public String credentialType() {
return COSSecretKeyCredential.COS_SECRET_KEY_CREDENTIAL_TYPE;
}

@Override
public Credential getCredential(CredentialContext context) {
return new COSSecretKeyCredential(accessKey, secretKey);
}
}
Loading
Loading