github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ui/src/util/localities.ts (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  import _ from "lodash";
    12  
    13  import { LocalityTier, LocalityTree } from "src/redux/localities";
    14  import { INodeStatus } from "src/util/proto";
    15  
    16  /*
    17   * parseLocalityRoute parses the URL fragment used to route to a particular
    18   * locality and returns the locality tiers it represents.
    19   */
    20  export function parseLocalityRoute(route: string): LocalityTier[] {
    21    if (_.isEmpty(route)) {
    22      return [];
    23    }
    24  
    25    const segments = route.split("/");
    26    return segments.map((segment) => {
    27      const [key, value] = segment.split("=");
    28      return { key, value };
    29    });
    30  }
    31  
    32  /*
    33   * generateLocalityRoute generates the URL fragment to route to a particular
    34   * locality from the locality tiers.
    35   */
    36  export function generateLocalityRoute(tiers: LocalityTier[]): string {
    37    return "/" + tiers.map(({ key, value }) => key + "=" + value).join("/");
    38  }
    39  
    40  /*
    41   * getNodeLocalityTiers returns the locality tiers of a node, typed as an array
    42   * of LocalityTier rather than Tier$Properties.
    43   */
    44  export function getNodeLocalityTiers(node: INodeStatus): LocalityTier[] {
    45    return node.desc.locality.tiers.map(({ key, value }) => ({ key, value }));
    46  }
    47  
    48  /*
    49   * getChildLocalities returns an array of the locality trees for localities that
    50   * are the immediate children of this one.
    51   */
    52  export function getChildLocalities(locality: LocalityTree): LocalityTree[] {
    53    const children: LocalityTree[] = [];
    54  
    55    _.values(locality.localities).forEach((tier) => {
    56      children.push(..._.values(tier));
    57    });
    58  
    59    return children;
    60  }
    61  
    62  /*
    63   * getLocality gets the locality within this tree which corresponds to a set of
    64   * locality tiers, or null if the locality is not present.
    65   */
    66  export function getLocality(localityTree: LocalityTree, tiers: LocalityTier[]): LocalityTree {
    67    let result = localityTree;
    68    for (let i = 0; i < tiers.length; i += 1) {
    69      const { key, value } = tiers[i];
    70  
    71      const thisTier = result.localities[key];
    72      if (_.isNil(thisTier)) {
    73        return null;
    74      }
    75  
    76      result = thisTier[value];
    77      if (_.isNil(result)) {
    78        return null;
    79      }
    80    }
    81  
    82    return result;
    83  }
    84  
    85  /* getLeaves returns the leaves under the given locality tree. Confusingly,
    86   * in this tree the "leaves" of the tree are nodes, i.e. servers.
    87   */
    88  export function getLeaves(tree: LocalityTree): INodeStatus[] {
    89    const output: INodeStatus[] = [];
    90    function recur(curTree: LocalityTree) {
    91      output.push(...curTree.nodes);
    92      _.forEach(curTree.localities, (localityValues) => {
    93        _.forEach(localityValues, recur);
    94      });
    95    }
    96    recur(tree);
    97    return output;
    98  }
    99  
   100  /*
   101   * getLocalityLabel returns the human-readable label for the locality.
   102   */
   103  export function getLocalityLabel(path: LocalityTier[]): string {
   104    if (path.length === 0) {
   105      return "Cluster";
   106    }
   107  
   108    const thisTier = path[path.length - 1];
   109    return `${thisTier.key}=${thisTier.value}`;
   110  }
   111  
   112  /*
   113   * allNodesHaveLocality returns true if there exists a node without a locality flag.
   114   */
   115  export function allNodesHaveLocality(nodes: INodeStatus[]): boolean {
   116    const nodesWithoutLocality = nodes.filter((n) => n.desc.locality.tiers.length === 0);
   117    return nodesWithoutLocality.length === 0;
   118  }