private void scanGrayReleaseRules() {
    long maxIdScanned = 0;
    boolean hasMore = true;

    while (hasMore && !Thread.currentThread().isInterrupted()) {
      List<GrayReleaseRule> grayReleaseRules = grayReleaseRuleRepository
          .findFirst500ByIdGreaterThanOrderByIdAsc(maxIdScanned);
      if (CollectionUtils.isEmpty(grayReleaseRules)) {
        break;
      }
      mergeGrayReleaseRules(grayReleaseRules);
      int rulesScanned = grayReleaseRules.size();
      maxIdScanned = grayReleaseRules.get(rulesScanned - 1).getId();
      //batch is 500
      hasMore = rulesScanned == 500;
    }
  }
@Test
  public void testScanGrayReleaseRules() throws Exception {
    String someAppId = "someAppId";
    String someClusterName = "someClusterName";
    String someNamespaceName = "someNamespaceName";
    String anotherNamespaceName = "anotherNamespaceName";

    Long someReleaseId = 1L;
    int activeBranchStatus = NamespaceBranchStatus.ACTIVE;

    String someClientAppId = "clientAppId1";
    String someClientIp = "1.1.1.1";
    String someClientLabel = "myLabel";
    String anotherClientAppId = "clientAppId2";
    String anotherClientIp = "2.2.2.2";
    String anotherClientLabel = "testLabel";

    GrayReleaseRule someRule = assembleGrayReleaseRule(someAppId, someClusterName,
        someNamespaceName, Lists.newArrayList(assembleRuleItem(someClientAppId, Sets.newHashSet
            (someClientIp), Sets.newHashSet(someClientLabel))), someReleaseId, activeBranchStatus);

    when(bizConfig.grayReleaseRuleScanInterval()).thenReturn(30);
    when(grayReleaseRuleRepository.findFirst500ByIdGreaterThanOrderByIdAsc(0L)).thenReturn(Lists
        .newArrayList(someRule));

    //scan rules
    grayReleaseRulesHolder.afterPropertiesSet();

    assertEquals(someReleaseId, grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule
        (someClientAppId, someClientIp, anotherClientLabel, someAppId, someClusterName, someNamespaceName));
    assertEquals(someReleaseId, grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule
        (someClientAppId, anotherClientIp, someClientLabel, someAppId, someClusterName, someNamespaceName));
    assertEquals(someReleaseId, grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule
        (someClientAppId.toUpperCase(), someClientIp, someClientLabel, someAppId.toUpperCase(), someClusterName, someNamespaceName.toUpperCase()));
    assertNull(grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule(someClientAppId,
        anotherClientIp, anotherClientLabel, someAppId, someClusterName, someNamespaceName));

    assertNull(grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule(anotherClientAppId,
        someClientIp, someClientLabel, someAppId, someClusterName, someNamespaceName));
    assertNull(grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule(anotherClientAppId,
        anotherClientIp, anotherClientLabel, someAppId, someClusterName, someNamespaceName));

    assertTrue(grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId, someClientIp,
        someNamespaceName));
    assertTrue(grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId.toUpperCase(), someClientIp,
        someNamespaceName.toUpperCase()));
    assertFalse(grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId, anotherClientIp,
        someNamespaceName));
    assertFalse(grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId, someClientIp,
        anotherNamespaceName));

    assertFalse(grayReleaseRulesHolder.hasGrayReleaseRule(anotherClientAppId, anotherClientIp,
        someNamespaceName));
    assertFalse(grayReleaseRulesHolder.hasGrayReleaseRule(anotherClientAppId, anotherClientIp,
        anotherNamespaceName));

    GrayReleaseRule anotherRule = assembleGrayReleaseRule(someAppId, someClusterName,
        someNamespaceName, Lists.newArrayList(assembleRuleItem(anotherClientAppId, Sets.newHashSet
            (anotherClientIp),Sets.newHashSet(anotherClientLabel))), someReleaseId, activeBranchStatus);

    when(grayReleaseRuleRepository.findByAppIdAndClusterNameAndNamespaceName(someAppId,
        someClusterName, someNamespaceName)).thenReturn(Lists.newArrayList(anotherRule));

    //send message
    grayReleaseRulesHolder.handleMessage(assembleReleaseMessage(someAppId, someClusterName,
        someNamespaceName), Topics.APOLLO_RELEASE_TOPIC);

    assertNull(grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule
        (someClientAppId, someClientIp, someClientLabel, someAppId, someClusterName, someNamespaceName));
    assertEquals(someReleaseId, grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule
        (anotherClientAppId, anotherClientIp, someClientLabel, someAppId, someClusterName, someNamespaceName));
    assertEquals(someReleaseId, grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule
        (anotherClientAppId, someClientIp, anotherClientLabel, someAppId, someClusterName, someNamespaceName));
    assertEquals(someReleaseId, grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule
        (anotherClientAppId, anotherClientIp, anotherClientLabel, someAppId, someClusterName, someNamespaceName));


    assertFalse(grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId, someClientIp,
        someNamespaceName));
    assertFalse(grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId, someClientIp,
        anotherNamespaceName));

    assertTrue(grayReleaseRulesHolder.hasGrayReleaseRule(anotherClientAppId, anotherClientIp,
        someNamespaceName));
    assertFalse(grayReleaseRulesHolder.hasGrayReleaseRule(anotherClientAppId, someClientIp,
        someNamespaceName));
    assertFalse(grayReleaseRulesHolder.hasGrayReleaseRule(anotherClientAppId, anotherClientIp,
        anotherNamespaceName));
  }