static ClientDatanodeProtocolPB createClientDatanodeProtocolProxy(
      DatanodeID datanodeid,
      Configuration conf,
      int socketTimeout,
      boolean connectToDnViaHostname,
      LocatedBlock locatedBlock)
      throws IOException {
    final String dnAddr = datanodeid.getIpcAddr(connectToDnViaHostname);
    InetSocketAddress addr = NetUtils.createSocketAddr(dnAddr);
    if (LOG.isDebugEnabled()) {
      LOG.debug("Connecting to datanode " + dnAddr + " addr=" + addr);
    }

    // Since we're creating a new UserGroupInformation here, we know that no
    // future RPC proxies will be able to re-use the same connection. And
    // usages of this proxy tend to be one-off calls.
    //
    // This is a temporary fix: callers should really achieve this by using
    // RPC.stopProxy() on the resulting object, but this is currently not
    // working in trunk. See the discussion on HDFS-1965.
    Configuration confWithNoIpcIdle = new Configuration(conf);
    confWithNoIpcIdle.setInt(
        CommonConfigurationKeysPublic.IPC_CLIENT_CONNECTION_MAXIDLETIME_KEY, 0);

    UserGroupInformation ticket =
        UserGroupInformation.createRemoteUser(locatedBlock.getBlock().getLocalBlock().toString());
    ticket.addToken(locatedBlock.getBlockToken());
    return createClientDatanodeProtocolProxy(
        addr, ticket, confWithNoIpcIdle, NetUtils.getDefaultSocketFactory(conf), socketTimeout);
  }
Пример #2
0
 /**
  * Obtain the tokens needed by the job and put them in the UGI
  *
  * @param conf
  */
 protected void downloadTokensAndSetupUGI(Configuration conf) {
   try {
     this.currentUser = UserGroupInformation.getCurrentUser();
     if (UserGroupInformation.isSecurityEnabled()) {
       // Read the file-system tokens from the localized tokens-file.
       Path jobSubmitDir =
           FileContext.getLocalFSFileContext()
               .makeQualified(
                   new Path(new File(DragonJobConfig.JOB_SUBMIT_DIR).getAbsolutePath()));
       Path jobTokenFile = new Path(jobSubmitDir, DragonJobConfig.APPLICATION_TOKENS_FILE);
       fsTokens.addAll(Credentials.readTokenStorageFile(jobTokenFile, conf));
       LOG.info("jobSubmitDir=" + jobSubmitDir + " jobTokenFile=" + jobTokenFile);
       for (Token<? extends TokenIdentifier> tk : fsTokens.getAllTokens()) {
         if (LOG.isDebugEnabled()) {
           LOG.debug(
               "Token of kind "
                   + tk.getKind()
                   + "in current ugi in the AppMaster for service "
                   + tk.getService());
         }
         currentUser.addToken(tk); // For use by AppMaster itself.
       }
     }
   } catch (IOException e) {
     throw new YarnException(e);
   }
 }
Пример #3
0
  /**
   * The function will verify the token with NameNode if available and will create a
   * UserGroupInformation.
   *
   * <p>Code in this function is copied from JspHelper.getTokenUGI
   *
   * @param identifier Delegation token identifier
   * @param password Delegation token password
   * @param kind the kind of token
   * @param service the service for this token
   * @param servletContext Jetty servlet context which contains the NN address
   * @throws SecurityException Thrown when authentication fails
   */
  private static void verifyToken(
      byte[] identifier, byte[] password, Text kind, Text service, ServletContext servletContext) {
    try {
      Token<DelegationTokenIdentifier> token =
          new Token<DelegationTokenIdentifier>(identifier, password, kind, service);

      ByteArrayInputStream buf = new ByteArrayInputStream(token.getIdentifier());
      DataInputStream in = new DataInputStream(buf);
      DelegationTokenIdentifier id = new DelegationTokenIdentifier();
      id.readFields(in);

      final NameNode nn = NameNodeHttpServer.getNameNodeFromContext(servletContext);
      if (nn != null) {
        nn.getNamesystem().verifyToken(id, token.getPassword());
      }

      UserGroupInformation userGroupInformation = id.getUser();
      userGroupInformation.addToken(token);
      LOG.debug(
          "user "
              + userGroupInformation.getUserName()
              + " ("
              + userGroupInformation.getShortUserName()
              + ") authenticated");

      // re-login if necessary
      userGroupInformation.checkTGTAndReloginFromKeytab();
    } catch (IOException e) {
      throw new SecurityException("Failed to verify delegation token " + e, e);
    }
  }
