今天hive user maillist上有人问show current roles命令问题:
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阶段就会出错
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执行的,看其具体实现:
private int roleDDL(RoleDDLDesc roleDDLDesc) throws HiveException, IOException { if(SessionState.get().isAuthorizationModeV2()){ return roleDDLV2(roleDDLDesc); //如果是v2的验证方式,调用roleDDLV2 } ....
在roleDDLV2中可以看到show current role命令的处理:
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:
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才可以,设置
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的具体实现类
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接口
反馈如下:
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
本文出自 “菜光光的博客” 博客,请务必保留此出处http://caiguangguang.blog.51cto.com/1652935/1587259
原文地址:http://caiguangguang.blog.51cto.com/1652935/1587259