From 081fbe1fbe0af527dd945093925646cdba06afbc Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Wed, 5 Mar 2025 11:28:24 -0800 Subject: [PATCH 01/12] builds --- ...olarisEclipseLinkMetaStoreManagerTest.java | 2 +- .../PolarisApplicationIntegrationTest.java | 5 +- ...larisManagementServiceIntegrationTest.java | 5 +- .../PolarisRestCatalogIntegrationTest.java | 11 +- ...PolarisRestCatalogViewIntegrationBase.java | 9 +- .../it/test/PolarisSparkIntegrationTest.java | 5 +- .../polaris/core/PolarisCallContext.java | 2 + .../polaris/core/PolarisConfiguration.java | 275 ------------------ .../core/auth/PolarisAuthorizerImpl.java | 7 +- .../config/BehaviorChangeConfiguration.java | 37 +++ .../core/config/FeatureConfiguration.java | 185 ++++++++++++ .../core/config/PolarisConfiguration.java | 140 +++++++++ .../PolarisConfigurationStore.java | 4 +- .../PolarisStorageConfigurationInfo.java | 6 +- .../aws/AwsCredentialsStorageIntegration.java | 4 +- .../AzureCredentialsStorageIntegration.java | 6 +- .../storage/cache/StorageCredentialCache.java | 11 +- .../PolarisTreeMapMetaStoreManagerTest.java | 2 +- .../InMemoryStorageIntegrationTest.java | 2 +- .../PolarisConfigurationStoreTest.java | 6 +- .../admintool/config/QuarkusProducers.java | 2 +- .../quarkus/config/QuarkusProducers.java | 2 +- .../quarkus/admin/PolarisAuthzTestBase.java | 7 +- .../admin/PolarisOverlappingTableTest.java | 4 +- .../catalog/BasePolarisCatalogTest.java | 35 +-- .../catalog/BasePolarisCatalogViewTest.java | 9 +- ...PolarisCatalogHandlerWrapperAuthzTest.java | 2 +- .../test/PolarisIntegrationTestHelper.java | 2 +- .../service/admin/PolarisAdminService.java | 7 +- .../service/admin/PolarisServiceImpl.java | 5 +- .../service/catalog/BasePolarisCatalog.java | 29 +- .../catalog/IcebergCatalogAdapter.java | 2 +- .../catalog/PolarisCatalogHandlerWrapper.java | 11 +- .../catalog/io/DefaultFileIOFactory.java | 2 +- .../service/catalog/io/FileIOUtil.java | 9 +- .../io/WasbTranslatingFileIOFactory.java | 2 +- .../config/DefaultConfigurationStore.java | 2 +- .../context/DefaultCallContextResolver.java | 2 +- .../apache/polaris/service/TestServices.java | 2 +- .../catalog/io/MeasuredFileIOFactory.java | 2 +- 40 files changed, 486 insertions(+), 376 deletions(-) delete mode 100644 polaris-core/src/main/java/org/apache/polaris/core/PolarisConfiguration.java create mode 100644 polaris-core/src/main/java/org/apache/polaris/core/config/BehaviorChangeConfiguration.java create mode 100644 polaris-core/src/main/java/org/apache/polaris/core/config/FeatureConfiguration.java create mode 100644 polaris-core/src/main/java/org/apache/polaris/core/config/PolarisConfiguration.java rename polaris-core/src/main/java/org/apache/polaris/core/{ => config}/PolarisConfigurationStore.java (98%) diff --git a/extension/persistence/eclipselink/src/test/java/org/apache/polaris/extension/persistence/impl/eclipselink/PolarisEclipseLinkMetaStoreManagerTest.java b/extension/persistence/eclipselink/src/test/java/org/apache/polaris/extension/persistence/impl/eclipselink/PolarisEclipseLinkMetaStoreManagerTest.java index 9415696da..bcb7f6d7a 100644 --- a/extension/persistence/eclipselink/src/test/java/org/apache/polaris/extension/persistence/impl/eclipselink/PolarisEclipseLinkMetaStoreManagerTest.java +++ b/extension/persistence/eclipselink/src/test/java/org/apache/polaris/extension/persistence/impl/eclipselink/PolarisEclipseLinkMetaStoreManagerTest.java @@ -36,7 +36,7 @@ import java.util.Objects; import java.util.stream.Stream; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDefaultDiagServiceImpl; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.entity.PolarisPrincipalSecrets; diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisApplicationIntegrationTest.java b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisApplicationIntegrationTest.java index 48dbce059..f002db844 100644 --- a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisApplicationIntegrationTest.java +++ b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisApplicationIntegrationTest.java @@ -70,6 +70,7 @@ import org.apache.polaris.core.admin.model.PolarisCatalog; import org.apache.polaris.core.admin.model.PrincipalRole; import org.apache.polaris.core.admin.model.StorageConfigInfo; +import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.entity.CatalogEntity; import org.apache.polaris.core.entity.PolarisEntityConstants; import org.apache.polaris.service.it.env.ClientCredentials; @@ -94,10 +95,10 @@ /** * @implSpec This test expects the server to be configured with the following features configured: * * The server must also be configured to reject request body sizes larger than 1MB (1000000 diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisManagementServiceIntegrationTest.java b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisManagementServiceIntegrationTest.java index e830a18ab..4f54c6e82 100644 --- a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisManagementServiceIntegrationTest.java +++ b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisManagementServiceIntegrationTest.java @@ -71,6 +71,7 @@ import org.apache.polaris.core.admin.model.UpdateCatalogRoleRequest; import org.apache.polaris.core.admin.model.UpdatePrincipalRequest; import org.apache.polaris.core.admin.model.UpdatePrincipalRoleRequest; +import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.entity.PolarisEntityConstants; import org.apache.polaris.service.it.env.CatalogApi; import org.apache.polaris.service.it.env.ClientCredentials; @@ -90,10 +91,10 @@ * @implSpec @implSpec This test expects the server to be configured with the following features * configured: * */ diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationTest.java b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationTest.java index 2a31f2f11..365c83515 100644 --- a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationTest.java +++ b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationTest.java @@ -58,7 +58,8 @@ import org.apache.iceberg.rest.RESTCatalog; import org.apache.iceberg.rest.responses.ErrorResponse; import org.apache.iceberg.types.Types; -import org.apache.polaris.core.PolarisConfiguration; +import org.apache.polaris.core.config.FeatureConfiguration; +import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.admin.model.AwsStorageConfigInfo; import org.apache.polaris.core.admin.model.Catalog; import org.apache.polaris.core.admin.model.CatalogGrant; @@ -449,7 +450,7 @@ public void testCreateTableWithOverriddenBaseLocation() { Catalog catalog = managementApi.getCatalog(currentCatalogName); Map catalogProps = new HashMap<>(catalog.getProperties().toMap()); catalogProps.put( - PolarisConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "false"); + FeatureConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "false"); managementApi.updateCatalog(catalog, catalogProps); restCatalog.createNamespace(Namespace.of("ns1")); @@ -477,7 +478,7 @@ public void testCreateTableWithOverriddenBaseLocationCannotOverlapSibling() { Catalog catalog = managementApi.getCatalog(currentCatalogName); Map catalogProps = new HashMap<>(catalog.getProperties().toMap()); catalogProps.put( - PolarisConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "false"); + FeatureConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "false"); managementApi.updateCatalog(catalog, catalogProps); restCatalog.createNamespace(Namespace.of("ns1")); @@ -514,7 +515,7 @@ public void testCreateTableWithOverriddenBaseLocationMustResideInNsDirectory() { Catalog catalog = managementApi.getCatalog(currentCatalogName); Map catalogProps = new HashMap<>(catalog.getProperties().toMap()); catalogProps.put( - PolarisConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "false"); + FeatureConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "false"); managementApi.updateCatalog(catalog, catalogProps); restCatalog.createNamespace(Namespace.of("ns1")); @@ -563,7 +564,7 @@ public void testLoadTableWithAccessDelegationForExternalCatalogWithConfigDisable .isInstanceOf(ForbiddenException.class) .hasMessageContaining("Access Delegation is not enabled for this catalog") .hasMessageContaining( - PolarisConfiguration.ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING.catalogConfig()); + FeatureConfiguration.ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING.catalogConfig()); } finally { resolvingFileIO.deleteFile(fileLocation); } diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogViewIntegrationBase.java b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogViewIntegrationBase.java index 1fb24f5fe..8fa8be6e6 100644 --- a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogViewIntegrationBase.java +++ b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogViewIntegrationBase.java @@ -24,7 +24,8 @@ import java.util.Map; import org.apache.iceberg.rest.RESTCatalog; import org.apache.iceberg.view.ViewCatalogTests; -import org.apache.polaris.core.PolarisConfiguration; +import org.apache.polaris.core.config.FeatureConfiguration; +import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.admin.model.Catalog; import org.apache.polaris.core.admin.model.CatalogProperties; import org.apache.polaris.core.admin.model.PolarisCatalog; @@ -50,7 +51,7 @@ * client. * * @implSpec This test expects the server to be configured with {@link - * org.apache.polaris.core.PolarisConfiguration#SUPPORTED_CATALOG_STORAGE_TYPES} set to the + * org.apache.polaris.core.config.FeatureConfiguration#SUPPORTED_CATALOG_STORAGE_TYPES} set to the * appropriate storage type. */ @ExtendWith(PolarisIntegrationTestExtension.class) @@ -99,9 +100,9 @@ public void before(TestInfo testInfo) { CatalogProperties.builder(defaultBaseLocation) .addProperty( CatalogEntity.REPLACE_NEW_LOCATION_PREFIX_WITH_CATALOG_DEFAULT_KEY, "file:") - .addProperty(PolarisConfiguration.ALLOW_EXTERNAL_TABLE_LOCATION.catalogConfig(), "true") + .addProperty(FeatureConfiguration.ALLOW_EXTERNAL_TABLE_LOCATION.catalogConfig(), "true") .addProperty( - PolarisConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") + FeatureConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") .build(); Catalog catalog = PolarisCatalog.builder() diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisSparkIntegrationTest.java b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisSparkIntegrationTest.java index 3625c69e8..96687140d 100644 --- a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisSparkIntegrationTest.java +++ b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisSparkIntegrationTest.java @@ -40,6 +40,7 @@ import org.apache.polaris.core.admin.model.ExternalCatalog; import org.apache.polaris.core.admin.model.PolarisCatalog; import org.apache.polaris.core.admin.model.StorageConfigInfo; +import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.service.it.env.CatalogApi; import org.apache.polaris.service.it.env.ClientCredentials; import org.apache.polaris.service.it.env.IntegrationTestsHelper; @@ -64,9 +65,9 @@ * @implSpec This test expects the server to be configured with the following features enabled: *
    *
  • {@link - * org.apache.polaris.core.PolarisConfiguration#SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION}: + * PolarisConfiguration#SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION}: * {@code true} - *
  • {@link org.apache.polaris.core.PolarisConfiguration#ALLOW_OVERLAPPING_CATALOG_URLS}: + *
  • {@link PolarisConfiguration#ALLOW_OVERLAPPING_CATALOG_URLS}: * {@code true} *
*/ diff --git a/polaris-core/src/main/java/org/apache/polaris/core/PolarisCallContext.java b/polaris-core/src/main/java/org/apache/polaris/core/PolarisCallContext.java index c584dde55..ac11fa704 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/PolarisCallContext.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/PolarisCallContext.java @@ -21,6 +21,8 @@ import jakarta.annotation.Nonnull; import java.time.Clock; import java.time.ZoneId; + +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.persistence.transactional.TransactionalPersistence; /** diff --git a/polaris-core/src/main/java/org/apache/polaris/core/PolarisConfiguration.java b/polaris-core/src/main/java/org/apache/polaris/core/PolarisConfiguration.java deleted file mode 100644 index ca1962e3c..000000000 --- a/polaris-core/src/main/java/org/apache/polaris/core/PolarisConfiguration.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * 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.polaris.core; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import org.apache.polaris.core.admin.model.StorageConfigInfo; -import org.apache.polaris.core.context.CallContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class PolarisConfiguration { - - private static final Logger LOGGER = LoggerFactory.getLogger(PolarisConfiguration.class); - - public final String key; - public final String description; - public final T defaultValue; - private final Optional catalogConfigImpl; - private final Class typ; - - @SuppressWarnings("unchecked") - public PolarisConfiguration( - String key, String description, T defaultValue, Optional catalogConfig) { - this.key = key; - this.description = description; - this.defaultValue = defaultValue; - this.catalogConfigImpl = catalogConfig; - this.typ = (Class) defaultValue.getClass(); - } - - public boolean hasCatalogConfig() { - return catalogConfigImpl.isPresent(); - } - - public String catalogConfig() { - return catalogConfigImpl.orElseThrow( - () -> - new IllegalStateException( - "Attempted to read a catalog config key from a configuration that doesn't have one.")); - } - - T cast(Object value) { - return this.typ.cast(value); - } - - public static class Builder { - private String key; - private String description; - private T defaultValue; - private Optional catalogConfig = Optional.empty(); - - public Builder key(String key) { - this.key = key; - return this; - } - - public Builder description(String description) { - this.description = description; - return this; - } - - @SuppressWarnings("unchecked") - public Builder defaultValue(T defaultValue) { - if (defaultValue instanceof List) { - // Type-safe handling of List - this.defaultValue = (T) new ArrayList<>((List) defaultValue); - } else { - this.defaultValue = defaultValue; - } - return this; - } - - public Builder catalogConfig(String catalogConfig) { - this.catalogConfig = Optional.of(catalogConfig); - return this; - } - - public PolarisConfiguration build() { - if (key == null || description == null || defaultValue == null) { - throw new IllegalArgumentException("key, description, and defaultValue are required"); - } - return new PolarisConfiguration<>(key, description, defaultValue, catalogConfig); - } - } - - /** - * Returns the value of a `PolarisConfiguration`, or the default if it cannot be loaded. This - * method does not need to be used when a `CallContext` is already available - */ - public static T loadConfig(PolarisConfiguration configuration) { - var callContext = CallContext.getCurrentContext(); - if (callContext == null) { - LOGGER.warn( - String.format( - "Unable to load current call context; using %s = %s", - configuration.key, configuration.defaultValue)); - return configuration.defaultValue; - } - return callContext - .getPolarisCallContext() - .getConfigurationStore() - .getConfiguration(callContext.getPolarisCallContext(), configuration); - } - - public static Builder builder() { - return new Builder<>(); - } - - public static final PolarisConfiguration - ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING = - PolarisConfiguration.builder() - .key("ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING") - .description( - "If set to true, require that principals must rotate their credentials before being used " - + "for anything else.") - .defaultValue(false) - .build(); - - public static final PolarisConfiguration SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION = - PolarisConfiguration.builder() - .key("SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION") - .description( - "If set to true, skip credential-subscoping indirection entirely whenever trying\n" - + " to obtain storage credentials for instantiating a FileIO. If 'true', no attempt is made\n" - + " to use StorageConfigs to generate table-specific storage credentials, but instead the default\n" - + " fallthrough of table-level credential properties or else provider-specific APPLICATION_DEFAULT\n" - + " credential-loading will be used for the FileIO.\n" - + " Typically this setting is used in single-tenant server deployments that don't rely on\n" - + " \"credential-vending\" and can use server-default environment variables or credential config\n" - + " files for all storage access, or in test/dev scenarios.") - .defaultValue(false) - .build(); - - public static final PolarisConfiguration ALLOW_TABLE_LOCATION_OVERLAP = - PolarisConfiguration.builder() - .key("ALLOW_TABLE_LOCATION_OVERLAP") - .catalogConfig("allow.overlapping.table.location") - .description( - "If set to true, allow one table's location to reside within another table's location. " - + "This is only enforced within a given namespace.") - .defaultValue(false) - .build(); - - public static final PolarisConfiguration ALLOW_NAMESPACE_LOCATION_OVERLAP = - PolarisConfiguration.builder() - .key("ALLOW_NAMESPACE_LOCATION_OVERLAP") - .description( - "If set to true, allow one namespace's location to reside within another namespace's location. " - + "This is only enforced within a parent catalog or namespace.") - .defaultValue(false) - .build(); - - public static final PolarisConfiguration ALLOW_EXTERNAL_METADATA_FILE_LOCATION = - PolarisConfiguration.builder() - .key("ALLOW_EXTERNAL_METADATA_FILE_LOCATION") - .description( - "If set to true, allows metadata files to be located outside the default metadata directory.") - .defaultValue(false) - .build(); - - public static final PolarisConfiguration ALLOW_OVERLAPPING_CATALOG_URLS = - PolarisConfiguration.builder() - .key("ALLOW_OVERLAPPING_CATALOG_URLS") - .description("If set to true, allows catalog URLs to overlap.") - .defaultValue(false) - .build(); - - public static final PolarisConfiguration ALLOW_UNSTRUCTURED_TABLE_LOCATION = - PolarisConfiguration.builder() - .key("ALLOW_UNSTRUCTURED_TABLE_LOCATION") - .catalogConfig("allow.unstructured.table.location") - .description("If set to true, allows unstructured table locations.") - .defaultValue(false) - .build(); - - public static final PolarisConfiguration ALLOW_EXTERNAL_TABLE_LOCATION = - PolarisConfiguration.builder() - .key("ALLOW_EXTERNAL_TABLE_LOCATION") - .catalogConfig("allow.external.table.location") - .description( - "If set to true, allows tables to have external locations outside the default structure.") - .defaultValue(false) - .build(); - - public static final PolarisConfiguration ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING = - PolarisConfiguration.builder() - .key("ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING") - .catalogConfig("enable.credential.vending") - .description("If set to true, allow credential vending for external catalogs.") - .defaultValue(true) - .build(); - - public static final PolarisConfiguration> SUPPORTED_CATALOG_STORAGE_TYPES = - PolarisConfiguration.>builder() - .key("SUPPORTED_CATALOG_STORAGE_TYPES") - .catalogConfig("supported.storage.types") - .description("The list of supported storage types for a catalog") - .defaultValue( - List.of( - StorageConfigInfo.StorageTypeEnum.S3.name(), - StorageConfigInfo.StorageTypeEnum.AZURE.name(), - StorageConfigInfo.StorageTypeEnum.GCS.name(), - StorageConfigInfo.StorageTypeEnum.FILE.name())) - .build(); - - public static final PolarisConfiguration CLEANUP_ON_NAMESPACE_DROP = - PolarisConfiguration.builder() - .key("CLEANUP_ON_NAMESPACE_DROP") - .catalogConfig("cleanup.on.namespace.drop") - .description("If set to true, clean up data when a namespace is dropped") - .defaultValue(false) - .build(); - - public static final PolarisConfiguration CLEANUP_ON_CATALOG_DROP = - PolarisConfiguration.builder() - .key("CLEANUP_ON_CATALOG_DROP") - .catalogConfig("cleanup.on.catalog.drop") - .description("If set to true, clean up data when a catalog is dropped") - .defaultValue(false) - .build(); - - public static final PolarisConfiguration DROP_WITH_PURGE_ENABLED = - PolarisConfiguration.builder() - .key("DROP_WITH_PURGE_ENABLED") - .catalogConfig("drop-with-purge.enabled") - .description( - "If set to true, allows tables to be dropped with the purge parameter set to true.") - .defaultValue(true) - .build(); - - public static final PolarisConfiguration STORAGE_CREDENTIAL_DURATION_SECONDS = - PolarisConfiguration.builder() - .key("STORAGE_CREDENTIAL_DURATION_SECONDS") - .description( - "The duration of time that vended storage credentials are valid for. Support for" - + " longer (or shorter) durations is dependent on the storage provider. GCS" - + " current does not respect this value.") - .defaultValue(60 * 60) // 1 hour - .build(); - - public static final PolarisConfiguration STORAGE_CREDENTIAL_CACHE_DURATION_SECONDS = - PolarisConfiguration.builder() - .key("STORAGE_CREDENTIAL_CACHE_DURATION_SECONDS") - .description( - "How long to store storage credentials in the local cache. This should be less than " - + STORAGE_CREDENTIAL_DURATION_SECONDS.key) - .defaultValue(30 * 60) // 30 minutes - .build(); - - public static final PolarisConfiguration MAX_METADATA_REFRESH_RETRIES = - PolarisConfiguration.builder() - .key("MAX_METADATA_REFRESH_RETRIES") - .description( - "How many times to retry refreshing metadata when the previous error was retryable") - .defaultValue(2) - .build(); -} diff --git a/polaris-core/src/main/java/org/apache/polaris/core/auth/PolarisAuthorizerImpl.java b/polaris-core/src/main/java/org/apache/polaris/core/auth/PolarisAuthorizerImpl.java index 96f449acb..320d04648 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/auth/PolarisAuthorizerImpl.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/auth/PolarisAuthorizerImpl.java @@ -98,8 +98,9 @@ import java.util.Set; import java.util.stream.Collectors; import org.apache.iceberg.exceptions.ForbiddenException; -import org.apache.polaris.core.PolarisConfiguration; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.FeatureConfiguration; +import org.apache.polaris.core.config.PolarisConfiguration; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.PolarisBaseEntity; import org.apache.polaris.core.entity.PolarisEntityConstants; @@ -510,7 +511,7 @@ public void authorizeOrThrow( boolean enforceCredentialRotationRequiredState = featureConfig.getConfiguration( CallContext.getCurrentContext().getPolarisCallContext(), - PolarisConfiguration.ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING); + FeatureConfiguration.ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING); if (enforceCredentialRotationRequiredState && authenticatedPrincipal .getPrincipalEntity() diff --git a/polaris-core/src/main/java/org/apache/polaris/core/config/BehaviorChangeConfiguration.java b/polaris-core/src/main/java/org/apache/polaris/core/config/BehaviorChangeConfiguration.java new file mode 100644 index 000000000..0666f0d5f --- /dev/null +++ b/polaris-core/src/main/java/org/apache/polaris/core/config/BehaviorChangeConfiguration.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.polaris.core.config; + +import java.util.Optional; + +/** + * Configurations for non-feature beheavior changes within Polaris. These configurations are not intended + * for use by end users and govern nuanced behavior changes and bugfixes. The configurations never expose + * user-facing catalog-level configurations. These configurations are not stable and may be removed at + * any time. + * @param The type of the configuration + */ +public class BehaviorChangeConfiguration extends PolarisConfiguration { + + public BehaviorChangeConfiguration( + String key, String description, T defaultValue, Optional catalogConfig) { + super(key, description, defaultValue, catalogConfig); + } +} diff --git a/polaris-core/src/main/java/org/apache/polaris/core/config/FeatureConfiguration.java b/polaris-core/src/main/java/org/apache/polaris/core/config/FeatureConfiguration.java new file mode 100644 index 000000000..9f3710c58 --- /dev/null +++ b/polaris-core/src/main/java/org/apache/polaris/core/config/FeatureConfiguration.java @@ -0,0 +1,185 @@ +/* + * 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.polaris.core.config; + +import org.apache.polaris.core.admin.model.StorageConfigInfo; + +import java.util.List; +import java.util.Optional; + +/** + * Configurations for features within Polaris. These configurations are intended to be customized + * and many expose user-facing catalog-level configurations. These configurations are stable over time. + * @param + */ +public class FeatureConfiguration extends PolarisConfiguration { + public FeatureConfiguration(String key, String description, T defaultValue, Optional catalogConfig) { + super(key, description, defaultValue, catalogConfig); + } + + public static final FeatureConfiguration + ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING = + PolarisConfiguration.builder() + .key("ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING") + .description( + "If set to true, require that principals must rotate their credentials before being used " + + "for anything else.") + .defaultValue(false) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION = + PolarisConfiguration.builder() + .key("SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION") + .description( + "If set to true, skip credential-subscoping indirection entirely whenever trying\n" + + " to obtain storage credentials for instantiating a FileIO. If 'true', no attempt is made\n" + + " to use StorageConfigs to generate table-specific storage credentials, but instead the default\n" + + " fallthrough of table-level credential properties or else provider-specific APPLICATION_DEFAULT\n" + + " credential-loading will be used for the FileIO.\n" + + " Typically this setting is used in single-tenant server deployments that don't rely on\n" + + " \"credential-vending\" and can use server-default environment variables or credential config\n" + + " files for all storage access, or in test/dev scenarios.") + .defaultValue(false) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration ALLOW_TABLE_LOCATION_OVERLAP = + PolarisConfiguration.builder() + .key("ALLOW_TABLE_LOCATION_OVERLAP") + .catalogConfig("allow.overlapping.table.location") + .description( + "If set to true, allow one table's location to reside within another table's location. " + + "This is only enforced within a given namespace.") + .defaultValue(false) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration ALLOW_NAMESPACE_LOCATION_OVERLAP = + PolarisConfiguration.builder() + .key("ALLOW_NAMESPACE_LOCATION_OVERLAP") + .description( + "If set to true, allow one namespace's location to reside within another namespace's location. " + + "This is only enforced within a parent catalog or namespace.") + .defaultValue(false) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration ALLOW_EXTERNAL_METADATA_FILE_LOCATION = + PolarisConfiguration.builder() + .key("ALLOW_EXTERNAL_METADATA_FILE_LOCATION") + .description( + "If set to true, allows metadata files to be located outside the default metadata directory.") + .defaultValue(false) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration ALLOW_OVERLAPPING_CATALOG_URLS = + PolarisConfiguration.builder() + .key("ALLOW_OVERLAPPING_CATALOG_URLS") + .description("If set to true, allows catalog URLs to overlap.") + .defaultValue(false) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration ALLOW_UNSTRUCTURED_TABLE_LOCATION = + PolarisConfiguration.builder() + .key("ALLOW_UNSTRUCTURED_TABLE_LOCATION") + .catalogConfig("allow.unstructured.table.location") + .description("If set to true, allows unstructured table locations.") + .defaultValue(false) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration ALLOW_EXTERNAL_TABLE_LOCATION = + PolarisConfiguration.builder() + .key("ALLOW_EXTERNAL_TABLE_LOCATION") + .catalogConfig("allow.external.table.location") + .description( + "If set to true, allows tables to have external locations outside the default structure.") + .defaultValue(false) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING = + PolarisConfiguration.builder() + .key("ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING") + .catalogConfig("enable.credential.vending") + .description("If set to true, allow credential vending for external catalogs.") + .defaultValue(true) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration> SUPPORTED_CATALOG_STORAGE_TYPES = + PolarisConfiguration.>builder() + .key("SUPPORTED_CATALOG_STORAGE_TYPES") + .catalogConfig("supported.storage.types") + .description("The list of supported storage types for a catalog") + .defaultValue( + List.of( + StorageConfigInfo.StorageTypeEnum.S3.name(), + StorageConfigInfo.StorageTypeEnum.AZURE.name(), + StorageConfigInfo.StorageTypeEnum.GCS.name(), + StorageConfigInfo.StorageTypeEnum.FILE.name())) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration CLEANUP_ON_NAMESPACE_DROP = + PolarisConfiguration.builder() + .key("CLEANUP_ON_NAMESPACE_DROP") + .catalogConfig("cleanup.on.namespace.drop") + .description("If set to true, clean up data when a namespace is dropped") + .defaultValue(false) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration CLEANUP_ON_CATALOG_DROP = + PolarisConfiguration.builder() + .key("CLEANUP_ON_CATALOG_DROP") + .catalogConfig("cleanup.on.catalog.drop") + .description("If set to true, clean up data when a catalog is dropped") + .defaultValue(false) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration DROP_WITH_PURGE_ENABLED = + PolarisConfiguration.builder() + .key("DROP_WITH_PURGE_ENABLED") + .catalogConfig("drop-with-purge.enabled") + .description( + "If set to true, allows tables to be dropped with the purge parameter set to true.") + .defaultValue(true) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration STORAGE_CREDENTIAL_DURATION_SECONDS = + PolarisConfiguration.builder() + .key("STORAGE_CREDENTIAL_DURATION_SECONDS") + .description( + "The duration of time that vended storage credentials are valid for. Support for" + + " longer (or shorter) durations is dependent on the storage provider. GCS" + + " current does not respect this value.") + .defaultValue(60 * 60) // 1 hour + .buildFeatureConfiguration(); + + public static final FeatureConfiguration STORAGE_CREDENTIAL_CACHE_DURATION_SECONDS = + PolarisConfiguration.builder() + .key("STORAGE_CREDENTIAL_CACHE_DURATION_SECONDS") + .description( + "How long to store storage credentials in the local cache. This should be less than " + + STORAGE_CREDENTIAL_DURATION_SECONDS.key) + .defaultValue(30 * 60) // 30 minutes + .buildFeatureConfiguration(); + + public static final FeatureConfiguration MAX_METADATA_REFRESH_RETRIES = + PolarisConfiguration.builder() + .key("MAX_METADATA_REFRESH_RETRIES") + .description( + "How many times to retry refreshing metadata when the previous error was retryable") + .defaultValue(2) + .buildFeatureConfiguration(); +} diff --git a/polaris-core/src/main/java/org/apache/polaris/core/config/PolarisConfiguration.java b/polaris-core/src/main/java/org/apache/polaris/core/config/PolarisConfiguration.java new file mode 100644 index 000000000..e40d2eb60 --- /dev/null +++ b/polaris-core/src/main/java/org/apache/polaris/core/config/PolarisConfiguration.java @@ -0,0 +1,140 @@ +/* + * 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.polaris.core.config; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.apache.polaris.core.context.CallContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * An ABC for Polaris configurations that alter the service's behavior + * @param The type of the configuration + */ +public abstract class PolarisConfiguration { + + private static final Logger LOGGER = LoggerFactory.getLogger(PolarisConfiguration.class); + + public final String key; + public final String description; + public final T defaultValue; + private final Optional catalogConfigImpl; + private final Class typ; + + @SuppressWarnings("unchecked") + protected PolarisConfiguration( + String key, String description, T defaultValue, Optional catalogConfig) { + this.key = key; + this.description = description; + this.defaultValue = defaultValue; + this.catalogConfigImpl = catalogConfig; + this.typ = (Class) defaultValue.getClass(); + } + + public boolean hasCatalogConfig() { + return catalogConfigImpl.isPresent(); + } + + public String catalogConfig() { + return catalogConfigImpl.orElseThrow( + () -> + new IllegalStateException( + "Attempted to read a catalog config key from a configuration that doesn't have one.")); + } + + T cast(Object value) { + return this.typ.cast(value); + } + + public static class Builder { + private String key; + private String description; + private T defaultValue; + private Optional catalogConfig = Optional.empty(); + + public Builder key(String key) { + this.key = key; + return this; + } + + public Builder description(String description) { + this.description = description; + return this; + } + + @SuppressWarnings("unchecked") + public Builder defaultValue(T defaultValue) { + if (defaultValue instanceof List) { + // Type-safe handling of List + this.defaultValue = (T) new ArrayList<>((List) defaultValue); + } else { + this.defaultValue = defaultValue; + } + return this; + } + + public Builder catalogConfig(String catalogConfig) { + this.catalogConfig = Optional.of(catalogConfig); + return this; + } + + public FeatureConfiguration buildFeatureConfiguration() { + if (key == null || description == null || defaultValue == null) { + throw new IllegalArgumentException("key, description, and defaultValue are required"); + } + return new FeatureConfiguration<>(key, description, defaultValue, catalogConfig); + } + + public BehaviorChangeConfiguration buildBehaviorChangeConfiguration() { + if (key == null || description == null || defaultValue == null) { + throw new IllegalArgumentException("key, description, and defaultValue are required"); + } + if (catalogConfig.isPresent()) { + throw new IllegalArgumentException("catalogConfig is not valid for behavior change configs"); + } + return new BehaviorChangeConfiguration<>(key, description, defaultValue, catalogConfig); + } + } + + /** + * Returns the value of a `PolarisConfiguration`, or the default if it cannot be loaded. This + * method does not need to be used when a `CallContext` is already available + */ + public static T loadConfig(PolarisConfiguration configuration) { + var callContext = CallContext.getCurrentContext(); + if (callContext == null) { + LOGGER.warn( + String.format( + "Unable to load current call context; using %s = %s", + configuration.key, configuration.defaultValue)); + return configuration.defaultValue; + } + return callContext + .getPolarisCallContext() + .getConfigurationStore() + .getConfiguration(callContext.getPolarisCallContext(), configuration); + } + + public static Builder builder() { + return new Builder<>(); + } +} diff --git a/polaris-core/src/main/java/org/apache/polaris/core/PolarisConfigurationStore.java b/polaris-core/src/main/java/org/apache/polaris/core/config/PolarisConfigurationStore.java similarity index 98% rename from polaris-core/src/main/java/org/apache/polaris/core/PolarisConfigurationStore.java rename to polaris-core/src/main/java/org/apache/polaris/core/config/PolarisConfigurationStore.java index a3c902206..c787f11d9 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/PolarisConfigurationStore.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/config/PolarisConfigurationStore.java @@ -16,13 +16,15 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.polaris.core; +package org.apache.polaris.core.config; import com.google.common.base.Preconditions; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; import java.util.ArrayList; import java.util.List; + +import org.apache.polaris.core.PolarisCallContext; import org.apache.polaris.core.entity.CatalogEntity; /** diff --git a/polaris-core/src/main/java/org/apache/polaris/core/storage/PolarisStorageConfigurationInfo.java b/polaris-core/src/main/java/org/apache/polaris/core/storage/PolarisStorageConfigurationInfo.java index 6b0638e83..edf57b488 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/storage/PolarisStorageConfigurationInfo.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/storage/PolarisStorageConfigurationInfo.java @@ -36,7 +36,9 @@ import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.apache.polaris.core.PolarisConfiguration; + +import org.apache.polaris.core.config.FeatureConfiguration; +import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.admin.model.Catalog; import org.apache.polaris.core.context.CallContext; @@ -168,7 +170,7 @@ public static Optional forEntityPath( .getConfiguration( CallContext.getCurrentContext().getPolarisCallContext(), catalog, - PolarisConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION); + FeatureConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION); if (!allowEscape && catalog.getCatalogType() != Catalog.TypeEnum.EXTERNAL && baseLocation != null) { diff --git a/polaris-core/src/main/java/org/apache/polaris/core/storage/aws/AwsCredentialsStorageIntegration.java b/polaris-core/src/main/java/org/apache/polaris/core/storage/aws/AwsCredentialsStorageIntegration.java index f522b77b5..43bf7de0c 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/storage/aws/AwsCredentialsStorageIntegration.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/storage/aws/AwsCredentialsStorageIntegration.java @@ -18,8 +18,8 @@ */ package org.apache.polaris.core.storage.aws; -import static org.apache.polaris.core.PolarisConfiguration.STORAGE_CREDENTIAL_DURATION_SECONDS; -import static org.apache.polaris.core.PolarisConfiguration.loadConfig; +import static org.apache.polaris.core.config.FeatureConfiguration.STORAGE_CREDENTIAL_DURATION_SECONDS; +import static org.apache.polaris.core.config.PolarisConfiguration.loadConfig; import jakarta.annotation.Nonnull; import java.net.URI; diff --git a/polaris-core/src/main/java/org/apache/polaris/core/storage/azure/AzureCredentialsStorageIntegration.java b/polaris-core/src/main/java/org/apache/polaris/core/storage/azure/AzureCredentialsStorageIntegration.java index 4013cbd81..319a10edf 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/storage/azure/AzureCredentialsStorageIntegration.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/storage/azure/AzureCredentialsStorageIntegration.java @@ -45,7 +45,9 @@ import java.util.HashSet; import java.util.Objects; import java.util.Set; -import org.apache.polaris.core.PolarisConfiguration; + +import org.apache.polaris.core.config.FeatureConfiguration; +import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.storage.InMemoryStorageIntegration; import org.apache.polaris.core.storage.PolarisCredentialProperty; @@ -126,7 +128,7 @@ public EnumMap getSubscopedCreds( // clock skew between the client and server, OffsetDateTime startTime = start.truncatedTo(ChronoUnit.SECONDS).atOffset(ZoneOffset.UTC); int intendedDurationSeconds = - PolarisConfiguration.loadConfig(PolarisConfiguration.STORAGE_CREDENTIAL_DURATION_SECONDS); + FeatureConfiguration.loadConfig(FeatureConfiguration.STORAGE_CREDENTIAL_DURATION_SECONDS); OffsetDateTime intendedEndTime = start.plusSeconds(intendedDurationSeconds).atOffset(ZoneOffset.UTC); OffsetDateTime maxAllowedEndTime = diff --git a/polaris-core/src/main/java/org/apache/polaris/core/storage/cache/StorageCredentialCache.java b/polaris-core/src/main/java/org/apache/polaris/core/storage/cache/StorageCredentialCache.java index 44a1b0fd4..e4dc728d4 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/storage/cache/StorageCredentialCache.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/storage/cache/StorageCredentialCache.java @@ -29,7 +29,8 @@ import java.util.function.Function; import org.apache.iceberg.exceptions.UnprocessableEntityException; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.PolarisConfiguration; +import org.apache.polaris.core.config.FeatureConfiguration; +import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.entity.PolarisEntity; import org.apache.polaris.core.entity.PolarisEntityType; import org.apache.polaris.core.storage.PolarisCredentialVendor; @@ -95,15 +96,15 @@ public long expireAfterRead( private static long maxCacheDurationMs() { var cacheDurationSeconds = PolarisConfiguration.loadConfig( - PolarisConfiguration.STORAGE_CREDENTIAL_CACHE_DURATION_SECONDS); + FeatureConfiguration.STORAGE_CREDENTIAL_CACHE_DURATION_SECONDS); var credentialDurationSeconds = - PolarisConfiguration.loadConfig(PolarisConfiguration.STORAGE_CREDENTIAL_DURATION_SECONDS); + PolarisConfiguration.loadConfig(FeatureConfiguration.STORAGE_CREDENTIAL_DURATION_SECONDS); if (cacheDurationSeconds >= credentialDurationSeconds) { throw new IllegalArgumentException( String.format( "%s should be less than %s", - PolarisConfiguration.STORAGE_CREDENTIAL_CACHE_DURATION_SECONDS.key, - PolarisConfiguration.STORAGE_CREDENTIAL_DURATION_SECONDS.key)); + FeatureConfiguration.STORAGE_CREDENTIAL_CACHE_DURATION_SECONDS.key, + FeatureConfiguration.STORAGE_CREDENTIAL_DURATION_SECONDS.key)); } else { return cacheDurationSeconds * 1000L; } diff --git a/polaris-core/src/test/java/org/apache/polaris/core/persistence/PolarisTreeMapMetaStoreManagerTest.java b/polaris-core/src/test/java/org/apache/polaris/core/persistence/PolarisTreeMapMetaStoreManagerTest.java index 65f8080d9..7bf972450 100644 --- a/polaris-core/src/test/java/org/apache/polaris/core/persistence/PolarisTreeMapMetaStoreManagerTest.java +++ b/polaris-core/src/test/java/org/apache/polaris/core/persistence/PolarisTreeMapMetaStoreManagerTest.java @@ -22,7 +22,7 @@ import java.time.ZoneId; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDefaultDiagServiceImpl; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.persistence.transactional.PolarisMetaStoreManagerImpl; diff --git a/polaris-core/src/test/java/org/apache/polaris/core/storage/InMemoryStorageIntegrationTest.java b/polaris-core/src/test/java/org/apache/polaris/core/storage/InMemoryStorageIntegrationTest.java index aa5317e99..a78debe15 100644 --- a/polaris-core/src/test/java/org/apache/polaris/core/storage/InMemoryStorageIntegrationTest.java +++ b/polaris-core/src/test/java/org/apache/polaris/core/storage/InMemoryStorageIntegrationTest.java @@ -26,7 +26,7 @@ import java.util.Map; import java.util.Set; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDefaultDiagServiceImpl; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.context.CallContext; diff --git a/polaris-core/src/test/java/org/apache/polaris/service/storage/PolarisConfigurationStoreTest.java b/polaris-core/src/test/java/org/apache/polaris/service/storage/PolarisConfigurationStoreTest.java index a0da2c5d8..d27730abb 100644 --- a/polaris-core/src/test/java/org/apache/polaris/service/storage/PolarisConfigurationStoreTest.java +++ b/polaris-core/src/test/java/org/apache/polaris/service/storage/PolarisConfigurationStoreTest.java @@ -21,8 +21,8 @@ import jakarta.annotation.Nullable; import java.util.List; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.PolarisConfiguration; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.PolarisConfiguration; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -91,6 +91,6 @@ private static PolarisConfiguration buildConfig(String key, T defaultValu .key(key) .description("") .defaultValue(defaultValue) - .build(); + .buildFeatureConfiguration(); } } diff --git a/quarkus/admin/src/main/java/org/apache/polaris/admintool/config/QuarkusProducers.java b/quarkus/admin/src/main/java/org/apache/polaris/admintool/config/QuarkusProducers.java index 6788742ba..c1db15098 100644 --- a/quarkus/admin/src/main/java/org/apache/polaris/admintool/config/QuarkusProducers.java +++ b/quarkus/admin/src/main/java/org/apache/polaris/admintool/config/QuarkusProducers.java @@ -25,7 +25,7 @@ import jakarta.enterprise.inject.Instance; import jakarta.enterprise.inject.Produces; import java.time.Clock; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDefaultDiagServiceImpl; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.persistence.MetaStoreManagerFactory; diff --git a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusProducers.java b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusProducers.java index cbe1cc262..fa7ad3bec 100644 --- a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusProducers.java +++ b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusProducers.java @@ -33,7 +33,7 @@ import jakarta.ws.rs.core.Context; import java.time.Clock; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDefaultDiagServiceImpl; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.auth.AuthenticatedPolarisPrincipal; diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java index 65bd9edbf..a5b4b09e8 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java @@ -47,8 +47,9 @@ import org.apache.iceberg.exceptions.ForbiddenException; import org.apache.iceberg.types.Types; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.PolarisConfiguration; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.FeatureConfiguration; +import org.apache.polaris.core.config.PolarisConfiguration; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.admin.model.FileStorageConfigInfo; import org.apache.polaris.core.admin.model.PrincipalWithCredentials; @@ -164,7 +165,7 @@ public Map getConfigOverrides() { new PolarisAuthorizerImpl( new DefaultConfigurationStore( Map.of( - PolarisConfiguration.ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING.key, + FeatureConfiguration.ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING.key, true))); @Inject protected MetaStoreManagerFactory managerFactory; diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisOverlappingTableTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisOverlappingTableTest.java index 878c35e82..f2e929484 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisOverlappingTableTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisOverlappingTableTest.java @@ -18,8 +18,8 @@ */ package org.apache.polaris.service.quarkus.admin; -import static org.apache.polaris.core.PolarisConfiguration.ALLOW_TABLE_LOCATION_OVERLAP; -import static org.apache.polaris.core.PolarisConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION; +import static org.apache.polaris.core.config.FeatureConfiguration.ALLOW_TABLE_LOCATION_OVERLAP; +import static org.apache.polaris.core.config.FeatureConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION; import static org.apache.polaris.service.quarkus.admin.PolarisAuthzTestBase.SCHEMA; import static org.assertj.core.api.Assertions.assertThat; diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogTest.java index 84ac558b6..3ec040c37 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogTest.java @@ -72,8 +72,9 @@ import org.apache.iceberg.io.FileIO; import org.apache.iceberg.types.Types; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.PolarisConfiguration; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.FeatureConfiguration; +import org.apache.polaris.core.config.PolarisConfiguration; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.admin.model.AwsStorageConfigInfo; import org.apache.polaris.core.admin.model.StorageConfigInfo; @@ -257,9 +258,9 @@ public void before(TestInfo testInfo) { .setDefaultBaseLocation(storageLocation) .setReplaceNewLocationPrefixWithCatalogDefault("file:") .addProperty( - PolarisConfiguration.ALLOW_EXTERNAL_TABLE_LOCATION.catalogConfig(), "true") + FeatureConfiguration.ALLOW_EXTERNAL_TABLE_LOCATION.catalogConfig(), "true") .addProperty( - PolarisConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") + FeatureConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") .setStorageConfigurationInfo(storageConfigModel, storageLocation) .build()); @@ -685,9 +686,9 @@ public void testCreateNotificationCreateTableInExternalLocation() { List.of(PolarisEntity.toCore(catalogEntity)), new CatalogEntity.Builder(CatalogEntity.of(catalogEntity)) .addProperty( - PolarisConfiguration.ALLOW_EXTERNAL_TABLE_LOCATION.catalogConfig(), "false") + FeatureConfiguration.ALLOW_EXTERNAL_TABLE_LOCATION.catalogConfig(), "false") .addProperty( - PolarisConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") + FeatureConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") .build()); BasePolarisCatalog catalog = catalog(); TableMetadata tableMetadata = @@ -742,9 +743,9 @@ public void testCreateNotificationCreateTableOutsideOfMetadataLocation() { List.of(PolarisEntity.toCore(catalogEntity)), new CatalogEntity.Builder(CatalogEntity.of(catalogEntity)) .addProperty( - PolarisConfiguration.ALLOW_EXTERNAL_TABLE_LOCATION.catalogConfig(), "false") + FeatureConfiguration.ALLOW_EXTERNAL_TABLE_LOCATION.catalogConfig(), "false") .addProperty( - PolarisConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") + FeatureConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") .build()); BasePolarisCatalog catalog = catalog(); TableMetadata tableMetadata = @@ -796,9 +797,9 @@ public void testUpdateNotificationCreateTableInExternalLocation() { List.of(PolarisEntity.toCore(catalogEntity)), new CatalogEntity.Builder(CatalogEntity.of(catalogEntity)) .addProperty( - PolarisConfiguration.ALLOW_EXTERNAL_TABLE_LOCATION.catalogConfig(), "false") + FeatureConfiguration.ALLOW_EXTERNAL_TABLE_LOCATION.catalogConfig(), "false") .addProperty( - PolarisConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") + FeatureConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") .build()); BasePolarisCatalog catalog = catalog(); InMemoryFileIO fileIO = (InMemoryFileIO) catalog.getIo(); @@ -907,7 +908,7 @@ public void testUpdateNotificationCreateTableWithLocalFilePrefix() { PolarisCallContext polarisCallContext = callContext.getPolarisCallContext(); if (!polarisCallContext .getConfigurationStore() - .getConfiguration(polarisCallContext, PolarisConfiguration.SUPPORTED_CATALOG_STORAGE_TYPES) + .getConfiguration(polarisCallContext, FeatureConfiguration.SUPPORTED_CATALOG_STORAGE_TYPES) .contains("FILE")) { Assertions.assertThatThrownBy(() -> catalog.sendNotification(table, request)) .isInstanceOf(ForbiddenException.class) @@ -973,7 +974,7 @@ public void testUpdateNotificationCreateTableWithHttpPrefix() { PolarisCallContext polarisCallContext = callContext.getPolarisCallContext(); if (!polarisCallContext .getConfigurationStore() - .getConfiguration(polarisCallContext, PolarisConfiguration.SUPPORTED_CATALOG_STORAGE_TYPES) + .getConfiguration(polarisCallContext, FeatureConfiguration.SUPPORTED_CATALOG_STORAGE_TYPES) .contains("FILE")) { Assertions.assertThatThrownBy(() -> catalog.sendNotification(table, request)) .isInstanceOf(ForbiddenException.class) @@ -994,7 +995,7 @@ public void testUpdateNotificationCreateTableWithHttpPrefix() { if (!polarisCallContext .getConfigurationStore() - .getConfiguration(polarisCallContext, PolarisConfiguration.SUPPORTED_CATALOG_STORAGE_TYPES) + .getConfiguration(polarisCallContext, FeatureConfiguration.SUPPORTED_CATALOG_STORAGE_TYPES) .contains("FILE")) { Assertions.assertThatThrownBy(() -> catalog.sendNotification(table, newRequest)) .isInstanceOf(ForbiddenException.class) @@ -1467,10 +1468,10 @@ public void testDropTableWithPurgeDisabled() { .setName(noPurgeCatalogName) .setDefaultBaseLocation(storageLocation) .setReplaceNewLocationPrefixWithCatalogDefault("file:") - .addProperty(PolarisConfiguration.ALLOW_EXTERNAL_TABLE_LOCATION.catalogConfig(), "true") + .addProperty(FeatureConfiguration.ALLOW_EXTERNAL_TABLE_LOCATION.catalogConfig(), "true") .addProperty( - PolarisConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") - .addProperty(PolarisConfiguration.DROP_WITH_PURGE_ENABLED.catalogConfig(), "false") + FeatureConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") + .addProperty(FeatureConfiguration.DROP_WITH_PURGE_ENABLED.catalogConfig(), "false") .setStorageConfigurationInfo(noPurgeStorageConfigModel, storageLocation) .build()); PolarisPassthroughResolutionView passthroughView = @@ -1507,7 +1508,7 @@ public void testDropTableWithPurgeDisabled() { // Attempt to drop the table: Assertions.assertThatThrownBy(() -> noPurgeCatalog.dropTable(TABLE, true)) .isInstanceOf(ForbiddenException.class) - .hasMessageContaining(PolarisConfiguration.DROP_WITH_PURGE_ENABLED.key); + .hasMessageContaining(FeatureConfiguration.DROP_WITH_PURGE_ENABLED.key); } private TableMetadata createSampleTableMetadata(String tableLocation) { diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogViewTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogViewTest.java index b85443faf..241b31907 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogViewTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogViewTest.java @@ -39,8 +39,9 @@ import org.apache.iceberg.catalog.Catalog; import org.apache.iceberg.view.ViewCatalogTests; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.PolarisConfiguration; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.FeatureConfiguration; +import org.apache.polaris.core.config.PolarisConfiguration; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.admin.model.FileStorageConfigInfo; import org.apache.polaris.core.admin.model.StorageConfigInfo; @@ -171,9 +172,9 @@ public void before(TestInfo testInfo) { adminService.createCatalog( new CatalogEntity.Builder() .setName(CATALOG_NAME) - .addProperty(PolarisConfiguration.ALLOW_EXTERNAL_TABLE_LOCATION.catalogConfig(), "true") + .addProperty(FeatureConfiguration.ALLOW_EXTERNAL_TABLE_LOCATION.catalogConfig(), "true") .addProperty( - PolarisConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") + FeatureConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") .setDefaultBaseLocation("file://tmp") .setStorageConfigurationInfo( new FileStorageConfigInfo( diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogHandlerWrapperAuthzTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogHandlerWrapperAuthzTest.java index 29d0bd90c..c0c4495dd 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogHandlerWrapperAuthzTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogHandlerWrapperAuthzTest.java @@ -50,7 +50,7 @@ import org.apache.iceberg.rest.requests.UpdateTableRequest; import org.apache.iceberg.view.ImmutableSQLViewRepresentation; import org.apache.iceberg.view.ImmutableViewVersion; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.admin.model.FileStorageConfigInfo; import org.apache.polaris.core.admin.model.PrincipalWithCredentialsCredentials; import org.apache.polaris.core.admin.model.StorageConfigInfo; diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/test/PolarisIntegrationTestHelper.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/test/PolarisIntegrationTestHelper.java index f7f5ed719..2ca0db58c 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/test/PolarisIntegrationTestHelper.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/test/PolarisIntegrationTestHelper.java @@ -22,7 +22,7 @@ import jakarta.inject.Inject; import jakarta.inject.Singleton; import java.time.Clock; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.persistence.MetaStoreManagerFactory; import org.apache.polaris.service.context.RealmContextResolver; diff --git a/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java b/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java index 70b2e20ef..477c7f249 100644 --- a/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java +++ b/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java @@ -45,7 +45,8 @@ import org.apache.iceberg.exceptions.NotFoundException; import org.apache.iceberg.exceptions.ValidationException; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.PolarisConfiguration; +import org.apache.polaris.core.config.FeatureConfiguration; +import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.admin.model.CatalogGrant; import org.apache.polaris.core.admin.model.CatalogPrivilege; @@ -527,7 +528,7 @@ private boolean catalogOverlapsWithExistingCatalog(CatalogEntity catalogEntity) getCurrentPolarisContext() .getConfigurationStore() .getConfiguration( - getCurrentPolarisContext(), PolarisConfiguration.ALLOW_OVERLAPPING_CATALOG_URLS); + getCurrentPolarisContext(), FeatureConfiguration.ALLOW_OVERLAPPING_CATALOG_URLS); if (allowOverlappingCatalogUrls) { return false; @@ -597,7 +598,7 @@ public void deleteCatalog(String name) { boolean cleanup = polarisCallContext .getConfigurationStore() - .getConfiguration(polarisCallContext, PolarisConfiguration.CLEANUP_ON_CATALOG_DROP); + .getConfiguration(polarisCallContext, FeatureConfiguration.CLEANUP_ON_CATALOG_DROP); DropEntityResult dropEntityResult = metaStoreManager.dropEntityIfExists( getCurrentPolarisContext(), null, entity, Map.of(), cleanup); diff --git a/service/common/src/main/java/org/apache/polaris/service/admin/PolarisServiceImpl.java b/service/common/src/main/java/org/apache/polaris/service/admin/PolarisServiceImpl.java index 15fb3854d..249895550 100644 --- a/service/common/src/main/java/org/apache/polaris/service/admin/PolarisServiceImpl.java +++ b/service/common/src/main/java/org/apache/polaris/service/admin/PolarisServiceImpl.java @@ -27,7 +27,8 @@ import org.apache.iceberg.catalog.TableIdentifier; import org.apache.iceberg.exceptions.NotAuthorizedException; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.PolarisConfiguration; +import org.apache.polaris.core.config.FeatureConfiguration; +import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.admin.model.AddGrantRequest; import org.apache.polaris.core.admin.model.Catalog; import org.apache.polaris.core.admin.model.CatalogGrant; @@ -137,7 +138,7 @@ private void validateStorageConfig(StorageConfigInfo storageConfigInfo) { polarisCallContext .getConfigurationStore() .getConfiguration( - polarisCallContext, PolarisConfiguration.SUPPORTED_CATALOG_STORAGE_TYPES); + polarisCallContext, FeatureConfiguration.SUPPORTED_CATALOG_STORAGE_TYPES); if (!allowedStorageTypes.contains(storageConfigInfo.getStorageType().name())) { LOGGER .atWarn() diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/BasePolarisCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/BasePolarisCatalog.java index ca9771ef2..50eca75f2 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/BasePolarisCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/BasePolarisCatalog.java @@ -77,7 +77,8 @@ import org.apache.iceberg.view.ViewOperations; import org.apache.iceberg.view.ViewUtil; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.PolarisConfiguration; +import org.apache.polaris.core.config.FeatureConfiguration; +import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.admin.model.StorageConfigInfo; import org.apache.polaris.core.catalog.PolarisCatalogHelpers; import org.apache.polaris.core.context.CallContext; @@ -514,7 +515,7 @@ private void createNamespaceInternal( .getConfigurationStore() .getConfiguration( callContext.getPolarisCallContext(), - PolarisConfiguration.ALLOW_NAMESPACE_LOCATION_OVERLAP)) { + FeatureConfiguration.ALLOW_NAMESPACE_LOCATION_OVERLAP)) { LOGGER.debug("Validating no overlap for {} with sibling tables or namespaces", namespace); validateNoLocationOverlap( entity.getBaseLocation(), resolvedParent.getRawFullPath(), entity.getName()); @@ -650,7 +651,7 @@ public boolean dropNamespace(Namespace namespace) throws NamespaceNotEmptyExcept polarisCallContext .getConfigurationStore() .getConfiguration( - polarisCallContext, PolarisConfiguration.CLEANUP_ON_NAMESPACE_DROP)); + polarisCallContext, FeatureConfiguration.CLEANUP_ON_NAMESPACE_DROP)); if (!dropEntityResult.isSuccess() && dropEntityResult.failedBecauseNotEmpty()) { throw new NamespaceNotEmptyException("Namespace %s is not empty", namespace); @@ -680,7 +681,7 @@ public boolean setProperties(Namespace namespace, Map properties .getConfigurationStore() .getConfiguration( callContext.getPolarisCallContext(), - PolarisConfiguration.ALLOW_NAMESPACE_LOCATION_OVERLAP)) { + FeatureConfiguration.ALLOW_NAMESPACE_LOCATION_OVERLAP)) { LOGGER.debug("Validating no overlap with sibling tables or namespaces"); validateNoLocationOverlap( NamespaceEntity.of(updatedEntity).getBaseLocation(), @@ -898,8 +899,8 @@ private Map refreshCredentials( PolarisEntity entity) { Boolean skipCredentialSubscopingIndirection = getBooleanContextConfiguration( - PolarisConfiguration.SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION.key, - PolarisConfiguration.SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION.defaultValue); + FeatureConfiguration.SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION.key, + FeatureConfiguration.SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION.defaultValue); if (Boolean.TRUE.equals(skipCredentialSubscopingIndirection)) { LOGGER .atInfo() @@ -1031,7 +1032,7 @@ private void validateLocationsForTableLike( .getConfigurationStore() .getConfiguration( callContext.getPolarisCallContext(), - PolarisConfiguration.SUPPORTED_CATALOG_STORAGE_TYPES); + FeatureConfiguration.SUPPORTED_CATALOG_STORAGE_TYPES); if (!allowedStorageTypes.contains(StorageConfigInfo.StorageTypeEnum.FILE.name())) { List invalidLocations = locations.stream() @@ -1061,7 +1062,7 @@ private void validateNoLocationOverlap( .getConfiguration( callContext.getPolarisCallContext(), catalog, - PolarisConfiguration.ALLOW_TABLE_LOCATION_OVERLAP)) { + FeatureConfiguration.ALLOW_TABLE_LOCATION_OVERLAP)) { LOGGER.debug("Skipping location overlap validation for identifier '{}'", identifier); } else { // if (entity.getSubType().equals(PolarisEntitySubType.TABLE)) { // TODO - is this necessary for views? overlapping views do not expose subdirectories via the @@ -1428,12 +1429,12 @@ private void validateMetadataFileInTableDir( polarisCallContext .getConfigurationStore() .getConfiguration( - polarisCallContext, PolarisConfiguration.ALLOW_EXTERNAL_TABLE_LOCATION); + polarisCallContext, FeatureConfiguration.ALLOW_EXTERNAL_TABLE_LOCATION); if (!allowEscape && !polarisCallContext .getConfigurationStore() .getConfiguration( - polarisCallContext, PolarisConfiguration.ALLOW_EXTERNAL_METADATA_FILE_LOCATION)) { + polarisCallContext, FeatureConfiguration.ALLOW_EXTERNAL_METADATA_FILE_LOCATION)) { LOGGER.debug( "Validating base location {} for table {} in metadata file {}", metadata.location(), @@ -1887,15 +1888,15 @@ private void updateTableLike(TableIdentifier identifier, PolarisEntity entity) { .getConfiguration( callContext.getPolarisCallContext(), catalogEntity, - PolarisConfiguration.DROP_WITH_PURGE_ENABLED); + FeatureConfiguration.DROP_WITH_PURGE_ENABLED); if (!dropWithPurgeEnabled) { throw new ForbiddenException( String.format( "Unable to purge entity: %s. To enable this feature, set the Polaris configuration %s " + "or the catalog configuration %s", identifier.name(), - PolarisConfiguration.DROP_WITH_PURGE_ENABLED.key, - PolarisConfiguration.DROP_WITH_PURGE_ENABLED.catalogConfig())); + FeatureConfiguration.DROP_WITH_PURGE_ENABLED.key, + FeatureConfiguration.DROP_WITH_PURGE_ENABLED.catalogConfig())); } } @@ -2126,6 +2127,6 @@ private int getMaxMetadataRefreshRetries() { .getPolarisCallContext() .getConfigurationStore() .getConfiguration( - callContext.getPolarisCallContext(), PolarisConfiguration.MAX_METADATA_REFRESH_RETRIES); + callContext.getPolarisCallContext(), FeatureConfiguration.MAX_METADATA_REFRESH_RETRIES); } } diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/IcebergCatalogAdapter.java b/service/common/src/main/java/org/apache/polaris/service/catalog/IcebergCatalogAdapter.java index 968d9c5fd..7130eb3c9 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/IcebergCatalogAdapter.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/IcebergCatalogAdapter.java @@ -55,7 +55,7 @@ import org.apache.iceberg.rest.responses.ConfigResponse; import org.apache.iceberg.rest.responses.ImmutableLoadCredentialsResponse; import org.apache.iceberg.rest.responses.LoadTableResponse; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.auth.AuthenticatedPolarisPrincipal; import org.apache.polaris.core.auth.PolarisAuthorizer; diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/PolarisCatalogHandlerWrapper.java b/service/common/src/main/java/org/apache/polaris/service/catalog/PolarisCatalogHandlerWrapper.java index 489ccd488..c0e0c99a7 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/PolarisCatalogHandlerWrapper.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/PolarisCatalogHandlerWrapper.java @@ -71,8 +71,9 @@ import org.apache.iceberg.rest.responses.LoadTableResponse; import org.apache.iceberg.rest.responses.LoadViewResponse; import org.apache.iceberg.rest.responses.UpdateNamespacePropertiesResponse; -import org.apache.polaris.core.PolarisConfiguration; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.FeatureConfiguration; +import org.apache.polaris.core.config.PolarisConfiguration; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.auth.AuthenticatedPolarisPrincipal; import org.apache.polaris.core.auth.PolarisAuthorizableOperation; @@ -850,11 +851,11 @@ public LoadTableResponse loadTableWithAccessDelegation( && !configurationStore.getConfiguration( callContext.getPolarisCallContext(), catalogEntity, - PolarisConfiguration.ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING)) { + FeatureConfiguration.ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING)) { throw new ForbiddenException( "Access Delegation is not enabled for this catalog. Please consult applicable " + "documentation for the catalog config property '%s' to enable this feature", - PolarisConfiguration.ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING.catalogConfig()); + FeatureConfiguration.ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING.catalogConfig()); } // TODO: Find a way for the configuration or caller to better express whether to fail or omit @@ -1070,7 +1071,7 @@ public void commitTransaction(CommitTransactionRequest commitTransactionRequest) .getConfigurationStore() .getConfiguration( callContext.getPolarisCallContext(), - PolarisConfiguration.ALLOW_NAMESPACE_LOCATION_OVERLAP)) { + FeatureConfiguration.ALLOW_NAMESPACE_LOCATION_OVERLAP)) { throw new BadRequestException( "Unsupported operation: commitTransaction containing SetLocation" + " for table '%s' and new location '%s'", diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/io/DefaultFileIOFactory.java b/service/common/src/main/java/org/apache/polaris/service/catalog/io/DefaultFileIOFactory.java index 48d9a280a..dfb2c793a 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/io/DefaultFileIOFactory.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/io/DefaultFileIOFactory.java @@ -31,7 +31,7 @@ import org.apache.iceberg.CatalogUtil; import org.apache.iceberg.catalog.TableIdentifier; import org.apache.iceberg.io.FileIO; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.context.RealmContext; import org.apache.polaris.core.entity.PolarisEntity; diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java b/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java index e0bed634f..07c01d207 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java @@ -22,8 +22,9 @@ import java.util.Optional; import java.util.Set; import org.apache.iceberg.catalog.TableIdentifier; -import org.apache.polaris.core.PolarisConfiguration; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.FeatureConfiguration; +import org.apache.polaris.core.config.PolarisConfiguration; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.PolarisEntity; import org.apache.polaris.core.entity.PolarisEntityConstants; @@ -88,8 +89,8 @@ public static Map refreshCredentials( boolean skipCredentialSubscopingIndirection = configurationStore.getConfiguration( callContext.getPolarisCallContext(), - PolarisConfiguration.SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION.key, - PolarisConfiguration.SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION.defaultValue); + FeatureConfiguration.SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION.key, + FeatureConfiguration.SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION.defaultValue); if (skipCredentialSubscopingIndirection) { LOGGER .atDebug() diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/io/WasbTranslatingFileIOFactory.java b/service/common/src/main/java/org/apache/polaris/service/catalog/io/WasbTranslatingFileIOFactory.java index 3bb365368..a7074fdc0 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/io/WasbTranslatingFileIOFactory.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/io/WasbTranslatingFileIOFactory.java @@ -26,7 +26,7 @@ import java.util.Set; import org.apache.iceberg.catalog.TableIdentifier; import org.apache.iceberg.io.FileIO; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.persistence.MetaStoreManagerFactory; import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; diff --git a/service/common/src/main/java/org/apache/polaris/service/config/DefaultConfigurationStore.java b/service/common/src/main/java/org/apache/polaris/service/config/DefaultConfigurationStore.java index 3db2fd998..8d9fd0e43 100644 --- a/service/common/src/main/java/org/apache/polaris/service/config/DefaultConfigurationStore.java +++ b/service/common/src/main/java/org/apache/polaris/service/config/DefaultConfigurationStore.java @@ -25,7 +25,7 @@ import jakarta.inject.Inject; import java.util.Map; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.context.CallContext; @ApplicationScoped diff --git a/service/common/src/main/java/org/apache/polaris/service/context/DefaultCallContextResolver.java b/service/common/src/main/java/org/apache/polaris/service/context/DefaultCallContextResolver.java index 14246692e..2ee0f15a8 100644 --- a/service/common/src/main/java/org/apache/polaris/service/context/DefaultCallContextResolver.java +++ b/service/common/src/main/java/org/apache/polaris/service/context/DefaultCallContextResolver.java @@ -24,7 +24,7 @@ import java.time.Clock; import java.util.Map; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.context.RealmContext; diff --git a/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java b/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java index 7dd4f6804..d25f09698 100644 --- a/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java +++ b/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java @@ -29,7 +29,7 @@ import java.util.Map; import java.util.Set; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.auth.AuthenticatedPolarisPrincipal; import org.apache.polaris.core.auth.PolarisAuthorizer; diff --git a/service/common/src/testFixtures/java/org/apache/polaris/service/catalog/io/MeasuredFileIOFactory.java b/service/common/src/testFixtures/java/org/apache/polaris/service/catalog/io/MeasuredFileIOFactory.java index 3e831361f..abfb6e8c3 100644 --- a/service/common/src/testFixtures/java/org/apache/polaris/service/catalog/io/MeasuredFileIOFactory.java +++ b/service/common/src/testFixtures/java/org/apache/polaris/service/catalog/io/MeasuredFileIOFactory.java @@ -29,7 +29,7 @@ import java.util.function.Supplier; import org.apache.iceberg.catalog.TableIdentifier; import org.apache.iceberg.io.FileIO; -import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.persistence.MetaStoreManagerFactory; import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; From fe48ac396fad34c67ae68780da97c0950f07961e Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Wed, 5 Mar 2025 11:58:54 -0800 Subject: [PATCH 02/12] builds, tests fail --- .../config/BehaviorChangeConfiguration.java | 2 +- .../core/config/FeatureConfiguration.java | 2 +- .../src/main/resources/application.properties | 2 + .../QuarkusBehaviorChangesConfiguration.java | 42 +++++++++++++++++++ 4 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusBehaviorChangesConfiguration.java diff --git a/polaris-core/src/main/java/org/apache/polaris/core/config/BehaviorChangeConfiguration.java b/polaris-core/src/main/java/org/apache/polaris/core/config/BehaviorChangeConfiguration.java index 0666f0d5f..7571ff8b5 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/config/BehaviorChangeConfiguration.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/config/BehaviorChangeConfiguration.java @@ -30,7 +30,7 @@ */ public class BehaviorChangeConfiguration extends PolarisConfiguration { - public BehaviorChangeConfiguration( + protected BehaviorChangeConfiguration( String key, String description, T defaultValue, Optional catalogConfig) { super(key, description, defaultValue, catalogConfig); } diff --git a/polaris-core/src/main/java/org/apache/polaris/core/config/FeatureConfiguration.java b/polaris-core/src/main/java/org/apache/polaris/core/config/FeatureConfiguration.java index 9f3710c58..27340ba9c 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/config/FeatureConfiguration.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/config/FeatureConfiguration.java @@ -30,7 +30,7 @@ * @param */ public class FeatureConfiguration extends PolarisConfiguration { - public FeatureConfiguration(String key, String description, T defaultValue, Optional catalogConfig) { + protected FeatureConfiguration(String key, String description, T defaultValue, Optional catalogConfig) { super(key, description, defaultValue, catalogConfig); } diff --git a/quarkus/defaults/src/main/resources/application.properties b/quarkus/defaults/src/main/resources/application.properties index d3a205737..0c416eeb7 100644 --- a/quarkus/defaults/src/main/resources/application.properties +++ b/quarkus/defaults/src/main/resources/application.properties @@ -95,6 +95,8 @@ polaris.features.defaults."SUPPORTED_CATALOG_STORAGE_TYPES"=["S3","GCS","AZURE", # polaris.features.realm-overrides."my-realm"."INITIALIZE_DEFAULT_CATALOG_FILEIO_FOR_TEST"=true # polaris.features.realm-overrides."my-realm"."SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION"=true +polaris.behavior-changes.defaults."SKIP_PRINTING_BANNER"=true + polaris.persistence.type=in-memory polaris.file-io.type=default diff --git a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusBehaviorChangesConfiguration.java b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusBehaviorChangesConfiguration.java new file mode 100644 index 000000000..5dbf3b0ce --- /dev/null +++ b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusBehaviorChangesConfiguration.java @@ -0,0 +1,42 @@ +/* + * 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.polaris.service.quarkus.config; + +import io.quarkus.runtime.annotations.StaticInitSafe; +import io.smallrye.config.ConfigMapping; +import io.smallrye.config.WithParentName; +import java.util.Map; +import org.apache.polaris.service.config.FeaturesConfiguration; + +@StaticInitSafe +@ConfigMapping(prefix = "polaris.behavior-changes") +public interface QuarkusBehaviorChangesConfiguration extends FeaturesConfiguration { + + @Override + Map defaults(); + + @Override + Map realmOverrides(); + + interface QuarkusRealmOverrides extends RealmOverrides { + @WithParentName + @Override + Map overrides(); + } +} From 1d51695c368bdfed24d80266443521cbb0080852 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Wed, 5 Mar 2025 11:59:01 -0800 Subject: [PATCH 03/12] autolint --- ...olarisEclipseLinkMetaStoreManagerTest.java | 2 +- .../polaris/core/PolarisCallContext.java | 1 - .../core/auth/PolarisAuthorizerImpl.java | 1 - .../config/BehaviorChangeConfiguration.java | 18 +- .../core/config/FeatureConfiguration.java | 313 +++++++++--------- .../core/config/PolarisConfiguration.java | 5 +- .../config/PolarisConfigurationStore.java | 1 - .../PolarisStorageConfigurationInfo.java | 4 +- .../AzureCredentialsStorageIntegration.java | 4 +- .../PolarisTreeMapMetaStoreManagerTest.java | 2 +- .../InMemoryStorageIntegrationTest.java | 2 +- .../admintool/config/QuarkusProducers.java | 2 +- .../QuarkusBehaviorChangesConfiguration.java | 18 +- .../quarkus/config/QuarkusProducers.java | 2 +- .../quarkus/admin/PolarisAuthzTestBase.java | 5 +- .../catalog/BasePolarisCatalogTest.java | 5 +- .../catalog/BasePolarisCatalogViewTest.java | 5 +- ...PolarisCatalogHandlerWrapperAuthzTest.java | 2 +- .../test/PolarisIntegrationTestHelper.java | 2 +- .../service/admin/PolarisAdminService.java | 3 +- .../service/admin/PolarisServiceImpl.java | 3 +- .../service/catalog/BasePolarisCatalog.java | 3 +- .../catalog/IcebergCatalogAdapter.java | 2 +- .../catalog/PolarisCatalogHandlerWrapper.java | 5 +- .../service/catalog/io/FileIOUtil.java | 1 - .../context/DefaultCallContextResolver.java | 2 +- .../apache/polaris/service/TestServices.java | 2 +- 27 files changed, 201 insertions(+), 214 deletions(-) diff --git a/extension/persistence/eclipselink/src/test/java/org/apache/polaris/extension/persistence/impl/eclipselink/PolarisEclipseLinkMetaStoreManagerTest.java b/extension/persistence/eclipselink/src/test/java/org/apache/polaris/extension/persistence/impl/eclipselink/PolarisEclipseLinkMetaStoreManagerTest.java index bcb7f6d7a..8e63a77db 100644 --- a/extension/persistence/eclipselink/src/test/java/org/apache/polaris/extension/persistence/impl/eclipselink/PolarisEclipseLinkMetaStoreManagerTest.java +++ b/extension/persistence/eclipselink/src/test/java/org/apache/polaris/extension/persistence/impl/eclipselink/PolarisEclipseLinkMetaStoreManagerTest.java @@ -36,9 +36,9 @@ import java.util.Objects; import java.util.stream.Stream; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDefaultDiagServiceImpl; import org.apache.polaris.core.PolarisDiagnostics; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.entity.PolarisPrincipalSecrets; import org.apache.polaris.core.persistence.BasePolarisMetaStoreManagerTest; import org.apache.polaris.core.persistence.PolarisTestMetaStoreManager; diff --git a/polaris-core/src/main/java/org/apache/polaris/core/PolarisCallContext.java b/polaris-core/src/main/java/org/apache/polaris/core/PolarisCallContext.java index ac11fa704..590d8157d 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/PolarisCallContext.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/PolarisCallContext.java @@ -21,7 +21,6 @@ import jakarta.annotation.Nonnull; import java.time.Clock; import java.time.ZoneId; - import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.persistence.transactional.TransactionalPersistence; diff --git a/polaris-core/src/main/java/org/apache/polaris/core/auth/PolarisAuthorizerImpl.java b/polaris-core/src/main/java/org/apache/polaris/core/auth/PolarisAuthorizerImpl.java index 320d04648..564be49da 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/auth/PolarisAuthorizerImpl.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/auth/PolarisAuthorizerImpl.java @@ -99,7 +99,6 @@ import java.util.stream.Collectors; import org.apache.iceberg.exceptions.ForbiddenException; import org.apache.polaris.core.config.FeatureConfiguration; -import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.PolarisBaseEntity; diff --git a/polaris-core/src/main/java/org/apache/polaris/core/config/BehaviorChangeConfiguration.java b/polaris-core/src/main/java/org/apache/polaris/core/config/BehaviorChangeConfiguration.java index 7571ff8b5..80b4377e1 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/config/BehaviorChangeConfiguration.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/config/BehaviorChangeConfiguration.java @@ -16,22 +16,22 @@ * specific language governing permissions and limitations * under the License. */ - package org.apache.polaris.core.config; import java.util.Optional; /** - * Configurations for non-feature beheavior changes within Polaris. These configurations are not intended - * for use by end users and govern nuanced behavior changes and bugfixes. The configurations never expose - * user-facing catalog-level configurations. These configurations are not stable and may be removed at - * any time. + * Configurations for non-feature beheavior changes within Polaris. These configurations are not + * intended for use by end users and govern nuanced behavior changes and bugfixes. The + * configurations never expose user-facing catalog-level configurations. These configurations are + * not stable and may be removed at any time. + * * @param The type of the configuration */ public class BehaviorChangeConfiguration extends PolarisConfiguration { - protected BehaviorChangeConfiguration( - String key, String description, T defaultValue, Optional catalogConfig) { - super(key, description, defaultValue, catalogConfig); - } + protected BehaviorChangeConfiguration( + String key, String description, T defaultValue, Optional catalogConfig) { + super(key, description, defaultValue, catalogConfig); + } } diff --git a/polaris-core/src/main/java/org/apache/polaris/core/config/FeatureConfiguration.java b/polaris-core/src/main/java/org/apache/polaris/core/config/FeatureConfiguration.java index 27340ba9c..087d0525e 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/config/FeatureConfiguration.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/config/FeatureConfiguration.java @@ -16,170 +16,171 @@ * specific language governing permissions and limitations * under the License. */ - package org.apache.polaris.core.config; -import org.apache.polaris.core.admin.model.StorageConfigInfo; - import java.util.List; import java.util.Optional; +import org.apache.polaris.core.admin.model.StorageConfigInfo; /** * Configurations for features within Polaris. These configurations are intended to be customized - * and many expose user-facing catalog-level configurations. These configurations are stable over time. + * and many expose user-facing catalog-level configurations. These configurations are stable over + * time. + * * @param */ public class FeatureConfiguration extends PolarisConfiguration { - protected FeatureConfiguration(String key, String description, T defaultValue, Optional catalogConfig) { - super(key, description, defaultValue, catalogConfig); - } - - public static final FeatureConfiguration - ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING = - PolarisConfiguration.builder() - .key("ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING") - .description( - "If set to true, require that principals must rotate their credentials before being used " - + "for anything else.") - .defaultValue(false) - .buildFeatureConfiguration(); - - public static final FeatureConfiguration SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION = - PolarisConfiguration.builder() - .key("SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION") - .description( - "If set to true, skip credential-subscoping indirection entirely whenever trying\n" - + " to obtain storage credentials for instantiating a FileIO. If 'true', no attempt is made\n" - + " to use StorageConfigs to generate table-specific storage credentials, but instead the default\n" - + " fallthrough of table-level credential properties or else provider-specific APPLICATION_DEFAULT\n" - + " credential-loading will be used for the FileIO.\n" - + " Typically this setting is used in single-tenant server deployments that don't rely on\n" - + " \"credential-vending\" and can use server-default environment variables or credential config\n" - + " files for all storage access, or in test/dev scenarios.") - .defaultValue(false) - .buildFeatureConfiguration(); - - public static final FeatureConfiguration ALLOW_TABLE_LOCATION_OVERLAP = - PolarisConfiguration.builder() - .key("ALLOW_TABLE_LOCATION_OVERLAP") - .catalogConfig("allow.overlapping.table.location") - .description( - "If set to true, allow one table's location to reside within another table's location. " - + "This is only enforced within a given namespace.") - .defaultValue(false) - .buildFeatureConfiguration(); - - public static final FeatureConfiguration ALLOW_NAMESPACE_LOCATION_OVERLAP = - PolarisConfiguration.builder() - .key("ALLOW_NAMESPACE_LOCATION_OVERLAP") - .description( - "If set to true, allow one namespace's location to reside within another namespace's location. " - + "This is only enforced within a parent catalog or namespace.") - .defaultValue(false) - .buildFeatureConfiguration(); - - public static final FeatureConfiguration ALLOW_EXTERNAL_METADATA_FILE_LOCATION = - PolarisConfiguration.builder() - .key("ALLOW_EXTERNAL_METADATA_FILE_LOCATION") - .description( - "If set to true, allows metadata files to be located outside the default metadata directory.") - .defaultValue(false) - .buildFeatureConfiguration(); - - public static final FeatureConfiguration ALLOW_OVERLAPPING_CATALOG_URLS = - PolarisConfiguration.builder() - .key("ALLOW_OVERLAPPING_CATALOG_URLS") - .description("If set to true, allows catalog URLs to overlap.") - .defaultValue(false) - .buildFeatureConfiguration(); - - public static final FeatureConfiguration ALLOW_UNSTRUCTURED_TABLE_LOCATION = - PolarisConfiguration.builder() - .key("ALLOW_UNSTRUCTURED_TABLE_LOCATION") - .catalogConfig("allow.unstructured.table.location") - .description("If set to true, allows unstructured table locations.") - .defaultValue(false) - .buildFeatureConfiguration(); - - public static final FeatureConfiguration ALLOW_EXTERNAL_TABLE_LOCATION = - PolarisConfiguration.builder() - .key("ALLOW_EXTERNAL_TABLE_LOCATION") - .catalogConfig("allow.external.table.location") - .description( - "If set to true, allows tables to have external locations outside the default structure.") - .defaultValue(false) - .buildFeatureConfiguration(); - - public static final FeatureConfiguration ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING = - PolarisConfiguration.builder() - .key("ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING") - .catalogConfig("enable.credential.vending") - .description("If set to true, allow credential vending for external catalogs.") - .defaultValue(true) - .buildFeatureConfiguration(); - - public static final FeatureConfiguration> SUPPORTED_CATALOG_STORAGE_TYPES = - PolarisConfiguration.>builder() - .key("SUPPORTED_CATALOG_STORAGE_TYPES") - .catalogConfig("supported.storage.types") - .description("The list of supported storage types for a catalog") - .defaultValue( - List.of( - StorageConfigInfo.StorageTypeEnum.S3.name(), - StorageConfigInfo.StorageTypeEnum.AZURE.name(), - StorageConfigInfo.StorageTypeEnum.GCS.name(), - StorageConfigInfo.StorageTypeEnum.FILE.name())) - .buildFeatureConfiguration(); - - public static final FeatureConfiguration CLEANUP_ON_NAMESPACE_DROP = - PolarisConfiguration.builder() - .key("CLEANUP_ON_NAMESPACE_DROP") - .catalogConfig("cleanup.on.namespace.drop") - .description("If set to true, clean up data when a namespace is dropped") - .defaultValue(false) - .buildFeatureConfiguration(); - - public static final FeatureConfiguration CLEANUP_ON_CATALOG_DROP = - PolarisConfiguration.builder() - .key("CLEANUP_ON_CATALOG_DROP") - .catalogConfig("cleanup.on.catalog.drop") - .description("If set to true, clean up data when a catalog is dropped") - .defaultValue(false) - .buildFeatureConfiguration(); - - public static final FeatureConfiguration DROP_WITH_PURGE_ENABLED = - PolarisConfiguration.builder() - .key("DROP_WITH_PURGE_ENABLED") - .catalogConfig("drop-with-purge.enabled") - .description( - "If set to true, allows tables to be dropped with the purge parameter set to true.") - .defaultValue(true) - .buildFeatureConfiguration(); - - public static final FeatureConfiguration STORAGE_CREDENTIAL_DURATION_SECONDS = - PolarisConfiguration.builder() - .key("STORAGE_CREDENTIAL_DURATION_SECONDS") - .description( - "The duration of time that vended storage credentials are valid for. Support for" - + " longer (or shorter) durations is dependent on the storage provider. GCS" - + " current does not respect this value.") - .defaultValue(60 * 60) // 1 hour - .buildFeatureConfiguration(); - - public static final FeatureConfiguration STORAGE_CREDENTIAL_CACHE_DURATION_SECONDS = - PolarisConfiguration.builder() - .key("STORAGE_CREDENTIAL_CACHE_DURATION_SECONDS") - .description( - "How long to store storage credentials in the local cache. This should be less than " - + STORAGE_CREDENTIAL_DURATION_SECONDS.key) - .defaultValue(30 * 60) // 30 minutes - .buildFeatureConfiguration(); - - public static final FeatureConfiguration MAX_METADATA_REFRESH_RETRIES = - PolarisConfiguration.builder() - .key("MAX_METADATA_REFRESH_RETRIES") - .description( - "How many times to retry refreshing metadata when the previous error was retryable") - .defaultValue(2) - .buildFeatureConfiguration(); + protected FeatureConfiguration( + String key, String description, T defaultValue, Optional catalogConfig) { + super(key, description, defaultValue, catalogConfig); + } + + public static final FeatureConfiguration + ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING = + PolarisConfiguration.builder() + .key("ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING") + .description( + "If set to true, require that principals must rotate their credentials before being used " + + "for anything else.") + .defaultValue(false) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION = + PolarisConfiguration.builder() + .key("SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION") + .description( + "If set to true, skip credential-subscoping indirection entirely whenever trying\n" + + " to obtain storage credentials for instantiating a FileIO. If 'true', no attempt is made\n" + + " to use StorageConfigs to generate table-specific storage credentials, but instead the default\n" + + " fallthrough of table-level credential properties or else provider-specific APPLICATION_DEFAULT\n" + + " credential-loading will be used for the FileIO.\n" + + " Typically this setting is used in single-tenant server deployments that don't rely on\n" + + " \"credential-vending\" and can use server-default environment variables or credential config\n" + + " files for all storage access, or in test/dev scenarios.") + .defaultValue(false) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration ALLOW_TABLE_LOCATION_OVERLAP = + PolarisConfiguration.builder() + .key("ALLOW_TABLE_LOCATION_OVERLAP") + .catalogConfig("allow.overlapping.table.location") + .description( + "If set to true, allow one table's location to reside within another table's location. " + + "This is only enforced within a given namespace.") + .defaultValue(false) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration ALLOW_NAMESPACE_LOCATION_OVERLAP = + PolarisConfiguration.builder() + .key("ALLOW_NAMESPACE_LOCATION_OVERLAP") + .description( + "If set to true, allow one namespace's location to reside within another namespace's location. " + + "This is only enforced within a parent catalog or namespace.") + .defaultValue(false) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration ALLOW_EXTERNAL_METADATA_FILE_LOCATION = + PolarisConfiguration.builder() + .key("ALLOW_EXTERNAL_METADATA_FILE_LOCATION") + .description( + "If set to true, allows metadata files to be located outside the default metadata directory.") + .defaultValue(false) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration ALLOW_OVERLAPPING_CATALOG_URLS = + PolarisConfiguration.builder() + .key("ALLOW_OVERLAPPING_CATALOG_URLS") + .description("If set to true, allows catalog URLs to overlap.") + .defaultValue(false) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration ALLOW_UNSTRUCTURED_TABLE_LOCATION = + PolarisConfiguration.builder() + .key("ALLOW_UNSTRUCTURED_TABLE_LOCATION") + .catalogConfig("allow.unstructured.table.location") + .description("If set to true, allows unstructured table locations.") + .defaultValue(false) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration ALLOW_EXTERNAL_TABLE_LOCATION = + PolarisConfiguration.builder() + .key("ALLOW_EXTERNAL_TABLE_LOCATION") + .catalogConfig("allow.external.table.location") + .description( + "If set to true, allows tables to have external locations outside the default structure.") + .defaultValue(false) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING = + PolarisConfiguration.builder() + .key("ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING") + .catalogConfig("enable.credential.vending") + .description("If set to true, allow credential vending for external catalogs.") + .defaultValue(true) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration> SUPPORTED_CATALOG_STORAGE_TYPES = + PolarisConfiguration.>builder() + .key("SUPPORTED_CATALOG_STORAGE_TYPES") + .catalogConfig("supported.storage.types") + .description("The list of supported storage types for a catalog") + .defaultValue( + List.of( + StorageConfigInfo.StorageTypeEnum.S3.name(), + StorageConfigInfo.StorageTypeEnum.AZURE.name(), + StorageConfigInfo.StorageTypeEnum.GCS.name(), + StorageConfigInfo.StorageTypeEnum.FILE.name())) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration CLEANUP_ON_NAMESPACE_DROP = + PolarisConfiguration.builder() + .key("CLEANUP_ON_NAMESPACE_DROP") + .catalogConfig("cleanup.on.namespace.drop") + .description("If set to true, clean up data when a namespace is dropped") + .defaultValue(false) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration CLEANUP_ON_CATALOG_DROP = + PolarisConfiguration.builder() + .key("CLEANUP_ON_CATALOG_DROP") + .catalogConfig("cleanup.on.catalog.drop") + .description("If set to true, clean up data when a catalog is dropped") + .defaultValue(false) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration DROP_WITH_PURGE_ENABLED = + PolarisConfiguration.builder() + .key("DROP_WITH_PURGE_ENABLED") + .catalogConfig("drop-with-purge.enabled") + .description( + "If set to true, allows tables to be dropped with the purge parameter set to true.") + .defaultValue(true) + .buildFeatureConfiguration(); + + public static final FeatureConfiguration STORAGE_CREDENTIAL_DURATION_SECONDS = + PolarisConfiguration.builder() + .key("STORAGE_CREDENTIAL_DURATION_SECONDS") + .description( + "The duration of time that vended storage credentials are valid for. Support for" + + " longer (or shorter) durations is dependent on the storage provider. GCS" + + " current does not respect this value.") + .defaultValue(60 * 60) // 1 hour + .buildFeatureConfiguration(); + + public static final FeatureConfiguration STORAGE_CREDENTIAL_CACHE_DURATION_SECONDS = + PolarisConfiguration.builder() + .key("STORAGE_CREDENTIAL_CACHE_DURATION_SECONDS") + .description( + "How long to store storage credentials in the local cache. This should be less than " + + STORAGE_CREDENTIAL_DURATION_SECONDS.key) + .defaultValue(30 * 60) // 30 minutes + .buildFeatureConfiguration(); + + public static final FeatureConfiguration MAX_METADATA_REFRESH_RETRIES = + PolarisConfiguration.builder() + .key("MAX_METADATA_REFRESH_RETRIES") + .description( + "How many times to retry refreshing metadata when the previous error was retryable") + .defaultValue(2) + .buildFeatureConfiguration(); } diff --git a/polaris-core/src/main/java/org/apache/polaris/core/config/PolarisConfiguration.java b/polaris-core/src/main/java/org/apache/polaris/core/config/PolarisConfiguration.java index e40d2eb60..bcb380988 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/config/PolarisConfiguration.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/config/PolarisConfiguration.java @@ -21,13 +21,13 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; - import org.apache.polaris.core.context.CallContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * An ABC for Polaris configurations that alter the service's behavior + * * @param The type of the configuration */ public abstract class PolarisConfiguration { @@ -109,7 +109,8 @@ public BehaviorChangeConfiguration buildBehaviorChangeConfiguration() { throw new IllegalArgumentException("key, description, and defaultValue are required"); } if (catalogConfig.isPresent()) { - throw new IllegalArgumentException("catalogConfig is not valid for behavior change configs"); + throw new IllegalArgumentException( + "catalogConfig is not valid for behavior change configs"); } return new BehaviorChangeConfiguration<>(key, description, defaultValue, catalogConfig); } diff --git a/polaris-core/src/main/java/org/apache/polaris/core/config/PolarisConfigurationStore.java b/polaris-core/src/main/java/org/apache/polaris/core/config/PolarisConfigurationStore.java index c787f11d9..65e613351 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/config/PolarisConfigurationStore.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/config/PolarisConfigurationStore.java @@ -23,7 +23,6 @@ import jakarta.annotation.Nullable; import java.util.ArrayList; import java.util.List; - import org.apache.polaris.core.PolarisCallContext; import org.apache.polaris.core.entity.CatalogEntity; diff --git a/polaris-core/src/main/java/org/apache/polaris/core/storage/PolarisStorageConfigurationInfo.java b/polaris-core/src/main/java/org/apache/polaris/core/storage/PolarisStorageConfigurationInfo.java index edf57b488..9631d95b4 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/storage/PolarisStorageConfigurationInfo.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/storage/PolarisStorageConfigurationInfo.java @@ -36,11 +36,9 @@ import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; - -import org.apache.polaris.core.config.FeatureConfiguration; -import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.admin.model.Catalog; +import org.apache.polaris.core.config.FeatureConfiguration; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.CatalogEntity; import org.apache.polaris.core.entity.PolarisEntity; diff --git a/polaris-core/src/main/java/org/apache/polaris/core/storage/azure/AzureCredentialsStorageIntegration.java b/polaris-core/src/main/java/org/apache/polaris/core/storage/azure/AzureCredentialsStorageIntegration.java index 319a10edf..62e4fc4dc 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/storage/azure/AzureCredentialsStorageIntegration.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/storage/azure/AzureCredentialsStorageIntegration.java @@ -45,10 +45,8 @@ import java.util.HashSet; import java.util.Objects; import java.util.Set; - -import org.apache.polaris.core.config.FeatureConfiguration; -import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.PolarisDiagnostics; +import org.apache.polaris.core.config.FeatureConfiguration; import org.apache.polaris.core.storage.InMemoryStorageIntegration; import org.apache.polaris.core.storage.PolarisCredentialProperty; import org.slf4j.Logger; diff --git a/polaris-core/src/test/java/org/apache/polaris/core/persistence/PolarisTreeMapMetaStoreManagerTest.java b/polaris-core/src/test/java/org/apache/polaris/core/persistence/PolarisTreeMapMetaStoreManagerTest.java index 7bf972450..d7491e038 100644 --- a/polaris-core/src/test/java/org/apache/polaris/core/persistence/PolarisTreeMapMetaStoreManagerTest.java +++ b/polaris-core/src/test/java/org/apache/polaris/core/persistence/PolarisTreeMapMetaStoreManagerTest.java @@ -22,9 +22,9 @@ import java.time.ZoneId; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDefaultDiagServiceImpl; import org.apache.polaris.core.PolarisDiagnostics; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.persistence.transactional.PolarisMetaStoreManagerImpl; import org.apache.polaris.core.persistence.transactional.PolarisTreeMapMetaStoreSessionImpl; import org.apache.polaris.core.persistence.transactional.PolarisTreeMapStore; diff --git a/polaris-core/src/test/java/org/apache/polaris/core/storage/InMemoryStorageIntegrationTest.java b/polaris-core/src/test/java/org/apache/polaris/core/storage/InMemoryStorageIntegrationTest.java index a78debe15..0f1f4f151 100644 --- a/polaris-core/src/test/java/org/apache/polaris/core/storage/InMemoryStorageIntegrationTest.java +++ b/polaris-core/src/test/java/org/apache/polaris/core/storage/InMemoryStorageIntegrationTest.java @@ -26,9 +26,9 @@ import java.util.Map; import java.util.Set; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDefaultDiagServiceImpl; import org.apache.polaris.core.PolarisDiagnostics; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.storage.aws.AwsStorageConfigurationInfo; import org.assertj.core.api.Assertions; diff --git a/quarkus/admin/src/main/java/org/apache/polaris/admintool/config/QuarkusProducers.java b/quarkus/admin/src/main/java/org/apache/polaris/admintool/config/QuarkusProducers.java index c1db15098..07ad02362 100644 --- a/quarkus/admin/src/main/java/org/apache/polaris/admintool/config/QuarkusProducers.java +++ b/quarkus/admin/src/main/java/org/apache/polaris/admintool/config/QuarkusProducers.java @@ -25,9 +25,9 @@ import jakarta.enterprise.inject.Instance; import jakarta.enterprise.inject.Produces; import java.time.Clock; -import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDefaultDiagServiceImpl; import org.apache.polaris.core.PolarisDiagnostics; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.persistence.MetaStoreManagerFactory; import org.apache.polaris.core.storage.PolarisStorageConfigurationInfo; import org.apache.polaris.core.storage.PolarisStorageIntegration; diff --git a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusBehaviorChangesConfiguration.java b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusBehaviorChangesConfiguration.java index 5dbf3b0ce..23b961ef5 100644 --- a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusBehaviorChangesConfiguration.java +++ b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusBehaviorChangesConfiguration.java @@ -28,15 +28,15 @@ @ConfigMapping(prefix = "polaris.behavior-changes") public interface QuarkusBehaviorChangesConfiguration extends FeaturesConfiguration { - @Override - Map defaults(); + @Override + Map defaults(); - @Override - Map realmOverrides(); + @Override + Map realmOverrides(); - interface QuarkusRealmOverrides extends RealmOverrides { - @WithParentName - @Override - Map overrides(); - } + interface QuarkusRealmOverrides extends RealmOverrides { + @WithParentName + @Override + Map overrides(); + } } diff --git a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusProducers.java b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusProducers.java index fa7ad3bec..0616b1228 100644 --- a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusProducers.java +++ b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusProducers.java @@ -33,12 +33,12 @@ import jakarta.ws.rs.core.Context; import java.time.Clock; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDefaultDiagServiceImpl; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.auth.AuthenticatedPolarisPrincipal; import org.apache.polaris.core.auth.PolarisAuthorizer; import org.apache.polaris.core.auth.PolarisAuthorizerImpl; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.context.RealmContext; import org.apache.polaris.core.persistence.MetaStoreManagerFactory; diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java index a5b4b09e8..bcc2ef425 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java @@ -47,9 +47,6 @@ import org.apache.iceberg.exceptions.ForbiddenException; import org.apache.iceberg.types.Types; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.config.FeatureConfiguration; -import org.apache.polaris.core.config.PolarisConfiguration; -import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.admin.model.FileStorageConfigInfo; import org.apache.polaris.core.admin.model.PrincipalWithCredentials; @@ -58,6 +55,8 @@ import org.apache.polaris.core.auth.AuthenticatedPolarisPrincipal; import org.apache.polaris.core.auth.PolarisAuthorizer; import org.apache.polaris.core.auth.PolarisAuthorizerImpl; +import org.apache.polaris.core.config.FeatureConfiguration; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.context.RealmContext; import org.apache.polaris.core.entity.CatalogEntity; diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogTest.java index 3ec040c37..555275839 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogTest.java @@ -72,15 +72,14 @@ import org.apache.iceberg.io.FileIO; import org.apache.iceberg.types.Types; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.config.FeatureConfiguration; -import org.apache.polaris.core.config.PolarisConfiguration; -import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.admin.model.AwsStorageConfigInfo; import org.apache.polaris.core.admin.model.StorageConfigInfo; import org.apache.polaris.core.auth.AuthenticatedPolarisPrincipal; import org.apache.polaris.core.auth.PolarisAuthorizerImpl; import org.apache.polaris.core.auth.PolarisSecretsManager.PrincipalSecretsResult; +import org.apache.polaris.core.config.FeatureConfiguration; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.context.RealmContext; import org.apache.polaris.core.entity.CatalogEntity; diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogViewTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogViewTest.java index 241b31907..471afa2d9 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogViewTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogViewTest.java @@ -39,14 +39,13 @@ import org.apache.iceberg.catalog.Catalog; import org.apache.iceberg.view.ViewCatalogTests; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.config.FeatureConfiguration; -import org.apache.polaris.core.config.PolarisConfiguration; -import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.admin.model.FileStorageConfigInfo; import org.apache.polaris.core.admin.model.StorageConfigInfo; import org.apache.polaris.core.auth.AuthenticatedPolarisPrincipal; import org.apache.polaris.core.auth.PolarisAuthorizerImpl; +import org.apache.polaris.core.config.FeatureConfiguration; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.context.RealmContext; import org.apache.polaris.core.entity.CatalogEntity; diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogHandlerWrapperAuthzTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogHandlerWrapperAuthzTest.java index c0c4495dd..a17091cba 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogHandlerWrapperAuthzTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogHandlerWrapperAuthzTest.java @@ -50,11 +50,11 @@ import org.apache.iceberg.rest.requests.UpdateTableRequest; import org.apache.iceberg.view.ImmutableSQLViewRepresentation; import org.apache.iceberg.view.ImmutableViewVersion; -import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.admin.model.FileStorageConfigInfo; import org.apache.polaris.core.admin.model.PrincipalWithCredentialsCredentials; import org.apache.polaris.core.admin.model.StorageConfigInfo; import org.apache.polaris.core.auth.AuthenticatedPolarisPrincipal; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.context.RealmContext; import org.apache.polaris.core.entity.CatalogEntity; diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/test/PolarisIntegrationTestHelper.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/test/PolarisIntegrationTestHelper.java index 2ca0db58c..714929154 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/test/PolarisIntegrationTestHelper.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/test/PolarisIntegrationTestHelper.java @@ -22,8 +22,8 @@ import jakarta.inject.Inject; import jakarta.inject.Singleton; import java.time.Clock; -import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDiagnostics; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.persistence.MetaStoreManagerFactory; import org.apache.polaris.service.context.RealmContextResolver; import org.junit.jupiter.api.TestInfo; diff --git a/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java b/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java index 477c7f249..b4b6b3d04 100644 --- a/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java +++ b/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java @@ -45,8 +45,6 @@ import org.apache.iceberg.exceptions.NotFoundException; import org.apache.iceberg.exceptions.ValidationException; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.config.FeatureConfiguration; -import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.admin.model.CatalogGrant; import org.apache.polaris.core.admin.model.CatalogPrivilege; @@ -68,6 +66,7 @@ import org.apache.polaris.core.auth.PolarisAuthorizer; import org.apache.polaris.core.auth.PolarisGrantManager.LoadGrantsResult; import org.apache.polaris.core.catalog.PolarisCatalogHelpers; +import org.apache.polaris.core.config.FeatureConfiguration; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.CatalogEntity; import org.apache.polaris.core.entity.CatalogRoleEntity; diff --git a/service/common/src/main/java/org/apache/polaris/service/admin/PolarisServiceImpl.java b/service/common/src/main/java/org/apache/polaris/service/admin/PolarisServiceImpl.java index 249895550..8b92956f8 100644 --- a/service/common/src/main/java/org/apache/polaris/service/admin/PolarisServiceImpl.java +++ b/service/common/src/main/java/org/apache/polaris/service/admin/PolarisServiceImpl.java @@ -27,8 +27,6 @@ import org.apache.iceberg.catalog.TableIdentifier; import org.apache.iceberg.exceptions.NotAuthorizedException; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.config.FeatureConfiguration; -import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.admin.model.AddGrantRequest; import org.apache.polaris.core.admin.model.Catalog; import org.apache.polaris.core.admin.model.CatalogGrant; @@ -59,6 +57,7 @@ import org.apache.polaris.core.admin.model.ViewGrant; import org.apache.polaris.core.auth.AuthenticatedPolarisPrincipal; import org.apache.polaris.core.auth.PolarisAuthorizer; +import org.apache.polaris.core.config.FeatureConfiguration; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.context.RealmContext; import org.apache.polaris.core.entity.CatalogEntity; diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/BasePolarisCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/BasePolarisCatalog.java index 50eca75f2..1874b7e6d 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/BasePolarisCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/BasePolarisCatalog.java @@ -77,10 +77,9 @@ import org.apache.iceberg.view.ViewOperations; import org.apache.iceberg.view.ViewUtil; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.config.FeatureConfiguration; -import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.admin.model.StorageConfigInfo; import org.apache.polaris.core.catalog.PolarisCatalogHelpers; +import org.apache.polaris.core.config.FeatureConfiguration; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.CatalogEntity; import org.apache.polaris.core.entity.NamespaceEntity; diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/IcebergCatalogAdapter.java b/service/common/src/main/java/org/apache/polaris/service/catalog/IcebergCatalogAdapter.java index 7130eb3c9..eb199f0e9 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/IcebergCatalogAdapter.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/IcebergCatalogAdapter.java @@ -55,10 +55,10 @@ import org.apache.iceberg.rest.responses.ConfigResponse; import org.apache.iceberg.rest.responses.ImmutableLoadCredentialsResponse; import org.apache.iceberg.rest.responses.LoadTableResponse; -import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.auth.AuthenticatedPolarisPrincipal; import org.apache.polaris.core.auth.PolarisAuthorizer; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.context.RealmContext; import org.apache.polaris.core.entity.PolarisEntity; diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/PolarisCatalogHandlerWrapper.java b/service/common/src/main/java/org/apache/polaris/service/catalog/PolarisCatalogHandlerWrapper.java index c0e0c99a7..837fb509f 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/PolarisCatalogHandlerWrapper.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/PolarisCatalogHandlerWrapper.java @@ -71,14 +71,13 @@ import org.apache.iceberg.rest.responses.LoadTableResponse; import org.apache.iceberg.rest.responses.LoadViewResponse; import org.apache.iceberg.rest.responses.UpdateNamespacePropertiesResponse; -import org.apache.polaris.core.config.FeatureConfiguration; -import org.apache.polaris.core.config.PolarisConfiguration; -import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.auth.AuthenticatedPolarisPrincipal; import org.apache.polaris.core.auth.PolarisAuthorizableOperation; import org.apache.polaris.core.auth.PolarisAuthorizer; import org.apache.polaris.core.catalog.PolarisCatalogHelpers; +import org.apache.polaris.core.config.FeatureConfiguration; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.CatalogEntity; import org.apache.polaris.core.entity.PolarisEntitySubType; diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java b/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java index 07c01d207..f70c594dd 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java @@ -23,7 +23,6 @@ import java.util.Set; import org.apache.iceberg.catalog.TableIdentifier; import org.apache.polaris.core.config.FeatureConfiguration; -import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.PolarisEntity; diff --git a/service/common/src/main/java/org/apache/polaris/service/context/DefaultCallContextResolver.java b/service/common/src/main/java/org/apache/polaris/service/context/DefaultCallContextResolver.java index 2ee0f15a8..90f381d75 100644 --- a/service/common/src/main/java/org/apache/polaris/service/context/DefaultCallContextResolver.java +++ b/service/common/src/main/java/org/apache/polaris/service/context/DefaultCallContextResolver.java @@ -24,8 +24,8 @@ import java.time.Clock; import java.util.Map; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDiagnostics; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.context.RealmContext; import org.apache.polaris.core.persistence.MetaStoreManagerFactory; diff --git a/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java b/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java index d25f09698..0f63106ac 100644 --- a/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java +++ b/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java @@ -29,10 +29,10 @@ import java.util.Map; import java.util.Set; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.auth.AuthenticatedPolarisPrincipal; import org.apache.polaris.core.auth.PolarisAuthorizer; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.context.RealmContext; import org.apache.polaris.core.entity.PolarisEntity; From d1fe3116eb489391d99815c81f8db4152b804317 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Wed, 5 Mar 2025 12:02:36 -0800 Subject: [PATCH 04/12] some fixes --- .../service/it/test/PolarisApplicationIntegrationTest.java | 5 ++--- .../it/test/PolarisManagementServiceIntegrationTest.java | 5 ++--- .../polaris/service/it/test/PolarisSparkIntegrationTest.java | 5 ++--- quarkus/defaults/src/main/resources/application.properties | 2 -- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisApplicationIntegrationTest.java b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisApplicationIntegrationTest.java index f002db844..3b611d7d1 100644 --- a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisApplicationIntegrationTest.java +++ b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisApplicationIntegrationTest.java @@ -70,7 +70,6 @@ import org.apache.polaris.core.admin.model.PolarisCatalog; import org.apache.polaris.core.admin.model.PrincipalRole; import org.apache.polaris.core.admin.model.StorageConfigInfo; -import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.entity.CatalogEntity; import org.apache.polaris.core.entity.PolarisEntityConstants; import org.apache.polaris.service.it.env.ClientCredentials; @@ -95,10 +94,10 @@ /** * @implSpec This test expects the server to be configured with the following features configured: *
    - *
  • {@link PolarisConfiguration#ALLOW_OVERLAPPING_CATALOG_URLS}: + *
  • {@link org.apache.polaris.core.config.FeatureConfiguration#ALLOW_OVERLAPPING_CATALOG_URLS}: * {@code true} *
  • {@link - * PolarisConfiguration#SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION}: + * org.apache.polaris.core.config.FeatureConfiguration#SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION}: * {@code true} *
* The server must also be configured to reject request body sizes larger than 1MB (1000000 diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisManagementServiceIntegrationTest.java b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisManagementServiceIntegrationTest.java index 4f54c6e82..ba0bce9bb 100644 --- a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisManagementServiceIntegrationTest.java +++ b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisManagementServiceIntegrationTest.java @@ -71,7 +71,6 @@ import org.apache.polaris.core.admin.model.UpdateCatalogRoleRequest; import org.apache.polaris.core.admin.model.UpdatePrincipalRequest; import org.apache.polaris.core.admin.model.UpdatePrincipalRoleRequest; -import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.entity.PolarisEntityConstants; import org.apache.polaris.service.it.env.CatalogApi; import org.apache.polaris.service.it.env.ClientCredentials; @@ -91,10 +90,10 @@ * @implSpec @implSpec This test expects the server to be configured with the following features * configured: *
    - *
  • {@link PolarisConfiguration#ALLOW_OVERLAPPING_CATALOG_URLS}: + *
  • {@link org.apache.polaris.core.config.FeatureConfiguration#ALLOW_OVERLAPPING_CATALOG_URLS}: * {@code true} *
  • {@link - * PolarisConfiguration#ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING}: + * org.apache.polaris.core.config.FeatureConfiguration#ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING}: * {@code true} *
*/ diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisSparkIntegrationTest.java b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisSparkIntegrationTest.java index 96687140d..b58a78b55 100644 --- a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisSparkIntegrationTest.java +++ b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisSparkIntegrationTest.java @@ -40,7 +40,6 @@ import org.apache.polaris.core.admin.model.ExternalCatalog; import org.apache.polaris.core.admin.model.PolarisCatalog; import org.apache.polaris.core.admin.model.StorageConfigInfo; -import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.service.it.env.CatalogApi; import org.apache.polaris.service.it.env.ClientCredentials; import org.apache.polaris.service.it.env.IntegrationTestsHelper; @@ -65,9 +64,9 @@ * @implSpec This test expects the server to be configured with the following features enabled: *
    *
  • {@link - * PolarisConfiguration#SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION}: + * org.apache.polaris.core.config.FeatureConfiguration#SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION}: * {@code true} - *
  • {@link PolarisConfiguration#ALLOW_OVERLAPPING_CATALOG_URLS}: + *
  • {@link org.apache.polaris.core.config.FeatureConfiguration#ALLOW_OVERLAPPING_CATALOG_URLS}: * {@code true} *
*/ diff --git a/quarkus/defaults/src/main/resources/application.properties b/quarkus/defaults/src/main/resources/application.properties index 0c416eeb7..d3a205737 100644 --- a/quarkus/defaults/src/main/resources/application.properties +++ b/quarkus/defaults/src/main/resources/application.properties @@ -95,8 +95,6 @@ polaris.features.defaults."SUPPORTED_CATALOG_STORAGE_TYPES"=["S3","GCS","AZURE", # polaris.features.realm-overrides."my-realm"."INITIALIZE_DEFAULT_CATALOG_FILEIO_FOR_TEST"=true # polaris.features.realm-overrides."my-realm"."SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION"=true -polaris.behavior-changes.defaults."SKIP_PRINTING_BANNER"=true - polaris.persistence.type=in-memory polaris.file-io.type=default From 110744823b45f6a9ffe9598d9a8a077905cbc006 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Wed, 5 Mar 2025 14:05:14 -0800 Subject: [PATCH 05/12] autolint --- .../quarkus/it/QuarkusApplicationIntegrationTest.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusApplicationIntegrationTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusApplicationIntegrationTest.java index 8aaac080e..9509e0fe3 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusApplicationIntegrationTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusApplicationIntegrationTest.java @@ -28,6 +28,7 @@ import java.io.IOException; import java.time.Instant; import java.util.Map; +import javax.inject.Inject; import org.apache.iceberg.rest.HTTPClient; import org.apache.iceberg.rest.RESTClient; import org.apache.iceberg.rest.auth.AuthConfig; @@ -35,12 +36,21 @@ import org.apache.polaris.service.it.env.ClientCredentials; import org.apache.polaris.service.it.env.PolarisApiEndpoints; import org.apache.polaris.service.it.test.PolarisApplicationIntegrationTest; +import org.apache.polaris.service.quarkus.config.QuarkusFeaturesConfiguration; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @QuarkusTest @TestProfile(QuarkusApplicationIntegrationTest.Profile.class) public class QuarkusApplicationIntegrationTest extends PolarisApplicationIntegrationTest { + @Inject QuarkusFeaturesConfiguration featuresConfiguration; + + @BeforeEach + void setup() { + System.out.println("Features Configuration: " + featuresConfiguration.defaults()); + } + public static class Profile implements QuarkusTestProfile { @Override From f21a6213cc6b6844a648fa1c4c9c7d53a3a43c37 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Wed, 5 Mar 2025 14:13:10 -0800 Subject: [PATCH 06/12] style --- .../service/it/test/PolarisApplicationIntegrationTest.java | 3 ++- .../it/test/PolarisManagementServiceIntegrationTest.java | 3 ++- .../service/it/test/PolarisRestCatalogIntegrationTest.java | 4 ++-- .../it/test/PolarisRestCatalogViewIntegrationBase.java | 7 +++---- .../service/it/test/PolarisSparkIntegrationTest.java | 3 ++- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisApplicationIntegrationTest.java b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisApplicationIntegrationTest.java index 3b611d7d1..023924607 100644 --- a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisApplicationIntegrationTest.java +++ b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisApplicationIntegrationTest.java @@ -94,7 +94,8 @@ /** * @implSpec This test expects the server to be configured with the following features configured: *
    - *
  • {@link org.apache.polaris.core.config.FeatureConfiguration#ALLOW_OVERLAPPING_CATALOG_URLS}: + *
  • {@link + * org.apache.polaris.core.config.FeatureConfiguration#ALLOW_OVERLAPPING_CATALOG_URLS}: * {@code true} *
  • {@link * org.apache.polaris.core.config.FeatureConfiguration#SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION}: diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisManagementServiceIntegrationTest.java b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisManagementServiceIntegrationTest.java index ba0bce9bb..d743351d9 100644 --- a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisManagementServiceIntegrationTest.java +++ b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisManagementServiceIntegrationTest.java @@ -90,7 +90,8 @@ * @implSpec @implSpec This test expects the server to be configured with the following features * configured: *
      - *
    • {@link org.apache.polaris.core.config.FeatureConfiguration#ALLOW_OVERLAPPING_CATALOG_URLS}: + *
    • {@link + * org.apache.polaris.core.config.FeatureConfiguration#ALLOW_OVERLAPPING_CATALOG_URLS}: * {@code true} *
    • {@link * org.apache.polaris.core.config.FeatureConfiguration#ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING}: diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationTest.java b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationTest.java index 365c83515..a832553cf 100644 --- a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationTest.java +++ b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationTest.java @@ -58,8 +58,6 @@ import org.apache.iceberg.rest.RESTCatalog; import org.apache.iceberg.rest.responses.ErrorResponse; import org.apache.iceberg.types.Types; -import org.apache.polaris.core.config.FeatureConfiguration; -import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.admin.model.AwsStorageConfigInfo; import org.apache.polaris.core.admin.model.Catalog; import org.apache.polaris.core.admin.model.CatalogGrant; @@ -77,6 +75,8 @@ import org.apache.polaris.core.admin.model.TablePrivilege; import org.apache.polaris.core.admin.model.ViewGrant; import org.apache.polaris.core.admin.model.ViewPrivilege; +import org.apache.polaris.core.config.FeatureConfiguration; +import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.entity.CatalogEntity; import org.apache.polaris.core.entity.PolarisEntityConstants; import org.apache.polaris.service.it.env.CatalogApi; diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogViewIntegrationBase.java b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogViewIntegrationBase.java index 8fa8be6e6..28c38c99e 100644 --- a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogViewIntegrationBase.java +++ b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogViewIntegrationBase.java @@ -24,13 +24,12 @@ import java.util.Map; import org.apache.iceberg.rest.RESTCatalog; import org.apache.iceberg.view.ViewCatalogTests; -import org.apache.polaris.core.config.FeatureConfiguration; -import org.apache.polaris.core.config.PolarisConfiguration; import org.apache.polaris.core.admin.model.Catalog; import org.apache.polaris.core.admin.model.CatalogProperties; import org.apache.polaris.core.admin.model.PolarisCatalog; import org.apache.polaris.core.admin.model.PrincipalWithCredentials; import org.apache.polaris.core.admin.model.StorageConfigInfo; +import org.apache.polaris.core.config.FeatureConfiguration; import org.apache.polaris.core.entity.CatalogEntity; import org.apache.polaris.service.it.env.ClientCredentials; import org.apache.polaris.service.it.env.IcebergHelper; @@ -51,8 +50,8 @@ * client. * * @implSpec This test expects the server to be configured with {@link - * org.apache.polaris.core.config.FeatureConfiguration#SUPPORTED_CATALOG_STORAGE_TYPES} set to the - * appropriate storage type. + * org.apache.polaris.core.config.FeatureConfiguration#SUPPORTED_CATALOG_STORAGE_TYPES} set to + * the appropriate storage type. */ @ExtendWith(PolarisIntegrationTestExtension.class) public abstract class PolarisRestCatalogViewIntegrationBase extends ViewCatalogTests { diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisSparkIntegrationTest.java b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisSparkIntegrationTest.java index b58a78b55..7333baa39 100644 --- a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisSparkIntegrationTest.java +++ b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisSparkIntegrationTest.java @@ -66,7 +66,8 @@ *
    • {@link * org.apache.polaris.core.config.FeatureConfiguration#SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION}: * {@code true} - *
    • {@link org.apache.polaris.core.config.FeatureConfiguration#ALLOW_OVERLAPPING_CATALOG_URLS}: + *
    • {@link + * org.apache.polaris.core.config.FeatureConfiguration#ALLOW_OVERLAPPING_CATALOG_URLS}: * {@code true} *
    */ From b9f2771531d4f5f5f267d5751641b63e018b2086 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Wed, 5 Mar 2025 14:43:48 -0800 Subject: [PATCH 07/12] working with duplicated code --- .../QuarkusBehaviorChangesConfiguration.java | 72 ++++++++++++++++--- .../it/QuarkusApplicationIntegrationTest.java | 11 +-- 2 files changed, 64 insertions(+), 19 deletions(-) diff --git a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusBehaviorChangesConfiguration.java b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusBehaviorChangesConfiguration.java index 23b961ef5..50f197215 100644 --- a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusBehaviorChangesConfiguration.java +++ b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusBehaviorChangesConfiguration.java @@ -18,25 +18,79 @@ */ package org.apache.polaris.service.quarkus.config; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import io.quarkus.runtime.annotations.StaticInitSafe; import io.smallrye.config.ConfigMapping; import io.smallrye.config.WithParentName; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import java.util.Map; import org.apache.polaris.service.config.FeaturesConfiguration; @StaticInitSafe @ConfigMapping(prefix = "polaris.behavior-changes") -public interface QuarkusBehaviorChangesConfiguration extends FeaturesConfiguration { +// FIXME: this should extend FeatureConfiguration, but that causes conflicts with QuarkusFeaturesConfiguration +public interface QuarkusBehaviorChangesConfiguration { + + interface RealmOverrides { + Map overrides(); + } - @Override Map defaults(); - @Override - Map realmOverrides(); + Map realmOverrides(); - interface QuarkusRealmOverrides extends RealmOverrides { - @WithParentName - @Override - Map overrides(); + default Map parseDefaults(ObjectMapper objectMapper) { + return convertMap(objectMapper, defaults()); + } + + default Map> parseRealmOverrides(ObjectMapper objectMapper) { + Map> m = new HashMap<>(); + for (String realm : realmOverrides().keySet()) { + m.put(realm, convertMap(objectMapper, realmOverrides().get(realm).overrides())); + } + return m; + } + + private static Map convertMap( + ObjectMapper objectMapper, Map properties) { + Map m = new HashMap<>(); + for (String configName : properties.keySet()) { + String json = properties.get(configName); + try { + JsonNode node = objectMapper.readTree(json); + m.put(configName, configValue(node)); + } catch (JsonProcessingException e) { + throw new RuntimeException( + "Invalid JSON value for feature configuration: " + configName, e); + } + } + return m; + } + + private static Object configValue(JsonNode node) { + return switch (node.getNodeType()) { + case BOOLEAN -> node.asBoolean(); + case STRING -> node.asText(); + case NUMBER -> + switch (node.numberType()) { + case INT, LONG -> node.asLong(); + case FLOAT, DOUBLE -> node.asDouble(); + default -> + throw new IllegalArgumentException("Unsupported number type: " + node.numberType()); + }; + case ARRAY -> { + List list = new ArrayList<>(); + node.elements().forEachRemaining(n -> list.add(configValue(n))); + yield List.copyOf(list); + } + default -> + throw new IllegalArgumentException( + "Unsupported feature configuration JSON type: " + node.getNodeType()); + }; } -} +} \ No newline at end of file diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusApplicationIntegrationTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusApplicationIntegrationTest.java index 9509e0fe3..aa64c7c1e 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusApplicationIntegrationTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusApplicationIntegrationTest.java @@ -28,7 +28,7 @@ import java.io.IOException; import java.time.Instant; import java.util.Map; -import javax.inject.Inject; + import org.apache.iceberg.rest.HTTPClient; import org.apache.iceberg.rest.RESTClient; import org.apache.iceberg.rest.auth.AuthConfig; @@ -36,21 +36,12 @@ import org.apache.polaris.service.it.env.ClientCredentials; import org.apache.polaris.service.it.env.PolarisApiEndpoints; import org.apache.polaris.service.it.test.PolarisApplicationIntegrationTest; -import org.apache.polaris.service.quarkus.config.QuarkusFeaturesConfiguration; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @QuarkusTest @TestProfile(QuarkusApplicationIntegrationTest.Profile.class) public class QuarkusApplicationIntegrationTest extends PolarisApplicationIntegrationTest { - @Inject QuarkusFeaturesConfiguration featuresConfiguration; - - @BeforeEach - void setup() { - System.out.println("Features Configuration: " + featuresConfiguration.defaults()); - } - public static class Profile implements QuarkusTestProfile { @Override From 4e6333527b28d53a8426d32d9d8aed54d32e3682 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Wed, 5 Mar 2025 14:43:55 -0800 Subject: [PATCH 08/12] autolint --- .../config/QuarkusBehaviorChangesConfiguration.java | 7 +++---- .../quarkus/it/QuarkusApplicationIntegrationTest.java | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusBehaviorChangesConfiguration.java b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusBehaviorChangesConfiguration.java index 50f197215..2a726821d 100644 --- a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusBehaviorChangesConfiguration.java +++ b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusBehaviorChangesConfiguration.java @@ -23,8 +23,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.quarkus.runtime.annotations.StaticInitSafe; import io.smallrye.config.ConfigMapping; -import io.smallrye.config.WithParentName; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -33,7 +31,8 @@ @StaticInitSafe @ConfigMapping(prefix = "polaris.behavior-changes") -// FIXME: this should extend FeatureConfiguration, but that causes conflicts with QuarkusFeaturesConfiguration +// FIXME: this should extend FeatureConfiguration, but that causes conflicts with +// QuarkusFeaturesConfiguration public interface QuarkusBehaviorChangesConfiguration { interface RealmOverrides { @@ -93,4 +92,4 @@ private static Object configValue(JsonNode node) { "Unsupported feature configuration JSON type: " + node.getNodeType()); }; } -} \ No newline at end of file +} diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusApplicationIntegrationTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusApplicationIntegrationTest.java index aa64c7c1e..8aaac080e 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusApplicationIntegrationTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusApplicationIntegrationTest.java @@ -28,7 +28,6 @@ import java.io.IOException; import java.time.Instant; import java.util.Map; - import org.apache.iceberg.rest.HTTPClient; import org.apache.iceberg.rest.RESTClient; import org.apache.iceberg.rest.auth.AuthConfig; From 315a638b188edf0d8edd7ad99fd8c2a47102ccce Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Wed, 5 Mar 2025 14:47:58 -0800 Subject: [PATCH 09/12] working with duplicated code --- .../QuarkusBehaviorChangesConfiguration.java | 4 --- .../config/QuarkusFeaturesConfiguration.java | 8 +---- .../quarkus/config/QuarkusRealmOverrides.java | 29 +++++++++++++++++++ 3 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusRealmOverrides.java diff --git a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusBehaviorChangesConfiguration.java b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusBehaviorChangesConfiguration.java index 2a726821d..852529a0c 100644 --- a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusBehaviorChangesConfiguration.java +++ b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusBehaviorChangesConfiguration.java @@ -35,10 +35,6 @@ // QuarkusFeaturesConfiguration public interface QuarkusBehaviorChangesConfiguration { - interface RealmOverrides { - Map overrides(); - } - Map defaults(); Map realmOverrides(); diff --git a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusFeaturesConfiguration.java b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusFeaturesConfiguration.java index 76ba04968..7d0d417cc 100644 --- a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusFeaturesConfiguration.java +++ b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusFeaturesConfiguration.java @@ -32,11 +32,5 @@ public interface QuarkusFeaturesConfiguration extends FeaturesConfiguration { Map defaults(); @Override - Map realmOverrides(); - - interface QuarkusRealmOverrides extends RealmOverrides { - @WithParentName - @Override - Map overrides(); - } + Map realmOverrides(); } diff --git a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusRealmOverrides.java b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusRealmOverrides.java new file mode 100644 index 000000000..4cfc56d50 --- /dev/null +++ b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusRealmOverrides.java @@ -0,0 +1,29 @@ +/* + * 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.polaris.service.quarkus.config; + +import io.smallrye.config.WithParentName; +import org.apache.polaris.service.config.FeaturesConfiguration; + +import java.util.Map; + +interface QuarkusRealmOverrides { + Map overrides(); +} From ab9c90220e5b800ccb2305957bc81244c2667582 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Wed, 5 Mar 2025 14:48:08 -0800 Subject: [PATCH 10/12] revert --- .../quarkus/config/QuarkusRealmOverrides.java | 29 ------------------- 1 file changed, 29 deletions(-) delete mode 100644 quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusRealmOverrides.java diff --git a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusRealmOverrides.java b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusRealmOverrides.java deleted file mode 100644 index 4cfc56d50..000000000 --- a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusRealmOverrides.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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.polaris.service.quarkus.config; - -import io.smallrye.config.WithParentName; -import org.apache.polaris.service.config.FeaturesConfiguration; - -import java.util.Map; - -interface QuarkusRealmOverrides { - Map overrides(); -} From 41676cd2ca9a39d7df9d20cf25eef7c611867d50 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Wed, 5 Mar 2025 14:50:38 -0800 Subject: [PATCH 11/12] autolint --- .../service/quarkus/config/QuarkusFeaturesConfiguration.java | 1 - 1 file changed, 1 deletion(-) diff --git a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusFeaturesConfiguration.java b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusFeaturesConfiguration.java index 7d0d417cc..85858440a 100644 --- a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusFeaturesConfiguration.java +++ b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusFeaturesConfiguration.java @@ -20,7 +20,6 @@ import io.quarkus.runtime.annotations.StaticInitSafe; import io.smallrye.config.ConfigMapping; -import io.smallrye.config.WithParentName; import java.util.Map; import org.apache.polaris.service.config.FeaturesConfiguration; From f496922146aa27f3292c85f4756d459d15c51cdc Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Wed, 5 Mar 2025 16:00:59 -0800 Subject: [PATCH 12/12] autolint --- .../config/BehaviorChangeConfiguration.java | 7 +++++ .../service/catalog/BasePolarisCatalog.java | 28 +++++++++++++++---- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/polaris-core/src/main/java/org/apache/polaris/core/config/BehaviorChangeConfiguration.java b/polaris-core/src/main/java/org/apache/polaris/core/config/BehaviorChangeConfiguration.java index 80b4377e1..b6d4299ea 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/config/BehaviorChangeConfiguration.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/config/BehaviorChangeConfiguration.java @@ -34,4 +34,11 @@ protected BehaviorChangeConfiguration( String key, String description, T defaultValue, Optional catalogConfig) { super(key, description, defaultValue, catalogConfig); } + + public static final BehaviorChangeConfiguration VALIDATE_VIEW_LOCATION_OVERLAP = + PolarisConfiguration.builder() + .key("STORAGE_CREDENTIAL_CACHE_DURATION_SECONDS") + .description("If true, validate that view locations don't overlap when views are created") + .defaultValue(true) + .buildBehaviorChangeConfiguration(); } diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/BasePolarisCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/BasePolarisCatalog.java index 1874b7e6d..01b2fbdd4 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/BasePolarisCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/BasePolarisCatalog.java @@ -79,6 +79,7 @@ import org.apache.polaris.core.PolarisCallContext; import org.apache.polaris.core.admin.model.StorageConfigInfo; import org.apache.polaris.core.catalog.PolarisCatalogHelpers; +import org.apache.polaris.core.config.BehaviorChangeConfiguration; import org.apache.polaris.core.config.FeatureConfiguration; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.CatalogEntity; @@ -1054,7 +1055,16 @@ private void validateNoLocationOverlap( CatalogEntity catalog, TableIdentifier identifier, List resolvedNamespace, - String location) { + String location, + PolarisEntity entity) { + boolean validateViewOverlap = + callContext + .getPolarisCallContext() + .getConfigurationStore() + .getConfiguration( + callContext.getPolarisCallContext(), + BehaviorChangeConfiguration.VALIDATE_VIEW_LOCATION_OVERLAP); + if (callContext .getPolarisCallContext() .getConfigurationStore() @@ -1063,9 +1073,7 @@ private void validateNoLocationOverlap( catalog, FeatureConfiguration.ALLOW_TABLE_LOCATION_OVERLAP)) { LOGGER.debug("Skipping location overlap validation for identifier '{}'", identifier); - } else { // if (entity.getSubType().equals(PolarisEntitySubType.TABLE)) { - // TODO - is this necessary for views? overlapping views do not expose subdirectories via the - // credential vending so this feels like an unnecessary restriction + } else if (validateViewOverlap || entity.getSubType().equals(PolarisEntitySubType.TABLE)) { LOGGER.debug("Validating no overlap with sibling tables or namespaces"); validateNoLocationOverlap(location, resolvedNamespace, identifier.name()); } @@ -1343,7 +1351,11 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { dataLocations.forEach( location -> validateNoLocationOverlap( - catalogEntity, tableIdentifier, resolvedNamespace, location)); + catalogEntity, + tableIdentifier, + resolvedNamespace, + location, + resolvedStorageEntity.getRawLeafEntity())); // and that the metadata file points to a location within the table's directory structure if (metadata.metadataFileLocation() != null) { validateMetadataFileInTableDir(tableIdentifier, metadata, catalog); @@ -1542,7 +1554,11 @@ public void doCommit(ViewMetadata base, ViewMetadata metadata) { // for the storage configuration inherited under this entity's path. validateLocationForTableLike(identifier, metadata.location(), resolvedStorageEntity); validateNoLocationOverlap( - catalogEntity, identifier, resolvedNamespace, metadata.location()); + catalogEntity, + identifier, + resolvedNamespace, + metadata.location(), + resolvedStorageEntity.getRawLeafEntity()); } Map tableProperties = new HashMap<>(metadata.properties());