Пример #4
0
  @SuppressWarnings("unchecked") // from Mockito mocks
  @Test
  public <T extends TokenIdentifier> void testUGITokens() throws Exception {
    UserGroupInformation ugi =
        UserGroupInformation.createUserForTesting("TheDoctor", new String[] {"TheTARDIS"});
    Token<T> t1 = mock(Token.class);
    Token<T> t2 = mock(Token.class);

    ugi.addToken(t1);
    ugi.addToken(t2);

    Collection<Token<? extends TokenIdentifier>> z = ugi.getTokens();
    assertTrue(z.contains(t1));
    assertTrue(z.contains(t2));
    assertEquals(2, z.size());

    try {
      z.remove(t1);
      fail("Shouldn't be able to modify token collection from UGI");
    } catch (UnsupportedOperationException uoe) {
      // Can't modify tokens
    }

    // ensure that the tokens are passed through doAs
    Collection<Token<? extends TokenIdentifier>> otherSet =
        ugi.doAs(
            new PrivilegedExceptionAction<Collection<Token<?>>>() {
              public Collection<Token<?>> run() throws IOException {
                return UserGroupInformation.getCurrentUser().getTokens();
              }
            });
    assertTrue(otherSet.contains(t1));
    assertTrue(otherSet.contains(t2));
  }
