update configure workflow 84/4684/1
authorNicolas Hu <jh245g@att.com>
Fri, 4 Sep 2020 14:11:35 +0000 (10:11 -0400)
committerNicolas Hu <jh245g@att.com>
Fri, 4 Sep 2020 14:13:30 +0000 (10:13 -0400)
Signed-off-by: Jun (Nicolas) Hu <jh245g@att.com>
Issue-ID: OAM-110
Change-Id: I8e905323932167f048758e7efaf483cb504baa20

dashboard/webapp-frontend/src/app/app-configuration/app-configuration.component.html
dashboard/webapp-frontend/src/app/app-configuration/app-configuration.component.scss
dashboard/webapp-frontend/src/app/app-configuration/app-configuration.component.ts
dashboard/webapp-frontend/src/app/app-control/app-control.component.html
dashboard/webapp-frontend/src/app/app-control/app-control.component.ts
dashboard/webapp-frontend/src/app/catalog/catalog.component.html
dashboard/webapp-frontend/src/app/catalog/catalog.component.ts
dashboard/webapp-frontend/src/app/services/app-mgr/app-mgr.service.ts
dashboard/webapp-frontend/src/assets/mockdata/config.json
docs/release-notes.rst

index 755e4e6..4f6061f 100644 (file)
   -->
 
 <div mat-dialog-title *ngIf="loading$ | async">
-  Loading {{data.xapp.name}} Configuration
+  Loading {{data.xapp}} Configuration
   <mat-spinner diameter=70></mat-spinner>
 </div>
 
 <div *ngIf="((loading$ | async)==false) " class="config-div">
 
   <div mat-dialog-title class="config-title">
-    {{data.xapp.name}} Configuration
+    {{data.xapp}} Configuration
   </div>
 
-  <div  class="config-form">
-    <json-schema-form loadExternalAssets="true"
-                      framework="material-design"
-                      [data]="xappConfigData"
-                      [schema]="xappConfigSchema"
-                      [layout]="xappLayout"
-                      (onSubmit)="updateconfig($event)">
-    </json-schema-form>
+  <mat-form-field>
+    <textarea #configTextarea matInput class="config-textarea">{{xappConfig | json}}</textarea>
+  </mat-form-field>
+  <div class="modal-footer justify-content-center">
+    <button mat-button class="mat-raised-button  mat-primary" (click)="updateconfig(configTextarea.value)" >upload</button>
+    <button mat-button class="mat-raised-button" [mat-dialog-close]="false">Cancel</button>
   </div>
 </div>
index d790920..6571967 100644 (file)
@@ -34,15 +34,23 @@ mat-spinner {
   margin-bottom:0px
 }
 
