From 70add54458ce2ce3a412252fed8ce4a1f63b7da1 Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 5 Sep 2024 15:41:41 +0200 Subject: [PATCH 1/7] chore(mesh-wide): fix set ref state for new links --- .../components/FeatureDetail/LinkDetail.tsx | 42 ++++++++++--------- .../src/components/Map/LinkLine.tsx | 6 ++- .../src/meshWideTypes.tsx | 3 +- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx index 07104a69..35cd02e4 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -175,8 +175,8 @@ const SelectedLink = ({ ); }; -const LinkFeatureDetail = ({ actual, reference }: LinkMapFeature) => { - const linkToShow = reference ?? actual; +const LinkFeatureDetail = ({ linkToShow, actual }: LinkMapFeature) => { + // const linkToShow = reference ?? actual; const [selectedLink, setSelectedLink] = useState(0); const { errors } = usePointToPointErrors({ id: linkToShow.id, @@ -224,12 +224,15 @@ const LinkFeatureDetail = ({ actual, reference }: LinkMapFeature) => { ); }; -export const LinkReferenceStatus = ({ reference }: LinkMapFeature) => { +export const LinkReferenceStatus = ({ + linkToShow, + reference, +}: LinkMapFeature) => { const isNewLink = !reference; const { errors } = usePointToPointErrors({ - id: reference.id, - type: reference.type, + id: linkToShow.id, + type: linkToShow.type, }); const { @@ -240,7 +243,7 @@ export const LinkReferenceStatus = ({ reference }: LinkMapFeature) => { // Check if there are errors of global reference state to shown const { reference: fetchDataReference } = getQueryByLinkType( - reference.type + linkToShow.type ); const { data: referenceData, isError: isReferenceError } = fetchDataReference({}); @@ -263,19 +266,19 @@ export const LinkReferenceStatus = ({ reference }: LinkMapFeature) => { }; if (!allNodes) return {}; // Then reduce the nodes to update - return reference.nodes.reduce((acc, node) => { + return linkToShow.nodes.reduce((acc, node) => { // If the node with node name exist get the ipv4 and hostname if (allNodes[node]) { acc[allNodes[node].ipv4] = allNodes[node].hostname; } return acc; }, {}); - }, [meshWideNodesReference, meshWideNodesActual, reference.nodes]); + }, [meshWideNodesReference, meshWideNodesActual, linkToShow.nodes]); // Mutation to update the reference state const { callMutations } = useSetLinkReferenceState({ - linkType: reference.type, - linkToUpdate: reference, + linkType: linkToShow.type, + linkToUpdate: linkToShow, isDown, nodesToUpdate, }); @@ -283,7 +286,7 @@ export const LinkReferenceStatus = ({ reference }: LinkMapFeature) => { // Show confirmation modal before run mutations const setReferenceState = useCallback(async () => { confirmModal( - reference.type, + linkToShow.type, Object.values(nodesToUpdate), isDown, async () => { @@ -311,20 +314,20 @@ export const LinkReferenceStatus = ({ reference }: LinkMapFeature) => { confirmModal, isDown, nodesToUpdate, - reference.type, + linkToShow.type, showToast, ]); let btnText = ( Set reference state for this -
{dataTypeNameMapping(reference.type)} +
{dataTypeNameMapping(linkToShow.type)}
); if (isDown) { btnText = ( - Delete this {dataTypeNameMapping(reference.type)} + Delete this {dataTypeNameMapping(linkToShow.type)}
from reference state
@@ -332,14 +335,15 @@ export const LinkReferenceStatus = ({ reference }: LinkMapFeature) => { } let errorMessage = Same status as in the reference state; - if (referenceError) { - errorMessage = Reference is not set or has errors; - } else if (errors?.hasErrors) { - errorMessage = This link has errors; - } else if (isNewLink) { + + if (isNewLink) { errorMessage = ( This Link is not registered on the reference state ); + } else if (referenceError) { + errorMessage = Reference is not set or has errors; + } else if (errors?.hasErrors) { + errorMessage = This link has errors; } const hasError = errors?.hasErrors || referenceError; diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx index 8833242e..d078c525 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx @@ -38,7 +38,11 @@ export const LinkLine = ({ referenceLink, actualLink }: ILinkLineProps) => { const _setSelectedFeature = () => { setSelectedMapFeature({ id: linkToShow.id, - feature: { reference: linkToShow, actual: actualLink }, + feature: { + reference: referenceLink, + actual: actualLink, + linkToShow, + }, type: "link", }); }; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx index 71a3d6f3..ba5b5999 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx @@ -96,7 +96,8 @@ export type INodes = { [key: string]: INodeInfo }; export type LinkMapFeature = { actual: PontToPointLink; - reference: PontToPointLink; + reference?: PontToPointLink; + linkToShow: PontToPointLink; }; export type NodeMapFeature = { From d98afb0f119853dc3627c823fadf632dd627eb9e Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 5 Sep 2024 16:24:22 +0200 Subject: [PATCH 2/7] chore(mesh-wide): fix reference state is not set --- .../components/FeatureDetail/LinkDetail.tsx | 56 ++++++++----------- .../src/components/configPage/modals.tsx | 17 ++++-- .../src/meshWideQueries.tsx | 12 +++- 3 files changed, 45 insertions(+), 40 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx index 35cd02e4..ee140fe6 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -285,38 +285,23 @@ export const LinkReferenceStatus = ({ // Show confirmation modal before run mutations const setReferenceState = useCallback(async () => { - confirmModal( - linkToShow.type, - Object.values(nodesToUpdate), - isDown, - async () => { - try { - const res = await callMutations(); - if (res.errors.length) { - console.log("Errors"); - throw new Error("Error setting new reference state!"); - } - showToast({ - text: New reference state set!, - }); - } catch (error) { - showToast({ - text: Error setting new reference state!, - }); - } finally { - closeModal(); - } + try { + const res = await callMutations(); + if (res.errors.length) { + console.log("Errors"); + throw new Error("Error setting new reference state!"); } - ); - }, [ - callMutations, - closeModal, - confirmModal, - isDown, - nodesToUpdate, - linkToShow.type, - showToast, - ]); + showToast({ + text: New reference state set!, + }); + } catch (error) { + showToast({ + text: Error setting new reference state!, + }); + } finally { + closeModal(); + } + }, [callMutations, closeModal, showToast]); let btnText = ( @@ -354,7 +339,14 @@ export const LinkReferenceStatus = ({ + confirmModal({ + dataType: linkToShow.type, + nodes: Object.values(nodesToUpdate), + isDown, + cb: setReferenceState, + }) + } > {errorMessage} diff --git a/plugins/lime-plugin-mesh-wide/src/components/configPage/modals.tsx b/plugins/lime-plugin-mesh-wide/src/components/configPage/modals.tsx index a0c1beb1..4fde5161 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/configPage/modals.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/configPage/modals.tsx @@ -120,12 +120,17 @@ export const useSetNodeInfoReferenceStateModal = () => { export const useSetLinkReferenceStateModal = () => { const { toggleModal, setModalState, isModalOpen, closeModal } = useModal(); - const confirmModal = ( - dataType: MeshWideMapDataTypeKeys, - nodes: string[], - isDown: boolean, - cb: () => Promise - ) => { + const confirmModal = ({ + dataType, + nodes, + isDown, + cb, + }: { + dataType: MeshWideMapDataTypeKeys; + nodes: string[]; + isDown: boolean; + cb: () => Promise; + }) => { let title = ( Set reference state for this {dataTypeNameMapping(dataType)}? diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx index 9aab0ae3..ee78fc0a 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx @@ -23,6 +23,7 @@ import { import { useMeshWideSyncCall } from "utils/meshWideSyncCall"; import { useSharedData } from "utils/useSharedData"; +import { isEmpty } from "utils/utils"; const refetchInterval = 60000; @@ -169,8 +170,9 @@ export const useSetLinkReferenceState = ({ let newReferenceLinks = (referenceData[hostname] ?? {}) as IBaseLink; - // This is a hotfix because backend returns an empty string somtimes - if (typeof newReferenceLinks !== "object") newReferenceLinks = {}; + + // This is a hotfix because backend returns an empty array sometimes + if (isEmpty(newReferenceLinks)) newReferenceLinks = {}; for (const mactomac of linkToUpdate.links) { if (isDown) { @@ -194,6 +196,12 @@ export const useSetLinkReferenceState = ({ }, } as ILinks ); + console.log("linkToUpdate", linkToUpdate); + console.log("newReferenceLinks", newReferenceLinks); + console.log("referenceData", referenceData); + console.log("data[hostname]", data[hostname]); + console.log("hostname", hostname); + console.log("queryKey", queryKey); return doSharedStateApiCall(queryKey, ip); }, ips: Object.keys(nodesToUpdate), From 11ef37ac2fdd9f06c7dbf2c8fa6f71ef003e5178 Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 5 Sep 2024 16:39:54 +0200 Subject: [PATCH 3/7] chore(mesh-wide): wrap links and coordinates on a try catch --- .../src/lib/links/getLinksCoordinates.ts | 155 ++++++++++-------- 1 file changed, 85 insertions(+), 70 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts index 19ad7d69..8218f269 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts @@ -18,91 +18,106 @@ export const mergeLinksAndCoordinates = ( nodes?: INodes ): LocatedLinkData => { if (!links || isEmpty(links)) return {}; - const result: LocatedLinkData = {}; - // for every node check all links - for (const actualNodeName in links) { - if ( - isEmpty(links[actualNodeName]) || - typeof links[actualNodeName].links !== "object" // todo(kon): this is an error from the backend - ) - continue; - const srcLoc = links[actualNodeName].src_loc; - for (const [linkKey, linkData] of Object.entries( - links[actualNodeName].links - )) { - // Find destination link info from shared state - let dest: IBaseLink; - for (const destNodeKey in links) { - // Prevent empty objects crashing from shared state - if (links[destNodeKey] && !isEmpty(links[destNodeKey]?.links)) { - const link = Object.entries(links[destNodeKey].links).find( - ([key]) => - key === linkKey && destNodeKey !== actualNodeName - ); - if (link) { - dest = { [destNodeKey]: link[1] }; + + try { + // for every node check all links + for (const actualNodeName in links) { + if ( + isEmpty(links[actualNodeName]) || + typeof links[actualNodeName].links !== "object" // todo(kon): this is an error from the backend + ) + continue; + const srcLoc = links[actualNodeName].src_loc; + for (const [linkKey, linkData] of Object.entries( + links[actualNodeName].links + )) { + // Find destination link info from shared state + let dest: IBaseLink = {}; + for (const destNodeKey in links) { + // Prevent empty objects crashing from shared state + if ( + links[destNodeKey] && + !isEmpty(links[destNodeKey]?.links) + ) { + const link = Object.entries( + links[destNodeKey].links + ).find( + ([key]) => + key === linkKey && + destNodeKey !== actualNodeName + ); + if (link) { + dest = { [destNodeKey]: link[1] }; + } } } - } - let destLoc = linkData?.dst_loc; - // If destination coords are undefined, try to find it on other ways. - if (!destLoc) { - if (dest && links[Object.keys(dest)[0]].src_loc) { - // If we have destination link info, try to find the src_loc - destLoc = links[Object.keys(dest)[0]].src_loc; - } else { - // Find the destination MAC between existing located nodes to get the position - const dstNode = Object.values(nodes).find((node) => { - return node.macs.find((mac) => { - return ( - mac.toLowerCase() === - linkData.dst_mac.toLowerCase() - ); + let destLoc = linkData?.dst_loc; + // If destination coords are undefined, try to find it on other ways. + if (!destLoc) { + if (dest && links[Object.keys(dest)[0]].src_loc) { + // If we have destination link info, try to find the src_loc + destLoc = links[Object.keys(dest)[0]].src_loc; + } else { + // Find the destination MAC between existing located nodes to get the position + const dstNode = Object.values(nodes).find((node) => { + return node.macs.find((mac) => { + return ( + mac.toLowerCase() === + linkData?.dst_mac?.toLowerCase() + ); + }); }); - }); - if (dstNode) { - destLoc = dstNode.coordinates; + if (dstNode) { + destLoc = dstNode.coordinates; + } } } - } - // What happen if the destination link or location is undefined? - // Maybe drawing somehow to the map and show the user that the link is not complete - // For the moment lets ignore the link - if (!destLoc) { - continue; - } + // What happen if the destination link or location is undefined? + // Maybe drawing somehow to the map and show the user that the link is not complete + // For the moment lets ignore the link + if (!destLoc) { + continue; + } - // Get Geolink key to check if is already added - const geoLinkKey = PontToPointLink.generateId(srcLoc, destLoc); + // Get Geolink key to check if is already added + const geoLinkKey = PontToPointLink.generateId(srcLoc, destLoc); - // If the link PontToPointLink already exists and the link is already added, ignore it - if (result[geoLinkKey] && result[geoLinkKey].linkExists(linkKey)) { - continue; - } + // If the link PontToPointLink already exists and the link is already added, ignore it + if ( + result[geoLinkKey] && + result[geoLinkKey].linkExists(linkKey) + ) { + continue; + } - // Instantiate new point to point link on the results array - if (!result[geoLinkKey]) { - result[geoLinkKey] = new PontToPointLink(srcLoc, destLoc); - } + // Instantiate new point to point link on the results array + if (!result[geoLinkKey]) { + result[geoLinkKey] = new PontToPointLink(srcLoc, destLoc); + } - // Add node names to the link data - result[geoLinkKey].addNodes([ - actualNodeName, - ...Object.keys(dest ?? ""), // If destination node is down, ignore node name - ]); + // Add node names to the link data + result[geoLinkKey].addNodes([ + actualNodeName, + ...Object.keys(dest ?? ""), // If destination node is down, ignore node name + ]); - const entry = { - [actualNodeName]: { - ...linkData, - }, - ...dest, - } as IBaseLink; + const entry = { + [actualNodeName]: { + ...linkData, + }, + ...dest, + } as IBaseLink; - result[geoLinkKey].addLink(new MacToMacLink(linkKey, entry, type)); + result[geoLinkKey].addLink( + new MacToMacLink(linkKey, entry, type) + ); + } } + } catch (e) { + console.error("Error merging links and coordinates", e); } return result; From 0b1c0bcc57d70e83d5f726c3331f097930dc441f Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 5 Sep 2024 17:03:35 +0200 Subject: [PATCH 4/7] chore(mesh-wide): fix links inside links --- plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx index ee78fc0a..5558ea38 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx @@ -168,12 +168,14 @@ export const useSetLinkReferenceState = ({ mutationFn: ({ ip }) => { const hostname = nodesToUpdate[ip]; - let newReferenceLinks = (referenceData[hostname] ?? + let newReferenceLinks = (referenceData[hostname].links ?? {}) as IBaseLink; // This is a hotfix because backend returns an empty array sometimes if (isEmpty(newReferenceLinks)) newReferenceLinks = {}; + console.log("PREEE ", newReferenceLinks); + for (const mactomac of linkToUpdate.links) { if (isDown) { delete newReferenceLinks[mactomac.id]; From 0577b31e4ec8e79abf1d078d753b1a8ee38afec0 Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 5 Sep 2024 17:10:13 +0200 Subject: [PATCH 5/7] chore(mesh-wide): prevent deleted node on reference --- .../src/lib/links/getLinksCoordinates.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts index 8218f269..077548a1 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts @@ -56,7 +56,11 @@ export const mergeLinksAndCoordinates = ( let destLoc = linkData?.dst_loc; // If destination coords are undefined, try to find it on other ways. if (!destLoc) { - if (dest && links[Object.keys(dest)[0]].src_loc) { + if ( + dest && + !isEmpty(dest) && + links[Object.keys(dest)[0]]?.src_loc + ) { // If we have destination link info, try to find the src_loc destLoc = links[Object.keys(dest)[0]].src_loc; } else { From afdf3470ec4e3309b77f76ea659874975330afbb Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 12 Sep 2024 16:31:43 +0200 Subject: [PATCH 6/7] chore(mesh-wide): fix new link is down --- .../src/components/FeatureDetail/LinkDetail.tsx | 5 ++++- plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx index ee140fe6..4ae5478c 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -280,6 +280,7 @@ export const LinkReferenceStatus = ({ linkType: linkToShow.type, linkToUpdate: linkToShow, isDown, + isNewLink, nodesToUpdate, }); @@ -309,7 +310,9 @@ export const LinkReferenceStatus = ({
{dataTypeNameMapping(linkToShow.type)}
); - if (isDown) { + // If is down and not a new link. + // Could happen that one of the links is not on the state yet and the other is not + if (isDown && !isNewLink) { btnText = ( Delete this {dataTypeNameMapping(linkToShow.type)} diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx index 5558ea38..f3bd9713 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx @@ -150,12 +150,14 @@ interface IUseSetLinkReferenceState { nodesToUpdate: { [ip: string]: string }; // { ip: hostname } params?: any; isDown: boolean; + isNewLink: boolean; } export const useSetLinkReferenceState = ({ linkType, linkToUpdate, isDown, + isNewLink, nodesToUpdate, params, }: IUseSetLinkReferenceState) => { @@ -174,10 +176,8 @@ export const useSetLinkReferenceState = ({ // This is a hotfix because backend returns an empty array sometimes if (isEmpty(newReferenceLinks)) newReferenceLinks = {}; - console.log("PREEE ", newReferenceLinks); - for (const mactomac of linkToUpdate.links) { - if (isDown) { + if (isDown && newReferenceLinks[mactomac.id] && !isNewLink) { delete newReferenceLinks[mactomac.id]; continue; } From 8cf89e1296f6f275838be0220c8ffaefc88ad427 Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 13 Sep 2024 15:39:06 +0200 Subject: [PATCH 7/7] chore(mesh-wide): prevent FIXME coords --- .../src/lib/links/getLinksCoordinates.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts index 077548a1..5338aa46 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts @@ -2,6 +2,7 @@ import { MacToMacLink, PontToPointLink, } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; +import { isValidCoordinate } from "plugins/lime-plugin-mesh-wide/src/lib/utils"; import { IBaseLink, ILinks, @@ -26,9 +27,15 @@ export const mergeLinksAndCoordinates = ( if ( isEmpty(links[actualNodeName]) || typeof links[actualNodeName].links !== "object" // todo(kon): this is an error from the backend - ) + ) { continue; + } const srcLoc = links[actualNodeName].src_loc; + // If the source location is not valid (FIXME coords), continue + if (!isValidCoordinate(srcLoc.lat, srcLoc.long)) { + continue; + } + for (const [linkKey, linkData] of Object.entries( links[actualNodeName].links )) { @@ -82,7 +89,10 @@ export const mergeLinksAndCoordinates = ( // What happen if the destination link or location is undefined? // Maybe drawing somehow to the map and show the user that the link is not complete // For the moment lets ignore the link - if (!destLoc) { + if ( + !destLoc || + (destLoc && !isValidCoordinate(destLoc.lat, destLoc.long)) // FIXME coords + ) { continue; }