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