Пример #5
0
 private void injectToken() throws IOException {
   if (UserGroupInformation.isSecurityEnabled()) {
     Token<DelegationTokenIdentifier> token = params.delegationToken();
     token.setKind(HDFS_DELEGATION_KIND);
     ugi.addToken(token);
   }
 }
  /**
   * Getter for proxiedFs, using the passed parameters to create an instance of a proxiedFs.
   *
   * @param properties
   * @param authType is either TOKEN or KEYTAB.
   * @param authPath is the KEYTAB location if the authType is KEYTAB; otherwise, it is the token
   *     file.
   * @param uri File system URI.
   * @throws IOException
   * @throws InterruptedException
   * @throws URISyntaxException
   * @return proxiedFs
   */
  public FileSystem getProxiedFileSystem(
      State properties, AuthType authType, String authPath, String uri)
      throws IOException, InterruptedException, URISyntaxException {
    Preconditions.checkArgument(
        StringUtils.isNotBlank(properties.getProp(ConfigurationKeys.FS_PROXY_AS_USER_NAME)),
        "State does not contain a proper proxy user name");
    String proxyUserName = properties.getProp(ConfigurationKeys.FS_PROXY_AS_USER_NAME);
    UserGroupInformation proxyUser;
    switch (authType) {
      case KEYTAB: // If the authentication type is KEYTAB, log in a super user first before
                   // creating a proxy user.
        Preconditions.checkArgument(
            StringUtils.isNotBlank(
                properties.getProp(ConfigurationKeys.SUPER_USER_NAME_TO_PROXY_AS_OTHERS)),
            "State does not contain a proper proxy token file name");
        String superUser = properties.getProp(ConfigurationKeys.SUPER_USER_NAME_TO_PROXY_AS_OTHERS);
        UserGroupInformation.loginUserFromKeytab(superUser, authPath);
        proxyUser =
            UserGroupInformation.createProxyUser(
                proxyUserName, UserGroupInformation.getLoginUser());
        break;
      case TOKEN: // If the authentication type is TOKEN, create a proxy user and then add the token
                  // to the user.
        proxyUser =
            UserGroupInformation.createProxyUser(
                proxyUserName, UserGroupInformation.getLoginUser());
        Optional<Token> proxyToken = this.getTokenFromSeqFile(authPath, proxyUserName);
        if (proxyToken.isPresent()) {
          proxyUser.addToken(proxyToken.get());
        } else {
          LOG.warn("No delegation token found for the current proxy user.");
        }
        break;
      default:
        LOG.warn(
            "Creating a proxy user without authentication, which could not perform File system operations.");
        proxyUser =
            UserGroupInformation.createProxyUser(
                proxyUserName, UserGroupInformation.getLoginUser());
        break;
    }

    final Configuration conf = new Configuration();
    JobConfigurationUtils.putStateIntoConfiguration(properties, conf);
    final URI fsURI = URI.create(uri);
    proxyUser.doAs(
        new PrivilegedExceptionAction<Void>() {
          @Override
          public Void run() throws IOException {
            LOG.debug(
                "Now performing file system operations as :"
                    + UserGroupInformation.getCurrentUser());
            proxiedFs = FileSystem.get(fsURI, conf);
            return null;
          }
        });
    return this.proxiedFs;
  }
  private void obtainTokenAndAddIntoUGI(UserGroupInformation clientUgi, String tokenSig)
      throws Exception {
    // obtain a token by directly invoking the metastore operation(without going
    // through the thrift interface). Obtaining a token makes the secret manager
    // aware of the user and that it gave the token to the user
    String tokenStrForm;
    if (tokenSig == null) {
      tokenStrForm = HiveMetaStore.getDelegationToken(clientUgi.getShortUserName());
    } else {
      tokenStrForm = HiveMetaStore.getDelegationToken(clientUgi.getShortUserName(), tokenSig);
      conf.set("hive.metastore.token.signature", tokenSig);
    }

    Token<DelegationTokenIdentifier> t = new Token<DelegationTokenIdentifier>();
    t.decodeFromUrlString(tokenStrForm);
    // add the token to the clientUgi for securely talking to the metastore
    clientUgi.addToken(t);
    // Create the metastore client as the clientUgi. Doing so this
    // way will give the client access to the token that was added earlier
    // in the clientUgi
    HiveMetaStoreClient hiveClient =
        clientUgi.doAs(
            new PrivilegedExceptionAction<HiveMetaStoreClient>() {
              public HiveMetaStoreClient run() throws Exception {
                HiveMetaStoreClient hiveClient = new HiveMetaStoreClient(conf);
                return hiveClient;
              }
            });

    assertTrue("Couldn't connect to metastore", hiveClient != null);

    // try out some metastore operations
    createDBAndVerifyExistence(hiveClient);
    hiveClient.close();

    // Now cancel the delegation token
    HiveMetaStore.cancelDelegationToken(tokenStrForm);

    // now metastore connection should fail
    hiveClient =
        clientUgi.doAs(
            new PrivilegedExceptionAction<HiveMetaStoreClient>() {
              public HiveMetaStoreClient run() {
                try {
                  HiveMetaStoreClient hiveClient = new HiveMetaStoreClient(conf);
                  return hiveClient;
                } catch (MetaException e) {
                  return null;
                }
              }
            });
    assertTrue("Expected metastore operations to fail", hiveClient == null);
  }
 private void updateAMRMToken(Token token) throws IOException {
   org.apache.hadoop.security.token.Token<AMRMTokenIdentifier> amrmToken =
       new org.apache.hadoop.security.token.Token<AMRMTokenIdentifier>(
           token.getIdentifier().array(),
           token.getPassword().array(),
           new Text(token.getKind()),
           new Text(token.getService()));
   // Preserve the token service sent by the RM when adding the token
   // to ensure we replace the previous token setup by the RM.
   // Afterwards we can update the service address for the RPC layer.
   UserGroupInformation currentUGI = UserGroupInformation.getCurrentUser();
   currentUGI.addToken(amrmToken);
   amrmToken.setService(ClientRMProxy.getAMRMTokenService(getConfig()));
 }
