Update to JDK 17 & Springboot 3 89/10789/2
authorJohnKeeney <john.keeney@est.tech>
Tue, 28 Mar 2023 16:42:18 +0000 (17:42 +0100)
committerJohn Keeney <john.keeney@est.tech>
Tue, 28 Mar 2023 17:47:02 +0000 (17:47 +0000)
Change-Id: I616592873e5cd270c2d7ba5a031ac6089e7896cb
Signed-off-by: JohnKeeney <john.keeney@est.tech>
Issue-ID: NONRTRIC-841

Dockerfile
api/rac-api.yaml
pom.xml
src/test/java/org/oransc/rappcatalogue/HttpsRequestTest.java

index cdba409..e781888 100644 (file)
 # 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
index 68558a8..96e863c 100644 (file)
@@ -1,5 +1,5 @@
 #  ============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":
@@ -99,100 +115,90 @@ paths:
           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
diff --git a/pom.xml b/pom.xml
index 53815b3..ebaa61b 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
     <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>
index 5e12f13..dea7a40 100644 (file)
@@ -24,10 +24,16 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 
 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;
@@ -38,7 +44,7 @@ import org.springframework.boot.test.web.client.TestRestTemplate;
 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;
@@ -93,18 +99,19 @@ class HttpsRequestTest {
 
     @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());