@Override
  public GetClusterNodeAttributesResponse getClusterNodeAttributes(
      GetClusterNodeAttributesRequest request) throws YarnException, IOException {
    if (request == null) {
      routerMetrics.incrGetClusterNodeAttributesFailedRetrieved();
      String msg = "Missing getClusterNodeAttributes request.";
      RouterAuditLogger.logFailure(user.getShortUserName(), GET_CLUSTERNODEATTRIBUTES, UNKNOWN,
          TARGET_CLIENT_RM_SERVICE, msg);
      RouterServerUtil.logAndThrowException(msg, null);
    }
    long startTime = clock.getTime();
    ClientMethod remoteMethod = new ClientMethod("getClusterNodeAttributes",
        new Class[] {GetClusterNodeAttributesRequest.class}, new Object[] {request});
    Collection<GetClusterNodeAttributesResponse> clusterNodeAttributesResponses = null;
    try {
      clusterNodeAttributesResponses = invokeConcurrent(remoteMethod,
          GetClusterNodeAttributesResponse.class);
    } catch (Exception ex) {
      routerMetrics.incrGetClusterNodeAttributesFailedRetrieved();
      String msg = "Unable to get cluster node attributes due to exception.";
      RouterAuditLogger.logFailure(user.getShortUserName(), GET_CLUSTERNODEATTRIBUTES, UNKNOWN,
          TARGET_CLIENT_RM_SERVICE, msg);
      RouterServerUtil.logAndThrowException(msg, ex);
    }
    long stopTime = clock.getTime();
    routerMetrics.succeededGetClusterNodeAttributesRetrieved(stopTime - startTime);
    RouterAuditLogger.logSuccess(user.getShortUserName(), GET_CLUSTERNODEATTRIBUTES,
        TARGET_CLIENT_RM_SERVICE);
    return RouterYarnClientUtils.mergeClusterNodeAttributesResponse(clusterNodeAttributesResponses);
  }
@Test
  public void testClusterNodeAttributes() throws Exception {
    LOG.info("Test FederationClientInterceptor : Get ClusterNodeAttributes request.");

    // null request
    LambdaTestUtils.intercept(YarnException.class, "Missing getClusterNodeAttributes request.",
        () -> interceptor.getClusterNodeAttributes(null));

    // normal request
    GetClusterNodeAttributesResponse response =
        interceptor.getClusterNodeAttributes(GetClusterNodeAttributesRequest.newInstance());

    Assert.assertNotNull(response);
    Set<NodeAttributeInfo> nodeAttributeInfos = response.getNodeAttributes();
    Assert.assertNotNull(nodeAttributeInfos);
    Assert.assertEquals(4, nodeAttributeInfos.size());

    NodeAttributeInfo nodeAttributeInfo1 =
        NodeAttributeInfo.newInstance(NodeAttributeKey.newInstance("GPU"),
        NodeAttributeType.STRING);
    Assert.assertTrue(nodeAttributeInfos.contains(nodeAttributeInfo1));

    NodeAttributeInfo nodeAttributeInfo2 =
        NodeAttributeInfo.newInstance(NodeAttributeKey.newInstance("OS"),
        NodeAttributeType.STRING);
    Assert.assertTrue(nodeAttributeInfos.contains(nodeAttributeInfo2));
  }