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 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;
  }
  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);
  }