Merge "Introduce rAPP Catalogue API"
diff --git a/.gitignore b/.gitignore
index e5a2f72..26c6731 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,10 +6,12 @@
# Eclipse
.checkstyle
+.classpath
+target/
.sts4-cache
.project
.settings
.pydevproject
infer-out/
-.vscode
\ No newline at end of file
+.vscode
diff --git a/docs/.project b/docs/.project
deleted file mode 100644
index e248a4f..0000000
--- a/docs/.project
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>docs</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- </buildSpec>
- <natures>
- </natures>
-</projectDescription>
diff --git a/docs/api-docs.rst b/docs/api-docs.rst
index 12ff516..9b0608a 100644
--- a/docs/api-docs.rst
+++ b/docs/api-docs.rst
@@ -15,9 +15,10 @@
:depth: 3
:local:
-The Non-RT RIC consists of two parts, described in the sections below:
+The Non-RT RIC consists of three parts, described in the sections below:
* The Policy Agent
* The SDNC A1 Controller
+ * The rAPP Catalogue
Policy Agent
@@ -44,6 +45,26 @@
See the README.md file in the nonrtric/sdnc-a1-controller repo for info about how to use it.
+rAPP Catalogue
+==============
+
+The Non RT-RIC Service Catalogue provides a way for services to register themselves for other services to discover.
+
+See `RAC API <./rac-api.html>`_ for how to use the API.
+
+.. |swagger-icon| image:: ./images/swagger.png
+ :width: 40px
+
+.. |yaml-icon| image:: ./images/yaml_logo.png
+ :width: 40px
+
+
+.. csv-table::
+ :header: "API name", "|swagger-icon|", "|yaml-icon|"
+ :widths: 10,5, 5
+
+ "RAC API", ":download:`link <../r-app-catalogue/api/rac-api.json>`", ":download:`link <../r-app-catalogue/api/rac-api.yaml>`"
+
Complementary tools
===================
diff --git a/docs/conf.py b/docs/conf.py
index d620289..a6ae7f9 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -7,9 +7,23 @@
linkcheck_ignore = [
'http://localhost.*',
'http://127.0.0.1.*',
- 'https://gerrit.o-ran-sc.org.*'
+ 'https://gerrit.o-ran-sc.org.*',
+ './rac-api.html' #Generated file that doesn't exist at link check.
]
+extensions = ['sphinxcontrib.redoc', 'sphinx.ext.intersphinx',]
+
+redoc = [
+ {
+ 'name': 'RAC API',
+ 'page': 'rac-api',
+ 'spec': '../r-app-catalogue/api/rac-api.json',
+ 'embed': True,
+ }
+ ]
+
+redoc_uri = 'https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js'
+
#intershpinx mapping with other projects
intersphinx_mapping = {}
diff --git a/docs/images/swagger.png b/docs/images/swagger.png
new file mode 100644
index 0000000..f5a9e0c
--- /dev/null
+++ b/docs/images/swagger.png
Binary files differ
diff --git a/docs/images/yaml_logo.png b/docs/images/yaml_logo.png
new file mode 100644
index 0000000..0492eb4
--- /dev/null
+++ b/docs/images/yaml_logo.png
Binary files differ
diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt
index 09a0c1c..78db685 100644
--- a/docs/requirements-docs.txt
+++ b/docs/requirements-docs.txt
@@ -1,5 +1,12 @@
-sphinx
-sphinx-rtd-theme
-sphinxcontrib-httpdomain
-recommonmark
-lfdocs-conf
+tox
+Sphinx>=2,<4
+doc8
+docutils
+setuptools
+six
+sphinx_rtd_theme>=0.4.3
+sphinxcontrib-needs>=0.2.3
+sphinxcontrib-swaggerdoc
+sphinx_bootstrap_theme
+sphinxcontrib-redoc
+lfdocs-conf
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index cb8302e..f21502f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -36,6 +36,7 @@
<module>policy-agent</module>
<module>sdnc-a1-controller</module>
<module>enrichment-coordinator-service</module>
+ <module>r-app-catalogue</module>
</modules>
<build>
<plugins>
diff --git a/r-app-catalogue/.gitignore b/r-app-catalogue/.gitignore
new file mode 100644
index 0000000..ad56f2d
--- /dev/null
+++ b/r-app-catalogue/.gitignore
@@ -0,0 +1,3 @@
+.swagger-codegen-ignore
+.swagger-codegen/
+api/README.md
diff --git a/r-app-catalogue/Dockerfile b/r-app-catalogue/Dockerfile
new file mode 100644
index 0000000..a85f57d
--- /dev/null
+++ b/r-app-catalogue/Dockerfile
@@ -0,0 +1,39 @@
+#
+# ============LICENSE_START=======================================================
+# Copyright (C) 2020 Nordix Foundation.
+# ================================================================================
+# 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.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+#
+FROM openjdk:11-jre-slim
+
+ARG JAR
+
+WORKDIR /opt/app/r-app-catalogue
+RUN mkdir -p /var/log/r-app-catalogue
+
+EXPOSE 8081 8433
+
+ADD /config/application.yaml /opt/app/r-app-catalogue/config/application.yaml
+ADD target/${JAR} /opt/app/r-app-catalogue/r-app-catalogue.jar
+
+
+RUN chmod -R 777 /opt/app/r-app-catalogue/config/
+
+CMD ["java", "-jar", "/opt/app/r-app-catalogue/r-app-catalogue.jar"]
+
+
+
+
diff --git a/r-app-catalogue/README.md b/r-app-catalogue/README.md
new file mode 100644
index 0000000..863713d
--- /dev/null
+++ b/r-app-catalogue/README.md
@@ -0,0 +1,27 @@
+# O-RAN-SC Non-RT RIC rAPP Catalogue
+
+The O-RAN Non-RT RIC rApp Catalogue provides an OpenApi 3.0 REST API for services to register themselves and discover
+other services.
+
+**NOTE!** The definition of the REST API is done in the `api/rac-api.json` file. The yaml version of the file is
+generated during compilation.
+
+The application is a SpringBoot application generated using the openapitools openapi-generator-maven-plugin.
+
+To start the application run:
+`mvn spring-boot:run`
+
+## License
+
+Copyright (C) 2020 Nordix Foundation. All rights reserved.
+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.
diff --git a/r-app-catalogue/api/rac-api.json b/r-app-catalogue/api/rac-api.json
new file mode 100644
index 0000000..3741bdd
--- /dev/null
+++ b/r-app-catalogue/api/rac-api.json
@@ -0,0 +1,246 @@
+{
+ "openapi": "3.0.0",
+ "info": {
+ "title": "rAPP Catalogue API",
+ "description": "The Non RT-RIC Service Catalogue provides a way for services to register themselves for other services to discover.",
+ "version": "1.0.0"
+ },
+ "paths": {
+ "/services": {
+ "get": {
+ "summary": "Service names",
+ "deprecated": false,
+ "operationId": "getServiceNamesUsingGET",
+ "responses": {
+ "200": {
+ "description": "Service names",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "example": [
+ "DroneIdentifier",
+ "Collector"
+ ]
+ }
+ }
+ },
+ "401": {
+ "description": "Unauthorized"
+ },
+ "403": {
+ "description": "Forbidden"
+ },
+ "404": {
+ "description": "Not used"
+ }
+ },
+ "tags": [
+ "rAPP Catalogue API"
+ ]
+ }
+ },
+ "/services/{serviceName}": {
+ "get": {
+ "summary": "Individual Service",
+ "deprecated": false,
+ "operationId": "getIndividualServiceUsingGET",
+ "responses": {
+ "200": {
+ "description": "EI Job",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/service"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Unauthorized"
+ },
+ "403": {
+ "description": "Forbidden"
+ },
+ "404": {
+ "description": "Service is not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/error_information"
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "in": "path",
+ "name": "serviceName",
+ "description": "serviceName",
+ "schema": {
+ "type": "string"
+ },
+ "required": true,
+ "example": "DroneIdentifier"
+ }
+ ],
+ "tags": [
+ "rAPP Catalogue API"
+ ]
+ },
+ "put": {
+ "summary": "Create or update a Service",
+ "deprecated": false,
+ "operationId": "putIndividualServiceUsingPUT",
+ "responses": {
+ "200": {
+ "description": "Service updated"
+ },
+ "201": {
+ "description": "Service created"
+ },
+ "401": {
+ "description": "Unauthorized"
+ },
+ "403": {
+ "description": "Forbidden"
+ },
+ "404": {
+ "description": "Provided service is not correct",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/error_information"
+ },
+ "example": {
+ "detail": "Service is missing required property version",
+ "status": 404
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "serviceName",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "example": "DroneIdentifier"
+ }
+ ],
+ "requestBody": {
+ "description": "Service to create/update",
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/service"
+ }
+ }
+ }
+ },
+ "tags": [
+ "rAPP Catalogue API"
+ ]
+ },
+ "delete": {
+ "summary": "Remove a Service from the catalogue",
+ "deprecated": false,
+ "operationId": "deleteIndividualServiceUsingDELETE",
+ "responses": {
+ "200": {
+ "description": "Not used"
+ },
+ "204": {
+ "description": "Job deleted"
+ },
+ "401": {
+ "description": "Unauthorized"
+ },
+ "403": {
+ "description": "Forbidden"
+ },
+ "404": {
+ "description": "Service is not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/error_information"
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "serviceName",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "example": "DroneIdentifier"
+ }
+ ],
+ "tags": [
+ "rAPP Catalogue API"
+ ]
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "service": {
+ "description": "A Service",
+ "type": "object",
+ "title": "service",
+ "required": [
+ "version"
+ ],
+ "properties": {
+ "version": {
+ "description": "Version of the Service",
+ "type": "string",
+ "example": "1.0.0"
+ },
+ "display_name": {
+ "description": "Display name for the Service",
+ "type": "string",
+ "example": "Drone Identifier"
+ },
+ "description": {
+ "description": "Description of the Service",
+ "type": "string",
+ "example": "Detects if a UE is a drone"
+ }
+ }
+ },
+ "error_information": {
+ "description": "Problem as defined in https://tools.ietf.org/html/rfc7807",
+ "type": "object",
+ "title": "error_information",
+ "properties": {
+ "detail": {
+ "description": "A human-readable explanation specific to this occurrence of the problem.",
+ "type": "string",
+ "example": "Service not found"
+ },
+ "status": {
+ "format": "int32",
+ "description": "The HTTP status code generated by the origin server for this occurrence of the problem.",
+ "type": "integer",
+ "example": 404
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/r-app-catalogue/api/rac-api.yaml b/r-app-catalogue/api/rac-api.yaml
new file mode 100644
index 0000000..87e2eb9
--- /dev/null
+++ b/r-app-catalogue/api/rac-api.yaml
@@ -0,0 +1,175 @@
+openapi: 3.0.0
+info:
+ title: rAPP Catalogue API
+ description: The Non RT-RIC Service Catalogue provides a way for services to register
+ themselves for other services to discover.
+ version: 1.0.0
+servers:
+- url: /
+paths:
+ /services:
+ get:
+ tags:
+ - rAPP Catalogue API
+ summary: Service names
+ operationId: getServiceNamesUsingGET
+ responses:
+ 200:
+ description: Service names
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ type: string
+ example:
+ - DroneIdentifier
+ - Collector
+ 401:
+ description: Unauthorized
+ 403:
+ description: Forbidden
+ 404:
+ description: Not used
+ deprecated: false
+ /services/{serviceName}:
+ get:
+ tags:
+ - rAPP Catalogue API
+ summary: Individual Service
+ operationId: getIndividualServiceUsingGET
+ parameters:
+ - name: serviceName
+ in: path
+ description: serviceName
+ required: true
+ style: simple
+ explode: false
+ schema:
+ type: string
+ example: DroneIdentifier
+ responses:
+ 200:
+ description: EI Job
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/service'
+ 401:
+ description: Unauthorized
+ 403:
+ description: Forbidden
+ 404:
+ description: Service is not found
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/error_information'
+ deprecated: false
+ put:
+ tags:
+ - rAPP Catalogue API
+ summary: Create or update a Service
+ operationId: putIndividualServiceUsingPUT
+ parameters:
+ - name: serviceName
+ in: path
+ required: true
+ style: simple
+ explode: false
+ schema:
+ type: string
+ example: DroneIdentifier
+ requestBody:
+ description: Service to create/update
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/service'
+ required: true
+ responses:
+ 200:
+ description: Service updated
+ 201:
+ description: Service created
+ 401:
+ description: Unauthorized
+ 403:
+ description: Forbidden
+ 404:
+ description: Provided service is not correct
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/error_information'
+ example:
+ detail: Service is missing required property version
+ status: 404
+ deprecated: false
+ delete:
+ tags:
+ - rAPP Catalogue API
+ summary: Remove a Service from the catalogue
+ operationId: deleteIndividualServiceUsingDELETE
+ parameters:
+ - name: serviceName
+ in: path
+ required: true
+ style: simple
+ explode: false
+ schema:
+ type: string
+ example: DroneIdentifier
+ responses:
+ 200:
+ description: Not used
+ 204:
+ description: Job deleted
+ 401:
+ description: Unauthorized
+ 403:
+ description: Forbidden
+ 404:
+ description: Service is not found
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/error_information'
+ deprecated: false
+components:
+ schemas:
+ service:
+ title: service
+ required:
+ - version
+ type: object
+ properties:
+ version:
+ type: string
+ description: Version of the Service
+ example: 1.0.0
+ display_name:
+ type: string
+ description: Display name for the Service
+ example: Drone Identifier
+ description:
+ type: string
+ description: Description of the Service
+ example: Detects if a UE is a drone
+ description: A Service
+ error_information:
+ title: error_information
+ type: object
+ properties:
+ detail:
+ type: string
+ description: A human-readable explanation specific to this occurrence of
+ the problem.
+ example: Service not found
+ status:
+ type: integer
+ description: The HTTP status code generated by the origin server for this
+ occurrence of the problem.
+ format: int32
+ example: 404
+ description: Problem as defined in https://tools.ietf.org/html/rfc7807
diff --git a/r-app-catalogue/config/application.yaml b/r-app-catalogue/config/application.yaml
new file mode 100644
index 0000000..fadf7d2
--- /dev/null
+++ b/r-app-catalogue/config/application.yaml
@@ -0,0 +1,4 @@
+spring:
+ profiles:
+ active: prod
+
diff --git a/r-app-catalogue/pom.xml b/r-app-catalogue/pom.xml
new file mode 100644
index 0000000..3ac8562
--- /dev/null
+++ b/r-app-catalogue/pom.xml
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+* ========================LICENSE_START=================================
+* O-RAN-SC
+* %%
+* Copyright (C) 2020 Nordix Foundation
+* %%
+* 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===================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-parent</artifactId>
+ <version>2.3.4.RELEASE</version>
+ <relativePath />
+ </parent>
+ <groupId>org.o-ran-sc.nonrtric</groupId>
+ <artifactId>r-app-catalogue</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <licenses>
+ <license>
+ <name>The Apache Software License, Version 2.0</name>
+ <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ </license>
+ </licenses>
+ <properties>
+ <java.version>11</java.version>
+ <swagger-annotations.version>1.5.22</swagger-annotations.version>
+ <springfox.version>2.9.2</springfox.version>
+ <jackson-databind-nullable.version>0.2.1</jackson-databind-nullable.version>
+ <openapi-generator-maven-plugin.version>4.3.1</openapi-generator-maven-plugin.version>
+ <swagger-codegen-maven-plugin.version>3.0.11</swagger-codegen-maven-plugin.version>
+ <docker-maven-plugin.version>0.30.0</docker-maven-plugin.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>io.swagger</groupId>
+ <artifactId>swagger-annotations</artifactId>
+ <version>${swagger-annotations.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-beans</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-autoconfigure</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-webmvc</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger2</artifactId>
+ <version>${springfox.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-core</artifactId>
+ <version>${springfox.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-spring-web</artifactId>
+ <version>${springfox.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-spi</artifactId>
+ <version>${springfox.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tomcat.embed</groupId>
+ <artifactId>tomcat-embed-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.openapitools</groupId>
+ <artifactId>jackson-databind-nullable</artifactId>
+ <version>${jackson-databind-nullable.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.validation</groupId>
+ <artifactId>validation-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.yaml</groupId>
+ <artifactId>snakeyaml</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ <!-- TEST -->
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-api</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.openapitools</groupId>
+ <artifactId>openapi-generator-maven-plugin</artifactId>
+ <version>${openapi-generator-maven-plugin.version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ <configuration>
+ <inputSpec>${project.basedir}/api/rac-api.json</inputSpec>
+ <generatorName>spring</generatorName>
+ <apiPackage>org.oransc.rappcatalogue.api</apiPackage>
+ <modelPackage>org.oransc.rappcatalogue.model</modelPackage>
+ <configOptions>
+ <delegatePattern>true</delegatePattern>
+ </configOptions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>io.swagger.codegen.v3</groupId>
+ <artifactId>swagger-codegen-maven-plugin</artifactId>
+ <version>${swagger-codegen-maven-plugin.version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ <configuration>
+ <inputSpec>${project.basedir}/api/rac-api.json</inputSpec>
+ <language>openapi-yaml</language>
+ <output>${project.basedir}/api/</output>
+ <configOptions>
+ <outputFile>rac-api.yaml</outputFile>
+ </configOptions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>io.fabric8</groupId>
+ <artifactId>docker-maven-plugin</artifactId>
+ <version>${docker-maven-plugin.version}</version>
+ <inherited>false</inherited>
+ <executions>
+ <execution>
+ <id>generate-r-app-catalogue-image</id>
+ <phase>package</phase>
+ <goals>
+ <goal>build</goal>
+ </goals>
+ <configuration>
+ <pullRegistry>${env.CONTAINER_PULL_REGISTRY}</pullRegistry>
+ <images>
+ <image>
+ <name>o-ran-sc/nonrtric-r-app-catalogue:${project.version}</name>
+ <build>
+ <cleanup>try</cleanup>
+ <contextDir>${basedir}</contextDir>
+ <dockerFile>Dockerfile</dockerFile>
+ <args>
+ <JAR>${project.build.finalName}.jar</JAR>
+ </args>
+ <tags>
+ <tag>${project.version}</tag>
+ </tags>
+ </build>
+ </image>
+ </images>
+ </configuration>
+ </execution>
+ <execution>
+ <id>push-r-app-catalogue-image</id>
+ <goals>
+ <goal>build</goal>
+ <goal>push</goal>
+ </goals>
+ <configuration>
+ <pullRegistry>${env.CONTAINER_PULL_REGISTRY}</pullRegistry>
+ <pushRegistry>${env.CONTAINER_PUSH_REGISTRY}</pushRegistry>
+ <images>
+ <image>
+ <name>o-ran-sc/nonrtric-r-app-catalogue:${project.version}</name>
+ <build>
+ <contextDir>${basedir}</contextDir>
+ <dockerFile>Dockerfile</dockerFile>
+ <args>
+ <JAR>${project.build.finalName}.jar</JAR>
+ </args>
+ <tags>
+ <tag>${project.version}</tag>
+ <tag>latest</tag>
+ </tags>
+ </build>
+ </image>
+ </images>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
diff --git a/r-app-catalogue/src/main/java/org/oransc/rappcatalogue/api/ServicesApiDelegateImpl.java b/r-app-catalogue/src/main/java/org/oransc/rappcatalogue/api/ServicesApiDelegateImpl.java
new file mode 100644
index 0000000..701f1d8
--- /dev/null
+++ b/r-app-catalogue/src/main/java/org/oransc/rappcatalogue/api/ServicesApiDelegateImpl.java
@@ -0,0 +1,34 @@
+package org.oransc.rappcatalogue.api;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+@org.springframework.stereotype.Service
+public class ServicesApiDelegateImpl implements ServicesApiDelegate {
+
+ @Override
+ public ResponseEntity<Void> deleteIndividualServiceUsingDELETE(String serviceName) {
+ return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+ }
+
+ // @Override
+ // public ResponseEntity<Service> getIndividualServiceUsingGET(String serviceName) {
+ // return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+
+ // }
+
+ @Override
+ public ResponseEntity<List<String>> getServiceNamesUsingGET() {
+ List<String> services = Arrays.asList("a", "b");
+ return ResponseEntity.ok(services);
+ }
+
+ // @Override
+ // public ResponseEntity<Void> putIndividualServiceUsingPUT(String serviceName, Service service) {
+ // return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+
+ // }
+}
diff --git a/r-app-catalogue/src/test/java/org/oransc/rappcatalogue/api/ServicesApiDelegateImplTest.java b/r-app-catalogue/src/test/java/org/oransc/rappcatalogue/api/ServicesApiDelegateImplTest.java
new file mode 100644
index 0000000..53dfc1a
--- /dev/null
+++ b/r-app-catalogue/src/test/java/org/oransc/rappcatalogue/api/ServicesApiDelegateImplTest.java
@@ -0,0 +1,33 @@
+package org.oransc.rappcatalogue.api;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@ExtendWith(SpringExtension.class)
+class ServicesApiDelegateImplTest {
+
+ @Test
+ void putValidService_shouldBeOk() {
+ ServicesApiDelegateImpl delegateUnderTest = new ServicesApiDelegateImpl();
+
+ ResponseEntity<List<String>> response = delegateUnderTest.getServiceNamesUsingGET();
+ }
+
+ @Test
+ void getServices_shouldProvideArrayOfServices() throws Exception {
+ ServicesApiDelegateImpl delegateUnderTest = new ServicesApiDelegateImpl();
+
+ ResponseEntity<List<String>> response = delegateUnderTest.getServiceNamesUsingGET();
+
+ assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
+ assertThat(response.getBody()).isEqualTo(Arrays.asList("a", "b"));
+ }
+}
diff --git a/tox.ini b/tox.ini
index 4491722..2705e16 100644
--- a/tox.ini
+++ b/tox.ini
@@ -24,23 +24,14 @@
[testenv:docs]
basepython = python3
-deps =
- sphinx
- sphinx-rtd-theme
- sphinxcontrib-httpdomain
- recommonmark
- lfdocs-conf
+deps = -r{toxinidir}/docs/requirements-docs.txt
commands =
- sphinx-build -W -b html -n -d {envtmpdir}/doctrees ./docs/ {toxinidir}/docs/_build/html
+ sphinx-build -W -b html -n -d {envtmpdir}/docs/doctrees ./docs/ {toxinidir}/docs/_build/html
echo "Generated docs available in {toxinidir}/docs/_build/html"
whitelist_externals = echo
[testenv:docs-linkcheck]
basepython = python3
-deps = sphinx
- sphinx-rtd-theme
- sphinxcontrib-httpdomain
- recommonmark
- lfdocs-conf
+deps = -r{toxinidir}/docs/requirements-docs.txt
commands = sphinx-build -W -b linkcheck -d {envtmpdir}/doctrees ./docs/ {toxinidir}/docs/_build/linkcheck