aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Dürre <michael.duerre@highstreet-technologies.com>2025-03-03 16:53:52 +0100
committerMichael Dürre <michael.duerre@highstreet-technologies.com>2025-03-03 16:54:04 +0100
commit0fc9b3ec08ccf9137eddf1490a6a1f2a3a069de3 (patch)
tree3956ddab2a6b31e939de374c6c522cd1ac360950
parent025618795be67e37ccdfef9c6d179d70cdffeaca (diff)
fix odlux config appHEADmaster
fixed augment resolving order Issue-ID: CCSDK-4094 Change-Id: I03d17f7a76266370df2201b2667a2e10b8fa93dd Signed-off-by: Michael Dürre <michael.duerre@highstreet-technologies.com>
-rw-r--r--sdnr/wt-odlux/odlux/apps/configurationApp/src/models/uiModels.ts3
-rw-r--r--sdnr/wt-odlux/odlux/apps/configurationApp/src/views/configurationApplication.tsx1
-rw-r--r--sdnr/wt-odlux/odlux/apps/configurationApp/src/yang/yangParser.ts223
-rw-r--r--sdnr/wt-odlux/odlux/framework/pom.xml2
-rw-r--r--sdnr/wt-odlux/odlux/framework/src2/main/resources/version.json4
-rw-r--r--sdnr/wt-odlux/odlux/odlux.properties6
6 files changed, 168 insertions, 71 deletions
diff --git a/sdnr/wt-odlux/odlux/apps/configurationApp/src/models/uiModels.ts b/sdnr/wt-odlux/odlux/apps/configurationApp/src/models/uiModels.ts
index c839f1c91..c9f5e8041 100644
--- a/sdnr/wt-odlux/odlux/apps/configurationApp/src/models/uiModels.ts
+++ b/sdnr/wt-odlux/odlux/apps/configurationApp/src/models/uiModels.ts
@@ -209,7 +209,7 @@ export const isViewElementEmpty = (viewElement: ViewElement): viewElement is Vie
return viewElement && viewElement.uiType === 'empty';
};
-export const ResolveFunction = Symbol('IsResolved');
+export const ResolveFunction = Symbol('ResolveFunction');
export type ViewSpecification = {
id: string;
@@ -219,6 +219,7 @@ export type ViewSpecification = {
parentView?: string;
language: string;
ifFeature?: string;
+ augmentations?: string[];
when?: WhenAST;
uses?: (string[]) & { [ResolveFunction]?: (parent: string) => void };
elements: { [name: string]: ViewElement };
diff --git a/sdnr/wt-odlux/odlux/apps/configurationApp/src/views/configurationApplication.tsx b/sdnr/wt-odlux/odlux/apps/configurationApp/src/views/configurationApplication.tsx
index c8a518b9c..6280950e4 100644
--- a/sdnr/wt-odlux/odlux/apps/configurationApp/src/views/configurationApplication.tsx
+++ b/sdnr/wt-odlux/odlux/apps/configurationApp/src/views/configurationApplication.tsx
@@ -939,7 +939,6 @@ class ConfigurationApplicationComponent extends React.Component<ConfigurationApp
}
render() {
- console.log('ConfigurationApplication.render()', this.props);
return this.props.collectingData || !this.state.viewData
? this.renderCollectingData()
: this.props.listSpecification
diff --git a/sdnr/wt-odlux/odlux/apps/configurationApp/src/yang/yangParser.ts b/sdnr/wt-odlux/odlux/apps/configurationApp/src/yang/yangParser.ts
index 10f12ddf6..ec242dbdf 100644
--- a/sdnr/wt-odlux/odlux/apps/configurationApp/src/yang/yangParser.ts
+++ b/sdnr/wt-odlux/odlux/apps/configurationApp/src/yang/yangParser.ts
@@ -490,6 +490,34 @@ export class YangParser {
return module;
}
+ private calculateExecutionOrder(moduleName: string, visited: Set<string> = new Set()): number {
+ if (visited.has(moduleName)) {
+ return 0;
+ }
+ visited.add(moduleName);
+
+ const module = this.modules[moduleName];
+ const augments = module?.augments || {};
+ const augmentPaths = Object.keys(augments);
+
+ if (augmentPaths.length === 0) {
+ module.executionOrder = 0;
+ return 0;
+ }
+
+ const orders = augmentPaths.map((path) => {
+ const pathParts = path.split('/');
+ const lastPart = pathParts[pathParts.length - 1];
+ const [ns] = lastPart.split(':');
+ const baseModuleOrder = this.calculateExecutionOrder(ns, visited);
+ return baseModuleOrder + 1;
+ });
+
+ const maxOrder = Math.max(...orders);
+ module.executionOrder = maxOrder;
+ return maxOrder;
+ }
+
public postProcess() {
// process all type refs
this._typeRefToResolve.forEach(cb => {
@@ -497,26 +525,28 @@ export class YangParser {
console.warn(error.message);
}
});
- /**
- * This is to fix the issue for sequential execution of modules based on their child and parent relationship
- * We are sorting the module object based on their augment status
- */
- Object.keys(this.modules)
- .map(elem => {
- if (this.modules[elem].augments && Object.keys(this.modules[elem].augments).length > 0) {
- const { augments, ..._rest } = this.modules[elem];
- const partsOfKeys = Object.keys(augments).map((key) => (key.split('/').length - 1));
- this.modules[elem].executionOrder = Math.max(...partsOfKeys);
- } else {
- this.modules[elem].executionOrder = 0;
- }
- });
- // process all augmentations / sort by namespace changes to ensure proper order
- Object.keys(this.modules).sort((a, b) => this.modules[a].executionOrder! - this.modules[b].executionOrder!).forEach(modKey => {
- const module = this.modules[modKey];
+ // process all groupings
+ this._groupingsToResolve.filter(vs => vs.uses && vs.uses[ResolveFunction]).forEach(vs => {
+ try { vs.uses![ResolveFunction] !== undefined && vs.uses![ResolveFunction]!('|'); } catch (error) {
+ console.warn(`Error resolving: [${vs.name}] [${error.message}]`);
+ }
+ });
+
+ // process all augmentations
+ Object.keys(this.modules).forEach((moduleName) => {
+ this.calculateExecutionOrder(moduleName);
+ });
+
+ const orderedModules = Object.values(this.modules)
+ .filter((m) => m.executionOrder)
+ .sort((a, b) => {
+ return a.executionOrder! - b.executionOrder!;
+ });
+
+ orderedModules.forEach((module) => {
const augmentKeysWithCounter = Object.keys(module.augments).map((key) => {
- const pathParts = splitVPath(key, /(?:(?:([^\/\:]+):)?([^\/]+))/g); // 1 = opt: namespace / 2 = property
+ const pathParts = splitVPath(key, /(?:(?:([^\/\:]+):)?([^\/]+))/g); // 1 = opt: namespace / 2 = property
let nameSpaceChangeCounter = 0;
let currentNS = module.name; // init namespace
pathParts.forEach(([ns, _]) => {
@@ -531,40 +561,96 @@ export class YangParser {
};
});
- const augmentKeys = augmentKeysWithCounter
- .sort((a, b) => a.nameSpaceChangeCounter > b.nameSpaceChangeCounter ? 1 : a.nameSpaceChangeCounter === b.nameSpaceChangeCounter ? 0 : -1)
- .map((a) => a.key);
-
- augmentKeys.forEach(augKey => {
- const augments = module.augments[augKey];
- const viewSpec = this.resolveView(augKey);
- if (!viewSpec) console.warn(`Could not find view to augment [${augKey}] in [${module.name}].`);
- if (augments && viewSpec) {
- augments.forEach(augment => Object.keys(augment.elements).forEach(key => {
- const elm = augment.elements[key];
-
- const when = elm.when && augment.when
- ? {
- type: WhenTokenType.AND,
- left: elm.when,
- right: augment.when,
- }
- : elm.when || augment.when;
-
- const ifFeature = elm.ifFeature
- ? `(${augment.ifFeature}) and (${elm.ifFeature})`
- : augment.ifFeature;
-
- viewSpec.elements[key] = {
- ...augment.elements[key],
- when,
- ifFeature,
- };
- }));
+ const augmentKeys = augmentKeysWithCounter.sort((a, b) => (a.nameSpaceChangeCounter > b.nameSpaceChangeCounter ? 1 : a.nameSpaceChangeCounter === b.nameSpaceChangeCounter ? 0 : -1)).map((a) => a.key);
+
+ augmentKeys.forEach((augKey) => {
+ const viewToAugment = this.resolveView(augKey);
+ const augmentations = module.augments[augKey];
+
+ if (!viewToAugment) {
+ console.warn(`Could not find view to augment [${augKey}] from [${module.name}].`);
+ return;
+ }
+
+ if (augmentations && viewToAugment) {
+ augmentations.forEach(({ id }) => {
+ viewToAugment.augmentations = viewToAugment.augmentations || [];
+ viewToAugment.augmentations.push(id);
+ });
}
});
});
+ // build a map of views with all their augmentation level
+ const viewsWithNestedAugmentations = new Map<ViewSpecification, number>();
+
+ // helper function to get maximum augmentation depth
+ const calculateAugmentationDepth = (view: ViewSpecification): number => {
+ // Return cached value if already calculated
+ if (viewsWithNestedAugmentations.has(view)) {
+ return viewsWithNestedAugmentations.get(view)!;
+ }
+
+ // Base case: no augmentations
+ if (!view.augmentations || view.augmentations.length === 0) {
+ viewsWithNestedAugmentations.set(view, 0);
+ return 0;
+ }
+
+ // Get depths of all child augmentations
+ let maxDepth = 0;
+ for (const augId of view.augmentations) {
+ const augView = this.views[+augId];
+ for (const nestedAugId in augView.elements || {}) {
+ const nestedAug = augView.elements[nestedAugId];
+ if (isViewElementObjectOrList(nestedAug)) {
+ const nestedView = this.views[+nestedAug.viewId];
+ maxDepth = nestedView ? Math.max(maxDepth, calculateAugmentationDepth(nestedView)) : maxDepth;
+ }
+ }
+ }
+
+ // Add 1 for current level and cache result
+ const totalDepth = maxDepth + 1;
+ viewsWithNestedAugmentations.set(view, totalDepth);
+ return totalDepth;
+ };
+
+ // process views from lowest to highest augmentation depth
+ const viewEntries = Object.entries(this.views.filter((v) => v.augmentations && v.augmentations.length > 0))
+ .map(([, view]) => view)
+ .sort((a, b) => calculateAugmentationDepth(a) - calculateAugmentationDepth(b));
+
+ for (const view of viewEntries) {
+ if (!view.augmentations || view.augmentations.length === 0) continue;
+
+ for (const augId of view.augmentations) {
+ const augmentation = this.views[+augId];
+
+ // merge elements from augmentation into main view
+ Object.keys(augmentation.elements).forEach((key) => {
+ const elm = augmentation.elements[key];
+
+ const when =
+ elm.when && augmentation.when
+ ? {
+ type: WhenTokenType.AND,
+ left: elm.when,
+ right: augmentation.when,
+ }
+ : elm.when || augmentation.when;
+
+ const ifFeature = elm.ifFeature ? `(${augmentation.ifFeature}) and (${elm.ifFeature})` : augmentation.ifFeature;
+
+ view.elements[key] = {
+ ...augmentation.elements[key],
+ when,
+ ifFeature,
+ };
+ });
+ }
+ }
+
// process Identities
const traverseIdentity = (identities: Identity[]) => {
const result: Identity[] = [];
@@ -614,13 +700,6 @@ export class YangParser {
}
});
- // process all groupings
- this._groupingsToResolve.filter(vs => vs.uses && vs.uses[ResolveFunction]).forEach(vs => {
- try { vs.uses![ResolveFunction] !== undefined && vs.uses![ResolveFunction]!('|'); } catch (error) {
- console.warn(`Error resolving: [${vs.name}] [${error.message}]`);
- }
- });
-
const knownViews: ViewSpecification[] = [];
// resolve readOnly
const resolveReadOnly = (view: ViewSpecification, parentConfig: boolean) => {
@@ -1561,6 +1640,29 @@ export class YangParser {
return [element, resultPathParts.slice(0, -1).map(p => `${moduleName !== p.ns ? `${moduleName = p.ns}:` : ''}${p.property}${p.ind || ''}`).join('/')];
}
+
+ private resolveViewElement(name: string, referenceView: ViewSpecification): ViewElement | null {
+ let element: ViewElement | null = null;
+ element = referenceView.elements[name];
+
+ if (element) {
+ return element;
+ }
+
+ const augmentViewIds = referenceView.augmentations;
+ if (augmentViewIds) {
+ for (let i = 0; i < augmentViewIds.length; ++i) {
+ const augmentView = this._views[+augmentViewIds[i]];
+ if (augmentView) {
+ element = this.resolveViewElement(name, augmentView);
+ if (element) break;
+ }
+ }
+ }
+ return element;
+ }
+
+
private resolveView(vPath: string) {
const vPathParser = /(?:(?:([^\/\[\]\:]+):)?([^\/\[\]]+)(\[[^\]]+\])?)/g; // 1 = opt: namespace / 2 = property / 3 = opt: indexPath
let element: ViewElement | null = null;
@@ -1572,16 +1674,17 @@ export class YangParser {
if (partMatch) {
if (element === null) {
moduleName = partMatch[1]!;
- const rootModule = this._modules[moduleName];
- if (!rootModule) return null;
- element = rootModule.elements[`${moduleName}:${partMatch[2]!}`];
+ view = Object.values(this.views).find((v) => v.parentView === '0' && v.ns === moduleName) || null;
+ if (view) {
+ element = this.resolveViewElement(`${moduleName}:${partMatch[2]!}`, view);
+ }
} else if (isViewElementObjectOrList(element)) {
view = this._views[+element.viewId];
if (moduleName !== partMatch[1]) {
moduleName = partMatch[1];
- element = view.elements[`${moduleName}:${partMatch[2]}`];
+ element = this.resolveViewElement(`${moduleName}:${partMatch[2]}`, view);
} else {
- element = view.elements[partMatch[2]];
+ element = this.resolveViewElement(partMatch[2], view);
}
} else {
return null;
diff --git a/sdnr/wt-odlux/odlux/framework/pom.xml b/sdnr/wt-odlux/odlux/framework/pom.xml
index bffbc04a7..eaba5d4e9 100644
--- a/sdnr/wt-odlux/odlux/framework/pom.xml
+++ b/sdnr/wt-odlux/odlux/framework/pom.xml
@@ -39,7 +39,7 @@
<properties>
<buildtime>${maven.build.timestamp}</buildtime>
<distversion>ONAP Frankfurt (Neon, mdsal ${odl.mdsal.version})</distversion>
- <buildno>172.b89e2c2b(23/10/04)</buildno>
+ <buildno>179.f46d0ef0(25/03/03)</buildno>
<odlux.version>ONAP SDN-R | ONF Wireless for ${distversion} - Build: ${buildtime} ${buildno} ${project.version}</odlux.version>
</properties>
diff --git a/sdnr/wt-odlux/odlux/framework/src2/main/resources/version.json b/sdnr/wt-odlux/odlux/framework/src2/main/resources/version.json
index 1d9af9029..91bd11cd1 100644
--- a/sdnr/wt-odlux/odlux/framework/src2/main/resources/version.json
+++ b/sdnr/wt-odlux/odlux/framework/src2/main/resources/version.json
@@ -9,11 +9,9 @@
"faultApp":"##odlux.apps.faultApp.buildno##",
"helpApp":"##odlux.apps.helpApp.buildno##",
"inventoryApp":"##odlux.apps.inventoryApp.buildno##",
- "linkCalculationApp":"##odlux.apps.linkCalculationApp.buildno##",
"maintenanceApp":"##odlux.apps.maintenanceApp.buildno##",
"mediatorApp":"##odlux.apps.mediatorApp.buildno##",
- "networkMapApp":"##odlux.apps.networkMapApp.buildno##",
"permanceHistoryApp":"##odlux.apps.permanceHistoryApp.buildno##"
-
+
}
} \ No newline at end of file
diff --git a/sdnr/wt-odlux/odlux/odlux.properties b/sdnr/wt-odlux/odlux/odlux.properties
index c4424acc2..05f314600 100644
--- a/sdnr/wt-odlux/odlux/odlux.properties
+++ b/sdnr/wt-odlux/odlux/odlux.properties
@@ -1,14 +1,10 @@
odlux.framework.buildno=172.b89e2c2b(23/10/04)
-odlux.apps.configurationApp.buildno=172.b89e2c2b(23/10/04)
+odlux.apps.configurationApp.buildno=179.f46d0ef0(25/03/03)
odlux.apps.connectApp.buildno=172.b89e2c2b(23/10/04)
odlux.apps.eventLogApp.buildno=172.b89e2c2b(23/10/04)
odlux.apps.faultApp.buildno=172.b89e2c2b(23/10/04)
odlux.apps.helpApp.buildno=172.b89e2c2b(23/10/04)
odlux.apps.inventoryApp.buildno=172.b89e2c2b(23/10/04)
-odlux.apps.linkCalculationApp.buildno=171.5e3c222(22/09/30)
odlux.apps.maintenanceApp.buildno=172.b89e2c2b(23/10/04)
odlux.apps.mediatorApp.buildno=172.b89e2c2b(23/10/04)
-odlux.apps.networkMapApp.buildno=172.b89e2c2b(23/10/04)
-odlux.apps.lineOfSightApp.buildno=168.38fd458(22/09/16)
odlux.apps.permanceHistoryApp.buildno=81.1c38886(20/12/04)
-odlux.apps.siteManagerApp=164.e02f116(22/08/12)