managed/src/main/java/com/yugabyte/yw/common/PlacementInfoUtil.java
/**
   * This method configures nodes for Edit case, with user specified placement info.
   * It supports the following combinations --
   * 1. Reset AZ, it result in a full move as new config is generated
   * 2. Any subsequent operation after a Reset AZ will be a full move since subsequent operations will build on reset
   * 3. Simple Node Count increase will result in an expand.
   * 4. Any Shrink scenario will be a full move. This is to prevent inconsistencies in cases where the node which is subtracted
   * is a master node vs. if it is not a master node which are indistinguishable from an AZ Selector pov.
   * 5. Multi to Single AZ ops will also be a full move operation since it involves shrinks
   * @param taskParams
   */
This method configures nodes for Edit case, with user specified placement info.
It supports the following combinations
1. Reset AZ, it result in a full move as new config is generated
2. Any subsequent operation after a Reset AZ will be a full move since subsequent operations will build on reset
3. Simple Node Count increase will result in an expand.
4. Any Shrink scenario will be a full move. This is to prevent inconsistencies in cases where the node which is subtracted
is a master node vs. if it is not a master node which are indistinguishable from an AZ Selector pov.
5. Multi to Single AZ ops will also be a full move operation since it involves shrinks
@param taskParams
This method configures nodes for Edit case with user specified placement info . It supports the following combinations 1 . Reset AZ it result in a full move as new config is generated 2 . Any subsequent operation after a Reset AZ will be a full move since subsequent operations will build on reset 3 . Simple Node Count increase will result in an expand . 4 . Any Shrink scenario will be a full move . This is to prevent inconsistencies in cases where the node which is subtracted is a master node vs . if it is not a master node which are indistinguishable from an AZ Selector pov . 5 . Multi to Single AZ ops will also be a full move operation since it involves shrinks @param taskParams
public static void configureNodeEditUsingPlacementInfo(UniverseDefinitionTaskParams taskParams) {
    PlacementInfo primaryPlacementInfo = taskParams.getPrimaryCluster().placementInfo;
    Universe universe = Universe.get(taskParams.universeUUID);
    Cluster primaryCluster = universe.getUniverseDetails().getPrimaryCluster();
    Collection<NodeDetails> existingNodes = universe.getNodesInCluster(primaryCluster.uuid);
    if (primaryPlacementInfo == null) {
      taskParams.nodeDetailsSet.removeIf((NodeDetails nd) -> {
        return (nd.placementUuid.equals(primaryCluster.uuid));
      });
      Cluster cluster = taskParams.getPrimaryCluster();
      taskParams.getPrimaryCluster().placementInfo = getPlacementInfo(cluster.clusterType, cluster.userIntent);
      configureDefaultNodeStates(cluster, taskParams.nodeDetailsSet, universe);
    } else {
      Map<UUID, Integer> requiredAZToNodeMap = getAzUuidToNumNodes(taskParams.getPrimaryCluster().placementInfo);
      Map<UUID, Integer> existingAZToNodeMap = getAzUuidToNumNodes(universe.getUniverseDetails().nodeDetailsSet);
      boolean isSimpleExpand = true;
      for (UUID requiredAZUUID: requiredAZToNodeMap.keySet()) {
        if (!existingAZToNodeMap.containsKey(requiredAZUUID) ||
            requiredAZToNodeMap.get(requiredAZUUID) < existingAZToNodeMap.get(requiredAZUUID)) {
          isSimpleExpand = false;
          break;
        } else {
          existingAZToNodeMap.remove(requiredAZUUID);
        }
      }
      if (existingAZToNodeMap.size() > 0) {
        isSimpleExpand = false;
      }
      if (isSimpleExpand) {
        configureNodesUsingPlacementInfo(taskParams.getPrimaryCluster(),
                                         taskParams.nodeDetailsSet, true);
        return;
      } else {
        taskParams.nodeDetailsSet.clear();
        int startIndex = getNextIndexToConfigure(existingNodes);
        int iter = 0;
        LinkedHashSet<PlacementIndexes> placements = new LinkedHashSet<PlacementIndexes>();
        for (int cIdx = 0; cIdx < primaryPlacementInfo.cloudList.size(); cIdx++) {
          PlacementCloud cloud = primaryPlacementInfo.cloudList.get(cIdx);
          for (int rIdx = 0; rIdx < cloud.regionList.size(); rIdx++) {
            PlacementRegion region = cloud.regionList.get(rIdx);
            for (int azIdx = 0; azIdx < region.azList.size(); azIdx++) {
              PlacementAZ az = region.azList.get(azIdx);
              int numDesired = az.numNodesInAZ;
              int numChange = Math.abs(numDesired);
              while (numChange > 0) {
                iter ++;
                placements.add(new PlacementIndexes(azIdx, rIdx, cIdx, true));
                NodeDetails nodeDetails =
                    createNodeDetailsWithPlacementIndex(taskParams.getPrimaryCluster(),
                        new PlacementIndexes(azIdx, rIdx, cIdx, true),
                        startIndex + iter);
                taskParams.nodeDetailsSet.add(nodeDetails);
                numChange--;
              }
            }
          }
        }
      }
    }
    LOG.info("Removing {} nodes.", existingNodes.size());
    for (NodeDetails node : existingNodes) {
      node.state = NodeDetails.NodeState.ToBeRemoved;
      taskParams.nodeDetailsSet.add(node);
    }
  }
