diff --git a/core/src/main/java/org/apache/gravitino/GravitinoEnv.java b/core/src/main/java/org/apache/gravitino/GravitinoEnv.java index db6ddc235fd..96c60b834fc 100644 --- a/core/src/main/java/org/apache/gravitino/GravitinoEnv.java +++ b/core/src/main/java/org/apache/gravitino/GravitinoEnv.java @@ -62,6 +62,7 @@ import org.apache.gravitino.listener.PartitionEventDispatcher; import org.apache.gravitino.listener.SchemaEventDispatcher; import org.apache.gravitino.listener.TableEventDispatcher; +import org.apache.gravitino.listener.TagEventDispatcher; import org.apache.gravitino.listener.TopicEventDispatcher; import org.apache.gravitino.lock.LockManager; import org.apache.gravitino.metalake.MetalakeDispatcher; @@ -71,6 +72,7 @@ import org.apache.gravitino.metrics.source.JVMMetricsSource; import org.apache.gravitino.storage.IdGenerator; import org.apache.gravitino.storage.RandomIdGenerator; +import org.apache.gravitino.tag.TagDispatcher; import org.apache.gravitino.tag.TagManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -108,6 +110,8 @@ public class GravitinoEnv { private CredentialManager credentialManager; + private TagDispatcher tagDispatcher; + private AccessControlDispatcher accessControlDispatcher; private IdGenerator idGenerator; @@ -122,7 +126,6 @@ public class GravitinoEnv { private AuditLogManager auditLogManager; - private TagManager tagManager; private EventBus eventBus; private OwnerManager ownerManager; private FutureGrantManager futureGrantManager; @@ -321,12 +324,12 @@ public AccessControlDispatcher accessControlDispatcher() { } /** - * Get the TagManager associated with the Gravitino environment. + * Get the tagDispatcher associated with the Gravitino environment. * - * @return The TagManager instance. + * @return The tagDispatcher instance. */ - public TagManager tagManager() { - return tagManager; + public TagDispatcher tagDispatcher() { + return tagDispatcher; } /** @@ -497,7 +500,7 @@ private void initGravitinoServerComponents() { // Tree lock this.lockManager = new LockManager(config); - // Tag manager - this.tagManager = new TagManager(idGenerator, entityStore); + // Create and initialize Tag related modules + this.tagDispatcher = new TagEventDispatcher(eventBus, new TagManager(idGenerator, entityStore)); } } diff --git a/core/src/main/java/org/apache/gravitino/listener/TagEventDispatcher.java b/core/src/main/java/org/apache/gravitino/listener/TagEventDispatcher.java new file mode 100644 index 00000000000..90ca0fda23d --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/TagEventDispatcher.java @@ -0,0 +1,180 @@ +/* + * 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.listener; + +import java.util.Map; +import org.apache.gravitino.MetadataObject; +import org.apache.gravitino.exceptions.NoSuchTagException; +import org.apache.gravitino.tag.Tag; +import org.apache.gravitino.tag.TagChange; +import org.apache.gravitino.tag.TagDispatcher; + +/** + * {@code TagEventDispatcher} is a decorator for {@link TagDispatcher} that not only delegates tag + * operations to the underlying tag dispatcher but also dispatches corresponding events to an {@link + * EventBus} after each operation is completed. This allows for event-driven workflows or monitoring + * of tag operations. + */ +public class TagEventDispatcher implements TagDispatcher { + @SuppressWarnings("unused") + private final EventBus eventBus; + + @SuppressWarnings("unused") + private final TagDispatcher dispatcher; + + public TagEventDispatcher(EventBus eventBus, TagDispatcher dispatcher) { + this.eventBus = eventBus; + this.dispatcher = dispatcher; + } + + @Override + public String[] listTags(String metalake) { + // TODO: listTagsPreEvent + try { + // TODO: listTagsEvent + return dispatcher.listTags(metalake); + } catch (Exception e) { + // TODO: listTagFailureEvent + throw e; + } + } + + @Override + public Tag[] listTagsInfo(String metalake) { + // TODO: listTagsInfoPreEvent + try { + // TODO: listTagsInfoEvent + return dispatcher.listTagsInfo(metalake); + } catch (Exception e) { + // TODO: listTagsInfoFailureEvent + throw e; + } + } + + @Override + public Tag getTag(String metalake, String name) throws NoSuchTagException { + // TODO: getTagPreEvent + try { + // TODO: getTagEvent + return dispatcher.getTag(metalake, name); + } catch (NoSuchTagException e) { + // TODO: getTagFailureEvent + throw e; + } + } + + @Override + public Tag createTag( + String metalake, String name, String comment, Map properties) { + // TODO: createTagPreEvent + try { + // TODO: createTagEvent + return dispatcher.createTag(metalake, name, comment, properties); + } catch (Exception e) { + // TODO: createTagFailureEvent + throw e; + } + } + + @Override + public Tag alterTag(String metalake, String name, TagChange... changes) { + // TODO: alterTagPreEvent + try { + // TODO: alterTagEvent + return dispatcher.alterTag(metalake, name, changes); + } catch (Exception e) { + // TODO: alterTagFailureEvent + throw e; + } + } + + @Override + public boolean deleteTag(String metalake, String name) { + // TODO: deleteTagPreEvent + try { + // TODO: deleteTagEvent + return dispatcher.deleteTag(metalake, name); + } catch (Exception e) { + // TODO: deleteTagFailureEvent + throw e; + } + } + + @Override + public MetadataObject[] listMetadataObjectsForTag(String metalake, String name) { + // TODO: listMetadataObjectsForTagPreEvent + try { + // TODO: listMetadataObjectsForTagEvent + return dispatcher.listMetadataObjectsForTag(metalake, name); + } catch (Exception e) { + // TODO: listMetadataObjectsForTagFailureEvent + throw e; + } + } + + @Override + public String[] listTagsForMetadataObject(String metalake, MetadataObject metadataObject) { + // TODO: listTagsForMetadataObjectPreEvent + try { + // TODO: listTagsForMetadataObjectEvent + return dispatcher.listTagsForMetadataObject(metalake, metadataObject); + } catch (Exception e) { + // TODO: listTagsForMetadataObjectFailureEvent + throw e; + } + } + + @Override + public Tag[] listTagsInfoForMetadataObject(String metalake, MetadataObject metadataObject) { + // TODO: listTagsInfoForMetadataObjectPreEvent + try { + // TODO: listTagsInfoForMetadataObjectEvent + return dispatcher.listTagsInfoForMetadataObject(metalake, metadataObject); + } catch (Exception e) { + // TODO: listTagsInfoForMetadataObjectFailureEvent + throw e; + } + } + + @Override + public String[] associateTagsForMetadataObject( + String metalake, MetadataObject metadataObject, String[] tagsToAdd, String[] tagsToRemove) { + // TODO: associateTagsForMetadataObjectPreEvent + try { + // TODO: associateTagsForMetadataObjectEvent + return dispatcher.associateTagsForMetadataObject( + metalake, metadataObject, tagsToAdd, tagsToRemove); + } catch (Exception e) { + // TODO: associateTagsForMetadataObjectFailureEvent + throw e; + } + } + + @Override + public Tag getTagForMetadataObject(String metalake, MetadataObject metadataObject, String name) { + // TODO: getTagForMetadataObjectPreEvent + try { + // TODO: getTagForMetadataObjectEvent + return dispatcher.getTagForMetadataObject(metalake, metadataObject, name); + } catch (Exception e) { + // TODO: getTagForMetadataObjectFailureEvent + throw e; + } + } +} diff --git a/core/src/main/java/org/apache/gravitino/tag/TagDispatcher.java b/core/src/main/java/org/apache/gravitino/tag/TagDispatcher.java new file mode 100644 index 00000000000..0070e27179c --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/tag/TagDispatcher.java @@ -0,0 +1,133 @@ +/* + * 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.tag; + +import java.util.Map; +import org.apache.gravitino.MetadataObject; +import org.apache.gravitino.exceptions.NoSuchTagException; + +/** + * {@code TagDispatcher} interface provides functionalities for managing tags within a metalake. It + * includes a comprehensive set of operations such as listing, creating, retrieving, updating, and + * deleting tags, as well as associating tags with other objects. + */ +public interface TagDispatcher { + /** + * List all the tag names for the specific object. + * + * @return The list of tag names. + */ + String[] listTags(String metalake); + + /** + * List all the tags with details for the specific object. + * + * @return The list of tags. + */ + Tag[] listTagsInfo(String metalake); + + /** + * Get a tag by its name for the specific object. + * + * @param name The name of the tag. + * @param metalake The name of the metalake + * @return The tag. + * @throws NoSuchTagException If the tag does not associate with the object. + */ + Tag getTag(String metalake, String name) throws NoSuchTagException; + + /** + * Create a new tag in the specified metalake. + * + * @param metalake The name of the metalake + * @param name The name of the tag + * @param comment A comment for the new tag. + * @param properties The properties of the tag. + * @return The created tag. + */ + Tag createTag(String metalake, String name, String comment, Map properties); + + /** + * Alter an existing tag in the specified metalake + * + * @param metalake The name of the metalake. + * @param name The name of the tag. + * @param changes The changes to apply to the tag. + * @return The updated tag. + */ + Tag alterTag(String metalake, String name, TagChange... changes); + + /** + * delete an existing tag in the specified metalake + * + * @param metalake The name of the metalake. + * @param name The name of the tag. + * @return True if the tag was successfully deleted, false otherwise + */ + boolean deleteTag(String metalake, String name); + + /** + * List all metadata objects associated with the specified tag. + * + * @param metalake The name of the metalake. + * @param name The name of the tag. + * @return The array of metadata objects associated with the specified tag. + */ + MetadataObject[] listMetadataObjectsForTag(String metalake, String name); + + /** + * List all tag names associated with the specified metadata object. + * + * @param metalake The name of the metalake + * @param metadataObject The metadata object for which associated tags + * @return The list of tag names associated with the given metadata object. + */ + String[] listTagsForMetadataObject(String metalake, MetadataObject metadataObject); + + /** + * List detailed information for all tags associated with the specified metadata object. + * + * @param metalake The name of the metalake + * @param metadataObject The metadata object to query tag details for. + * @return An array of tags with detailed information. + */ + Tag[] listTagsInfoForMetadataObject(String metalake, MetadataObject metadataObject); + + /** + * Associate or disassociate tags with the specified metadata object. + * + * @param metalake The name of the metalake. + * @param metadataObject The metadata object to update tags for. + * @param tagsToAdd Tags to associate with the object. + * @param tagsToRemove Tags to disassociate from the object. + * @return An array of updated tag names. + */ + String[] associateTagsForMetadataObject( + String metalake, MetadataObject metadataObject, String[] tagsToAdd, String[] tagsToRemove); + + /** + * Retrieve a specific tag associated with the specified metadata object. + * + * @param metalake The name of the metalake. + * @param metadataObject The metadata object to query the tag for. + * @param name The name of the tag to retrieve. + * @return The tag associated with the metadata object. + */ + Tag getTagForMetadataObject(String metalake, MetadataObject metadataObject, String name); +} diff --git a/core/src/main/java/org/apache/gravitino/tag/TagManager.java b/core/src/main/java/org/apache/gravitino/tag/TagManager.java index 30fa658130e..f7932fe2607 100644 --- a/core/src/main/java/org/apache/gravitino/tag/TagManager.java +++ b/core/src/main/java/org/apache/gravitino/tag/TagManager.java @@ -51,7 +51,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class TagManager { +public class TagManager implements TagDispatcher { private static final Logger LOG = LoggerFactory.getLogger(TagManager.class); diff --git a/server/src/main/java/org/apache/gravitino/server/GravitinoServer.java b/server/src/main/java/org/apache/gravitino/server/GravitinoServer.java index 554791fff3c..16a2096f328 100644 --- a/server/src/main/java/org/apache/gravitino/server/GravitinoServer.java +++ b/server/src/main/java/org/apache/gravitino/server/GravitinoServer.java @@ -47,7 +47,7 @@ import org.apache.gravitino.server.web.mapper.JsonParseExceptionMapper; import org.apache.gravitino.server.web.mapper.JsonProcessingExceptionMapper; import org.apache.gravitino.server.web.ui.WebUIFilter; -import org.apache.gravitino.tag.TagManager; +import org.apache.gravitino.tag.TagDispatcher; import org.glassfish.hk2.utilities.binding.AbstractBinder; import org.glassfish.jersey.CommonProperties; import org.glassfish.jersey.jackson.JacksonFeature; @@ -114,7 +114,7 @@ protected void configure() { bind(gravitinoEnv.partitionDispatcher()).to(PartitionDispatcher.class).ranked(1); bind(gravitinoEnv.filesetDispatcher()).to(FilesetDispatcher.class).ranked(1); bind(gravitinoEnv.topicDispatcher()).to(TopicDispatcher.class).ranked(1); - bind(gravitinoEnv.tagManager()).to(TagManager.class).ranked(1); + bind(gravitinoEnv.tagDispatcher()).to(TagDispatcher.class).ranked(1); bind(gravitinoEnv.credentialManager()).to(CredentialManager.class).ranked(1); } }); diff --git a/server/src/main/java/org/apache/gravitino/server/web/rest/MetadataObjectTagOperations.java b/server/src/main/java/org/apache/gravitino/server/web/rest/MetadataObjectTagOperations.java index c8668d225f8..9c3eda52b38 100644 --- a/server/src/main/java/org/apache/gravitino/server/web/rest/MetadataObjectTagOperations.java +++ b/server/src/main/java/org/apache/gravitino/server/web/rest/MetadataObjectTagOperations.java @@ -50,7 +50,7 @@ import org.apache.gravitino.metrics.MetricNames; import org.apache.gravitino.server.web.Utils; import org.apache.gravitino.tag.Tag; -import org.apache.gravitino.tag.TagManager; +import org.apache.gravitino.tag.TagDispatcher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,13 +58,13 @@ public class MetadataObjectTagOperations { private static final Logger LOG = LoggerFactory.getLogger(MetadataObjectTagOperations.class); - private final TagManager tagManager; + private final TagDispatcher tagDispatcher; @Context private HttpServletRequest httpRequest; @Inject - public MetadataObjectTagOperations(TagManager tagManager) { - this.tagManager = tagManager; + public MetadataObjectTagOperations(TagDispatcher tagDispatcher) { + this.tagDispatcher = tagDispatcher; } // TagOperations will reuse this class to be compatible with legacy interfaces. @@ -164,7 +164,7 @@ public Response listTagsForMetadataObject( fullName, MetadataObject.Type.valueOf(type.toUpperCase(Locale.ROOT))); List tags = Lists.newArrayList(); - Tag[] nonInheritedTags = tagManager.listTagsInfoForMetadataObject(metalake, object); + Tag[] nonInheritedTags = tagDispatcher.listTagsInfoForMetadataObject(metalake, object); if (ArrayUtils.isNotEmpty(nonInheritedTags)) { Collections.addAll( tags, @@ -176,7 +176,7 @@ public Response listTagsForMetadataObject( MetadataObject parentObject = MetadataObjects.parent(object); while (parentObject != null) { Tag[] inheritedTags = - tagManager.listTagsInfoForMetadataObject(metalake, parentObject); + tagDispatcher.listTagsInfoForMetadataObject(metalake, parentObject); if (ArrayUtils.isNotEmpty(inheritedTags)) { Collections.addAll( tags, @@ -240,7 +240,7 @@ public Response associateTagsForObject( MetadataObjects.parse( fullName, MetadataObject.Type.valueOf(type.toUpperCase(Locale.ROOT))); String[] tagNames = - tagManager.associateTagsForMetadataObject( + tagDispatcher.associateTagsForMetadataObject( metalake, object, request.getTagsToAdd(), request.getTagsToRemove()); tagNames = tagNames == null ? new String[0] : tagNames; @@ -260,7 +260,7 @@ public Response associateTagsForObject( private Optional getTagForObject(String metalake, MetadataObject object, String tagName) { try { - return Optional.ofNullable(tagManager.getTagForMetadataObject(metalake, object, tagName)); + return Optional.ofNullable(tagDispatcher.getTagForMetadataObject(metalake, object, tagName)); } catch (NoSuchTagException e) { LOG.info("Tag {} not found for object: {}", tagName, object); return Optional.empty(); diff --git a/server/src/main/java/org/apache/gravitino/server/web/rest/TagOperations.java b/server/src/main/java/org/apache/gravitino/server/web/rest/TagOperations.java index 7fdd2fc6965..68ed8a2c2f0 100644 --- a/server/src/main/java/org/apache/gravitino/server/web/rest/TagOperations.java +++ b/server/src/main/java/org/apache/gravitino/server/web/rest/TagOperations.java @@ -53,7 +53,7 @@ import org.apache.gravitino.server.web.Utils; import org.apache.gravitino.tag.Tag; import org.apache.gravitino.tag.TagChange; -import org.apache.gravitino.tag.TagManager; +import org.apache.gravitino.tag.TagDispatcher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -62,13 +62,13 @@ public class TagOperations { private static final Logger LOG = LoggerFactory.getLogger(TagOperations.class); - private final TagManager tagManager; + private final TagDispatcher tagDispatcher; @Context private HttpServletRequest httpRequest; @Inject - public TagOperations(TagManager tagManager) { - this.tagManager = tagManager; + public TagOperations(TagDispatcher tagDispatcher) { + this.tagDispatcher = tagDispatcher; } @GET @@ -86,7 +86,7 @@ public Response listTags( httpRequest, () -> { if (verbose) { - Tag[] tags = tagManager.listTagsInfo(metalake); + Tag[] tags = tagDispatcher.listTagsInfo(metalake); TagDTO[] tagDTOs; if (ArrayUtils.isEmpty(tags)) { tagDTOs = new TagDTO[0]; @@ -101,7 +101,7 @@ public Response listTags( return Utils.ok(new TagListResponse(tagDTOs)); } else { - String[] tagNames = tagManager.listTags(metalake); + String[] tagNames = tagDispatcher.listTags(metalake); tagNames = tagNames == null ? new String[0] : tagNames; LOG.info("List {} tags under metalake: {}", tagNames.length, metalake); @@ -126,7 +126,7 @@ public Response createTag(@PathParam("metalake") String metalake, TagCreateReque () -> { request.validate(); Tag tag = - tagManager.createTag( + tagDispatcher.createTag( metalake, request.getName(), request.getComment(), request.getProperties()); LOG.info("Created tag: {} under metalake: {}", tag.name(), metalake); @@ -150,7 +150,7 @@ public Response getTag(@PathParam("metalake") String metalake, @PathParam("tag") return Utils.doAs( httpRequest, () -> { - Tag tag = tagManager.getTag(metalake, name); + Tag tag = tagDispatcher.getTag(metalake, name); LOG.info("Get tag: {} under metalake: {}", name, metalake); return Utils.ok(new TagResponse(DTOConverters.toDTO(tag, Optional.empty()))); }); @@ -180,7 +180,7 @@ public Response alterTag( request.getUpdates().stream() .map(TagUpdateRequest::tagChange) .toArray(TagChange[]::new); - Tag tag = tagManager.alterTag(metalake, name, changes); + Tag tag = tagDispatcher.alterTag(metalake, name, changes); LOG.info("Altered tag: {} under metalake: {}", name, metalake); return Utils.ok(new TagResponse(DTOConverters.toDTO(tag, Optional.empty()))); @@ -202,7 +202,7 @@ public Response deleteTag(@PathParam("metalake") String metalake, @PathParam("ta return Utils.doAs( httpRequest, () -> { - boolean deleted = tagManager.deleteTag(metalake, name); + boolean deleted = tagDispatcher.deleteTag(metalake, name); if (!deleted) { LOG.warn("Failed to delete tag {} under metalake {}", name, metalake); } else { @@ -229,7 +229,7 @@ public Response listMetadataObjectsForTag( return Utils.doAs( httpRequest, () -> { - MetadataObject[] objects = tagManager.listMetadataObjectsForTag(metalake, tagName); + MetadataObject[] objects = tagDispatcher.listMetadataObjectsForTag(metalake, tagName); objects = objects == null ? new MetadataObject[0] : objects; LOG.info( @@ -260,7 +260,7 @@ public Response listTagsForMetadataObject( @PathParam("fullName") String fullName, @QueryParam("details") @DefaultValue("false") boolean verbose) { MetadataObjectTagOperations metadataObjectTagOperations = - new MetadataObjectTagOperations(tagManager); + new MetadataObjectTagOperations(tagDispatcher); metadataObjectTagOperations.setHttpRequest(httpRequest); return metadataObjectTagOperations.listTagsForMetadataObject(metalake, type, fullName, verbose); } @@ -277,7 +277,7 @@ public Response getTagForObject( @PathParam("fullName") String fullName, @PathParam("tag") String tagName) { MetadataObjectTagOperations metadataObjectTagOperations = - new MetadataObjectTagOperations(tagManager); + new MetadataObjectTagOperations(tagDispatcher); metadataObjectTagOperations.setHttpRequest(httpRequest); return metadataObjectTagOperations.getTagForObject(metalake, type, fullName, tagName); } @@ -294,7 +294,7 @@ public Response associateTagsForObject( @PathParam("fullName") String fullName, TagsAssociateRequest request) { MetadataObjectTagOperations metadataObjectTagOperations = - new MetadataObjectTagOperations(tagManager); + new MetadataObjectTagOperations(tagDispatcher); metadataObjectTagOperations.setHttpRequest(httpRequest); return metadataObjectTagOperations.associateTagsForObject(metalake, type, fullName, request); } diff --git a/server/src/test/java/org/apache/gravitino/server/web/rest/TestMetadataObjectTagOperations.java b/server/src/test/java/org/apache/gravitino/server/web/rest/TestMetadataObjectTagOperations.java index 8e0324bea2b..8a1d09d21e8 100644 --- a/server/src/test/java/org/apache/gravitino/server/web/rest/TestMetadataObjectTagOperations.java +++ b/server/src/test/java/org/apache/gravitino/server/web/rest/TestMetadataObjectTagOperations.java @@ -50,6 +50,7 @@ import org.apache.gravitino.meta.TagEntity; import org.apache.gravitino.rest.RESTUtils; import org.apache.gravitino.tag.Tag; +import org.apache.gravitino.tag.TagDispatcher; import org.apache.gravitino.tag.TagManager; import org.glassfish.jersey.internal.inject.AbstractBinder; import org.glassfish.jersey.server.ResourceConfig; @@ -92,7 +93,7 @@ protected Application configure() { new AbstractBinder() { @Override protected void configure() { - bind(tagManager).to(TagManager.class).ranked(2); + bind(tagManager).to(TagDispatcher.class).ranked(2); bindFactory(MockServletRequestFactory.class).to(HttpServletRequest.class); } }); diff --git a/server/src/test/java/org/apache/gravitino/server/web/rest/TestTagOperations.java b/server/src/test/java/org/apache/gravitino/server/web/rest/TestTagOperations.java index 23b87b60d28..50258239c6e 100644 --- a/server/src/test/java/org/apache/gravitino/server/web/rest/TestTagOperations.java +++ b/server/src/test/java/org/apache/gravitino/server/web/rest/TestTagOperations.java @@ -60,6 +60,7 @@ import org.apache.gravitino.rest.RESTUtils; import org.apache.gravitino.tag.Tag; import org.apache.gravitino.tag.TagChange; +import org.apache.gravitino.tag.TagDispatcher; import org.apache.gravitino.tag.TagManager; import org.glassfish.jersey.internal.inject.AbstractBinder; import org.glassfish.jersey.server.ResourceConfig; @@ -102,7 +103,7 @@ protected Application configure() { new AbstractBinder() { @Override protected void configure() { - bind(tagManager).to(TagManager.class).ranked(2); + bind(tagManager).to(TagDispatcher.class).ranked(2); bindFactory(TestTagOperations.MockServletRequestFactory.class) .to(HttpServletRequest.class); }