diff --git a/catalogs/catalog-hadoop/src/test/java/org/apache/gravitino/catalog/hadoop/TestHadoopCatalogOperations.java b/catalogs/catalog-hadoop/src/test/java/org/apache/gravitino/catalog/hadoop/TestHadoopCatalogOperations.java index 1a3e49b5499..7bbd0482324 100644 --- a/catalogs/catalog-hadoop/src/test/java/org/apache/gravitino/catalog/hadoop/TestHadoopCatalogOperations.java +++ b/catalogs/catalog-hadoop/src/test/java/org/apache/gravitino/catalog/hadoop/TestHadoopCatalogOperations.java @@ -197,6 +197,9 @@ public static void setUp() { MetalakeMetaService metalakeMetaService = MetalakeMetaService.getInstance(); MetalakeMetaService spyMetaservice = Mockito.spy(metalakeMetaService); doReturn(1L).when(spyMetaservice).getMetalakeIdByName(Mockito.anyString()); + doReturn(1L) + .when(spyMetaservice) + .getMetalakeIdByNameIdentifier(Mockito.any(NameIdentifier.class)); CatalogMetaService catalogMetaService = CatalogMetaService.getInstance(); CatalogMetaService spyCatalogMetaService = Mockito.spy(catalogMetaService); diff --git a/catalogs/catalog-kafka/src/test/java/org/apache/gravitino/catalog/kafka/TestKafkaCatalogOperations.java b/catalogs/catalog-kafka/src/test/java/org/apache/gravitino/catalog/kafka/TestKafkaCatalogOperations.java index c12c191482e..94806f53a42 100644 --- a/catalogs/catalog-kafka/src/test/java/org/apache/gravitino/catalog/kafka/TestKafkaCatalogOperations.java +++ b/catalogs/catalog-kafka/src/test/java/org/apache/gravitino/catalog/kafka/TestKafkaCatalogOperations.java @@ -150,6 +150,9 @@ public static void setUp() { MetalakeMetaService metalakeMetaService = MetalakeMetaService.getInstance(); MetalakeMetaService spyMetaservice = Mockito.spy(metalakeMetaService); doReturn(1L).when(spyMetaservice).getMetalakeIdByName(Mockito.anyString()); + doReturn(1L) + .when(spyMetaservice) + .getMetalakeIdByNameIdentifier(Mockito.any(NameIdentifier.class)); CatalogMetaService catalogMetaService = CatalogMetaService.getInstance(); CatalogMetaService spyCatalogMetaService = Mockito.spy(catalogMetaService); diff --git a/core/src/main/java/org/apache/gravitino/storage/relational/JDBCBackend.java b/core/src/main/java/org/apache/gravitino/storage/relational/JDBCBackend.java index a0892512979..8aa479244c6 100644 --- a/core/src/main/java/org/apache/gravitino/storage/relational/JDBCBackend.java +++ b/core/src/main/java/org/apache/gravitino/storage/relational/JDBCBackend.java @@ -30,6 +30,7 @@ import org.apache.gravitino.Config; import org.apache.gravitino.Configs; import org.apache.gravitino.Entity; +import org.apache.gravitino.Entity.EntityType; import org.apache.gravitino.EntityAlreadyExistsException; import org.apache.gravitino.HasIdentifier; import org.apache.gravitino.MetadataObject; @@ -58,6 +59,8 @@ import org.apache.gravitino.storage.relational.service.MetalakeMetaService; import org.apache.gravitino.storage.relational.service.ModelMetaService; import org.apache.gravitino.storage.relational.service.ModelVersionMetaService; +import org.apache.gravitino.storage.relational.service.NameIdMappingService; +import org.apache.gravitino.storage.relational.service.NameIdMappingService.EntityIdentifier; import org.apache.gravitino.storage.relational.service.OwnerMetaService; import org.apache.gravitino.storage.relational.service.RoleMetaService; import org.apache.gravitino.storage.relational.service.SchemaMetaService; @@ -143,6 +146,7 @@ public boolean exists(NameIdentifier ident, Entity.EntityType entityType) throws @Override public void insert(E e, boolean overwritten) throws EntityAlreadyExistsException, IOException { + EntityType entityType = e.type(); if (e instanceof BaseMetalake) { MetalakeMetaService.getInstance().insertMetalake((BaseMetalake) e, overwritten); } else if (e instanceof CatalogEntity) { @@ -176,12 +180,19 @@ public void insert(E e, boolean overwritten) throw new UnsupportedEntityTypeException( "Unsupported entity type: %s for insert operation", e.getClass()); } + + NameIdMappingService.getInstance() + .put(EntityIdentifier.of(e.nameIdentifier(), entityType), e.id()); } @Override public E update( NameIdentifier ident, Entity.EntityType entityType, Function updater) throws IOException, NoSuchEntityException, EntityAlreadyExistsException { + // Remove all the children entities in the cache as we can't guarantee the children entities + // are still valid after the parent entity is updated. + EntityIdentifier entityIdentifier = EntityIdentifier.of(ident, entityType); + NameIdMappingService.getInstance().invalidateWithPrefix(entityIdentifier); switch (entityType) { case METALAKE: return (E) MetalakeMetaService.getInstance().updateMetalake(ident, updater); @@ -245,36 +256,49 @@ public E get( } @Override - public boolean delete(NameIdentifier ident, Entity.EntityType entityType, boolean cascade) - throws IOException { - switch (entityType) { - case METALAKE: - return MetalakeMetaService.getInstance().deleteMetalake(ident, cascade); - case CATALOG: - return CatalogMetaService.getInstance().deleteCatalog(ident, cascade); - case SCHEMA: - return SchemaMetaService.getInstance().deleteSchema(ident, cascade); - case TABLE: - return TableMetaService.getInstance().deleteTable(ident); - case FILESET: - return FilesetMetaService.getInstance().deleteFileset(ident); - case TOPIC: - return TopicMetaService.getInstance().deleteTopic(ident); - case USER: - return UserMetaService.getInstance().deleteUser(ident); - case GROUP: - return GroupMetaService.getInstance().deleteGroup(ident); - case ROLE: - return RoleMetaService.getInstance().deleteRole(ident); - case TAG: - return TagMetaService.getInstance().deleteTag(ident); - case MODEL: - return ModelMetaService.getInstance().deleteModel(ident); - case MODEL_VERSION: - return ModelVersionMetaService.getInstance().deleteModelVersion(ident); - default: - throw new UnsupportedEntityTypeException( - "Unsupported entity type: %s for delete operation", entityType); + public boolean delete(NameIdentifier ident, Entity.EntityType entityType, boolean cascade) { + // Invalidate the cache first + EntityIdentifier entityIdentifier = EntityIdentifier.of(ident, entityType); + NameIdMappingService.getInstance().invalidate(entityIdentifier); + if (cascade) { + // Remove all the children entities in the cache; + NameIdMappingService.getInstance().invalidateWithPrefix(entityIdentifier); + } + + try { + switch (entityType) { + case METALAKE: + return MetalakeMetaService.getInstance().deleteMetalake(ident, cascade); + case CATALOG: + return CatalogMetaService.getInstance().deleteCatalog(ident, cascade); + case SCHEMA: + return SchemaMetaService.getInstance().deleteSchema(ident, cascade); + case TABLE: + return TableMetaService.getInstance().deleteTable(ident); + case FILESET: + return FilesetMetaService.getInstance().deleteFileset(ident); + case TOPIC: + return TopicMetaService.getInstance().deleteTopic(ident); + case USER: + return UserMetaService.getInstance().deleteUser(ident); + case GROUP: + return GroupMetaService.getInstance().deleteGroup(ident); + case ROLE: + return RoleMetaService.getInstance().deleteRole(ident); + case TAG: + return TagMetaService.getInstance().deleteTag(ident); + case MODEL: + return ModelMetaService.getInstance().deleteModel(ident); + case MODEL_VERSION: + return ModelVersionMetaService.getInstance().deleteModelVersion(ident); + default: + throw new UnsupportedEntityTypeException( + "Unsupported entity type: %s for delete operation", entityType); + } + } finally { + // Remove the entity from the cache again because we may add the cache during the deletion + // process + NameIdMappingService.getInstance().invalidateWithPrefix(entityIdentifier); } } @@ -379,6 +403,8 @@ public void close() throws IOException { SqlSessionFactoryHelper.getInstance().close(); SQLExceptionConverterFactory.close(); + NameIdMappingService.getInstance().close(); + if (jdbcDatabase != null) { jdbcDatabase.close(); } diff --git a/core/src/main/java/org/apache/gravitino/storage/relational/service/CatalogMetaService.java b/core/src/main/java/org/apache/gravitino/storage/relational/service/CatalogMetaService.java index 310b8cc08e9..117dc688d8f 100644 --- a/core/src/main/java/org/apache/gravitino/storage/relational/service/CatalogMetaService.java +++ b/core/src/main/java/org/apache/gravitino/storage/relational/service/CatalogMetaService.java @@ -18,6 +18,7 @@ */ package org.apache.gravitino.storage.relational.service; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import java.io.IOException; import java.util.List; @@ -47,6 +48,7 @@ import org.apache.gravitino.storage.relational.mapper.TagMetadataObjectRelMapper; import org.apache.gravitino.storage.relational.mapper.TopicMetaMapper; import org.apache.gravitino.storage.relational.po.CatalogPO; +import org.apache.gravitino.storage.relational.service.NameIdMappingService.EntityIdentifier; import org.apache.gravitino.storage.relational.utils.ExceptionUtils; import org.apache.gravitino.storage.relational.utils.POConverters; import org.apache.gravitino.storage.relational.utils.SessionUtils; @@ -90,6 +92,7 @@ public CatalogPO getCatalogPOById(Long catalogId) { return catalogPO; } + @VisibleForTesting public Long getCatalogIdByMetalakeIdAndName(Long metalakeId, String catalogName) { Long catalogId = SessionUtils.getWithoutCommit( @@ -105,6 +108,22 @@ public Long getCatalogIdByMetalakeIdAndName(Long metalakeId, String catalogName) return catalogId; } + public Long getCatalogIdByNameIdentifier(NameIdentifier identifier) { + NameIdentifierUtil.checkCatalog(identifier); + EntityIdentifier catalogIdent = EntityIdentifier.of(identifier, Entity.EntityType.CATALOG); + + return NameIdMappingService.getInstance() + .get( + catalogIdent, + ident -> { + String catalogName = ident.ident.name(); + Long metalakeId = + CommonMetaService.getInstance() + .getParentEntityIdByNamespace(ident.ident.namespace()); + return getCatalogIdByMetalakeIdAndName(metalakeId, catalogName); + }); + } + public CatalogEntity getCatalogByIdentifier(NameIdentifier identifier) { NameIdentifierUtil.checkCatalog(identifier); String catalogName = identifier.name(); @@ -198,10 +217,7 @@ public boolean deleteCatalog(NameIdentifier identifier, boolean cascade) { NameIdentifierUtil.checkCatalog(identifier); String catalogName = identifier.name(); - Long metalakeId = - CommonMetaService.getInstance().getParentEntityIdByNamespace(identifier.namespace()); - - Long catalogId = getCatalogIdByMetalakeIdAndName(metalakeId, catalogName); + Long catalogId = getCatalogIdByNameIdentifier(identifier); if (cascade) { SessionUtils.doMultipleWithCommit( @@ -296,8 +312,6 @@ public boolean deleteCatalog(NameIdentifier identifier, boolean cascade) { public int deleteCatalogMetasByLegacyTimeline(Long legacyTimeline, int limit) { return SessionUtils.doWithCommitAndFetchResult( CatalogMetaMapper.class, - mapper -> { - return mapper.deleteCatalogMetasByLegacyTimeline(legacyTimeline, limit); - }); + mapper -> mapper.deleteCatalogMetasByLegacyTimeline(legacyTimeline, limit)); } } diff --git a/core/src/main/java/org/apache/gravitino/storage/relational/service/CommonMetaService.java b/core/src/main/java/org/apache/gravitino/storage/relational/service/CommonMetaService.java index bdab2ad9fe5..4a7978d6a43 100644 --- a/core/src/main/java/org/apache/gravitino/storage/relational/service/CommonMetaService.java +++ b/core/src/main/java/org/apache/gravitino/storage/relational/service/CommonMetaService.java @@ -20,6 +20,7 @@ package org.apache.gravitino.storage.relational.service; import com.google.common.base.Preconditions; +import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.Namespace; /** The service class for common metadata operations. */ @@ -36,26 +37,26 @@ public Long getParentEntityIdByNamespace(Namespace namespace) { Preconditions.checkArgument( !namespace.isEmpty() && namespace.levels().length <= 3, "Namespace should not be empty and length should be less than or equal to 3."); - Long parentEntityId = null; - if (namespace.levels().length >= 1) { - parentEntityId = MetalakeMetaService.getInstance().getMetalakeIdByName(namespace.level(0)); - } + String[] level = namespace.levels(); + NameIdentifier ident = NameIdentifier.of(level); + Long entityId = null; - if (namespace.levels().length >= 2) { - parentEntityId = - CatalogMetaService.getInstance() - .getCatalogIdByMetalakeIdAndName(parentEntityId, namespace.level(1)); + switch (level.length) { + case 1: + entityId = MetalakeMetaService.getInstance().getMetalakeIdByNameIdentifier(ident); + break; + case 2: + entityId = CatalogMetaService.getInstance().getCatalogIdByNameIdentifier(ident); + break; + case 3: + entityId = SchemaMetaService.getInstance().getSchemaIdByNameIdentifier(ident); + break; } - if (namespace.levels().length >= 3) { - parentEntityId = - SchemaMetaService.getInstance() - .getSchemaIdByCatalogIdAndName(parentEntityId, namespace.level(2)); - } Preconditions.checkState( - parentEntityId != null && parentEntityId > 0, + entityId != null && entityId > 0, "Parent entity id should not be null and should be greater than 0."); - return parentEntityId; + return entityId; } public Long[] getParentEntityIdsByNamespace(Namespace namespace) { diff --git a/core/src/main/java/org/apache/gravitino/storage/relational/service/FilesetMetaService.java b/core/src/main/java/org/apache/gravitino/storage/relational/service/FilesetMetaService.java index 9233005c34a..f8605f4f902 100644 --- a/core/src/main/java/org/apache/gravitino/storage/relational/service/FilesetMetaService.java +++ b/core/src/main/java/org/apache/gravitino/storage/relational/service/FilesetMetaService.java @@ -24,6 +24,7 @@ import java.util.Objects; import java.util.function.Function; import org.apache.gravitino.Entity; +import org.apache.gravitino.Entity.EntityType; import org.apache.gravitino.HasIdentifier; import org.apache.gravitino.MetadataObject; import org.apache.gravitino.NameIdentifier; @@ -37,6 +38,7 @@ import org.apache.gravitino.storage.relational.mapper.TagMetadataObjectRelMapper; import org.apache.gravitino.storage.relational.po.FilesetMaxVersionPO; import org.apache.gravitino.storage.relational.po.FilesetPO; +import org.apache.gravitino.storage.relational.service.NameIdMappingService.EntityIdentifier; import org.apache.gravitino.storage.relational.utils.ExceptionUtils; import org.apache.gravitino.storage.relational.utils.POConverters; import org.apache.gravitino.storage.relational.utils.SessionUtils; @@ -83,7 +85,22 @@ public FilesetPO getFilesetPOById(Long filesetId) { return filesetPO; } - public Long getFilesetIdBySchemaIdAndName(Long schemaId, String filesetName) { + public Long getFilesetIdByNameIdentifier(NameIdentifier identifier) { + NameIdentifierUtil.checkFileset(identifier); + + EntityIdentifier fileIdentifier = EntityIdentifier.of(identifier, EntityType.FILESET); + return NameIdMappingService.getInstance() + .get( + fileIdentifier, + ident -> { + Long schemaId = + CommonMetaService.getInstance() + .getParentEntityIdByNamespace(ident.ident.namespace()); + return getFilesetIdBySchemaIdAndName(schemaId, ident.ident.name()); + }); + } + + private Long getFilesetIdBySchemaIdAndName(Long schemaId, String filesetName) { Long filesetId = SessionUtils.getWithoutCommit( FilesetMetaMapper.class, @@ -225,12 +242,7 @@ public FilesetEntity updateFileset( public boolean deleteFileset(NameIdentifier identifier) { NameIdentifierUtil.checkFileset(identifier); - String filesetName = identifier.name(); - - Long schemaId = - CommonMetaService.getInstance().getParentEntityIdByNamespace(identifier.namespace()); - - Long filesetId = getFilesetIdBySchemaIdAndName(schemaId, filesetName); + Long filesetId = getFilesetIdByNameIdentifier(identifier); // We should delete meta and version info SessionUtils.doMultipleWithCommit( diff --git a/core/src/main/java/org/apache/gravitino/storage/relational/service/GroupMetaService.java b/core/src/main/java/org/apache/gravitino/storage/relational/service/GroupMetaService.java index 4329b3a0a10..f160670e6b1 100644 --- a/core/src/main/java/org/apache/gravitino/storage/relational/service/GroupMetaService.java +++ b/core/src/main/java/org/apache/gravitino/storage/relational/service/GroupMetaService.java @@ -44,6 +44,7 @@ import org.apache.gravitino.storage.relational.po.GroupPO; import org.apache.gravitino.storage.relational.po.GroupRoleRelPO; import org.apache.gravitino.storage.relational.po.RolePO; +import org.apache.gravitino.storage.relational.service.NameIdMappingService.EntityIdentifier; import org.apache.gravitino.storage.relational.utils.ExceptionUtils; import org.apache.gravitino.storage.relational.utils.POConverters; import org.apache.gravitino.storage.relational.utils.SessionUtils; @@ -88,6 +89,19 @@ public Long getGroupIdByMetalakeIdAndName(Long metalakeId, String groupName) { return groupId; } + public Long getGroupIdByNameIdentifier(NameIdentifier identifier) { + EntityIdentifier groupIdentifier = EntityIdentifier.of(identifier, Entity.EntityType.GROUP); + return NameIdMappingService.getInstance() + .get( + groupIdentifier, + ident -> { + Long metalakeId = + MetalakeMetaService.getInstance() + .getMetalakeIdByName(ident.ident.namespace().level(0)); + return getGroupIdByMetalakeIdAndName(metalakeId, ident.ident.name()); + }); + } + public GroupEntity getGroupByIdentifier(NameIdentifier identifier) { AuthorizationUtils.checkGroup(identifier); @@ -160,9 +174,7 @@ public void insertGroup(GroupEntity groupEntity, boolean overwritten) throws IOE public boolean deleteGroup(NameIdentifier identifier) { AuthorizationUtils.checkGroup(identifier); - Long metalakeId = - MetalakeMetaService.getInstance().getMetalakeIdByName(identifier.namespace().level(0)); - Long groupId = getGroupIdByMetalakeIdAndName(metalakeId, identifier.name()); + Long groupId = getGroupIdByNameIdentifier(identifier); SessionUtils.doMultipleWithCommit( () -> diff --git a/core/src/main/java/org/apache/gravitino/storage/relational/service/MetadataObjectService.java b/core/src/main/java/org/apache/gravitino/storage/relational/service/MetadataObjectService.java index 188c06ac23e..e6ea2ed2507 100644 --- a/core/src/main/java/org/apache/gravitino/storage/relational/service/MetadataObjectService.java +++ b/core/src/main/java/org/apache/gravitino/storage/relational/service/MetadataObjectService.java @@ -18,14 +18,20 @@ */ package org.apache.gravitino.storage.relational.service; +import static org.apache.gravitino.Entity.ROLE_SCHEMA_NAME; +import static org.apache.gravitino.Entity.SYSTEM_CATALOG_RESERVED_NAME; + import com.google.common.base.Joiner; import com.google.common.base.Splitter; +import com.google.common.collect.Lists; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import javax.annotation.Nullable; +import org.apache.commons.lang3.ArrayUtils; import org.apache.gravitino.MetadataObject; +import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.storage.relational.mapper.CatalogMetaMapper; import org.apache.gravitino.storage.relational.mapper.FilesetMetaMapper; import org.apache.gravitino.storage.relational.mapper.MetalakeMetaMapper; @@ -60,46 +66,43 @@ public class MetadataObjectService { private MetadataObjectService() {} public static long getMetadataObjectId( - long metalakeId, String fullName, MetadataObject.Type type) { + String metalakeName, String fullName, MetadataObject.Type type) { if (type == MetadataObject.Type.METALAKE) { return MetalakeMetaService.getInstance().getMetalakeIdByName(fullName); } if (type == MetadataObject.Type.ROLE) { - return RoleMetaService.getInstance().getRoleIdByMetalakeIdAndName(metalakeId, fullName); + NameIdentifier nameIdentifier = + NameIdentifier.of(metalakeName, SYSTEM_CATALOG_RESERVED_NAME, ROLE_SCHEMA_NAME, fullName); + return RoleMetaService.getInstance().getRoleIdByNameIdentifier(nameIdentifier); } + List names = DOT_SPLITTER.splitToList(fullName); + List realNames = Lists.newArrayList(metalakeName); + realNames.addAll(names); + NameIdentifier nameIdentifier = NameIdentifier.of(realNames.toArray(new String[0])); - long catalogId = - CatalogMetaService.getInstance().getCatalogIdByMetalakeIdAndName(metalakeId, names.get(0)); if (type == MetadataObject.Type.CATALOG) { - return catalogId; - } - - long schemaId = - SchemaMetaService.getInstance().getSchemaIdByCatalogIdAndName(catalogId, names.get(1)); - if (type == MetadataObject.Type.SCHEMA) { - return schemaId; - } - - if (type == MetadataObject.Type.FILESET) { - return FilesetMetaService.getInstance().getFilesetIdBySchemaIdAndName(schemaId, names.get(2)); + return CatalogMetaService.getInstance().getCatalogIdByNameIdentifier(nameIdentifier); + } else if (type == MetadataObject.Type.SCHEMA) { + return SchemaMetaService.getInstance().getSchemaIdByNameIdentifier(nameIdentifier); + } else if (type == MetadataObject.Type.FILESET) { + return FilesetMetaService.getInstance().getFilesetIdByNameIdentifier(nameIdentifier); } else if (type == MetadataObject.Type.TOPIC) { - return TopicMetaService.getInstance().getTopicIdBySchemaIdAndName(schemaId, names.get(2)); + return TopicMetaService.getInstance().getTopicIdByNameIdentifier(nameIdentifier); + } else if (type == MetadataObject.Type.TABLE) { + return TableMetaService.getInstance().getTableByNameIdentifier(nameIdentifier); } else if (type == MetadataObject.Type.MODEL) { - return ModelMetaService.getInstance() - .getModelIdBySchemaIdAndModelName(schemaId, names.get(2)); - } - - long tableId = - TableMetaService.getInstance().getTableIdBySchemaIdAndName(schemaId, names.get(2)); - if (type == MetadataObject.Type.TABLE) { - return tableId; + return ModelMetaService.getInstance().getModelIdByNameIdentifier(nameIdentifier); } - if (type == MetadataObject.Type.COLUMN) { + long tableId = + TableMetaService.getInstance() + .getTableByNameIdentifier( + NameIdentifier.of( + ArrayUtils.remove(realNames.toArray(new String[0]), realNames.size() - 1))); return TableColumnMetaService.getInstance() - .getColumnIdByTableIdAndName(tableId, names.get(3)); + .getColumnIdByTableIdAndName(tableId, names.get(4)); } throw new IllegalArgumentException(String.format("Doesn't support the type %s", type)); diff --git a/core/src/main/java/org/apache/gravitino/storage/relational/service/MetalakeMetaService.java b/core/src/main/java/org/apache/gravitino/storage/relational/service/MetalakeMetaService.java index 75e217279d0..288b36195e2 100644 --- a/core/src/main/java/org/apache/gravitino/storage/relational/service/MetalakeMetaService.java +++ b/core/src/main/java/org/apache/gravitino/storage/relational/service/MetalakeMetaService.java @@ -25,6 +25,7 @@ import java.util.Objects; import java.util.function.Function; import org.apache.gravitino.Entity; +import org.apache.gravitino.Entity.EntityType; import org.apache.gravitino.HasIdentifier; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.exceptions.NoSuchEntityException; @@ -52,6 +53,7 @@ import org.apache.gravitino.storage.relational.mapper.UserMetaMapper; import org.apache.gravitino.storage.relational.mapper.UserRoleRelMapper; import org.apache.gravitino.storage.relational.po.MetalakePO; +import org.apache.gravitino.storage.relational.service.NameIdMappingService.EntityIdentifier; import org.apache.gravitino.storage.relational.utils.ExceptionUtils; import org.apache.gravitino.storage.relational.utils.POConverters; import org.apache.gravitino.storage.relational.utils.SessionUtils; @@ -77,17 +79,47 @@ public List listMetalakes() { return POConverters.fromMetalakePOs(metalakePOS); } + public Long getMetalakeIdByNameIdentifier(NameIdentifier nameIdentifier) { + NameIdentifierUtil.checkMetalake(nameIdentifier); + EntityIdentifier metalakeIdentifier = EntityIdentifier.of(nameIdentifier, EntityType.METALAKE); + return NameIdMappingService.getInstance() + .get( + metalakeIdentifier, + ident -> { + Long metalakeId = + SessionUtils.getWithoutCommit( + MetalakeMetaMapper.class, + mapper -> mapper.selectMetalakeIdMetaByName(ident.ident.name())); + if (metalakeId == null) { + throw new NoSuchEntityException( + NoSuchEntityException.NO_SUCH_ENTITY_MESSAGE, + Entity.EntityType.METALAKE.name().toLowerCase(), + nameIdentifier.toString()); + } + return metalakeId; + }); + } + public Long getMetalakeIdByName(String metalakeName) { - Long metalakeId = - SessionUtils.getWithoutCommit( - MetalakeMetaMapper.class, mapper -> mapper.selectMetalakeIdMetaByName(metalakeName)); - if (metalakeId == null) { - throw new NoSuchEntityException( - NoSuchEntityException.NO_SUCH_ENTITY_MESSAGE, - Entity.EntityType.METALAKE.name().toLowerCase(), - metalakeName); - } - return metalakeId; + EntityIdentifier metalakeIdentifier = + EntityIdentifier.of(NameIdentifier.of(metalakeName), EntityType.METALAKE); + + return NameIdMappingService.getInstance() + .get( + metalakeIdentifier, + ident -> { + Long metalakeId = + SessionUtils.getWithoutCommit( + MetalakeMetaMapper.class, + mapper -> mapper.selectMetalakeIdMetaByName(metalakeName)); + if (metalakeId == null) { + throw new NoSuchEntityException( + NoSuchEntityException.NO_SUCH_ENTITY_MESSAGE, + Entity.EntityType.METALAKE.name().toLowerCase(), + metalakeName); + } + return metalakeId; + }); } public BaseMetalake getMetalakeByIdentifier(NameIdentifier ident) { diff --git a/core/src/main/java/org/apache/gravitino/storage/relational/service/ModelMetaService.java b/core/src/main/java/org/apache/gravitino/storage/relational/service/ModelMetaService.java index 0197dfdd2dd..018ddd54aa2 100644 --- a/core/src/main/java/org/apache/gravitino/storage/relational/service/ModelMetaService.java +++ b/core/src/main/java/org/apache/gravitino/storage/relational/service/ModelMetaService.java @@ -25,6 +25,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import org.apache.gravitino.Entity; +import org.apache.gravitino.Entity.EntityType; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.Namespace; import org.apache.gravitino.exceptions.NoSuchEntityException; @@ -33,6 +34,7 @@ import org.apache.gravitino.storage.relational.mapper.ModelVersionAliasRelMapper; import org.apache.gravitino.storage.relational.mapper.ModelVersionMetaMapper; import org.apache.gravitino.storage.relational.po.ModelPO; +import org.apache.gravitino.storage.relational.service.NameIdMappingService.EntityIdentifier; import org.apache.gravitino.storage.relational.utils.ExceptionUtils; import org.apache.gravitino.storage.relational.utils.POConverters; import org.apache.gravitino.storage.relational.utils.SessionUtils; @@ -155,6 +157,22 @@ Long getModelIdBySchemaIdAndModelName(Long schemaId, String modelName) { return modelId; } + public Long getModelIdByNameIdentifier(NameIdentifier identifier) { + NameIdentifierUtil.checkModel(identifier); + EntityIdentifier modelIdent = EntityIdentifier.of(identifier, EntityType.MODEL); + + return NameIdMappingService.getInstance() + .get( + modelIdent, + ident -> { + Long schemaId = + CommonMetaService.getInstance() + .getParentEntityIdByNamespace(ident.ident.namespace()); + + return getModelIdBySchemaIdAndModelName(schemaId, ident.ident.name()); + }); + } + ModelPO getModelPOById(Long modelId) { ModelPO modelPO = SessionUtils.getWithoutCommit( diff --git a/core/src/main/java/org/apache/gravitino/storage/relational/service/NameIdMappingService.java b/core/src/main/java/org/apache/gravitino/storage/relational/service/NameIdMappingService.java new file mode 100644 index 00000000000..b54630ab5b3 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/storage/relational/service/NameIdMappingService.java @@ -0,0 +1,174 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.gravitino.storage.relational.service; + +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.Scheduler; +import com.google.common.base.Objects; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import java.io.Closeable; +import java.io.IOException; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import org.apache.gravitino.Entity.EntityType; +import org.apache.gravitino.NameIdentifier; + +public class NameIdMappingService implements Closeable { + + private static volatile NameIdMappingService instance; + + /** + * Cache to store the mapping between the entity identifier and the entity id. + * + *

Note: both the key and value are unique, so we can use BiMap here and get the key by value. + */ + private Cache ident2IdCache; + + private NameIdMappingService() { + this.ident2IdCache = + Caffeine.newBuilder() + .expireAfterAccess(24 * 3600 * 1000L /* 1 day */, TimeUnit.MILLISECONDS) + .maximumSize(1000000) + .initialCapacity(1000) + .scheduler( + Scheduler.forScheduledExecutorService( + new ScheduledThreadPoolExecutor( + 1, + new ThreadFactoryBuilder() + .setDaemon(true) + .setNameFormat("ident-to-id-cleaner-%d") + .build()))) + .build(); + } + + public static class EntityIdentifier { + final NameIdentifier ident; + final EntityType type; + + private EntityIdentifier(NameIdentifier ident, EntityType type) { + this.ident = ident; + this.type = type; + } + + public static EntityIdentifier of(NameIdentifier ident, EntityType type) { + return new EntityIdentifier(ident, type); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof EntityIdentifier)) { + return false; + } + EntityIdentifier that = (EntityIdentifier) o; + return Objects.equal(ident, that.ident) && type == that.type; + } + + @Override + public int hashCode() { + return Objects.hashCode(ident, type); + } + } + + public static NameIdMappingService getInstance() { + if (instance == null) { + synchronized (NameIdMappingService.class) { + if (instance == null) { + instance = new NameIdMappingService(); + } + } + } + + return instance; + } + + public void put(EntityIdentifier key, Long value) { + ident2IdCache.put(key, value); + } + + public Long get(EntityIdentifier key, Function mappingFunction) { + return ident2IdCache.get(key, mappingFunction); + } + + public Long get(EntityIdentifier key) { + return ident2IdCache.getIfPresent(key); + } + + /** + * Get the entity identifier by the entity id. + * + * @param value the entity id + * @param mappingFunction the function to get the entity identifier by the entity id + * @return the entity identifier + */ + public EntityIdentifier getById(Long value, Function mappingFunction) { + synchronized (this) { + BiMap map = HashBiMap.create(ident2IdCache.asMap()); + if (map.containsValue(value)) { + return map.inverse().get(value); + } else { + EntityIdentifier nameIdentifier = mappingFunction.apply(value); + if (nameIdentifier != null) { + ident2IdCache.put(nameIdentifier, value); + } + return nameIdentifier; + } + } + } + + /** + * Get the entity identifier by the entity id. + * + * @param value the entity id + * @return the entity identifier + */ + public EntityIdentifier getById(Long value) { + synchronized (this) { + BiMap map = HashBiMap.create(ident2IdCache.asMap()); + if (map.containsValue(value)) { + return map.inverse().get(value); + } + return null; + } + } + + public void invalidate(EntityIdentifier key) { + ident2IdCache.invalidate(key); + } + + public void invalidateWithPrefix(EntityIdentifier nameIdentifier) { + ident2IdCache.asMap().keySet().stream() + .filter(k -> k.ident.toString().startsWith(nameIdentifier.ident.toString())) + .forEach(ident2IdCache::invalidate); + } + + @Override + public void close() throws IOException { + if (ident2IdCache != null) { + ident2IdCache.invalidateAll(); + ident2IdCache.cleanUp(); + } + } +} diff --git a/core/src/main/java/org/apache/gravitino/storage/relational/service/OwnerMetaService.java b/core/src/main/java/org/apache/gravitino/storage/relational/service/OwnerMetaService.java index 1118467b0a7..d453f21b3df 100644 --- a/core/src/main/java/org/apache/gravitino/storage/relational/service/OwnerMetaService.java +++ b/core/src/main/java/org/apache/gravitino/storage/relational/service/OwnerMetaService.java @@ -18,9 +18,12 @@ */ package org.apache.gravitino.storage.relational.service; +import static org.apache.gravitino.utils.NameIdentifierUtil.getMetalake; + import java.util.Collections; import java.util.Optional; import org.apache.gravitino.Entity; +import org.apache.gravitino.Entity.EntityType; import org.apache.gravitino.MetadataObject; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.authorization.AuthorizationUtils; @@ -44,10 +47,8 @@ public static OwnerMetaService getInstance() { } public Optional getOwner(NameIdentifier identifier, Entity.EntityType type) { - long metalakeId = - MetalakeMetaService.getInstance() - .getMetalakeIdByName(NameIdentifierUtil.getMetalake(identifier)); - Long entityId = getEntityId(metalakeId, identifier, type); + String metalakeName = getMetalake(identifier); + Long entityId = getEntityId(metalakeName, identifier, type); UserPO userPO = SessionUtils.getWithoutCommit( @@ -59,7 +60,7 @@ public Optional getOwner(NameIdentifier identifier, Entity.EntityType ty POConverters.fromUserPO( userPO, Collections.emptyList(), - AuthorizationUtils.ofUserNamespace(NameIdentifierUtil.getMetalake(identifier)))); + AuthorizationUtils.ofUserNamespace(getMetalake(identifier)))); } GroupPO groupPO = @@ -72,7 +73,7 @@ public Optional getOwner(NameIdentifier identifier, Entity.EntityType ty POConverters.fromGroupPO( groupPO, Collections.emptyList(), - AuthorizationUtils.ofGroupNamespace(NameIdentifierUtil.getMetalake(identifier)))); + AuthorizationUtils.ofGroupNamespace(getMetalake(identifier)))); } return Optional.empty(); @@ -83,12 +84,11 @@ public void setOwner( Entity.EntityType entityType, NameIdentifier owner, Entity.EntityType ownerType) { - long metalakeId = - MetalakeMetaService.getInstance() - .getMetalakeIdByName(NameIdentifierUtil.getMetalake(entity)); - - Long entityId = getEntityId(metalakeId, entity, entityType); - Long ownerId = getEntityId(metalakeId, owner, ownerType); + String metalakeName = getMetalake(entity); + Long metalakeId = + getEntityId(metalakeName, NameIdentifier.of(metalakeName), EntityType.METALAKE); + Long entityId = getEntityId(metalakeName, entity, entityType); + Long ownerId = getEntityId(metalakeName, owner, ownerType); OwnerRelPO ownerRelPO = POConverters.initializeOwnerRelPOsWithVersion( @@ -107,18 +107,16 @@ public void setOwner( } private static long getEntityId( - long metalakeId, NameIdentifier identifier, Entity.EntityType type) { + String metalake, NameIdentifier identifier, Entity.EntityType type) { switch (type) { case USER: - return UserMetaService.getInstance() - .getUserIdByMetalakeIdAndName(metalakeId, identifier.name()); + return UserMetaService.getInstance().getUserIdByNameIdentifier(identifier); case GROUP: - return GroupMetaService.getInstance() - .getGroupIdByMetalakeIdAndName(metalakeId, identifier.name()); + return GroupMetaService.getInstance().getGroupIdByNameIdentifier(identifier); default: MetadataObject object = NameIdentifierUtil.toMetadataObject(identifier, type); return MetadataObjectService.getMetadataObjectId( - metalakeId, object.fullName(), object.type()); + metalake, object.fullName(), object.type()); } } } diff --git a/core/src/main/java/org/apache/gravitino/storage/relational/service/RoleMetaService.java b/core/src/main/java/org/apache/gravitino/storage/relational/service/RoleMetaService.java index 3f27902d0c8..17b25ed5daa 100644 --- a/core/src/main/java/org/apache/gravitino/storage/relational/service/RoleMetaService.java +++ b/core/src/main/java/org/apache/gravitino/storage/relational/service/RoleMetaService.java @@ -49,6 +49,7 @@ import org.apache.gravitino.storage.relational.mapper.UserRoleRelMapper; import org.apache.gravitino.storage.relational.po.RolePO; import org.apache.gravitino.storage.relational.po.SecurableObjectPO; +import org.apache.gravitino.storage.relational.service.NameIdMappingService.EntityIdentifier; import org.apache.gravitino.storage.relational.utils.ExceptionUtils; import org.apache.gravitino.storage.relational.utils.POConverters; import org.apache.gravitino.storage.relational.utils.SessionUtils; @@ -82,6 +83,22 @@ public Long getRoleIdByMetalakeIdAndName(Long metalakeId, String roleName) { return roleId; } + public Long getRoleIdByNameIdentifier(NameIdentifier identifier) { + AuthorizationUtils.checkRole(identifier); + + EntityIdentifier entityIdentifier = EntityIdentifier.of(identifier, Entity.EntityType.ROLE); + + return NameIdMappingService.getInstance() + .get( + entityIdentifier, + ident -> { + Long metalakeId = + MetalakeMetaService.getInstance() + .getMetalakeIdByName(ident.ident.namespace().level(0)); + return getRoleIdByMetalakeIdAndName(metalakeId, ident.ident.name()); + }); + } + public List listRolesByUserId(Long userId) { return SessionUtils.getWithoutCommit( RoleMetaMapper.class, mapper -> mapper.listRolesByUserId(userId)); @@ -90,12 +107,11 @@ public List listRolesByUserId(Long userId) { public List listRolesByMetadataObject( NameIdentifier metadataObjectIdent, Entity.EntityType metadataObjectType, boolean allFields) { String metalake = NameIdentifierUtil.getMetalake(metadataObjectIdent); - long metalakeId = MetalakeMetaService.getInstance().getMetalakeIdByName(metalake); MetadataObject metadataObject = NameIdentifierUtil.toMetadataObject(metadataObjectIdent, metadataObjectType); long metadataObjectId = MetadataObjectService.getMetadataObjectId( - metalakeId, metadataObject.fullName(), metadataObject.type()); + metalake, metadataObject.fullName(), metadataObject.type()); List rolePOs = SessionUtils.getWithoutCommit( RoleMetaMapper.class, @@ -125,6 +141,7 @@ public void insertRole(RoleEntity roleEntity, boolean overwritten) throws IOExce try { AuthorizationUtils.checkRole(roleEntity.nameIdentifier()); + String metalakeName = roleEntity.namespace().level(0); Long metalakeId = MetalakeMetaService.getInstance().getMetalakeIdByName(roleEntity.namespace().level(0)); RolePO.Builder builder = RolePO.builder().withMetalakeId(metalakeId); @@ -136,7 +153,7 @@ public void insertRole(RoleEntity roleEntity, boolean overwritten) throws IOExce roleEntity.id(), object, getEntityType(object)); objectBuilder.withMetadataObjectId( MetadataObjectService.getMetadataObjectId( - metalakeId, object.fullName(), object.type())); + metalakeName, object.fullName(), object.type())); securableObjectPOs.add(objectBuilder.build()); } @@ -201,10 +218,10 @@ public RoleEntity updateRole( } List deleteSecurableObjectPOs = - toSecurableObjectPOs(deleteObjects, oldRoleEntity, metalakeId); + toSecurableObjectPOs(deleteObjects, oldRoleEntity, metalake); List insertSecurableObjectPOs = - toSecurableObjectPOs(insertObjects, oldRoleEntity, metalakeId); + toSecurableObjectPOs(insertObjects, oldRoleEntity, metalake); SessionUtils.doMultipleWithCommit( () -> @@ -240,14 +257,15 @@ public RoleEntity updateRole( } private List toSecurableObjectPOs( - Set deleteObjects, RoleEntity oldRoleEntity, Long metalakeId) { + Set deleteObjects, RoleEntity oldRoleEntity, String metalakeName) { List securableObjectPOs = Lists.newArrayList(); for (SecurableObject object : deleteObjects) { SecurableObjectPO.Builder objectBuilder = POConverters.initializeSecurablePOBuilderWithVersion( oldRoleEntity.id(), object, getEntityType(object)); objectBuilder.withMetadataObjectId( - MetadataObjectService.getMetadataObjectId(metalakeId, object.fullName(), object.type())); + MetadataObjectService.getMetadataObjectId( + metalakeName, object.fullName(), object.type())); securableObjectPOs.add(objectBuilder.build()); } return securableObjectPOs; @@ -268,9 +286,7 @@ public RoleEntity getRoleByIdentifier(NameIdentifier identifier) { public boolean deleteRole(NameIdentifier identifier) { AuthorizationUtils.checkRole(identifier); - Long metalakeId = - MetalakeMetaService.getInstance().getMetalakeIdByName(identifier.namespace().level(0)); - Long roleId = getRoleIdByMetalakeIdAndName(metalakeId, identifier.name()); + Long roleId = getRoleIdByNameIdentifier(identifier); SessionUtils.doMultipleWithCommit( () -> diff --git a/core/src/main/java/org/apache/gravitino/storage/relational/service/SchemaMetaService.java b/core/src/main/java/org/apache/gravitino/storage/relational/service/SchemaMetaService.java index f300e70cae3..13788f60457 100644 --- a/core/src/main/java/org/apache/gravitino/storage/relational/service/SchemaMetaService.java +++ b/core/src/main/java/org/apache/gravitino/storage/relational/service/SchemaMetaService.java @@ -47,6 +47,7 @@ import org.apache.gravitino.storage.relational.mapper.TagMetadataObjectRelMapper; import org.apache.gravitino.storage.relational.mapper.TopicMetaMapper; import org.apache.gravitino.storage.relational.po.SchemaPO; +import org.apache.gravitino.storage.relational.service.NameIdMappingService.EntityIdentifier; import org.apache.gravitino.storage.relational.utils.ExceptionUtils; import org.apache.gravitino.storage.relational.utils.POConverters; import org.apache.gravitino.storage.relational.utils.SessionUtils; @@ -99,6 +100,23 @@ public Long getSchemaIdByCatalogIdAndName(Long catalogId, String schemaName) { return schemaId; } + public Long getSchemaIdByNameIdentifier(NameIdentifier identifier) { + EntityIdentifier entityIdentifier = EntityIdentifier.of(identifier, Entity.EntityType.SCHEMA); + return NameIdMappingService.getInstance() + .get( + entityIdentifier, + entityIdent -> { + NameIdentifierUtil.checkSchema(entityIdent.ident); + String schemaName = entityIdent.ident.name(); + + Long catalogId = + CommonMetaService.getInstance() + .getParentEntityIdByNamespace(entityIdent.ident.namespace()); + + return getSchemaIdByCatalogIdAndName(catalogId, schemaName); + }); + } + public SchemaEntity getSchemaByIdentifier(NameIdentifier identifier) { NameIdentifierUtil.checkSchema(identifier); String schemaName = identifier.name(); @@ -189,9 +207,11 @@ public boolean deleteSchema(NameIdentifier identifier, boolean cascade) { NameIdentifierUtil.checkSchema(identifier); String schemaName = identifier.name(); - Long catalogId = - CommonMetaService.getInstance().getParentEntityIdByNamespace(identifier.namespace()); - Long schemaId = getSchemaIdByCatalogIdAndName(catalogId, schemaName); + Long schemaId = getSchemaIdByNameIdentifier(identifier); + + // Invalidate it in the cache. + NameIdMappingService.getInstance() + .invalidate(EntityIdentifier.of(identifier, Entity.EntityType.SCHEMA)); if (schemaId != null) { if (cascade) { @@ -309,9 +329,7 @@ public boolean deleteSchema(NameIdentifier identifier, boolean cascade) { public int deleteSchemaMetasByLegacyTimeline(Long legacyTimeline, int limit) { return SessionUtils.doWithCommitAndFetchResult( SchemaMetaMapper.class, - mapper -> { - return mapper.deleteSchemaMetasByLegacyTimeline(legacyTimeline, limit); - }); + mapper -> mapper.deleteSchemaMetasByLegacyTimeline(legacyTimeline, limit)); } private void fillSchemaPOBuilderParentEntityId(SchemaPO.Builder builder, Namespace namespace) { diff --git a/core/src/main/java/org/apache/gravitino/storage/relational/service/TableMetaService.java b/core/src/main/java/org/apache/gravitino/storage/relational/service/TableMetaService.java index bc44ac43a92..22f81b413b3 100644 --- a/core/src/main/java/org/apache/gravitino/storage/relational/service/TableMetaService.java +++ b/core/src/main/java/org/apache/gravitino/storage/relational/service/TableMetaService.java @@ -38,6 +38,7 @@ import org.apache.gravitino.storage.relational.mapper.TagMetadataObjectRelMapper; import org.apache.gravitino.storage.relational.po.ColumnPO; import org.apache.gravitino.storage.relational.po.TablePO; +import org.apache.gravitino.storage.relational.service.NameIdMappingService.EntityIdentifier; import org.apache.gravitino.storage.relational.utils.ExceptionUtils; import org.apache.gravitino.storage.relational.utils.POConverters; import org.apache.gravitino.storage.relational.utils.SessionUtils; @@ -62,7 +63,7 @@ public TablePO getTablePOById(Long tableId) { return tablePO; } - public Long getTableIdBySchemaIdAndName(Long schemaId, String tableName) { + private Long getTableIdBySchemaIdAndName(Long schemaId, String tableName) { Long tableId = SessionUtils.getWithoutCommit( TableMetaMapper.class, @@ -77,6 +78,22 @@ public Long getTableIdBySchemaIdAndName(Long schemaId, String tableName) { return tableId; } + public Long getTableByNameIdentifier(NameIdentifier identifier) { + NameIdentifierUtil.checkTable(identifier); + EntityIdentifier tableIdentifier = EntityIdentifier.of(identifier, Entity.EntityType.TABLE); + + return NameIdMappingService.getInstance() + .get( + tableIdentifier, + ident -> { + Long schemaId = + CommonMetaService.getInstance() + .getParentEntityIdByNamespace(ident.ident.namespace()); + + return getTableIdBySchemaIdAndName(schemaId, ident.ident.name()); + }); + } + public TableEntity getTableByIdentifier(NameIdentifier identifier) { NameIdentifierUtil.checkTable(identifier); @@ -204,13 +221,7 @@ public TableEntity updateTable( public boolean deleteTable(NameIdentifier identifier) { NameIdentifierUtil.checkTable(identifier); - String tableName = identifier.name(); - - Long schemaId = - CommonMetaService.getInstance().getParentEntityIdByNamespace(identifier.namespace()); - - Long tableId = getTableIdBySchemaIdAndName(schemaId, tableName); - + Long tableId = getTableByNameIdentifier(identifier); AtomicInteger deleteResult = new AtomicInteger(0); SessionUtils.doMultipleWithCommit( () -> diff --git a/core/src/main/java/org/apache/gravitino/storage/relational/service/TagMetaService.java b/core/src/main/java/org/apache/gravitino/storage/relational/service/TagMetaService.java index 5863877ae7b..8ef90b8c07e 100644 --- a/core/src/main/java/org/apache/gravitino/storage/relational/service/TagMetaService.java +++ b/core/src/main/java/org/apache/gravitino/storage/relational/service/TagMetaService.java @@ -162,10 +162,9 @@ public List listTagsForMetadataObject( List tagPOs = null; try { - Long metalakeId = MetalakeMetaService.getInstance().getMetalakeIdByName(metalake); Long metadataObjectId = MetadataObjectService.getMetadataObjectId( - metalakeId, metadataObject.fullName(), metadataObject.type()); + metalake, metadataObject.fullName(), metadataObject.type()); tagPOs = SessionUtils.doWithoutCommitAndFetchResult( @@ -191,10 +190,9 @@ public TagEntity getTagForMetadataObject( TagPO tagPO = null; try { - Long metalakeId = MetalakeMetaService.getInstance().getMetalakeIdByName(metalake); Long metadataObjectId = MetadataObjectService.getMetadataObjectId( - metalakeId, metadataObject.fullName(), metadataObject.type()); + metalake, metadataObject.fullName(), metadataObject.type()); tagPO = SessionUtils.getWithoutCommit( @@ -262,10 +260,9 @@ public List associateTagsWithMetadataObject( String metalake = objectIdent.namespace().level(0); try { - Long metalakeId = MetalakeMetaService.getInstance().getMetalakeIdByName(metalake); Long metadataObjectId = MetadataObjectService.getMetadataObjectId( - metalakeId, metadataObject.fullName(), metadataObject.type()); + metalake, metadataObject.fullName(), metadataObject.type()); // Fetch all the tags need to associate with the metadata object. List tagNamesToAdd = diff --git a/core/src/main/java/org/apache/gravitino/storage/relational/service/TopicMetaService.java b/core/src/main/java/org/apache/gravitino/storage/relational/service/TopicMetaService.java index 66a12aa9de1..e4368bd29ac 100644 --- a/core/src/main/java/org/apache/gravitino/storage/relational/service/TopicMetaService.java +++ b/core/src/main/java/org/apache/gravitino/storage/relational/service/TopicMetaService.java @@ -35,6 +35,7 @@ import org.apache.gravitino.storage.relational.mapper.TagMetadataObjectRelMapper; import org.apache.gravitino.storage.relational.mapper.TopicMetaMapper; import org.apache.gravitino.storage.relational.po.TopicPO; +import org.apache.gravitino.storage.relational.service.NameIdMappingService.EntityIdentifier; import org.apache.gravitino.storage.relational.utils.ExceptionUtils; import org.apache.gravitino.storage.relational.utils.POConverters; import org.apache.gravitino.storage.relational.utils.SessionUtils; @@ -175,12 +176,7 @@ public TopicEntity getTopicByIdentifier(NameIdentifier identifier) { public boolean deleteTopic(NameIdentifier identifier) { NameIdentifierUtil.checkTopic(identifier); - String topicName = identifier.name(); - - Long schemaId = - CommonMetaService.getInstance().getParentEntityIdByNamespace(identifier.namespace()); - - Long topicId = getTopicIdBySchemaIdAndName(schemaId, topicName); + Long topicId = getTopicIdByNameIdentifier(identifier); SessionUtils.doMultipleWithCommit( () -> @@ -216,7 +212,22 @@ public int deleteTopicMetasByLegacyTimeline(Long legacyTimeline, int limit) { }); } - public Long getTopicIdBySchemaIdAndName(Long schemaId, String topicName) { + public Long getTopicIdByNameIdentifier(NameIdentifier identifier) { + NameIdentifierUtil.checkTopic(identifier); + + EntityIdentifier topicEntity = EntityIdentifier.of(identifier, Entity.EntityType.TOPIC); + return NameIdMappingService.getInstance() + .get( + topicEntity, + ident -> { + Long schemaId = + CommonMetaService.getInstance() + .getParentEntityIdByNamespace(ident.ident.namespace()); + return getTopicIdBySchemaIdAndName(schemaId, ident.ident.name()); + }); + } + + private Long getTopicIdBySchemaIdAndName(Long schemaId, String topicName) { Long topicId = SessionUtils.getWithoutCommit( TopicMetaMapper.class, diff --git a/core/src/main/java/org/apache/gravitino/storage/relational/service/UserMetaService.java b/core/src/main/java/org/apache/gravitino/storage/relational/service/UserMetaService.java index a8991da14b1..deb801c9666 100644 --- a/core/src/main/java/org/apache/gravitino/storage/relational/service/UserMetaService.java +++ b/core/src/main/java/org/apache/gravitino/storage/relational/service/UserMetaService.java @@ -44,6 +44,7 @@ import org.apache.gravitino.storage.relational.po.RolePO; import org.apache.gravitino.storage.relational.po.UserPO; import org.apache.gravitino.storage.relational.po.UserRoleRelPO; +import org.apache.gravitino.storage.relational.service.NameIdMappingService.EntityIdentifier; import org.apache.gravitino.storage.relational.utils.ExceptionUtils; import org.apache.gravitino.storage.relational.utils.POConverters; import org.apache.gravitino.storage.relational.utils.SessionUtils; @@ -88,6 +89,21 @@ public Long getUserIdByMetalakeIdAndName(Long metalakeId, String userName) { return userId; } + public Long getUserIdByNameIdentifier(NameIdentifier identifier) { + AuthorizationUtils.checkUser(identifier); + + EntityIdentifier userIdIdentifier = EntityIdentifier.of(identifier, Entity.EntityType.USER); + return NameIdMappingService.getInstance() + .get( + userIdIdentifier, + ident -> { + Long metalakeId = + MetalakeMetaService.getInstance() + .getMetalakeIdByName(ident.ident.namespace().level(0)); + return getUserIdByMetalakeIdAndName(metalakeId, ident.ident.name()); + }); + } + public UserEntity getUserByIdentifier(NameIdentifier identifier) { AuthorizationUtils.checkUser(identifier); @@ -159,10 +175,7 @@ public void insertUser(UserEntity userEntity, boolean overwritten) throws IOExce public boolean deleteUser(NameIdentifier identifier) { AuthorizationUtils.checkUser(identifier); - - Long metalakeId = - MetalakeMetaService.getInstance().getMetalakeIdByName(identifier.namespace().level(0)); - Long userId = getUserIdByMetalakeIdAndName(metalakeId, identifier.name()); + Long userId = getUserIdByNameIdentifier(identifier); SessionUtils.doMultipleWithCommit( () -> diff --git a/core/src/test/java/org/apache/gravitino/storage/relational/service/TestIdNameMappingService.java b/core/src/test/java/org/apache/gravitino/storage/relational/service/TestIdNameMappingService.java new file mode 100644 index 00000000000..64becc9b8f3 --- /dev/null +++ b/core/src/test/java/org/apache/gravitino/storage/relational/service/TestIdNameMappingService.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.gravitino.storage.relational.service; + +import java.io.IOException; +import org.apache.gravitino.Entity.EntityType; +import org.apache.gravitino.NameIdentifier; +import org.apache.gravitino.storage.relational.service.NameIdMappingService.EntityIdentifier; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class TestIdNameMappingService { + + @Test + public void testGetInstance() throws IOException { + NameIdMappingService instance = NameIdMappingService.getInstance(); + + EntityIdentifier metalakeIdent1 = + EntityIdentifier.of(NameIdentifier.of("m1"), EntityType.METALAKE); + EntityIdentifier metalakeIdent2 = + EntityIdentifier.of(NameIdentifier.of("m2"), EntityType.METALAKE); + + instance.put(metalakeIdent1, 1L); + Assertions.assertEquals(1L, instance.get(metalakeIdent1, (EntityIdentifier key) -> 1L)); + + instance.put(metalakeIdent2, 2L); + Assertions.assertEquals(2L, instance.get(metalakeIdent2)); + + instance.invalidate(metalakeIdent2); + Assertions.assertNull(instance.get(metalakeIdent2)); + + Assertions.assertEquals(metalakeIdent1, instance.getById(1L)); + + Assertions.assertEquals(metalakeIdent2, instance.getById(2L, (Long value) -> metalakeIdent2)); + + instance.close(); + } +}