0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 package org.apache.hive.service.cli;
0020
0021 import java.io.IOException;
0022 import java.util.List;
0023 import java.util.Map;
0024 import java.util.concurrent.CancellationException;
0025 import java.util.concurrent.ExecutionException;
0026 import java.util.concurrent.TimeUnit;
0027 import java.util.concurrent.TimeoutException;
0028
0029 import javax.security.auth.login.LoginException;
0030
0031 import org.apache.hadoop.hive.conf.HiveConf;
0032 import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
0033 import org.apache.hadoop.hive.metastore.HiveMetaStoreClient;
0034 import org.apache.hadoop.hive.metastore.IMetaStoreClient;
0035 import org.apache.hadoop.hive.metastore.api.MetaException;
0036 import org.apache.hadoop.hive.ql.exec.FunctionRegistry;
0037 import org.apache.hadoop.hive.ql.metadata.Hive;
0038 import org.apache.hadoop.hive.ql.metadata.HiveException;
0039 import org.apache.hadoop.hive.ql.session.SessionState;
0040 import org.apache.hadoop.hive.shims.Utils;
0041 import org.apache.hadoop.security.UserGroupInformation;
0042 import org.apache.hive.service.CompositeService;
0043 import org.apache.hive.service.ServiceException;
0044 import org.apache.hive.service.auth.HiveAuthFactory;
0045 import org.apache.hive.service.cli.operation.Operation;
0046 import org.apache.hive.service.cli.session.HiveSession;
0047 import org.apache.hive.service.cli.session.SessionManager;
0048 import org.apache.hive.service.rpc.thrift.TProtocolVersion;
0049 import org.apache.hive.service.server.HiveServer2;
0050 import org.slf4j.Logger;
0051 import org.slf4j.LoggerFactory;
0052
0053
0054
0055
0056
0057 public class CLIService extends CompositeService implements ICLIService {
0058
0059 public static final TProtocolVersion SERVER_VERSION;
0060
0061 static {
0062 TProtocolVersion[] protocols = TProtocolVersion.values();
0063 SERVER_VERSION = protocols[protocols.length - 1];
0064 }
0065
0066 private final Logger LOG = LoggerFactory.getLogger(CLIService.class.getName());
0067
0068 private HiveConf hiveConf;
0069 private SessionManager sessionManager;
0070 private UserGroupInformation serviceUGI;
0071 private UserGroupInformation httpUGI;
0072
0073 private final HiveServer2 hiveServer2;
0074
0075 public CLIService(HiveServer2 hiveServer2) {
0076 super(CLIService.class.getSimpleName());
0077 this.hiveServer2 = hiveServer2;
0078 }
0079
0080 @Override
0081 public synchronized void init(HiveConf hiveConf) {
0082 this.hiveConf = hiveConf;
0083 sessionManager = new SessionManager(hiveServer2);
0084 addService(sessionManager);
0085
0086 if (UserGroupInformation.isSecurityEnabled()) {
0087 try {
0088 HiveAuthFactory.loginFromKeytab(hiveConf);
0089 this.serviceUGI = Utils.getUGI();
0090 } catch (IOException e) {
0091 throw new ServiceException("Unable to login to kerberos with given principal/keytab", e);
0092 } catch (LoginException e) {
0093 throw new ServiceException("Unable to login to kerberos with given principal/keytab", e);
0094 }
0095
0096
0097 String principal = hiveConf.getVar(ConfVars.HIVE_SERVER2_SPNEGO_PRINCIPAL);
0098 String keyTabFile = hiveConf.getVar(ConfVars.HIVE_SERVER2_SPNEGO_KEYTAB);
0099 if (principal.isEmpty() || keyTabFile.isEmpty()) {
0100 LOG.info("SPNego httpUGI not created, spNegoPrincipal: " + principal +
0101 ", ketabFile: " + keyTabFile);
0102 } else {
0103 try {
0104 this.httpUGI = HiveAuthFactory.loginFromSpnegoKeytabAndReturnUGI(hiveConf);
0105 LOG.info("SPNego httpUGI successfully created.");
0106 } catch (IOException e) {
0107 LOG.warn("SPNego httpUGI creation failed: ", e);
0108 }
0109 }
0110 }
0111
0112 try {
0113 applyAuthorizationConfigPolicy(hiveConf);
0114 } catch (Exception e) {
0115 throw new RuntimeException("Error applying authorization policy on hive configuration: "
0116 + e.getMessage(), e);
0117 }
0118 setupBlockedUdfs();
0119 super.init(hiveConf);
0120 }
0121
0122 private void applyAuthorizationConfigPolicy(HiveConf newHiveConf) throws HiveException,
0123 MetaException {
0124
0125
0126 SessionState ss = new SessionState(newHiveConf);
0127 ss.setIsHiveServerQuery(true);
0128 SessionState.start(ss);
0129 ss.applyAuthorizationPolicy();
0130 }
0131
0132 private void setupBlockedUdfs() {
0133 FunctionRegistry.setupPermissionsForBuiltinUDFs(
0134 hiveConf.getVar(ConfVars.HIVE_SERVER2_BUILTIN_UDF_WHITELIST),
0135 hiveConf.getVar(ConfVars.HIVE_SERVER2_BUILTIN_UDF_BLACKLIST));
0136 }
0137
0138 public UserGroupInformation getServiceUGI() {
0139 return this.serviceUGI;
0140 }
0141
0142 public UserGroupInformation getHttpUGI() {
0143 return this.httpUGI;
0144 }
0145
0146 @Override
0147 public synchronized void start() {
0148 super.start();
0149
0150 IMetaStoreClient metastoreClient = null;
0151 try {
0152 metastoreClient = new HiveMetaStoreClient(hiveConf);
0153 metastoreClient.getDatabases("default");
0154 } catch (Exception e) {
0155 throw new ServiceException("Unable to connect to MetaStore!", e);
0156 }
0157 finally {
0158 if (metastoreClient != null) {
0159 metastoreClient.close();
0160 }
0161 }
0162 }
0163
0164 @Override
0165 public synchronized void stop() {
0166 super.stop();
0167 }
0168
0169
0170
0171
0172 @Deprecated
0173 public SessionHandle openSession(TProtocolVersion protocol, String username, String password,
0174 Map<String, String> configuration) throws HiveSQLException {
0175 SessionHandle sessionHandle = sessionManager.openSession(protocol, username, password, null, configuration, false, null);
0176 LOG.debug(sessionHandle + ": openSession()");
0177 return sessionHandle;
0178 }
0179
0180
0181
0182
0183 @Deprecated
0184 public SessionHandle openSessionWithImpersonation(TProtocolVersion protocol, String username,
0185 String password, Map<String, String> configuration, String delegationToken)
0186 throws HiveSQLException {
0187 SessionHandle sessionHandle = sessionManager.openSession(protocol, username, password, null, configuration,
0188 true, delegationToken);
0189 LOG.debug(sessionHandle + ": openSessionWithImpersonation()");
0190 return sessionHandle;
0191 }
0192
0193 public SessionHandle openSession(TProtocolVersion protocol, String username, String password, String ipAddress,
0194 Map<String, String> configuration) throws HiveSQLException {
0195 SessionHandle sessionHandle = sessionManager.openSession(protocol, username, password, ipAddress, configuration, false, null);
0196 LOG.debug(sessionHandle + ": openSession()");
0197 return sessionHandle;
0198 }
0199
0200 public SessionHandle openSessionWithImpersonation(TProtocolVersion protocol, String username,
0201 String password, String ipAddress, Map<String, String> configuration, String delegationToken)
0202 throws HiveSQLException {
0203 SessionHandle sessionHandle = sessionManager.openSession(protocol, username, password, ipAddress, configuration,
0204 true, delegationToken);
0205 LOG.debug(sessionHandle + ": openSession()");
0206 return sessionHandle;
0207 }
0208
0209
0210
0211
0212 @Override
0213 public SessionHandle openSession(String username, String password, Map<String, String> configuration)
0214 throws HiveSQLException {
0215 SessionHandle sessionHandle = sessionManager.openSession(SERVER_VERSION, username, password, null, configuration, false, null);
0216 LOG.debug(sessionHandle + ": openSession()");
0217 return sessionHandle;
0218 }
0219
0220
0221
0222
0223 @Override
0224 public SessionHandle openSessionWithImpersonation(String username, String password, Map<String, String> configuration,
0225 String delegationToken) throws HiveSQLException {
0226 SessionHandle sessionHandle = sessionManager.openSession(SERVER_VERSION, username, password, null, configuration,
0227 true, delegationToken);
0228 LOG.debug(sessionHandle + ": openSession()");
0229 return sessionHandle;
0230 }
0231
0232
0233
0234
0235 @Override
0236 public void closeSession(SessionHandle sessionHandle)
0237 throws HiveSQLException {
0238 sessionManager.closeSession(sessionHandle);
0239 LOG.debug(sessionHandle + ": closeSession()");
0240 }
0241
0242
0243
0244
0245 @Override
0246 public GetInfoValue getInfo(SessionHandle sessionHandle, GetInfoType getInfoType)
0247 throws HiveSQLException {
0248 GetInfoValue infoValue = sessionManager.getSession(sessionHandle)
0249 .getInfo(getInfoType);
0250 LOG.debug(sessionHandle + ": getInfo()");
0251 return infoValue;
0252 }
0253
0254
0255
0256
0257
0258 @Override
0259 public OperationHandle executeStatement(SessionHandle sessionHandle, String statement,
0260 Map<String, String> confOverlay) throws HiveSQLException {
0261 HiveSession session = sessionManager.getSession(sessionHandle);
0262
0263
0264 session.getSessionState().updateProgressMonitor(null);
0265 OperationHandle opHandle = session.executeStatement(statement, confOverlay);
0266 LOG.debug(sessionHandle + ": executeStatement()");
0267 return opHandle;
0268 }
0269
0270
0271
0272
0273 @Override
0274 public OperationHandle executeStatement(SessionHandle sessionHandle, String statement,
0275 Map<String, String> confOverlay, long queryTimeout) throws HiveSQLException {
0276 HiveSession session = sessionManager.getSession(sessionHandle);
0277
0278
0279 session.getSessionState().updateProgressMonitor(null);
0280 OperationHandle opHandle = session.executeStatement(statement, confOverlay, queryTimeout);
0281 LOG.debug(sessionHandle + ": executeStatement()");
0282 return opHandle;
0283 }
0284
0285
0286
0287
0288 @Override
0289 public OperationHandle executeStatementAsync(SessionHandle sessionHandle, String statement,
0290 Map<String, String> confOverlay) throws HiveSQLException {
0291 HiveSession session = sessionManager.getSession(sessionHandle);
0292
0293
0294 session.getSessionState().updateProgressMonitor(null);
0295 OperationHandle opHandle = session.executeStatementAsync(statement, confOverlay);
0296 LOG.debug(sessionHandle + ": executeStatementAsync()");
0297 return opHandle;
0298 }
0299
0300
0301
0302
0303 @Override
0304 public OperationHandle executeStatementAsync(SessionHandle sessionHandle, String statement,
0305 Map<String, String> confOverlay, long queryTimeout) throws HiveSQLException {
0306 HiveSession session = sessionManager.getSession(sessionHandle);
0307
0308
0309 session.getSessionState().updateProgressMonitor(null);
0310 OperationHandle opHandle = session.executeStatementAsync(statement, confOverlay, queryTimeout);
0311 LOG.debug(sessionHandle + ": executeStatementAsync()");
0312 return opHandle;
0313 }
0314
0315
0316
0317
0318
0319 @Override
0320 public OperationHandle getTypeInfo(SessionHandle sessionHandle)
0321 throws HiveSQLException {
0322 OperationHandle opHandle = sessionManager.getSession(sessionHandle)
0323 .getTypeInfo();
0324 LOG.debug(sessionHandle + ": getTypeInfo()");
0325 return opHandle;
0326 }
0327
0328
0329
0330
0331 @Override
0332 public OperationHandle getCatalogs(SessionHandle sessionHandle)
0333 throws HiveSQLException {
0334 OperationHandle opHandle = sessionManager.getSession(sessionHandle)
0335 .getCatalogs();
0336 LOG.debug(sessionHandle + ": getCatalogs()");
0337 return opHandle;
0338 }
0339
0340
0341
0342
0343 @Override
0344 public OperationHandle getSchemas(SessionHandle sessionHandle,
0345 String catalogName, String schemaName)
0346 throws HiveSQLException {
0347 OperationHandle opHandle = sessionManager.getSession(sessionHandle)
0348 .getSchemas(catalogName, schemaName);
0349 LOG.debug(sessionHandle + ": getSchemas()");
0350 return opHandle;
0351 }
0352
0353
0354
0355
0356 @Override
0357 public OperationHandle getTables(SessionHandle sessionHandle,
0358 String catalogName, String schemaName, String tableName, List<String> tableTypes)
0359 throws HiveSQLException {
0360 OperationHandle opHandle = sessionManager.getSession(sessionHandle)
0361 .getTables(catalogName, schemaName, tableName, tableTypes);
0362 LOG.debug(sessionHandle + ": getTables()");
0363 return opHandle;
0364 }
0365
0366
0367
0368
0369 @Override
0370 public OperationHandle getTableTypes(SessionHandle sessionHandle)
0371 throws HiveSQLException {
0372 OperationHandle opHandle = sessionManager.getSession(sessionHandle)
0373 .getTableTypes();
0374 LOG.debug(sessionHandle + ": getTableTypes()");
0375 return opHandle;
0376 }
0377
0378
0379
0380
0381 @Override
0382 public OperationHandle getColumns(SessionHandle sessionHandle,
0383 String catalogName, String schemaName, String tableName, String columnName)
0384 throws HiveSQLException {
0385 OperationHandle opHandle = sessionManager.getSession(sessionHandle)
0386 .getColumns(catalogName, schemaName, tableName, columnName);
0387 LOG.debug(sessionHandle + ": getColumns()");
0388 return opHandle;
0389 }
0390
0391
0392
0393
0394 @Override
0395 public OperationHandle getFunctions(SessionHandle sessionHandle,
0396 String catalogName, String schemaName, String functionName)
0397 throws HiveSQLException {
0398 OperationHandle opHandle = sessionManager.getSession(sessionHandle)
0399 .getFunctions(catalogName, schemaName, functionName);
0400 LOG.debug(sessionHandle + ": getFunctions()");
0401 return opHandle;
0402 }
0403
0404
0405
0406
0407 @Override
0408 public OperationHandle getPrimaryKeys(SessionHandle sessionHandle,
0409 String catalog, String schema, String table) throws HiveSQLException {
0410 OperationHandle opHandle = sessionManager.getSession(sessionHandle)
0411 .getPrimaryKeys(catalog, schema, table);
0412 LOG.debug(sessionHandle + ": getPrimaryKeys()");
0413 return opHandle;
0414 }
0415
0416
0417
0418
0419 @Override
0420 public OperationHandle getCrossReference(SessionHandle sessionHandle,
0421 String primaryCatalog, String primarySchema, String primaryTable, String foreignCatalog,
0422 String foreignSchema, String foreignTable) throws HiveSQLException {
0423 OperationHandle opHandle = sessionManager.getSession(sessionHandle)
0424 .getCrossReference(primaryCatalog, primarySchema, primaryTable,
0425 foreignCatalog,
0426 foreignSchema, foreignTable);
0427 LOG.debug(sessionHandle + ": getCrossReference()");
0428 return opHandle;
0429 }
0430
0431
0432
0433
0434 @Override
0435 public OperationStatus getOperationStatus(OperationHandle opHandle)
0436 throws HiveSQLException {
0437 Operation operation = sessionManager.getOperationManager().getOperation(opHandle);
0438
0439
0440
0441
0442
0443
0444 if (operation.shouldRunAsync()) {
0445 HiveConf conf = operation.getParentSession().getHiveConf();
0446 long timeout = HiveConf.getTimeVar(conf,
0447 HiveConf.ConfVars.HIVE_SERVER2_LONG_POLLING_TIMEOUT, TimeUnit.MILLISECONDS);
0448 try {
0449 operation.getBackgroundHandle().get(timeout, TimeUnit.MILLISECONDS);
0450 } catch (TimeoutException e) {
0451
0452 LOG.trace(opHandle + ": Long polling timed out");
0453 } catch (CancellationException e) {
0454
0455 LOG.trace(opHandle + ": The background operation was cancelled", e);
0456 } catch (ExecutionException e) {
0457
0458 LOG.warn(opHandle + ": The background operation was aborted", e);
0459 } catch (InterruptedException e) {
0460
0461
0462 }
0463 }
0464 OperationStatus opStatus = operation.getStatus();
0465 LOG.debug(opHandle + ": getOperationStatus()");
0466 return opStatus;
0467 }
0468
0469 public HiveConf getSessionConf(SessionHandle sessionHandle) throws HiveSQLException {
0470 return sessionManager.getSession(sessionHandle).getHiveConf();
0471 }
0472
0473
0474
0475
0476 @Override
0477 public void cancelOperation(OperationHandle opHandle)
0478 throws HiveSQLException {
0479 sessionManager.getOperationManager().getOperation(opHandle)
0480 .getParentSession().cancelOperation(opHandle);
0481 LOG.debug(opHandle + ": cancelOperation()");
0482 }
0483
0484
0485
0486
0487 @Override
0488 public void closeOperation(OperationHandle opHandle)
0489 throws HiveSQLException {
0490 sessionManager.getOperationManager().getOperation(opHandle)
0491 .getParentSession().closeOperation(opHandle);
0492 LOG.debug(opHandle + ": closeOperation");
0493 }
0494
0495
0496
0497
0498 @Override
0499 public TableSchema getResultSetMetadata(OperationHandle opHandle)
0500 throws HiveSQLException {
0501 TableSchema tableSchema = sessionManager.getOperationManager()
0502 .getOperation(opHandle).getParentSession().getResultSetMetadata(opHandle);
0503 LOG.debug(opHandle + ": getResultSetMetadata()");
0504 return tableSchema;
0505 }
0506
0507
0508
0509
0510 @Override
0511 public RowSet fetchResults(OperationHandle opHandle)
0512 throws HiveSQLException {
0513 return fetchResults(opHandle, Operation.DEFAULT_FETCH_ORIENTATION,
0514 Operation.DEFAULT_FETCH_MAX_ROWS, FetchType.QUERY_OUTPUT);
0515 }
0516
0517 @Override
0518 public RowSet fetchResults(OperationHandle opHandle, FetchOrientation orientation,
0519 long maxRows, FetchType fetchType) throws HiveSQLException {
0520 RowSet rowSet = sessionManager.getOperationManager().getOperation(opHandle)
0521 .getParentSession().fetchResults(opHandle, orientation, maxRows, fetchType);
0522 LOG.debug(opHandle + ": fetchResults()");
0523 return rowSet;
0524 }
0525
0526
0527 public synchronized String getDelegationTokenFromMetaStore(String owner)
0528 throws HiveSQLException, UnsupportedOperationException, LoginException, IOException {
0529 if (!hiveConf.getBoolVar(HiveConf.ConfVars.METASTORE_USE_THRIFT_SASL) ||
0530 !hiveConf.getBoolVar(HiveConf.ConfVars.HIVE_SERVER2_ENABLE_DOAS)) {
0531 throw new UnsupportedOperationException(
0532 "delegation token is can only be obtained for a secure remote metastore");
0533 }
0534
0535 try {
0536 Hive.closeCurrent();
0537 return Hive.get(hiveConf).getDelegationToken(owner, owner);
0538 } catch (HiveException e) {
0539 if (e.getCause() instanceof UnsupportedOperationException) {
0540 throw (UnsupportedOperationException)e.getCause();
0541 } else {
0542 throw new HiveSQLException("Error connect metastore to setup impersonation", e);
0543 }
0544 }
0545 }
0546
0547 @Override
0548 public String getDelegationToken(SessionHandle sessionHandle, HiveAuthFactory authFactory,
0549 String owner, String renewer) throws HiveSQLException {
0550 String delegationToken = sessionManager.getSession(sessionHandle)
0551 .getDelegationToken(authFactory, owner, renewer);
0552 LOG.info(sessionHandle + ": getDelegationToken()");
0553 return delegationToken;
0554 }
0555
0556 @Override
0557 public void cancelDelegationToken(SessionHandle sessionHandle, HiveAuthFactory authFactory,
0558 String tokenStr) throws HiveSQLException {
0559 sessionManager.getSession(sessionHandle).cancelDelegationToken(authFactory, tokenStr);
0560 LOG.info(sessionHandle + ": cancelDelegationToken()");
0561 }
0562
0563 @Override
0564 public void renewDelegationToken(SessionHandle sessionHandle, HiveAuthFactory authFactory,
0565 String tokenStr) throws HiveSQLException {
0566 sessionManager.getSession(sessionHandle).renewDelegationToken(authFactory, tokenStr);
0567 LOG.info(sessionHandle + ": renewDelegationToken()");
0568 }
0569
0570 public SessionManager getSessionManager() {
0571 return sessionManager;
0572 }
0573 }