From dd8bd8961fad4151746896000ff9f2764b697b09 Mon Sep 17 00:00:00 2001 From: Pooja Nilangekar Date: Tue, 24 Jun 2025 14:32:24 -0700 Subject: [PATCH 1/5] Add SUPPORTED_FEDERATION_AUTHENTICATION_TYPES feature configuration --- .../core/config/FeatureConfiguration.java | 11 ++++ .../src/main/resources/application.properties | 1 + .../service/admin/PolarisServiceImpl.java | 59 +++++++++++++------ 3 files changed, 53 insertions(+), 18 deletions(-) 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 fe265c3072..b1ff6ca5a1 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 @@ -20,6 +20,7 @@ import java.util.List; import java.util.Optional; +import org.apache.polaris.core.admin.model.AuthenticationParameters; import org.apache.polaris.core.admin.model.StorageConfigInfo; import org.apache.polaris.core.connection.ConnectionType; import org.apache.polaris.core.context.CallContext; @@ -261,6 +262,16 @@ public static void enforceFeatureEnabledOrThrow( .defaultValue(List.of(ConnectionType.ICEBERG_REST.name())) .buildFeatureConfiguration(); + public static final FeatureConfiguration> SUPPORTED_FEDERATION_AUTHENTICATION_TYPES = + PolarisConfiguration.>builder() + .key("SUPPORTED_FEDERATION_AUTHENTICATION_TYPES") + .description("The list of supported authentication types for catalog federation") + .defaultValue( + List.of( + AuthenticationParameters.AuthenticationTypeEnum.OAUTH.name(), + AuthenticationParameters.AuthenticationTypeEnum.BEARER.name())) + .buildFeatureConfiguration(); + public static final FeatureConfiguration ICEBERG_COMMIT_MAX_RETRIES = PolarisConfiguration.builder() .key("ICEBERG_COMMIT_MAX_RETRIES") diff --git a/runtime/defaults/src/main/resources/application.properties b/runtime/defaults/src/main/resources/application.properties index 592501f76d..4e9532dd83 100644 --- a/runtime/defaults/src/main/resources/application.properties +++ b/runtime/defaults/src/main/resources/application.properties @@ -112,6 +112,7 @@ polaris.features."ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING"=false polaris.features."SUPPORTED_CATALOG_STORAGE_TYPES"=["S3","GCS","AZURE"] # polaris.features."ENABLE_CATALOG_FEDERATION"=true polaris.features."SUPPORTED_CATALOG_CONNECTION_TYPES"=["ICEBERG_REST"] +polaris.features."SUPPORTED_FEDERATION_AUTHENTICATION_TYPES"=["OAUTH", "BEARER"] # realm overrides # polaris.features.realm-overrides."my-realm"."SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION"=true 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 719e6d44b0..6dec152ced 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 @@ -29,11 +29,13 @@ import org.apache.iceberg.exceptions.NotAuthorizedException; import org.apache.polaris.core.PolarisCallContext; import org.apache.polaris.core.admin.model.AddGrantRequest; +import org.apache.polaris.core.admin.model.AuthenticationParameters; import org.apache.polaris.core.admin.model.Catalog; import org.apache.polaris.core.admin.model.CatalogGrant; import org.apache.polaris.core.admin.model.CatalogRole; import org.apache.polaris.core.admin.model.CatalogRoles; import org.apache.polaris.core.admin.model.Catalogs; +import org.apache.polaris.core.admin.model.ConnectionConfigInfo; import org.apache.polaris.core.admin.model.CreateCatalogRequest; import org.apache.polaris.core.admin.model.CreateCatalogRoleRequest; import org.apache.polaris.core.admin.model.CreatePrincipalRequest; @@ -145,7 +147,7 @@ public Response createCatalog( PolarisAdminService adminService = newAdminService(realmContext, securityContext); Catalog catalog = request.getCatalog(); validateStorageConfig(catalog.getStorageConfigInfo()); - validateConnectionConfigInfo(catalog); + validateExternalCatalog(catalog); Catalog newCatalog = new CatalogEntity(adminService.createCatalog(request)).asCatalog(); LOGGER.info("Created new catalog {}", newCatalog); return Response.status(Response.Status.CREATED).build(); @@ -169,30 +171,51 @@ private void validateStorageConfig(StorageConfigInfo storageConfigInfo) { } } - private void validateConnectionConfigInfo(Catalog catalog) { + private void validateExternalCatalog(Catalog catalog) { if (catalog.getType() == Catalog.TypeEnum.EXTERNAL) { if (catalog instanceof ExternalCatalog externalCatalog) { - if (externalCatalog.getConnectionConfigInfo() != null) { - String connectionType = - externalCatalog.getConnectionConfigInfo().getConnectionType().name(); - List supportedConnectionTypes = - callContext - .getPolarisCallContext() - .getConfigurationStore() - .getConfiguration( - callContext.getRealmContext(), - FeatureConfiguration.SUPPORTED_CATALOG_CONNECTION_TYPES) - .stream() - .map(s -> s.toUpperCase(Locale.ROOT)) - .toList(); - if (!supportedConnectionTypes.contains(connectionType)) { - throw new IllegalStateException("Unsupported connection type: " + connectionType); - } + ConnectionConfigInfo connectionConfigInfo = externalCatalog.getConnectionConfigInfo(); + if (connectionConfigInfo != null) { + validateConnectionConfigInfo(connectionConfigInfo); + validateAuthenticationParameters(connectionConfigInfo.getAuthenticationParameters()); } } } } + private void validateConnectionConfigInfo(ConnectionConfigInfo connectionConfigInfo) { + + String connectionType = connectionConfigInfo.getConnectionType().name(); + List supportedConnectionTypes = + callContext + .getPolarisCallContext() + .getConfigurationStore() + .getConfiguration( + callContext.getRealmContext(), + FeatureConfiguration.SUPPORTED_CATALOG_CONNECTION_TYPES) + .stream() + .map(s -> s.toUpperCase(Locale.ROOT)) + .toList(); + if (!supportedConnectionTypes.contains(connectionType)) { + throw new IllegalStateException("Unsupported connection type: " + connectionType); + } + } + + private void validateAuthenticationParameters(AuthenticationParameters authenticationParameters) { + + String authenticationType = authenticationParameters.getAuthenticationType().name(); + List supportedAuthenticationTypes = + callContext + .getPolarisCallContext() + .getConfigurationStore() + .getConfiguration( + callContext.getRealmContext(), + FeatureConfiguration.SUPPORTED_FEDERATION_AUTHENTICATION_TYPES); + if (!supportedAuthenticationTypes.contains(authenticationType)) { + throw new IllegalStateException("Unsupported authentication type: " + authenticationType); + } + } + /** From PolarisCatalogsApiService */ @Override public Response deleteCatalog( From 4450b4b253688320914bc4e8cb51a2143d68a219 Mon Sep 17 00:00:00 2001 From: Pooja Nilangekar Date: Wed, 25 Jun 2025 11:09:57 -0700 Subject: [PATCH 2/5] Add unit tests --- .../src/main/resources/application.properties | 1 - .../service/admin/PolarisServiceImplTest.java | 239 ++++++++++++++++++ 2 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 service/common/src/test/java/org/apache/polaris/service/admin/PolarisServiceImplTest.java diff --git a/runtime/defaults/src/main/resources/application.properties b/runtime/defaults/src/main/resources/application.properties index 4e9532dd83..592501f76d 100644 --- a/runtime/defaults/src/main/resources/application.properties +++ b/runtime/defaults/src/main/resources/application.properties @@ -112,7 +112,6 @@ polaris.features."ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING"=false polaris.features."SUPPORTED_CATALOG_STORAGE_TYPES"=["S3","GCS","AZURE"] # polaris.features."ENABLE_CATALOG_FEDERATION"=true polaris.features."SUPPORTED_CATALOG_CONNECTION_TYPES"=["ICEBERG_REST"] -polaris.features."SUPPORTED_FEDERATION_AUTHENTICATION_TYPES"=["OAUTH", "BEARER"] # realm overrides # polaris.features.realm-overrides."my-realm"."SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION"=true diff --git a/service/common/src/test/java/org/apache/polaris/service/admin/PolarisServiceImplTest.java b/service/common/src/test/java/org/apache/polaris/service/admin/PolarisServiceImplTest.java new file mode 100644 index 0000000000..6b3c276459 --- /dev/null +++ b/service/common/src/test/java/org/apache/polaris/service/admin/PolarisServiceImplTest.java @@ -0,0 +1,239 @@ +/* + * 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.admin; + +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.when; + +import java.lang.reflect.Method; +import java.util.List; +import org.apache.polaris.core.PolarisCallContext; +import org.apache.polaris.core.admin.model.AuthenticationParameters; +import org.apache.polaris.core.admin.model.Catalog; +import org.apache.polaris.core.admin.model.CatalogProperties; +import org.apache.polaris.core.admin.model.ConnectionConfigInfo; +import org.apache.polaris.core.admin.model.ExternalCatalog; +import org.apache.polaris.core.admin.model.FileStorageConfigInfo; +import org.apache.polaris.core.admin.model.PolarisCatalog; +import org.apache.polaris.core.admin.model.StorageConfigInfo; +import org.apache.polaris.core.auth.PolarisAuthorizer; +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.persistence.MetaStoreManagerFactory; +import org.apache.polaris.core.secrets.UserSecretsManagerFactory; +import org.apache.polaris.service.config.RealmEntityManagerFactory; +import org.apache.polaris.service.config.ReservedProperties; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.Mockito; + +public class PolarisServiceImplTest { + + @Mock private RealmEntityManagerFactory entityManagerFactory; + @Mock private MetaStoreManagerFactory metaStoreManagerFactory; + @Mock private UserSecretsManagerFactory userSecretsManagerFactory; + @Mock private PolarisAuthorizer polarisAuthorizer; + @Mock private CallContext callContext; + @Mock private ReservedProperties reservedProperties; + @Mock private PolarisCallContext polarisCallContext; + @Mock private PolarisConfigurationStore configurationStore; + @Mock private RealmContext realmContext; + + private PolarisServiceImpl polarisService; + + @BeforeEach + void setUp() { + entityManagerFactory = Mockito.mock(RealmEntityManagerFactory.class); + metaStoreManagerFactory = Mockito.mock(MetaStoreManagerFactory.class); + userSecretsManagerFactory = Mockito.mock(UserSecretsManagerFactory.class); + polarisAuthorizer = Mockito.mock(PolarisAuthorizer.class); + callContext = Mockito.mock(CallContext.class); + reservedProperties = Mockito.mock(ReservedProperties.class); + polarisCallContext = Mockito.mock(PolarisCallContext.class); + configurationStore = Mockito.mock(PolarisConfigurationStore.class); + realmContext = Mockito.mock(RealmContext.class); + + when(callContext.getPolarisCallContext()).thenReturn(polarisCallContext); + when(callContext.getRealmContext()).thenReturn(realmContext); + when(polarisCallContext.getConfigurationStore()).thenReturn(configurationStore); + when(configurationStore.getConfiguration( + realmContext, FeatureConfiguration.SUPPORTED_CATALOG_CONNECTION_TYPES)) + .thenReturn(List.of("ICEBERG_REST")); + when(configurationStore.getConfiguration( + realmContext, FeatureConfiguration.SUPPORTED_FEDERATION_AUTHENTICATION_TYPES)) + .thenReturn(List.of("OAUTH")); + + polarisService = + new PolarisServiceImpl( + entityManagerFactory, + metaStoreManagerFactory, + userSecretsManagerFactory, + polarisAuthorizer, + callContext, + reservedProperties); + } + + @Test + void testValidateExternalCatalog_InternalCatalog() { + StorageConfigInfo storageConfig = + FileStorageConfigInfo.builder(StorageConfigInfo.StorageTypeEnum.FILE) + .setAllowedLocations(List.of("file://tmp")) + .build(); + + PolarisCatalog internalCatalog = + PolarisCatalog.builder() + .setType(Catalog.TypeEnum.INTERNAL) + .setName("test-catalog") + .setProperties(new CatalogProperties("file://tmp")) + .setStorageConfigInfo(storageConfig) + .build(); + + assertThatCode(() -> invokeValidateExternalCatalog(polarisService, internalCatalog)) + .doesNotThrowAnyException(); + } + + @Test + void testValidateExternalCatalog_LegacyExternalCatalog() { + StorageConfigInfo storageConfig = + FileStorageConfigInfo.builder(StorageConfigInfo.StorageTypeEnum.FILE) + .setAllowedLocations(List.of("file://tmp")) + .build(); + ExternalCatalog externalCatalog = + ExternalCatalog.builder() + .setType(Catalog.TypeEnum.EXTERNAL) + .setName("test-catalog") + .setProperties(new CatalogProperties("file://tmp")) + .setStorageConfigInfo(storageConfig) + .setConnectionConfigInfo(null) + .build(); + + assertThatCode(() -> invokeValidateExternalCatalog(polarisService, externalCatalog)) + .doesNotThrowAnyException(); + } + + @Test + void testValidateExternalCatalog_SupportedExternalCatalog() { + StorageConfigInfo storageConfig = + FileStorageConfigInfo.builder(StorageConfigInfo.StorageTypeEnum.FILE) + .setAllowedLocations(List.of("file://tmp")) + .build(); + + ConnectionConfigInfo connectionConfigInfo = Mockito.mock(ConnectionConfigInfo.class); + AuthenticationParameters authenticationParameters = + Mockito.mock(AuthenticationParameters.class); + when(connectionConfigInfo.getConnectionType()) + .thenReturn(ConnectionConfigInfo.ConnectionTypeEnum.ICEBERG_REST); + when(connectionConfigInfo.getAuthenticationParameters()).thenReturn(authenticationParameters); + when(authenticationParameters.getAuthenticationType()) + .thenReturn(AuthenticationParameters.AuthenticationTypeEnum.OAUTH); + + ExternalCatalog externalCatalog = + ExternalCatalog.builder() + .setType(Catalog.TypeEnum.EXTERNAL) + .setName("test-catalog") + .setProperties(new CatalogProperties("file://tmp")) + .setStorageConfigInfo(storageConfig) + .setConnectionConfigInfo(connectionConfigInfo) + .build(); + + assertThatCode(() -> invokeValidateExternalCatalog(polarisService, externalCatalog)) + .doesNotThrowAnyException(); + } + + @Test + void testValidateExternalCatalog_UnsupportedConnectionType() { + StorageConfigInfo storageConfig = + FileStorageConfigInfo.builder(StorageConfigInfo.StorageTypeEnum.FILE) + .setAllowedLocations(List.of("file://tmp")) + .build(); + + ConnectionConfigInfo connectionConfigInfo = Mockito.mock(ConnectionConfigInfo.class); + AuthenticationParameters authenticationParameters = + Mockito.mock(AuthenticationParameters.class); + when(connectionConfigInfo.getConnectionType()) + .thenReturn(ConnectionConfigInfo.ConnectionTypeEnum.HADOOP); + when(connectionConfigInfo.getAuthenticationParameters()).thenReturn(authenticationParameters); + when(authenticationParameters.getAuthenticationType()) + .thenReturn(AuthenticationParameters.AuthenticationTypeEnum.OAUTH); + + ExternalCatalog externalCatalog = + ExternalCatalog.builder() + .setType(Catalog.TypeEnum.EXTERNAL) + .setName("test-catalog") + .setProperties(new CatalogProperties("file://tmp")) + .setStorageConfigInfo(storageConfig) + .setConnectionConfigInfo(connectionConfigInfo) + .build(); + + assertThatThrownBy(() -> invokeValidateExternalCatalog(polarisService, externalCatalog)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Unsupported connection type: HADOOP"); + } + + @Test + void testValidateExternalCatalog_UnsupportedAuthenticationType() { + StorageConfigInfo storageConfig = + FileStorageConfigInfo.builder(StorageConfigInfo.StorageTypeEnum.FILE) + .setAllowedLocations(List.of("file://tmp")) + .build(); + + ConnectionConfigInfo connectionConfigInfo = Mockito.mock(ConnectionConfigInfo.class); + AuthenticationParameters authenticationParameters = + Mockito.mock(AuthenticationParameters.class); + when(connectionConfigInfo.getConnectionType()) + .thenReturn(ConnectionConfigInfo.ConnectionTypeEnum.ICEBERG_REST); + when(connectionConfigInfo.getAuthenticationParameters()).thenReturn(authenticationParameters); + when(authenticationParameters.getAuthenticationType()) + .thenReturn(AuthenticationParameters.AuthenticationTypeEnum.BEARER); + + ExternalCatalog externalCatalog = + ExternalCatalog.builder() + .setType(Catalog.TypeEnum.EXTERNAL) + .setName("test-catalog") + .setProperties(new CatalogProperties("file://tmp")) + .setStorageConfigInfo(storageConfig) + .setConnectionConfigInfo(connectionConfigInfo) + .build(); + + assertThatThrownBy(() -> invokeValidateExternalCatalog(polarisService, externalCatalog)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Unsupported authentication type: BEARER"); + } + + private void invokeValidateExternalCatalog(PolarisServiceImpl service, Catalog catalog) + throws Exception { + Method method = + PolarisServiceImpl.class.getDeclaredMethod("validateExternalCatalog", Catalog.class); + method.setAccessible(true); + try { + method.invoke(service, catalog); + } catch (java.lang.reflect.InvocationTargetException e) { + Throwable cause = e.getCause(); + if (cause instanceof Exception) { + throw (Exception) cause; + } else { + throw e; + } + } + } +} From 3f8761da4c465f8b30351bcfada2b56179ca875a Mon Sep 17 00:00:00 2001 From: Pooja Nilangekar Date: Wed, 25 Jun 2025 13:05:06 -0700 Subject: [PATCH 3/5] Rename to --- .../core/config/FeatureConfiguration.java | 32 ++++++++++--------- .../src/main/resources/application.properties | 3 +- .../service/admin/PolarisServiceImpl.java | 7 ++-- .../service/admin/PolarisServiceImplTest.java | 4 +-- 4 files changed, 26 insertions(+), 20 deletions(-) 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 b1ff6ca5a1..c4731d121c 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 @@ -255,22 +255,24 @@ public static void enforceFeatureEnabledOrThrow( .defaultValue(true) .buildFeatureConfiguration(); - public static final FeatureConfiguration> SUPPORTED_CATALOG_CONNECTION_TYPES = - PolarisConfiguration.>builder() - .key("SUPPORTED_CATALOG_CONNECTION_TYPES") - .description("The list of supported catalog connection types for federation") - .defaultValue(List.of(ConnectionType.ICEBERG_REST.name())) - .buildFeatureConfiguration(); + public static final FeatureConfiguration> + SUPPORTED_EXTERNAL_CATALOG_CONNECTION_TYPES = + PolarisConfiguration.>builder() + .key("SUPPORTED_EXTERNAL_CATALOG_CONNECTION_TYPES") + .description("The list of supported catalog connection types for federation") + .defaultValue(List.of(ConnectionType.ICEBERG_REST.name())) + .buildFeatureConfiguration(); - public static final FeatureConfiguration> SUPPORTED_FEDERATION_AUTHENTICATION_TYPES = - PolarisConfiguration.>builder() - .key("SUPPORTED_FEDERATION_AUTHENTICATION_TYPES") - .description("The list of supported authentication types for catalog federation") - .defaultValue( - List.of( - AuthenticationParameters.AuthenticationTypeEnum.OAUTH.name(), - AuthenticationParameters.AuthenticationTypeEnum.BEARER.name())) - .buildFeatureConfiguration(); + public static final FeatureConfiguration> + SUPPORTED_EXTERNAL_CATALOG_AUTHENTICATION_TYPES = + PolarisConfiguration.>builder() + .key("SUPPORTED_EXTERNAL_CATALOG_AUTHENTICATION_TYPES") + .description("The list of supported authentication types for catalog federation") + .defaultValue( + List.of( + AuthenticationParameters.AuthenticationTypeEnum.OAUTH.name(), + AuthenticationParameters.AuthenticationTypeEnum.BEARER.name())) + .buildFeatureConfiguration(); public static final FeatureConfiguration ICEBERG_COMMIT_MAX_RETRIES = PolarisConfiguration.builder() diff --git a/runtime/defaults/src/main/resources/application.properties b/runtime/defaults/src/main/resources/application.properties index 592501f76d..133b782505 100644 --- a/runtime/defaults/src/main/resources/application.properties +++ b/runtime/defaults/src/main/resources/application.properties @@ -111,7 +111,8 @@ polaris.realm-context.require-header=false polaris.features."ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING"=false polaris.features."SUPPORTED_CATALOG_STORAGE_TYPES"=["S3","GCS","AZURE"] # polaris.features."ENABLE_CATALOG_FEDERATION"=true -polaris.features."SUPPORTED_CATALOG_CONNECTION_TYPES"=["ICEBERG_REST"] +polaris.features."SUPPORTED_EXTERNAL_CATALOG_CONNECTION_TYPES"=["ICEBERG_REST"] +polaris.features."SUPPORTED_EXTERNAL_CATALOG_AUTHENTICATION_TYPES"=["OAUTH", "BEARER"] # realm overrides # polaris.features.realm-overrides."my-realm"."SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION"=true 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 6dec152ced..a3e7c19f6c 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 @@ -192,7 +192,7 @@ private void validateConnectionConfigInfo(ConnectionConfigInfo connectionConfigI .getConfigurationStore() .getConfiguration( callContext.getRealmContext(), - FeatureConfiguration.SUPPORTED_CATALOG_CONNECTION_TYPES) + FeatureConfiguration.SUPPORTED_EXTERNAL_CATALOG_CONNECTION_TYPES) .stream() .map(s -> s.toUpperCase(Locale.ROOT)) .toList(); @@ -210,7 +210,10 @@ private void validateAuthenticationParameters(AuthenticationParameters authentic .getConfigurationStore() .getConfiguration( callContext.getRealmContext(), - FeatureConfiguration.SUPPORTED_FEDERATION_AUTHENTICATION_TYPES); + FeatureConfiguration.SUPPORTED_EXTERNAL_CATALOG_AUTHENTICATION_TYPES) + .stream() + .map(s -> s.toUpperCase(Locale.ROOT)) + .toList(); if (!supportedAuthenticationTypes.contains(authenticationType)) { throw new IllegalStateException("Unsupported authentication type: " + authenticationType); } diff --git a/service/common/src/test/java/org/apache/polaris/service/admin/PolarisServiceImplTest.java b/service/common/src/test/java/org/apache/polaris/service/admin/PolarisServiceImplTest.java index 6b3c276459..51f33c7c1e 100644 --- a/service/common/src/test/java/org/apache/polaris/service/admin/PolarisServiceImplTest.java +++ b/service/common/src/test/java/org/apache/polaris/service/admin/PolarisServiceImplTest.java @@ -77,10 +77,10 @@ void setUp() { when(callContext.getRealmContext()).thenReturn(realmContext); when(polarisCallContext.getConfigurationStore()).thenReturn(configurationStore); when(configurationStore.getConfiguration( - realmContext, FeatureConfiguration.SUPPORTED_CATALOG_CONNECTION_TYPES)) + realmContext, FeatureConfiguration.SUPPORTED_EXTERNAL_CATALOG_CONNECTION_TYPES)) .thenReturn(List.of("ICEBERG_REST")); when(configurationStore.getConfiguration( - realmContext, FeatureConfiguration.SUPPORTED_FEDERATION_AUTHENTICATION_TYPES)) + realmContext, FeatureConfiguration.SUPPORTED_EXTERNAL_CATALOG_AUTHENTICATION_TYPES)) .thenReturn(List.of("OAUTH")); polarisService = From 72de204a65a4f964c878d4b8a7169cd8dc6d9d26 Mon Sep 17 00:00:00 2001 From: Pooja Nilangekar Date: Thu, 26 Jun 2025 09:44:45 -0700 Subject: [PATCH 4/5] Remove CONNECTION_TYPES change --- .../polaris/core/config/FeatureConfiguration.java | 13 ++++++------- .../src/main/resources/application.properties | 2 +- .../polaris/service/admin/PolarisServiceImpl.java | 2 +- .../service/admin/PolarisServiceImplTest.java | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) 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 c4731d121c..d44585a0ef 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 @@ -255,13 +255,12 @@ public static void enforceFeatureEnabledOrThrow( .defaultValue(true) .buildFeatureConfiguration(); - public static final FeatureConfiguration> - SUPPORTED_EXTERNAL_CATALOG_CONNECTION_TYPES = - PolarisConfiguration.>builder() - .key("SUPPORTED_EXTERNAL_CATALOG_CONNECTION_TYPES") - .description("The list of supported catalog connection types for federation") - .defaultValue(List.of(ConnectionType.ICEBERG_REST.name())) - .buildFeatureConfiguration(); + public static final FeatureConfiguration> SUPPORTED_CATALOG_CONNECTION_TYPES = + PolarisConfiguration.>builder() + .key("SUPPORTED_CATALOG_CONNECTION_TYPES") + .description("The list of supported catalog connection types for federation") + .defaultValue(List.of(ConnectionType.ICEBERG_REST.name())) + .buildFeatureConfiguration(); public static final FeatureConfiguration> SUPPORTED_EXTERNAL_CATALOG_AUTHENTICATION_TYPES = diff --git a/runtime/defaults/src/main/resources/application.properties b/runtime/defaults/src/main/resources/application.properties index 133b782505..d88df31d4d 100644 --- a/runtime/defaults/src/main/resources/application.properties +++ b/runtime/defaults/src/main/resources/application.properties @@ -111,7 +111,7 @@ polaris.realm-context.require-header=false polaris.features."ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING"=false polaris.features."SUPPORTED_CATALOG_STORAGE_TYPES"=["S3","GCS","AZURE"] # polaris.features."ENABLE_CATALOG_FEDERATION"=true -polaris.features."SUPPORTED_EXTERNAL_CATALOG_CONNECTION_TYPES"=["ICEBERG_REST"] +polaris.features."SUPPORTED_CATALOG_CONNECTION_TYPES"=["ICEBERG_REST"] polaris.features."SUPPORTED_EXTERNAL_CATALOG_AUTHENTICATION_TYPES"=["OAUTH", "BEARER"] # realm overrides 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 a3e7c19f6c..071e6b61aa 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 @@ -192,7 +192,7 @@ private void validateConnectionConfigInfo(ConnectionConfigInfo connectionConfigI .getConfigurationStore() .getConfiguration( callContext.getRealmContext(), - FeatureConfiguration.SUPPORTED_EXTERNAL_CATALOG_CONNECTION_TYPES) + FeatureConfiguration.SUPPORTED_CATALOG_CONNECTION_TYPES) .stream() .map(s -> s.toUpperCase(Locale.ROOT)) .toList(); diff --git a/service/common/src/test/java/org/apache/polaris/service/admin/PolarisServiceImplTest.java b/service/common/src/test/java/org/apache/polaris/service/admin/PolarisServiceImplTest.java index 51f33c7c1e..cfef5e8c51 100644 --- a/service/common/src/test/java/org/apache/polaris/service/admin/PolarisServiceImplTest.java +++ b/service/common/src/test/java/org/apache/polaris/service/admin/PolarisServiceImplTest.java @@ -77,7 +77,7 @@ void setUp() { when(callContext.getRealmContext()).thenReturn(realmContext); when(polarisCallContext.getConfigurationStore()).thenReturn(configurationStore); when(configurationStore.getConfiguration( - realmContext, FeatureConfiguration.SUPPORTED_EXTERNAL_CATALOG_CONNECTION_TYPES)) + realmContext, FeatureConfiguration.SUPPORTED_CATALOG_CONNECTION_TYPES)) .thenReturn(List.of("ICEBERG_REST")); when(configurationStore.getConfiguration( realmContext, FeatureConfiguration.SUPPORTED_EXTERNAL_CATALOG_AUTHENTICATION_TYPES)) From 3db6ed8b15348530f8873b7fe5280cac8b870ea1 Mon Sep 17 00:00:00 2001 From: Pooja Nilangekar Date: Thu, 26 Jun 2025 11:39:09 -0700 Subject: [PATCH 5/5] Remove @Mock annotations in the test --- .../service/admin/PolarisServiceImplTest.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/service/common/src/test/java/org/apache/polaris/service/admin/PolarisServiceImplTest.java b/service/common/src/test/java/org/apache/polaris/service/admin/PolarisServiceImplTest.java index cfef5e8c51..fab1d7da41 100644 --- a/service/common/src/test/java/org/apache/polaris/service/admin/PolarisServiceImplTest.java +++ b/service/common/src/test/java/org/apache/polaris/service/admin/PolarisServiceImplTest.java @@ -44,20 +44,19 @@ import org.apache.polaris.service.config.ReservedProperties; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.mockito.Mock; import org.mockito.Mockito; public class PolarisServiceImplTest { - @Mock private RealmEntityManagerFactory entityManagerFactory; - @Mock private MetaStoreManagerFactory metaStoreManagerFactory; - @Mock private UserSecretsManagerFactory userSecretsManagerFactory; - @Mock private PolarisAuthorizer polarisAuthorizer; - @Mock private CallContext callContext; - @Mock private ReservedProperties reservedProperties; - @Mock private PolarisCallContext polarisCallContext; - @Mock private PolarisConfigurationStore configurationStore; - @Mock private RealmContext realmContext; + private RealmEntityManagerFactory entityManagerFactory; + private MetaStoreManagerFactory metaStoreManagerFactory; + private UserSecretsManagerFactory userSecretsManagerFactory; + private PolarisAuthorizer polarisAuthorizer; + private CallContext callContext; + private ReservedProperties reservedProperties; + private PolarisCallContext polarisCallContext; + private PolarisConfigurationStore configurationStore; + private RealmContext realmContext; private PolarisServiceImpl polarisService;