首页 > 代码库 > hive show current roles问题

hive show current roles问题

今天hive user maillist上有人问show current roles命令问题:

1
2
3
4
5
6
I am trying to run ‘Show current roles’ on Apache hive 0.13.1 but getting following error,
hive> SHOW CURRENT ROLES;
Error in role operation show_current_role on role name null, error message Unkown role operation show_current_role
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask
Can someone tell me whether this command is supported on apache Hive 0.13.1 or not. If it is supported the what could be the issue.
Any pointer would be really helpful.

在我的印象中,这个命令应该不存在才对。。手动运行了一下,果然报错,仔细看日志,可以看到命令式可以完成parse和analyzer阶段的,运行的时候报错,
按我的理解,如果sql不支持的话应该在parse阶段就会出错

1
2
3
4
5
6
7
8
9
14/11/20 11:22:55 INFO ql.Driver: Starting command: show current roles
14/11/20 11:22:55 INFO log.PerfLogger: </PERFLOG method=TimeToSubmit start=1416453775411 end=1416453775795 duration=384 from=org.apache.hadoop.hive.ql.Driver>
14/11/20 11:22:55 INFO log.PerfLogger: <PERFLOG method=runTasks from=org.apache.hadoop.hive.ql.Driver>
14/11/20 11:22:55 INFO log.PerfLogger: <PERFLOG method=task.DDL.Stage-0 from=org.apache.hadoop.hive.ql.Driver>
Error in role operation show_current_role on role name null, error message Unkown role operation show_current_role
14/11/20 11:22:55 ERROR exec.Task: Error in role operation show_current_role on role name null, error message Unkown role operation show_current_role
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask
14/11/20 11:22:55 ERROR ql.Driver: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask
14/11/20 11:22:55 DEBUG ql.Driver: Shutting down query show current roles

根据堆栈信息,show current roles命令是由DDLTask执行的,看其具体实现:

