From 437f67407aece6f7aed8e989638b0d64075f0c0a Mon Sep 17 00:00:00 2001 From: Aijana Schumann Date: Wed, 4 Aug 2021 11:59:18 +0200 Subject: Update ODLUX Add various updates and bugfixes to NetworkMap, Configuration, LinkCalculation and ConnectApp Issue-ID: CCSDK-3414 Signed-off-by: Aijana Schumann Change-Id: I6ea5c3a9d6ccbe9c450da43220654a53fd2f262b Signed-off-by: Aijana Schumann --- .../configurationApp/src/services/restServices.ts | 123 ++++++++++++++------- 1 file changed, 86 insertions(+), 37 deletions(-) (limited to 'sdnr/wt/odlux/apps/configurationApp/src/services/restServices.ts') diff --git a/sdnr/wt/odlux/apps/configurationApp/src/services/restServices.ts b/sdnr/wt/odlux/apps/configurationApp/src/services/restServices.ts index bdef64cf2..02060ef12 100644 --- a/sdnr/wt/odlux/apps/configurationApp/src/services/restServices.ts +++ b/sdnr/wt/odlux/apps/configurationApp/src/services/restServices.ts @@ -21,52 +21,101 @@ import { convertPropertyNames, replaceHyphen } from "../../../../framework/src/u import { NetworkElementConnection } from "../models/networkElementConnection"; +type ImportOnlyResponse = { + "ietf-yang-library:yang-library": { + "module-set": { + "import-only-module": { + "name": string, + "revision": string, + }[], + }[], + }, +} + + type CapabilityResponse = { - "network-topology:node": { - "node-id": string, - "netconf-node-topology:available-capabilities": { - "available-capability": { - "capability-origin": string, - "capability": string, - }[] - }, - "netconf-node-topology:unavailable-capabilities": { - "unavailable-capability": { - "capability": string, - "failure-reason": string, - }[] - } - }[] + "network-topology:node": { + "node-id": string, + "netconf-node-topology:available-capabilities": { + "available-capability": { + "capability-origin": string, + "capability": string, + }[] + }, + "netconf-node-topology:unavailable-capabilities": { + "unavailable-capability": { + "capability": string, + "failure-reason": string, + }[] + } + }[] } -type CapabilityAnswer = { - avaliableCapabilities: { - capabilityOrigin: string, - capability: string - }[] | null , - unavaliableCapabilities: { - failureReason: string, - capability: string - }[] | null , +type CapabilityAnswer = { + availableCapabilities: { + capabilityOrigin: string, + capability: string, + version: string, + }[] | null, + unavailableCapabilities: { + failureReason: string, + capability: string, + version: string, + }[] | null, + importOnlyModules: { + name: string, + revision: string, + }[] | null } +const capParser = /^\(.*\?revision=(\d{4}-\d{2}-\d{2})\)(\S+)$/i; + class RestService { public getNetworkElementUri = (nodeId: string) => '/rests/data/network-topology:network-topology/topology=topology-netconf/node=' + nodeId; - public async getCapabilitiesByMoutId(nodeId: string): Promise { + public async getImportOnlyModules(nodeId: string): Promise<{ name: string, revision: string }[]> { + const path = `${this.getNetworkElementUri(nodeId)}/yang-ext:mount/ietf-yang-library:yang-library?content=nonconfig&fields=module-set(import-only-module(name;revision))`; + const importOnlyResult = await requestRest(path, { method: "GET" }); + const importOnlyModules = importOnlyResult + ? importOnlyResult["ietf-yang-library:yang-library"]["module-set"][0]["import-only-module"] + : []; + return importOnlyModules; + } + + public async getCapabilitiesByMountId(nodeId: string): Promise { const path = this.getNetworkElementUri(nodeId); const capabilitiesResult = await requestRest(path, { method: "GET" }); - const avaliableCapabilities = capabilitiesResult && capabilitiesResult["network-topology:node"] && capabilitiesResult["network-topology:node"].length > 0 && - capabilitiesResult["network-topology:node"][0]["netconf-node-topology:available-capabilities"] && - capabilitiesResult["network-topology:node"][0]["netconf-node-topology:available-capabilities"]["available-capability"] && - capabilitiesResult["network-topology:node"][0]["netconf-node-topology:available-capabilities"]["available-capability"].map(obj => convertPropertyNames(obj, replaceHyphen)) || []; - - const unavaliableCapabilities = capabilitiesResult && capabilitiesResult["network-topology:node"] && capabilitiesResult["network-topology:node"].length > 0 && - capabilitiesResult["network-topology:node"][0]["netconf-node-topology:unavailable-capabilities"] && - capabilitiesResult["network-topology:node"][0]["netconf-node-topology:unavailable-capabilities"]["unavailable-capability"] && - capabilitiesResult["network-topology:node"][0]["netconf-node-topology:unavailable-capabilities"]["unavailable-capability"].map(obj => convertPropertyNames(obj, replaceHyphen)) || [] - - return { avaliableCapabilities, unavaliableCapabilities }; + const availableCapabilities = capabilitiesResult && capabilitiesResult["network-topology:node"] && capabilitiesResult["network-topology:node"].length > 0 && + (capabilitiesResult["network-topology:node"][0]["netconf-node-topology:available-capabilities"] && + capabilitiesResult["network-topology:node"][0]["netconf-node-topology:available-capabilities"]["available-capability"] && + capabilitiesResult["network-topology:node"][0]["netconf-node-topology:available-capabilities"]["available-capability"].map(obj => convertPropertyNames(obj, replaceHyphen)) || []) + .map(cap => { + const capMatch = cap && capParser.exec(cap.capability); + return capMatch ? { + capabilityOrigin: cap.capabilityOrigin, + capability: capMatch && capMatch[2] || '', + version: capMatch && capMatch[1] || '', + } : null ; + }).filter((cap) => cap != null) || [] as any; + + const unavailableCapabilities = capabilitiesResult && capabilitiesResult["network-topology:node"] && capabilitiesResult["network-topology:node"].length > 0 && + (capabilitiesResult["network-topology:node"][0]["netconf-node-topology:unavailable-capabilities"] && + capabilitiesResult["network-topology:node"][0]["netconf-node-topology:unavailable-capabilities"]["unavailable-capability"] && + capabilitiesResult["network-topology:node"][0]["netconf-node-topology:unavailable-capabilities"]["unavailable-capability"].map(obj => convertPropertyNames(obj, replaceHyphen)) || []) + .map(cap => { + const capMatch = cap && capParser.exec(cap.capability); + return capMatch ? { + failureReason: cap.failureReason, + capability: capMatch && capMatch[2] || '', + version: capMatch && capMatch[1] || '', + } : null ; + }).filter((cap) => cap != null) || [] as any; + + const importOnlyModules = availableCapabilities && availableCapabilities.findIndex((ac: {capability: string }) => ac.capability && ac.capability.toLowerCase() === "ietf-yang-library") > -1 + ? await this.getImportOnlyModules(nodeId) + : null; + + return { availableCapabilities, unavailableCapabilities, importOnlyModules }; } public async getMountedNetworkElementByMountId(nodeId: string): Promise { @@ -80,7 +129,7 @@ class RestService { return networkElementResult && networkElementResult["data-provider:output"] && networkElementResult["data-provider:output"].data && networkElementResult["data-provider:output"].data.map(obj => convertPropertyNames(obj, replaceHyphen))[0] || null; } - + /** Reads the config data by restconf path. * @param path The restconf path to be used for read. * @returns The data. -- cgit 1.2.3-korg