HashBasedRouterPolicy extends AbstractRouterPolicy { @Override public SubClusterId getHomeSubcluster( ApplicationSubmissionContext appSubmissionContext, List<SubClusterId> blackListSubClusters) throws YarnException { Map<SubClusterId, SubClusterInfo> activeSubclusters = getActiveSubclusters(); FederationPolicyUtils.validateSubClusterAvailability( new ArrayList<SubClusterId>(activeSubclusters.keySet()), blackListSubClusters); if (blackListSubClusters != null) { for (SubClusterId scId : blackListSubClusters) { activeSubclusters.remove(scId); } } validate(appSubmissionContext); int chosenPosition = Math.abs( appSubmissionContext.getQueue().hashCode() % activeSubclusters.size()); List<SubClusterId> list = new ArrayList<>(activeSubclusters.keySet()); Collections.sort(list); return list.get(chosenPosition); }  @Override void reinitialize(
      FederationPolicyInitializationContext federationPolicyContext); @Override SubClusterId getHomeSubcluster(
      ApplicationSubmissionContext appSubmissionContext,
      List<SubClusterId> blackListSubClusters);  }
@Test public void testHashSpreadUniformlyAmongSubclusters() throws YarnException { SubClusterId chosen; Map<SubClusterId, AtomicLong> counter = new HashMap<>(); for (SubClusterId id : getActiveSubclusters().keySet()) { counter.put(id, new AtomicLong(0)); } long jobPerSub = 100; ApplicationSubmissionContext applicationSubmissionContext = mock(ApplicationSubmissionContext.class); for (int i = 0; i < jobPerSub * numSubclusters; i++) { when(applicationSubmissionContext.getQueue()).thenReturn("queue" + i); chosen = ((FederationRouterPolicy) getPolicy()) .getHomeSubcluster(applicationSubmissionContext, null); counter.get(chosen).addAndGet(1); } for (AtomicLong a : counter.values()) { Assert.assertEquals(a.get(), jobPerSub); } }