123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- import { endsWith } from 'lodash';
- import { Set as makeSet, List as makeList, Map as makeMap } from 'immutable';
- import stableStringify from 'json-stable-stringify';
- import { isPausedSelector } from '../selectors/time-travel';
- import { isResourceViewModeSelector } from '../selectors/topology';
- import { pinnedMetricSelector } from '../selectors/node-metric';
- import { shownNodesSelector, shownResourceTopologyIdsSelector } from '../selectors/node-filters';
- //
- // top priority first
- //
- const TOPOLOGY_DISPLAY_PRIORITY = [
- 'ecs-services',
- 'ecs-tasks',
- 'kube-controllers',
- 'services',
- 'replica-sets',
- 'pods',
- 'containers',
- ];
- export function getDefaultTopology(topologies) {
- const flatTopologies = topologies
- .flatMap(t => makeList([t]).concat(t.get('sub_topologies', makeList())));
- return flatTopologies
- .sortBy((t) => {
- const index = TOPOLOGY_DISPLAY_PRIORITY.indexOf(t.get('id'));
- return index === -1 ? Infinity : index;
- })
- .getIn([0, 'id']);
- }
- /**
- * Returns a cache ID based on the topologyId and optionsQuery
- * @param {String} topologyId
- * @param {object} topologyOptions (optional)
- * @return {String}
- */
- export function buildTopologyCacheId(topologyId, topologyOptions) {
- let id = '';
- if (topologyId) {
- id = topologyId;
- if (topologyOptions) {
- id += stableStringify(topologyOptions);
- }
- }
- return id;
- }
- /**
- * Returns a topology object from the topology tree
- * @param {List} subTree
- * @param {String} topologyId
- * @return {Map} topology if found
- */
- export function findTopologyById(subTree, topologyId) {
- let foundTopology;
- subTree.forEach((topology) => {
- if (endsWith(topology.get('url'), topologyId)) {
- foundTopology = topology;
- }
- if (!foundTopology && topology.has('sub_topologies')) {
- foundTopology = findTopologyById(topology.get('sub_topologies'), topologyId);
- }
- });
- return foundTopology;
- }
- export function updateNodeDegrees(nodes, edges) {
- return nodes.map((node) => {
- const nodeId = node.get('id');
- const degree = edges.count(edge => edge.get('source') === nodeId
- || edge.get('target') === nodeId);
- return node.set('degree', degree);
- });
- }
- /* set topology.id and parentId for sub-topologies in place */
- export function updateTopologyIds(topologies, parentId) {
- if(topologies) {
- return topologies.map((topology) => {
- if (topology) {
- const result = Object.assign({}, topology);
- result.id = topology.url.split('/').pop();
- if (parentId) {
- result.parentId = parentId;
- }
- if (topology.sub_topologies) {
- result.sub_topologies = updateTopologyIds(topology.sub_topologies, result.id);
- }
- return result;
- }
- });
- }
- }
- export function addTopologyFullname(topologies) {
- return topologies.map((t) => {
- if (!t.sub_topologies) {
- return Object.assign({}, t, {fullName: t.name});
- }
- return Object.assign({}, t, {
- fullName: t.name,
- sub_topologies: t.sub_topologies.map(st => (
- Object.assign({}, st, {fullName: `${t.name} ${st.name}`})
- ))
- });
- });
- }
- // adds ID field to topology (based on last part of URL path) and save urls in
- // map for easy lookup
- export function setTopologyUrlsById(topologyUrlsById, topologies) {
- let urlMap = topologyUrlsById;
- if (topologies) {
- topologies.forEach((topology) => {
- urlMap = urlMap.set(topology.id, topology.url);
- if (topology.sub_topologies) {
- topology.sub_topologies.forEach((subTopology) => {
- urlMap = urlMap.set(subTopology.id, subTopology.url);
- });
- }
- });
- }
- return urlMap;
- }
- export function filterHiddenTopologies(topologies, currentTopology) {
- currentTopology = currentTopology || makeMap();
- return topologies.filter(t => (!t.hide_if_empty || t.stats.node_count > 0
- || t.stats.filtered_nodes > 0 || t.id === currentTopology.get('id')
- || t.id === currentTopology.get('parentId')));
- }
- export function getCurrentTopologyOptions(state) {
- return state.getIn(['currentTopology', 'options']);
- }
- export function isTopologyNodeCountZero(state) {
- const nodeCount = state.getIn(['currentTopology', 'stats', 'node_count'], 0);
- // If we are browsing the past, assume there would normally be some nodes at different times.
- // If we are in the resource view, don't rely on these stats at all (for now).
- return nodeCount === 0 && !isPausedSelector(state) && !isResourceViewModeSelector(state);
- }
- export function isNodesDisplayEmpty(state) {
- // Consider a topology in the resource view empty if it has no pinned metric.
- if (isResourceViewModeSelector(state)) {
- return !pinnedMetricSelector(state) || shownResourceTopologyIdsSelector(state).isEmpty();
- }
- // Otherwise (in graph and table view), we only look at the nodes content.
- return shownNodesSelector(state).isEmpty();
- }
- export function getAdjacentNodes(state, originNodeId) {
- let adjacentNodes = makeSet();
- const nodeId = originNodeId || state.get('selectedNodeId');
- if (nodeId) {
- if (state.hasIn(['nodes', nodeId])) {
- adjacentNodes = makeSet(state.getIn(['nodes', nodeId, 'adjacency']));
- // fill up set with reverse edges
- state.get('nodes').forEach((node, id) => {
- if (node.get('adjacency') && node.get('adjacency').includes(nodeId)) {
- adjacentNodes = adjacentNodes.add(id);
- }
- });
- }
- }
- return adjacentNodes;
- }
- export function hasSelectedNode(state) {
- const selectedNodeId = state.get('selectedNodeId');
- return state.hasIn(['nodes', selectedNodeId]);
- }
- export function getCurrentTopologyUrl(state) {
- return state.getIn(['currentTopology', 'url']);
- }
|