Пример #9
0
 private WebHdfsFileSystem getWebHdfsFileSystem(UserGroupInformation ugi, Configuration conf)
     throws IOException {
   if (UserGroupInformation.isSecurityEnabled()) {
     DelegationTokenIdentifier dtId =
         new DelegationTokenIdentifier(new Text(ugi.getUserName()), null, null);
     FSNamesystem namesystem = mock(FSNamesystem.class);
     DelegationTokenSecretManager dtSecretManager =
         new DelegationTokenSecretManager(86400000, 86400000, 86400000, 86400000, namesystem);
     dtSecretManager.startThreads();
     Token<DelegationTokenIdentifier> token =
         new Token<DelegationTokenIdentifier>(dtId, dtSecretManager);
     SecurityUtil.setTokenService(token, NetUtils.createSocketAddr(uri.getAuthority()));
     token.setKind(WebHdfsConstants.WEBHDFS_TOKEN_KIND);
     ugi.addToken(token);
   }
   return (WebHdfsFileSystem) FileSystem.get(uri, conf);
 }
  /**
   * Get the currently logged in user.
   *
   * @return the logged in user
   * @throws IOException if login fails
   */
  public static synchronized UserGroupInformation getLoginUser() throws IOException {
    if (loginUser == null) {
      try {
        Subject subject = new Subject();
        LoginContext login;
        if (isSecurityEnabled()) {
          login = new LoginContext(HadoopConfiguration.USER_KERBEROS_CONFIG_NAME, subject);
        } else if (useConfiguredFileAuth) {
          login = new LoginContext(HadoopConfiguration.FILE_CONFIG_NAME, subject);
        } else {
          login = new LoginContext(HadoopConfiguration.SIMPLE_CONFIG_NAME, subject);
        }
        login.login();
        loginUser = new UserGroupInformation(subject);
        loginUser.setLogin(login);
        // loginUser.setAuthenticationMethod(isSecurityEnabled() ?
        //                                  AuthenticationMethod.KERBEROS :
        //                                  AuthenticationMethod.SIMPLE);
        AuthenticationMethod authMethod = AuthenticationMethod.SIMPLE;
        if (isSecurityEnabled()) {
          authMethod = AuthenticationMethod.KERBEROS;
        } else if (useConfiguredFileAuth) {
          authMethod = AuthenticationMethod.CONFIGFILE;
        } else {
          authMethod = AuthenticationMethod.SIMPLE;
        }
        loginUser.setAuthenticationMethod(authMethod);

        loginUser = new UserGroupInformation(login.getSubject());
        String fileLocation = System.getenv(HADOOP_TOKEN_FILE_LOCATION);
        if (fileLocation != null && isSecurityEnabled()) {
          // load the token storage file and put all of the tokens into the
          // user.
          Credentials cred = Credentials.readTokenStorageFiles(fileLocation, conf);
          for (Token<?> token : cred.getAllTokens()) {
            loginUser.addToken(token);
          }
        }
        loginUser.spawnAutoRenewalThreadForUserCreds();
      } catch (LoginException le) {
        throw new IOException("failure to login", le);
      }
    }
    return loginUser;
  }
Пример #11
0
  public static void cloneDelegationTokenForLogicalAddress(
      UserGroupInformation ugi, String haJtAddress, Collection<InetSocketAddress> jtAddresses) {
    Text haService = HAUtil.buildTokenServiceForLogicalAddress(haJtAddress);
    Token<DelegationTokenIdentifier> haToken =
        tokenSelector.selectToken(haService, ugi.getTokens());

    if (haToken != null) {
      for (InetSocketAddress singleJtAddr : jtAddresses) {
        Token<DelegationTokenIdentifier> specificToken =
            new Token<DelegationTokenIdentifier>(haToken);
        SecurityUtil.setTokenService(specificToken, singleJtAddr);
        ugi.addToken(specificToken);
        LOG.debug(
            "Mapped HA service delegation token for logical address "
                + haJtAddress
                + " to jt "
                + singleJtAddr);
      }
    } else {
      LOG.debug("No HA service delegation token found for logical address " + haJtAddress);
    }
  }
