diff --git a/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/DatasourceOperations.java b/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/DatasourceOperations.java index 66ee8f9710..a8a854ad4e 100644 --- a/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/DatasourceOperations.java +++ b/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/DatasourceOperations.java @@ -32,7 +32,6 @@ import java.util.List; import java.util.Objects; import java.util.function.Consumer; -import java.util.function.Function; import java.util.stream.Stream; import javax.sql.DataSource; import org.apache.polaris.extension.persistence.relational.jdbc.models.Converter; @@ -96,20 +95,14 @@ public void executeScript(String scriptFilePath) throws SQLException { * @param query : Query to executed * @param converterInstance : An instance of the type being selected, used to convert to a * business entity like PolarisBaseEntity - * @param transformer Transformation of entity class to Result class * @return The list of results yielded by the query - * @param : Persistence entity class - * @param : Business entity class + * @param : Business entity class * @throws SQLException : Exception during the query execution. */ - public List executeSelect( - @Nonnull String query, - @Nonnull Converter converterInstance, - @Nonnull Function transformer) + public List executeSelect(@Nonnull String query, @Nonnull Converter converterInstance) throws SQLException { - ArrayList results = new ArrayList<>(); - executeSelectOverStream( - query, converterInstance, stream -> stream.map(transformer).forEach(results::add)); + ArrayList results = new ArrayList<>(); + executeSelectOverStream(query, converterInstance, stream -> stream.forEach(results::add)); return results; } diff --git a/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/JdbcBasePersistenceImpl.java b/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/JdbcBasePersistenceImpl.java index cd6a0b6c07..e229100fe2 100644 --- a/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/JdbcBasePersistenceImpl.java +++ b/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/JdbcBasePersistenceImpl.java @@ -299,8 +299,7 @@ public PolarisBaseEntity lookupEntityByName( @Nullable private PolarisBaseEntity getPolarisBaseEntity(String query) { try { - List results = - datasourceOperations.executeSelect(query, new ModelEntity(), ModelEntity::toEntity); + var results = datasourceOperations.executeSelect(query, new ModelEntity()); if (results.isEmpty()) { return null; } else if (results.size() > 1) { @@ -324,7 +323,7 @@ public List lookupEntities( if (entityIds == null || entityIds.isEmpty()) return new ArrayList<>(); String query = generateSelectQueryWithEntityIds(realmId, entityIds); try { - return datasourceOperations.executeSelect(query, new ModelEntity(), ModelEntity::toEntity); + return datasourceOperations.executeSelect(query, new ModelEntity()); } catch (SQLException e) { throw new RuntimeException( String.format("Failed to retrieve polaris entities due to %s", e.getMessage()), e); @@ -420,7 +419,7 @@ public Page listEntities( query, new ModelEntity(), stream -> { - var data = stream.map(ModelEntity::toEntity).filter(entityFilter); + var data = stream.filter(entityFilter); if (pageToken instanceof HasPageSize hasPageSize) { data = data.limit(hasPageSize.getPageSize()); } @@ -472,9 +471,7 @@ public PolarisGrantRecord lookupGrantRecord( realmId); String query = generateSelectQuery(new ModelGrantRecord(), params); try { - List results = - datasourceOperations.executeSelect( - query, new ModelGrantRecord(), ModelGrantRecord::toGrantRecord); + var results = datasourceOperations.executeSelect(query, new ModelGrantRecord()); if (results.size() > 1) { throw new IllegalStateException( String.format( @@ -503,9 +500,7 @@ public List loadAllGrantRecordsOnSecurable( realmId); String query = generateSelectQuery(new ModelGrantRecord(), params); try { - List results = - datasourceOperations.executeSelect( - query, new ModelGrantRecord(), ModelGrantRecord::toGrantRecord); + var results = datasourceOperations.executeSelect(query, new ModelGrantRecord()); return results == null ? Collections.emptyList() : results; } catch (SQLException e) { throw new RuntimeException( @@ -525,9 +520,7 @@ public List loadAllGrantRecordsOnGrantee( "grantee_catalog_id", granteeCatalogId, "grantee_id", granteeId, "realm_id", realmId); String query = generateSelectQuery(new ModelGrantRecord(), params); try { - List results = - datasourceOperations.executeSelect( - query, new ModelGrantRecord(), ModelGrantRecord::toGrantRecord); + var results = datasourceOperations.executeSelect(query, new ModelGrantRecord()); return results == null ? Collections.emptyList() : results; } catch (SQLException e) { throw new RuntimeException( @@ -553,8 +546,7 @@ public boolean hasChildren( } String query = generateSelectQuery(new ModelEntity(), params); try { - List results = - datasourceOperations.executeSelect(query, new ModelEntity(), Function.identity()); + var results = datasourceOperations.executeSelect(query, new ModelEntity()); return results != null && !results.isEmpty(); } catch (SQLException e) { throw new RuntimeException( @@ -571,11 +563,8 @@ public PolarisPrincipalSecrets loadPrincipalSecrets( Map params = Map.of("principal_client_id", clientId, "realm_id", realmId); String query = generateSelectQuery(new ModelPrincipalAuthenticationData(), params); try { - List results = - datasourceOperations.executeSelect( - query, - new ModelPrincipalAuthenticationData(), - ModelPrincipalAuthenticationData::toPrincipalAuthenticationData); + var results = + datasourceOperations.executeSelect(query, new ModelPrincipalAuthenticationData()); return results == null || results.isEmpty() ? null : results.getFirst(); } catch (SQLException e) { LOGGER.error( @@ -875,11 +864,7 @@ public List loadAllTargetsOnPolicy( private List fetchPolicyMappingRecords(String query) { try { - List results = - datasourceOperations.executeSelect( - query, - new ModelPolicyMappingRecord(), - ModelPolicyMappingRecord::toPolicyMappingRecord); + var results = datasourceOperations.executeSelect(query, new ModelPolicyMappingRecord()); return results == null ? Collections.emptyList() : results; } catch (SQLException e) { throw new RuntimeException( diff --git a/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/Converter.java b/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/Converter.java index 45f8e99b36..dbd7114b9b 100644 --- a/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/Converter.java +++ b/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/Converter.java @@ -27,7 +27,7 @@ public interface Converter { * Converts a ResultSet to model. * * @param rs : ResultSet from JDBC. - * @return Model of Entity + * @return the corresponding business entity * @throws SQLException : Exception while fetching from ResultSet. */ T fromResultSet(ResultSet rs) throws SQLException; diff --git a/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/ModelEntity.java b/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/ModelEntity.java index 948f9a8693..512f4afe17 100644 --- a/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/ModelEntity.java +++ b/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/ModelEntity.java @@ -26,7 +26,7 @@ import org.apache.polaris.core.entity.PolarisEntitySubType; import org.apache.polaris.core.entity.PolarisEntityType; -public class ModelEntity implements Converter { +public class ModelEntity implements Converter { // the id of the catalog associated to that entity. use 0 if this entity is top-level // like a catalog private long catalogId; @@ -138,27 +138,29 @@ public static Builder builder() { } @Override - public ModelEntity fromResultSet(ResultSet r) throws SQLException { - return ModelEntity.builder() - .catalogId(r.getObject("catalog_id", Long.class)) - .id(r.getObject("id", Long.class)) - .parentId(r.getObject("parent_id", Long.class)) - .typeCode(r.getObject("type_code", Integer.class)) - .name(r.getObject("name", String.class)) - .entityVersion(r.getObject("entity_version", Integer.class)) - .subTypeCode(r.getObject("sub_type_code", Integer.class)) - .createTimestamp(r.getObject("create_timestamp", Long.class)) - .dropTimestamp(r.getObject("drop_timestamp", Long.class)) - .purgeTimestamp(r.getObject("purge_timestamp", Long.class)) - .toPurgeTimestamp(r.getObject("to_purge_timestamp", Long.class)) - .lastUpdateTimestamp(r.getObject("last_update_timestamp", Long.class)) - .properties( - r.getString("properties")) // required for extracting when the underlying type is JSONB - .internalProperties( - r.getString( - "internal_properties")) // required for extracting when the underlying type is JSONB - .grantRecordsVersion(r.getObject("grant_records_version", Integer.class)) - .build(); + public PolarisBaseEntity fromResultSet(ResultSet r) throws SQLException { + var modelEntity = + ModelEntity.builder() + .catalogId(r.getObject("catalog_id", Long.class)) + .id(r.getObject("id", Long.class)) + .parentId(r.getObject("parent_id", Long.class)) + .typeCode(r.getObject("type_code", Integer.class)) + .name(r.getObject("name", String.class)) + .entityVersion(r.getObject("entity_version", Integer.class)) + .subTypeCode(r.getObject("sub_type_code", Integer.class)) + .createTimestamp(r.getObject("create_timestamp", Long.class)) + .dropTimestamp(r.getObject("drop_timestamp", Long.class)) + .purgeTimestamp(r.getObject("purge_timestamp", Long.class)) + .toPurgeTimestamp(r.getObject("to_purge_timestamp", Long.class)) + .lastUpdateTimestamp(r.getObject("last_update_timestamp", Long.class)) + // JSONB: use getString(), not getObject(). + .properties(r.getString("properties")) + // JSONB: use getString(), not getObject(). + .internalProperties(r.getString("internal_properties")) + .grantRecordsVersion(r.getObject("grant_records_version", Integer.class)) + .build(); + + return toEntity(modelEntity); } @Override diff --git a/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/ModelGrantRecord.java b/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/ModelGrantRecord.java index 8f06d78c71..e101bfc6a7 100644 --- a/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/ModelGrantRecord.java +++ b/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/ModelGrantRecord.java @@ -24,7 +24,7 @@ import java.util.Map; import org.apache.polaris.core.entity.PolarisGrantRecord; -public class ModelGrantRecord implements Converter { +public class ModelGrantRecord implements Converter { // id of the catalog where the securable entity resides, use 0, if this entity is a // top-level account entity. private long securableCatalogId; @@ -67,14 +67,17 @@ public static Builder builder() { } @Override - public ModelGrantRecord fromResultSet(ResultSet rs) throws SQLException { - return ModelGrantRecord.builder() - .securableCatalogId(rs.getObject("securable_catalog_id", Long.class)) - .securableId(rs.getObject("securable_id", Long.class)) - .granteeCatalogId(rs.getObject("grantee_catalog_id", Long.class)) - .granteeId(rs.getObject("grantee_id", Long.class)) - .privilegeCode(rs.getObject("privilege_code", Integer.class)) - .build(); + public PolarisGrantRecord fromResultSet(ResultSet rs) throws SQLException { + var modelGrantRecord = + ModelGrantRecord.builder() + .securableCatalogId(rs.getObject("securable_catalog_id", Long.class)) + .securableId(rs.getObject("securable_id", Long.class)) + .granteeCatalogId(rs.getObject("grantee_catalog_id", Long.class)) + .granteeId(rs.getObject("grantee_id", Long.class)) + .privilegeCode(rs.getObject("privilege_code", Integer.class)) + .build(); + + return toGrantRecord(modelGrantRecord); } @Override diff --git a/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/ModelPolicyMappingRecord.java b/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/ModelPolicyMappingRecord.java index 0913a3570e..296db14ddb 100644 --- a/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/ModelPolicyMappingRecord.java +++ b/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/ModelPolicyMappingRecord.java @@ -24,7 +24,7 @@ import java.util.Map; import org.apache.polaris.core.policy.PolarisPolicyMappingRecord; -public class ModelPolicyMappingRecord implements Converter { +public class ModelPolicyMappingRecord implements Converter { // id of the catalog where target entity resides private long targetCatalogId; @@ -140,15 +140,18 @@ public static PolarisPolicyMappingRecord toPolicyMappingRecord(ModelPolicyMappin } @Override - public ModelPolicyMappingRecord fromResultSet(ResultSet rs) throws SQLException { - return ModelPolicyMappingRecord.builder() - .targetCatalogId(rs.getObject("target_catalog_id", Long.class)) - .targetId(rs.getObject("target_id", Long.class)) - .policyTypeCode(rs.getObject("policy_type_code", Integer.class)) - .policyCatalogId(rs.getObject("policy_catalog_id", Long.class)) - .policyId(rs.getObject("policy_id", Long.class)) - .parameters(rs.getString("parameters")) - .build(); + public PolarisPolicyMappingRecord fromResultSet(ResultSet rs) throws SQLException { + var modelRecord = + ModelPolicyMappingRecord.builder() + .targetCatalogId(rs.getObject("target_catalog_id", Long.class)) + .targetId(rs.getObject("target_id", Long.class)) + .policyTypeCode(rs.getObject("policy_type_code", Integer.class)) + .policyCatalogId(rs.getObject("policy_catalog_id", Long.class)) + .policyId(rs.getObject("policy_id", Long.class)) + .parameters(rs.getString("parameters")) + .build(); + + return toPolicyMappingRecord(modelRecord); } @Override diff --git a/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/ModelPrincipalAuthenticationData.java b/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/ModelPrincipalAuthenticationData.java index 2b78d43828..0f1fcb0b51 100644 --- a/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/ModelPrincipalAuthenticationData.java +++ b/extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/ModelPrincipalAuthenticationData.java @@ -24,8 +24,7 @@ import java.util.Map; import org.apache.polaris.core.entity.PolarisPrincipalSecrets; -public class ModelPrincipalAuthenticationData - implements Converter { +public class ModelPrincipalAuthenticationData implements Converter { // the id of the principal private long principalId; @@ -65,14 +64,17 @@ public static Builder builder() { } @Override - public ModelPrincipalAuthenticationData fromResultSet(ResultSet rs) throws SQLException { - return ModelPrincipalAuthenticationData.builder() - .principalId(rs.getObject("principal_id", Long.class)) - .principalClientId(rs.getObject("principal_client_id", String.class)) - .mainSecretHash(rs.getObject("main_secret_hash", String.class)) - .secondarySecretHash(rs.getObject("secondary_secret_hash", String.class)) - .secretSalt(rs.getObject("secret_salt", String.class)) - .build(); + public PolarisPrincipalSecrets fromResultSet(ResultSet rs) throws SQLException { + var modelRecord = + ModelPrincipalAuthenticationData.builder() + .principalId(rs.getObject("principal_id", Long.class)) + .principalClientId(rs.getObject("principal_client_id", String.class)) + .mainSecretHash(rs.getObject("main_secret_hash", String.class)) + .secondarySecretHash(rs.getObject("secondary_secret_hash", String.class)) + .secretSalt(rs.getObject("secret_salt", String.class)) + .build(); + + return toPrincipalAuthenticationData(modelRecord); } @Override diff --git a/extension/persistence/relational-jdbc/src/test/java/org/apache/polaris/extension/persistence/impl/relational/jdbc/DatasourceOperationsTest.java b/extension/persistence/relational-jdbc/src/test/java/org/apache/polaris/extension/persistence/impl/relational/jdbc/DatasourceOperationsTest.java index f5694982c7..c73cf3fd4b 100644 --- a/extension/persistence/relational-jdbc/src/test/java/org/apache/polaris/extension/persistence/impl/relational/jdbc/DatasourceOperationsTest.java +++ b/extension/persistence/relational-jdbc/src/test/java/org/apache/polaris/extension/persistence/impl/relational/jdbc/DatasourceOperationsTest.java @@ -24,7 +24,6 @@ import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; -import java.util.function.Function; import javax.sql.DataSource; import org.apache.polaris.extension.persistence.relational.jdbc.DatasourceOperations; import org.apache.polaris.extension.persistence.relational.jdbc.models.ModelEntity; @@ -76,8 +75,7 @@ void testExecuteSelect_exception() throws Exception { when(mockStatement.executeQuery(query)).thenThrow(new SQLException()); assertThrows( - SQLException.class, - () -> datasourceOperations.executeSelect(query, new ModelEntity(), Function.identity())); + SQLException.class, () -> datasourceOperations.executeSelect(query, new ModelEntity())); } @Test