Fix Sonar issues and IDE suggestions 72/14872/1
authoraravind.est <aravindhan.a@est.tech>
Thu, 4 Sep 2025 13:18:47 +0000 (14:18 +0100)
committeraravind.est <aravindhan.a@est.tech>
Thu, 4 Sep 2025 13:18:47 +0000 (14:18 +0100)
Sonar issues fixed.
IDE suggestions fixed.

Issue-ID: INT-193
Change-Id: I34c35cdbb02d429a4f775efd6c669db5c581faa3
Signed-off-by: aravind.est <aravindhan.a@est.tech>
36 files changed:
api/ics-api.json
api/ics-api.yaml
src/main/java/org/oransc/ics/Application.java
src/main/java/org/oransc/ics/clients/AsyncRestClient.java
src/main/java/org/oransc/ics/clients/AsyncRestClientFactory.java
src/main/java/org/oransc/ics/controllers/ErrorResponse.java
src/main/java/org/oransc/ics/controllers/StatusController.java
src/main/java/org/oransc/ics/controllers/a1e/A1eController.java
src/main/java/org/oransc/ics/controllers/a1e/A1eEiJobInfo.java
src/main/java/org/oransc/ics/controllers/a1e/A1eEiJobStatus.java
src/main/java/org/oransc/ics/controllers/authorization/AuthorizationResult.java
src/main/java/org/oransc/ics/controllers/authorization/SubscriptionAuthRequest.java
src/main/java/org/oransc/ics/controllers/r1consumer/ConsumerController.java
src/main/java/org/oransc/ics/controllers/r1consumer/ConsumerInfoTypeInfo.java
src/main/java/org/oransc/ics/controllers/r1consumer/ConsumerJobInfo.java
src/main/java/org/oransc/ics/controllers/r1consumer/ConsumerJobStatus.java
src/main/java/org/oransc/ics/controllers/r1consumer/ConsumerTypeRegistrationInfo.java
src/main/java/org/oransc/ics/controllers/r1consumer/ConsumerTypeSubscriptionInfo.java
src/main/java/org/oransc/ics/controllers/r1producer/ProducerCallbacks.java
src/main/java/org/oransc/ics/controllers/r1producer/ProducerController.java
src/main/java/org/oransc/ics/controllers/r1producer/ProducerInfoTypeInfo.java
src/main/java/org/oransc/ics/controllers/r1producer/ProducerJobInfo.java
src/main/java/org/oransc/ics/controllers/r1producer/ProducerRegistrationInfo.java
src/main/java/org/oransc/ics/controllers/r1producer/ProducerStatusInfo.java
src/main/java/org/oransc/ics/datastore/S3ObjectStore.java
src/main/java/org/oransc/ics/repository/InfoJob.java
src/main/java/org/oransc/ics/repository/InfoJobs.java
src/main/java/org/oransc/ics/repository/InfoProducer.java
src/main/java/org/oransc/ics/repository/InfoProducers.java
src/main/java/org/oransc/ics/repository/InfoType.java
src/main/java/org/oransc/ics/repository/InfoTypeSubscriptions.java
src/test/java/org/oransc/ics/ApplicationTest.java
src/test/java/org/oransc/ics/MockInformationService.java
src/test/java/org/oransc/ics/clients/AsyncRestClientTest.java
src/test/java/org/oransc/ics/controller/OpenPolicyAgentSimulatorController.java
src/test/java/org/oransc/ics/controller/ProducerSimulatorController.java

index 346ef46..81d8ea6 100644 (file)
                     "description": "Identity of the owner of the job",
                     "type": "string"
                 },
-                "job_definition": {
-                    "description": "Information type specific job data",
-                    "type": "object"
-                },
                 "status_notification_uri": {
                     "description": "The target of Information subscription job status notifications",
                     "type": "string"
+                },
+                "job_definition": {
+                    "description": "Information type specific job data",
+                    "type": "object"
                 }
             }
         },
index 6762bc5..a36dd94 100644 (file)
@@ -1625,12 +1625,12 @@ components:
         job_owner:
           type: string
           description: Identity of the owner of the job
-        job_definition:
-          type: object
-          description: Information type specific job data
         status_notification_uri:
           type: string
           description: The target of Information subscription job status notifications
+        job_definition:
+          type: object
+          description: Information type specific job data
       description: Information for an Information Job
     producer_status:
       required:
index 694bfe3..e3b051d 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2019 Nordix Foundation
+ * Copyright (C) 2019-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,12 +36,9 @@ public class Application {
 
     public static void main(String[] args) {
         ConfigurableApplicationContext context = SpringApplication.run(Application.class);
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                logger.warn("Shutting down, received signal SIGTERM");
-                SpringApplication.exit(context);
-            }
-        });
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            logger.warn("Shutting down, received signal SIGTERM");
+            SpringApplication.exit(context);
+        }));
     }
 }
index 3edabf9..59465a2 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -144,8 +145,7 @@ public class AsyncRestClient {
     }
 
     private void onError(Throwable t) {
-        if (t instanceof WebClientResponseException) {
-            WebClientResponseException e = (WebClientResponseException) t;
+        if (t instanceof WebClientResponseException e) {
             logger.debug("Response error: {}", e.getResponseBodyAsString());
         }
     }
index 64a3ce5..f8452f3 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -37,7 +38,6 @@ import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 import java.util.Collections;
 import java.util.List;
-import java.util.stream.Collectors;
 import javax.net.ssl.KeyManagerFactory;
 
 import org.oransc.ics.configuration.WebClientConfig;
@@ -123,7 +123,7 @@ public class AsyncRestClientFactory {
             List<Certificate> certificateList = Collections.list(trustStore.aliases()).stream() //
                 .filter(alias -> isCertificateEntry(trustStore, alias)) //
                 .map(alias -> getCertificate(trustStore, alias)) //
-                .collect(Collectors.toList());
+                .toList();
             final X509Certificate[] certificates = certificateList.toArray(new X509Certificate[certificateList.size()]);
 
             return SslContextBuilder.forClient() //
@@ -136,7 +136,7 @@ public class AsyncRestClientFactory {
             try {
                 return trustStore.isCertificateEntry(alias);
             } catch (KeyStoreException e) {
-                logger.error("Error reading truststore {}", e.getMessage());
+                logger.error("Error reading truststore for certificate entry {}", e.getMessage());
                 return false;
             }
         }
index 43c5748..052c1a5 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -99,11 +100,8 @@ public class ErrorResponse {
     public static ResponseEntity<Object> create(Throwable e, HttpStatus code) {
         if (e instanceof RuntimeException) {
             code = HttpStatus.INTERNAL_SERVER_ERROR;
-        } else if (e instanceof ServiceException) {
-            ServiceException se = (ServiceException) e;
-            if (se.getHttpStatus() != null) {
-                code = se.getHttpStatus();
-            }
+        } else if (e instanceof ServiceException se && se.getHttpStatus() != null) {
+            code = se.getHttpStatus();
         }
         return create(e.getMessage(), code);
     }
index ef43f8e..fd8c8f1 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -30,10 +31,10 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse;
 import io.swagger.v3.oas.annotations.responses.ApiResponses;
 import io.swagger.v3.oas.annotations.tags.Tag;
 
+import lombok.RequiredArgsConstructor;
 import org.oransc.ics.repository.InfoJobs;
 import org.oransc.ics.repository.InfoProducers;
 import org.oransc.ics.repository.InfoTypes;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
@@ -41,21 +42,20 @@ import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RestController;
 import reactor.core.publisher.Mono;
 
+@SuppressWarnings("java:S6830")
 @RestController("StatusController")
 @Tag(name = StatusController.API_NAME, description = StatusController.API_DESCRIPTION)
+@RequiredArgsConstructor
 public class StatusController {
 
     public static final String API_NAME = "Service status";
     public static final String API_DESCRIPTION = "API for monitoring of the service";
 
-    @Autowired
-    private InfoJobs infoJobs;
+    private final InfoJobs infoJobs;
 
-    @Autowired
-    private InfoTypes infoTypes;
+    private final InfoTypes infoTypes;
 
-    @Autowired
-    private InfoProducers infoProducers;
+    private final InfoProducers infoProducers;
 
     @Schema(name = "service_status_info")
     public static class StatusInfo {
index 879d6d8..bff261a 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,7 +21,6 @@
 
 package org.oransc.ics.controllers.a1e;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 
@@ -34,14 +34,11 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses;
 import io.swagger.v3.oas.annotations.tags.Tag;
 
 import java.lang.invoke.MethodHandles;
-import java.net.URI;
-import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
-import org.json.JSONObject;
-import org.oransc.ics.configuration.ApplicationConfig;
+import lombok.RequiredArgsConstructor;
 import org.oransc.ics.controllers.ErrorResponse;
 import org.oransc.ics.controllers.VoidResponse;
 import org.oransc.ics.controllers.authorization.AuthorizationCheck;
@@ -55,7 +52,6 @@ import org.oransc.ics.repository.InfoType;
 import org.oransc.ics.repository.InfoTypes;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
@@ -70,33 +66,26 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 import reactor.core.publisher.Mono;
 
-@SuppressWarnings("java:S3457") // No need to call "toString()" method as formatting and string ..
+@SuppressWarnings({"java:S3457", "java:S6830"}) // No need to call "toString()" method as formatting and string ..
 @RestController("A1-EI")
 @Tag(name = A1eConsts.CONSUMER_API_NAME, description = A1eConsts.CONSUMER_API_DESCRIPTION)
 @RequestMapping(path = A1eConsts.API_ROOT, produces = MediaType.APPLICATION_JSON_VALUE)
+@RequiredArgsConstructor
 public class A1eController {
 
     private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-    @Autowired
-    ApplicationConfig applicationConfig;
+    private final InfoJobs infoJobs;
 
-    @Autowired
-    private InfoJobs infoJobs;
+    private final InfoTypes infoTypes;
 
-    @Autowired
-    private InfoTypes infoTypes;
+    private final InfoProducers infoProducers;
 
-    @Autowired
-    private InfoProducers infoProducers;
+    private final ProducerCallbacks producerCallbacks;
 
-    @Autowired
-    ProducerCallbacks producerCallbacks;
+    private final AuthorizationCheck authorization;
 
-    @Autowired
-    private AuthorizationCheck authorization;
-
-    private static Gson gson = new GsonBuilder().disableHtmlEscaping().create();
+    private static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();
 
     @GetMapping(path = "/eitypes", produces = MediaType.APPLICATION_JSON_VALUE)
     @Operation(summary = "EI type identifiers", description = "")
@@ -293,7 +282,7 @@ public class A1eController {
     public Mono<ResponseEntity<Object>> putIndividualEiJob( //
         @PathVariable("eiJobId") String eiJobId, //
         @RequestBody A1eEiJobInfo eiJobObject, //
-        @RequestHeader Map<String, String> headers) throws ServiceException {
+        @RequestHeader Map<String, String> headers) {
 
         final boolean isNewJob = this.infoJobs.get(eiJobId) == null;
         try {
@@ -302,7 +291,7 @@ public class A1eController {
             return authorization.doAccessControl(headers, eiType, eiJobObject.jobDefinition, AccessType.WRITE) //
                 .flatMap(x -> validatePutEiJob(eiJobId, eiType, eiJobObject)) //
                 .flatMap(job -> startEiJob(job, eiType)) //
-                .doOnNext(newEiJob -> this.infoJobs.put(newEiJob)) //
+                .doOnNext(this.infoJobs::put) //
                 .map(newEiJob -> new ResponseEntity<>(isNewJob ? HttpStatus.CREATED : HttpStatus.OK)) //
                 .onErrorResume(
                     throwable -> Mono.just(ErrorResponse.create(throwable, HttpStatus.INTERNAL_SERVER_ERROR)));
@@ -320,9 +309,9 @@ public class A1eController {
 
     private Mono<InfoJob> validatePutEiJob(String eiJobId, InfoType eiType, A1eEiJobInfo eiJobInfo) {
         try {
-            validateJsonObjectAgainstSchema(eiType.getJobDataSchema(), eiJobInfo.jobDefinition);
-            validateUri(eiJobInfo.jobResultUri);
-            validateUri(eiJobInfo.statusNotificationUri);
+            this.infoJobs.validateJsonObjectAgainstSchema(eiType.getJobDataSchema(), eiJobInfo.jobDefinition);
+            this.infoJobs.validateUri(eiJobInfo.jobResultUri);
+            this.infoJobs.validateUri(eiJobInfo.statusNotificationUri);
 
             InfoJob existingEiJob = this.infoJobs.get(eiJobId);
             if (existingEiJob != null) {
@@ -337,31 +326,6 @@ public class A1eController {
         }
     }
 
-    private void validateUri(String url) throws URISyntaxException, ServiceException {
-        if (url != null && !url.isEmpty()) {
-            URI uri = new URI(url);
-            if (!uri.isAbsolute()) {
-                throw new ServiceException("URI: " + url + " is not absolute", HttpStatus.BAD_REQUEST);
-            }
-        }
-    }
-
-    private void validateJsonObjectAgainstSchema(Object schemaObj, Object object) throws ServiceException {
-        try {
-            ObjectMapper mapper = new ObjectMapper();
-
-            String schemaAsString = mapper.writeValueAsString(schemaObj);
-            JSONObject schemaJSON = new JSONObject(schemaAsString);
-            var schema = org.everit.json.schema.loader.SchemaLoader.load(schemaJSON);
-
-            String objectAsString = mapper.writeValueAsString(object);
-            JSONObject json = new JSONObject(objectAsString);
-            schema.validate(json);
-        } catch (Exception e) {
-            throw new ServiceException("Json validation failure " + e.toString(), HttpStatus.BAD_REQUEST);
-        }
-    }
-
     private InfoJob toEiJob(A1eEiJobInfo info, String id, InfoType type) {
         return InfoJob.builder() //
             .id(id) //
index 2a042f1..913b973 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -28,27 +29,27 @@ import io.swagger.v3.oas.annotations.media.Schema;
 @Schema(name = "EiJobObject", description = "Information for an Enrichment Information Job")
 public class A1eEiJobInfo {
 
-    @Schema(name = "eiTypeId", description = "EI type Idenitifier of the EI job", required = true)
+    @Schema(name = "eiTypeId", description = "EI type Idenitifier of the EI job", requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("eiTypeId")
     @JsonProperty(value = "eiTypeId", required = true)
     public String eiTypeId = "";
 
-    @Schema(name = "jobOwner", description = "Identity of the owner of the job", required = true)
+    @Schema(name = "jobOwner", description = "Identity of the owner of the job", requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("jobOwner")
     @JsonProperty(value = "jobOwner", required = true)
     public String owner = "";
 
-    @Schema(name = "jobDefinition", description = "EI type specific job data", required = true)
+    @Schema(name = "jobDefinition", description = "EI type specific job data", requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("jobDefinition")
     @JsonProperty(value = "jobDefinition", required = true)
     public Object jobDefinition;
 
-    @Schema(name = "jobResultUri", description = "The target URI of the EI data", required = true)
+    @Schema(name = "jobResultUri", description = "The target URI of the EI data", requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("jobResultUri")
     @JsonProperty(value = "jobResultUri", required = true)
     public String jobResultUri = "";
 
-    @Schema(name = "statusNotificationUri", description = "The target of EI job status notifications", required = false)
+    @Schema(name = "statusNotificationUri", description = "The target of EI job status notifications", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
     @SerializedName("jobStatusNotificationUri")
     @JsonProperty(value = "jobStatusNotificationUri", required = false)
     public String statusNotificationUri = "";
index e635f2e..1d01427 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2019 Nordix Foundation
+ * Copyright (C) 2019-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -37,7 +38,7 @@ public class A1eEiJobStatus {
         + "ENABLED: the A1-EI producer is able to deliver EI result for the EI job <br/>" //
         + "DISABLED: the A1-EI producer is unable to deliver EI result for the EI job";
 
-    @Schema(name = "eiJobStatus", description = OPERATIONAL_STATE_DESCRIPTION, required = true)
+    @Schema(name = "eiJobStatus", description = OPERATIONAL_STATE_DESCRIPTION, requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("eiJobStatus")
     @JsonProperty(value = "eiJobStatus", required = true)
     public EiJobStatusValues state;
index ef986ea..f1919d5 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2022 Nordix Foundation
+ * Copyright (C) 2022-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,7 +32,7 @@ import lombok.Getter;
 @Builder
 public class AuthorizationResult {
 
-    @Schema(name = "result", description = "If true, the access is granted", required = true)
+    @Schema(name = "result", description = "If true, the access is granted", requiredMode = Schema.RequiredMode.REQUIRED)
     @JsonProperty(value = "result", required = true)
     @SerializedName("result")
     @Getter
index 1b07ac9..329db29 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2022 Nordix Foundation
+ * Copyright (C) 2022-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -51,29 +52,29 @@ public class SubscriptionAuthRequest {
             READ, WRITE
         }
 
-        @Schema(name = "access_type", description = "Access type", required = true)
+        @Schema(name = "access_type", description = "Access type", requiredMode = Schema.RequiredMode.REQUIRED)
         @JsonProperty(value = "access_type", required = true)
         @SerializedName("access_type")
         private AccessType accessType;
 
-        @Schema(name = "info_type_id", description = "Information type identifier", required = true)
+        @Schema(name = "info_type_id", description = "Information type identifier", requiredMode = Schema.RequiredMode.REQUIRED)
         @SerializedName("info_type_id")
         @JsonProperty(value = "info_type_id", required = true)
         private String infoTypeId;
 
-        @Schema(name = "job_definition", description = "Information type specific job data", required = true)
+        @Schema(name = "job_definition", description = "Information type specific job data", requiredMode = Schema.RequiredMode.REQUIRED)
         @SerializedName("job_definition")
         @JsonProperty(value = "job_definition", required = true)
         private Object jobDefinition;
 
-        @Schema(name = "auth_token", description = "Authorization token", required = true)
+        @Schema(name = "auth_token", description = "Authorization token", requiredMode = Schema.RequiredMode.REQUIRED)
         @SerializedName("auth_token")
         @JsonProperty(value = "auth_token", required = true)
         private String authToken;
 
     }
 
-    @Schema(name = "input", description = "Input", required = true)
+    @Schema(name = "input", description = "Input", requiredMode = Schema.RequiredMode.REQUIRED)
     @JsonProperty(value = "input", required = true)
     @SerializedName("input")
     private Input input;
index b48ac35..4dbcc43 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,7 +21,6 @@
 
 package org.oransc.ics.controllers.r1consumer;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 
@@ -34,14 +34,11 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses;
 import io.swagger.v3.oas.annotations.tags.Tag;
 
 import java.lang.invoke.MethodHandles;
-import java.net.URI;
-import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
-import org.json.JSONObject;
 import org.oransc.ics.controllers.ErrorResponse;
 import org.oransc.ics.controllers.VoidResponse;
 import org.oransc.ics.controllers.authorization.AuthorizationCheck;
@@ -73,7 +70,7 @@ import org.springframework.web.bind.annotation.RestController;
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 
-@SuppressWarnings("java:S3457") // No need to call "toString()" method as formatting and string ..
+@SuppressWarnings({"java:S3457", "java:S6830"}) // No need to call "toString()" method as formatting and string ..
 @RestController("Consumer API")
 @Tag(name = ConsumerConsts.CONSUMER_API_NAME, description = ConsumerConsts.CONSUMER_API_DESCRIPTION)
 @RequestMapping(path = ConsumerConsts.API_ROOT, produces = MediaType.APPLICATION_JSON_VALUE)
@@ -489,9 +486,9 @@ public class ConsumerController {
 
     private Mono<InfoJob> validatePutInfoJob(String jobId, InfoType infoType, ConsumerJobInfo jobInfo) {
         try {
-            validateJsonObjectAgainstSchema(infoType.getJobDataSchema(), jobInfo.jobDefinition);
-            validateUri(jobInfo.statusNotificationUri);
-            validateUri(jobInfo.jobResultUri);
+            this.infoJobs.validateJsonObjectAgainstSchema(infoType.getJobDataSchema(), jobInfo.jobDefinition);
+            this.infoJobs.validateUri(jobInfo.statusNotificationUri);
+            this.infoJobs.validateUri(jobInfo.jobResultUri);
 
             InfoJob existingJob = this.infoJobs.get(jobId);
             if (existingJob != null) {
@@ -507,31 +504,6 @@ public class ConsumerController {
         }
     }
 
-    private void validateUri(String url) throws URISyntaxException, ServiceException {
-        if (url != null && !url.isEmpty()) {
-            URI uri = new URI(url);
-            if (!uri.isAbsolute()) {
-                throw new ServiceException("URI: " + url + " is not absolute", HttpStatus.BAD_REQUEST);
-            }
-        }
-    }
-
-    private void validateJsonObjectAgainstSchema(Object schemaObj, Object object) throws ServiceException {
-        try {
-            ObjectMapper mapper = new ObjectMapper();
-
-            String schemaAsString = mapper.writeValueAsString(schemaObj);
-            JSONObject schemaJSON = new JSONObject(schemaAsString);
-            var schema = org.everit.json.schema.loader.SchemaLoader.load(schemaJSON);
-
-            String objectAsString = mapper.writeValueAsString(object);
-            JSONObject json = new JSONObject(objectAsString);
-            schema.validate(json);
-        } catch (Exception e) {
-            throw new ServiceException("Json validation failure " + e.toString(), HttpStatus.BAD_REQUEST);
-        }
-    }
-
     private InfoJob toInfoJob(ConsumerJobInfo info, String id, InfoType type) {
         return InfoJob.builder() //
             .id(id) //
index 1f11c15..8675efe 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -28,7 +29,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
 @Schema(name = "consumer_information_type", description = "Information for an Information type")
 public class ConsumerInfoTypeInfo {
 
-    @Schema(name = "job_data_schema", description = "Json schema for the job data", required = true)
+    @Schema(name = "job_data_schema", description = "Json schema for the job data", requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("job_data_schema")
     @JsonProperty(value = "job_data_schema", required = true)
     public Object jobDataSchema;
@@ -42,12 +43,12 @@ public class ConsumerInfoTypeInfo {
         + "ENABLED: one or several producers for the information type are available <br/>" //
         + "DISABLED: no producers for the information type are available";
 
-    @Schema(name = "type_status", description = STATUS_DESCRIPTION, required = true)
+    @Schema(name = "type_status", description = STATUS_DESCRIPTION, requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("type_status")
     @JsonProperty(value = "type_status", required = true)
     public ConsumerTypeStatusValues state;
 
-    @Schema(name = "no_of_producers", description = "The number of registered producers for the type", required = true)
+    @Schema(name = "no_of_producers", description = "The number of registered producers for the type", requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("no_of_producers")
     @JsonProperty(value = "no_of_producers", required = true)
     public int noOfProducers;
index 62483d0..fcac7a8 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -33,34 +34,34 @@ public class ConsumerJobInfo {
     @Schema(
         name = "info_type_id",
         description = "Information type Idenitifier of the subscription job",
-        required = true)
+            requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("info_type_id")
     @JsonProperty(value = "info_type_id", required = true)
     public String infoTypeId = "";
 
-    @Schema(name = "job_owner", description = "Identity of the owner of the job", required = true)
-    @SerializedName("job_owner")
-    @JsonProperty(value = "job_owner", required = true)
-    public String owner = "";
-
-    @Schema(name = "job_definition", description = "Information type specific job data", required = true)
-    @SerializedName("job_definition")
-    @JsonProperty(value = "job_definition", required = true)
-    public Object jobDefinition;
-
-    @Schema(name = "job_result_uri", description = "The target URI of the subscribed information", required = true)
+    @Schema(name = "job_result_uri", description = "The target URI of the subscribed information", requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("job_result_uri")
     @JsonProperty(value = "job_result_uri", required = false)
     public String jobResultUri = "";
 
+    @Schema(name = "job_owner", description = "Identity of the owner of the job", requiredMode = Schema.RequiredMode.REQUIRED)
+    @SerializedName("job_owner")
+    @JsonProperty(value = "job_owner", required = true)
+    public String owner = "";
+
     @Schema(
         name = "status_notification_uri",
         description = "The target of Information subscription job status notifications",
-        required = false)
+            requiredMode = Schema.RequiredMode.NOT_REQUIRED)
     @SerializedName("status_notification_uri")
     @JsonProperty(value = "status_notification_uri", required = false)
     public String statusNotificationUri = "";
 
+    @Schema(name = "job_definition", description = "Information type specific job data", requiredMode = Schema.RequiredMode.REQUIRED)
+    @SerializedName("job_definition")
+    @JsonProperty(value = "job_definition", required = true)
+    public Object jobDefinition;
+
     public ConsumerJobInfo() {
     }
 
index 78657fd..0a91df1 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2019 Nordix Foundation
+ * Copyright (C) 2019-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -41,12 +42,12 @@ public class ConsumerJobStatus {
 
     private static final String PRODUCERS_DESCRIPTION = "An array of all registered Information Producer Identifiers.";
 
-    @Schema(name = "info_job_status", description = OPERATIONAL_STATE_DESCRIPTION, required = true)
+    @Schema(name = "info_job_status", description = OPERATIONAL_STATE_DESCRIPTION, requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("info_job_status")
     @JsonProperty(value = "info_job_status", required = true)
     public InfoJobStatusValues state;
 
-    @Schema(name = "producers", description = PRODUCERS_DESCRIPTION, required = true)
+    @Schema(name = "producers", description = PRODUCERS_DESCRIPTION, requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("producers")
     @JsonProperty(value = "producers", required = true)
     public Collection<String> producers;
index fa4ea99..ac127be 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -28,12 +29,12 @@ import io.swagger.v3.oas.annotations.media.Schema;
 @Schema(name = "consumer_type_registration_info", description = "Information for an Information type")
 public class ConsumerTypeRegistrationInfo {
 
-    @Schema(name = "info_type_id", description = "Information type identifier", required = true)
+    @Schema(name = "info_type_id", description = "Information type identifier", requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("info_type_id")
     @JsonProperty(value = "info_type_id", required = true)
     public String infoTypeId;
 
-    @Schema(name = "job_data_schema", description = "Json schema for the job data", required = true)
+    @Schema(name = "job_data_schema", description = "Json schema for the job data", requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("job_data_schema")
     @JsonProperty(value = "job_data_schema", required = true)
     public Object jobDataSchema;
@@ -47,7 +48,7 @@ public class ConsumerTypeRegistrationInfo {
         + "REGISTERED: the information type has been registered <br/>" //
         + "DEREGISTERED: the information type has been removed";
 
-    @Schema(name = "status", description = REGISTRATION_DESCRIPTION, required = true)
+    @Schema(name = "status", description = REGISTRATION_DESCRIPTION, requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("status")
     @JsonProperty(value = "status", required = true)
     public ConsumerTypeStatusValues state;
index fc3c35d..10b80d9 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -32,12 +33,12 @@ import lombok.ToString;
 @Schema(name = "consumer_type_subscription_info", description = "Information for an information type subscription")
 public class ConsumerTypeSubscriptionInfo {
 
-    @Schema(name = "status_result_uri", description = "The target URI of the subscribed information", required = true)
+    @Schema(name = "status_result_uri", description = "The target URI of the subscribed information", requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("status_result_uri")
     @JsonProperty(value = "status_result_uri", required = true)
     public String statusResultUri = "";
 
-    @Schema(name = "owner", description = "Identity of the owner of the subscription", required = true)
+    @Schema(name = "owner", description = "Identity of the owner of the subscription", requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("owner")
     @JsonProperty(value = "owner", required = true)
     public String owner = "";
index 25e20e3..a142032 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -27,6 +28,7 @@ import java.lang.invoke.MethodHandles;
 import java.time.Duration;
 import java.util.Collection;
 
+import java.util.List;
 import org.oransc.ics.clients.AsyncRestClient;
 import org.oransc.ics.clients.AsyncRestClientFactory;
 import org.oransc.ics.clients.SecurityContext;
@@ -50,7 +52,7 @@ import reactor.util.retry.Retry;
 public class ProducerCallbacks {
 
     private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-    private static Gson gson = new GsonBuilder().disableHtmlEscaping().create();
+    private static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();
 
     private final AsyncRestClient restClient;
 
@@ -87,14 +89,14 @@ public class ProducerCallbacks {
         return Flux.fromIterable(getProducersForJob(type, infoProducers)) //
             .flatMap(infoProducer -> startInfoJob(infoProducer, infoJob, retrySpec)) //
             .collectList() //
-            .map(okResponses -> Integer.valueOf(okResponses.size())); //
+            .map(List::size); //
     }
 
     /**
      * Start all jobs for one producer
      *
-     * @param producer
-     * @param infoJobs
+     * @param producer information producer
+     * @param infoJobs information jobs
      */
     public Flux<String> startInfoJobs(InfoProducer producer, InfoJobs infoJobs) {
         final int maxNoOfParalellRequests = 10;
index b2a7d52..bfb0837 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -41,6 +42,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import lombok.RequiredArgsConstructor;
 import org.oransc.ics.controllers.ErrorResponse;
 import org.oransc.ics.controllers.VoidResponse;
 import org.oransc.ics.exceptions.ServiceException;
@@ -54,7 +56,6 @@ import org.oransc.ics.repository.InfoTypeSubscriptions;
 import org.oransc.ics.repository.InfoTypes;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
@@ -66,25 +67,22 @@ import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
-@SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally
+@SuppressWarnings({"squid:S2629", "java:S6830"}) // Invoke method(s) only conditionally
 @RestController("Producer registry")
 @Tag(name = ProducerConsts.PRODUCER_API_NAME, description = ProducerConsts.PRODUCER_API_DESCRIPTION)
+@RequiredArgsConstructor
 public class ProducerController {
 
-    private static Gson gson = new GsonBuilder().disableHtmlEscaping().create();
+    private static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();
     private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-    @Autowired
-    private InfoJobs infoJobs;
+    private final InfoJobs infoJobs;
 
-    @Autowired
-    private InfoTypes infoTypes;
+    private final InfoTypes infoTypes;
 
-    @Autowired
-    private InfoProducers infoProducers;
+    private final InfoProducers infoProducers;
 
-    @Autowired
-    private InfoTypeSubscriptions typeSubscriptions;
+    private final InfoTypeSubscriptions typeSubscriptions;
 
     @GetMapping(path = ProducerConsts.API_ROOT + "/info-types", produces = MediaType.APPLICATION_JSON_VALUE) //
     @Operation(summary = "Info Type identifiers", description = "") //
index 45c5a93..4dd3c68 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -28,7 +29,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
 @Schema(name = "producer_info_type_info", description = "Information for an Information Type")
 public class ProducerInfoTypeInfo {
 
-    @Schema(name = "info_job_data_schema", description = "Json schema for the job data", required = true)
+    @Schema(name = "info_job_data_schema", description = "Json schema for the job data", requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("info_job_data_schema")
     @JsonProperty(value = "info_job_data_schema", required = true)
     public Object jobDataSchema;
@@ -36,7 +37,7 @@ public class ProducerInfoTypeInfo {
     @Schema(
         name = "info_type_information",
         description = "Type specific information for the information type",
-        required = false)
+            requiredMode = Schema.RequiredMode.NOT_REQUIRED)
     @SerializedName("info_type_information")
     @JsonProperty(value = "info_type_information", required = false)
     public Object typeSpecificInformation;
index 6dc9717..d64de41 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -30,7 +31,7 @@ import org.oransc.ics.repository.InfoJob;
 @Schema(name = "producer_info_job_request", description = "The body of the Information Producer callbacks for Information Job creation and deletion")
 public class ProducerJobInfo {
 
-    @Schema(name = "info_job_identity", description = "Identity of the Information Job", required = true)
+    @Schema(name = "info_job_identity", description = "Identity of the Information Job", requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("info_job_identity")
     @JsonProperty("info_job_identity")
     public String id = "";
index f2c7ad1..9626077 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -33,12 +34,12 @@ import lombok.ToString;
 @Schema(name = "producer_registration_info", description = "Information for an Information Producer")
 public class ProducerRegistrationInfo {
 
-    @Schema(name = "supported_info_types", description = "Supported Information Type IDs", required = true)
+    @Schema(name = "supported_info_types", description = "Supported Information Type IDs", requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("supported_info_types")
     @JsonProperty(value = "supported_info_types", required = true)
     public Collection<String> supportedTypeIds;
 
-    @Schema(name = "info_job_callback_url", description = "callback for Information Job", required = true)
+    @Schema(name = "info_job_callback_url", description = "callback for Information Job", requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("info_job_callback_url")
     @JsonProperty(value = "info_job_callback_url", required = true)
     public String jobCallbackUrl = "";
@@ -46,7 +47,7 @@ public class ProducerRegistrationInfo {
     @Schema(
         name = "info_producer_supervision_callback_url",
         description = "callback for producer supervision",
-        required = true)
+            requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("info_producer_supervision_callback_url")
     @JsonProperty(value = "info_producer_supervision_callback_url", required = true)
     public String producerSupervisionCallbackUrl = "";
index 9a04023..9877569 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2019 Nordix Foundation
+ * Copyright (C) 2019-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -33,11 +34,12 @@ public class ProducerStatusInfo {
         ENABLED, DISABLED
     }
 
-    private static final String OPERATIONAL_STATE_DESCRIPTION = "Operational state, values:\n" //
-        + "ENABLED: the producer is operational\n" //
-        + "DISABLED: the producer is not operational";
+    private static final String OPERATIONAL_STATE_DESCRIPTION = """
+        Operational state, values:
+        ENABLED: the producer is operational
+        DISABLED: the producer is not operational""";
 
-    @Schema(name = "operational_state", description = OPERATIONAL_STATE_DESCRIPTION, required = true)
+    @Schema(name = "operational_state", description = OPERATIONAL_STATE_DESCRIPTION, requiredMode = Schema.RequiredMode.REQUIRED)
     @SerializedName("operational_state")
     @JsonProperty(value = "operational_state", required = true)
     public final OperationalState opState;
index 8d564a6..b35531c 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2022 Nordix Foundation
+ * Copyright (C) 2022-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -42,7 +43,6 @@ import software.amazon.awssdk.services.s3.S3AsyncClient;
 import software.amazon.awssdk.services.s3.S3AsyncClientBuilder;
 import software.amazon.awssdk.services.s3.model.CreateBucketRequest;
 import software.amazon.awssdk.services.s3.model.CreateBucketResponse;
-import software.amazon.awssdk.services.s3.model.Delete;
 import software.amazon.awssdk.services.s3.model.DeleteBucketRequest;
 import software.amazon.awssdk.services.s3.model.DeleteBucketResponse;
 import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
@@ -72,11 +72,10 @@ class S3ObjectStore implements DataStore {
         getS3AsynchClient(applicationConfig);
     }
 
-    private static synchronized S3AsyncClient getS3AsynchClient(ApplicationConfig applicationConfig) {
+    private static synchronized void getS3AsynchClient(ApplicationConfig applicationConfig) {
         if (applicationConfig.isS3Enabled() && s3AsynchClient == null) {
             s3AsynchClient = getS3AsyncClientBuilder(applicationConfig).build();
         }
-        return s3AsynchClient;
     }
 
     private static S3AsyncClientBuilder getS3AsyncClientBuilder(ApplicationConfig applicationConfig) {
@@ -168,13 +167,9 @@ class S3ObjectStore implements DataStore {
             oids.add(oid);
         }
 
-        Delete delete = Delete.builder() //
-            .objects(oids) //
-            .build();
-
         DeleteObjectsRequest request = DeleteObjectsRequest.builder() //
             .bucket(bucket()) //
-            .delete(delete) //
+            .delete(delete -> delete.objects(oids)) //
             .build();
 
         CompletableFuture<DeleteObjectsResponse> future = s3AsynchClient.deleteObjects(request);
index e9a43e8..26f19c5 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2019 Nordix Foundation
+ * Copyright (C) 2019-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -100,8 +101,8 @@ public class InfoJob {
 
     @Override
     public boolean equals(Object o) {
-        if (o instanceof InfoJob) {
-            return this.id.equals(((InfoJob) o).id);
+        if (o instanceof InfoJob infoJob) {
+            return this.id.equals(infoJob.id);
         }
         return this.id.equals(o);
     }
index ff5a403..05e12ed 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2019 Nordix Foundation
+ * Copyright (C) 2019-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 package org.oransc.ics.repository;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.TypeAdapterFactory;
 
 import java.lang.invoke.MethodHandles;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
@@ -32,6 +36,7 @@ import java.util.Objects;
 import java.util.ServiceLoader;
 import java.util.Vector;
 
+import org.json.JSONObject;
 import org.oransc.ics.configuration.ApplicationConfig;
 import org.oransc.ics.controllers.r1producer.ProducerCallbacks;
 import org.oransc.ics.datastore.DataStore;
@@ -47,10 +52,10 @@ import reactor.core.publisher.Mono;
  * Dynamic representation of all existing Information Jobs.
  */
 public class InfoJobs {
-    private Map<String, InfoJob> allEiJobs = new HashMap<>();
+    private final Map<String, InfoJob> allEiJobs = new HashMap<>();
 
-    private MultiMap<String, InfoJob> jobsByType = new MultiMap<>();
-    private MultiMap<String, InfoJob> jobsByOwner = new MultiMap<>();
+    private final MultiMap<String, InfoJob> jobsByType = new MultiMap<>();
+    private final MultiMap<String, InfoJob> jobsByOwner = new MultiMap<>();
     private final Gson gson;
     private final InfoTypes infoTypes;
 
@@ -176,6 +181,31 @@ public class InfoJobs {
         dataStore.deleteAllData().flatMap(s -> dataStore.createDataStore()).blockLast();
     }
 
+    public void validateUri(String url) throws URISyntaxException, ServiceException {
+        if (url != null && !url.isEmpty()) {
+            URI uri = new URI(url);
+            if (!uri.isAbsolute()) {
+                throw new ServiceException("URI: " + url + " is not absolute", HttpStatus.BAD_REQUEST);
+            }
+        }
+    }
+
+    public void validateJsonObjectAgainstSchema(Object schemaObj, Object object) throws ServiceException {
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+
+            String schemaAsString = mapper.writeValueAsString(schemaObj);
+            JSONObject schemaJSON = new JSONObject(schemaAsString);
+            var schema = org.everit.json.schema.loader.SchemaLoader.load(schemaJSON);
+
+            String objectAsString = mapper.writeValueAsString(object);
+            JSONObject json = new JSONObject(objectAsString);
+            schema.validate(json);
+        } catch (Exception e) {
+            throw new ServiceException("Json validation failure " + e, HttpStatus.BAD_REQUEST);
+        }
+    }
+
     private void doPut(InfoJob job) {
         InfoJob prevDefinition = this.get(job.getId());
         if (prevDefinition == null) {
index 3fa278e..a284c27 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2019 Nordix Foundation
+ * Copyright (C) 2019-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -88,8 +89,8 @@ public class InfoProducer {
 
     @Override
     public boolean equals(Object o) {
-        if (o instanceof InfoProducer) {
-            return this.id.equals(((InfoProducer) o).id);
+        if (o instanceof InfoProducer infoProducer) {
+            return this.id.equals(infoProducer.id);
         }
         return this.id.equals(o);
     }
index 17ad366..7adc7e5 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2019 Nordix Foundation
+ * Copyright (C) 2019-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -54,7 +55,7 @@ public class InfoProducers {
         this.infoTypes = infoTypes;
     }
 
-    public InfoProducer registerProducer(InfoProducerRegistrationInfo producerInfo) {
+    public void registerProducer(InfoProducerRegistrationInfo producerInfo) {
         final String producerId = producerInfo.getId();
         InfoProducer previousDefinition = this.get(producerId);
 
@@ -71,7 +72,6 @@ public class InfoProducers {
             .flatMapMany(list -> consumerCallbacks.notifyJobStatus(previousTypes, this)) //
             .subscribe();
 
-        return producer;
     }
 
     private InfoProducer createProducer(InfoProducerRegistrationInfo producerInfo) {
index db7e26b..519bdef 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2019 Nordix Foundation
+ * Copyright (C) 2019-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -197,8 +198,8 @@ public class InfoType {
 
     @Override
     public boolean equals(Object o) {
-        if (o instanceof InfoType) {
-            return this.id.equals(((InfoType) o).id);
+        if (o instanceof InfoType infoType) {
+            return this.id.equals(infoType.id);
         }
         return this.id.equals(o);
     }
index a7961f8..786a335 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2019 Nordix Foundation
+ * Copyright (C) 2019-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -85,8 +86,8 @@ public class InfoTypeSubscriptions {
 
         @Override
         public boolean equals(Object o) {
-            if (o instanceof SubscriptionInfo) {
-                return this.id.equals(((SubscriptionInfo) o).id);
+            if (o instanceof SubscriptionInfo subscriptionInfo) {
+                return this.id.equals(subscriptionInfo.id);
             }
             return this.id.equals(o);
         }
index 42b8696..a0d39b5 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,8 +25,6 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.awaitility.Awaitility.await;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonMappingException;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.JsonParser;
@@ -119,10 +118,10 @@ import reactor.test.StepVerifier;
 class ApplicationTest {
     private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-    private final String TYPE_ID = "typeId_1.9.9";
-    private final String PRODUCER_ID = "producerId";
-    private final String EI_JOB_PROPERTY = "\"property1\"";
-    private final String JOB_ID = "jobId";
+    private final String typeId = "typeId_1.9.9";
+    private final String producerId = "producerId";
+    private final String eiJobProperty = "\"property1\"";
+    private final String jobId = "jobId";
 
     @Autowired
     ApplicationContext context;
@@ -216,7 +215,7 @@ class ApplicationTest {
 
     @Test
     void a1eGetEiTypes() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, "test");
+        putInfoProducerWithOneType(producerId, "test");
         String url = A1eConsts.API_ROOT + "/eitypes";
         String rsp = restClient().get(url).block();
         assertThat(rsp).isEqualTo("[\"test\"]");
@@ -224,7 +223,7 @@ class ApplicationTest {
 
     @Test
     void testTrustValidation() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, "test");
+        putInfoProducerWithOneType(producerId, "test");
         String url = A1eConsts.API_ROOT + "/eitypes";
         String rsp = restClient(true).get(url).block();
         assertThat(rsp).isEqualTo("[\"test\"]");
@@ -232,7 +231,7 @@ class ApplicationTest {
 
     @Test
     void consumerGetInfoTypes() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, "test");
+        putInfoProducerWithOneType(producerId, "test");
         String url = ConsumerConsts.API_ROOT + "/info-types";
         String rsp = restClient().get(url).block();
         assertThat(rsp).isEqualTo("[\"test\"]");
@@ -240,10 +239,10 @@ class ApplicationTest {
 
     @Test
     void consumerDeleteJobsForOneOwner() throws Exception {
-        putInfoProducerWithOneType("producer1", TYPE_ID);
-        putInfoJob(TYPE_ID, "jobId1");
-        putInfoJob(TYPE_ID, "jobId2");
-        putEiJob(TYPE_ID, "jobId3", "otherOwner");
+        putInfoProducerWithOneType("producer1", typeId);
+        putInfoJob(typeId, "jobId1");
+        putInfoJob(typeId, "jobId2");
+        putEiJob(typeId, "jobId3", "otherOwner");
         assertThat(this.infoJobs.size()).isEqualTo(3);
         String url = ConsumerConsts.API_ROOT + "/info-jobs?owner=owner";
         restClient().delete(url).block();
@@ -255,14 +254,14 @@ class ApplicationTest {
     }
 
     @Test
-    void a1eGetEiTypesEmpty() throws Exception {
+    void a1eGetEiTypesEmpty() {
         String url = A1eConsts.API_ROOT + "/eitypes";
         String rsp = restClient().get(url).block();
         assertThat(rsp).isEqualTo("[]");
     }
 
     @Test
-    void consumerGetEiTypesEmpty() throws Exception {
+    void consumerGetEiTypesEmpty() {
         String url = ConsumerConsts.API_ROOT + "/info-types";
         String rsp = restClient().get(url).block();
         assertThat(rsp).isEqualTo("[]");
@@ -270,7 +269,7 @@ class ApplicationTest {
 
     @Test
     void a1eGetEiType() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, "test");
+        putInfoProducerWithOneType(producerId, "test");
         String url = A1eConsts.API_ROOT + "/eitypes/test";
         String rsp = restClient().get(url).block();
         A1eEiTypeInfo info = gson.fromJson(rsp, A1eEiTypeInfo.class);
@@ -279,7 +278,7 @@ class ApplicationTest {
 
     @Test
     void consumerGetEiType() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, "test");
+        putInfoProducerWithOneType(producerId, "test");
         String url = ConsumerConsts.API_ROOT + "/info-types/test";
         String rsp = restClient().get(url).block();
         ConsumerInfoTypeInfo info = gson.fromJson(rsp, ConsumerInfoTypeInfo.class);
@@ -290,23 +289,23 @@ class ApplicationTest {
     }
 
     @Test
-    void a1eGetEiTypeNotFound() throws Exception {
+    void a1eGetEiTypeNotFound() {
         String url = A1eConsts.API_ROOT + "/eitypes/junk";
         testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND, "Information type not found: junk");
     }
 
     @Test
-    void consumerGetEiTypeNotFound() throws Exception {
+    void consumerGetEiTypeNotFound() {
         String url = ConsumerConsts.API_ROOT + "/info-types/junk";
         testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND, "Information type not found: junk");
     }
 
     @Test
     void a1eGetEiJobsIds() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        putInfoJob(TYPE_ID, "jobId");
+        putInfoProducerWithOneType(producerId, typeId);
+        putInfoJob(typeId, "jobId");
         final String JOB_ID_JSON = "[\"jobId\"]";
-        String url = A1eConsts.API_ROOT + "/eijobs?infoTypeId=" + TYPE_ID;
+        String url = A1eConsts.API_ROOT + "/eijobs?infoTypeId=" + typeId;
         String rsp = restClient().get(url).block();
         assertThat(rsp).isEqualTo(JOB_ID_JSON);
 
@@ -322,7 +321,7 @@ class ApplicationTest {
         rsp = restClient().get(url).block();
         assertThat(rsp).isEqualTo(JOB_ID_JSON);
 
-        url = A1eConsts.API_ROOT + "/eijobs?eiTypeId=" + TYPE_ID + "&&owner=owner";
+        url = A1eConsts.API_ROOT + "/eijobs?eiTypeId=" + typeId + "&&owner=owner";
         rsp = restClient().get(url).block();
         assertThat(rsp).isEqualTo(JOB_ID_JSON);
 
@@ -333,10 +332,10 @@ class ApplicationTest {
 
     @Test
     void consumerGetInformationJobsIds() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        putInfoJob(TYPE_ID, "jobId");
+        putInfoProducerWithOneType(producerId, typeId);
+        putInfoJob(typeId, "jobId");
         final String JOB_ID_JSON = "[\"jobId\"]";
-        String url = ConsumerConsts.API_ROOT + "/info-jobs?infoTypeId=" + TYPE_ID;
+        String url = ConsumerConsts.API_ROOT + "/info-jobs?infoTypeId=" + typeId;
         String rsp = restClient().get(url).block();
         assertThat(rsp).isEqualTo(JOB_ID_JSON);
 
@@ -352,7 +351,7 @@ class ApplicationTest {
         rsp = restClient().get(url).block();
         assertThat(rsp).isEqualTo(JOB_ID_JSON);
 
-        url = ConsumerConsts.API_ROOT + "/info-jobs?infoTypeId=" + TYPE_ID + "&&owner=owner";
+        url = ConsumerConsts.API_ROOT + "/info-jobs?infoTypeId=" + typeId + "&&owner=owner";
         rsp = restClient().get(url).block();
         assertThat(rsp).isEqualTo(JOB_ID_JSON);
 
@@ -363,67 +362,67 @@ class ApplicationTest {
 
     @Test
     void a1eGetEiJob() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        putInfoJob(TYPE_ID, "jobId");
+        putInfoProducerWithOneType(producerId, typeId);
+        putInfoJob(typeId, "jobId");
         String url = A1eConsts.API_ROOT + "/eijobs/jobId";
         String rsp = restClient().get(url).block();
         A1eEiJobInfo info = gson.fromJson(rsp, A1eEiJobInfo.class);
         assertThat(info.owner).isEqualTo("owner");
-        assertThat(info.eiTypeId).isEqualTo(TYPE_ID);
+        assertThat(info.eiTypeId).isEqualTo(typeId);
     }
 
     @Test
     void consumerGetEiJob() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        putInfoJob(TYPE_ID, "jobId");
+        putInfoProducerWithOneType(producerId, typeId);
+        putInfoJob(typeId, "jobId");
         String url = ConsumerConsts.API_ROOT + "/info-jobs/jobId";
         String rsp = restClient().get(url).block();
         ConsumerJobInfo info = gson.fromJson(rsp, ConsumerJobInfo.class);
         assertThat(info.owner).isEqualTo("owner");
-        assertThat(info.infoTypeId).isEqualTo(TYPE_ID);
+        assertThat(info.infoTypeId).isEqualTo(typeId);
     }
 
     @Test
     void a1eGetEiJobNotFound() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
+        putInfoProducerWithOneType(producerId, typeId);
         String url = A1eConsts.API_ROOT + "/eijobs/junk";
         testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND, "Could not find Information job: junk");
     }
 
     @Test
     void consumerGetInfoJobNotFound() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
+        putInfoProducerWithOneType(producerId, typeId);
         String url = ConsumerConsts.API_ROOT + "/info-jobs/junk";
         testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND, "Could not find Information job: junk");
     }
 
     @Test
     void a1eGetEiJobStatus() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        putInfoJob(TYPE_ID, "jobId");
+        putInfoProducerWithOneType(producerId, typeId);
+        putInfoJob(typeId, "jobId");
 
         verifyJobStatus("jobId", "ENABLED");
     }
 
     @Test
     void consumerGetInfoJobStatus() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        putInfoJob(TYPE_ID, "jobId");
+        putInfoProducerWithOneType(producerId, typeId);
+        putInfoJob(typeId, "jobId");
 
         String url = ConsumerConsts.API_ROOT + "/info-jobs/jobId/status";
         String rsp = restClient().get(url).block();
         assertThat(rsp) //
             .contains("ENABLED") //
-            .contains(PRODUCER_ID);
+            .contains(producerId);
 
         ConsumerJobStatus status = gson.fromJson(rsp, ConsumerJobStatus.class);
-        assertThat(status.producers).contains(PRODUCER_ID);
+        assertThat(status.producers).contains(producerId);
     }
 
     @Test
     void a1eDeleteEiJob() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        putInfoJob(TYPE_ID, "jobId");
+        putInfoProducerWithOneType(producerId, typeId);
+        putInfoJob(typeId, "jobId");
         assertThat(this.infoJobs.size()).isEqualTo(1);
         String url = A1eConsts.API_ROOT + "/eijobs/jobId";
         restClient().delete(url).block();
@@ -437,8 +436,8 @@ class ApplicationTest {
 
     @Test
     void consumerDeleteInfoJob() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        putInfoJob(TYPE_ID, "jobId");
+        putInfoProducerWithOneType(producerId, typeId);
+        putInfoJob(typeId, "jobId");
         assertThat(this.infoJobs.size()).isEqualTo(1);
         String url = ConsumerConsts.API_ROOT + "/info-jobs/jobId";
         restClient().delete(url).block();
@@ -453,24 +452,24 @@ class ApplicationTest {
 
     @Test
     void a1eDeleteEiJobNotFound() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
+        putInfoProducerWithOneType(producerId, typeId);
         String url = A1eConsts.API_ROOT + "/eijobs/junk";
-        testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND, "Could not find Information job: junk");
+        testErrorCode(restClient().delete(url), HttpStatus.NOT_FOUND, "Could not find Information job: junk");
     }
 
     @Test
     void consumerDeleteEiJobNotFound() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
+        putInfoProducerWithOneType(producerId, typeId);
         String url = ConsumerConsts.API_ROOT + "/info-jobs/junk";
-        testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND, "Could not find Information job: junk");
+        testErrorCode(restClient().delete(url), HttpStatus.NOT_FOUND, "Could not find Information job: junk");
     }
 
     @Test
     void a1ePutEiJob() throws Exception {
 
         // Test that one producer accepting a job is enough
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        putInfoProducerWithOneTypeRejecting("simulateProducerError", TYPE_ID);
+        putInfoProducerWithOneType(producerId, typeId);
+        putInfoProducerWithOneTypeRejecting("simulateProducerError", typeId);
 
         String url = A1eConsts.API_ROOT + "/eijobs/jobId";
         String body = gson.toJson(eiJobInfo());
@@ -492,7 +491,7 @@ class ApplicationTest {
         InfoJob job = this.infoJobs.getJob("jobId");
         assertThat(job.getOwner()).isEqualTo("owner");
 
-        verifyJobStatus(JOB_ID, "ENABLED");
+        verifyJobStatus(jobId, "ENABLED");
     }
 
     @Test
@@ -511,8 +510,8 @@ class ApplicationTest {
         putInfoProducerWithOneType(REG_TYPE_ID4, REG_TYPE_ID4);
         putInfoProducerWithOneType(REG_TYPE_ID5, REG_TYPE_ID5);
 
-        String url = A1eConsts.API_ROOT + "/eijobs/" + JOB_ID;
-        String body = gson.toJson(eiJobInfo(PUT_TYPE_ID, JOB_ID));
+        String url = A1eConsts.API_ROOT + "/eijobs/" + jobId;
+        String body = gson.toJson(eiJobInfo(PUT_TYPE_ID, jobId));
         ResponseEntity<String> resp = restClient().putForEntity(url, body).block();
         assertThat(this.infoJobs.size()).isEqualTo(1);
         assertThat(this.infoJobs.getJobs().iterator().next().getType().getId()).isEqualTo(REG_TYPE_ID1);
@@ -530,21 +529,21 @@ class ApplicationTest {
         final String REG_TYPE_ID1 = "type_1.5.0"; // Compatible
         putInfoProducerWithOneType(REG_TYPE_ID1, REG_TYPE_ID1);
 
-        String body = gson.toJson(eiJobInfo("junkTypeId", JOB_ID));
+        String body = gson.toJson(eiJobInfo("junkTypeId", jobId));
 
         String url = A1eConsts.API_ROOT + "/eijobs/jobId";
         testErrorCode(restClient().put(url, body), HttpStatus.NOT_FOUND, "not found");
 
-        url = A1eConsts.API_ROOT + "/eijobs/" + JOB_ID;
+        url = A1eConsts.API_ROOT + "/eijobs/" + jobId;
         final String PUT_TYPE_ERROR_ID = "type_1.1";
-        body = gson.toJson(eiJobInfo(PUT_TYPE_ERROR_ID, JOB_ID));
+        body = gson.toJson(eiJobInfo(PUT_TYPE_ERROR_ID, jobId));
         testErrorCode(restClient().put(url, body), HttpStatus.NOT_FOUND, "not found");
     }
 
     @Test
     void consumerPutInformationJob() throws Exception {
         // Test that one producer accepting a job is enough
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
+        putInfoProducerWithOneType(producerId, typeId);
 
         String url = ConsumerConsts.API_ROOT + "/info-jobs/jobId";
         String body = gson.toJson(consumerJobInfo());
@@ -562,7 +561,7 @@ class ApplicationTest {
         InfoJob job = this.infoJobs.getJob("jobId");
         assertThat(job.getOwner()).isEqualTo("owner");
 
-        verifyJobStatus(JOB_ID, "ENABLED");
+        verifyJobStatus(jobId, "ENABLED");
 
         body = gson.toJson(consumerJobInfo("junkTypeId", "jobId", ""));
         testErrorCode(restClient().put(url, body), HttpStatus.NOT_FOUND, "not found");
@@ -604,7 +603,7 @@ class ApplicationTest {
         // the principles for backwards compability.
         assertThat(request.typeId.equals(REG_TYPE_ID1) || request.typeId.equals(REG_TYPE_ID2)).isTrue();
 
-        verifyJobStatus(JOB_ID, "ENABLED");
+        verifyJobStatus(jobId, "ENABLED");
 
         // Test update job
         resp = restClient().putForEntity(url, body).block();
@@ -615,11 +614,11 @@ class ApplicationTest {
 
     @Test
     void a1ePutEiJob_jsonSchemavalidationError() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
+        putInfoProducerWithOneType(producerId, typeId);
 
         String url = A1eConsts.API_ROOT + "/eijobs/jobId";
         // The element with name "property1" is mandatory in the schema
-        A1eEiJobInfo jobInfo = new A1eEiJobInfo(TYPE_ID, toJsonObject("{ \"XXstring\" : \"value\" }"), "owner",
+        A1eEiJobInfo jobInfo = new A1eEiJobInfo(typeId, toJsonObject("{ \"XXstring\" : \"value\" }"), "owner",
             "targetUri", "jobStatusUrl");
         String body = gson.toJson(jobInfo);
 
@@ -631,12 +630,12 @@ class ApplicationTest {
 
     @Test
     void consumerPutJob_jsonSchemavalidationError() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
+        putInfoProducerWithOneType(producerId, typeId);
 
         String url = ConsumerConsts.API_ROOT + "/info-jobs/jobId";
         // The element with name "property1" is mandatory in the schema
         ConsumerJobInfo jobInfo =
-            new ConsumerJobInfo(TYPE_ID, toJsonObject("{ \"XXstring\" : \"value\" }"), "owner", "targetUri", null);
+            new ConsumerJobInfo(typeId, toJsonObject("{ \"XXstring\" : \"value\" }"), "owner", "targetUri", null);
         String body = gson.toJson(jobInfo);
 
         testErrorCode(restClient().put(url, body), HttpStatus.BAD_REQUEST, "Json validation failure");
@@ -644,11 +643,11 @@ class ApplicationTest {
 
     @Test
     void consumerPutJob_uriError() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
+        putInfoProducerWithOneType(producerId, typeId);
 
         String url = ConsumerConsts.API_ROOT + "/info-jobs/jobId";
 
-        ConsumerJobInfo jobInfo = new ConsumerJobInfo(TYPE_ID, jsonObject(""), "owner", "junk", null);
+        ConsumerJobInfo jobInfo = new ConsumerJobInfo(typeId, jsonObject(""), "owner", "junk", null);
         String body = gson.toJson(jobInfo);
 
         testErrorCode(restClient().put(url, body), HttpStatus.BAD_REQUEST, "URI: junk is not absolute");
@@ -678,14 +677,14 @@ class ApplicationTest {
     }
 
     @Test
-    void producerPutType() throws JsonMappingException, JsonProcessingException, ServiceException {
-        assertThat(putInfoType(TYPE_ID)).isEqualTo(HttpStatus.CREATED);
-        assertThat(putInfoType(TYPE_ID)).isEqualTo(HttpStatus.OK);
+    void producerPutType() throws ServiceException {
+        assertThat(putInfoType(typeId)).isEqualTo(HttpStatus.CREATED);
+        assertThat(putInfoType(typeId)).isEqualTo(HttpStatus.OK);
     }
 
     @Test
     void producerPutType_noSchema() {
-        String url = ProducerConsts.API_ROOT + "/info-types/" + TYPE_ID;
+        String url = ProducerConsts.API_ROOT + "/info-types/" + typeId;
         String body = "{}";
         testErrorCode(restClient().put(url, body), HttpStatus.BAD_REQUEST, "No schema provided");
 
@@ -694,31 +693,31 @@ class ApplicationTest {
 
     @Test
     void producerDeleteType() throws Exception {
-        putInfoType(TYPE_ID);
-        this.putInfoJob(TYPE_ID, "job1");
-        this.putInfoJob(TYPE_ID, "job2");
-        deleteInfoType(TYPE_ID);
+        putInfoType(typeId);
+        this.putInfoJob(typeId, "job1");
+        this.putInfoJob(typeId, "job2");
+        deleteInfoType(typeId);
 
         assertThat(this.infoTypes.size()).isZero();
         assertThat(this.infoJobs.size()).isZero(); // Test that also the job is deleted
 
-        testErrorCode(restClient().delete(deleteInfoTypeUrl(TYPE_ID)), HttpStatus.NOT_FOUND,
+        testErrorCode(restClient().delete(deleteInfoTypeUrl(typeId)), HttpStatus.NOT_FOUND,
             "Information type not found");
     }
 
     @Test
     void producerDeleteTypeExistingProducer() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        String url = ProducerConsts.API_ROOT + "/info-types/" + TYPE_ID;
-        testErrorCode(restClient().delete(url), HttpStatus.CONFLICT, "The type has active producers: " + PRODUCER_ID);
+        putInfoProducerWithOneType(producerId, typeId);
+        String url = ProducerConsts.API_ROOT + "/info-types/" + typeId;
+        testErrorCode(restClient().delete(url), HttpStatus.CONFLICT, "The type has active producers: " + producerId);
         assertThat(this.infoTypes.size()).isEqualTo(1);
     }
 
     @Test
     void producerDeleteTypeExistingJob() throws Exception {
-        putInfoType(TYPE_ID);
-        String url = ProducerConsts.API_ROOT + "/info-types/" + TYPE_ID;
-        putInfoJob(TYPE_ID, JOB_ID);
+        putInfoType(typeId);
+        String url = ProducerConsts.API_ROOT + "/info-types/" + typeId;
+        putInfoJob(typeId, jobId);
         restClient().delete(url).block();
         assertThat(this.infoTypes.size()).isZero();
 
@@ -728,8 +727,8 @@ class ApplicationTest {
 
     @Test
     void producerPutProducerWithOneType_rejecting() throws Exception {
-        putInfoProducerWithOneTypeRejecting("simulateProducerError", TYPE_ID);
-        String url = A1eConsts.API_ROOT + "/eijobs/" + JOB_ID;
+        putInfoProducerWithOneTypeRejecting("simulateProducerError", typeId);
+        String url = A1eConsts.API_ROOT + "/eijobs/" + jobId;
         String body = gson.toJson(eiJobInfo());
         restClient().put(url, body).block();
 
@@ -738,39 +737,39 @@ class ApplicationTest {
         await().untilAsserted(() -> assertThat(simulatorResults.noOfRejectedCreate).isEqualTo(2));
         assertThat(simulatorResults.noOfRejectedCreate).isEqualTo(2);
 
-        verifyJobStatus(JOB_ID, "DISABLED");
+        verifyJobStatus(jobId, "DISABLED");
     }
 
     @Test
     void producerGetInfoProducerTypes() throws Exception {
-        final String EI_TYPE_ID_2 = TYPE_ID + "_2";
-        putInfoProducerWithOneType("producer1", TYPE_ID);
-        putInfoJob(TYPE_ID, "jobId");
+        final String EI_TYPE_ID_2 = typeId + "_2";
+        putInfoProducerWithOneType("producer1", typeId);
+        putInfoJob(typeId, "jobId");
         putInfoProducerWithOneType("producer2", EI_TYPE_ID_2);
         putInfoJob(EI_TYPE_ID_2, "jobId2");
         String url = ProducerConsts.API_ROOT + "/info-types";
 
         ResponseEntity<String> resp = restClient().getForEntity(url).block();
         assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
-        assertThat(resp.getBody()).contains(TYPE_ID);
+        assertThat(resp.getBody()).contains(typeId);
         assertThat(resp.getBody()).contains(EI_TYPE_ID_2);
     }
 
     @Test
     void producerPutInfoProducer() throws Exception {
-        this.putInfoType(TYPE_ID);
+        this.putInfoType(typeId);
         String url = ProducerConsts.API_ROOT + "/info-producers/infoProducerId";
-        String body = gson.toJson(producerInfoRegistratioInfo(TYPE_ID));
+        String body = gson.toJson(producerInfoRegistratioInfo(typeId));
 
         ResponseEntity<String> resp = restClient().putForEntity(url, body).block();
         assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.CREATED);
 
         assertThat(this.infoTypes.size()).isEqualTo(1);
-        InfoType type = this.infoTypes.getType(TYPE_ID);
+        InfoType type = this.infoTypes.getType(typeId);
         assertThat(this.infoProducers.getProducersSupportingType(type)).hasSize(1);
         assertThat(this.infoProducers.size()).isEqualTo(1);
         assertThat(this.infoProducers.get("infoProducerId").getInfoTypes().iterator().next().getId())
-            .isEqualTo(TYPE_ID);
+            .isEqualTo(typeId);
 
         resp = restClient().putForEntity(url, body).block();
         assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
@@ -785,10 +784,10 @@ class ApplicationTest {
 
     @Test
     void producerPutInfoProducerExistingJob() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        putInfoJob(TYPE_ID, "jobId");
+        putInfoProducerWithOneType(producerId, typeId);
+        putInfoJob(typeId, "jobId");
         String url = ProducerConsts.API_ROOT + "/info-producers/infoProducerId";
-        String body = gson.toJson(producerInfoRegistratioInfo(TYPE_ID));
+        String body = gson.toJson(producerInfoRegistratioInfo(typeId));
         restClient().putForEntity(url, body).block();
 
         ProducerSimulatorController.TestResults simulatorResults = this.producerSimulator.getTestResults();
@@ -798,20 +797,20 @@ class ApplicationTest {
     }
 
     @Test
-    void testPutInfoProducer_noType() throws Exception {
+    void testPutInfoProducer_noType() {
         String url = ProducerConsts.API_ROOT + "/info-producers/infoProducerId";
-        String body = gson.toJson(producerInfoRegistratioInfo(TYPE_ID));
+        String body = gson.toJson(producerInfoRegistratioInfo(typeId));
         testErrorCode(restClient().put(url, body), HttpStatus.NOT_FOUND, "Information type not found");
     }
 
     @Test
     void producerPutProducerAndInfoJob() throws Exception {
-        this.putInfoType(TYPE_ID);
+        this.putInfoType(typeId);
         String url = ProducerConsts.API_ROOT + "/info-producers/infoProducerId";
-        String body = gson.toJson(producerInfoRegistratioInfo(TYPE_ID));
+        String body = gson.toJson(producerInfoRegistratioInfo(typeId));
         restClient().putForEntity(url, body).block();
         assertThat(this.infoTypes.size()).isEqualTo(1);
-        this.infoTypes.getType(TYPE_ID);
+        this.infoTypes.getType(typeId);
 
         url = A1eConsts.API_ROOT + "/eijobs/jobId";
         body = gson.toJson(eiJobInfo());
@@ -825,13 +824,13 @@ class ApplicationTest {
 
     @Test
     void producerGetInfoJobsForProducer() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        putInfoJob(TYPE_ID, "jobId1");
-        putInfoJob(TYPE_ID, "jobId2");
+        putInfoProducerWithOneType(producerId, typeId);
+        putInfoJob(typeId, "jobId1");
+        putInfoJob(typeId, "jobId2");
 
         // PUT a consumerRestApiTestBase.java
         String url = ProducerConsts.API_ROOT + "/info-producers/infoProducerId";
-        String body = gson.toJson(producerInfoRegistratioInfo(TYPE_ID));
+        String body = gson.toJson(producerInfoRegistratioInfo(typeId));
         restClient().putForEntity(url, body).block();
 
         url = ProducerConsts.API_ROOT + "/info-producers/infoProducerId/info-jobs";
@@ -839,20 +838,20 @@ class ApplicationTest {
         assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
 
         ProducerJobInfo[] parsedResp = gson.fromJson(resp.getBody(), ProducerJobInfo[].class);
-        assertThat(parsedResp[0].typeId).isEqualTo(TYPE_ID);
-        assertThat(parsedResp[1].typeId).isEqualTo(TYPE_ID);
+        assertThat(parsedResp[0].typeId).isEqualTo(typeId);
+        assertThat(parsedResp[1].typeId).isEqualTo(typeId);
     }
 
     @Test
     void producerDeleteInfoProducer() throws Exception {
-        putInfoProducerWithOneType("infoProducerId", TYPE_ID);
-        putInfoProducerWithOneType("infoProducerId2", TYPE_ID);
+        putInfoProducerWithOneType("infoProducerId", typeId);
+        putInfoProducerWithOneType("infoProducerId2", typeId);
 
         assertThat(this.infoProducers.size()).isEqualTo(2);
-        InfoType type = this.infoTypes.getType(TYPE_ID);
+        InfoType type = this.infoTypes.getType(typeId);
         assertThat(this.infoProducers.getProducerIdsForType(type)).contains("infoProducerId");
         assertThat(this.infoProducers.getProducerIdsForType(type)).contains("infoProducerId2");
-        putInfoJob(TYPE_ID, "jobId");
+        putInfoJob(typeId, "jobId");
         assertThat(this.infoJobs.size()).isEqualTo(1);
 
         deleteInfoProducer("infoProducerId");
@@ -874,9 +873,9 @@ class ApplicationTest {
         A1eCallbacksSimulatorController.TestResults consumerCalls = this.a1eCallbacksSimulator.getTestResults();
         ProducerSimulatorController.TestResults producerCalls = this.producerSimulator.getTestResults();
 
-        putInfoProducerWithOneType("infoProducerId", TYPE_ID);
-        putInfoJob(TYPE_ID, "jobId");
-        putInfoProducerWithOneType("infoProducerId2", TYPE_ID);
+        putInfoProducerWithOneType("infoProducerId", typeId);
+        putInfoJob(typeId, "jobId");
+        putInfoProducerWithOneType("infoProducerId2", typeId);
         await().untilAsserted(() -> assertThat(producerCalls.jobsStarted).hasSize(2));
 
         deleteInfoProducer("infoProducerId2");
@@ -888,7 +887,7 @@ class ApplicationTest {
         assertThat(consumerCalls.eiJobStatusCallbacks.get(0).state)
             .isEqualTo(A1eEiJobStatus.EiJobStatusValues.DISABLED);
 
-        putInfoProducerWithOneType("infoProducerId", TYPE_ID);
+        putInfoProducerWithOneType("infoProducerId", typeId);
         await().untilAsserted(() -> assertThat(consumerCalls.eiJobStatusCallbacks).hasSize(2));
         assertThat(consumerCalls.eiJobStatusCallbacks.get(1).state).isEqualTo(A1eEiJobStatus.EiJobStatusValues.ENABLED);
     }
@@ -898,27 +897,27 @@ class ApplicationTest {
         // Test replacing a producer with new and removed types
 
         // Create a job
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        putInfoJob(TYPE_ID, JOB_ID);
+        putInfoProducerWithOneType(producerId, typeId);
+        putInfoJob(typeId, jobId);
 
         // change the type for the producer, the job shall be disabled
-        putInfoProducerWithOneType(PRODUCER_ID, "junk");
-        verifyJobStatus(JOB_ID, "DISABLED");
+        putInfoProducerWithOneType(producerId, "junk");
+        verifyJobStatus(jobId, "DISABLED");
         A1eCallbacksSimulatorController.TestResults consumerCalls = this.a1eCallbacksSimulator.getTestResults();
         await().untilAsserted(() -> assertThat(consumerCalls.eiJobStatusCallbacks).hasSize(1));
         assertThat(consumerCalls.eiJobStatusCallbacks.get(0).state)
             .isEqualTo(A1eEiJobStatus.EiJobStatusValues.DISABLED);
 
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        verifyJobStatus(JOB_ID, "ENABLED");
+        putInfoProducerWithOneType(producerId, typeId);
+        verifyJobStatus(jobId, "ENABLED");
         await().untilAsserted(() -> assertThat(consumerCalls.eiJobStatusCallbacks).hasSize(2));
         assertThat(consumerCalls.eiJobStatusCallbacks.get(1).state).isEqualTo(A1eEiJobStatus.EiJobStatusValues.ENABLED);
     }
 
     @Test
-    void producerGetProducerInfoType() throws JsonMappingException, JsonProcessingException, ServiceException {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        String url = ProducerConsts.API_ROOT + "/info-types/" + TYPE_ID;
+    void producerGetProducerInfoType() throws ServiceException {
+        putInfoProducerWithOneType(producerId, typeId);
+        String url = ProducerConsts.API_ROOT + "/info-types/" + typeId;
         ResponseEntity<String> resp = restClient().getForEntity(url).block();
         ProducerInfoTypeInfo info = gson.fromJson(resp.getBody(), ProducerInfoTypeInfo.class);
         assertThat(info.jobDataSchema).isNotNull();
@@ -928,15 +927,15 @@ class ApplicationTest {
     }
 
     @Test
-    void producerGetProducerIdentifiers() throws JsonMappingException, JsonProcessingException, ServiceException {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
+    void producerGetProducerIdentifiers() throws ServiceException {
+        putInfoProducerWithOneType(producerId, typeId);
         String url = ProducerConsts.API_ROOT + "/info-producers";
         ResponseEntity<String> resp = restClient().getForEntity(url).block();
-        assertThat(resp.getBody()).contains(PRODUCER_ID);
+        assertThat(resp.getBody()).contains(producerId);
 
-        url = ProducerConsts.API_ROOT + "/info-producers?infoTypeId=" + TYPE_ID;
+        url = ProducerConsts.API_ROOT + "/info-producers?infoTypeId=" + typeId;
         resp = restClient().getForEntity(url).block();
-        assertThat(resp.getBody()).contains(PRODUCER_ID);
+        assertThat(resp.getBody()).contains(producerId);
 
         url = ProducerConsts.API_ROOT + "/info-producers?infoTypeId=junk";
         resp = restClient().getForEntity(url).block();
@@ -947,19 +946,19 @@ class ApplicationTest {
     void producerSupervision() throws Exception {
 
         A1eCallbacksSimulatorController.TestResults consumerResults = this.a1eCallbacksSimulator.getTestResults();
-        putInfoProducerWithOneTypeRejecting("simulateProducerError", TYPE_ID);
+        putInfoProducerWithOneTypeRejecting("simulateProducerError", typeId);
 
         {
             // Create a job
-            putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-            putInfoJob(TYPE_ID, JOB_ID);
-            verifyJobStatus(JOB_ID, "ENABLED");
-            deleteInfoProducer(PRODUCER_ID);
+            putInfoProducerWithOneType(producerId, typeId);
+            putInfoJob(typeId, jobId);
+            verifyJobStatus(jobId, "ENABLED");
+            deleteInfoProducer(producerId);
             // A Job disabled status notification shall now be received
             await().untilAsserted(() -> assertThat(consumerResults.eiJobStatusCallbacks).hasSize(1));
             assertThat(consumerResults.eiJobStatusCallbacks.get(0).state)
                 .isEqualTo(A1eEiJobStatus.EiJobStatusValues.DISABLED);
-            verifyJobStatus(JOB_ID, "DISABLED");
+            verifyJobStatus(jobId, "DISABLED");
         }
 
         assertThat(this.infoProducers.size()).isEqualTo(1);
@@ -980,11 +979,11 @@ class ApplicationTest {
 
         // Now we have one disabled job, and no producer.
         // PUT a producer, then a Job ENABLED status notification shall be received
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
+        putInfoProducerWithOneType(producerId, typeId);
         await().untilAsserted(() -> assertThat(consumerResults.eiJobStatusCallbacks).hasSize(2));
         assertThat(consumerResults.eiJobStatusCallbacks.get(1).state)
             .isEqualTo(A1eEiJobStatus.EiJobStatusValues.ENABLED);
-        verifyJobStatus(JOB_ID, "ENABLED");
+        verifyJobStatus(jobId, "ENABLED");
     }
 
     @Test
@@ -992,16 +991,16 @@ class ApplicationTest {
         // Test that supervision enables not enabled jobs and sends a notification when
         // suceeded
 
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        putInfoJob(TYPE_ID, JOB_ID);
+        putInfoProducerWithOneType(producerId, typeId);
+        putInfoJob(typeId, jobId);
 
-        InfoProducer producer = this.infoProducers.getProducer(PRODUCER_ID);
-        InfoJob job = this.infoJobs.getJob(JOB_ID);
+        InfoProducer producer = this.infoProducers.getProducer(producerId);
+        InfoJob job = this.infoJobs.getJob(jobId);
         // Pretend that the producer did reject the job and the a DISABLED notification
         // is sent for the job
         producer.setJobDisabled(job);
         job.setLastReportedStatus(false);
-        verifyJobStatus(JOB_ID, "DISABLED");
+        verifyJobStatus(jobId, "DISABLED");
 
         // Run the supervision and wait for the job to get started in the producer
         this.producerSupervision.createTask().blockLast();
@@ -1009,13 +1008,13 @@ class ApplicationTest {
         await().untilAsserted(() -> assertThat(consumerResults.eiJobStatusCallbacks).hasSize(1));
         assertThat(consumerResults.eiJobStatusCallbacks.get(0).state)
             .isEqualTo(A1eEiJobStatus.EiJobStatusValues.ENABLED);
-        verifyJobStatus(JOB_ID, "ENABLED");
+        verifyJobStatus(jobId, "ENABLED");
     }
 
     @Test
-    void testGetStatus() throws JsonMappingException, JsonProcessingException, ServiceException {
-        putInfoProducerWithOneTypeRejecting("simulateProducerError", TYPE_ID);
-        putInfoProducerWithOneTypeRejecting("simulateProducerError2", TYPE_ID);
+    void testGetStatus() throws ServiceException {
+        putInfoProducerWithOneTypeRejecting("simulateProducerError", typeId);
+        putInfoProducerWithOneTypeRejecting("simulateProducerError2", typeId);
 
         String url = "/status";
         ResponseEntity<String> resp = restClient().getForEntity(url).block();
@@ -1035,7 +1034,7 @@ class ApplicationTest {
         List<?> entries = db.listObjects("").collectList().block();
         assertThat(entries).hasSize(NO_OF_OBJS);
 
-        db.listObjects("").doOnNext(name -> logger.debug("deleted {}", name)).flatMap(name -> db.deleteObject(name))
+        db.listObjects("").doOnNext(name -> logger.debug("deleted {}", name)).flatMap(db::deleteObject)
             .blockLast();
 
         db.createDataStore().block();
@@ -1044,9 +1043,9 @@ class ApplicationTest {
 
     @Test
     void testJobDatabasePersistence() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        putInfoJob(TYPE_ID, "jobId1");
-        putInfoJob(TYPE_ID, "jobId2");
+        putInfoProducerWithOneType(producerId, typeId);
+        putInfoJob(typeId, "jobId1");
+        putInfoJob(typeId, "jobId2");
         waitForS3();
 
         assertThat(this.infoJobs.size()).isEqualTo(2);
@@ -1080,8 +1079,8 @@ class ApplicationTest {
 
     @Test
     void testTypesDatabasePersistence() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        InfoType savedType = this.infoTypes.getType(TYPE_ID);
+        putInfoProducerWithOneType(producerId, typeId);
+        InfoType savedType = this.infoTypes.getType(typeId);
 
         waitForS3();
         assertThat(this.infoTypes.size()).isEqualTo(1);
@@ -1090,7 +1089,7 @@ class ApplicationTest {
             // Restore the types
             InfoTypes restoredTypes = new InfoTypes(this.applicationConfig);
             restoredTypes.restoreTypesFromDatabase().blockLast();
-            InfoType restoredType = restoredTypes.getType(TYPE_ID);
+            InfoType restoredType = restoredTypes.getType(typeId);
             assertThat(restoredType.getPersistentInfo()).isEqualTo(savedType.getPersistentInfo());
             assertThat(restoredTypes.size()).isEqualTo(1);
         }
@@ -1102,7 +1101,7 @@ class ApplicationTest {
             assertThat(restoredTypes.size()).isZero();
         }
         logger.warn("Test removing a job when the db file is gone");
-        this.infoTypes.remove(this.infoTypes.getType(TYPE_ID));
+        this.infoTypes.remove(this.infoTypes.getType(typeId));
         assertThat(this.infoJobs.size()).isZero();
     }
 
@@ -1180,13 +1179,13 @@ class ApplicationTest {
             final ConsumerSimulatorController.TestResults consumerCalls = this.consumerSimulator.getTestResults();
 
             // Test callback for PUT type
-            this.putInfoType(TYPE_ID);
+            this.putInfoType(typeId);
             await().untilAsserted(() -> assertThat(consumerCalls.typeRegistrationInfoCallbacks).hasSize(1));
             assertThat(consumerCalls.typeRegistrationInfoCallbacks.get(0).state)
                 .isEqualTo(ConsumerTypeRegistrationInfo.ConsumerTypeStatusValues.REGISTERED);
 
             // Test callback for DELETE type
-            this.deleteInfoType(TYPE_ID);
+            this.deleteInfoType(typeId);
             await().untilAsserted(() -> assertThat(consumerCalls.typeRegistrationInfoCallbacks).hasSize(2));
             assertThat(consumerCalls.typeRegistrationInfoCallbacks.get(1).state)
                 .isEqualTo(ConsumerTypeRegistrationInfo.ConsumerTypeStatusValues.DEREGISTERED);
@@ -1213,13 +1212,13 @@ class ApplicationTest {
         restClient().putForEntity(typeSubscriptionUrl() + "/subscriptionId", body).block();
         assertThat(this.infoTypeSubscriptions.size()).isEqualTo(1);
 
-        this.putInfoType(TYPE_ID);
+        this.putInfoType(typeId);
         // The callback will fail and the subscription will be removed
         await().untilAsserted(() -> assertThat(this.infoTypeSubscriptions.size()).isZero());
     }
 
     @Test
-    void testTypeSubscriptionErrorCodes() throws Exception {
+    void testTypeSubscriptionErrorCodes() {
 
         testErrorCode(restClient().get(typeSubscriptionUrl() + "/junk"), HttpStatus.NOT_FOUND,
             "Could not find Information subscription: junk");
@@ -1235,8 +1234,8 @@ class ApplicationTest {
         Path authFile = Files.createTempFile("icsTestAuthToken", ".txt");
         Files.write(authFile, AUTH_TOKEN.getBytes());
         this.securityContext.setAuthTokenFilePath(authFile);
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        putInfoJob(TYPE_ID, "jobId");
+        putInfoProducerWithOneType(producerId, typeId);
+        putInfoJob(typeId, "jobId");
 
         var testResults = openPolicyAgentSimulatorController.getTestResults();
 
@@ -1245,14 +1244,14 @@ class ApplicationTest {
         // Test OPA check
         SubscriptionAuthRequest authRequest = testResults.receivedRequests.get(0);
         assertThat(authRequest.getInput().getAccessType()).isEqualTo(AccessType.WRITE);
-        assertThat(authRequest.getInput().getInfoTypeId()).isEqualTo(TYPE_ID);
+        assertThat(authRequest.getInput().getInfoTypeId()).isEqualTo(typeId);
         assertThat(authRequest.getInput().getAuthToken()).isEqualTo(AUTH_TOKEN);
     }
 
     @Test
     void testFineGrainedAuthorizationCheckRejections() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        putInfoJob(TYPE_ID, JOB_ID);
+        putInfoProducerWithOneType(producerId, typeId);
+        putInfoJob(typeId, jobId);
 
         // Test rejection from OPA
         this.applicationConfig
@@ -1260,51 +1259,51 @@ class ApplicationTest {
         var testResults = openPolicyAgentSimulatorController.getTestResults();
 
         // R1
-        String url = ConsumerConsts.API_ROOT + "/info-jobs/" + JOB_ID;
+        String url = ConsumerConsts.API_ROOT + "/info-jobs/" + jobId;
         testErrorCode(restClient().delete(url), HttpStatus.UNAUTHORIZED, "Not authorized");
         assertThat(testResults.receivedRequests).hasSize(2);
         SubscriptionAuthRequest authRequest = testResults.receivedRequests.get(1);
         assertThat(authRequest.getInput().getAccessType()).isEqualTo(AccessType.WRITE);
 
-        String body = gson.toJson(consumerJobInfo(TYPE_ID, JOB_ID, "owner"));
+        String body = gson.toJson(consumerJobInfo(typeId, jobId, "owner"));
         testErrorCode(restClient().put(url, body), HttpStatus.UNAUTHORIZED, "Not authorized");
 
         testErrorCode(restClient().get(url), HttpStatus.UNAUTHORIZED, "Not authorized");
 
         // A1-E
-        url = A1eConsts.API_ROOT + "/eijobs/" + JOB_ID;
+        url = A1eConsts.API_ROOT + "/eijobs/" + jobId;
         testErrorCode(restClient().get(url), HttpStatus.UNAUTHORIZED, "Not authorized");
 
         testErrorCode(restClient().delete(url), HttpStatus.UNAUTHORIZED, "Not authorized");
 
-        body = gson.toJson(eiJobInfo(TYPE_ID, JOB_ID, "owner"));
+        body = gson.toJson(eiJobInfo(typeId, jobId, "owner"));
         testErrorCode(restClient().put(url, body), HttpStatus.UNAUTHORIZED, "Not authorized");
     }
 
     @Test
     void testFineGrainedAuthorizationCheckRejections_OPA_UNAVALIABLE() throws Exception {
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        putInfoJob(TYPE_ID, JOB_ID);
+        putInfoProducerWithOneType(producerId, typeId);
+        putInfoJob(typeId, jobId);
 
         // Test rejection from OPA
         this.applicationConfig.setAuthAgentUrl("junk");
 
         // R1
-        String url = ConsumerConsts.API_ROOT + "/info-jobs/" + JOB_ID;
+        String url = ConsumerConsts.API_ROOT + "/info-jobs/" + jobId;
         testErrorCode(restClient().delete(url), HttpStatus.UNAUTHORIZED, "Not authorized");
 
-        String body = gson.toJson(consumerJobInfo(TYPE_ID, JOB_ID, "owner"));
+        String body = gson.toJson(consumerJobInfo(typeId, jobId, "owner"));
         testErrorCode(restClient().put(url, body), HttpStatus.UNAUTHORIZED, "Not authorized");
 
         testErrorCode(restClient().get(url), HttpStatus.UNAUTHORIZED, "Not authorized");
 
         // A1-E
-        url = A1eConsts.API_ROOT + "/eijobs/" + JOB_ID;
+        url = A1eConsts.API_ROOT + "/eijobs/" + jobId;
         testErrorCode(restClient().get(url), HttpStatus.UNAUTHORIZED, "Not authorized");
 
         testErrorCode(restClient().delete(url), HttpStatus.UNAUTHORIZED, "Not authorized");
 
-        body = gson.toJson(eiJobInfo(TYPE_ID, JOB_ID, "owner"));
+        body = gson.toJson(eiJobInfo(typeId, jobId, "owner"));
         testErrorCode(restClient().put(url, body), HttpStatus.UNAUTHORIZED, "Not authorized");
     }
 
@@ -1314,8 +1313,8 @@ class ApplicationTest {
         Path authFile = Files.createTempFile("icsTestAuthToken", ".txt");
         Files.write(authFile, AUTH_TOKEN.getBytes());
         this.securityContext.setAuthTokenFilePath(authFile);
-        putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID);
-        putInfoJob(TYPE_ID, "jobId");
+        putInfoProducerWithOneType(producerId, typeId);
+        putInfoJob(typeId, "jobId");
 
         // Test that authorization header is sent to the producer.
         await().untilAsserted(() -> assertThat(this.producerSimulator.getTestResults().receivedHeaders).hasSize(1));
@@ -1325,7 +1324,7 @@ class ApplicationTest {
         Files.delete(authFile);
 
         // Test that it works when the file is deleted. The cached header is used
-        putInfoJob(TYPE_ID, "jobId2");
+        putInfoJob(typeId, "jobId2");
         await().untilAsserted(() -> assertThat(this.infoJobs.size()).isEqualByComparingTo(2));
         headers = this.producerSimulator.getTestResults().receivedHeaders.get(1);
         assertThat(headers).containsEntry("authorization", "Bearer " + AUTH_TOKEN);
@@ -1348,7 +1347,7 @@ class ApplicationTest {
 
         StepVerifier.create(restClient().get(ConsumerConsts.API_ROOT + "/info-jobs")) // Any call
             .expectSubscription() //
-            .expectErrorMatches(t -> t instanceof WebClientRequestException) //
+            .expectErrorMatches(WebClientRequestException.class::isInstance) //
             .verify();
     }
 
@@ -1375,44 +1374,40 @@ class ApplicationTest {
         assertThat(statusInfo.opState).isEqualTo(expectedOperationalState);
     }
 
-    ProducerInfoTypeInfo ProducerInfoTypeRegistrationInfo(String typeId)
-        throws JsonMappingException, JsonProcessingException {
+    ProducerInfoTypeInfo ProducerInfoTypeRegistrationInfo() {
         return new ProducerInfoTypeInfo(jsonSchemaObject(), typeSpecifcInfoObject());
     }
 
-    ProducerRegistrationInfo producerEiRegistratioInfoRejecting(String typeId)
-        throws JsonMappingException, JsonProcessingException {
+    ProducerRegistrationInfo producerEiRegistratioInfoRejecting(String typeId) {
         return new ProducerRegistrationInfo(Arrays.asList(typeId), //
             baseUrl() + ProducerSimulatorController.JOB_ERROR_URL,
             baseUrl() + ProducerSimulatorController.SUPERVISION_ERROR_URL);
     }
 
-    ProducerRegistrationInfo producerInfoRegistratioInfo(String typeId)
-        throws JsonMappingException, JsonProcessingException {
+    ProducerRegistrationInfo producerInfoRegistratioInfo(String typeId) {
         return new ProducerRegistrationInfo(Arrays.asList(typeId), //
             baseUrl() + ProducerSimulatorController.JOB_URL, baseUrl() + ProducerSimulatorController.SUPERVISION_URL);
     }
 
-    private ConsumerJobInfo consumerJobInfo() throws JsonMappingException, JsonProcessingException {
-        return consumerJobInfo(TYPE_ID, JOB_ID, "owner");
+    private ConsumerJobInfo consumerJobInfo() {
+        return consumerJobInfo(typeId, jobId, "owner");
     }
 
-    ConsumerJobInfo consumerJobInfo(String typeId, String infoJobId, String owner)
-        throws JsonMappingException, JsonProcessingException {
+    ConsumerJobInfo consumerJobInfo(String typeId, String infoJobId, String owner) {
         return new ConsumerJobInfo(typeId, jsonObject(owner), owner, "https://junk.com",
             baseUrl() + A1eCallbacksSimulatorController.getJobStatusUrl(infoJobId));
     }
 
-    private A1eEiJobInfo eiJobInfo() throws Exception {
-        return eiJobInfo(TYPE_ID, JOB_ID);
+    private A1eEiJobInfo eiJobInfo() {
+        return eiJobInfo(typeId, jobId);
     }
 
-    A1eEiJobInfo eiJobInfo(String typeId, String infoJobId) throws Exception {
+    A1eEiJobInfo eiJobInfo(String typeId, String infoJobId) {
         return eiJobInfo(typeId, infoJobId, "owner");
 
     }
 
-    A1eEiJobInfo eiJobInfo(String typeId, String infoJobId, String owner) throws Exception {
+    A1eEiJobInfo eiJobInfo(String typeId, String infoJobId, String owner) {
         return new A1eEiJobInfo(typeId, jsonObject(owner), owner, "https://junk.com",
             baseUrl() + A1eCallbacksSimulatorController.getJobStatusUrl(infoJobId));
     }
@@ -1426,7 +1421,7 @@ class ApplicationTest {
     }
 
     private Object jsonObject(String aValue) {
-        return toJsonObject("{ " + EI_JOB_PROPERTY + " : \"" + aValue + "\" }");
+        return toJsonObject("{ " + eiJobProperty + " : \"" + aValue + "\" }");
     }
 
     private Object typeSpecifcInfoObject() {
@@ -1439,12 +1434,12 @@ class ApplicationTest {
             + "\"$schema\": \"http://json-schema.org/draft-04/schema#\"," //
             + "\"type\": \"object\"," //
             + "\"properties\": {" //
-            + EI_JOB_PROPERTY + " : {" //
+            + eiJobProperty + " : {" //
             + "    \"type\": \"string\"" //
             + "  }" //
             + "}," //
             + "\"required\": [" //
-            + EI_JOB_PROPERTY //
+            + eiJobProperty //
             + "]" //
             + "}"; //
         return toJsonObject(schemaStr);
@@ -1471,9 +1466,9 @@ class ApplicationTest {
     }
 
     private HttpStatusCode putInfoType(String infoTypeId)
-        throws JsonMappingException, JsonProcessingException, ServiceException {
+        throws ServiceException {
         String url = ProducerConsts.API_ROOT + "/info-types/" + infoTypeId;
-        String body = gson.toJson(ProducerInfoTypeRegistrationInfo(infoTypeId));
+        String body = gson.toJson(ProducerInfoTypeRegistrationInfo());
 
         ResponseEntity<String> resp = restClient().putForEntity(url, body).block();
         this.infoTypes.getType(infoTypeId);
@@ -1489,7 +1484,7 @@ class ApplicationTest {
     }
 
     private InfoType putInfoProducerWithOneTypeRejecting(String producerId, String infoTypeId)
-        throws JsonMappingException, JsonProcessingException, ServiceException {
+        throws ServiceException {
         this.putInfoType(infoTypeId);
         String url = ProducerConsts.API_ROOT + "/info-producers/" + producerId;
         String body = gson.toJson(producerEiRegistratioInfoRejecting(infoTypeId));
@@ -1498,7 +1493,7 @@ class ApplicationTest {
     }
 
     private InfoType putInfoProducerWithOneType(String producerId, String infoTypeId)
-        throws JsonMappingException, JsonProcessingException, ServiceException {
+        throws ServiceException {
         if (this.infoTypes.get(infoTypeId) == null) {
             this.putInfoType(infoTypeId);
         }
index a2ce52b..a4c7061 100644 (file)
@@ -52,9 +52,9 @@ class MockInformationService {
     InfoJobs infoJobs;
 
     @Test
-    @SuppressWarnings("squid:S2699")
+    @SuppressWarnings({"squid:S2699", "squid:S2925" })
     void runMock() throws Exception {
-        logger.warn("**************** Keeping server alive! " + this.port);
+        logger.warn("**************** Keeping server alive! {}", this.port);
         synchronized (this) {
             while (true) {
                 System.out.println("**** Types *** ");
index 3f5f78d..0627011 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -84,7 +85,7 @@ class AsyncRestClientTest {
 
         Mono<String> returnedMono = clientUnderTest.get(REQUEST_URL);
         StepVerifier.create(returnedMono)
-            .expectErrorMatches(throwable -> throwable instanceof WebClientResponseException).verify();
+            .expectErrorMatches(WebClientResponseException.class::isInstance).verify();
     }
 
     @Test
@@ -103,7 +104,7 @@ class AsyncRestClientTest {
 
         Mono<String> returnedMono = clientUnderTest.put(REQUEST_URL, TEST_JSON);
         StepVerifier.create(returnedMono)
-            .expectErrorMatches(throwable -> throwable instanceof WebClientResponseException).verify();
+            .expectErrorMatches(WebClientResponseException.class::isInstance).verify();
     }
 
     @Test
@@ -120,7 +121,7 @@ class AsyncRestClientTest {
 
         Mono<String> returnedMono = clientUnderTest.delete(REQUEST_URL);
         StepVerifier.create(returnedMono)
-            .expectErrorMatches(throwable -> throwable instanceof WebClientResponseException).verify();
+            .expectErrorMatches(WebClientResponseException.class::isInstance).verify();
     }
 
     @Test
@@ -139,7 +140,7 @@ class AsyncRestClientTest {
 
         Mono<String> returnedMono = clientUnderTest.post(REQUEST_URL, TEST_JSON);
         StepVerifier.create(returnedMono)
-            .expectErrorMatches(throwable -> throwable instanceof WebClientResponseException).verify();
+            .expectErrorMatches(WebClientResponseException.class::isInstance).verify();
     }
 
     @Test
@@ -158,6 +159,6 @@ class AsyncRestClientTest {
 
         Mono<String> returnedMono = clientUnderTest.postWithAuthHeader(REQUEST_URL, TEST_JSON, USERNAME, PASSWORD);
         StepVerifier.create(returnedMono)
-            .expectErrorMatches(throwable -> throwable instanceof WebClientResponseException).verify();
+            .expectErrorMatches(WebClientResponseException.class::isInstance).verify();
     }
 }
index f711ca9..5af422d 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2022 Nordix Foundation
+ * Copyright (C) 2022-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -68,6 +69,7 @@ public class OpenPolicyAgentSimulatorController {
             Collections.synchronizedList(new ArrayList<SubscriptionAuthRequest>());
 
         public TestResults() {
+            //empty class
         }
 
         public void reset() {
index 76207c1..fba152f 100644 (file)
@@ -2,7 +2,8 @@
  * ========================LICENSE_START=================================
  * O-RAN-SC
  * %%
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe
  * %%
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -76,6 +77,7 @@ public class ProducerSimulatorController {
         public boolean errorFound = false;
 
         public TestResults() {
+            // empty class
         }
 
         public void reset() {
@@ -89,7 +91,7 @@ public class ProducerSimulatorController {
     }
 
     @Getter
-    private TestResults testResults = new TestResults();
+    private final TestResults testResults = new TestResults();
 
     @PostMapping(path = JOB_URL, produces = MediaType.APPLICATION_JSON_VALUE)
     @Operation(