Upgrade ANR spec to version 0.0.4.
Drop the A1 Mediation Controller for pendulum demo.
Add footer with version info.
Add get-version endpoints for clients.
Change-Id: Ie45d412b8f126853fa59d74bb50e74fdecd94688
Signed-off-by: Lott, Christopher (cl778h) <cl778h@att.com>
<parent>
<groupId>org.o-ran-sc.portal.ric-dashboard</groupId>
<artifactId>ric-dash-parent</artifactId>
- <version>1.0.2-SNAPSHOT</version>
+ <version>1.0.3-SNAPSHOT</version>
</parent>
<!-- This groupId will NOT allow deployment in LF -->
<groupId>org.o-ran-sc.ric.a1med.client</groupId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <!-- Jenkins invokes maven with -Dbuild.number=.. -->
+ <build.number>0</build.number>
+ <!-- same as groupId BUT without hyphens -->
<client.base.package.name>org.oransc.ric.a1med.client</client.base.package.name>
</properties>
<!-- Successful compilation requires generated code dependencies -->
</execution>
</executions>
</plugin>
+ <!-- add build information to manifest. Java provides access to the implementation
+ version for a package, so cram the build number into there. -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <!-- version>2.5</version> -->
+ <configuration>
+ <archive>
+ <manifest>
+ <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+ </manifest>
+ <manifestEntries>
+ <Implementation-Version>${project.version}-b${build.number}</Implementation-Version>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
<!-- Skip the deploy-jar-to-nexus step -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<parent>
<groupId>org.o-ran-sc.portal.ric-dashboard</groupId>
<artifactId>ric-dash-parent</artifactId>
- <version>1.0.2-SNAPSHOT</version>
+ <version>1.0.3-SNAPSHOT</version>
</parent>
<!-- This groupId will NOT allow deployment in LF -->
<groupId>org.o-ran-sc.ric.anrxapp.client</groupId>
<artifactId>anr-xapp-client</artifactId>
<name>RIC ANR xApp client</name>
- <version>0.0.3-SNAPSHOT</version>
+ <version>0.0.4-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <!-- Jenkins invokes maven with -Dbuild.number=.. -->
+ <build.number>0</build.number>
<!-- same as groupId BUT without hyphens -->
<client.base.package.name>org.oransc.ric.anrxapp.client</client.base.package.name>
</properties>
<goal>generate</goal>
</goals>
<configuration>
- <inputSpec>${project.basedir}/src/main/resources/anr_swagger_0.0.3.yaml</inputSpec>
+ <inputSpec>${project.basedir}/src/main/resources/anr_swagger_0.0.4.yaml</inputSpec>
<language>java</language>
<configOptions>
<groupId>${project.groupId}</groupId>
</execution>
</executions>
</plugin>
+ <!-- add build information to manifest. Java provides access to the implementation
+ version for a package, so cram the build number into there. -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <!-- version>2.5</version> -->
+ <configuration>
+ <archive>
+ <manifest>
+ <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+ </manifest>
+ <manifestEntries>
+ <Implementation-Version>${project.version}-b${build.number}</Implementation-Version>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
<!-- Skip the deploy-jar-to-nexus step -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
</goals>
</pluginExecutionFilter>
<action>
- <ignore/>
+ <ignore />
</action>
</pluginExecution>
</pluginExecutions>
swagger : '2.0'
info :
description : REST API specification for RIC ANR closed xAPP
- version : 0.0.3
+ version : 0.0.4
title : RIC ANR
license:
name : Nokia Closed App
/health/alive :
get :
summary : Health check of ANR - Liveness probe
- tags :
+ tags :
- health
operationId : getHealthAlive
responses :
/health/ready :
get :
summary : Health check of ANR - Readiness probe
- tags :
+ tags :
- health
operationId : getHealthReady
responses :
- $ref : '#/parameters/limit'
get :
summary : Returns neighbor cell relation table for all gnodeBs or based on query string
- tags :
+ tags :
- ncrt
operationId : getNcrtInfo
produces :
/ncrt/cell/{cellIdentifier} :
parameters :
- $ref : '#/parameters/cellIdentifier'
- - $ref : '#/parameters/startIndex'
- - $ref : '#/parameters/limit'
- - $ref : '#/parameters/neighborCellIdentifierNrpci'
- - $ref : '#/parameters/neighborCellIdentifierNrcgi'
+ - $ref : '#/parameters/neighborCellNrpci'
+ - $ref : '#/parameters/neighborCellNrcgi'
get :
summary : Returns neighbor cell relation table for a Source Cell (NR CGI) and optionally a neighbor cell based on query string
- tags :
+ tags :
- ncrt
operationId : getCellNcrtInfo
produces :
- application/json
+ parameters :
+ - $ref : '#/parameters/startIndex'
+ - $ref : '#/parameters/limit'
responses :
'200' :
description : successful operation
schema :
$ref : '#/definitions/neighborCellRelationTable'
'400' :
- description : Non-existant identifier {cellIdentifier | neighborCellIdentifierNrpci | neighborCellIdentifierNrcgi} in request
+ description : Non-existant identifier {cellIdentifier | neighborCellNrpci | neighborCellNrcgi} in request
put :
summary : Modify neighbor cell relation based on Source Cell NR CGI and Target Cell NR PCI / NR CGI
- tags :
+ tags :
- ncrt
- operationId : modifyNCRT
+ operationId : modifyNcrt
consumes :
- application/json
produces :
- application/json
parameters :
- - name : NCRTModificationParameters
+ - name : NcrtModificationParameters
in : body
description : Parameters to modify neighbor cell relation
required : true
description : Successfully modified neighbor cell relation
'400' :
description : Modification failed.
- { Identifier neighborCellIdentifierNrpci / neighborCellIdentifierNrcgi not provided |
- Non-existant identifier {cellIdentifier | neighborCellIdentifierNrpci | neighborCellIdentifierNrcgi} in request |
+ { Identifier neighborCellNrpci / neighborCellNrcgi not provided |
+ Non-existant identifier {cellIdentifier | neighborCellNrpci | neighborCellNrcgi} in request |
Invalid data in body
}
delete :
summary : Delete neighbor cell relation based on Source Cell NR CGI and Target Cell NR PCI / NR CGI
- tags :
+ tags :
- ncrt
operationId : deleteNcrt
parameters :
- - name : NCRTDeletionParameters
+ - name : NcrtDeletionParameters
in : body
description : Parameters to delete neighbor cell relation
required : true
schema :
- $ref : '#/definitions/neighborCellRelationDelTable'
+ $ref : '#/definitions/neighborCellRelationDelTable'
responses :
'204' :
description : Successfully deleted neighbor cell relation
'400' :
description : Deletion failed.
- { Identifier neighborCellIdentifierNrpci / neighborCellIdentifierNrcgi not provided |
- Non-existant identifier {cellIdentifier | neighborCellIdentifierNrpci | neighborCellIdentifierNrcgi} in request
+ { Identifier neighborCellNrpci / neighborCellNrcgi not provided |
+ Non-existant identifier {cellIdentifier | neighborCellNrpci | neighborCellNrcgi} in request
}
parameters :
ggnbId :
description : Source Cell Identifier (NR CGI)
in : path
required : true
- neighborCellIdentifierNrpci :
+ neighborCellNrpci :
type : string
- name : neighborCellIdentifierNrpci
+ name : neighborCellNrpci
description : Neighbor Cell Identifier (NR PCI)
in : query
- neighborCellIdentifierNrcgi :
+ neighborCellNrcgi :
type : string
- name : neighborCellIdentifierNrcgi
+ name : neighborCellNrcgi
description : Neigbhor Cell Identifier (NR CGI)
in : query
definitions :
neighborCellRelationTable :
type : object
- properties :
- ncrtRelations :
+ properties :
+ ncrtRelations :
type : array
items :
$ref : '#/definitions/neighborCellRelation'
$ref : '#/definitions/neighborCellRelationMod'
neighborCellRelationDelTable :
type : array
- items :
+ items :
$ref : '#/definitions/neighborCellRelationDel'
neighborCellRelation :
type : object
- required :
+ required :
- cellIdentifierNrcgi
- - neighborCellIdentifierNrpci
- - neighborCellIdentifierNrcgi
+ - neighborCellNrpci
+ - neighborCellNrcgi
- flagNoHo
- flagNoXn
- flagNoRemove
type : string
description : Source / Serving Cell Identifier (NR CGI)
example : E12345
- neighborCellIdentifierNrpci :
+ neighborCellNrpci :
type : string
description : Neighbor Cell Identifier (NR PCI)
example : E12345
- neighborCellIdentifierNrcgi :
+ neighborCellNrcgi :
type : string
description : Neighbor Cell Identifier (NR CGI)
example : E12345
- nrpciToNrcgiMapping
- flagUpdates
- nrcgiMappingAndFlagUpdates
- neighborCellIdentifierNrpci :
+ neighborCellNrpci :
type : string
description : Neighbor Cell Identifier (NR PCI)
example : E12345
- neighborCellIdentifierNrcgi :
+ neighborCellNrcgi :
type : string
description : Neighbor Cell Identifier (NR CGI)
example : E12345
enum :
- nrpci
- nrcgi
- neighborCellIdentifierNrpci :
+ neighborCellNrpci :
type : string
description : Neighbor Cell Identifier (NR PCI)
example : E12345
- neighborCellIdentifierNrcgi :
+ neighborCellNrcgi :
type : string
description : Neighbor Cell Identifier (NR PCI)
example : E12345
RIC Dashboard Release Notes
===========================
+Version 1.0.3, 15 May 2019
+--------------------------
+* Add AC xapp controller
+* Add RAN type radio selector to connection setup
+* Update ANR xApp client to spec version 0.0.4
+* Add get-version methods to all controllers
+* Add simple page footer with copyright and version
+
Version 1.0.2, 13 May 2019
--------------------------
* Update A1 mediator client to version 0.4.0
<parent>
<groupId>org.o-ran-sc.portal.ric-dashboard</groupId>
<artifactId>ric-dash-parent</artifactId>
- <version>1.0.2-SNAPSHOT</version>
+ <version>1.0.3-SNAPSHOT</version>
</parent>
<!-- This groupId will NOT allow deployment in LF -->
<groupId>org.o-ran-sc.ric.e2mgr.client</groupId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <!-- Jenkins invokes maven with -Dbuild.number=.. -->
+ <build.number>0</build.number>
+ <!-- same as groupId BUT without hyphens -->
<client.base.package.name>org.oransc.ric.e2mgr.client</client.base.package.name>
</properties>
<!-- Successful compilation requires generated code dependencies -->
</execution>
</executions>
</plugin>
+ <!-- add build information to manifest. Java provides access to the implementation
+ version for a package, so cram the build number into there. -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <!-- version>2.5</version> -->
+ <configuration>
+ <archive>
+ <manifest>
+ <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+ </manifest>
+ <manifestEntries>
+ <Implementation-Version>${project.version}-b${build.number}</Implementation-Version>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
<!-- Skip the deploy-jar-to-nexus step -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>ric-dash-parent</artifactId>
<name>RIC Dashboard project</name>
<packaging>pom</packaging>
- <version>1.0.2-SNAPSHOT</version>
+ <version>1.0.3-SNAPSHOT</version>
<!-- Properties for the license-maven-plugin in child POMs -->
<properties>
<lmp.organization.name>AT&T Intellectual Property and Nokia</lmp.organization.name>
<parent>
<groupId>org.o-ran-sc.portal.ric-dashboard</groupId>
<artifactId>ric-dash-parent</artifactId>
- <version>1.0.2-SNAPSHOT</version>
+ <version>1.0.3-SNAPSHOT</version>
</parent>
<artifactId>ric-dash-be</artifactId>
<name>RIC Dashboard Webapp backend</name>
<dependency>
<groupId>org.o-ran-sc.ric.anrxapp.client</groupId>
<artifactId>anr-xapp-client</artifactId>
- <version>0.0.3-SNAPSHOT</version>
+ <version>0.0.4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.o-ran-sc.ric.e2mgr.client</groupId>
public static void main(String[] args) {
SpringApplication.run(DashboardApplication.class, args);
// Force this onto the console by using level WARN
- logger.warn("main: version '{}' successful start", getVersion());
+ logger.warn("main: version '{}' successful start", getImplementationVersion(MethodHandles.lookup().lookupClass()));
}
/**
- * Gets version details.
+ * Gets version details for the specified class.
+ *
+ * @param clazz
+ * Class to get the version
*
* @return the value of the MANIFEST.MF property Implementation-Version as
* written by maven when packaged in a jar; 'unknown' otherwise.
*/
- private static String getVersion() {
- Class<?> clazz = MethodHandles.lookup().lookupClass();
+ public static String getImplementationVersion(Class<?> clazz) {
String classPath = clazz.getResource(clazz.getSimpleName() + ".class").toString();
- return classPath.startsWith("jar") ? clazz.getPackage().getImplementationVersion() : "unknown";
+ return classPath.startsWith("jar") ? clazz.getPackage().getImplementationVersion() : "unknown-not-jar";
}
}
}
public static final String ENDPOINT_PREFIX = "/api/";
+ public static final String HEALTHCHECK_PATH = "health";
+ public static final String VERSION_PATH = "version";
+
}
NcrtApi mockApi = mock(NcrtApi.class);
when(mockApi.getApiClient()).thenReturn(apiClient);
- NeighborCellRelation a = new NeighborCellRelation().cellIdentifierNrcgi("A12345")
- .neighborCellIdentifierNrpci("A123456").neighborCellIdentifierNrcgi("A12347").flagNoHo(true)
- .flagNoXn(true).flagNoRemove(true);
- NeighborCellRelation e = new NeighborCellRelation().cellIdentifierNrcgi("E12345")
- .neighborCellIdentifierNrpci("E123456").neighborCellIdentifierNrcgi("E12347").flagNoHo(true)
- .flagNoXn(true).flagNoRemove(true);
+ NeighborCellRelation a = new NeighborCellRelation().cellIdentifierNrcgi("A12345").neighborCellNrpci("A123456")
+ .neighborCellNrcgi("A12347").flagNoHo(true).flagNoXn(true).flagNoRemove(true);
+ NeighborCellRelation e = new NeighborCellRelation().cellIdentifierNrcgi("E12345").neighborCellNrpci("E123456")
+ .neighborCellNrcgi("E12347").flagNoHo(true).flagNoXn(true).flagNoRemove(true);
NeighborCellRelationTable ncrt = new NeighborCellRelationTable().addNcrtRelationsItem(a)
.addNcrtRelationsItem(e);
when(mockApi.getNcrtInfo(any(String.class), any(String.class), any(Integer.class))).thenReturn(ncrt);
- when(mockApi.getCellNcrtInfo(any(String.class), any(String.class), any(Integer.class), any(String.class),
- any(String.class))).thenReturn(ncrt);
+ when(mockApi.getCellNcrtInfo(any(String.class), any(String.class), any(String.class), any(String.class),
+ any(Integer.class))).thenReturn(ncrt);
doAnswer(i -> {
return null;
}).when(mockApi).deleteNcrt(any(String.class), any(NeighborCellRelationDelTable.class), any(String.class),
- any(Integer.class), any(String.class), any(String.class));
+ any(String.class));
doAnswer(i -> {
return null;
- }).when(mockApi).modifyNCRT(any(String.class), any(NeighborCellRelationModTable.class), any(String.class),
- any(Integer.class), any(String.class), any(String.class));
+ }).when(mockApi).modifyNcrt(any(String.class), any(NeighborCellRelationModTable.class), any(String.class),
+ any(String.class));
return mockApi;
}
+++ /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.controller;
-
-import java.lang.invoke.MethodHandles;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URL;
-
-import javax.servlet.http.HttpServletResponse;
-
-import org.oransc.ric.portal.dashboard.DashboardConstants;
-import org.oransc.ric.portal.dashboard.model.DelayTransport;
-import org.oransc.ric.portal.dashboard.model.ErrorTransport;
-import org.oransc.ric.portal.dashboard.model.IDashboardResponse;
-import org.oransc.ric.portal.dashboard.model.LoadTransport;
-import org.oransc.ric.portal.dashboard.model.MetricsTransport;
-import org.oransc.ric.portal.dashboard.model.PathTransport;
-import org.oransc.ric.portal.dashboard.model.SuccessTransport;
-import org.oransc.ric.portal.dashboard.model.UrlTransport;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.ParameterizedTypeReference;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.client.RestTemplate;
-import org.springframework.web.util.UriComponentsBuilder;
-
-import io.swagger.annotations.ApiOperation;
-
-/**
- * Provides endpoints to get/set paths, AND to access the REST resources at
- * those paths. This allows very late binding of deployment details.
- */
-@Configuration
-@RestController
-@RequestMapping(value = DashboardConstants.ENDPOINT_PREFIX + "/a1med", produces = MediaType.APPLICATION_JSON_VALUE)
-public class A1MediationController {
-
- private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- private static final String A1_MEDIATION_URL = "url";
- private static final String A1_MEDIATION_DELAY = "delay";
- private static final String A1_MEDIATION_DELAY_PATH = A1_MEDIATION_DELAY + "path";
- private static final String A1_MEDIATION_LOAD = "load";
- private static final String A1_MEDIATION_LOAD_PATH = A1_MEDIATION_LOAD + "path";
- private static final String A1_MEDIATION_METRICS = "metrics";
- private static final String A1_MEDIATION_METRICS_PATH = A1_MEDIATION_METRICS + "path";
-
- @Value("${a1med.basepath}")
- private String a1MediationUrl;
- @Value("${a1med.delaypath}")
- private String a1MediationDelayPath;
- @Value("${a1med.loadpath}")
- private String a1MediationLoadPath;
- @Value("${a1med.metricspath}")
- private String a1MediationMetricsPath;
-
- // For demo purposes
- private final boolean mockData = true;
- private final DelayTransport mockDelay = new DelayTransport(10);
- private final LoadTransport mockLoad = new LoadTransport(1);
- private final MetricsTransport mockMetrics = new MetricsTransport(11, 100, 123);
-
- private final RestTemplate restTemplate = new RestTemplate();
-
- private URI buildUri(final String baseUrl, final String[] paths) {
- UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(baseUrl);
- for (int p = 0; p < paths.length; ++p) {
- if (paths[p] == null)
- throw new IllegalArgumentException("Unexpected null at index " + Integer.toString(p));
- // this allows slashes
- builder.path(paths[p]);
- }
- return builder.build().encode().toUri();
- }
-
- @ApiOperation(value = "Gets the A1 Mediation URL.", response = IDashboardResponse.class)
- @RequestMapping(value = A1_MEDIATION_URL, method = RequestMethod.GET)
- public IDashboardResponse getA1MediationUrl() {
- return new UrlTransport(a1MediationUrl);
- }
-
- @ApiOperation(value = "Sets the A1 Mediation URL.", response = IDashboardResponse.class)
- @RequestMapping(value = A1_MEDIATION_URL, method = RequestMethod.PUT)
- public IDashboardResponse setA1MediationUrl(@RequestBody UrlTransport st, HttpServletResponse response) {
- try {
- this.a1MediationUrl = new URL(st.getUrl()).toString();
- return new SuccessTransport(HttpServletResponse.SC_OK, null);
- } catch (MalformedURLException ex) {
- logger.error("Failed to parse url " + st.getUrl(), ex);
- response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- return new ErrorTransport(400, "Bad URL", ex);
- }
- }
-
- @ApiOperation(value = "Gets the A1 Mediation delay path.", response = IDashboardResponse.class)
- @RequestMapping(value = A1_MEDIATION_DELAY_PATH, method = RequestMethod.GET)
- public IDashboardResponse getA1MediationDelayPath() {
- return new PathTransport(a1MediationDelayPath);
- }
-
- @ApiOperation(value = "Sets the A1 Mediation delay path.", response = IDashboardResponse.class)
- @RequestMapping(value = A1_MEDIATION_DELAY_PATH, method = RequestMethod.PUT)
- public IDashboardResponse setA1MediationDelayPath(@RequestBody PathTransport st) {
- this.a1MediationDelayPath = st.getPath();
- return new SuccessTransport(HttpServletResponse.SC_OK, null);
- }
-
- @ApiOperation(value = "Gets the A1 Mediation load path.", response = IDashboardResponse.class)
- @RequestMapping(value = A1_MEDIATION_LOAD_PATH, method = RequestMethod.GET)
- public IDashboardResponse getA1MediationLoadPath() {
- return new PathTransport(a1MediationLoadPath);
- }
-
- @ApiOperation(value = "Sets the A1 Mediation load path.", response = IDashboardResponse.class)
- @RequestMapping(value = A1_MEDIATION_LOAD_PATH, method = RequestMethod.PUT)
- public IDashboardResponse setA1MediationLoadPath(@RequestBody PathTransport st) {
- this.a1MediationLoadPath = st.getPath();
- return new SuccessTransport(HttpServletResponse.SC_OK, null);
- }
-
- @ApiOperation(value = "Gets the A1 Mediation metrics path.", response = IDashboardResponse.class)
- @RequestMapping(value = A1_MEDIATION_METRICS_PATH, method = RequestMethod.GET)
- public IDashboardResponse getA1MediationMetricsPath() {
- return new PathTransport(a1MediationMetricsPath);
- }
-
- @ApiOperation(value = "Sets the A1 Mediation metrics path.", response = IDashboardResponse.class)
- @RequestMapping(value = A1_MEDIATION_METRICS_PATH, method = RequestMethod.PUT)
- public IDashboardResponse setA1MediationMetricsPath(@RequestBody PathTransport st) {
- this.a1MediationMetricsPath = st.getPath();
- return new SuccessTransport(HttpServletResponse.SC_OK, null);
- }
-
- @ApiOperation(value = "Gets the A1 Mediation delay value.", response = DelayTransport.class)
- @RequestMapping(value = A1_MEDIATION_DELAY, method = RequestMethod.GET)
- public DelayTransport getA1MediationDelay() {
- if (mockData) {
- return mockDelay;
- } else {
- URI uri = buildUri(a1MediationUrl, new String[] { a1MediationDelayPath });
- logger.debug("getA1MediationDelay: uri {}", uri);
- ResponseEntity<DelayTransport> response = restTemplate.exchange(uri, HttpMethod.GET, null,
- new ParameterizedTypeReference<DelayTransport>() {
- });
- return response.getBody();
- }
- }
-
- @ApiOperation(value = "Sets the A1 Mediation delay value.")
- @RequestMapping(value = A1_MEDIATION_DELAY, method = RequestMethod.PUT)
- public void putA1MediationDelay(DelayTransport value) {
- if (mockData) {
- mockDelay.setDelay(value.getDelay());
- } else {
- URI uri = buildUri(a1MediationUrl, new String[] { a1MediationDelayPath });
- logger.debug("putA1MediationDelay: uri {}", uri);
- restTemplate.put(uri, value);
- }
- }
-
- @ApiOperation(value = "Gets the A1 Mediation load value.", response = LoadTransport.class)
- @RequestMapping(value = A1_MEDIATION_LOAD, method = RequestMethod.GET)
- public LoadTransport getA1MediationLoad() {
- if (mockData) {
- return mockLoad;
- } else {
- URI uri = buildUri(a1MediationUrl, new String[] { a1MediationLoadPath });
- logger.debug("getA1MediationLoad: uri {}", uri);
- ResponseEntity<LoadTransport> response = restTemplate.exchange(uri, HttpMethod.GET, null,
- new ParameterizedTypeReference<LoadTransport>() {
- });
- return response.getBody();
- }
- }
-
- @ApiOperation(value = "Sets the A1 Mediation delay value.")
- @RequestMapping(value = A1_MEDIATION_LOAD, method = RequestMethod.PUT)
- public void putA1MediationLoad(LoadTransport value) {
- if (mockData) {
- mockLoad.setLoad(value.getLoad());
- } else {
- URI uri = buildUri(a1MediationUrl, new String[] { a1MediationDelayPath });
- logger.debug("putA1MediationLoad: uri {}", uri);
- restTemplate.put(uri, value);
- }
- }
-
- @ApiOperation(value = "Gets the A1 Mediation metrics object.", response = MetricsTransport.class)
- @RequestMapping(value = A1_MEDIATION_METRICS, method = RequestMethod.GET)
- public MetricsTransport getA1MediationMetrics() {
- if (mockData) {
- return mockMetrics;
- } else {
- URI uri = buildUri(a1MediationUrl, new String[] { a1MediationLoadPath });
- logger.debug("getA1MediationMetrics: uri {}", uri);
- ResponseEntity<MetricsTransport> response = restTemplate.exchange(uri, HttpMethod.GET, null,
- new ParameterizedTypeReference<MetricsTransport>() {
- });
- return response.getBody();
- }
- }
-
-}
--- /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.controller;
+
+import java.lang.invoke.MethodHandles;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.oransc.ric.a1med.client.api.A1MediatorApi;
+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.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.util.Assert;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+
+/**
+ * Provides methods to manage policies of the Admission Control xApp. All
+ * messages go via the A1 Mediatior.
+ */
+@RestController
+@RequestMapping(value = DashboardConstants.ENDPOINT_PREFIX + "/xapp/ac", produces = MediaType.APPLICATION_JSON_VALUE)
+public class AcXappController {
+
+ private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+ private static final String POLICY_NAME = "policyname";
+
+ // Populated by the autowired constructor
+ private final A1MediatorApi a1MediatorApi;
+
+ @Autowired
+ public AcXappController(final A1MediatorApi a1MediatorApi) {
+ Assert.notNull(a1MediatorApi, "API must not be null");
+ this.a1MediatorApi = a1MediatorApi;
+ }
+
+ @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");
+ return new SuccessTransport(200, DashboardApplication.getImplementationVersion(A1MediatorApi.class));
+ }
+
+ @ApiOperation(value = "Gets the named policy for AC xApp via the A1 Mediator")
+ @RequestMapping(value = "policy/{" + POLICY_NAME + "}", method = RequestMethod.GET)
+ public Object getPolicy(@PathVariable(POLICY_NAME) String policyName) {
+ logger.debug("getPolicy: policy {}", policyName);
+ a1MediatorApi.a1ControllerGetHandler(policyName);
+ return null;
+ }
+
+ @ApiOperation(value = "Sets the named policy for AC xApp via the A1 Mediator")
+ @RequestMapping(value = "policy/{" + POLICY_NAME + "}", method = RequestMethod.PUT)
+ public void putPolicy(@PathVariable(POLICY_NAME) String policyName, //
+ @ApiParam(value = "JSON formatted policy") @RequestBody JsonNode policy, //
+ HttpServletResponse response) {
+ logger.debug("putPolicy: policy {}", policyName);
+ a1MediatorApi.a1ControllerPutHandler(policyName, policy);
+ response.setStatus(a1MediatorApi.getApiClient().getStatusCode().value());
+ }
+
+}
import org.oransc.ric.anrxapp.client.model.NeighborCellRelationDelTable;
import org.oransc.ric.anrxapp.client.model.NeighborCellRelationModTable;
import org.oransc.ric.anrxapp.client.model.NeighborCellRelationTable;
+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.beans.factory.annotation.Autowired;
*/
@Configuration
@RestController
-@RequestMapping(value = DashboardConstants.ENDPOINT_PREFIX + "/ncrt", produces = MediaType.APPLICATION_JSON_VALUE)
+@RequestMapping(value = DashboardConstants.ENDPOINT_PREFIX + "/xapp/anr", produces = MediaType.APPLICATION_JSON_VALUE)
public class AnrXappController {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
this.ncrtApi = ncrtApi;
}
+ @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");
+ 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) {
@RequestParam(name = NRCGI, required = false) String nrcgi) {
logger.debug("queryNcrtAllCells: cellIdentifier {}, startIndex {} limit {} nrpci {} nrcgi {}", cellIdentifier,
startIndex, limit, nrpci, nrcgi);
- return ncrtApi.getCellNcrtInfo(cellIdentifier, startIndex, limit, nrpci, nrcgi);
+ return ncrtApi.getCellNcrtInfo(cellIdentifier, nrpci, nrcgi, startIndex, limit);
}
@ApiOperation(value = "Modify neighbor cell relation based on Source Cell NR CGI and Target Cell NR PCI / NR CGI")
@RequestBody NeighborCellRelationModTable ncrtModTable, //
HttpServletResponse response) {
logger.debug("modifyNcrt: cellIdentifier {} modTable {}", cellIdentifier, ncrtModTable);
- ncrtApi.modifyNCRT(cellIdentifier, ncrtModTable, null, null, null, null);
+ ncrtApi.modifyNcrt(cellIdentifier, ncrtModTable, null, null);
response.setStatus(healthApi.getApiClient().getStatusCode().value());
}
@RequestBody NeighborCellRelationDelTable ncrtDelTable, //
HttpServletResponse response) {
logger.debug("modifyNcrt: cellIdentifier {} delTable {}", cellIdentifier, ncrtDelTable);
- ncrtApi.deleteNcrt(cellIdentifier, ncrtDelTable, null, null, null, null);
+ ncrtApi.deleteNcrt(cellIdentifier, ncrtDelTable, null, null);
response.setStatus(healthApi.getApiClient().getStatusCode().value());
}
}
import org.oransc.ric.e2mgr.client.api.E2ManagerApi;
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.IDashboardResponse;
+import org.oransc.ric.portal.dashboard.model.SuccessTransport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
throw new IllegalArgumentException("Empty not permitted");
}
+ @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");
+ return new SuccessTransport(200, DashboardApplication.getImplementationVersion(E2ManagerApi.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) {
--- /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.controller;
+
+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;
+import org.springframework.web.bind.annotation.RestController;
+
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * Answers REST requests for the API service health etc.
+ */
+@RestController
+@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");
+ 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");
+ return new SuccessTransport(200, DashboardApplication.getImplementationVersion(MethodHandles.lookup().lookupClass()));
+ }
+
+}
import javax.servlet.http.HttpServletResponse;
+import org.oransc.ric.portal.dashboard.DashboardApplication;
import org.oransc.ric.portal.dashboard.DashboardConstants;
import org.oransc.ric.portal.dashboard.model.ErrorTransport;
+import org.oransc.ric.portal.dashboard.model.SuccessTransport;
import org.oransc.ric.xappmgr.client.api.HealthApi;
import org.oransc.ric.xappmgr.client.api.XappApi;
import org.oransc.ric.xappmgr.client.model.AllXapps;
this.xappApi = xappApi;
}
+ @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");
+ return new SuccessTransport(200, DashboardApplication.getImplementationVersion(HealthApi.class));
+ }
+
@ApiOperation(value = "Calls the xApp Manager health check.")
@RequestMapping(value = "/health", method = RequestMethod.GET)
public void getHealth(HttpServletResponse response) {
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.7.2.tgz",
"integrity": "sha512-Ha4HshKdCVKgu4TVCtG8XyPPYdzTzNW4/fvPnn+LT7AosRABryhlRv4cc4+o84dgpvVJN9reN7jo/c+nYujFug=="
},
+ "@material/animation": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@material/animation/-/animation-1.0.0.tgz",
+ "integrity": "sha512-Ed5/vggn6ZhSJ87yn3ZS1d826VJNFz73jHF2bSsgRtHDoB8KCuOwQMfdgAgDa4lKDF6CDIPCKBZPKrs2ubehdw==",
+ "requires": {
+ "tslib": "^1.9.3"
+ }
+ },
+ "@material/base": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@material/base/-/base-1.0.0.tgz",
+ "integrity": "sha512-5dxFp46x5FA+Epg6YHLzN+5zRt9S2wR84UdvVAEJ1egea94m9UHUg7y9tAnNSN16aexRSywmzyLwPr+i8PGEYA==",
+ "requires": {
+ "tslib": "^1.9.3"
+ }
+ },
+ "@material/dom": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@material/dom/-/dom-1.1.0.tgz",
+ "integrity": "sha512-+HWW38ZaM2UBPu4+7QCusLDSf4tFT31rsEXHkTkxYSg/QpDivfPx6YDz4OmYtafmhPR1d1YjqB3MYysUHdodyw==",
+ "requires": {
+ "tslib": "^1.9.3"
+ }
+ },
+ "@material/feature-targeting": {
+ "version": "0.44.1",
+ "resolved": "https://registry.npmjs.org/@material/feature-targeting/-/feature-targeting-0.44.1.tgz",
+ "integrity": "sha512-90cc7njn4aHbH9UxY8qgZth1W5JgOgcEdWdubH1t7sFkwqFxS5g3zgxSBt46TygFBVIXNZNq35Xmg80wgqO7Pg=="
+ },
+ "@material/radio": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@material/radio/-/radio-2.1.1.tgz",
+ "integrity": "sha512-srbafm+JP4HhfvqLKOsLaIH1L67Y2EDfmeHbkI5Ag2zLsLLqGT8BI3AtytrOeg9xSvChqex/Bg8So8+i9FcalA==",
+ "requires": {
+ "@material/animation": "^1.0.0",
+ "@material/base": "^1.0.0",
+ "@material/feature-targeting": "^0.44.1",
+ "@material/ripple": "^2.1.1",
+ "@material/theme": "^1.1.0",
+ "tslib": "^1.9.3"
+ }
+ },
+ "@material/ripple": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-2.1.1.tgz",
+ "integrity": "sha512-/WIOBen3OLasJrr2ZXo9wpVJo6Z+1qFxnOvC61iXWqnDctq1fgTAQQbiMaRtsbfU68jDfhgLFJlwjgzvqAvFWQ==",
+ "requires": {
+ "@material/animation": "^1.0.0",
+ "@material/base": "^1.0.0",
+ "@material/dom": "^1.1.0",
+ "@material/feature-targeting": "^0.44.1",
+ "@material/theme": "^1.1.0",
+ "tslib": "^1.9.3"
+ }
+ },
+ "@material/theme": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@material/theme/-/theme-1.1.0.tgz",
+ "integrity": "sha512-YYUV9Rhbx4r/EMb/zoOYJUWjhXChNaLlH1rqt3vpNVyxRcxGqoVMGp5u1XALBCFiD9dACPKLIkKyRYa928nmPQ==",
+ "requires": {
+ "@material/feature-targeting": "^0.44.1"
+ }
+ },
"@ngtools/webpack": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-7.2.3.tgz",
"@angular/platform-browser-dynamic": "~7.2.0",
"@angular/router": "~7.2.0",
"@fortawesome/fontawesome-free": "^5.7.2",
+ "@material/radio": "^2.1.1",
"@types/chart.js": "^2.7.46",
"angular-bootstrap-md": "^7.4.2",
"bootstrap": "^4.3.1",
<parent>
<groupId>org.o-ran-sc.portal.ric-dashboard</groupId>
<artifactId>ric-dash-parent</artifactId>
- <version>1.0.2-SNAPSHOT</version>
+ <version>1.0.3-SNAPSHOT</version>
</parent>
<artifactId>ric-dash-fe</artifactId>
<name>RIC Dashboard Webapp frontend</name>
*/
.main__footer {
background: transparent;
- position: absolute;
+ /* position: absolute;
bottom: 1rem;
- left: 1.5rem;
+ left: 1.5rem; */
+ margin: 10px;
z-index: 100;
}
-.copyright__text {
- letter-spacing: 0.1rem;
- color: gray;
+.main__footer-dark {
+ background-color: #2B244D;
+ color: white;
+}
+
+.main-footer__bg-dark {
+ opacity: 1;
+ background: linear-gradient(to bottom, #B290FF, #2E1D65);
+ transition: opacity 300ms linear;
}
@media only screen and (max-width: 300px) {
</div>
<div class="account-details">
<span class="name__text">Demo</span>
- <span class="email__text">demo@onap.org</span>
+ <span class="email__text">demo@o-ran-sc.org</span>
</div>
</section>
<section #sidenav class="menu-body">
</svg>
<img src="../../assets/oran-logo.png" width="180%" height="100%" style="position: relative; z-index: 50"/>
<svg class="logo__icon" viewBox="150.3 22.2 313.7 42.8">
- <!--<path fill="#00ff9b" d="M150.3 65V22.2L193 65z" data-name="Path 1"/>
- <path fill="#003eff" d="M193.1 65h-42.8L193 22.2z" data-name="Path 2"/>-->
-
<text [ngClass]="{'logo__text-dark': darkModeActive}" class="logo__text" fill="#432c85"
font-size="30" font-weight="600"
letter-spacing=".1em" transform="translate(149 56)">
<h3 class="date__text"></h3>
-
<div class="mode-toggle__container">
<span class="mode-toggle__text">Light</span>
-
<label class="toggle-button__container">
<input (click)="modeToggleSwitch()" type="checkbox" class="mode-toggle__input"/>
<span [ngClass]="{'mode-toggle__bg-checked': darkModeActive}" class="mode-toggle__bg"></span>
<span [ngClass]="{'mode-toggle__circle-checked': darkModeActive}" class="mode-toggle__circle"></span>
</label>
-
-
<span class="mode-toggle__text">Dark</span>
</div>
</header>
<!-- Main Content -->
-
- <!--<router-outlet></router-outlet>-->
<main class="main__container">
<div class="main-container__bg" [ngClass]="{'main-container__bg-dark': darkModeActive}"></div>
<router-outlet></router-outlet>
</main>
<!-- Footer -->
+ <footer class="main__footer">
+ <div class="main-footer__bg" [ngClass]="{'main-footer__bg-dark': darkModeActive}"></div>
+ <app-footer></app-footer>
+ </footer>
-<!-- <footer class="main__footer">
- <small class="copyright__text">© 2019 AT&T and Nokia. All rights reserved.</small>
- </footer> -->
</div>
import { BrowserModule } from '@angular/platform-browser';
// tslint:disable-next-line:max-line-length
import { MatIconModule, MatCardModule, MatListModule, MatSidenavModule,
- MatButtonToggleModule, MatSliderModule, MatGridListModule, MatSlideToggleModule,
- MatExpansionModule, MatTabsModule, MatDialogModule, MatFormFieldModule, MatButtonModule, MatInputModule, MatSnackBarModule} from '@angular/material';
+ MatButtonToggleModule, MatSliderModule, MatGridListModule, MatSlideToggleModule,
+ MatExpansionModule, MatTabsModule, MatDialogModule, MatFormFieldModule,
+ MatButtonModule, MatInputModule, MatSnackBarModule} 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';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.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';
@NgModule({
ConfigEventComponent,
AppRANConnectDialog,
ConfirmDialogComponent,
+ FooterComponent,
],
imports: [
BrowserModule,
ReactiveFormsModule,
MatButtonToggleModule,
MatExpansionModule,
+ MatRadioModule,
MatSliderModule,
MatCardModule,
MatIconModule,
--- /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===================================
+ -->
+<div class="copyright__text">
+ Copyright (C) 2019 AT&T Intellectual Property and Nokia. Licensed under the Apache License, Version 2.0.
+ <br/>
+ Version {{dashboardVersion}}
+</div>
--- /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===================================
+ */
+.copyright__text {
+ color: gray;
+ letter-spacing: 0.1rem;
+ font-size: 12px;
+}
--- /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===================================
+ */
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { FooterComponent } from './footer.component';
+
+describe('FooterComponent', () => {
+ let component: FooterComponent;
+ let fixture: ComponentFixture<FooterComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ FooterComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(FooterComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
--- /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===================================
+ */
+import { Component, OnInit } from '@angular/core'
+import { Observable } from 'rxjs/Rx'
+import { VersionService } from '../services/version/version.service'
+import { DashboardSuccessTransport } from '../interfaces/dashboard.types'
+
+@Component({
+ selector: 'app-footer',
+ templateUrl: './footer.component.html',
+ styleUrls: ['./footer.component.scss']
+})
+
+/**
+ * Fetches the version on load for display in the footer
+ */
+export class FooterComponent implements OnInit {
+
+ public dashboardVersion : string
+
+ // Inject the service
+ constructor(public versionService: VersionService) { }
+
+ ngOnInit() {
+ this.versionService.getDashboardVersion().subscribe((res : DashboardSuccessTransport) => this.dashboardVersion = res.data)
+ }
+
+}
--- /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===================================
+ */
+
+// Models of data used by the AC xApp
+
+export interface ACAdmissionIntervalControl {
+ dc_admission_start_time: string;
+ dc_admission_end_time: string;
+}
+
+export interface ACAdmissionIntervalControlAck {
+ status: string;
+ message: string;
+}
--- /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===================================
+ */
+
+// Models of data used by the ANR xApp
+
+export interface ANRNeighborCellRelation {
+ cellIdentifierNrcgi: string;
+ neighborCellNrpci: string;
+ neighborCellNrcgi: string;
+ flagNoHo: boolean;
+ flagNoXn: boolean;
+ flagNoRemove: boolean;
+}
+
+export interface ANRNeighborCellRelationDel {
+ idType: string;
+ neighborCellNrpci: string;
+ neighborCellNrcgi: string;
+}
+
+export interface ANRNeighborCellRelationMod {
+ neighbourCellIdentifierType: string;
+ action: string;
+ neighborCellNrpci: string;
+ neighborCellNrcgi: string;
+ flagNoHo: boolean;
+ flagNoXn: boolean;
+ flagNoRemove: boolean;
+}
--- /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===================================
+ */
+
+// Models of data used by the Dashboard
+
+export interface DashboardSuccessTransport {
+ status: number;
+ data: string;
+}
--- /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===================================
+ */
+
+// Models of data used by the E2 Manager
+
+export interface E2SetupRequest {
+ ranName: string;
+ ranIp: string;
+ ranPort: number;
+}
+
+export interface E2ErrorResponse {
+ errorCode: string;
+ errorMessage: string;
+}
* ========================LICENSE_END===================================
*/
-package org.oransc.ric.portal.dashboard.model;
-
-/**
- * Trivial model to transport a URL, to be serialized as JSON.
- */
-public class UrlTransport implements IDashboardResponse {
-
- private String url;
-
- /**
- * Builds an empty object.
- */
- public UrlTransport() {
- // no-arg constructor
- }
-
- /**
- * Builds an object with the specified value.
- *
- * @param s
- * value to transport.
- */
- public UrlTransport(String s) {
- this.url = s;
- }
+// Models of data used by the xApp Manager
+
+export interface XMSubscription {
+ eventType: string;
+ id: string;
+ maxRetries: number;
+ retryTimer: number;
+ targetUrl: string;
+}
- public String getUrl() {
- return url;
- }
+export interface XMXappInfo {
+ xAppName: string;
+}
- public void setUrl(String s) {
- this.url = s;
- }
+export interface XMXappInstance {
+ ip: string;
+ name: string;
+ port: number;
+ status: string;
+ rxMessages: Array<string>;
+ txMessages: Array<string>;
+}
+export interface XMXapp {
+ name: string;
+ status: string;
+ version: string;
+ instances: Array<XMXappInstance>;
}
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
+import { XMXappInfo } from '../../interfaces/xapp-mgr.types';
@Injectable()
export class CatalogService {
- constructor(private http: HttpClient) {
+ constructor(private httpClient: HttpClient) {
+ // injects to variable httpClient
}
getAll() {
- return this.http.get('api/xappmgr/xapps');
+ return this.httpClient.get('api/xappmgr/xapps');
}
deployXapp(name) {
- return this.http.post('api/xappmgr/xapps',
- {
- "xAppName": name
- }
- , { observe: 'response' });
+ let xappInfo: XMXappInfo = {
+ xAppName: name
+ };
+ return this.httpClient.post('api/xappmgr/xapps', xappInfo, { observe: 'response' });
}
}
*/
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
-import { Observable } from 'rxjs';
@Injectable()
export class SignalService {
- constructor(private http: HttpClient) {
+ constructor(private httpClient: HttpClient) {
+ // injects to variable httpClient
}
getAll() {
- return this.http.get('api/e2mgr/setup');
+ return this.httpClient.get('api/e2mgr/setup');
}
x2Setup(req) {
- return this.http.post('api/e2mgr/x2Setup', req);
+ return this.httpClient.post('api/e2mgr/x2Setup', req);
}
endcSetup(req) {
- return this.http.post('api/e2mgr/endcSetup', req);
+ return this.httpClient.post('api/e2mgr/endcSetup', req);
}
}
--- /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===================================
+ */
+import { TestBed } from '@angular/core/testing';
+
+import { VersionService } from './version.service';
+
+describe('VersionService', () => {
+ beforeEach(() => TestBed.configureTestingModule({}));
+
+ it('should be created', () => {
+ const service: VersionService = TestBed.get(VersionService);
+ expect(service).toBeTruthy();
+ });
+});
--- /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===================================
+ */
+import { Injectable } from '@angular/core'
+import { HttpClient } from '@angular/common/http'
+
+@Injectable({
+ providedIn: 'root'
+})
+export class VersionService {
+
+ constructor(private httpClient : HttpClient) {
+ // injects to variable httpClient
+ }
+
+ /**
+ * Gets an Observable with version details
+ * @returns {Observable<SuccessTransport>} with Dashboard version
+ */
+ getDashboardVersion() {
+ return this.httpClient.get('api/dashboard/version')
+ }
+
+ /**
+ * Gets an Observable with version details
+ * @returns {Observable<SuccessTransport>} with A1 Mediator version
+ */
+ getA1MediatorVersion() {
+ // Remember that AC traffic goes via A1
+ return this.httpClient.get('api/xapp/ac/version')
+ }
+
+ /**
+ * Gets an Observable with version details
+ * @returns {Observable<SuccessTransport>} with ANR xApp version
+ */
+ getAnrXappVersion() {
+ return this.httpClient.get('api/xapp/anr/version')
+ }
+
+ /**
+ * Gets an Observable with version details
+ * @returns {Observable<SuccessTransport>} with E2 Manager version
+ */
+ getE2ManagerVersion() {
+ return this.httpClient.get('api/e2mgr/version')
+ }
+
+ /**
+ * Gets an Observable with version details
+ * @returns {Observable<SuccessTransport>} with XApp Manager version
+ */
+ getXappManagerVersion(){
+ return this.httpClient.get('api/xappmgr/version')
+ }
+
+}
Setup RAN Connection
</div>
-<form [formGroup]="ranDialogForm" novalidate autocomplete="off">
+<form [formGroup]="ranDialogForm" novalidate autocomplete="off" (ngSubmit)="setupConnection(ranDialogForm.value)">
<div mat-dialog-content>
+ <div name="rantype">
+ <label id="request-type-radio-group-label">Select the RAN type</label>
+ <mat-radio-group aria-label="Select the 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>
+ </div>
<mat-form-field class="input-display-block">
- <input matInput type="text" placeholder="eNB/gNB Name" [(ngModel)]="data.ranName" formControlName="ranName">
- <mat-hint align="end">Not more then 50 characters long.</mat-hint>
+ <input matInput type="text" placeholder="eNB/gNB 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>
</mat-form-field>
<mat-form-field class="input-display-block">
- <input matInput type="text" placeholder="IP" [(ngModel)]="data.ranIp" formControlName="ranIp">
+ <input matInput type="text" placeholder="IP" formControlName="ranIp">
<mat-error *ngIf="validateControl('ranIp') && hasError('ranIp', 'required')">IP is required</mat-error>
<mat-error *ngIf="hasError('ranIp', 'pattern')">Valid IP is required</mat-error>
</mat-form-field>
<mat-form-field class="input-display-block">
- <input matInput type="text" placeholder="Port" [(ngModel)]="data.ranPort" formControlName="ranPort">
+ <input matInput type="text" placeholder="Port" formControlName="ranPort">
<mat-error *ngIf="validateControl('ranPort') && hasError('ranPort', 'required')">Port is required</mat-error>
<mat-error *ngIf="hasError('ranPort', 'pattern')">Valid port number is required</mat-error>
</mat-form-field>
</div>
<div mat-dialog-actions class="modal-footer justify-content-center">
- <button class="mat-raised-button" (click)="close()">Cancel</button>
- <button class="mat-raised-button mat-primary"
- [disabled]="(validateControl('ranName') && hasError('ranName', 'required'))
- || (validateControl('ranIp') && hasError('ranIp', 'required'))
- || (validateControl('ranPort') && hasError('ranPort', 'required'))
- || hasError('ranName', 'maxlength')
- || hasError('ranIp', 'pattern')
- || hasError('ranPort', 'pattern')
- || (!data.ranName || !data.ranIp || !data.ranPort)"
- (click)="connectRAN()">Connect</button>
+ <button class="mat-raised-button" (click)="onCancel()">Cancel</button>
+ <button class="mat-raised-button mat-primary" [disabled]="!ranDialogForm.valid">Connect</button>
</div>
</form>
*/
import { Component, OnInit, Inject } from '@angular/core';
import { LocalDataSource } from 'ng2-smart-table';
-import { SignalService } from '../services/signal/signal.service';
import { Router } from '@angular/router';
-import { MatDialog, MatDialogConfig, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
+import { MatDialog, MatDialogConfig, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material';
-import { FormGroup, FormControl, FormBuilder, ReactiveFormsModule, Validators} from '@angular/forms';
+import { MatRadioModule } from '@angular/material/radio';
+import { FormGroup, FormControl, FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Rx';
-
-export interface DialogData {
- ranName: string;
- ranIp: number;
- ranPort: number;
-}
+import { SignalService } from '../services/signal/signal.service';
+import { E2SetupRequest } from '../interfaces/e2-mgr.types';
@Component({
- selector: 'app-signal',
- templateUrl: 'signal.component.html',
- styleUrls: ['signal.component.css']
+ selector: 'app-signal',
+ templateUrl: 'signal.component.html',
+ styleUrls: ['signal.component.css']
})
export class SignalComponent {
- settings = {
- hideSubHeader: true,
- actions: {
- columnTitle: 'Actions',
- add: false,
- edit: false,
- delete: false,
- position: 'right'
- },
- columns: {
- requestType: {
- title: 'Request Type',
- type: 'string',
- },
- ranName: {
- title: 'eNodeB/gNodeB Name',
- type: 'string',
- },
- ranIp: {
- title: 'IP',
- type: 'number',
- },
- ranPort: {
- title: 'Port',
- type: 'number',
- },
- responseCode: {
- title: 'Response',
- type: 'number',
- },
- timeStamp: {
- title: 'Time Stamp',
- type: 'string',
- }
- }
- };
-
- source: LocalDataSource = new LocalDataSource();
-
- ranName: string;
-
- ranIp: number;
-
- ranPort: number;
-
- constructor(private service: SignalService, public dialog: MatDialog, private http: HttpClient) {
- this.service.getAll().subscribe((val: any[]) => this.source.load(val));
+ settings = {
+ hideSubHeader: true,
+ actions: {
+ columnTitle: 'Actions',
+ add: false,
+ edit: false,
+ delete: false,
+ position: 'right'
+ },
+ columns: {
+ requestType: {
+ title: 'RAN Type',
+ type: 'string',
+ },
+ ranName: {
+ title: 'eNodeB/gNodeB Name',
+ type: 'string',
+ },
+ ranIp: {
+ title: 'IP',
+ type: 'number',
+ },
+ ranPort: {
+ title: 'Port',
+ type: 'number',
+ },
+ responseCode: {
+ title: 'Response',
+ type: 'number',
+ },
+ timeStamp: {
+ title: 'Time Stamp',
+ type: 'string',
+ }
}
+ };
- openRanConnectDialog() {
+ source: LocalDataSource = new LocalDataSource();
- const dialogRef = this.dialog.open(AppRANConnectDialog, {
- width: '450px',
- data: {ranName: this.ranName, ranIp: this.ranIp, ranPort: this.ranPort}
- })
+ constructor(private service: SignalService, public dialog: MatDialog, private http: HttpClient) {
+ this.service.getAll().subscribe((val: any[]) => this.source.load(val));
+ }
- dialogRef.afterClosed().subscribe(result => {
- this.service.getAll().subscribe((val: any[]) => this.source.load(val));
- });
+ openRanConnectDialog() {
+ const dialogRef = this.dialog.open(AppRANConnectDialog, {
+ width: '450px',
+ data: { }
+ })
+ dialogRef.afterClosed().subscribe(result => {
+ this.service.getAll().subscribe((val: any[]) => this.source.load(val));
+ });
+ }
- }
-}
+}// class SignalComponent
@Component({
- selector: 'app-signal-ranconnect-dialog',
- templateUrl: 'signal.component.ranconnect-dialog.html',
- styleUrls: ['signal.component.css']
+ selector: 'app-signal-ranconnect-dialog',
+ templateUrl: 'signal.component.ranconnect-dialog.html',
+ styleUrls: ['signal.component.css']
})
export class AppRANConnectDialog implements OnInit {
- constructor(public dialogRef: MatDialogRef<AppRANConnectDialog>,
- private service: SignalService,
- @Inject(MAT_DIALOG_DATA) public data: DialogData) {
- }
-
- public ranDialogForm: FormGroup;
+ public ranDialogForm: FormGroup;
- public ranName: string;
-
- public ranIp: number;
-
- public ranPort: number;
-
- ngOnInit() {
- const ipPattern = /((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))/;
- const portPattern = /^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/;
- this.ranDialogForm = new FormGroup({
- ranName: new FormControl('', [Validators.required, Validators.maxLength(50)]),
- ranIp: new FormControl('', [Validators.required, Validators.pattern(ipPattern)]),
- ranPort: new FormControl('', [Validators.required, Validators.pattern(portPattern)])
- });
+ constructor(
+ public dialogRef: MatDialogRef<AppRANConnectDialog>,
+ private service: SignalService,
+ @Inject(MAT_DIALOG_DATA) public data: E2SetupRequest) {
}
- close() {
- this.dialogRef.close();
+ ngOnInit() {
+ const namePattern = /^([A-Z]){4}([0-9]){6}$/;
+ const ipPattern = /((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))/;
+ const portPattern = /^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/;
+ this.ranDialogForm = new FormGroup({
+ ranType: new FormControl('endc'),
+ ranName: new FormControl('', [Validators.required, Validators.pattern(namePattern)]),
+ ranIp: new FormControl('', [Validators.required, Validators.pattern(ipPattern)]),
+ ranPort: new FormControl('', [Validators.required, Validators.pattern(portPattern)])
+ });
+ }
+
+ onCancel() {
+ this.dialogRef.close();
+ }
+
+ public setupConnection = (ranFormValue) => {
+ if (this.ranDialogForm.valid) {
+ this.executeSetupConnection(ranFormValue);
}
+ }
- connectRAN(): void {
- this.service.x2Setup(this.data).subscribe((val: any[]) => {});
- this.dialogRef.close();
+ private executeSetupConnection = (ranFormValue) => {
+ let setupRequest: E2SetupRequest = {
+ ranName: ranFormValue.ranName,
+ ranIp: ranFormValue.ranIp,
+ ranPort: ranFormValue.ranPort
}
-
- public hasError(controlName: string, errorName: string) {
- if (this.ranDialogForm.controls[controlName].hasError(errorName))
- return true;
- return false;
+ if (ranFormValue.ranType === 'endc') {
+ this.service.endcSetup(setupRequest).subscribe((val: any[]) => {});
}
+ else {
+ this.service.x2Setup(setupRequest).subscribe((val: any[]) => {});
+ }
+ this.dialogRef.close();
+ }
+
+ public hasError(controlName: string, errorName: string) {
+ if (this.ranDialogForm.controls[controlName].hasError(errorName))
+ return true;
+ return false;
+ }
public validateControl(controlName: string) {
- if (this.ranDialogForm.controls[controlName].invalid && this.ranDialogForm.controls[controlName].touched)
- return true;
- return false;
- }
-}
+ if (this.ranDialogForm.controls[controlName].invalid && this.ranDialogForm.controls[controlName].touched)
+ return true;
+ return false;
+ }
+
+} // class AppRANConnectDialog
<div style="color: black; size: 1em; text-align: center">
<mat-icon>settings_input_antenna</mat-icon> ANR</div>
<div style="color: black; size: 1em; text-align: center">
- <mat-icon>call_split</mat-icon> IFLB</div>
-
+ <mat-icon>open_in_new</mat-icon> Deploy</div>
</div>
<div class="body__container">
- <img src="../../../assets/intelligence.png" width="100%" height="100%"/>
+ <img src="../../../assets/intelligence.png" width="250px"/>
</div>
</div>
<div class="add__card" routerLink="/control" [ngClass]="{'add__card-dark': darkMode}">
<div class="header__container">
<span class="card__title">xApp Control</span><br><br><br>
- <div style="color: black; size: 1em; text-align: center">
- <mat-icon>open_in_new</mat-icon> Deploy</div>
<div style="color: black; size: 1em; text-align: center">
<mat-icon>play_circle_outline</mat-icon> Start</div>
<div style="color: black; size: 1em; text-align: center">
</div>
<div class="body__container">
- <img src="../../../assets/xAppControl.png" width="100%" height="100%"/>
+ <img src="../../../assets/xAppControl.png" width="250px"/>
</div>
</div>
-->
<!doctype html>
<html lang="en">
-<head>
- <meta charset="utf-8">
- <title>RIC Dashboard</title>
- <base href="/">
-
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <link rel="icon" type="image/x-icon" href="assets/oran-logo.png">
-</head>
-<body>
- <app-root></app-root>
-</body>
+ <head>
+ <meta charset="utf-8">
+ <title>RIC Dashboard</title>
+ <base href="/">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel="icon" type="image/x-icon" href="assets/oran-logo.png">
+ </head>
+ <body>
+ <app-root></app-root>
+ </body>
</html>
<parent>
<groupId>org.o-ran-sc.portal.ric-dashboard</groupId>
<artifactId>ric-dash-parent</artifactId>
- <version>1.0.2-SNAPSHOT</version>
+ <version>1.0.3-SNAPSHOT</version>
</parent>
<!-- This groupId will NOT allow deployment in LF -->
<groupId>org.o-ran-sc.ric.xappmgr.client</groupId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <!-- Jenkins invokes maven with -Dbuild.number=.. -->
+ <build.number>0</build.number>
+ <!-- same as groupId BUT without hyphens -->
<client.base.package.name>org.oransc.ric.xappmgr.client</client.base.package.name>
</properties>
<!-- Successful compilation requires generated code dependencies -->
</execution>
</executions>
</plugin>
+ <!-- add build information to manifest. Java provides access to the implementation
+ version for a package, so cram the build number into there. -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <!-- version>2.5</version> -->
+ <configuration>
+ <archive>
+ <manifest>
+ <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+ </manifest>
+ <manifestEntries>
+ <Implementation-Version>${project.version}-b${build.number}</Implementation-Version>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
<!-- Skip the deploy-jar-to-nexus step -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
</goals>
</pluginExecutionFilter>
<action>
- <ignore/>
+ <ignore />
</action>
</pluginExecution>
</pluginExecutions>