RIC Dashboard Release Notes
===========================
-Version 1.0.5, 30 June 2019
+Version 1.0.5, 28 June 2019
---------------------------
* Upgrade to Angular version 8
* Upgrade to Spring-Boot 2.1.6.RELEASE
* Fixed AC xApp policy page title is not aligned
+* Update E2 manager client to spec version 20190626
+* Add configuration-driven mock of E2 getNodebIdList
Version 1.0.4, 27 June 2019
---------------------------
* Add build number to dashboard version string
* Move mock admin screen user data to backend
* Update App manager client to spec version 0.1.5
+* Move RAN connection feature to control screen
* Rework admin table
+<<<<<<< HEAD
* Update the notification service
* Remove the RAN connection invocation link from left menu and move it to control screen
+=======
+* Update the notification service
+* Move RAN connection feature to control screen
+>>>>>>> Upgrade E2 to version 20190626
* Repair deploy-app feature and use icon instead of text button
Version 1.0.3, 28 May 2019
<groupId>org.o-ran-sc.ric.plt.e2mgr.client</groupId>
<artifactId>e2-mgr-client</artifactId>
<name>RIC E2 Manager client</name>
- <version>20190620-SNAPSHOT</version>
+ <version>20190626-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<goal>generate</goal>
</goals>
<configuration>
- <inputSpec>${project.basedir}/src/main/resources/E2_Manager_API_2019-06-20.yaml</inputSpec>
+ <inputSpec>${project.basedir}/src/main/resources/E2_Manager_API_2019-06-26.yaml</inputSpec>
<language>java</language>
<packageName>${client.base.package.name}</packageName>
<modelPackage>${client.base.package.name}.model</modelPackage>
content:
application/problem+json:
schema:
- $ref: '#/components/schemas/ErrorResponse'
- '/nodeb':
+ $ref: '#/components/schemas/ErrorResponse'
+ /nodeb:
delete:
tags:
- nodeb
- summary: Close all connections to the RANs and delete the data from the nodeb-rnib DB
+ summary: >-
+ Close all connections to the RANs and delete the data from the
+ nodeb-rnib DB
responses:
'204':
description: Successful operation
content:
application/problem+json:
schema:
- $ref: '#/components/schemas/ErrorResponse'
+ $ref: '#/components/schemas/ErrorResponse'
+ /nodeb/ids:
+ get:
+ tags:
+ - nodeb
+ summary: Get RANs identities list
+ operationId: getNodebIdList
+ responses:
+ '200':
+ description: Successful operation
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/NodebIdentity'
+ '500':
+ description: Internal Error
+ content:
+ application/problem+json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
/health:
get:
tags:
format: uint16
ranName:
type: string
+ NodebIdentity:
+ properties:
+ globalNbId:
+ properties:
+ nbId:
+ type: string
+ plmnId:
+ type: string
+ type: object
+ inventoryName:
+ type: string
+ type: object
GetNodebResponse:
properties:
connectionStatus:
<dependency>
<groupId>org.o-ran-sc.ric.plt.e2mgr.client</groupId>
<artifactId>e2-mgr-client</artifactId>
- <version>20190620-SNAPSHOT</version>
+ <version>20190626-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
private final NeighborCellRelationTable ncrt, ncrtNodeB1, ncrtNodeB2, ncrtNodeB3;
private final GgNodeBTable gNodebTable;
- private static final String gnodeb1 = "GNB:001EF5:0045FE50";
- private static final String gnodeb2 = "GNB:001EF6:0045FE51";
- private static final String gnodeb3 = "GNB:001EF7:0045FE52";
+ private static final String gnodeb1 = "001EF5:0045FE50";
+ private static final String gnodeb2 = "001EF6:0045FE51";
+ private static final String gnodeb3 = "001EF7:0045FE52";
public AnrXappMockConfiguration() {
import static org.mockito.Mockito.when;
import java.lang.invoke.MethodHandles;
+import java.util.ArrayList;
+import java.util.List;
import org.oransc.ric.e2mgr.client.api.HealthCheckApi;
import org.oransc.ric.e2mgr.client.api.NodebApi;
import org.oransc.ric.e2mgr.client.invoker.ApiClient;
import org.oransc.ric.e2mgr.client.model.GetNodebResponse;
+import org.oransc.ric.e2mgr.client.model.NodebIdentity;
+import org.oransc.ric.e2mgr.client.model.NodebIdentityGlobalNbId;
import org.oransc.ric.e2mgr.client.model.SetupRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
/**
- * Creates a mock implementation of the E2 manager client API. This version
- * answers only status codes, no data, so the mock implementations are trivial.
+ * Creates a mock implementation of the E2 Manager client API.
*/
@Profile("mock")
@Configuration
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+ private final List<NodebIdentity> nodebIdList;
private final GetNodebResponse nodebResponse;
public E2ManagerMockConfiguration() {
logger.info("Configuring mock E2 Manager");
- nodebResponse = new GetNodebResponse().ip("1.2.3.4").port(123).ranName("myRan");
+ NodebIdentityGlobalNbId globalNbId = new NodebIdentityGlobalNbId().nbId("mockNbId").plmnId("mockPlmId");
+ NodebIdentity nbid = new NodebIdentity().inventoryName("mockInvName").globalNbId(globalNbId);
+ nodebIdList = new ArrayList<>();
+ nodebIdList.add(nbid);
+ nodebResponse = new GetNodebResponse().connectionStatus("mockConnectionStatus").failureType("mockFailureType")
+ .ip("1.2.3.4").nodeType("mockNodeType").port(123).ranName("mockRanName");
}
private ApiClient apiClient() {
return nodebResponse;
}).when(mockApi).getNb(any(String.class));
+ doAnswer(i -> {
+ return nodebIdList;
+ }).when(mockApi).getNodebIdList();
+
doAnswer(i -> {
return null;
}).when(mockApi).endcSetup(any(SetupRequest.class));
package org.oransc.ric.portal.dashboard.controller;
import java.lang.invoke.MethodHandles;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.ArrayList;
+import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.oransc.ric.e2mgr.client.api.HealthCheckApi;
import org.oransc.ric.e2mgr.client.api.NodebApi;
import org.oransc.ric.e2mgr.client.model.GetNodebResponse;
+import org.oransc.ric.e2mgr.client.model.NodebIdentity;
+import org.oransc.ric.e2mgr.client.model.NodebIdentityGlobalNbId;
import org.oransc.ric.e2mgr.client.model.SetupRequest;
import org.oransc.ric.portal.dashboard.DashboardApplication;
import org.oransc.ric.portal.dashboard.DashboardConstants;
-import org.oransc.ric.portal.dashboard.model.E2SetupRequestType;
-import org.oransc.ric.portal.dashboard.model.E2SetupResponse;
+import org.oransc.ric.portal.dashboard.model.ErrorTransport;
+import org.oransc.ric.portal.dashboard.model.RanDetailsTransport;
import org.oransc.ric.portal.dashboard.model.SuccessTransport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
/**
* Proxies calls from the front end to the E2 Manager API. All methods answer
- * 502 on failure: <blockquote>HTTP server received an invalid response from a
- * server it consulted when acting as a proxy or gateway.</blockquote>
+ * 502 on failure and wrap the remote details: <blockquote>HTTP server received
+ * an invalid response from a server it consulted when acting as a proxy or
+ * gateway.</blockquote>
*
- * As of this writing the E2 interface does not support get-all, so this class
- * mocks up some of that functionality.
+ * In R1 the E2 interface does not yet implement the get-ID-list method, so this
+ * class mocks up some functionality.
*/
@Configuration
@RestController
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+ private final List<NodebIdentity> mockNodebIdList;
+
// Path parameters
private static final String PP_RANNAME = "ranName";
private final HealthCheckApi e2HealthCheckApi;
private final NodebApi e2NodebApi;
- // Stores the requests and results.
- // TODO remove when the E2 manager is extended.
- private Set<E2SetupResponse> responses = new HashSet<>();
-
@Autowired
- public E2ManagerController(final HealthCheckApi e2HealthCheckApi, final NodebApi e2NodebApi) {
+ public E2ManagerController(final HealthCheckApi e2HealthCheckApi, final NodebApi e2NodebApi,
+ @Value("${e2mgr.mock.rannames:#{null}}") final String mockRanNames) {
Assert.notNull(e2HealthCheckApi, "API must not be null");
Assert.notNull(e2NodebApi, "API must not be null");
this.e2HealthCheckApi = e2HealthCheckApi;
this.e2NodebApi = e2NodebApi;
- }
-
- private void assertNotNull(Object o) {
- if (o == null)
- throw new IllegalArgumentException("Null not permitted");
- }
-
- private void assertNotEmpty(String s) {
- assertNotNull(s);
- if (s.isEmpty())
- throw new IllegalArgumentException("Empty not permitted");
+ mockNodebIdList = new ArrayList<>();
+ if (mockRanNames != null) {
+ logger.debug("ctor: Mocking RAN names: {}", mockRanNames);
+ for (String id : mockRanNames.split(",")) {
+ NodebIdentityGlobalNbId globalNbId = new NodebIdentityGlobalNbId().nbId("mockNbId").plmnId("mockPlmId");
+ mockNodebIdList.add(new NodebIdentity().globalNbId(globalNbId).inventoryName(id.trim()));
+ }
+ }
}
@ApiOperation(value = "Gets the E2 manager client library MANIFEST.MF property Implementation-Version.", response = SuccessTransport.class)
return null;
} catch (HttpStatusCodeException ex) {
logger.warn("healthGet failed: {}", ex.toString());
- return ResponseEntity.status(HttpServletResponse.SC_BAD_GATEWAY).body(ex.getResponseBodyAsString());
+ return new ResponseEntity<ErrorTransport>(new ErrorTransport(ex.getRawStatusCode(), ex.toString()),
+ HttpStatus.BAD_GATEWAY);
+ }
+ }
+
+ // This calls other methods to simplify the task of the front-end.
+ @ApiOperation(value = "Gets all RAN identities and statuses from the E2 manager.", response = RanDetailsTransport.class, responseContainer = "List")
+ @RequestMapping(value = "/ran", method = RequestMethod.GET)
+ public Object getRanDetails() {
+ logger.debug("getRanDetails");
+ List<NodebIdentity> nodebIdList = null;
+ try {
+ // TODO: remove mock when e2mgr delivers the getNodebIdList() method
+ nodebIdList = mockNodebIdList.isEmpty() ? e2NodebApi.getNodebIdList() : mockNodebIdList;
+ } catch (HttpStatusCodeException ex) {
+ logger.warn("getRanDetails: getNodebIdList failed: {}", ex.toString());
+ return new ResponseEntity<ErrorTransport>(new ErrorTransport(ex.getRawStatusCode(), ex.toString()),
+ HttpStatus.BAD_GATEWAY);
+ }
+ List<RanDetailsTransport> details = new ArrayList<>();
+ for (NodebIdentity nbid : nodebIdList) {
+ GetNodebResponse nbResp = null;
+ try {
+ // Keep looping despite failures
+ nbResp = e2NodebApi.getNb(nbid.getInventoryName());
+ } catch (HttpStatusCodeException ex) {
+ logger.warn("getRanDetails failed for name {}: {}", nbid.getInventoryName(), ex.toString());
+ nbResp = new GetNodebResponse().connectionStatus("UNKNOWN").ip("UNKNOWN").port(-1)
+ .ranName(nbid.getInventoryName());
+ }
+ details.add(new RanDetailsTransport(nbid, nbResp));
}
+ return details;
}
- // TODO replace with actual functionality
- @ApiOperation(value = "Gets the unique requests submitted to the E2 manager.", response = E2SetupResponse.class, responseContainer = "List")
- @RequestMapping(value = "/setup", method = RequestMethod.GET)
- public Iterable<E2SetupResponse> getRequests() {
- logger.debug("getRequests");
- return responses;
+ @ApiOperation(value = "Get RAN identities list.", response = NodebIdentity.class, responseContainer = "List")
+ @RequestMapping(value = "/nodeb/id", method = RequestMethod.GET)
+ public Object getNodebIdList() {
+ logger.debug("getNodebIdList");
+ try {
+ return e2NodebApi.getNodebIdList();
+ } catch (HttpStatusCodeException ex) {
+ logger.warn("getNodebIdList failed: {}", ex.toString());
+ return new ResponseEntity<ErrorTransport>(new ErrorTransport(ex.getRawStatusCode(), ex.toString()),
+ HttpStatus.BAD_GATEWAY);
+ }
}
@ApiOperation(value = "Get RAN by name.", response = GetNodebResponse.class)
return e2NodebApi.getNb(ranName);
} catch (HttpStatusCodeException ex) {
logger.warn("getNb failed: {}", ex.toString());
- return ResponseEntity.status(HttpServletResponse.SC_BAD_GATEWAY).body(ex.getResponseBodyAsString());
+ return new ResponseEntity<ErrorTransport>(new ErrorTransport(ex.getRawStatusCode(), ex.toString()),
+ HttpStatus.BAD_GATEWAY);
}
}
@ApiOperation(value = "Close all connections to the RANs and delete the data from the nodeb-rnib DB.")
@RequestMapping(value = "/nodeb", method = RequestMethod.DELETE)
- public void nodebDelete() {
+ public Object nodebDelete(HttpServletResponse response) {
logger.debug("nodebDelete");
- e2NodebApi.nodebDelete();
- // TODO: remove this mock functionality
- responses.clear();
+ try {
+ e2NodebApi.nodebDelete();
+ response.setStatus(e2NodebApi.getApiClient().getStatusCode().value());
+ return null;
+ } catch (HttpStatusCodeException ex) {
+ logger.warn("nodebDelete failed: {}", ex.toString());
+ return new ResponseEntity<ErrorTransport>(new ErrorTransport(ex.getRawStatusCode(), ex.toString()),
+ HttpStatus.BAD_GATEWAY);
+ }
}
- @ApiOperation(value = "Sets up an EN-DC RAN connection via the E2 manager.", response = E2SetupResponse.class)
+ @ApiOperation(value = "Sets up an EN-DC RAN connection via the E2 manager.")
@RequestMapping(value = "/endcSetup", method = RequestMethod.POST)
- public Object endcSetup(@RequestBody SetupRequest setupRequest) {
+ public Object endcSetup(@RequestBody SetupRequest setupRequest, HttpServletResponse response) {
logger.debug("endcSetup {}", setupRequest);
- try {
- assertNotEmpty(setupRequest.getRanIp());
- assertNotEmpty(setupRequest.getRanName());
- assertNotNull(setupRequest.getRanPort());
- } catch (Exception ex) {
- return new E2SetupResponse(E2SetupRequestType.ENDC, setupRequest, HttpServletResponse.SC_BAD_REQUEST);
- }
try {
e2NodebApi.endcSetup(setupRequest);
- E2SetupResponse r = new E2SetupResponse(E2SetupRequestType.ENDC, setupRequest,
- e2NodebApi.getApiClient().getStatusCode().value());
- responses.add(r);
- return r;
+ response.setStatus(e2NodebApi.getApiClient().getStatusCode().value());
+ return null;
} catch (HttpStatusCodeException ex) {
logger.warn("endcSetup failed: {}", ex.toString());
- return ResponseEntity.status(HttpServletResponse.SC_BAD_GATEWAY).body(ex.getResponseBodyAsString());
+ return new ResponseEntity<ErrorTransport>(new ErrorTransport(ex.getRawStatusCode(), ex.toString()),
+ HttpStatus.BAD_GATEWAY);
}
}
- @ApiOperation(value = "Sets up an X2 RAN connection via the E2 manager.", response = E2SetupResponse.class)
+ @ApiOperation(value = "Sets up an X2 RAN connection via the E2 manager.")
@RequestMapping(value = "/x2Setup", method = RequestMethod.POST)
- public Object x2Setup(@RequestBody SetupRequest setupRequest) {
+ public Object x2Setup(@RequestBody SetupRequest setupRequest, HttpServletResponse response) {
logger.debug("x2Setup {}", setupRequest);
- try {
- assertNotEmpty(setupRequest.getRanIp());
- assertNotEmpty(setupRequest.getRanName());
- assertNotNull(setupRequest.getRanPort());
- } catch (Exception ex) {
- return new E2SetupResponse(E2SetupRequestType.ENDC, setupRequest, HttpServletResponse.SC_BAD_REQUEST);
- }
try {
e2NodebApi.x2Setup(setupRequest);
- E2SetupResponse r = new E2SetupResponse(E2SetupRequestType.X2, setupRequest,
- e2NodebApi.getApiClient().getStatusCode().value());
- responses.add(r);
- return r;
+ response.setStatus(e2NodebApi.getApiClient().getStatusCode().value());
+ return null;
} catch (HttpStatusCodeException ex) {
logger.warn("x2Setup failed: {}", ex.toString());
- return ResponseEntity.status(HttpServletResponse.SC_BAD_GATEWAY).body(ex.getResponseBodyAsString());
+ return new ResponseEntity<ErrorTransport>(new ErrorTransport(ex.getRawStatusCode(), ex.toString()),
+ HttpStatus.BAD_GATEWAY);
}
}
+++ /dev/null
-/*-
- * ========================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===================================
- */
-package org.oransc.ric.portal.dashboard.model;
-
-import java.time.Instant;
-
-import org.oransc.ric.e2mgr.client.model.SetupRequest;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-/**
- * Response to an E2 Manager setupRequest message carries the original
- * information plus request type, timestamp and HTTP response code.
- */
-public class E2SetupResponse extends SetupRequest implements IDashboardResponse {
-
- public E2SetupResponse() {
- }
-
- public E2SetupResponse(E2SetupRequestType type, SetupRequest request, int responseCode) {
- super.ranName(request.getRanName()).ranIp(request.getRanIp()).ranPort(request.getRanPort());
- this.requestType = type;
- this.timeStamp = Instant.now();
- this.responseCode = responseCode;
- }
-
- @JsonProperty("requestType")
- private E2SetupRequestType requestType = null;
-
- public SetupRequest requestType(E2SetupRequestType type) {
- this.requestType = type;
- return this;
- }
-
- /**
- * Get requestType
- *
- * @return requestType
- **/
- public E2SetupRequestType getRequestType() {
- return requestType;
- }
-
- public void setRequestType(E2SetupRequestType type) {
- this.requestType = type;
- }
-
- @JsonProperty("timeStamp")
- private Instant timeStamp = null;
-
- public SetupRequest timeStamp(Instant timeStamp) {
- this.timeStamp = timeStamp;
- return this;
- }
-
- /**
- * Get timeStamp
- *
- * @return timeStamp
- **/
- public Instant getTimeStamp() {
- return timeStamp;
- }
-
- public void setTimeStamp(Instant timeStamp) {
- this.timeStamp = timeStamp;
- }
-
- @JsonProperty("responseCode")
- private Integer responseCode = null;
-
- public SetupRequest responseCode(Integer responseCode) {
- this.responseCode = responseCode;
- return this;
- }
-
- /**
- * Get responseCode
- *
- * @return responseCode
- **/
- public Integer getResponseCode() {
- return responseCode;
- }
-
- public void setResponseCode(Integer responseCode) {
- this.responseCode = responseCode;
- }
-
-}
--- /dev/null
+/*-
+ * ========================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===================================
+ */
+
+package org.oransc.ric.portal.dashboard.model;
+
+import org.oransc.ric.e2mgr.client.model.GetNodebResponse;
+import org.oransc.ric.e2mgr.client.model.NodebIdentity;
+
+public class RanDetailsTransport {
+
+ private NodebIdentity nodebIdentity;
+ private GetNodebResponse nodebStatus;
+
+ public RanDetailsTransport() {
+ }
+
+ public RanDetailsTransport(NodebIdentity nodebIdentity, GetNodebResponse nodebResponse) {
+ this.nodebIdentity = nodebIdentity;
+ this.nodebStatus = nodebResponse;
+ }
+
+ public NodebIdentity getNodebIdentity() {
+ return nodebIdentity;
+ }
+
+ public void setNodebIdentity(NodebIdentity nodebIdentity) {
+ this.nodebIdentity = nodebIdentity;
+ }
+
+ public GetNodebResponse getNodebStatus() {
+ return nodebStatus;
+ }
+
+ public void setNodebStatus(GetNodebResponse nodebStatus) {
+ this.nodebStatus = nodebStatus;
+ }
+
+ public RanDetailsTransport nodebIdentity(NodebIdentity n) {
+ this.nodebIdentity = n;
+ return this;
+ }
+
+ public RanDetailsTransport nodebStatus(GetNodebResponse s) {
+ this.nodebStatus = s;
+ return this;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((nodebIdentity == null) ? 0 : nodebIdentity.hashCode());
+ result = prime * result + ((nodebStatus == null) ? 0 : nodebStatus.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ RanDetailsTransport other = (RanDetailsTransport) obj;
+ if (nodebIdentity == null) {
+ if (other.nodebIdentity != null)
+ return false;
+ } else if (!nodebIdentity.equals(other.nodebIdentity))
+ return false;
+ if (nodebStatus == null) {
+ if (other.nodebStatus != null)
+ return false;
+ } else if (!nodebStatus.equals(other.nodebStatus))
+ return false;
+ return true;
+ }
+
+}
# E2 Manager
e2mgr.url = http://jar-app-props-default-E2-URL
+# Supply CSV to mock the get-list API for testing e2mgr in R1;
+# missing key or empty value disables the mock behavior
+# e2mgr.mock.rannames = RANONE, RANTWO
# Xapp Manager
xappmgr.url = http://jar-app-props-default-Xapp-Mgr-URL
errorCode: string;
errorMessage: string;
}
+
+export interface E2NodebIdentityGlobalNbId {
+ nbId: string;
+ plmnId: string;
+}
+
+export interface E2NodebIdentity {
+ inventoryName: string;
+ globalNbId: E2NodebIdentityGlobalNbId;
+}
+
+export interface E2GetNodebResponse {
+ connectionStatus: string; // actually one-of, but model as string
+ enb: object; // don't model this until needed
+ failureType: string; // actually one-of, butmodel as string
+ gnb: object; // don't model this until needed
+ ip: string;
+ nodeType: object; // actually one-of, but model as string
+ port: number; // actually integer
+ ranName: string;
+ setupFailure: object; // don't model this until needed
+}
+
+export interface E2RanDetails {
+ nodebIdentity: E2NodebIdentity;
+ nodebStatus: E2GetNodebResponse;
+}
display: block;
}
+/* leave a bit of space */
+.ran-type-radio-button {
+ margin-left: 5px;
+}
<div mat-dialog-content>
<div name="rantype">
<label id="request-type-radio-group-label">RAN type:</label>
- <mat-radio-group aria-label="RAN type" formControlName="ranType">
- <mat-radio-button value="endc">EN-DC</mat-radio-button>
- <mat-radio-button value="x2">X2</mat-radio-button>
+ <mat-radio-group aria-label="RAN Type" formControlName="ranType">
+ <mat-radio-button class="ran-type-radio-button" value="endc">EN-DC</mat-radio-button>
+ <mat-radio-button class="ran-type-radio-button" value="x2">X2</mat-radio-button>
</mat-radio-group>
</div>
<mat-form-field class="input-display-block">
- <input matInput type="text" placeholder="eNB/gNB Name" formControlName="ranName">
+ <input matInput type="text" placeholder="RAN Name" formControlName="ranName">
<mat-hint align="end">Example: ABCD123456</mat-hint>
<mat-error *ngIf="validateControl('ranName') && hasError('ranName', 'required')">Name is required</mat-error>
<mat-error *ngIf="hasError('ranName', 'length')">Valid name is required</mat-error>
<table mat-table class="ran-control-table mat-elevation-z8" [dataSource]="dataSource">
- <ng-container matColumnDef="requestType">
- <mat-header-cell *matHeaderCellDef>RAN Type</mat-header-cell>
- <mat-cell *matCellDef="let rconnect">{{rconnect.requestType}}</mat-cell>
+ <ng-container matColumnDef="nbId">
+ <mat-header-cell *matHeaderCellDef>Nodeb ID</mat-header-cell>
+ <mat-cell *matCellDef="let ran">{{ran.nodebIdentity.globalNbId.nbId}}</mat-cell>
+ </ng-container>
+
+ <ng-container matColumnDef="nodeType">
+ <mat-header-cell *matHeaderCellDef>Node Type</mat-header-cell>
+ <mat-cell *matCellDef="let ran">{{ran.nodebStatus.nodeType}}</mat-cell>
</ng-container>
<ng-container matColumnDef="ranName">
- <mat-header-cell *matHeaderCellDef>eNodeB/gNodeB Name</mat-header-cell>
- <mat-cell *matCellDef="let rconnect">{{rconnect.ranName}}</mat-cell>
+ <mat-header-cell *matHeaderCellDef>RAN Name</mat-header-cell>
+ <mat-cell *matCellDef="let ran">{{ran.nodebIdentity.inventoryName}}</mat-cell>
</ng-container>
<ng-container matColumnDef="ranIp">
<mat-header-cell *matHeaderCellDef>IP</mat-header-cell>
- <mat-cell *matCellDef="let rconnect">{{rconnect.ranIp}}</mat-cell>
+ <mat-cell *matCellDef="let ran">{{ran.nodebStatus.ip}}</mat-cell>
</ng-container>
<ng-container matColumnDef="ranPort">
<mat-header-cell *matHeaderCellDef>Port</mat-header-cell>
- <mat-cell *matCellDef="let rconnect">{{rconnect.ranPort}}</mat-cell>
- </ng-container>
-
- <ng-container matColumnDef="responseCode">
- <mat-header-cell *matHeaderCellDef>Response</mat-header-cell>
- <mat-cell *matCellDef="let rconnect">{{rconnect.responseCode}}</mat-cell>
+ <mat-cell *matCellDef="let ran">{{ran.nodebStatus.port}}</mat-cell>
</ng-container>
- <ng-container matColumnDef="timeStamp">
- <mat-header-cell *matHeaderCellDef>Time Stamp</mat-header-cell>
- <mat-cell *matCellDef="let rconnect">{{rconnect.timeStamp}}</mat-cell>
+ <ng-container matColumnDef="connectionStatus">
+ <mat-header-cell *matHeaderCellDef>Connection Status</mat-header-cell>
+ <mat-cell *matCellDef="let ran">{{ran.nodebStatus.connectionStatus}}</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
.disconnect-all-button {
float: right;
-}
\ No newline at end of file
+}
+
+.version__text {
+ color: gray;
+ letter-spacing: 0.1rem;
+ font-size: 10px;
+}
styleUrls: ['./ran-control.component.scss']
})
export class RanControlComponent implements OnInit {
- displayedColumns: string[] = ['requestType', 'ranName', 'ranIp', 'ranPort', 'responseCode', 'timeStamp'];
+ displayedColumns: string[] = ['nbId', 'nodeType', 'ranName', 'ranIp', 'ranPort', 'connectionStatus'];
dataSource: RANControlDataSource;
constructor(private e2MgrSvc: E2ManagerService,
import { catchError, finalize } from 'rxjs/operators';
import { of } from 'rxjs/observable/of';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
-import { E2SetupRequest } from '../interfaces/e2-mgr.types';
+import { E2RanDetails, E2SetupRequest } from '../interfaces/e2-mgr.types';
import { E2ManagerService } from '../services/e2-mgr/e2-mgr.service';
-export class RANControlDataSource extends DataSource<E2SetupRequest> {
+export class RANControlDataSource extends DataSource<E2RanDetails> {
- private ranControlSubject = new BehaviorSubject<E2SetupRequest[]>([]);
+ private ranControlSubject = new BehaviorSubject<E2RanDetails[]>([]);
private loadingSubject = new BehaviorSubject<boolean>(false);
loadTable() {
this.loadingSubject.next(true);
- this.e2MgrSvcservice.getAll()
+ this.e2MgrSvcservice.getRan()
.pipe(
catchError(() => of([])),
finalize(() => this.loadingSubject.next(false))
)
- .subscribe((ranControl: E2SetupRequest[]) => this.ranControlSubject.next(ranControl));
+ .subscribe((ranControl: E2RanDetails[]) => this.ranControlSubject.next(ranControl));
}
- connect(collectionViewer: CollectionViewer): Observable<E2SetupRequest[]> {
+ connect(collectionViewer: CollectionViewer): Observable<E2RanDetails[]> {
return this.ranControlSubject.asObservable();
}
* ========================LICENSE_END===================================
*/
import { Injectable } from '@angular/core';
-import { HttpClient } from '@angular/common/http';
-import { E2SetupRequest } from '../../interfaces/e2-mgr.types';
+import { HttpClient, HttpResponse } from '@angular/common/http';
+import { Observable } from 'rxjs';
+import { map } from 'rxjs/operators';
+import { E2RanDetails, E2SetupRequest } from '../../interfaces/e2-mgr.types';
+import { DashboardSuccessTransport } from '../../interfaces/dashboard.types';
@Injectable({
providedIn: 'root'
}
/**
- * Gets E2 manager client version details
- * @returns Observable that should yield a DashboardSuccessTransport object
+ * Gets E2 client version details
+ * @returns Observable that should yield a String
*/
- getE2ManagerVersion() {
- return this.httpClient.get(this.basePath + 'version');
+ getVersion(): Observable<string> {
+ const url = this.basePath + 'version';
+ return this.httpClient.get<DashboardSuccessTransport>(url).pipe(
+ // Extract the string here
+ map(res => res['data'])
+ );
}
/**
- * Gets setup request history
+ * Gets RAN details
* @returns Observable that should yield an array of objects
*/
- getAll() {
- return this.httpClient.get(this.basePath + 'setup');
+ getRan(): Observable<Array<E2RanDetails>> {
+ return this.httpClient.get<Array<E2RanDetails>>(this.basePath + 'ran');
}
/**
* Sends a request to setup an ENDC/gNodeB connection
- * @returns Observable
+ * @returns Observable. On success there is no data, only a code.
*/
- endcSetup(req: E2SetupRequest) {
- return this.httpClient.post(this.basePath + 'endcSetup', req);
+ endcSetup(req: E2SetupRequest): Observable<HttpResponse<Object>> {
+ return this.httpClient.post(this.basePath + 'endcSetup', req, { observe: 'response' });
}
/**
* Sends a request to setup an X2/eNodeB connection
- * @returns Observable
+ * @returns Observable. On success there is no data, only a code.
*/
- x2Setup(req: E2SetupRequest) {
- return this.httpClient.post(this.basePath + 'x2Setup', req);
+ x2Setup(req: E2SetupRequest): Observable<HttpResponse<Object>> {
+ return this.httpClient.post(this.basePath + 'x2Setup', req, { observe: 'response' });
}
/**
* Sends a request to drop all RAN connections
- * @returns Observable
+ * @returns Observable. Response code indicates result.
*/
- nodebDelete() {
+ nodebDelete(): Observable<HttpResponse<Object>> {
return this.httpClient.delete((this.basePath + 'nodeb'), { observe: 'response' });
}