private String getProbeUpdateString() {
    StringBuilder probeModifyBuilder = new StringBuilder();
    for (Entry<String, ConcurrentHashMap<String, CacheData>> cacheDatasEntry :
        this.cache.entrySet()) {
      String dataId = cacheDatasEntry.getKey();
      ConcurrentHashMap<String, CacheData> cacheDatas = cacheDatasEntry.getValue();
      if (null == cacheDatas) {
        continue;
      }
      for (Entry<String, CacheData> cacheDataEntry : cacheDatas.entrySet()) {
        final CacheData data = cacheDataEntry.getValue();
        if (!data.isUseLocalConfigInfo()) {
          probeModifyBuilder.append(dataId).append(WORD_SEPARATOR);

          if (null != cacheDataEntry.getValue().getGroup()
              && Constants.NULL != cacheDataEntry.getValue().getGroup()) {
            probeModifyBuilder.append(cacheDataEntry.getValue().getGroup()).append(WORD_SEPARATOR);
          } else {
            probeModifyBuilder.append(WORD_SEPARATOR);
          }

          if (null != cacheDataEntry.getValue().getMd5()
              && Constants.NULL != cacheDataEntry.getValue().getMd5()) {
            probeModifyBuilder.append(cacheDataEntry.getValue().getMd5()).append(LINE_SEPARATOR);
          } else {
            probeModifyBuilder.append(LINE_SEPARATOR);
          }
        }
      }
    }
    String probeModifyString = probeModifyBuilder.toString();
    return probeModifyString;
  }
 private void checkLocalConfigInfo() {
   for (Entry<String /* dataId */, ConcurrentHashMap<String /* group */, CacheData>>
       cacheDatasEntry : cache.entrySet()) {
     ConcurrentHashMap<String, CacheData> cacheDatas = cacheDatasEntry.getValue();
     if (null == cacheDatas) {
       continue;
     }
     for (Entry<String, CacheData> cacheDataEntry : cacheDatas.entrySet()) {
       final CacheData cacheData = cacheDataEntry.getValue();
       try {
         String configInfo = getLocalConfigureInfomation(cacheData);
         if (null != configInfo) {
           if (log.isInfoEnabled()) {
             log.info(
                 "Read local configure, dataId:"
                     + cacheData.getDataId()
                     + ", group:"
                     + cacheData.getGroup());
           }
           popConfigInfo(cacheData, configInfo);
           continue;
         }
         if (cacheData.isUseLocalConfigInfo()) {
           continue;
         }
       } catch (Exception e) {
         log.error("checkLocalConfigInfo error:", e);
       }
     }
   }
 }
  private String getNotModified(String dataId, CacheData cacheData, HttpMethod httpMethod) {
    Header md5Header = httpMethod.getResponseHeader(Constants.CONTENT_MD5);
    if (null == md5Header) {
      throw new RuntimeException("RP_NO_CHANGE response not contain MD5");
    }
    String md5 = md5Header.getValue();
    if (!cacheData.getMd5().equals(md5)) {
      String lastMd5 = cacheData.getMd5();
      cacheData.setMd5(Constants.NULL);
      cacheData.setLastModifiedHeader(Constants.NULL);

      throw new RuntimeException(
          "MD5 verify error,DataID:["
              + dataId
              + "]MD5 last:["
              + lastMd5
              + "]MD5 current:["
              + md5
              + "]");
    }

    cacheData.setMd5(md5);
    changeSpacingInterval(httpMethod);
    if (log.isInfoEnabled()) {
      log.info("DataId: " + dataId + ",not changed");
    }
    return null;
  }
 private String getSnapshotConfigInformation(String dataId, String group) {
   if (group == null) {
     group = Constants.DEFAULT_GROUP;
   }
   try {
     CacheData cacheData = getCacheData(dataId, group);
     String config = this.snapshotConfigInfoProcessor.getConfigInfomation(dataId, group);
     if (config != null && cacheData != null) {
       cacheData.incrementFetchCountAndGet();
     }
     return config;
   } catch (Exception e) {
     log.error("getSnapshotConfigInformation error dataId=" + dataId + ",group=" + group, e);
     return null;
   }
 }
  private String getSuccess(
      String dataId, String group, CacheData cacheData, HttpMethod httpMethod) {
    String configInfo = Constants.NULL;
    configInfo = getContent(httpMethod);
    if (null == configInfo) {
      throw new RuntimeException("RP_OK configInfo is null");
    }

    Header md5Header = httpMethod.getResponseHeader(Constants.CONTENT_MD5);
    if (null == md5Header) {
      throw new RuntimeException("RP_OK not contain MD5, " + configInfo);
    }
    String md5 = md5Header.getValue();
    if (!checkContent(configInfo, md5)) {
      throw new RuntimeException(
          "MD5 verify error,DataID:["
              + dataId
              + "]ConfigInfo:["
              + configInfo
              + "]MD5:["
              + md5
              + "]");
    }

    Header lastModifiedHeader = httpMethod.getResponseHeader(Constants.LAST_MODIFIED);
    if (null == lastModifiedHeader) {
      throw new RuntimeException("RP_OK result not contain lastModifiedHeader");
    }
    String lastModified = lastModifiedHeader.getValue();

    cacheData.setMd5(md5);
    cacheData.setLastModifiedHeader(lastModified);

    changeSpacingInterval(httpMethod);

    String key = makeCacheKey(dataId, group);
    contentCache.put(key, configInfo);

    StringBuilder buf = new StringBuilder();
    buf.append("dataId=").append(dataId);
    buf.append(" ,group=").append(group);
    buf.append(" ,content=").append(configInfo);
    dataLog.info(buf.toString());

    return configInfo;
  }
 private void checkSnapshot() {
   for (Entry<String, ConcurrentHashMap<String, CacheData>> cacheDatasEntry : cache.entrySet()) {
     ConcurrentHashMap<String, CacheData> cacheDatas = cacheDatasEntry.getValue();
     if (null == cacheDatas) {
       continue;
     }
     for (Entry<String, CacheData> cacheDataEntry : cacheDatas.entrySet()) {
       final CacheData cacheData = cacheDataEntry.getValue();
       if (!cacheData.isUseLocalConfigInfo() && cacheData.getFetchCount() == 0) {
         String configInfo =
             getSnapshotConfigInformation(cacheData.getDataId(), cacheData.getGroup());
         if (configInfo != null) {
           popConfigInfo(cacheData, configInfo);
         }
       }
     }
   }
 }
  public String getConfigureInfomationFromLocal(String dataId, String group, long timeout) {
    if (null == group) {
      group = Constants.DEFAULT_GROUP;
    }
    CacheData cacheData = getCacheData(dataId, group);
    try {
      String localConfig = localConfigInfoProcessor.getLocalConfigureInfomation(cacheData, true);
      if (localConfig != null) {
        cacheData.incrementFetchCountAndGet();
        saveSnapshot(dataId, group, localConfig);

        return localConfig;
      }
    } catch (IOException e) {
      log.error("getLocalConfigureInfomation error", e);
    }

    return null;
  }
 void popConfigInfo(final CacheData cacheData, final String configInfo) {
   final ConfigureInfomation configureInfomation = new ConfigureInfomation();
   configureInfomation.setConfigureInfomation(configInfo);
   final String dataId = cacheData.getDataId();
   final String group = cacheData.getGroup();
   configureInfomation.setDataId(dataId);
   configureInfomation.setGroup(group);
   cacheData.incrementFetchCountAndGet();
   if (null != this.subscriberListener.getExecutor()) {
     this.subscriberListener
         .getExecutor()
         .execute(
             new Runnable() {
               public void run() {
                 try {
                   subscriberListener.receiveConfigInfo(configureInfomation);
                   saveSnapshot(dataId, group, configInfo);
                 } catch (Throwable t) {
                   log.error(
                       "popConfigInfo listener receiveConfigInfo error: group="
                           + group
                           + ", dataId="
                           + dataId,
                       t);
                 }
               }
             });
   } else {
     try {
       subscriberListener.receiveConfigInfo(configureInfomation);
       saveSnapshot(dataId, group, configInfo);
     } catch (Throwable t) {
       log.error(
           "popConfigInfo listener receiveConfigInfo error: group=" + group + ", dataId=" + dataId,
           t);
     }
   }
 }
  private void configureHttpMethod(
      boolean skipContentCache, CacheData cacheData, long onceTimeOut, HttpMethod httpMethod) {
    if (skipContentCache && null != cacheData) {
      if (null != cacheData.getLastModifiedHeader()
          && Constants.NULL != cacheData.getLastModifiedHeader()) {
        httpMethod.addRequestHeader(Constants.IF_MODIFIED_SINCE, cacheData.getLastModifiedHeader());
      }
      if (null != cacheData.getMd5() && Constants.NULL != cacheData.getMd5()) {
        httpMethod.addRequestHeader(Constants.CONTENT_MD5, cacheData.getMd5());
      }
    }

    httpMethod.addRequestHeader(Constants.ACCEPT_ENCODING, "gzip,deflate");

    HttpMethodParams params = new HttpMethodParams();
    params.setSoTimeout((int) onceTimeOut);
    httpMethod.setParams(params);
    httpClient
        .getHostConfiguration()
        .setHost(
            diamondConfigure.getDomainNameList().get(this.domainNamePos.get()),
            diamondConfigure.getPort());
  }
  String getConfigureInformation(
      String dataId, String group, long timeout, boolean skipContentCache) {
    start();
    if (!isRun) {
      throw new RuntimeException(
          "DiamondSubscriber is not running, so can't fetch from ConfigureInformation");
    }
    if (null == group) {
      group = Constants.DEFAULT_GROUP;
    }
    // =======================ʹ�ò���ģʽ=======================
    if (MockServer.isTestMode()) {
      return MockServer.getConfigInfo(dataId, group);
    }

    if (!skipContentCache) {
      String key = makeCacheKey(dataId, group);
      String content = contentCache.get(key);
      if (content != null) {
        return content;
      }
    }

    long waitTime = 0;

    String uri = getUriString(dataId, group);
    if (log.isInfoEnabled()) {
      log.info(uri);
    }

    CacheData cacheData = getCacheData(dataId, group);

    int retryTimes = this.getDiamondConfigure().getRetrieveDataRetryTimes();
    log.info("Retry times is " + retryTimes);
    int tryCount = 0;

    while (0 == timeout || timeout > waitTime) {
      tryCount++;
      if (tryCount > retryTimes + 1) {
        log.warn("Retry time reach the limit, so break");
        break;
      }
      log.info("Fetch config " + tryCount + "times, waitTime:" + waitTime);

      long onceTimeOut = getOnceTimeOut(waitTime, timeout);
      waitTime += onceTimeOut;

      HttpMethod httpMethod = new GetMethod(uri);

      configureHttpMethod(skipContentCache, cacheData, onceTimeOut, httpMethod);

      try {
        int httpStatus = httpClient.executeMethod(httpMethod);

        switch (httpStatus) {
          case SC_OK:
            {
              String result = getSuccess(dataId, group, cacheData, httpMethod);
              return result;
            }

          case SC_NOT_MODIFIED:
            {
              String result = getNotModified(dataId, cacheData, httpMethod);
              return result;
            }

          case SC_NOT_FOUND:
            {
              log.warn("DataID:" + dataId + "not found");
              cacheData.setMd5(Constants.NULL);
              this.snapshotConfigInfoProcessor.removeSnapshot(dataId, group);
              return null;
            }

          case SC_SERVICE_UNAVAILABLE:
            {
              rotateToNextDomain();
            }
            break;

          default:
            {
              log.warn("HTTP State: " + httpStatus + ":" + httpClient.getState());
              rotateToNextDomain();
            }
        }
      } catch (HttpException e) {
        log.error("Fetch config HttpException", e);
        rotateToNextDomain();
      } catch (IOException e) {
        log.error("Fetch config IOException", e);
        rotateToNextDomain();
      } catch (Exception e) {
        log.error("Unknown Exception", e);
        rotateToNextDomain();
      } finally {
        httpMethod.releaseConnection();
      }
    }
    throw new RuntimeException(
        "Fetch config timeout, DataID=" + dataId + ", Group=" + group + ",timeout=" + timeout);
  }