今天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
|