diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/glue/ForGlueHiveMetastore.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/glue/ForGlueHiveMetastore.java new file mode 100644 index 000000000000..bb718759adf0 --- /dev/null +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/glue/ForGlueHiveMetastore.java @@ -0,0 +1,29 @@ +/* + * Licensed 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 io.trino.plugin.hive.metastore.glue; + +import com.google.inject.BindingAnnotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Retention(RUNTIME) +@Target({FIELD, PARAMETER, METHOD}) +@BindingAnnotation +public @interface ForGlueHiveMetastore {} diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/glue/GlueHiveExecutionInterceptor.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/glue/GlueHiveExecutionInterceptor.java index 5dd7417dfd88..1f62c0e78dac 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/glue/GlueHiveExecutionInterceptor.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/glue/GlueHiveExecutionInterceptor.java @@ -13,6 +13,7 @@ */ package io.trino.plugin.hive.metastore.glue; +import com.google.inject.Inject; import software.amazon.awssdk.core.SdkRequest; import software.amazon.awssdk.core.interceptor.Context; import software.amazon.awssdk.core.interceptor.ExecutionAttributes; @@ -24,9 +25,10 @@ public class GlueHiveExecutionInterceptor { private final boolean skipArchive; - GlueHiveExecutionInterceptor(boolean isSkipArchive) + @Inject + GlueHiveExecutionInterceptor(GlueHiveMetastoreConfig config) { - this.skipArchive = isSkipArchive; + this.skipArchive = config.isSkipArchive(); } @Override diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/glue/GlueMetastoreModule.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/glue/GlueMetastoreModule.java index 8c04a29ff7bb..584ad46efe92 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/glue/GlueMetastoreModule.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/glue/GlueMetastoreModule.java @@ -13,11 +13,15 @@ */ package io.trino.plugin.hive.metastore.glue; +import com.google.common.collect.ImmutableList; import com.google.inject.Binder; +import com.google.inject.Inject; import com.google.inject.Key; +import com.google.inject.Provider; import com.google.inject.Provides; import com.google.inject.Scopes; import com.google.inject.Singleton; +import com.google.inject.multibindings.Multibinder; import com.google.inject.multibindings.ProvidesIntoOptional; import io.airlift.configuration.AbstractConfigurationAwareModule; import io.airlift.units.Duration; @@ -32,6 +36,7 @@ import io.trino.spi.catalog.CatalogName; import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.core.interceptor.ExecutionInterceptor; import software.amazon.awssdk.http.apache.ApacheHttpClient; import software.amazon.awssdk.http.apache.ProxyConfiguration; import software.amazon.awssdk.regions.Region; @@ -52,10 +57,12 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; +import static com.google.inject.multibindings.Multibinder.newSetBinder; import static com.google.inject.multibindings.OptionalBinder.newOptionalBinder; import static com.google.inject.multibindings.ProvidesIntoOptional.Type.DEFAULT; import static io.airlift.configuration.ConfigBinder.configBinder; import static io.trino.plugin.base.ClosingBinder.closingBinder; +import static java.util.Objects.requireNonNull; import static org.weakref.jmx.guice.ExportBinder.newExporter; public class GlueMetastoreModule @@ -76,6 +83,10 @@ protected void setup(Binder binder) .in(Scopes.SINGLETON); binder.bind(Key.get(boolean.class, AllowHiveTableRename.class)).toInstance(false); + Multibinder executionInterceptorMultibinder = newSetBinder(binder, ExecutionInterceptor.class, ForGlueHiveMetastore.class); + executionInterceptorMultibinder.addBinding().toProvider(TelemetryExecutionInterceptorProvider.class).in(Scopes.SINGLETON); + executionInterceptorMultibinder.addBinding().to(GlueHiveExecutionInterceptor.class).in(Scopes.SINGLETON); + closingBinder(binder).registerCloseable(GlueClient.class); } @@ -121,16 +132,12 @@ public static GlueCache createGlueCache(CachingHiveMetastoreConfig config, Catal @Provides @Singleton - public static GlueClient createGlueClient(GlueHiveMetastoreConfig config, OpenTelemetry openTelemetry) + public static GlueClient createGlueClient(GlueHiveMetastoreConfig config, @ForGlueHiveMetastore Set executionInterceptors) { GlueClientBuilder glue = GlueClient.builder(); glue.overrideConfiguration(builder -> builder - .addExecutionInterceptor(AwsSdkTelemetry.builder(openTelemetry) - .setCaptureExperimentalSpanAttributes(true) - .setRecordIndividualHttpError(true) - .build().newExecutionInterceptor()) - .addExecutionInterceptor(new GlueHiveExecutionInterceptor(config.isSkipArchive())) + .executionInterceptors(ImmutableList.copyOf(executionInterceptors)) .retryStrategy(retryBuilder -> retryBuilder .retryOnException(throwable -> throwable instanceof ConcurrentModificationException) .backoffStrategy(BackoffStrategy.exponentialDelay( @@ -209,4 +216,26 @@ else if (config.getPinGlueClientToCurrentRegion()) { return sts.build(); } + + private static class TelemetryExecutionInterceptorProvider + implements Provider + { + private final OpenTelemetry openTelemetry; + + @Inject + public TelemetryExecutionInterceptorProvider(OpenTelemetry openTelemetry) + { + this.openTelemetry = requireNonNull(openTelemetry, "openTelemetry is null"); + } + + @Override + public ExecutionInterceptor get() + { + return AwsSdkTelemetry.builder(openTelemetry) + .setCaptureExperimentalSpanAttributes(true) + .setRecordIndividualHttpError(true) + .build() + .newExecutionInterceptor(); + } + } } diff --git a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/TestHiveGlueMetadataListing.java b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/TestHiveGlueMetadataListing.java index 9b886f4fbf69..42fc5ff5f07d 100644 --- a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/TestHiveGlueMetadataListing.java +++ b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/TestHiveGlueMetadataListing.java @@ -16,7 +16,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import io.airlift.log.Logger; -import io.opentelemetry.api.OpenTelemetry; import io.trino.Session; import io.trino.plugin.hive.metastore.glue.GlueHiveMetastore; import io.trino.plugin.hive.metastore.glue.GlueHiveMetastoreConfig; @@ -27,6 +26,7 @@ import io.trino.tpch.TpchTable; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; +import org.testcontainers.shaded.com.google.common.collect.ImmutableSet; import software.amazon.awssdk.services.glue.GlueClient; import software.amazon.awssdk.services.glue.model.CreateTableRequest; import software.amazon.awssdk.services.glue.model.TableInput; @@ -124,7 +124,7 @@ private void createBrokenTable(Path dataDirectory) { GlueHiveMetastoreConfig glueConfig = new GlueHiveMetastoreConfig() .setDefaultWarehouseDir(dataDirectory.toString()); - try (GlueClient glueClient = createGlueClient(glueConfig, OpenTelemetry.noop())) { + try (GlueClient glueClient = createGlueClient(glueConfig, ImmutableSet.of())) { TableInput tableInput = TableInput.builder() .name(FAILING_TABLE_WITH_NULL_STORAGE_DESCRIPTOR_NAME) .tableType("HIVE") diff --git a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/glue/TestHiveConcurrentModificationGlueMetastore.java b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/glue/TestHiveConcurrentModificationGlueMetastore.java index 82a915e109fc..9a86ebb10570 100644 --- a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/glue/TestHiveConcurrentModificationGlueMetastore.java +++ b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/glue/TestHiveConcurrentModificationGlueMetastore.java @@ -13,9 +13,9 @@ */ package io.trino.plugin.hive.metastore.glue; -import io.opentelemetry.api.OpenTelemetry; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; +import org.testcontainers.shaded.com.google.common.collect.ImmutableSet; import software.amazon.awssdk.awscore.exception.AwsErrorDetails; import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration; import software.amazon.awssdk.retries.api.RefreshRetryTokenRequest; @@ -36,7 +36,7 @@ public class TestHiveConcurrentModificationGlueMetastore @Test public void testGlueClientShouldRetryConcurrentModificationException() { - try (GlueClient glueClient = createGlueClient(new GlueHiveMetastoreConfig(), OpenTelemetry.noop())) { + try (GlueClient glueClient = createGlueClient(new GlueHiveMetastoreConfig(), ImmutableSet.of())) { ClientOverrideConfiguration clientOverrideConfiguration = glueClient.serviceClientConfiguration().overrideConfiguration(); RetryStrategy retryStrategy = clientOverrideConfiguration.retryStrategy().orElseThrow(); diff --git a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/glue/TestingGlueHiveMetastore.java b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/glue/TestingGlueHiveMetastore.java index 40eeb96b0894..6c490989f11b 100644 --- a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/glue/TestingGlueHiveMetastore.java +++ b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/glue/TestingGlueHiveMetastore.java @@ -13,7 +13,7 @@ */ package io.trino.plugin.hive.metastore.glue; -import io.opentelemetry.api.OpenTelemetry; +import com.google.common.collect.ImmutableSet; import io.trino.plugin.hive.metastore.glue.GlueHiveMetastore.TableKind; import software.amazon.awssdk.services.glue.GlueClient; @@ -52,7 +52,7 @@ public static GlueHiveMetastore createTestingGlueHiveMetastore(URI warehouseUri, { GlueHiveMetastoreConfig glueConfig = new GlueHiveMetastoreConfig() .setDefaultWarehouseDir(warehouseUri.toString()); - GlueClient glueClient = createGlueClient(glueConfig, OpenTelemetry.noop()); + GlueClient glueClient = createGlueClient(glueConfig, ImmutableSet.of()); registerResource.accept(glueClient); return new GlueHiveMetastore( glueClient,