Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.sentry.service.thrift; import com.google.common.base.Preconditions; import java.io.File; import java.io.IOException; import java.security.PrivilegedExceptionAction; import javax.security.auth.login.LoginException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.metastore.HiveMetaStoreClient; import org.apache.hadoop.hive.metastore.api.MetaException; import org.apache.hadoop.net.NetUtils; import org.apache.hadoop.security.SaslRpcServer; import org.apache.hadoop.security.SecurityUtil; import org.apache.hadoop.security.UserGroupInformation; import org.apache.sentry.service.common.ServiceConstants.ServerConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Factory used to generate Hive connections. * Supports insecure and Kerberos connections. * For Kerberos connections starts the ticket renewal thread and sets * up Kerberos credentials. */ public final class HiveSimpleConnectionFactory implements HiveConnectionFactory { private static final Logger LOGGER = LoggerFactory.getLogger(HiveSimpleConnectionFactory.class); /** Sentty configuration */ private final Configuration conf; /** Hive configuration */ private final HiveConf hiveConf; private final boolean insecure; private SentryKerberosContext kerberosContext = null; public HiveSimpleConnectionFactory(Configuration sentryConf, HiveConf hiveConf) { this.conf = sentryConf; this.hiveConf = hiveConf; insecure = !ServerConfig.SECURITY_MODE_KERBEROS.equalsIgnoreCase( sentryConf.get(ServerConfig.SECURITY_MODE, ServerConfig.SECURITY_MODE_NONE).trim()); } /** * Initialize the Factory. * For insecure connections there is nothing to initialize. * For Kerberos connections sets up ticket renewal thread. * @throws IOException * @throws LoginException */ public void init() throws IOException, LoginException { if (insecure) { LOGGER.info("Using insecure connection to HMS"); return; } LOGGER.info("Using secured connection to HMS"); int port = conf.getInt(ServerConfig.RPC_PORT, ServerConfig.RPC_PORT_DEFAULT); String rawPrincipal = Preconditions.checkNotNull(conf.get(ServerConfig.PRINCIPAL), "%s is required", ServerConfig.PRINCIPAL); String principal = SecurityUtil.getServerPrincipal(rawPrincipal, NetUtils .createSocketAddr(conf.get(ServerConfig.RPC_ADDRESS, ServerConfig.RPC_ADDRESS_DEFAULT), port) .getAddress()); LOGGER.debug("Opening kerberos connection to HMS using kerberos principal {}", principal); String[] principalParts = SaslRpcServer.splitKerberosName(principal); Preconditions.checkArgument(principalParts.length == 3, "Kerberos principal %s should have 3 parts", principal); String keytab = Preconditions.checkNotNull(conf.get(ServerConfig.KEY_TAB), "Configuration is missing required %s paraeter", ServerConfig.KEY_TAB); File keytabFile = new File(keytab); Preconditions.checkState(keytabFile.isFile() && keytabFile.canRead(), "Keytab %s does not exist or is not readable", keytab); // Instantiating SentryKerberosContext in non-server mode handles the ticket renewal. kerberosContext = new SentryKerberosContext(principal, keytab, false); UserGroupInformation.setConfiguration(conf); LOGGER.info("Using secure connection to HMS"); } /** * Connect to HMS in unsecure mode or in Kerberos mode according to config. * * @return HMS connection * @throws IOException if could not establish connection * @throws InterruptedException if connection was interrupted * @throws MetaException if other errors happened */ public HMSClient connect() throws IOException, InterruptedException, MetaException { UserGroupInformation clientUGI; if (insecure) { clientUGI = UserGroupInformation.getCurrentUser(); } else { clientUGI = UserGroupInformation.getUGIFromSubject(kerberosContext.getSubject()); } return new HMSClient(clientUGI.doAs(new PrivilegedExceptionAction<HiveMetaStoreClient>() { @Override public HiveMetaStoreClient run() throws MetaException { return new HiveMetaStoreClient(hiveConf); } })); } @Override public void close() throws Exception { if (kerberosContext != null) { kerberosContext.shutDown(); kerberosContext = null; } } }