Пример #12
0
  /**
   * Get {@link UserGroupInformation} and possibly the delegation token out of the request.
   *
   * @param context the Servlet context
   * @param request the http request
   * @param conf configuration
   * @param secureAuthMethod the AuthenticationMethod used in secure mode.
   * @param tryUgiParameter Should it try the ugi parameter?
   * @return a new user from the request
   * @throws AccessControlException if the request has no token
   */
  public static UserGroupInformation getUGI(
      ServletContext context,
      HttpServletRequest request,
      Configuration conf,
      final AuthenticationMethod secureAuthMethod,
      final boolean tryUgiParameter)
      throws IOException {
    final UserGroupInformation ugi;
    final String usernameFromQuery = getUsernameFromQuery(request, tryUgiParameter);
    final String doAsUserFromQuery = request.getParameter(DoAsParam.NAME);

    if (UserGroupInformation.isSecurityEnabled()) {
      final String remoteUser = request.getRemoteUser();
      String tokenString = request.getParameter(DELEGATION_PARAMETER_NAME);
      if (tokenString != null) {
        Token<DelegationTokenIdentifier> token = new Token<DelegationTokenIdentifier>();
        token.decodeFromUrlString(tokenString);
        SecurityUtil.setTokenService(token, NameNode.getAddress(conf));
        token.setKind(DelegationTokenIdentifier.HDFS_DELEGATION_KIND);

        ByteArrayInputStream buf = new ByteArrayInputStream(token.getIdentifier());
        DataInputStream in = new DataInputStream(buf);
        DelegationTokenIdentifier id = new DelegationTokenIdentifier();
        id.readFields(in);
        if (context != null) {
          NameNode nn = (NameNode) context.getAttribute("name.node");
          if (nn != null) {
            // Verify the token.
            nn.getNamesystem()
                .getDelegationTokenSecretManager()
                .verifyToken(id, token.getPassword());
          }
        }
        ugi = id.getUser();
        if (ugi.getRealUser() == null) {
          // non-proxy case
          checkUsername(ugi.getShortUserName(), usernameFromQuery);
          checkUsername(null, doAsUserFromQuery);
        } else {
          // proxy case
          checkUsername(ugi.getRealUser().getShortUserName(), usernameFromQuery);
          checkUsername(ugi.getShortUserName(), doAsUserFromQuery);
          ProxyUsers.authorize(ugi, request.getRemoteAddr(), conf);
        }
        ugi.addToken(token);
        ugi.setAuthenticationMethod(AuthenticationMethod.TOKEN);
      } else {
        if (remoteUser == null) {
          throw new IOException("Security enabled but user not " + "authenticated by filter");
        }
        final UserGroupInformation realUgi = UserGroupInformation.createRemoteUser(remoteUser);
        checkUsername(realUgi.getShortUserName(), usernameFromQuery);
        // This is not necessarily true, could have been auth'ed by user-facing
        // filter
        realUgi.setAuthenticationMethod(secureAuthMethod);
        ugi = initUGI(realUgi, doAsUserFromQuery, request, true, conf);
      }
    } else { // Security's not on, pull from url
      final UserGroupInformation realUgi =
          usernameFromQuery == null
              ? getDefaultWebUser(conf) // not specified in request
              : UserGroupInformation.createRemoteUser(usernameFromQuery);
      realUgi.setAuthenticationMethod(AuthenticationMethod.SIMPLE);
      ugi = initUGI(realUgi, doAsUserFromQuery, request, false, conf);
    }

    if (LOG.isDebugEnabled()) LOG.debug("getUGI is returning: " + ugi.getShortUserName());
    return ugi;
  }
