@Override
  public AppsInfo getApps(HttpServletRequest hsr, String stateQuery,
      Set<String> statesQuery, String finalStatusQuery, String userQuery,
      String queueQuery, String count, String startedBegin, String startedEnd,
      String finishBegin, String finishEnd, Set<String> applicationTypes,
      Set<String> applicationTags, String name, Set<String> unselectedFields) {

    RouterAppInfoCacheKey routerAppInfoCacheKey = RouterAppInfoCacheKey.newInstance(
        hsr, stateQuery, statesQuery, finalStatusQuery, userQuery, queueQuery, count,
        startedBegin, startedEnd, finishBegin, finishEnd, applicationTypes,
        applicationTags, name, unselectedFields);

    if (appInfosCacheEnabled && routerAppInfoCacheKey != null) {
      if (appInfosCaches.containsKey(routerAppInfoCacheKey)) {
        return appInfosCaches.get(routerAppInfoCacheKey);
      }
    }

    AppsInfo apps = new AppsInfo();
    long startTime = clock.getTime();

    // HttpServletRequest does not work with ExecutorCompletionService.
    // Create a duplicate hsr.
    final HttpServletRequest hsrCopy = clone(hsr);
    Collection<SubClusterInfo> subClusterInfos = federationFacade.getActiveSubClusters();

    List<AppsInfo> appsInfos = subClusterInfos.parallelStream().map(subCluster -> {
      try {
        DefaultRequestInterceptorREST interceptor = getOrCreateInterceptorForSubCluster(subCluster);
        AppsInfo rmApps = interceptor.getApps(hsrCopy, stateQuery, statesQuery, finalStatusQuery,
            userQuery, queueQuery, count, startedBegin, startedEnd, finishBegin, finishEnd,
            applicationTypes, applicationTags, name, unselectedFields);
        if (rmApps != null) {
          return rmApps;
        }
      } catch (Exception e) {
        LOG.warn("Failed to get application report.", e);
      }
      routerMetrics.incrMultipleAppsFailedRetrieved();
      LOG.error("Subcluster {} failed to return appReport.", subCluster.getSubClusterId());
      return null;
    }).collect(Collectors.toList());

    appsInfos.forEach(appsInfo -> {
      if (appsInfo != null) {
        apps.addAll(appsInfo.getApps());
        long stopTime = clock.getTime();
        routerMetrics.succeededMultipleAppsRetrieved(stopTime - startTime);
      }
    });

    if (apps.getApps().isEmpty()) {
      return new AppsInfo();
    }

    // Merge all the application reports got from all the available YARN RMs
    AppsInfo resultAppsInfo = RouterWebServiceUtil.mergeAppsInfo(
        apps.getApps(), returnPartialReport);

    if (appInfosCacheEnabled && routerAppInfoCacheKey != null) {
      appInfosCaches.put(routerAppInfoCacheKey, resultAppsInfo);
    }

    return resultAppsInfo;
  }
@Test
  public void testGetApplicationsReport() {

    AppsInfo responseGet = interceptor.getApps(null, null, null, null, null,
        null, null, null, null, null, null, null, null, null, null);

    Assert.assertNotNull(responseGet);
    Assert.assertEquals(NUM_SUBCLUSTER, responseGet.getApps().size());
    // The merged operations is tested in TestRouterWebServiceUtil
  }