Skip to content

Commit

Permalink
[apache#4236] feat(core): Supports the post-hook for the managers or …
Browse files Browse the repository at this point in the history
…dispatcher
  • Loading branch information
jerqi committed Jul 23, 2024
1 parent 9be7cc9 commit cd3526b
Show file tree
Hide file tree
Showing 12 changed files with 562 additions and 166 deletions.
55 changes: 43 additions & 12 deletions core/src/main/java/org/apache/gravitino/GravitinoEnv.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
package org.apache.gravitino;

import com.google.common.base.Preconditions;
import org.apache.gravitino.authorization.AccessControlDispatcher;
import org.apache.gravitino.authorization.AccessControlManager;
import org.apache.gravitino.authorization.AuthorizationUtils;
import org.apache.gravitino.auxiliary.AuxiliaryServiceManager;
import org.apache.gravitino.catalog.CatalogDispatcher;
import org.apache.gravitino.catalog.CatalogManager;
Expand All @@ -39,6 +41,8 @@
import org.apache.gravitino.catalog.TopicDispatcher;
import org.apache.gravitino.catalog.TopicNormalizeDispatcher;
import org.apache.gravitino.catalog.TopicOperationDispatcher;
import org.apache.gravitino.lifecycle.LifecycleHookHelper;
import org.apache.gravitino.lifecycle.LifecycleHooks;
import org.apache.gravitino.listener.CatalogEventDispatcher;
import org.apache.gravitino.listener.EventBus;
import org.apache.gravitino.listener.EventListenerManager;
Expand Down Expand Up @@ -86,7 +90,7 @@ public class GravitinoEnv {

private MetalakeDispatcher metalakeDispatcher;

private AccessControlManager accessControlManager;
private AccessControlDispatcher accessControlDispatcher;

private IdGenerator idGenerator;

Expand Down Expand Up @@ -140,52 +144,60 @@ public void initialize(Config config) {
EventBus eventBus = eventListenerManager.createEventBus();

// Create and initialize metalake related modules
MetalakeManager metalakeManager = new MetalakeManager(entityStore, idGenerator);
MetalakeManager metalakeManager =
installLifecycleHooks(new MetalakeManager(entityStore, idGenerator));
MetalakeNormalizeDispatcher metalakeNormalizeDispatcher =
new MetalakeNormalizeDispatcher(metalakeManager);
this.metalakeDispatcher = new MetalakeEventDispatcher(eventBus, metalakeNormalizeDispatcher);

// Create and initialize Catalog related modules
this.catalogManager = new CatalogManager(config, entityStore, idGenerator);
this.catalogManager =
installLifecycleHooks(new CatalogManager(config, entityStore, idGenerator));
CatalogNormalizeDispatcher catalogNormalizeDispatcher =
new CatalogNormalizeDispatcher(catalogManager);
this.catalogDispatcher = new CatalogEventDispatcher(eventBus, catalogNormalizeDispatcher);

SchemaOperationDispatcher schemaOperationDispatcher =
new SchemaOperationDispatcher(catalogManager, entityStore, idGenerator);
installLifecycleHooks(
new SchemaOperationDispatcher(catalogManager, entityStore, idGenerator));
SchemaNormalizeDispatcher schemaNormalizeDispatcher =
new SchemaNormalizeDispatcher(schemaOperationDispatcher);
this.schemaDispatcher = new SchemaEventDispatcher(eventBus, schemaNormalizeDispatcher);

TableOperationDispatcher tableOperationDispatcher =
new TableOperationDispatcher(catalogManager, entityStore, idGenerator);
installLifecycleHooks(
new TableOperationDispatcher(catalogManager, entityStore, idGenerator));
TableNormalizeDispatcher tableNormalizeDispatcher =
new TableNormalizeDispatcher(tableOperationDispatcher);
this.tableDispatcher = new TableEventDispatcher(eventBus, tableNormalizeDispatcher);

PartitionOperationDispatcher partitionOperationDispatcher =
new PartitionOperationDispatcher(catalogManager, entityStore, idGenerator);
installLifecycleHooks(
new PartitionOperationDispatcher(catalogManager, entityStore, idGenerator));
// todo: support PartitionEventDispatcher
this.partitionDispatcher = new PartitionNormalizeDispatcher(partitionOperationDispatcher);

FilesetOperationDispatcher filesetOperationDispatcher =
new FilesetOperationDispatcher(catalogManager, entityStore, idGenerator);
installLifecycleHooks(
new FilesetOperationDispatcher(catalogManager, entityStore, idGenerator));
FilesetNormalizeDispatcher filesetNormalizeDispatcher =
new FilesetNormalizeDispatcher(filesetOperationDispatcher);
this.filesetDispatcher = new FilesetEventDispatcher(eventBus, filesetNormalizeDispatcher);

TopicOperationDispatcher topicOperationDispatcher =
new TopicOperationDispatcher(catalogManager, entityStore, idGenerator);
installLifecycleHooks(
new TopicOperationDispatcher(catalogManager, entityStore, idGenerator));
TopicNormalizeDispatcher topicNormalizeDispatcher =
new TopicNormalizeDispatcher(topicOperationDispatcher);
this.topicDispatcher = new TopicEventDispatcher(eventBus, topicNormalizeDispatcher);

// Create and initialize access control related modules
boolean enableAuthorization = config.get(Configs.ENABLE_AUTHORIZATION);
if (enableAuthorization) {
this.accessControlManager = new AccessControlManager(entityStore, idGenerator, config);
this.accessControlDispatcher =
installLifecycleHooks(new AccessControlManager(entityStore, idGenerator, config));
} else {
this.accessControlManager = null;
this.accessControlDispatcher = null;
}

this.auxServiceManager = new AuxiliaryServiceManager();
Expand Down Expand Up @@ -305,8 +317,8 @@ public LockManager getLockManager() {
*
* @return The AccessControlManager instance.
*/
public AccessControlManager accessControlManager() {
return accessControlManager;
public AccessControlDispatcher accessControlDispatcher() {
return accessControlDispatcher;
}

/**
Expand Down Expand Up @@ -358,4 +370,23 @@ public void shutdown() {

LOG.info("Gravitino Environment is shut down.");
}

// Provides a universal entrance to install lifecycle hooks. This method
// focuses the logic of installing hooks.
// We should reuse the ability of *NormalizeDispatcher to avoid solving
// normalization names, this is useful for pre-hooks.
// so we can't install the hooks for the outside of *NormalizeDispatcher.
private <T> T installLifecycleHooks(T manager) {
boolean enableAuthorization = config.get(Configs.ENABLE_AUTHORIZATION);
LifecycleHooks hooks = new LifecycleHooks();
if (enableAuthorization) {
AuthorizationUtils.prepareAuthorizationHooks(manager, hooks);
}

if (hooks.isEmpty()) {
return manager;
}

return LifecycleHookHelper.installHooks(manager, hooks);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
/*
* 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.authorization;

import java.util.List;
import java.util.Map;
import org.apache.gravitino.exceptions.GroupAlreadyExistsException;
import org.apache.gravitino.exceptions.NoSuchGroupException;
import org.apache.gravitino.exceptions.NoSuchMetalakeException;
import org.apache.gravitino.exceptions.NoSuchRoleException;
import org.apache.gravitino.exceptions.NoSuchUserException;
import org.apache.gravitino.exceptions.RoleAlreadyExistsException;
import org.apache.gravitino.exceptions.UserAlreadyExistsException;

/**
* This interface is related to the access control. This interface is mainly used for
* LifecycleHooks. The lifecycleHooks used the InvocationHandler. The InvocationHandler can only
* hook the interfaces.
*/
public interface AccessControlDispatcher {
/**
* Adds a new User.
*
* @param metalake The Metalake of the User.
* @param user The name of the User.
* @return The added User instance.
* @throws UserAlreadyExistsException If a User with the same name already exists.
* @throws NoSuchMetalakeException If the Metalake with the given name does not exist.
* @throws RuntimeException If adding the User encounters storage issues.
*/
User addUser(String metalake, String user)
throws UserAlreadyExistsException, NoSuchMetalakeException;

/**
* Removes a User.
*
* @param metalake The Metalake of the User.
* @param user The name of the User.
* @return True if the User was successfully removed, false only when there's no such user,
* otherwise it will throw an exception.
* @throws NoSuchMetalakeException If the Metalake with the given name does not exist.
* @throws RuntimeException If removing the User encounters storage issues.
*/
boolean removeUser(String metalake, String user) throws NoSuchMetalakeException;

/**
* Gets a User.
*
* @param metalake The Metalake of the User.
* @param user The name of the User.
* @return The getting User instance.
* @throws NoSuchUserException If the User with the given name does not exist.
* @throws NoSuchMetalakeException If the Metalake with the given name does not exist.
* @throws RuntimeException If getting the User encounters storage issues.
*/
User getUser(String metalake, String user) throws NoSuchUserException, NoSuchMetalakeException;

/**
* Adds a new Group.
*
* @param metalake The Metalake of the Group.
* @param group The name of the Group.
* @return The Added Group instance.
* @throws GroupAlreadyExistsException If a Group with the same name already exists.
* @throws NoSuchMetalakeException If the Metalake with the given name does not exist.
* @throws RuntimeException If adding the Group encounters storage issues.
*/
Group addGroup(String metalake, String group)
throws GroupAlreadyExistsException, NoSuchMetalakeException;

/**
* Removes a Group.
*
* @param metalake The Metalake of the Group.
* @param group THe name of the Group.
* @return True if the Group was successfully removed, false only when there's no such group,
* otherwise it will throw an exception.
* @throws NoSuchMetalakeException If the Metalake with the given name does not exist.
* @throws RuntimeException If removing the Group encounters storage issues.
*/
boolean removeGroup(String metalake, String group) throws NoSuchMetalakeException;

/**
* Gets a Group.
*
* @param metalake The Metalake of the Group.
* @param group The name of the Group.
* @return The getting Group instance.
* @throws NoSuchGroupException If the Group with the given name does not exist.
* @throws NoSuchMetalakeException If the Metalake with the given name does not exist.
* @throws RuntimeException If getting the Group encounters storage issues.
*/
Group getGroup(String metalake, String group)
throws NoSuchGroupException, NoSuchMetalakeException;

/**
* Grant roles to a user.
*
* @param metalake The metalake of the User.
* @param user The name of the User.
* @param roles The names of the Role.
* @return The User after granted.
* @throws NoSuchUserException If the User with the given name does not exist.
* @throws NoSuchRoleException If the Role with the given name does not exist.
* @throws NoSuchMetalakeException If the Metalake with the given name does not exist.
* @throws RuntimeException If granting roles to a user encounters storage issues.
*/
User grantRolesToUser(String metalake, List<String> roles, String user)
throws NoSuchUserException, NoSuchRoleException, NoSuchMetalakeException;

/**
* Grant roles to a group.
*
* @param metalake The metalake of the Group.
* @param group The name of the Group.
* @param roles The names of the Role.
* @return The Group after granted.
* @throws NoSuchGroupException If the Group with the given name does not exist.
* @throws NoSuchRoleException If the Role with the given name does not exist.
* @throws NoSuchMetalakeException If the Metalake with the given name does not exist.
* @throws RuntimeException If granting roles to a group encounters storage issues.
*/
Group grantRolesToGroup(String metalake, List<String> roles, String group)
throws NoSuchGroupException, NoSuchRoleException, NoSuchMetalakeException;

/**
* Revoke roles from a group.
*
* @param metalake The metalake of the Group.
* @param group The name of the Group.
* @param roles The name of the Role.
* @return The Group after revoked.
* @throws NoSuchGroupException If the Group with the given name does not exist.
* @throws NoSuchRoleException If the Role with the given name does not exist.
* @throws NoSuchMetalakeException If the Metalake with the given name does not exist.
* @throws RuntimeException If revoking roles from a group encounters storage issues.
*/
Group revokeRolesFromGroup(String metalake, List<String> roles, String group)
throws NoSuchGroupException, NoSuchRoleException, NoSuchMetalakeException;

/**
* Revoke roles from a user.
*
* @param metalake The metalake of the User.
* @param user The name of the User.
* @param roles The name of the Role.
* @return The User after revoked.
* @throws NoSuchUserException If the User with the given name does not exist.
* @throws NoSuchRoleException If the Role with the given name does not exist.
* @throws NoSuchMetalakeException If the Metalake with the given name does not exist.
* @throws RuntimeException If revoking roles from a user encounters storage issues.
*/
User revokeRolesFromUser(String metalake, List<String> roles, String user)
throws NoSuchUserException, NoSuchRoleException, NoSuchMetalakeException;

/**
* Judges whether the user is the service admin.
*
* @param user the name of the user
* @return True if the user is service admin, otherwise false.
*/
boolean isServiceAdmin(String user);

/**
* Creates a new Role.
*
* @param metalake The Metalake of the Role.
* @param role The name of the Role.
* @param properties The properties of the Role.
* @param securableObjects The securable objects of the Role.
* @return The created Role instance.
* @throws RoleAlreadyExistsException If a Role with the same name already exists.
* @throws NoSuchMetalakeException If the Metalake with the given name does not exist.
* @throws RuntimeException If creating the Role encounters storage issues.
*/
Role createRole(
String metalake,
String role,
Map<String, String> properties,
List<SecurableObject> securableObjects)
throws RoleAlreadyExistsException, NoSuchMetalakeException;

/**
* Gets a Role.
*
* @param metalake The Metalake of the Role.
* @param role The name of the Role.
* @return The getting Role instance.
* @throws NoSuchRoleException If the Role with the given name does not exist.
* @throws NoSuchMetalakeException If the Metalake with the given name does not exist.
* @throws RuntimeException If getting the Role encounters storage issues.
*/
Role getRole(String metalake, String role) throws NoSuchRoleException, NoSuchMetalakeException;

/**
* Deletes a Role.
*
* @param metalake The Metalake of the Role.
* @param role The name of the Role.
* @return True if the Role was successfully deleted, false only when there's no such role,
* otherwise it will throw an exception.
* @throws NoSuchMetalakeException If the Metalake with the given name does not exist.
* @throws RuntimeException If deleting the Role encounters storage issues.
*/
public boolean deleteRole(String metalake, String role) throws NoSuchMetalakeException;
}
Loading

0 comments on commit cd3526b

Please sign in to comment.