-.config-form {
-  max-height: 400px;
-  overflow-y:scroll;
+.config-textarea {
+  height: 300px;
+  overflow-y: scroll;
 }
 
-.config-form::-webkit-scrollbar {
+.config-textarea::-webkit-scrollbar {
   display: none;
 }
 
 .mat-form-field-wrapper{
   margin-right:10px
+}
+
+.mat-raised-button {
+  margin-right: 5px;
+}
+
+mat-form-field {
+  width: 90%
 }
\ No newline at end of file
index 0e73413..7a943ea 100644 (file)
@@ -27,6 +27,7 @@ import { ErrorDialogService } from '../services/ui/error-dialog.service';
 import { LoadingDialogService } from '../services/ui/loading-dialog.service';
 import { HttpErrorResponse, HttpResponse } from '@angular/common/http';
 import { NotificationService } from '../services/ui/notification.service';
+import { XMXappConfig } from "../interfaces/app-mgr.types"
 
 @Component({
   selector: 'rd-app-configuration',
@@ -47,10 +48,8 @@ export class AppConfigurationComponent implements OnInit {
     @Inject(MAT_DIALOG_DATA) private data
   ) { }
 
-  xappMetadata: any;
-  xappConfigSchema: any;
-  xappConfigData: any;
-  xappLayout: any;
+  xappConfig: XMXappConfig
+
   ngOnInit() {
     this.loadingSubject.next(true);
     this.appMgrService.getConfig(this.data.instanceKey)
@@ -59,20 +58,14 @@ export class AppConfigurationComponent implements OnInit {
       )
       .subscribe(
         (allConfig: any) => {
-          this.loadConfigForm(this.data.xapp.name, allConfig);
+          this.loadConfigForm(this.data.xapp, allConfig);
         }
       );
   }
 
-  updateconfig(event) {
-    const config = {
-      metadata: this.xappMetadata,
-      descriptor: this.xappConfigSchema,
-      config: event,
-      layout: this.xappLayout
-    };
-    this.loadingDialogService.startLoading('Updating ' + this.data.xapp.name + ' configuration');
-    this.appMgrService.putConfig(this.data.instanceKey, config)
+  updateconfig(config: any) {
+    this.loadingDialogService.startLoading('Updating ' + this.data.xapp + ' configuration');
+    this.appMgrService.putConfig(this.data.instanceKey, JSON.parse(config))
       .pipe(
         finalize(() => {
           this.loadingDialogService.stopLoading();
@@ -96,10 +89,7 @@ export class AppConfigurationComponent implements OnInit {
   loadConfigForm(name: string, allConfig: any) {
     const xappConfig = allConfig.find(xapp => xapp.metadata.name === name);
     if (xappConfig != null) {
-      this.xappMetadata = xappConfig.metadata;
-      this.xappConfigSchema = xappConfig.descriptor;
-      this.xappConfigData = xappConfig.config;
-      this.xappLayout = xappConfig.layout;
+      this.xappConfig = xappConfig
     } else {
       this.errorDiaglogService.displayError('Cannot find configration data for ' + name);
       this.dialogRef.close();
index ec802f4..3bf2d7a 100644 (file)
       <mat-header-cell *matHeaderCellDef> Action </mat-header-cell>
       <!-- click on button should not expand/collapse the row -->
       <mat-cell *matCellDef="let element" (click)="$event.stopPropagation()">
-      <button mat-icon-button (click)="controlApp(element)">
+        <button mat-icon-button (click)="onConfigureApp(element)">
           <mat-icon matTooltip="Adjust settings">settings</mat-icon>
         </button>
+<!--        <button mat-icon-button (click)="controlApp(element)">
+          <mat-icon matTooltip="Adjust settings">settings</mat-icon>
+        </button>-->
         <button mat-icon-button (click)="onUndeployApp(element)">
           <mat-icon matTooltip="Undeploy app">cloud_download</mat-icon>
         </button>
index 75044a3..9a5d072 100644 (file)
@@ -19,6 +19,7 @@
  */
 import { HttpErrorResponse, HttpResponse } from '@angular/common/http';
 import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
+import { MatDialog } from '@angular/material/dialog';
 import { MatSort } from '@angular/material/sort';
 import { Router } from '@angular/router';
 import { Subscription } from 'rxjs';
@@ -31,6 +32,8 @@ import { ConfirmDialogService } from '../services/ui/confirm-dialog.service';
 import { ErrorDialogService } from '../services/ui/error-dialog.service';
 import { LoadingDialogService } from '../services/ui/loading-dialog.service';
 import { NotificationService } from '../services/ui/notification.service';
+import { UiService } from '../services/ui/ui.service';
+import { AppConfigurationComponent } from './../app-configuration/app-configuration.component';
 import { AppControlAnimations } from './app-control.animations';
 import { AppControlDataSource } from './app-control.datasource';
 
@@ -42,6 +45,8 @@ import { AppControlDataSource } from './app-control.datasource';
 })
 export class AppControlComponent implements OnInit, OnDestroy {
 
+  darkMode: boolean;
+  panelClass: string;
   displayedColumns: string[] = ['xapp', 'name', 'status', 'ip', 'port', 'action'];
   dataSource: AppControlDataSource;
   @ViewChild(MatSort, { static: true }) sort: MatSort;
@@ -51,15 +56,21 @@ export class AppControlComponent implements OnInit, OnDestroy {
   constructor(
     private appMgrSvc: AppMgrService,
     private router: Router,
+    private dialog: MatDialog,
     private confirmDialogService: ConfirmDialogService,
     private errorDialogService: ErrorDialogService,
     private loadingDialogService: LoadingDialogService,
     public instanceSelectorService: InstanceSelectorService,
-    private notificationService: NotificationService) { }
+    private notificationService: NotificationService,
+    public ui: UiService
+    ) { }
 
 
   ngOnInit() {
     this.dataSource = new AppControlDataSource(this.appMgrSvc, this.sort, this.notificationService);
+    this.ui.darkModeState.subscribe((isDark) => {
+      this.darkMode = isDark;
+    });
     this.instanceChange = this.instanceSelectorService.getSelectedInstance().subscribe((instance: RicInstance) => {
       if (instance.key) {
         this.instanceKey = instance.key;
@@ -77,6 +88,27 @@ export class AppControlComponent implements OnInit, OnDestroy {
     this.errorDialogService.displayError('No control available for ' + app.xapp + ' (yet)');
   }
 
+  onConfigureApp(xappRow: XappControlRow): void {
+    if (this.darkMode) {
+      this.panelClass = 'dark-theme';
+    } else {
+      this.panelClass = '';
+    }
+    const dialogRef = this.dialog.open(AppConfigurationComponent, {
+      panelClass: this.panelClass,
+      width: '80%',
+      maxHeight: '70%',
+      position: {
+        top: '10%'
+      },
+      data: {
+        xapp: xappRow.xapp,
+        instanceKey: this.instanceKey
+      }
+
+    });
+  }
+
   onUndeployApp(app: XappControlRow): void {
     this.confirmDialogService.openConfirmDialog('Are you sure you want to undeploy App ' + app.xapp + '?')
       .afterClosed().subscribe((res: boolean) => {
index b54d5db..9982e48 100644 (file)
@@ -38,9 +38,6 @@
         <mat-header-cell *matHeaderCellDef> Action </mat-header-cell>
         <mat-cell *matCellDef="let element">
           <div class="catalog-button-row">
-            <button mat-icon-button (click)="onConfigureApp(element)">
-              <mat-icon matTooltip="Adjust settings">settings</mat-icon>
-            </button>
             <button mat-icon-button (click)="onDeployApp(element)">
               <mat-icon matTooltip="Deploy app">cloud_upload</mat-icon>
             </button>
index df43995..bab515a 100644 (file)
@@ -30,7 +30,6 @@ import { LoadingDialogService } from '../services/ui/loading-dialog.service';
 import { NotificationService } from '../services/ui/notification.service';
 import { UiService } from '../services/ui/ui.service';
 import { DeployDialogComponent } from '../ui/deploy-dialog/deploy-dialog.component';
-import { AppConfigurationComponent } from './../app-configuration/app-configuration.component';
 import { OnboardComponent } from './../onboard/onboard.component';
 import { CatalogDataSource } from './catalog.datasource';
 
@@ -52,9 +51,7 @@ export class CatalogComponent implements OnInit, OnDestroy {
 
   constructor(
     private appMgrService: AppMgrService,
-    private confirmDialogService: ConfirmDialogService,
     private dialog: MatDialog,
-    private loadingDialogService: LoadingDialogService,
     private notificationService: NotificationService,
     public instanceSelectorService: InstanceSelectorService,
     public ui: UiService) { }
@@ -77,27 +74,6 @@ export class CatalogComponent implements OnInit, OnDestroy {
     this.instanceChange.unsubscribe();
   }
 
-  onConfigureApp(xapp: XMXapp): void {
-    if (this.darkMode) {
-      this.panelClass = 'dark-theme';
-    } else {
-      this.panelClass = '';
-    }
-    const dialogRef = this.dialog.open(AppConfigurationComponent, {
-      panelClass: this.panelClass,
-      width: '40%',
-      maxHeight: '500px',
-      position: {
-        top: '10%'
-      },
-      data: {
-        xapp: xapp,
-        instanceKey: this.instanceKey
-      }
-
-    });
-  }
-
   onDeployApp(app: XMXapp): void {
     if (this.darkMode) {
       this.panelClass = 'dark-theme';
index bddf690..e280e7f 100644 (file)
@@ -57,10 +57,10 @@ export class AppMgrService {
 
   getConfig(instanceKey: string): Observable<XMAllXappConfig> {
     // For demo purpose, pull example config from local
-    return this.httpClient.get<XMAllXappConfig>('/assets/mockdata/config.json');
+    //return this.httpClient.get<XMAllXappConfig>('/assets/mockdata/config.json');
     // Once Xapp manager contains layout, should call backend to get xapp config
-    // const path = this.dashboardSvc.buildPath(this.component, instanceKey, 'config');
-    // return this.httpClient.get<any[]>(path);
+    const path = this.dashboardSvc.buildPath(this.component, instanceKey, 'config');
+    return this.httpClient.get<any[]>(path);
   }
 
   putConfig(instanceKey: string, config: XMXappConfig): Observable<HttpResponse<Object>> {
index f69aef7..6bd8444 100644 (file)
@@ -5,334 +5,6 @@
       "configName": "UEEC-appconfig",
       "namespace": "ricxapp"
     },
-    "descriptor": {
-      "definitions": {},
-      "$schema": "http://json-schema.org/draft-07/schema#",
-      "$id": "http://example.com/root.json",
-      "type": "object",
-      "title": "The Root Schema",
-      "required": [
-        "local",
-        "logger",
-        "rmr",
-        "db",
-        "controls",
-        "metrics"
-      ],
-      "properties": {
-        "local": {
-          "$id": "#/properties/local",
-          "type": "object",
-          "title": "The Local Schema",
-          "required": [
-            "host"
-          ],
-          "properties": {
-            "host": {
-              "$id": "#/properties/local/properties/host",
-              "type": "string",
-              "title": "The Host Schema",
-              "default": "",
-              "examples": [
-                ":8080"
-              ],
-              "pattern": "^(.*)$"
-            }
-          }
-        },
-        "logger": {
-          "$id": "#/properties/logger",
-          "type": "object",
-          "title": "The Logger Schema",
-          "required": [
-            "level"
-          ],
-          "properties": {
-            "level": {
-              "$id": "#/properties/logger/properties/level",
-              "type": "integer",
-              "title": "The Level Schema",
-              "default": 0,
-              "examples": [
-                3
-              ]
-            }
-          }
-        },
-        "rmr": {
-          "$id": "#/properties/rmr",
-          "type": "object",
-          "title": "The Rmr Schema",
-          "required": [
-            "protPort",
-            "maxSize",
-            "numWorkers",
-            "txMessages",
-            "rxMessages"
-          ],
-          "properties": {
-            "protPort": {
-              "$id": "#/properties/rmr/properties/protPort",
-              "type": "string",
-              "title": "The Protport Schema",
-              "default": "",
-              "examples": [
-                "tcp:4560"
-              ],
-              "pattern": "^(.*)$"
-            },
-            "maxSize": {
-              "$id": "#/properties/rmr/properties/maxSize",
-              "type": "integer",
-              "title": "The Maxsize Schema",
-              "default": 0,
-              "examples": [
-                2072
-              ]
-            },
-            "numWorkers": {
-              "$id": "#/properties/rmr/properties/numWorkers",
-              "type": "integer",
-              "title": "The Numworkers Schema",
-              "default": 0,
-              "examples": [
-                1
-              ]
-            },
-            "txMessages": {
-              "$id": "#/properties/rmr/properties/txMessages",
-              "type": "array",
-              "title": "The Txmessages Schema",
-              "items": {
-                "$id": "#/properties/rmr/properties/txMessages/items",
-                "type": "string",
-                "title": "The Items Schema",
-                "default": "",
-                "examples": [
-                  "RIC_SUB_REQ",
-                  "RIC_SUB_DEL_REQ"
-                ],
-                "pattern": "^(.*)$"
-              }
-            },
-            "rxMessages": {
-              "$id": "#/properties/rmr/properties/rxMessages",
-              "type": "array",
-              "title": "The Rxmessages Schema",
-              "items": {
-                "$id": "#/properties/rmr/properties/rxMessages/items",
-                "type": "string",
-                "title": "The Items Schema",
-                "default": "",
-                "examples": [
-                  "RIC_SUB_RESP",
-                  "RIC_SUB_FAILURE",
-                  "RIC_SUB_DEL_RESP",
-                  "RIC_SUB_DEL_FAILURE",
-                  "RIC_INDICATION"
-                ],
-                "pattern": "^(.*)$"
-              }
-            }
-          }
-        },
-        "db": {
-          "$id": "#/properties/db",
-          "type": "object",
-          "title": "The Db Schema",
-          "required": [
-            "host",
-            "port",
-            "namespaces"
-          ],
-          "properties": {
-            "host": {
-              "$id": "#/properties/db/properties/host",
-              "type": "string",
-              "title": "The Host Schema",
-              "default": "",
-              "examples": [
-                "localhost"
-              ],
-              "pattern": "^(.*)$"
-            },
-            "port": {
-              "$id": "#/properties/db/properties/port",
-              "type": "integer",
-              "title": "The Port Schema",
-              "default": 0,
-              "examples": [
-                6379
-              ]
-            },
-            "namespaces": {
-              "$id": "#/properties/db/properties/namespaces",
-              "type": "array",
-              "title": "The Namespaces Schema",
-              "items": {
-                "$id": "#/properties/db/properties/namespaces/items",
-                "type": "string",
-                "title": "The Items Schema",
-                "default": "",
-                "examples": [
-                  "sdl",
-                  "rnib"
-                ],
-                "pattern": "^(.*)$"
-              }
-            }
-          }
-        },
-        "controls": {
-          "$id": "#/properties/controls",
-          "type": "object",
-          "title": "The Controls Schema",
-          "required": [
-            "active",
-            "requestorId",
-            "ranFunctionId",
-            "ricActionId",
-            "interfaceId"
-          ],
-          "properties": {
-            "active": {
-              "$id": "#/properties/controls/properties/active",
-              "type": "boolean",
-              "title": "The Active Schema",
-              "default": false,
-              "examples": [
-                true
-              ]
-            },
-            "requestorId": {
-              "$id": "#/properties/controls/properties/requestorId",
-              "type": "integer",
-              "title": "The Requestorid Schema",
-              "default": 0,
-              "examples": [
-                66
-              ]
-            },
-            "ranFunctionId": {
-              "$id": "#/properties/controls/properties/ranFunctionId",
-              "type": "integer",
-              "title": "The Ranfunctionid Schema",
-              "default": 0,
-              "examples": [
-                1
-              ]
-            },
-            "ricActionId": {
-              "$id": "#/properties/controls/properties/ricActionId",
-              "type": "integer",
-              "title": "The Ricactionid Schema",
-              "default": 0,
-              "examples": [
-                0
-              ]
-            },
-            "interfaceId": {
-              "$id": "#/properties/controls/properties/interfaceId",
-              "type": "object",
-              "title": "The Interfaceid Schema",
-              "required": [
-                "globalENBId"
-              ],
-              "properties": {
-                "globalENBId": {
-                  "$id": "#/properties/controls/properties/interfaceId/properties/globalENBId",
-                  "type": "object",
-                  "title": "The Globalenbid Schema",
-                  "required": [
-                    "plmnId",
-                    "eNBId"
-                  ],
-                  "properties": {
-                    "plmnId": {
-                      "$id": "#/properties/controls/properties/interfaceId/properties/globalENBId/properties/plmnId",
-                      "type": "string",
-                      "title": "The Plmnid Schema",
-                      "default": "",
-                      "examples": [
-                        "43962"
-                      ],
-                      "pattern": "^(.*)$"
-                    },
-                    "eNBId": {
-                      "$id": "#/properties/controls/properties/interfaceId/properties/globalENBId/properties/eNBId",
-                      "type": "string",
-                      "title": "The Enbid Schema",
-                      "default": "",
-                      "examples": [
-                        "43962"
-                      ],
-                      "pattern": "^(.*)$"
-                    }
-                  }
-                }
-              }
-            }
-          }
-        },
-        "metrics": {
-          "$id": "#/properties/metrics",
-          "type": "array",
-          "title": "The Metrics Schema",
-          "items": {
-            "$id": "#/properties/metrics/items",
-            "type": "object",
-            "title": "The Items Schema",
-            "required": [
-              "name",
-              "type",
-              "enabled",
-              "description"
-            ],
-            "properties": {
-              "name": {
-                "$id": "#/properties/metrics/items/properties/name",
-                "type": "string",
-                "title": "The Name Schema",
-                "default": "",
-                "examples": [
-                  "UEContextCreated"
-                ],
-                "pattern": "^(.*)$"
-              },
-              "type": {
-                "$id": "#/properties/metrics/items/properties/type",
-                "type": "string",
-                "title": "The Type Schema",
-                "default": "",
-                "examples": [
-                  "counter"
-                ],
-                "pattern": "^(.*)$"
-              },
-              "enabled": {
-                "$id": "#/properties/metrics/items/properties/enabled",
-                "type": "boolean",
-                "title": "The Enabled Schema",
-                "default": false,
-                "examples": [
-                  true
-                ]
-              },
-              "description": {
-                "$id": "#/properties/metrics/items/properties/description",
-                "type": "string",
-                "title": "The Description Schema",
-                "default": "",
-                "examples": [
-                  "The total number of UE context creation events"
-                ],
-                "pattern": "^(.*)$"
-              }
-            }
-          }
-        }
-      }
-    },
     "config": {
       "local": {
         "host": ":8080"
           "description": "The total number of UE context release events"
         }
       ]
-    },
-    "layout": [
-      {
-        "key": "controls.active",
-        "title": "Active"
-      },
-      {
-        "key": "controls.requestorId",
-        "title": "Requestor Id"
-      },
-      {
-        "key": "controls.ranFunctionId",
-        "title": "RAN Function Id"
-      },
-      {
-        "key": "controls.ricActionId",
-        "title": "RIC Action Id"
-      },
-      {
-        "key": "controls.interfaceId.globalENBId",
-        "title": "Global ENB Id"
-      },
-      {
-        "type": "flex",
-        "flex-flow": "row wrap",
-        "items": [
-          {
-            "key": "controls.interfaceId.globalENBId.plmnId",
-            "title": "Plmn Id"
-          },
-          {
-            "key": "controls.interfaceId.globalENBId.eNBId",
-            "title": "ENB Id"
-
-          }
-        ]
-      }
-    ]
+    }
   }
 ]
\ No newline at end of file
index 762fd15..ae47afb 100644 (file)
@@ -7,6 +7,7 @@ RIC Dashboard Release Notes
 
 Version 2.1.0, 26 Aug 2020
 --------------------------
+* Update the workflow of configure running Xapp in Dashboard (`OAM-110 <https://jira.o-ran-sc.org/browse/OAM-110>`_)
 * Extend the Dashboard Xapp deploy workflow to accept configuration (`OAM-109 <https://jira.o-ran-sc.org/browse/OAM-109>`_)
 * Add Xapp Onboarder client to backend (`OAM-108 <https://jira.o-ran-sc.org/browse/OAM-108>`_)
 * Add Xapp Onboarder frontend UI (`OAM-108 <https://jira.o-ran-sc.org/browse/OAM-108>`_)