From 29ce34b03e4099786f14cd7fc5473305da8750d6 Mon Sep 17 00:00:00 2001 From: "Lott, Christopher (cl778h)" Date: Mon, 20 May 2019 11:38:32 -0400 Subject: [PATCH] Add table with automatic neighbor relation data Includes edit and delete features. Drops the xapp screen which was for pendulum control. Bump version to 1.0.4 Change-Id: I64c5379164dd3a52f33c782d206f11d2b792b18e Signed-off-by: Lott, Christopher (cl778h) --- a1-med-client/pom.xml | 2 +- anr-xapp-client/pom.xml | 2 +- docs/release-notes.rst | 5 + e2-mgr-client/pom.xml | 2 +- pom.xml | 2 +- webapp-backend/pom.xml | 2 +- .../dashboard/config/AnrXappMockConfiguration.java | 12 ++- .../dashboard/controller/AcXappController.java | 3 +- .../dashboard/controller/AnrXappController.java | 11 +- .../dashboard/controller/E2ManagerController.java | 6 +- .../controller/HealthcheckController.java | 10 +- .../controller/XappManagerController.java | 3 +- webapp-frontend/pom.xml | 2 +- .../anr-xapp/anr-edit-ncr-dialog.component.html | 53 ++++++++++ .../anr-edit-ncr-dialog.component.scss} | 32 ++---- .../app/anr-xapp/anr-edit-ncr-dialog.component.ts | 93 +++++++++++++++++ .../src/app/anr-xapp/anr-xapp.component.html | 83 +++++++++++++-- .../src/app/anr-xapp/anr-xapp.component.scss | 41 ++++++-- .../src/app/anr-xapp/anr-xapp.component.spec.ts | 4 +- .../src/app/anr-xapp/anr-xapp.component.ts | 105 +++++++++++++++++-- .../src/app/anr-xapp/anr-xapp.datasource.ts | 61 +++++++++++ webapp-frontend/src/app/app-routing.module.ts | 4 +- webapp-frontend/src/app/app.module.ts | 49 +++++---- .../src/app/control/control.component.html | 16 ++- .../src/app/control/control.component.ts | 32 +++--- .../src/app/interfaces/anr-xapp.types.ts | 19 ++-- .../src/app/interfaces/xapp-mgr.types.ts | 2 +- .../sidenav-list/sidenav-list.component.html | 2 + .../src/app/services/anr-xapp/anr-xapp.service.ts | 116 ++++++++++++--------- .../src/app/services/xapp-mgr/xapp-mgr.service.ts | 3 +- webapp-frontend/src/app/xapp/xapp.component.html | 77 -------------- webapp-frontend/src/app/xapp/xapp.component.scss | 0 webapp-frontend/src/app/xapp/xapp.component.ts | 59 ----------- xapp-mgr-client/pom.xml | 2 +- 34 files changed, 590 insertions(+), 325 deletions(-) create mode 100644 webapp-frontend/src/app/anr-xapp/anr-edit-ncr-dialog.component.html rename webapp-frontend/src/app/{xapp/xapp.component.spec.ts => anr-xapp/anr-edit-ncr-dialog.component.scss} (55%) create mode 100644 webapp-frontend/src/app/anr-xapp/anr-edit-ncr-dialog.component.ts create mode 100644 webapp-frontend/src/app/anr-xapp/anr-xapp.datasource.ts delete mode 100644 webapp-frontend/src/app/xapp/xapp.component.html delete mode 100644 webapp-frontend/src/app/xapp/xapp.component.scss delete mode 100644 webapp-frontend/src/app/xapp/xapp.component.ts diff --git a/a1-med-client/pom.xml b/a1-med-client/pom.xml index 8c106b04..974abccd 100644 --- a/a1-med-client/pom.xml +++ b/a1-med-client/pom.xml @@ -25,7 +25,7 @@ limitations under the License. org.o-ran-sc.portal.ric-dashboard ric-dash-parent - 1.0.3-SNAPSHOT + 1.0.4-SNAPSHOT org.o-ran-sc.ric.a1med.client diff --git a/anr-xapp-client/pom.xml b/anr-xapp-client/pom.xml index 83f79e28..2a73208d 100644 --- a/anr-xapp-client/pom.xml +++ b/anr-xapp-client/pom.xml @@ -25,7 +25,7 @@ limitations under the License. org.o-ran-sc.portal.ric-dashboard ric-dash-parent - 1.0.3-SNAPSHOT + 1.0.4-SNAPSHOT org.o-ran-sc.ric.anrxapp.client diff --git a/docs/release-notes.rst b/docs/release-notes.rst index 915df844..7265c477 100644 --- a/docs/release-notes.rst +++ b/docs/release-notes.rst @@ -20,6 +20,11 @@ RIC Dashboard Release Notes =========================== +Version 1.0.4, 29 May 2019 +-------------------------- +* Add ANR xApp neighbor cell relation table +* Drop the pendulum xApp control screen + Version 1.0.3, 28 May 2019 -------------------------- * Add AC xApp controller to backend diff --git a/e2-mgr-client/pom.xml b/e2-mgr-client/pom.xml index b180f895..997c90bd 100644 --- a/e2-mgr-client/pom.xml +++ b/e2-mgr-client/pom.xml @@ -25,7 +25,7 @@ limitations under the License. org.o-ran-sc.portal.ric-dashboard ric-dash-parent - 1.0.3-SNAPSHOT + 1.0.4-SNAPSHOT org.o-ran-sc.ric.e2mgr.client diff --git a/pom.xml b/pom.xml index 19468235..4e6feaf7 100644 --- a/pom.xml +++ b/pom.xml @@ -32,7 +32,7 @@ limitations under the License. ric-dash-parent RIC Dashboard project pom - 1.0.3-SNAPSHOT + 1.0.4-SNAPSHOT AT&T Intellectual Property and Nokia diff --git a/webapp-backend/pom.xml b/webapp-backend/pom.xml index 77d39218..0f19b875 100644 --- a/webapp-backend/pom.xml +++ b/webapp-backend/pom.xml @@ -25,7 +25,7 @@ limitations under the License. org.o-ran-sc.portal.ric-dashboard ric-dash-parent - 1.0.3-SNAPSHOT + 1.0.4-SNAPSHOT ric-dash-be RIC Dashboard Webapp backend diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/AnrXappMockConfiguration.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/AnrXappMockConfiguration.java index 578107f8..550963b3 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/AnrXappMockConfiguration.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/AnrXappMockConfiguration.java @@ -32,6 +32,7 @@ import java.lang.invoke.MethodHandles; import org.oransc.ric.anrxapp.client.api.HealthApi; import org.oransc.ric.anrxapp.client.api.NcrtApi; import org.oransc.ric.anrxapp.client.invoker.ApiClient; +import org.oransc.ric.anrxapp.client.model.GgNodeBTable; import org.oransc.ric.anrxapp.client.model.NeighborCellRelation; import org.oransc.ric.anrxapp.client.model.NeighborCellRelationMod; import org.oransc.ric.anrxapp.client.model.NeighborCellRelationTable; @@ -52,9 +53,12 @@ public class AnrXappMockConfiguration { private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private final NeighborCellRelationTable ncrt, ncrtNodeB1, ncrtNodeB2; + private final GgNodeBTable gNodebTable; public AnrXappMockConfiguration() { logger.info("Configuring mock ANR xApp client"); + gNodebTable = new GgNodeBTable(); + gNodebTable.addGNodeBIdsItem("A").addGNodeBIdsItem("B"); ncrtNodeB1 = new NeighborCellRelationTable(); ncrtNodeB2 = new NeighborCellRelationTable(); ncrt = new NeighborCellRelationTable(); @@ -81,11 +85,10 @@ public class AnrXappMockConfiguration { } @Bean - public HealthApi anrHealthMockApi() { - ApiClient mockClient = mock(ApiClient.class); - when(mockClient.getStatusCode()).thenReturn(HttpStatus.OK); + public HealthApi anrHealthApi() { + ApiClient apiClient = apiClient(); HealthApi mockApi = mock(HealthApi.class); - when(mockApi.getApiClient()).thenReturn(mockClient); + when(mockApi.getApiClient()).thenReturn(apiClient); doAnswer(i -> { return null; }).when(mockApi).getHealthAlive(); @@ -100,6 +103,7 @@ public class AnrXappMockConfiguration { ApiClient apiClient = apiClient(); NcrtApi mockApi = mock(NcrtApi.class); when(mockApi.getApiClient()).thenReturn(apiClient); + when(mockApi.getgNodeB()).thenReturn(gNodebTable); // Swagger sends nulls; front end sends empty strings when(mockApi.getNcrt((String) isNull(), (String) isNull(), (String) isNull())).thenReturn(ncrt); when(mockApi.getNcrt(eq(""), any(String.class), any(String.class))).thenReturn(ncrt); diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/AcXappController.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/AcXappController.java index c1aac8f3..69864d9d 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/AcXappController.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/AcXappController.java @@ -66,8 +66,7 @@ public class AcXappController { @ApiOperation(value = "Gets the A1 client library MANIFEST.MF property Implementation-Version.", response = SuccessTransport.class) @RequestMapping(value = DashboardConstants.VERSION_PATH, method = RequestMethod.GET) - public SuccessTransport getVersion() { - logger.debug("getVersion enter"); + public SuccessTransport getA1MediatorClientVersion() { return new SuccessTransport(200, DashboardApplication.getImplementationVersion(A1MediatorApi.class)); } diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/AnrXappController.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/AnrXappController.java index 7f14cdee..5b1a6e2d 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/AnrXappController.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/AnrXappController.java @@ -79,23 +79,20 @@ public class AnrXappController { @ApiOperation(value = "Gets the ANR client library MANIFEST.MF property Implementation-Version.", response = SuccessTransport.class) @RequestMapping(value = DashboardConstants.VERSION_PATH, method = RequestMethod.GET) - public SuccessTransport getVersion() { - logger.debug("getVersion enter"); + public SuccessTransport getAnrXappClientVersion() { return new SuccessTransport(200, DashboardApplication.getImplementationVersion(HealthApi.class)); } @ApiOperation(value = "Performs a liveness probe on the ANR xApp, result expressed as the response code.") @RequestMapping(value = "/health/alive", method = RequestMethod.GET) - public void getHealthAlive(HttpServletResponse response) { - logger.debug("getHealthAlive"); + public void getAnrXappHealthAlive(HttpServletResponse response) { healthApi.getHealthAlive(); response.setStatus(healthApi.getApiClient().getStatusCode().value()); } @ApiOperation(value = "Performs a readiness probe on the ANR xApp, result expressed as the response code.") @RequestMapping(value = "/health/ready", method = RequestMethod.GET) - public void getHealthReady(HttpServletResponse response) { - logger.debug("getHealthReady"); + public void getAnrXappHealthReady(HttpServletResponse response) { healthApi.getHealthReady(); response.setStatus(healthApi.getApiClient().getStatusCode().value()); } @@ -112,7 +109,7 @@ public class AnrXappController { @RequestParam(name = QP_NODEB, required = false) String ggnbId, // @RequestParam(name = QP_SERVING, required = false) String servingCellNrcgi, // @RequestParam(name = QP_NEIGHBOR, required = false) String neighborCellNrpci) { - logger.debug("getNcrtInfo: ggnbid {}, servingCellNrpci {} neighborCellNrcgi {}", ggnbId, servingCellNrcgi, + logger.debug("getNcrtInfo: ggnbid {}, servingCellNrpci {}, neighborCellNrcgi {}", ggnbId, servingCellNrcgi, neighborCellNrpci); return ncrtApi.getNcrt(ggnbId, servingCellNrcgi, neighborCellNrpci); } diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/E2ManagerController.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/E2ManagerController.java index 97ea3344..b9213eac 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/E2ManagerController.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/E2ManagerController.java @@ -90,15 +90,13 @@ public class E2ManagerController { @ApiOperation(value = "Gets the E2 manager client library MANIFEST.MF property Implementation-Version.", response = SuccessTransport.class) @RequestMapping(value = DashboardConstants.VERSION_PATH, method = RequestMethod.GET) - public SuccessTransport getVersion() { - logger.debug("getVersion enter"); + public SuccessTransport getE2ManagerClientVersion() { return new SuccessTransport(200, DashboardApplication.getImplementationVersion(HealthCheckApi.class)); } @ApiOperation(value = "Gets the health from the E2 manager, expressed as the response code.") @RequestMapping(value = "/health", method = RequestMethod.GET) - public void getHealth(HttpServletResponse response) { - logger.debug("getHealth"); + public void getE2ManagerHealth(HttpServletResponse response) { e2HealthCheckApi.healthGet(); response.setStatus(e2HealthCheckApi.getApiClient().getStatusCode().value()); } diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/HealthcheckController.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/HealthcheckController.java index f12c59a0..235bcabd 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/HealthcheckController.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/HealthcheckController.java @@ -24,8 +24,6 @@ import java.lang.invoke.MethodHandles; import org.oransc.ric.portal.dashboard.DashboardApplication; import org.oransc.ric.portal.dashboard.DashboardConstants; import org.oransc.ric.portal.dashboard.model.SuccessTransport; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -40,20 +38,16 @@ import io.swagger.annotations.ApiOperation; @RequestMapping(value = DashboardConstants.ENDPOINT_PREFIX + "/dashboard", produces = MediaType.APPLICATION_JSON_VALUE) public class HealthcheckController { - private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - @ApiOperation(value = "Checks the health of the application by (TBD).", response = SuccessTransport.class) @RequestMapping(value = DashboardConstants.HEALTHCHECK_PATH, method = RequestMethod.GET) - public SuccessTransport getHealth() { - logger.debug("getHealth enter"); + public SuccessTransport getDashblardHealth() { long count = 0; return new SuccessTransport(200, "(TBD) reports count is " + count); } @ApiOperation(value = "Gets the Dashboard MANIFEST.MF property Implementation-Version.", response = SuccessTransport.class) @RequestMapping(value = DashboardConstants.VERSION_PATH, method = RequestMethod.GET) - public SuccessTransport getVersion() { - logger.debug("getVersion enter"); + public SuccessTransport getDashboardVersion() { return new SuccessTransport(200, DashboardApplication.getImplementationVersion(MethodHandles.lookup().lookupClass())); } diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/XappManagerController.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/XappManagerController.java index ad62bb0e..efb296dc 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/XappManagerController.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/XappManagerController.java @@ -75,8 +75,7 @@ public class XappManagerController { @ApiOperation(value = "Gets the XApp manager client library MANIFEST.MF property Implementation-Version.", response = SuccessTransport.class) @RequestMapping(value = DashboardConstants.VERSION_PATH, method = RequestMethod.GET) - public SuccessTransport getVersion() { - logger.debug("getVersion enter"); + public SuccessTransport getXappManagerClientVersion() { return new SuccessTransport(200, DashboardApplication.getImplementationVersion(HealthApi.class)); } diff --git a/webapp-frontend/pom.xml b/webapp-frontend/pom.xml index 9a8e84e7..29ddc86a 100644 --- a/webapp-frontend/pom.xml +++ b/webapp-frontend/pom.xml @@ -25,7 +25,7 @@ limitations under the License. org.o-ran-sc.portal.ric-dashboard ric-dash-parent - 1.0.3-SNAPSHOT + 1.0.4-SNAPSHOT ric-dash-fe RIC Dashboard Webapp frontend diff --git a/webapp-frontend/src/app/anr-xapp/anr-edit-ncr-dialog.component.html b/webapp-frontend/src/app/anr-xapp/anr-edit-ncr-dialog.component.html new file mode 100644 index 00000000..7f22819c --- /dev/null +++ b/webapp-frontend/src/app/anr-xapp/anr-edit-ncr-dialog.component.html @@ -0,0 +1,53 @@ + + +
+ Edit Neighbor Cell Relation +
+ +
+
+ + + + + + + + + Example: A12345 + Neighbor cell identifier is required + Valid NRCGI is required + +
+ Flag No Handover +
+
+ Flag No Transaction +
+
+ Flag No Remove +
+
+ +
diff --git a/webapp-frontend/src/app/xapp/xapp.component.spec.ts b/webapp-frontend/src/app/anr-xapp/anr-edit-ncr-dialog.component.scss similarity index 55% rename from webapp-frontend/src/app/xapp/xapp.component.spec.ts rename to webapp-frontend/src/app/anr-xapp/anr-edit-ncr-dialog.component.scss index 0e88e2ef..400600c7 100644 --- a/webapp-frontend/src/app/xapp/xapp.component.spec.ts +++ b/webapp-frontend/src/app/anr-xapp/anr-edit-ncr-dialog.component.scss @@ -7,9 +7,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,28 +17,8 @@ * limitations under the License. * ========================LICENSE_END=================================== */ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { XappComponent } from './xapp.component'; - -describe('XappComponent', () => { - let component: XappComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ XappComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(XappComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); + /* used to place form fields on separate lines/rows in dialog */ +.input-display-block { + display: block; + } \ No newline at end of file diff --git a/webapp-frontend/src/app/anr-xapp/anr-edit-ncr-dialog.component.ts b/webapp-frontend/src/app/anr-xapp/anr-edit-ncr-dialog.component.ts new file mode 100644 index 00000000..2857f55d --- /dev/null +++ b/webapp-frontend/src/app/anr-xapp/anr-edit-ncr-dialog.component.ts @@ -0,0 +1,93 @@ +/*- + * ========================LICENSE_START================================= + * O-RAN-SC + * %% + * Copyright (C) 2019 AT&T Intellectual Property and Nokia + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================LICENSE_END=================================== + */ +import { Component, OnInit, Inject } from '@angular/core'; +import { FormGroup, FormControl, Validators } from '@angular/forms'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { ANRXappService } from '../services/anr-xapp/anr-xapp.service'; +import { ErrorDialogService } from '../services/ui/error-dialog.service'; +import { ANRNeighborCellRelation, ANRNeighborCellRelationMod } from '../interfaces/anr-xapp.types'; +import { modelGroupProvider } from '@angular/forms/src/directives/ng_model_group'; + +@Component({ + selector: 'app-ncr-edit-dialog', + templateUrl: './anr-edit-ncr-dialog.component.html', + styleUrls: ['./anr-edit-ncr-dialog.component.scss'] +}) + +export class ANREditNCRDialogComponent implements OnInit { + + private ncrDialogForm: FormGroup; + + constructor( + private dialogRef: MatDialogRef, + private dataService: ANRXappService, private errorService: ErrorDialogService, + @Inject(MAT_DIALOG_DATA) private data: ANRNeighborCellRelation) { + console.log('constructed with data ' + data); + } + + ngOnInit() { + const namePattern = /^([A-Z])+([0-9])+$/; + this.ncrDialogForm = new FormGroup({ + servingCellNrcgi: new FormControl(this.data.servingCellNrcgi), // readonly + neighborCellNrpci: new FormControl(this.data.neighborCellNrpci), // readonly + neighborCellNrcgi: new FormControl(this.data.neighborCellNrcgi, [Validators.required, Validators.pattern(namePattern)]), + flagNoHo: new FormControl(this.data.flagNoHo), + flagNoXn: new FormControl(this.data.flagNoXn), + flagNoRemove: new FormControl(this.data.flagNoRemove) + }); + } + + onCancel() { + this.dialogRef.close(); + } + + modifyNcr = (ncrFormValue: ANRNeighborCellRelation) => { + if (this.ncrDialogForm.valid) { + const ncrm = {} as ANRNeighborCellRelationMod; + // there must be a btter way + ncrm.neighborCellNrcgi = ncrFormValue.neighborCellNrcgi; + ncrm.neighborCellNrpci = ncrFormValue.neighborCellNrpci; + ncrm.flagNoHo = ncrFormValue.flagNoHo; + ncrm.flagNoXn = ncrFormValue.flagNoXn; + ncrm.flagNoRemove = ncrFormValue.flagNoRemove; + this.dataService.modifyNcr(ncrFormValue.servingCellNrcgi, ncrFormValue.neighborCellNrpci, ncrm).subscribe((val: any[]) => {}, + (error => { + this.errorService.displayError('NCR update failed: ' + error.message); + }) + ); + this.dialogRef.close(); + } + } + + public hasError(controlName: string, errorName: string) { + if (this.ncrDialogForm.controls[controlName].hasError(errorName)) { + return true; + } + return false; + } + + public validateControl(controlName: string) { + if (this.ncrDialogForm.controls[controlName].invalid && this.ncrDialogForm.controls[controlName].touched) { + return true; + } + return false; + } + +} diff --git a/webapp-frontend/src/app/anr-xapp/anr-xapp.component.html b/webapp-frontend/src/app/anr-xapp/anr-xapp.component.html index 0684ac74..a245b2de 100644 --- a/webapp-frontend/src/app/anr-xapp/anr-xapp.component.html +++ b/webapp-frontend/src/app/anr-xapp/anr-xapp.component.html @@ -7,9 +7,9 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -18,9 +18,78 @@ ========================LICENSE_END=================================== -->
-

ANR xApp

- - - -
+

ANR xApp Neighbor Cell Relation Table

+ + + GgNodeB + + + + + + + + + + +
+ +
+ + + + + Serving Cell NRCGI + {{ncr.servingCellNrcgi}} + + + + Neighbor Cell NRPCI + {{ncr.neighborCellNrpci}} + + + + Neighbor Cell NRCGI + {{ncr.neighborCellNrcgi}} + + + + Flag No Handover + {{ncr.flagNoHo}} + + + Flag No Xn + {{ncr.flagNoXn}} + + + + Flag No Remove + {{ncr.flagNoRemove}} + + + + Action + + + + + + + + + + +
+ +
+ ANR client version {{anrClientVersion}} +
+ diff --git a/webapp-frontend/src/app/anr-xapp/anr-xapp.component.scss b/webapp-frontend/src/app/anr-xapp/anr-xapp.component.scss index 183d90dc..bcac3a0e 100644 --- a/webapp-frontend/src/app/anr-xapp/anr-xapp.component.scss +++ b/webapp-frontend/src/app/anr-xapp/anr-xapp.component.scss @@ -7,9 +7,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,7 +19,7 @@ */ .anr__section { position: relative; - top: -150px; + top: -50px; } .anr__header { @@ -31,10 +31,37 @@ transform: translate(149 56); } -:host /deep/ ng2-smart-table tbody > tr > td{ - text-align: left; +.spinner-container { + height: 360px; + width: 390px; + position: fixed; } -:host /deep/ ng2-smart-table thead th{ - text-align: left; +.spinner-container mat-spinner { + margin: 130px auto 0 auto; +} + +.ncr-table { + width: 99%; /* 100 looks wrong */ + min-height: 150px; + margin-top: 10px; + background-color:transparent; +} + +.ncr-table__bg-dark { + color: white; +} + +.input-pad-left { + padding-left: 10px; +} + +.input-pad-right { + padding-right: 10px; +} + +.version__text { + color: gray; + letter-spacing: 0.1rem; + font-size: 10px; } diff --git a/webapp-frontend/src/app/anr-xapp/anr-xapp.component.spec.ts b/webapp-frontend/src/app/anr-xapp/anr-xapp.component.spec.ts index 6a156fdc..173ecd2b 100644 --- a/webapp-frontend/src/app/anr-xapp/anr-xapp.component.spec.ts +++ b/webapp-frontend/src/app/anr-xapp/anr-xapp.component.spec.ts @@ -7,9 +7,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/webapp-frontend/src/app/anr-xapp/anr-xapp.component.ts b/webapp-frontend/src/app/anr-xapp/anr-xapp.component.ts index efe0992c..d173505b 100644 --- a/webapp-frontend/src/app/anr-xapp/anr-xapp.component.ts +++ b/webapp-frontend/src/app/anr-xapp/anr-xapp.component.ts @@ -7,9 +7,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,18 +17,111 @@ * limitations under the License. * ========================LICENSE_END=================================== */ -import { Component, OnInit } from '@angular/core'; + +import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { fromEvent } from 'rxjs/observable/fromEvent'; +import { debounceTime, distinctUntilChanged, tap } from 'rxjs/operators'; +import { ANRNeighborCellRelation } from '../interfaces/anr-xapp.types'; +import { ANRXappDataSource } from './anr-xapp.datasource'; +import { ANRXappService } from '../services/anr-xapp/anr-xapp.service'; +import { ANREditNCRDialogComponent } from './anr-edit-ncr-dialog.component'; +import { ConfirmDialogService } from './../services/ui/confirm-dialog.service'; +import { ErrorDialogService } from '../services/ui/error-dialog.service'; +import { NotificationService } from './../services/ui/notification.service'; @Component({ - selector: 'app-anr-xapp', + selector: 'app-anr', templateUrl: './anr-xapp.component.html', styleUrls: ['./anr-xapp.component.scss'] }) -export class AnrXappComponent implements OnInit { +export class AnrXappComponent implements AfterViewInit, OnInit { + + dataSource: ANRXappDataSource; + anrClientVersion: string; + gNodeBIds: string[]; + @ViewChild('ggNodeB') ggNodeB: ElementRef; + @ViewChild('servingCellNrcgi') servingCellNrcgi: ElementRef; + @ViewChild('neighborCellNrpci') neighborCellNrpci: ElementRef; + + displayedColumns = ['cellIdentifierNrcgi', 'neighborCellNrpci', 'neighborCellNrcgi', + 'flagNoHo', 'flagNoXn', 'flagNoRemove', 'action']; - constructor() { } + constructor( + private anrXappService: ANRXappService, + private dialog: MatDialog, + private confirmDialogService: ConfirmDialogService, + private errorDialogService: ErrorDialogService, + private notificationService: NotificationService) { } ngOnInit() { + this.dataSource = new ANRXappDataSource(this.anrXappService); + this.dataSource.loadTable(); + // Empty string occurs first in the array of gNodeBIds + this.anrXappService.getgNodeBs().subscribe((res: string[]) => this.gNodeBIds = res); + this.anrXappService.getVersion().subscribe((res: string) => this.anrClientVersion = res); + } + + ngAfterViewInit() { + // the selector event calls loadNcrtPage() directly. + fromEvent(this.servingCellNrcgi.nativeElement, 'keyup') + .pipe( + debounceTime(150), + distinctUntilChanged(), + tap(() => { + this.loadNcrtPage(); + }) + ) + .subscribe(); + fromEvent(this.neighborCellNrpci.nativeElement, 'keyup') + .pipe( + debounceTime(150), + distinctUntilChanged(), + tap(() => { + this.loadNcrtPage(); + }) + ) + .subscribe(); + } + + loadNcrtPage() { + this.dataSource.loadTable( + this.ggNodeB.nativeElement.value, + this.servingCellNrcgi.nativeElement.value, + this.neighborCellNrpci.nativeElement.value); + } + + modifyNcr(ncr: ANRNeighborCellRelation): void { + const dialogRef = this.dialog.open(ANREditNCRDialogComponent, { + width: '300px', + data: ncr + }); + dialogRef.afterClosed().subscribe(result => { + this.loadNcrtPage(); + }); + } + + deleteNcr(ncr: ANRNeighborCellRelation): void { + this.confirmDialogService + .openConfirmDialog('Are you sure you want to delete this relation?') + .afterClosed().subscribe(res => { + if (res) { + this.anrXappService.deleteNcr(ncr.servingCellNrcgi, ncr.neighborCellNrpci) + .subscribe( + response => { + switch (response.status) { + case 200: + this.notificationService.success('Delete succeeded!'); + break; + default: + this.notificationService.warn('Delete failed.'); + } + }, + error => { + this.errorDialogService.displayError(error.message); + }); + } + }); } } diff --git a/webapp-frontend/src/app/anr-xapp/anr-xapp.datasource.ts b/webapp-frontend/src/app/anr-xapp/anr-xapp.datasource.ts new file mode 100644 index 00000000..bca766c6 --- /dev/null +++ b/webapp-frontend/src/app/anr-xapp/anr-xapp.datasource.ts @@ -0,0 +1,61 @@ +/*- + * ========================LICENSE_START================================= + * O-RAN-SC + * %% + * Copyright (C) 2019 AT&T Intellectual Property and Nokia + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================LICENSE_END=================================== + */ + +import { CollectionViewer, DataSource} from '@angular/cdk/collections'; +import { Observable } from 'rxjs/Observable'; +import { catchError, finalize } from 'rxjs/operators'; +import { of } from 'rxjs/observable/of'; +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; +import { ANRNeighborCellRelation } from '../interfaces/anr-xapp.types'; +import { ANRXappService } from '../services/anr-xapp/anr-xapp.service'; + +// https://blog.angular-university.io/angular-material-data-table/ +export class ANRXappDataSource extends DataSource { + + private relationsSubject = new BehaviorSubject([]); + + private loadingSubject = new BehaviorSubject(false); + + public loading$ = this.loadingSubject.asObservable(); + + constructor(private anrXappService: ANRXappService) { + super(); + } + + loadTable(ggnodeb = '', servingCellNrcgi = '', neighborCellNrpci = '') { + this.loadingSubject.next(true); + this.anrXappService.getNcrtInfo(ggnodeb, servingCellNrcgi, neighborCellNrpci) + .pipe( + catchError(() => of([])), + finalize(() => this.loadingSubject.next(false)) + ) + .subscribe(ncrt => this.relationsSubject.next(ncrt)); + } + + connect(collectionViewer: CollectionViewer): Observable { + return this.relationsSubject.asObservable(); + } + + disconnect(collectionViewer: CollectionViewer): void { + this.relationsSubject.complete(); + this.loadingSubject.complete(); + } + +} diff --git a/webapp-frontend/src/app/app-routing.module.ts b/webapp-frontend/src/app/app-routing.module.ts index 3fa11e6a..130703ce 100644 --- a/webapp-frontend/src/app/app-routing.module.ts +++ b/webapp-frontend/src/app/app-routing.module.ts @@ -26,7 +26,7 @@ import { ControlComponent } from './control/control.component'; import { RANConnectionComponent } from './ran-connection/ran-connection.component'; import { StatsComponent } from './stats/stats.component'; import { AdminComponent } from './admin/admin.component'; -import { XappComponent } from './xapp/xapp.component'; +import { AnrXappComponent } from './anr-xapp/anr-xapp.component'; const routes: Routes = [ {path: '', component: LoginComponent}, @@ -36,7 +36,7 @@ const routes: Routes = [ {path: 'ran-connection', component: RANConnectionComponent}, {path: 'stats', component: StatsComponent}, {path: 'admin', component: AdminComponent}, - {path: 'xapp', component: XappComponent}, + {path: 'anr', component: AnrXappComponent}, ]; @NgModule({ diff --git a/webapp-frontend/src/app/app.module.ts b/webapp-frontend/src/app/app.module.ts index 8bd8b4a9..ab3afd0d 100644 --- a/webapp-frontend/src/app/app.module.ts +++ b/webapp-frontend/src/app/app.module.ts @@ -19,19 +19,22 @@ */ import { BrowserModule } from '@angular/platform-browser'; // tslint:disable-next-line:max-line-length -import {MatButtonModule, MatButtonToggleModule, MatCardModule, MatDialogModule, - MatExpansionModule, MatFormFieldModule, MatGridListModule, MatIconModule, - MatInputModule, MatListModule, MatPaginatorModule, MatProgressSpinnerModule, - MatSidenavModule, MatSliderModule, MatSlideToggleModule, MatSnackBarModule, - MatSortModule,MatTableModule, MatTabsModule} from '@angular/material'; +import {MatButtonModule, MatButtonToggleModule, MatCardModule, MatCheckboxModule, + MatDialogModule, MatExpansionModule, MatFormFieldModule, MatGridListModule, + MatIconModule, MatInputModule, MatListModule, MatPaginatorModule, + MatProgressSpinnerModule, MatSelectModule, MatSidenavModule, MatSliderModule, + MatSlideToggleModule, MatSnackBarModule, MatSortModule, MatTableModule, + MatTabsModule} from '@angular/material'; import { BrowserAnimationsModule} from '@angular/platform-browser/animations'; import { NgModule } from '@angular/core'; -import { Ng2SmartTableModule } from 'ng2-smart-table'; import { MatRadioModule } from '@angular/material/radio'; import { ChartsModule } from 'ng2-charts'; import { MDBBootstrapModule } from 'angular-bootstrap-md'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +// RETIRE THIS +import { Ng2SmartTableModule } from 'ng2-smart-table'; + import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { LoginComponent } from './login/login.component'; @@ -45,13 +48,13 @@ import { SidenavListComponent } from './navigation/sidenav-list/sidenav-list.com import { ControlComponent } from './control/control.component'; import { RANConnectionDialogComponent } from './ran-connection/ran-connection-dialog.component'; import { RANConnectionComponent } from './ran-connection/ran-connection.component'; +import { ANREditNCRDialogComponent } from './anr-xapp/anr-edit-ncr-dialog.component'; import { StatsComponent } from './stats/stats.component'; import { AdminComponent } from './admin/admin.component'; import { CatalogCardComponent } from './ui/catalog-card/catalog-card.component'; import { ControlCardComponent } from './ui/control-card/control-card.component'; import { StatCardComponent } from './ui/stat-card/stat-card.component'; import { ModalEventComponent } from './ui/modal-event/modal-event.component'; -import { XappComponent } from './xapp/xapp.component'; import { ConfigEventComponent } from './ui/config-event/config-event.component'; import { ConfirmDialogComponent } from './ui/confirm-dialog/confirm-dialog.component'; import { FooterComponent } from './footer/footer.component'; @@ -73,41 +76,44 @@ import { ErrorDialogService } from './services/ui/error-dialog.service'; StatsComponent, AdminComponent, ModalEventComponent, - XappComponent, ConfigEventComponent, AnrXappComponent, RANConnectionDialogComponent, + ANREditNCRDialogComponent, ConfirmDialogComponent, FooterComponent, ErrorDialogComponent ], imports: [ + AppRoutingModule, BrowserModule, BrowserAnimationsModule, ChartsModule, - AppRoutingModule, FormsModule, - MatDialogModule, - ReactiveFormsModule, + MatButtonModule, MatButtonToggleModule, - MatExpansionModule, - MatRadioModule, - MatSliderModule, MatCardModule, - MatIconModule, + MatCheckboxModule, + MatDialogModule, + MatExpansionModule, + MatFormFieldModule, MatGridListModule, + MatIconModule, + MatInputModule, MatListModule, + MatPaginatorModule, + MatProgressSpinnerModule, + MatRadioModule, + MatSelectModule, + MatSliderModule, MatSidenavModule, MatSlideToggleModule, + MatSnackBarModule, + MatSortModule, MatTableModule, MatTabsModule, - MatSortModule, - MatFormFieldModule, - MatButtonModule, - MatInputModule, - MatProgressSpinnerModule, Ng2SmartTableModule, - MatSnackBarModule, + ReactiveFormsModule, MDBBootstrapModule.forRoot(), ], exports: [ @@ -131,6 +137,7 @@ import { ErrorDialogService } from './services/ui/error-dialog.service'; ], entryComponents: [ RANConnectionDialogComponent, + ANREditNCRDialogComponent, ConfirmDialogComponent, ErrorDialogComponent ], diff --git a/webapp-frontend/src/app/control/control.component.html b/webapp-frontend/src/app/control/control.component.html index d29191cc..1e7bca2d 100644 --- a/webapp-frontend/src/app/control/control.component.html +++ b/webapp-frontend/src/app/control/control.component.html @@ -51,14 +51,12 @@ Action - - - @@ -85,8 +83,8 @@ + [class.example-expanded-row]="expandedElement === element" + (click)="expandedElement = expandedElement === element ? null : element"> - + \ No newline at end of file diff --git a/webapp-frontend/src/app/control/control.component.ts b/webapp-frontend/src/app/control/control.component.ts index 54ce96d4..29a88ccf 100644 --- a/webapp-frontend/src/app/control/control.component.ts +++ b/webapp-frontend/src/app/control/control.component.ts @@ -7,9 +7,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,12 +20,13 @@ import { Component, OnInit } from '@angular/core'; import { XappMgrService } from '../services/xapp-mgr/xapp-mgr.service'; import { Router } from '@angular/router'; -import { ConfirmDialogService } from './../services/ui/confirm-dialog.service' -import { NotificationService } from './../services/ui/notification.service' -import { XMXapp } from '../interfaces/xapp-mgr.types'; +import { ErrorDialogService } from './../services/ui/error-dialog.service'; +import { ConfirmDialogService } from './../services/ui/confirm-dialog.service'; +import { NotificationService } from './../services/ui/notification.service'; +import { XappControlRow } from '../interfaces/xapp-mgr.types'; import { ControlAnimations } from './control.animations'; import { ControlDataSource } from './control.datasource'; - +import { routerNgProbeToken } from '@angular/router/src/router_module'; @Component({ selector: 'app-control', @@ -42,6 +43,7 @@ export class ControlComponent implements OnInit { private xappMgrSvc: XappMgrService, private router: Router, private confirmDialogService: ConfirmDialogService, + private errorDialogService: ErrorDialogService, private notification: NotificationService) { } ngOnInit() { @@ -49,16 +51,20 @@ export class ControlComponent implements OnInit { this.dataSource.loadTable(); } - view(): void { - const url = '/xapp'; - this.router.navigate([url]); + controlApp(app: XappControlRow): void { + const anrXappPattern = /[Aa][Nn][Rr]/; + if (anrXappPattern.test(app.xapp)) { + this.router.navigate(['/anr']); + } else { + this.errorDialogService.displayError('No control available for ' + app.xapp + ' (yet)'); + } } - undeploy(name: string): void { - this.confirmDialogService.openConfirmDialog('Are you sure you want to undeploy this xApp ?') + undeployApp(app: XappControlRow): void { + this.confirmDialogService.openConfirmDialog('Are you sure you want to undeploy xApp ' + app.xapp + '?') .afterClosed().subscribe(res => { if (res) { - this.xappMgrSvc.undeployXapp(name).subscribe( + this.xappMgrSvc.undeployXapp(app.xapp).subscribe( response => { this.dataSource.loadTable(); switch (response.status) { @@ -74,6 +80,4 @@ export class ControlComponent implements OnInit { }); } - - } diff --git a/webapp-frontend/src/app/interfaces/anr-xapp.types.ts b/webapp-frontend/src/app/interfaces/anr-xapp.types.ts index f0a5a43d..078753f1 100644 --- a/webapp-frontend/src/app/interfaces/anr-xapp.types.ts +++ b/webapp-frontend/src/app/interfaces/anr-xapp.types.ts @@ -20,8 +20,16 @@ // Models of data used by the ANR xApp +export interface ANRGgNodeBTable { + gNodeBIds: Array; +} + +export interface ANRNeighborCellRelationTable { + ncrtRelations: Array; +} + export interface ANRNeighborCellRelation { - cellIdentifierNrcgi: string; + servingCellNrcgi: string; neighborCellNrpci: string; neighborCellNrcgi: string; flagNoHo: boolean; @@ -29,15 +37,8 @@ export interface ANRNeighborCellRelation { flagNoRemove: boolean; } -export interface ANRNeighborCellRelationDel { - idType: string; - neighborCellNrpci: string; - neighborCellNrcgi: string; -} - export interface ANRNeighborCellRelationMod { - neighbourCellIdentifierType: string; - action: string; + servingCellNrcgi: string; neighborCellNrpci: string; neighborCellNrcgi: string; flagNoHo: boolean; diff --git a/webapp-frontend/src/app/interfaces/xapp-mgr.types.ts b/webapp-frontend/src/app/interfaces/xapp-mgr.types.ts index 7654377f..1c3cc388 100644 --- a/webapp-frontend/src/app/interfaces/xapp-mgr.types.ts +++ b/webapp-frontend/src/app/interfaces/xapp-mgr.types.ts @@ -51,4 +51,4 @@ export interface XMXapp { export interface XappControlRow { xapp: string; instance: XMXappInstance; -} \ No newline at end of file +} diff --git a/webapp-frontend/src/app/navigation/sidenav-list/sidenav-list.component.html b/webapp-frontend/src/app/navigation/sidenav-list/sidenav-list.component.html index 7df8c478..8e8a75ed 100644 --- a/webapp-frontend/src/app/navigation/sidenav-list/sidenav-list.component.html +++ b/webapp-frontend/src/app/navigation/sidenav-list/sidenav-list.component.html @@ -17,6 +17,8 @@ limitations under the License. ========================LICENSE_END=================================== --> + + home Home diff --git a/webapp-frontend/src/app/services/anr-xapp/anr-xapp.service.ts b/webapp-frontend/src/app/services/anr-xapp/anr-xapp.service.ts index f9403f1f..a2dfb75e 100644 --- a/webapp-frontend/src/app/services/anr-xapp/anr-xapp.service.ts +++ b/webapp-frontend/src/app/services/anr-xapp/anr-xapp.service.ts @@ -21,27 +21,43 @@ import { Injectable } from '@angular/core'; import { HttpClient, HttpParams } from '@angular/common/http'; import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; import { DashboardSuccessTransport } from '../../interfaces/dashboard.types'; import { ANRNeighborCellRelation, ANRNeighborCellRelationMod } from '../../interfaces/anr-xapp.types'; @Injectable({ providedIn: 'root' }) -export class AnrXappService { +export class ANRXappService { - private basePath = 'api/xapp/anr/'; - private cellPath = 'cell/cellIdentifier/'; + // Trailing slashes are confusing so omit them here + private basePath = 'api/xapp/anr'; + private ncrtPath = 'ncrt'; + private servingPath = 'servingcells'; + private neighborPath = 'neighborcells'; constructor(private httpClient: HttpClient) { // injects to variable httpClient } + private buildPath(...args: any[]) { + let result = this.basePath; + args.forEach(part => { + result = result + '/' + part; + }); + return result; + } + /** * Gets ANR xApp client version details * @returns Observable that should yield a DashboardSuccessTransport */ - getVersion(): Observable { - return this.httpClient.get(this.basePath + 'version'); + getVersion(): Observable { + const url = this.buildPath('version'); + return this.httpClient.get(url).pipe( + // Extract the string here + map(res => res['data']) + ); } /** @@ -49,7 +65,8 @@ export class AnrXappService { * @returns Observable that should yield a response code (no data) */ getHealthAlive(): Observable { - return this.httpClient.get(this.basePath + 'health/alive'); + const url = this.buildPath('health/alive'); + return this.httpClient.get(url); } /** @@ -57,62 +74,63 @@ export class AnrXappService { * @returns Observable that should yield a response code (no data) */ getHealthReady(): Observable { - return this.httpClient.get(this.basePath + 'health/ready'); + const url = this.buildPath('health/ready'); + return this.httpClient.get(url); + } + + /** + * Gets ANR xApp client version details + * @returns Observable that should yield a DashboardSuccessTransport + */ + getgNodeBs(): Observable { + const url = this.buildPath('gnodebs'); + return this.httpClient.get(url).pipe( + // Extract the array of IDs here + map(res => res['gNodeBIds']) + ); } /** - * Query NCRT of all cells, all or one gNB(s) + * Gets the neighbor cell relation table for all gNodeBs or based on query parameters * @param ggnbId Optional parameter for the gNB ID - * @param startIndex Optional parameter for the start index - * @param limit Optional parameter for the limit (page size) - * @returns Observable of ANRNeighborCellRelation + * @param servingCellNrcgi Serving cell NRCGI + * @param neighborCellNrpci Neighbor cell NRPCI + * @returns Neighbor cell relation table, which wraps an array */ - getNcrtInfo(ggnbId?: string, startIndex?: string, limit?: number): Observable { - const queryParams = new HttpParams(); - if (ggnbId) { - queryParams.set('ggnbid', ggnbId); - } - if (startIndex) { - queryParams.set('startIndex', startIndex); - } - if (limit) { - queryParams.set('limit', limit.toString()); - } - return this.httpClient.get(this.basePath + 'cell', { params: queryParams } ); + getNcrtInfo(ggnodeb: string = '', servingCellNrcgi: string = '', neighborCellNrpci: string = ''): Observable { + const url = this.buildPath(this.ncrtPath); + return this.httpClient.get(url, { + params: new HttpParams() + .set('ggnodeb', ggnodeb) + .set('servingCellNrcgi', servingCellNrcgi) + .set('neighborCellNrpci', neighborCellNrpci) + }).pipe( + // Extract the array of relations here + map(res => res['ncrtRelations']) + ); } /** - * Query NCRT of a single serving cell, all or one gNB(s) - * @param cellId cell ID - * @param ggnbid Optional parameter for the gNB ID - * @param startIndex Optional parameter for the start index - * @param limit Optional parameter for the limit (page size) - * @returns Observable of ANRNeighborCellRelation + * Modify neighbor cell relation based on Serving Cell NRCGI and Neighbor Cell NRPCI + * @param servingCellNrcgi Serving cell NRCGI + * @param neighborCellNrpci Neighbor cell NRPCI + * @param mod Values to store in the specified relation + * @returns Response code only, no data */ - getCellNcrtInfo(cellId: string, ggnbId?: string, startIndex?: string, limit?: number): Observable { - const queryParams = new HttpParams(); - if (ggnbId) { - queryParams.set('ggnbid', ggnbId); - } - if (startIndex) { - queryParams.set('startIndex', startIndex); - } - if (limit) { - queryParams.set('limit', limit.toString()); - } - return this.httpClient.get(this.basePath + this.cellPath + cellId, { params: queryParams } ); + modifyNcr(servingCellNrcgi: string, neighborCellNrpci: string, mod: ANRNeighborCellRelationMod): Observable { + const url = this.buildPath(this.ncrtPath, this.servingPath, servingCellNrcgi, this.neighborPath, neighborCellNrpci); + return this.httpClient.put(url, mod, { observe: 'response' }); } /** - * Modify neighbor cell relations based on Source Cell NR CGI and Target Cell NR PCI / NR CGI - * @param cellId cell ID - * @param table Array of ANRNeighborCellRelationMod - * @returns Observable that should yield a response code (no data) + * Deletes neighbor cell relation based on Serving Cell NRCGI and Neighbor Cell NRPCI + * @param servingCellNrcgi Serving cell NRCGI + * @param neighborCellNrpci Neighbor cell NRPCI + * @returns Response code only, no data */ - modifyNcrt(cellId: string, table: ANRNeighborCellRelationMod []): Observable { - return this.httpClient.put(this.basePath + this.cellPath + cellId, table); + deleteNcr(servingCellNrcgi: string, neighborCellNrpci: string): Observable { + const url = this.buildPath(this.ncrtPath, this.servingPath, servingCellNrcgi, this.neighborPath, neighborCellNrpci); + return this.httpClient.delete(url, { observe: 'response' }); } - /** TODO: deleteNcrt */ - } diff --git a/webapp-frontend/src/app/services/xapp-mgr/xapp-mgr.service.ts b/webapp-frontend/src/app/services/xapp-mgr/xapp-mgr.service.ts index 13ae13db..48132d22 100644 --- a/webapp-frontend/src/app/services/xapp-mgr/xapp-mgr.service.ts +++ b/webapp-frontend/src/app/services/xapp-mgr/xapp-mgr.service.ts @@ -34,7 +34,6 @@ export class XappMgrService { getAll(): Observable{ return this.httpClient.get(this.basePath) - } deployXapp(name: string) { @@ -46,4 +45,4 @@ export class XappMgrService { return this.httpClient.delete((this.basePath + '/' + name), { observe: 'response' }); } -} \ No newline at end of file +} diff --git a/webapp-frontend/src/app/xapp/xapp.component.html b/webapp-frontend/src/app/xapp/xapp.component.html deleted file mode 100644 index 5058c9d5..00000000 --- a/webapp-frontend/src/app/xapp/xapp.component.html +++ /dev/null @@ -1,77 +0,0 @@ - - -
-

Pendulum Control xApp

-

Pod ID: dc-ric-app-b8c6668d8-56bjb

-

Status: running

-
- - - -
diff --git a/webapp-frontend/src/app/xapp/xapp.component.scss b/webapp-frontend/src/app/xapp/xapp.component.scss deleted file mode 100644 index e69de29b..00000000 diff --git a/webapp-frontend/src/app/xapp/xapp.component.ts b/webapp-frontend/src/app/xapp/xapp.component.ts deleted file mode 100644 index f337b730..00000000 --- a/webapp-frontend/src/app/xapp/xapp.component.ts +++ /dev/null @@ -1,59 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2019 AT&T Intellectual Property and Nokia - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ========================LICENSE_END=================================== - */ -import { Component, Input, OnInit , Output, EventEmitter } from '@angular/core'; -import { FormControl, Validators } from '@angular/forms'; -import { ViewCell } from 'ng2-smart-table'; - -@Component({ - selector: 'app-xapp', - templateUrl: './xapp.component.html', - styleUrls: ['./xapp.component.scss'] -}) -export class XappComponent implements ViewCell, OnInit { - - public renderValue; - - @Input() value; - @Input() rowData: any; - @Output() save: EventEmitter = new EventEmitter(); - contactFormModalHelm = new FormControl('', Validators.required); - onOpened(event: any) { - console.log(event); - this.rowData = event.data; - } - - - constructor() { } - - ngOnInit() { - this.renderValue = this.value; - - } - - example() { - alert(this.renderValue); - } - - onDeployxApp() { - this.save.emit(this.rowData); - } - - -} diff --git a/xapp-mgr-client/pom.xml b/xapp-mgr-client/pom.xml index 1b37bf55..86639f48 100644 --- a/xapp-mgr-client/pom.xml +++ b/xapp-mgr-client/pom.xml @@ -25,7 +25,7 @@ limitations under the License. org.o-ran-sc.portal.ric-dashboard ric-dash-parent - 1.0.3-SNAPSHOT + 1.0.4-SNAPSHOT org.o-ran-sc.ric.xappmgr.client -- 2.16.6