Пример #13
0
  @Override
  public void secureBulkLoadHFiles(
      RpcController controller,
      SecureBulkLoadHFilesRequest request,
      RpcCallback<SecureBulkLoadHFilesResponse> done) {
    final List<Pair<byte[], String>> familyPaths = new ArrayList<Pair<byte[], String>>();
    for (ClientProtos.BulkLoadHFileRequest.FamilyPath el : request.getFamilyPathList()) {
      familyPaths.add(new Pair(el.getFamily().toByteArray(), el.getPath()));
    }

    Token userToken = null;
    if (userProvider.isHadoopSecurityEnabled()) {
      userToken =
          new Token(
              request.getFsToken().getIdentifier().toByteArray(),
              request.getFsToken().getPassword().toByteArray(),
              new Text(request.getFsToken().getKind()),
              new Text(request.getFsToken().getService()));
    }
    final String bulkToken = request.getBulkToken();
    User user = getActiveUser();
    final UserGroupInformation ugi = user.getUGI();
    if (userToken != null) {
      ugi.addToken(userToken);
    } else if (userProvider.isHadoopSecurityEnabled()) {
      // we allow this to pass through in "simple" security mode
      // for mini cluster testing
      ResponseConverter.setControllerException(
          controller, new DoNotRetryIOException("User token cannot be null"));
      done.run(SecureBulkLoadHFilesResponse.newBuilder().setLoaded(false).build());
      return;
    }

    HRegion region = env.getRegion();
    boolean bypass = false;
    if (region.getCoprocessorHost() != null) {
      try {
        bypass = region.getCoprocessorHost().preBulkLoadHFile(familyPaths);
      } catch (IOException e) {
        ResponseConverter.setControllerException(controller, e);
        done.run(SecureBulkLoadHFilesResponse.newBuilder().setLoaded(false).build());
        return;
      }
    }
    boolean loaded = false;
    if (!bypass) {
      // Get the target fs (HBase region server fs) delegation token
      // Since we have checked the permission via 'preBulkLoadHFile', now let's give
      // the 'request user' necessary token to operate on the target fs.
      // After this point the 'doAs' user will hold two tokens, one for the source fs
      // ('request user'), another for the target fs (HBase region server principal).
      if (userProvider.isHadoopSecurityEnabled()) {
        FsDelegationToken targetfsDelegationToken = new FsDelegationToken(userProvider, "renewer");
        try {
          targetfsDelegationToken.acquireDelegationToken(fs);
        } catch (IOException e) {
          ResponseConverter.setControllerException(controller, e);
          done.run(SecureBulkLoadHFilesResponse.newBuilder().setLoaded(false).build());
          return;
        }
        Token<?> targetFsToken = targetfsDelegationToken.getUserToken();
        if (targetFsToken != null
            && (userToken == null || !targetFsToken.getService().equals(userToken.getService()))) {
          ugi.addToken(targetFsToken);
        }
      }

      loaded =
          ugi.doAs(
              new PrivilegedAction<Boolean>() {
                @Override
                public Boolean run() {
                  FileSystem fs = null;
                  try {
                    Configuration conf = env.getConfiguration();
                    fs = FileSystem.get(conf);
                    for (Pair<byte[], String> el : familyPaths) {
                      Path p = new Path(el.getSecond());
                      Path stageFamily = new Path(bulkToken, Bytes.toString(el.getFirst()));
                      if (!fs.exists(stageFamily)) {
                        fs.mkdirs(stageFamily);
                        fs.setPermission(stageFamily, PERM_ALL_ACCESS);
                      }
                    }
                    // We call bulkLoadHFiles as requesting user
                    // To enable access prior to staging
                    return env.getRegion()
                        .bulkLoadHFiles(
                            familyPaths, true, new SecureBulkLoadListener(fs, bulkToken, conf));
                  } catch (Exception e) {
                    LOG.error("Failed to complete bulk load", e);
                  }
                  return false;
                }
              });
    }
    if (region.getCoprocessorHost() != null) {
      try {
        loaded = region.getCoprocessorHost().postBulkLoadHFile(familyPaths, loaded);
      } catch (IOException e) {
        ResponseConverter.setControllerException(controller, e);
        done.run(SecureBulkLoadHFilesResponse.newBuilder().setLoaded(false).build());
        return;
      }
    }
    done.run(SecureBulkLoadHFilesResponse.newBuilder().setLoaded(loaded).build());
  }