public static void configureNodeEditUsingPlacementInfo ( UniverseDefinitionTaskParams taskParams ) { PlacementInfo primaryPlacementInfo = taskParams . getPrimaryCluster ( ) . placementInfo ; Universe universe = Universe . get ( taskParams . universeUUID ) ; Cluster primaryCluster = universe . getUniverseDetails ( ) . getPrimaryCluster ( ) ; Collection < NodeDetails > existingNodes = universe . getNodesInCluster ( primaryCluster . uuid ) ; if ( primaryPlacementInfo == null ) { taskParams . nodeDetailsSet . removeIf ( ( NodeDetails nd ) -> { return ( nd . placementUuid . equals ( primaryCluster . uuid ) ) ; } ) ; Cluster cluster = taskParams . getPrimaryCluster ( ) ; taskParams . getPrimaryCluster ( ) . placementInfo = getPlacementInfo ( cluster . clusterType , cluster . userIntent ) ; configureDefaultNodeStates ( cluster , taskParams . nodeDetailsSet , universe ) ; } else { Map < UUID , Integer > requiredAZToNodeMap = getAzUuidToNumNodes ( taskParams . getPrimaryCluster ( ) . placementInfo ) ; Map < UUID , Integer > existingAZToNodeMap = getAzUuidToNumNodes ( universe . getUniverseDetails ( ) . nodeDetailsSet ) ; boolean isSimpleExpand = true ; for ( UUID requiredAZUUID : requiredAZToNodeMap . keySet ( ) ) { if ( ! existingAZToNodeMap . containsKey ( requiredAZUUID ) || requiredAZToNodeMap . get ( requiredAZUUID ) < existingAZToNodeMap . get ( requiredAZUUID ) ) { isSimpleExpand = false ; break ; } else { existingAZToNodeMap . remove ( requiredAZUUID ) ; } } if ( existingAZToNodeMap . size ( ) > 0 ) { isSimpleExpand = false ; } if ( isSimpleExpand ) { configureNodesUsingPlacementInfo ( taskParams . getPrimaryCluster ( ) , taskParams . nodeDetailsSet , true ) ; return ; } else { taskParams . nodeDetailsSet . clear ( ) ; int startIndex = getNextIndexToConfigure ( existingNodes ) ; int iter = 0 ; LinkedHashSet < PlacementIndexes > placements = new LinkedHashSet < PlacementIndexes > ( ) ; for ( int cIdx = 0 ; cIdx < primaryPlacementInfo . cloudList . size ( ) ; cIdx ++ ) { PlacementCloud cloud = primaryPlacementInfo . cloudList . get ( cIdx ) ; for ( int rIdx = 0 ; rIdx < cloud . regionList . size ( ) ; rIdx ++ ) { PlacementRegion region = cloud . regionList . get ( rIdx ) ; for ( int azIdx = 0 ; azIdx < region . azList . size ( ) ; azIdx ++ ) { PlacementAZ az = region . azList . get ( azIdx ) ; int numDesired = az . numNodesInAZ ; int numChange = Math . abs ( numDesired ) ; while ( numChange > 0 ) { iter ++ ; placements . add ( new PlacementIndexes ( azIdx , rIdx , cIdx , true ) ) ; NodeDetails nodeDetails = createNodeDetailsWithPlacementIndex ( taskParams . getPrimaryCluster ( ) , new PlacementIndexes ( azIdx , rIdx , cIdx , true ) , startIndex + iter ) ; taskParams . nodeDetailsSet . add ( nodeDetails ) ; numChange -- ; } } } } } } LOG . info ( "Removing {} nodes." , existingNodes . size ( ) ) ; for ( NodeDetails node : existingNodes ) { node . state = NodeDetails . NodeState . ToBeRemoved ; taskParams . nodeDetailsSet . add ( node ) ; } }
This method configures nodes for Edit case, with user specified placement info.
This method configures nodes for Edit case with user specified placement info .
// If placementInfo is null then user has chosen to Reset AZ config // Hence a new full move configuration is generated // Remove primary cluster nodes which will be added back in ToBeRemoved state // In other operations we need to distinguish between expand and full-move. // If simple expand we can go in the configure using placement info path // Break execution sequence because there are no nodes to be decomissioned // If not simply create a nodeDetailsSet from the provided placement info. // Add all new nodes in the tbe added state