@Override
  protected Release findLatestActiveRelease(String appId, String clusterName, String namespaceName,
                                            ApolloNotificationMessages clientMessages) {
    String messageKey = ReleaseMessageKeyGenerator.generate(appId, clusterName, namespaceName);
    String cacheKey = messageKey;

    if (bizConfig.isConfigServiceCacheKeyIgnoreCase()) {
      cacheKey = cacheKey.toLowerCase();
    }

    Tracer.logEvent(TRACER_EVENT_CACHE_GET, cacheKey);

    ConfigCacheEntry cacheEntry = configCache.getUnchecked(cacheKey);

    //cache is out-dated
    if (clientMessages != null && clientMessages.has(messageKey) &&
        clientMessages.get(messageKey) > cacheEntry.getNotificationId()) {
      //invalidate the cache and try to load from db again
      invalidate(cacheKey);
      cacheEntry = configCache.getUnchecked(cacheKey);
    }

    return cacheEntry.getRelease();
  }
@Test
  public void testFindLatestActiveReleaseWithReleaseNotFound() throws Exception {
    when(releaseMessageService.findLatestReleaseMessageForMessages(Lists.newArrayList(someKey))).thenReturn(null);
    when(releaseService.findLatestActiveRelease(someAppId, someClusterName, someNamespaceName)).thenReturn(null);

    Release release = configServiceWithCache.findLatestActiveRelease(someAppId, someClusterName, someNamespaceName,
        someNotificationMessages);
    Release anotherRelease = configServiceWithCache.findLatestActiveRelease(someAppId, someClusterName,
        someNamespaceName, someNotificationMessages);

    int retryTimes = 100;

    for (int i = 0; i < retryTimes; i++) {
      configServiceWithCache.findLatestActiveRelease(someAppId, someClusterName,
          someNamespaceName, someNotificationMessages);
    }

    assertNull(release);
    assertNull(anotherRelease);

    verify(releaseMessageService, times(1)).findLatestReleaseMessageForMessages(Lists.newArrayList(someKey));
    verify(releaseService, times(1)).findLatestActiveRelease(someAppId, someClusterName, someNamespaceName);
  }