Пример #14
0
  @Override
  protected TaskRunner2Result callInternal() throws Exception {
    isStarted.set(true);

    this.startTime = System.currentTimeMillis();
    this.threadName = Thread.currentThread().getName();
    if (LOG.isDebugEnabled()) {
      LOG.debug("canFinish: " + taskSpec.getTaskAttemptID() + ": " + canFinish());
    }

    // Unregister from the AMReporter, since the task is now running.
    this.amReporter.unregisterTask(request.getAmHost(), request.getAmPort());

    synchronized (this) {
      if (!shouldRunTask) {
        LOG.info("Not starting task {} since it was killed earlier", taskSpec.getTaskAttemptID());
        return new TaskRunner2Result(EndReason.KILL_REQUESTED, null, false);
      }
    }

    // TODO This executor seems unnecessary. Here and TezChild
    ExecutorService executorReal =
        Executors.newFixedThreadPool(
            1, new ThreadFactoryBuilder().setDaemon(true).setNameFormat("TezTaskRunner").build());
    executor = MoreExecutors.listeningDecorator(executorReal);

    // TODO Consolidate this code with TezChild.
    runtimeWatch.start();
    UserGroupInformation taskUgi = UserGroupInformation.createRemoteUser(request.getUser());
    taskUgi.addCredentials(credentials);

    Map<String, ByteBuffer> serviceConsumerMetadata = new HashMap<>();
    serviceConsumerMetadata.put(
        TezConstants.TEZ_SHUFFLE_HANDLER_SERVICE_ID,
        TezCommonUtils.convertJobTokenToBytes(jobToken));
    Multimap<String, String> startedInputsMap = createStartedInputMap(request.getFragmentSpec());

    UserGroupInformation taskOwner =
        UserGroupInformation.createRemoteUser(request.getTokenIdentifier());
    final InetSocketAddress address =
        NetUtils.createSocketAddrForHost(request.getAmHost(), request.getAmPort());
    SecurityUtil.setTokenService(jobToken, address);
    taskOwner.addToken(jobToken);
    umbilical =
        taskOwner.doAs(
            new PrivilegedExceptionAction<LlapTaskUmbilicalProtocol>() {
              @Override
              public LlapTaskUmbilicalProtocol run() throws Exception {
                return RPC.getProxy(
                    LlapTaskUmbilicalProtocol.class,
                    LlapTaskUmbilicalProtocol.versionID,
                    address,
                    conf);
              }
            });

    taskReporter =
        new LlapTaskReporter(
            umbilical,
            confParams.amHeartbeatIntervalMsMax,
            confParams.amCounterHeartbeatInterval,
            confParams.amMaxEventsPerHeartbeat,
            new AtomicLong(0),
            request.getContainerIdString());

    String attemptId = fragmentInfo.getFragmentIdentifierString();
    IOContextMap.setThreadAttemptId(attemptId);
    try {
      synchronized (this) {
        if (shouldRunTask) {
          taskRunner =
              new TezTaskRunner2(
                  conf,
                  taskUgi,
                  fragmentInfo.getLocalDirs(),
                  taskSpec,
                  request.getAppAttemptNumber(),
                  serviceConsumerMetadata,
                  envMap,
                  startedInputsMap,
                  taskReporter,
                  executor,
                  objectRegistry,
                  pid,
                  executionContext,
                  memoryAvailable,
                  false);
        }
      }
      if (taskRunner == null) {
        LOG.info("Not starting task {} since it was killed earlier", taskSpec.getTaskAttemptID());
        return new TaskRunner2Result(EndReason.KILL_REQUESTED, null, false);
      }

      try {
        TaskRunner2Result result = taskRunner.run();
        if (result.isContainerShutdownRequested()) {
          LOG.warn("Unexpected container shutdown requested while running task. Ignoring");
        }
        isCompleted.set(true);
        return result;
      } finally {
        FileSystem.closeAllForUGI(taskUgi);
        LOG.info(
            "ExecutionTime for Container: "
                + request.getContainerIdString()
                + "="
                + runtimeWatch.stop().elapsedMillis());
        if (LOG.isDebugEnabled()) {
          LOG.debug(
              "canFinish post completion: " + taskSpec.getTaskAttemptID() + ": " + canFinish());
        }
      }
    } finally {
      IOContextMap.clearThreadAttempt(attemptId);
    }
  }