1
2
3
4
5
  private int roleDDL(RoleDDLDesc roleDDLDesc) throws HiveException, IOException {
    if(SessionState.get().isAuthorizationModeV2()){
      return roleDDLV2(roleDDLDesc);  //如果是v2的验证方式,调用roleDDLV2
    }
....

在roleDDLV2中可以看到show current role命令的处理:

1
2
3
4
5
6
7
8
9
10
11
    private int roleDDLV2(RoleDDLDesc roleDDLDesc) throws HiveException, IOException {
    HiveAuthorizer authorizer = SessionState.get().getAuthorizerV2();
    RoleDDLDesc.RoleOperation operation = roleDDLDesc.getOperation();
    //call the appropriate hive authorizer function
    switch(operation){
...
    case SHOW_CURRENT_ROLE:
      List<String> roleNames = authorizer.getCurrentRoleNames();
      writeListToFileAfterSort(roleNames, roleDDLDesc.getResFile());
      break;
...

即show current role这个语法在v2里面支持,那么什么时候SessionState.get().isAuthorizationModeV2()为true呢?来看看SessionState类,isAuthorizationModeV2调用getAuthorizationMode,getAuthorizationMode调用setupAuth

1
2
3
4
5
6
7
8
9
10
11
12
13
public AuthorizationMode getAuthorizationMode(){
    setupAuth();   //调用setupAuth类设置authorizer和authorizerV2
    if(authorizer != null){
      return AuthorizationMode.V1;
    }else if(authorizerV2 != null){
      return AuthorizationMode.V2;
    }
    //should not happen - this should not get called before this.start() is called
    throw new AssertionError("Authorization plugins not initialized!");
  }
  public boolean isAuthorizationModeV2(){
    return getAuthorizationMode() == AuthorizationMode.V2;
  }

如果要让AuthorizationMode.V2成立,需要让authorizer为null,authorizerV2不为null才可以,设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
authorizer和authorizerV2是在setupAuth方法中实现的
  private HiveAuthorizationProvider authorizer;
  private HiveAuthorizer authorizerV2;
...
  private void setupAuth() {
    if (authenticator != null) {
      // auth has been initialized
      return;
    }
    try {
...
      authorizer = HiveUtils.getAuthorizeProviderManager(conf,
          HiveConf.ConfVars.HIVE_AUTHORIZATION_MANAGER, authenticator, true);  //hive.security.authorization.manager 默认为org.apache.hadoop.hive.ql.security.authorization.DefaultHiveAuthorizationProvider         
      if (authorizer == null) { //authorizer的值为null时,才可以有机会返回v2
        // if it was null, the new authorization plugin must be specified in
        // config
        HiveAuthorizerFactory authorizerFactory = HiveUtils.getAuthorizerFactory(conf,
            HiveConf.ConfVars.HIVE_AUTHORIZATION_MANAGER);
        authorizerV2 = authorizerFactory.createHiveAuthorizer(new HiveMetastoreClientFactoryImpl(),
            conf, authenticator);
        authorizerV2.applyAuthorizationConfigPolicy(conf);
        // create the create table grants with new config
        createTableGrants = CreateTableAutomaticGrant.create(conf);
      }
..

因为hive.security.authorization.manager默认为org.apache.hadoop.hive.ql.security.authorization.DefaultHiveAuthorizationProvider,所以为authorizer为V1,要想设置为v2,需要让HiveUtils.getAuthorizeProviderManager返回null
HiveUtils.getAuthorizeProviderManager中可以获取设置的authorizer的具体实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  public static HiveAuthorizationProvider getAuthorizeProviderManager(
      Configuration conf, HiveConf.ConfVars authorizationProviderConfKey,
      HiveAuthenticationProvider authenticator, boolean nullIfOtherClass) throws HiveException {
    String clsStr = HiveConf.getVar(conf, authorizationProviderConfKey); //由hive.security.authorization.manager的设置获取类名
    HiveAuthorizationProvider ret = null;
    try {
      Class<? extends HiveAuthorizationProvider> cls = null;
      if (clsStr == null || clsStr.trim().equals("")) { //如果为null或者设置为空,则实现类为DefaultHiveAuthorizationProvider
        cls = DefaultHiveAuthorizationProvider.class;
      else {
        Class<?> configClass = Class.forName(clsStr, true, JavaUtils.getClassLoader()); //否则为具体的实现的类
        if(nullIfOtherClass && !HiveAuthorizationProvider.class.isAssignableFrom(configClass) ){ //配置的类和HiveAuthorizationProvider类没有关系时,返回null
          return null;
        }
        cls = (Class<? extends HiveAuthorizationProvider>)configClass;
      }
      if (cls != null) {
        ret = ReflectionUtils.newInstance(cls, conf);
      }
    catch (Exception e) {
      throw new HiveException(e);
    }
    ret.setAuthenticator(authenticator);
    return ret;
  }

如果要想返回v2,需要让设置的authorize相关类必须实现HiveAuthorizerFactory接口,且不能实现HiveAuthorizationProvider接口
反馈如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Refer to the org.apache.Hadoop.hive.ql.exec.DDLTask.roleDDL function, AuthorizationMode 
doesn‘t support  SHOW CURRENT ROLES statement
But AuthorizationModeV2 supports this:
private int roleDDLV2(RoleDDLDesc roleDDLDesc) throws HiveException, IOException {
…….
    case SHOW_CURRENT_ROLE:
      List<String> roleNames = authorizer.getCurrentRoleNames();
      writeListToFileAfterSort(roleNames, roleDDLDesc.getResFile());
      break;
But by default,hive uses AuthorizationMode (because the default value of 
hive.security.authorization.manager is
org.apache.hadoop.hive.ql.security.authorization.DefaultHiveAuthorizationProvider,
which means AuthorizationMode )
If you want to use AuthorizationModeV2,you must use another authorization class
which implements the
org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthorizerFactory interface
but not the 
org.apache.hadoop.hive.ql.security.authorization.HiveAuthorizationProvider interface

hive show current roles问题