# SPDX-License-Identifier: Apache-2.0
# ============LICENSE_END=========================================================
#
-FROM openjdk:11-jre-slim
+#Get JDK & shrink it to equivalent to a JRE
+FROM openjdk:17-jdk as jre-build
+RUN $JAVA_HOME/bin/jlink \
+ --verbose \
+ --add-modules ALL-MODULE-PATH \
+ --strip-debug \
+ --no-man-pages \
+ --no-header-files \
+ --compress=2 \
+ --output /customjre
+# Use debian base image (same as openjdk uses)
+FROM debian:11-slim
+
+#Copy JRE from the jre-base image
+ENV JAVA_HOME=/jre
+ENV PATH=${JAVA_HOME}/bin:${PATH}
+COPY --from=jre-build /customjre $JAVA_HOME
ARG JAR
WORKDIR /opt/app/rappcatalogue
# ============LICENSE_START===============================================
-# Copyright (C) 2020-2022 Nordix Foundation. All rights reserved.
+# Copyright (C) 2020-2023 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.
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.
+ title: rAPP Catalogue API
version: 1.0.0
servers:
- url: /
paths:
/services:
get:
- tags:
- - rAPP Catalogue API
- summary: Services
+ deprecated: false
operationId: getServices
responses:
"200":
- description: Services
content:
application/json:
schema:
- type: array
items:
$ref: '#/components/schemas/service'
- deprecated: false
- /services/{serviceName}:
- get:
+ type: array
+ description: Services
+ summary: Services
tags:
- rAPP Catalogue API
- summary: Individual Service
- operationId: getIndividualService
+ /services/{serviceName}:
+ delete:
+ deprecated: false
+ operationId: deleteIndividualService
parameters:
- - name: serviceName
+ - example: DroneIdentifier
+ explode: false
in: path
- description: serviceName
+ name: serviceName
required: true
+ schema:
+ type: string
style: simple
+ responses:
+ "204":
+ description: Service deleted
+ summary: Remove a Service from the catalogue
+ tags:
+ - rAPP Catalogue API
+ get:
+ deprecated: false
+ operationId: getIndividualService
+ parameters:
+ - description: serviceName
+ example: DroneIdentifier
explode: false
+ in: path
+ name: serviceName
+ required: true
schema:
type: string
- example: DroneIdentifier
+ style: simple
responses:
"200":
- description: Service
content:
application/json:
schema:
$ref: '#/components/schemas/service'
+ description: Service
"404":
- description: Service is not found
content:
application/json:
schema:
$ref: '#/components/schemas/error_information'
- deprecated: false
- put:
+ description: Service is not found
+ summary: Individual Service
tags:
- rAPP Catalogue API
- summary: Create or update a Service
+ put:
+ deprecated: false
operationId: putIndividualService
parameters:
- - name: serviceName
+ - example: DroneIdentifier
+ explode: false
in: path
+ name: serviceName
required: true
- style: simple
- explode: false
schema:
type: string
- example: DroneIdentifier
+ style: simple
requestBody:
- description: Service to create/update
content:
application/json:
schema:
$ref: '#/components/schemas/inputService'
+ description: Service to create/update
required: true
responses:
"200":
headers:
Location:
description: URL to the created Service
- style: simple
explode: false
schema:
type: string
+ style: simple
"400":
- description: Provided service is not correct
content:
application/json:
- schema:
- $ref: '#/components/schemas/error_information'
example:
detail: "Service is missing required property: version"
status: 400
- deprecated: false
- delete:
+ schema:
+ $ref: '#/components/schemas/error_information'
+ description: Provided service is not correct
+ summary: Create or update a Service
tags:
- rAPP Catalogue API
- summary: Remove a Service from the catalogue
- operationId: deleteIndividualService
- parameters:
- - name: serviceName
- in: path
- required: true
- style: simple
- explode: false
- schema:
- type: string
- example: DroneIdentifier
- responses:
- "204":
- description: Service deleted
- deprecated: false
components:
schemas:
inputService:
- title: inputService
- required:
- - version
- type: object
+ description: A Service to register
properties:
version:
- type: string
description: Version of the Service
example: 1.0.0
- display_name:
type: string
+ display_name:
description: Display name for the Service
example: Drone Identifier
- description:
type: string
+ description:
description: Description of the Service
example: Detects if a UE is a drone
- description: A Service to register
- service:
- title: service
+ type: string
required:
- - name
- - registrationDate
- version
+ title: inputService
type: object
+ service:
+ description: A Service
+ example:
+ name: DroneIdentifier
+ registrationDate: 2020-11-03
+ description: Detects if a UE is a drone
+ display_name: Drone Identifier
+ version: 1.0.0
properties:
name:
- type: string
description: Unique identifier of the Service
example: DroneIdentifier
- version:
type: string
+ version:
description: Version of the Service
example: 1.0.0
- display_name:
type: string
+ display_name:
description: Display name for the Service
example: Drone Identifier
- description:
type: string
+ description:
description: Description of the Service
example: Detects if a UE is a drone
- registrationDate:
type: string
+ registrationDate:
description: Date when the Service was registered in the catalogue
example: 2020-11-03
- description: A Service
- error_information:
- title: error_information
+ type: string
+ required:
+ - name
+ - registrationDate
+ - version
+ title: service
type: object
+ error_information:
+ description: Problem as defined in https://tools.ietf.org/html/rfc7807
properties:
detail:
- type: string
description: A human-readable explanation specific to this occurrence of
the problem.
example: Service not found
+ type: string
status:
- type: integer
description: The HTTP status code for this occurrence of the problem.
- format: int32
example: 404
- description: Problem as defined in https://tools.ietf.org/html/rfc7807
+ format: int32
+ type: integer
+ title: error_information
+ type: object
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
- <version>2.6.2</version>
+ <version>3.0.4</version>
<relativePath />
</parent>
<groupId>org.o-ran-sc.nonrtric.plt</groupId>
</license>
</licenses>
<properties>
- <java.version>11</java.version>
- <swagger-annotations.version>1.5.22</swagger-annotations.version>
- <springfox.version>2.9.2</springfox.version>
+ <java.version>17</java.version>
+ <javax-validation.version>2.0.1.Final</javax-validation.version>
+ <javax-servlet-api.version>3.1.0</javax-servlet-api.version>
+ <javax-annotation-api.version>1.3.2</javax-annotation-api.version>
<jackson-databind-nullable.version>0.2.1</jackson-databind-nullable.version>
- <openapi-generator-maven-plugin.version>5.3.1</openapi-generator-maven-plugin.version>
- <swagger-codegen-maven-plugin.version>3.0.31</swagger-codegen-maven-plugin.version>
+ <openapi-generator-maven-plugin.version>6.0.0</openapi-generator-maven-plugin.version>
<formatter-maven-plugin.version>2.12.2</formatter-maven-plugin.version>
<spotless-maven-plugin.version>1.24.3</spotless-maven-plugin.version>
- <jacoco-maven-plugin.version>0.8.6</jacoco-maven-plugin.version>
- <docker-maven-plugin.version>0.30.0</docker-maven-plugin.version>
+ <jacoco-maven-plugin.version>0.8.8</jacoco-maven-plugin.version>
+ <docker-maven-plugin.version>0.42.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>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
- <groupId>io.springfox</groupId>
- <artifactId>springfox-swagger2</artifactId>
- <version>${springfox.version}</version>
+ <groupId>org.springdoc</groupId>
+ <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
+ <version>2.0.2</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>
+ <groupId>org.springdoc</groupId>
+ <artifactId>springdoc-openapi-ui</artifactId>
+ <version>1.6.15</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
+ <version>${javax-validation.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <version>${javax-servlet-api.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.annotation</groupId>
+ <artifactId>javax.annotation-api</artifactId>
+ <version>${javax-annotation-api.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.apache.httpcomponents</groupId>
- <artifactId>httpclient</artifactId>
+ <groupId>org.apache.httpcomponents.client5</groupId>
+ <artifactId>httpclient5</artifactId>
+ <version>5.2.1</version>
<scope>test</scope>
</dependency>
-
</dependencies>
-
<build>
<plugins>
<plugin>
<version>${openapi-generator-maven-plugin.version}</version>
<executions>
<execution>
+ <id>generate-openapi-java</id>
<goals>
<goal>generate</goal>
</goals>
</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>
+ <id>generate-openapi-yaml</id>
+ <phase>prepare-package</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/api/rac-api.json</inputSpec>
- <language>openapi-yaml</language>
+ <generatorName>openapi-yaml</generatorName>
+ <verbose>false</verbose>
<output>${project.basedir}/api/</output>
<configOptions>
<outputFile>rac-api.yaml</outputFile>
<cleanup>try</cleanup>
<contextDir>${basedir}</contextDir>
<dockerFile>Dockerfile</dockerFile>
+ <filter>false</filter>
<args>
<JAR>${project.build.finalName}.jar</JAR>
</args>
<build>
<contextDir>${basedir}</contextDir>
<dockerFile>Dockerfile</dockerFile>
+ <filter>false</filter>
<args>
<JAR>${project.build.finalName}.jar</JAR>
</args>
import javax.net.ssl.SSLContext;
-import org.apache.http.client.HttpClient;
-import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.ssl.SSLContextBuilder;
+import org.apache.hc.client5.http.classic.HttpClient;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.HttpClients;
+import org.apache.hc.client5.http.impl.io.BasicHttpClientConnectionManager;
+import org.apache.hc.client5.http.socket.ConnectionSocketFactory;
+import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory;
+import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
+import org.apache.hc.core5.http.config.Registry;
+import org.apache.hc.core5.http.config.RegistryBuilder;
+import org.apache.hc.core5.ssl.SSLContextBuilder;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.web.client.TestRestTemplate.HttpClientOption;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.boot.web.server.AbstractConfigurableWebServerFactory;
-import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
@Test
void rest_WithTwoWaySSL_AuthenticatesAndGetsExpectedResponse() throws Exception {
-
SSLContext sslContext = new SSLContextBuilder().loadKeyMaterial(ResourceUtils.getFile(keyStore),
keyStorePassword.toCharArray(), keyStorePassword.toCharArray()).build();
-
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext);
- HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).build();
+ Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()
+ .register("https", socketFactory)
+ .register("http", new PlainConnectionSocketFactory())
+ .build();
+ BasicHttpClientConnectionManager connectionManager = new BasicHttpClientConnectionManager(socketFactoryRegistry);
+ CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
RestTemplateBuilder rtb =
new RestTemplateBuilder().requestFactory(() -> factory).rootUri("https://localhost:" + port);
-
TestRestTemplate template = new TestRestTemplate(rtb, null, null, HttpClientOption.SSL);
-
ResponseEntity<String> responseEntity = template.getForEntity("/services", String.class);
assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
assertEquals("[]", responseEntity.getBody());