private void initKerberosIfNecessary()

in catalogs/catalog-hive/src/main/java/org/apache/gravitino/catalog/hive/HiveCatalogOperations.java [176:267]


  private void initKerberosIfNecessary(Map<String, String> conf, Configuration hadoopConf) {
    if (UserGroupInformation.AuthenticationMethod.KERBEROS
        == SecurityUtil.getAuthenticationMethod(hadoopConf)) {
      try {
        Path keytabsPath = Paths.get("keytabs");
        if (!Files.exists(keytabsPath)) {
          // Ignore the return value, because there exists many Hive catalog operations making
          // this directory.
          Files.createDirectory(keytabsPath);
        }

        // The id of entity is a random unique id.
        Path keytabPath = Paths.get(String.format(GRAVITINO_KEYTAB_FORMAT, info.id()));
        keytabPath.toFile().deleteOnExit();
        if (Files.exists(keytabPath)) {
          try {
            Files.delete(keytabPath);
          } catch (IOException e) {
            throw new IllegalStateException(
                String.format("Fail to delete keytab file %s", keytabPath.toAbsolutePath()), e);
          }
        }

        String keytabUri =
            (String)
                propertiesMetadata
                    .catalogPropertiesMetadata()
                    .getOrDefault(conf, HiveCatalogPropertiesMetadata.KEY_TAB_URI);
        Preconditions.checkArgument(StringUtils.isNotBlank(keytabUri), "Keytab uri can't be blank");
        // TODO: Support to download the file from Kerberos HDFS
        Preconditions.checkArgument(
            !keytabUri.trim().startsWith("hdfs"), "Keytab uri doesn't support to use HDFS");

        int fetchKeytabFileTimeout =
            (int)
                propertiesMetadata
                    .catalogPropertiesMetadata()
                    .getOrDefault(conf, HiveCatalogPropertiesMetadata.FETCH_TIMEOUT_SEC);

        FetchFileUtils.fetchFileFromUri(
            keytabUri, keytabPath.toFile(), fetchKeytabFileTimeout, hadoopConf);

        hiveConf.setVar(
            ConfVars.METASTORE_KERBEROS_KEYTAB_FILE, keytabPath.toAbsolutePath().toString());

        String catalogPrincipal =
            (String) propertiesMetadata.catalogPropertiesMetadata().getOrDefault(conf, PRINCIPAL);
        Preconditions.checkArgument(
            StringUtils.isNotBlank(catalogPrincipal), "The principal can't be blank");
        @SuppressWarnings("null")
        List<String> principalComponents = Splitter.on('@').splitToList(catalogPrincipal);
        Preconditions.checkArgument(
            principalComponents.size() == 2, "The principal has the wrong format");
        this.kerberosRealm = principalComponents.get(1);

        checkTgtExecutor =
            new ScheduledThreadPoolExecutor(
                1, getThreadFactory(String.format("Kerberos-check-%s", info.id())));

        LOG.info("krb5 path: {}", System.getProperty("java.security.krb5.conf"));
        refreshKerberosConfig();
        UserGroupInformation.setConfiguration(hadoopConf);
        UserGroupInformation.loginUserFromKeytab(
            catalogPrincipal, keytabPath.toAbsolutePath().toString());

        UserGroupInformation kerberosLoginUgi = UserGroupInformation.getCurrentUser();

        int checkInterval =
            (int)
                propertiesMetadata
                    .catalogPropertiesMetadata()
                    .getOrDefault(conf, HiveCatalogPropertiesMetadata.CHECK_INTERVAL_SEC);

        checkTgtExecutor.scheduleAtFixedRate(
            () -> {
              try {
                kerberosLoginUgi.checkTGTAndReloginFromKeytab();
              } catch (Exception e) {
                LOG.error("Fail to refresh ugi token: ", e);
              }
            },
            checkInterval,
            checkInterval,
            TimeUnit.SECONDS);

      } catch (IOException ioe) {
        throw new UncheckedIOException(ioe);
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
    }
  }