jerryshao commented on code in PR #4109:
URL: https://github.com/apache/gravitino/pull/4109#discussion_r1675480786
##########
core/src/main/java/com/datastrato/gravitino/tag/TagManager.java:
##########
@@ -188,22 +203,147 @@ public boolean deleteTag(String metalake, String name) {
});
}
- public String[] listTagsForMetadataObject(String metalake, MetadataObject
metadataObject) {
- throw new UnsupportedOperationException("Not implemented yet");
+ public MetadataObject[] listMetadataObjectsForTag(String metalake, String
name)
+ throws NoSuchTagException {
+ NameIdentifier tagId = ofTagIdent(metalake, name);
+ return TreeLockUtils.doWithTreeLock(
+ tagId,
+ LockType.READ,
+ () -> {
+ try {
+ if (!entityStore.exists(tagId, Entity.EntityType.TAG)) {
+ throw new NoSuchTagException(
+ "Tag with name %s under metalake %s does not exist", name,
metalake);
+ }
+
+ return supportsTagOperations
+ .listAssociatedMetadataObjectsForTag(tagId)
+ .toArray(new MetadataObject[0]);
+ } catch (IOException e) {
+ LOG.error("Failed to list metadata objects for tag {}", name, e);
+ throw new RuntimeException(e);
+ }
+ });
+ }
+
+ public String[] listTagsForMetadataObject(String metalake, MetadataObject
metadataObject)
+ throws NotFoundException {
+ return Arrays.stream(listTagsInfoForMetadataObject(metalake,
metadataObject))
+ .map(Tag::name)
+ .toArray(String[]::new);
}
- public Tag[] listTagsInfoForMetadataObject(String metalake, MetadataObject
metadataObject) {
- throw new UnsupportedOperationException("Not implemented yet");
+ public Tag[] listTagsInfoForMetadataObject(String metalake, MetadataObject
metadataObject)
+ throws NotFoundException {
+ NameIdentifier entityIdent = MetadataObjectUtil.toEntityIdent(metalake,
metadataObject);
+ Entity.EntityType entityType =
MetadataObjectUtil.toEntityType(metadataObject);
+
+ return TreeLockUtils.doWithTreeLock(
+ entityIdent,
+ LockType.READ,
+ () -> {
+ try {
+ return supportsTagOperations
+ .listAssociatedTagsForMetadataObject(entityIdent, entityType)
+ .toArray(new Tag[0]);
+ } catch (NoSuchEntityException e) {
+ throw new NotFoundException(
+ e, "Failed to list tags for metadata object %s due to not
found", metadataObject);
+ } catch (IOException e) {
+ LOG.error("Failed to list tags for metadata object {}",
metadataObject, e);
+ throw new RuntimeException(e);
+ }
+ });
}
public Tag getTagForMetadataObject(String metalake, MetadataObject
metadataObject, String name)
- throws NoSuchTagException {
- throw new UnsupportedOperationException("Not implemented yet");
+ throws NotFoundException {
+ NameIdentifier entityIdent = MetadataObjectUtil.toEntityIdent(metalake,
metadataObject);
+ Entity.EntityType entityType =
MetadataObjectUtil.toEntityType(metadataObject);
+ NameIdentifier tagIdent = ofTagIdent(metalake, name);
+
+ return TreeLockUtils.doWithTreeLock(
+ entityIdent,
+ LockType.READ,
+ () -> {
+ try {
+ return supportsTagOperations.getTagForMetadataObject(entityIdent,
entityType, tagIdent);
+ } catch (NoSuchEntityException e) {
+ if (e.getMessage().contains("No such tag entity")) {
+ throw new NoSuchTagException(
+ e, "Tag %s does not exist for metadata object %s", name,
metadataObject);
+ } else {
+ throw new NotFoundException(
+ e, "Failed to get tag for metadata object %s due to not
found", metadataObject);
+ }
+ } catch (IOException e) {
+ LOG.error("Failed to get tag for metadata object {}",
metadataObject, e);
+ throw new RuntimeException(e);
+ }
+ });
}
public String[] associateTagsForMetadataObject(
- String metalake, MetadataObject metadataObject, String[] tagsToAdd,
String[] tagsToRemove) {
- throw new UnsupportedOperationException("Not implemented yet");
+ String metalake, MetadataObject metadataObject, String[] tagsToAdd,
String[] tagsToRemove)
+ throws NotFoundException, TagAlreadyAssociatedException {
+ Preconditions.checkArgument(
+ !metadataObject.type().equals(MetadataObject.Type.METALAKE)
+ && !metadataObject.type().equals(MetadataObject.Type.COLUMN),
+ "Cannot associate tags for unsupported metadata object type %s",
+ metadataObject.type());
+
+ NameIdentifier entityIdent = MetadataObjectUtil.toEntityIdent(metalake,
metadataObject);
+ Entity.EntityType entityType =
MetadataObjectUtil.toEntityType(metadataObject);
+
+ // Remove all the tags that are both set to add and remove
+ Set<String> tagsToAddSet = tagsToAdd == null ? Sets.newHashSet() :
Sets.newHashSet(tagsToAdd);
+ Set<String> tagsToRemoveSet =
+ tagsToRemove == null ? Sets.newHashSet() :
Sets.newHashSet(tagsToRemove);
+ Set<String> common = Sets.intersection(tagsToAddSet,
tagsToRemoveSet).immutableCopy();
+ tagsToAddSet.removeAll(common);
+ tagsToRemoveSet.removeAll(common);
+
+ NameIdentifier[] tagsToAddIdent =
+ tagsToAddSet.stream().map(tag -> ofTagIdent(metalake,
tag)).toArray(NameIdentifier[]::new);
+ NameIdentifier[] tagsToRemoveIdent =
+ tagsToRemoveSet.stream()
+ .map(tag -> ofTagIdent(metalake, tag))
+ .toArray(NameIdentifier[]::new);
+
+ // TODO. We need to add a write lock to Tag's namespace to avoid tag
alteration and deletion
+ // during the association operation.
+ return TreeLockUtils.doWithTreeLock(
+ entityIdent,
+ LockType.READ,
+ () ->
+ TreeLockUtils.doWithTreeLock(
+ NameIdentifier.of(ofTagNamespace(metalake).levels()),
+ LockType.WRITE,
Review Comment:
@yuqi1129 please check this double tree lock implementation here.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]