All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.arextest.schedule.comparer.impl.PrepareCompareSourceRemoteLoader Maven / Gradle / Ivy

There is a newer version: 2.0.4
Show newest version
package com.arextest.schedule.comparer.impl;

import com.arextest.model.replay.CompareRelationResult;
import com.arextest.model.mock.AREXMocker;
import com.arextest.model.mock.MockCategoryType;
import com.arextest.model.replay.QueryReplayResultRequestType;
import com.arextest.model.replay.QueryReplayResultResponseType;
import com.arextest.model.replay.holder.ListResultHolder;
import com.arextest.schedule.client.HttpWepServiceApiClient;
import com.arextest.schedule.comparer.CategoryComparisonHolder;
import com.arextest.schedule.comparer.CategoryComparisonHolder.CompareResultItem;
import com.arextest.schedule.comparer.CompareItem;
import com.arextest.schedule.model.ReplayActionCaseItem;
import com.arextest.schedule.serialization.ZstdJacksonSerializer;
import com.arextest.schedule.service.MetricService;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public final class PrepareCompareSourceRemoteLoader {

  private static final int INDEX_NOT_FOUND = -1;
  @Resource
  MetricService metricService;
  @Value("${arex.storage.replayResult.url}")
  private String replayResultUrl;
  @Resource
  private HttpWepServiceApiClient httpWepServiceApiClient;
  @Resource
  private ZstdJacksonSerializer zstdJacksonSerializer;
  @Resource
  private PrepareCompareItemBuilder prepareCompareItemBuilder;

  public List buildWaitCompareList(ReplayActionCaseItem caseItem,
      boolean useReplayId) {
    String targetResultId = null;
    String sourceResultId = null;
    if (useReplayId) {
      targetResultId = caseItem.getTargetResultId();
      sourceResultId = caseItem.getSourceResultId();
    }
    final String recordId = caseItem.getRecordId();

    if (StringUtils.isNotBlank(sourceResultId)) {

      List sourceResponse = this.getReplayResult(recordId,
          sourceResultId);
      List targetResponse = this.getReplayResult(recordId,
          targetResultId);
      if (CollectionUtils.isEmpty(sourceResponse) || CollectionUtils.isEmpty(targetResponse)) {
        LOGGER.warn(
            "replay recordId:{} invalid response,source replayId:{} size:{},target replayId:{} size:{}",
            recordId, sourceResultId, sourceResponse.size(), targetResultId, targetResponse.size());
        return Collections.emptyList();
      }
      return buildWaitCompareList(sourceResponse, targetResponse);
    }
    List replayResult = this.getReplayResult(recordId, targetResultId);
    // todo record the QMessage replay log, which will be optimized for removal later.
    metricService.recordTraceIdEvent(caseItem, replayResult);
    return replayResult;
  }

  // TODO: In the scenario where the operation is empty, there is a problem of redundant returns in the record.
  public List getReplayResult(String replayId, String resultId) {
    QueryReplayResultResponseType responseType = remoteLoad(replayId, resultId);
    return decodeResult(responseType);
  }

  private QueryReplayResultResponseType remoteLoad(String replayId, String resultId) {
    QueryReplayResultRequestType resultRequest = new QueryReplayResultRequestType();
    resultRequest.setRecordId(replayId);
    resultRequest.setReplayResultId(resultId);
    return httpWepServiceApiClient.retryZstdJsonPost(replayResultUrl,
        resultRequest, QueryReplayResultResponseType.class);
  }

  /**
   * Compatible logic.
   * The subsequent agent will match the packets and does not need to be processed in the schedule.
   * @param replayResultResponseType
   * @return
   */
  private List decodeResult(
      QueryReplayResultResponseType replayResultResponseType) {
    if (replayResultResponseType == null ||
        replayResultResponseType.getResponseStatusType() == null ||
        replayResultResponseType.getResponseStatusType().hasError() ||
        Boolean.TRUE.equals(replayResultResponseType.getInvalidResult())) {
      LOGGER.warn("failed to get replay result because of invalid case");
      return Collections.emptyList();
    }

    // Use needMatch to determine whether to adopt new logic
    return Boolean.TRUE.equals(replayResultResponseType.getNeedMatch()) ?
        processMatchNeeded(replayResultResponseType) : processMatchNotNeeded(replayResultResponseType);
  }

  /**
   * Processing of messages that require matching relationships that need to be compared
   * @param replayResultResponseType
   * @return
   */
  private List processMatchNeeded(QueryReplayResultResponseType replayResultResponseType) {
    List resultHolderList = replayResultResponseType.getResultHolderList();
    if (CollectionUtils.isEmpty(resultHolderList)) {
      LOGGER.warn("query replay result has empty size");
      return Collections.emptyList();
    }

    List decodedListResult = new ArrayList<>(resultHolderList.size());
    for (ListResultHolder stringListResultHolder : resultHolderList) {
      MockCategoryType categoryType = stringListResultHolder.getCategoryType();
      if (categoryType == null || (categoryType.isSkipComparison() &&
          !MockCategoryType.Q_MESSAGE_CONSUMER.getName().equalsIgnoreCase(categoryType.getName()))) {
        continue;
      }

      CategoryComparisonHolder resultHolder = new CategoryComparisonHolder();
      resultHolder.setCategoryName(categoryType.getName());
      decodedListResult.add(resultHolder);

      List recordList = zstdDeserialize(stringListResultHolder.getRecord());
      List replayResultList = zstdDeserialize(stringListResultHolder.getReplayResult());

      if (categoryType.isEntryPoint() && (CollectionUtils.isEmpty(recordList) || CollectionUtils.isEmpty(replayResultList))) {
        // call missing or new call
        return Collections.emptyList();
      }

      resultHolder.setRecord(recordList);
      resultHolder.setReplayResult(replayResultList);
      resultHolder.setNeedMatch(true);
    }
    return decodedListResult;
  }

  /**
   * Processing of packets that do not require matching
   * @param replayResultResponseType
   * @return
   */
  private List processMatchNotNeeded(QueryReplayResultResponseType replayResultResponseType) {
    List replayResults = replayResultResponseType.getReplayResults();
    if (CollectionUtils.isEmpty(replayResults)) {
      LOGGER.warn("query replay result has empty size");
      return Collections.emptyList();
    }

    List decodedListResult = new ArrayList<>(replayResults.size());
    for (CompareRelationResult result : replayResults) {
      MockCategoryType categoryType = result.getCategoryType();
      if (categoryType == null || (!categoryType.isEntryPoint() && categoryType.isSkipComparison())) {
        continue;
      }

      if (categoryType.isEntryPoint() && !categoryType.isSkipComparison() &&
          (StringUtils.isEmpty(result.getRecordMessage()) || StringUtils.isEmpty(result.getReplayMessage()))) {
        // The main category is missing
        return Collections.emptyList();
      }

      CategoryComparisonHolder resultHolder = new CategoryComparisonHolder();
      resultHolder.setCategoryName(categoryType.getName());

      CompareItem recordCompareItem = prepareCompareItemBuilder.build(result, true);
      CompareItem replayCompareItem = prepareCompareItemBuilder.build(result, false);

      resultHolder.setCompareResultItem(new CompareResultItem(recordCompareItem, replayCompareItem));
      resultHolder.setNeedMatch(false);
      decodedListResult.add(resultHolder);
    }
    return decodedListResult;
  }

  private List zstdDeserialize(List base64List) {
    if (CollectionUtils.isEmpty(base64List)) {
      return Collections.emptyList();
    }
    List decodedResult = new ArrayList<>(base64List.size());
    for (int i = 0; i < base64List.size(); i++) {
      String base64 = base64List.get(i);
      AREXMocker source = zstdJacksonSerializer.deserialize(base64, AREXMocker.class);
      if (source == null) {
        continue;
      }
      CompareItem item = prepareCompareItemBuilder.build(source);
      if (item != null) {
        decodedResult.add(item);
      }
    }
    return decodedResult;
  }

  private List buildWaitCompareList(
      List sourceResult,
      List targetResultList) {
    for (CategoryComparisonHolder sourceResultHolder : sourceResult) {
      int targetIndex = findResultByCategory(targetResultList,
          sourceResultHolder.getCategoryName());
      sourceResultHolder.setRecord(sourceResultHolder.getReplayResult());
      if (targetIndex == INDEX_NOT_FOUND) {
        continue;
      }
      CategoryComparisonHolder targetResult = targetResultList.get(targetIndex);
      sourceResultHolder.setReplayResult(targetResult.getReplayResult());
      targetResultList.remove(targetIndex);
    }
    if (CollectionUtils.isNotEmpty(targetResultList)) {
      for (CategoryComparisonHolder resultHolder : targetResultList) {
        resultHolder.setRecord(Collections.emptyList());
        sourceResult.add(resultHolder);
      }
    }
    return sourceResult;
  }

  private int findResultByCategory(List source, String category) {
    for (int i = 0; i < source.size(); i++) {
      CategoryComparisonHolder resultHolder = source.get(i);
      if (StringUtils.equals(resultHolder.getCategoryName(), category)) {
        return i;
      }
    }
    return INDEX_NOT_FOUND;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy