private boolean verifyBestPossAndExtView()

in helix-core/src/main/java/org/apache/helix/tools/ClusterStateVerifier.java [203:343]


    private boolean verifyBestPossAndExtView(HelixDataAccessor accessor,
        Map<String, Map<String, String>> errStates, String clusterName, Set<String> resources) {
      try {
        PropertyKey.Builder keyBuilder = accessor.keyBuilder();
        // read cluster once and do verification
        ResourceControllerDataProvider cache = new ResourceControllerDataProvider(clusterName);
        cache.refresh(accessor);

        Map<String, IdealState> idealStates = new HashMap<>(cache.getIdealStates());

        // filter out all resources that use Task state model
        Iterator<Map.Entry<String, IdealState>> it = idealStates.entrySet().iterator();
        while (it.hasNext()) {
          Map.Entry<String, IdealState> pair = it.next();
          if (pair.getValue().getStateModelDefRef().equals(TaskConstants.STATE_MODEL_NAME)) {
            it.remove();
          }
        }

        Map<String, ExternalView> extViews =
            accessor.getChildValuesMap(keyBuilder.externalViews(), true);
        if (extViews == null) {
          extViews = Collections.emptyMap();
        }

        // Filter resources if requested
        if (resources != null && !resources.isEmpty()) {
          idealStates.keySet().retainAll(resources);
          extViews.keySet().retainAll(resources);
        }

        // if externalView is not empty and idealState doesn't exist
        // add empty idealState for the resource
        for (String resource : extViews.keySet()) {
          if (!idealStates.containsKey(resource)) {
            idealStates.put(resource, new IdealState(resource));
          }
        }

        // calculate best possible state
        BestPossibleStateOutput bestPossOutput = calcBestPossState(cache, resources);
        Map<String, Map<Partition, Map<String, String>>> bestPossStateMap =
            bestPossOutput.getStateMap();

        // set error states
        if (errStates != null) {
          for (String resourceName : errStates.keySet()) {
            Map<String, String> partErrStates = errStates.get(resourceName);
            for (String partitionName : partErrStates.keySet()) {
              String instanceName = partErrStates.get(partitionName);

              if (!bestPossStateMap.containsKey(resourceName)) {
                bestPossStateMap.put(resourceName, new HashMap<Partition, Map<String, String>>());
              }
              Partition partition = new Partition(partitionName);
              if (!bestPossStateMap.get(resourceName).containsKey(partition)) {
                bestPossStateMap.get(resourceName).put(partition, new HashMap<String, String>());
              }
              bestPossStateMap.get(resourceName).get(partition)
                  .put(instanceName, HelixDefinedState.ERROR.toString());
            }
          }
        }

        // System.out.println("stateMap: " + bestPossStateMap);

        for (String resourceName : idealStates.keySet()) {
          ExternalView extView = extViews.get(resourceName);
          if (extView == null) {
            IdealState is = idealStates.get(resourceName);
            if (is.isExternalViewDisabled()) {
              continue;
            } else {
              LOG.info("externalView for " + resourceName + " is not available");
              return false;
            }
          }

          // step 0: remove empty map and DROPPED state from best possible state
          Map<Partition, Map<String, String>> bpStateMap =
              bestPossOutput.getResourceMap(resourceName);
          Iterator<Map.Entry<Partition, Map<String, String>>> iter = bpStateMap.entrySet().iterator();
          while (iter.hasNext()) {
            Map.Entry<Partition, Map<String, String>> entry = iter.next();
            Map<String, String> instanceStateMap = entry.getValue();
            if (instanceStateMap.isEmpty()) {
              iter.remove();
            } else {
              // remove instances with DROPPED state
              Iterator<Map.Entry<String, String>> insIter = instanceStateMap.entrySet().iterator();
              while (insIter.hasNext()) {
                Map.Entry<String, String> insEntry = insIter.next();
                String state = insEntry.getValue();
                if (state.equalsIgnoreCase(HelixDefinedState.DROPPED.toString())) {
                  insIter.remove();
                }
              }
            }
          }

          // System.err.println("resource: " + resourceName + ", bpStateMap: " + bpStateMap);

          // step 1: externalView and bestPossibleState has equal size
          int extViewSize = extView.getRecord().getMapFields().size();
          int bestPossStateSize = bestPossOutput.getResourceMap(resourceName).size();
          if (extViewSize != bestPossStateSize) {
            LOG.info("exterView size (" + extViewSize + ") is different from bestPossState size ("
                + bestPossStateSize + ") for resource: " + resourceName);

            // System.err.println("exterView size (" + extViewSize
            // + ") is different from bestPossState size (" + bestPossStateSize
            // + ") for resource: " + resourceName);
            // System.out.println("extView: " + extView.getRecord().getMapFields());
            // System.out.println("bestPossState: " +
            // bestPossOutput.getResourceMap(resourceName));
            return false;
          }

          // step 2: every entry in external view is contained in best possible state
          for (String partition : extView.getRecord().getMapFields().keySet()) {
            Map<String, String> evInstanceStateMap = extView.getRecord().getMapField(partition);
            Map<String, String> bpInstanceStateMap =
                bestPossOutput.getInstanceStateMap(resourceName, new Partition(partition));

            boolean result = compareMap(evInstanceStateMap, bpInstanceStateMap);
            if (result == false) {
              LOG.info("externalView is different from bestPossibleState for partition:" + partition);

              // System.err.println("externalView is different from bestPossibleState for partition: "
              // + partition + ", actual: " + evInstanceStateMap + ", bestPoss: " +
              // bpInstanceStateMap);
              return false;
            }
          }
        }
        return true;
      } catch (Exception e) {
        LOG.error("exception in verification", e);
        return false;
      }
    }