From c0218ada67784a7d5c3a488303bcbab2b3dce5b5 Mon Sep 17 00:00:00 2001 From: PatrikBuhr Date: Mon, 28 Nov 2022 09:40:36 +0100 Subject: A1-PMS, graceful shutdown Support for granceful shutdown via signal "SIGTERM" and via calling REST POST /actuator/shutdown Issue-ID: CCSDK-3830 Signed-off-by: PatrikBuhr Change-Id: Ibc71cd8a2c9f44ec844ab49c8f225ae128549776 --- a1-policy-management/api/pms-api.json | 19 ++++++++++-- a1-policy-management/api/pms-api.yaml | 19 ++++++++++-- a1-policy-management/config/application.yaml | 8 ++++- .../a1policymanagementservice/Application.java | 17 ++++++++++- .../a1policymanagementservice/SwaggerConfig.java | 11 +++++-- .../aspect/LogAspect.java | 4 ++- .../clients/A1ClientFactory.java | 3 +- .../configuration/ConfigurationFile.java | 3 +- .../datastore/S3ObjectStore.java | 3 +- .../dmaap/DmaapMessageConsumer.java | 3 +- .../dmaap/DmaapMessageHandler.java | 4 ++- .../exceptions/GlobalExceptionHandler.java | 4 ++- .../a1policymanagementservice/repository/Lock.java | 3 +- .../a1policymanagementservice/repository/Ric.java | 3 +- .../repository/Services.java | 3 +- .../tasks/RefreshConfigTask.java | 3 +- .../tasks/RicSupervision.java | 3 +- .../tasks/RicSynchronizationTask.java | 3 +- .../tasks/ServiceSupervision.java | 3 +- .../MockPolicyManagementService.java | 3 +- .../controllers/v2/ApplicationTest.java | 34 +++++++++++++++++++++- .../controllers/v2/ConcurrencyTestRunnable.java | 3 +- docs/offeredapis/swagger/pms-api.json | 19 ++++++++++-- docs/offeredapis/swagger/pms-api.yaml | 19 ++++++++++-- 24 files changed, 167 insertions(+), 30 deletions(-) diff --git a/a1-policy-management/api/pms-api.json b/a1-policy-management/api/pms-api.json index ce2d9aa8..b8a9b955 100644 --- a/a1-policy-management/api/pms-api.json +++ b/a1-policy-management/api/pms-api.json @@ -471,6 +471,21 @@ ], "tags": ["NearRT-RIC Repository"] }}, + "/actuator/shutdown": {"post": { + "summary": "Actuator web endpoint 'shutdown'", + "operationId": "shutdown", + "responses": {"200": { + "description": "OK", + "content": {"*/*": { + "schema": { + "type": "object", + "example": null + }, + "example": null + }} + }}, + "tags": ["Actuator"] + }}, "/a1-policy/v2/policy-types": {"get": { "summary": "Query policy type identities", "operationId": "getPolicyTypes", @@ -1221,10 +1236,10 @@ }, "info": { "license": { - "name": "Copyright (C) 2020-2022 Nordix Foundation. Licensed under the Apache License.", + "name": "Copyright (C) 2020-2023 Nordix Foundation. Licensed under the Apache License.", "url": "http://www.apache.org/licenses/LICENSE-2.0" }, - "description": "

General<\/h2>

The O-RAN Non-RT RIC Policy Management Service provides a REST API for management of A1 policies.
The main tasks of the service are:<\/p>

  • A1 Policy creation, modification and deletion.<\/li>
  • Monitoring and maintaining consistency of the SMO view of A1 policies and the Near-RT RICs<\/li>
  • Maintaining a view of supported Near-RT RIC policy types<\/li>
  • Supervision of using services (R-APPs). When a service is unavailable, its policies are removed.<\/li><\/ul>

    APIs provided by the service<\/h2>

    A1 Policy Management<\/h3>

    This is an API for management of A1 Policies.<\/p>

    • A1 Policy retrieval, creation, modification and deletion.<\/li>
    • Retrieval of supported A1 Policy types for a Near-RT RIC<\/li>
    • Retrieval of status for existing A1 policies<\/li><\/ul>

      Management of configuration<\/h3>

      API for updating and retrieval of the component configuration. Note that there other ways to maintain the configuration.<\/p>

      Callbacks<\/h3>

      These are endpoints that are invoked by this service. The callbacks are registered in this service at service registration.<\/p>

      NearRT-RIC Repository<\/h3>

      This is an API that provides support for looking up a NearRT-RIC. Each A1 policy is targeted for one Near-RT RIC.<\/p>

      Health Check<\/h3>

      API used for supervision of the PMS component.<\/p>

      Service Registry and Supervision<\/h3>

      API used for registering services that uses PMS. Each A1 policy is optionally owned by a service. PMS can supervise each registered service by a heart-beat supervision and will automatically remove policies for unavailable services. Note that a service does not need to be registered in order to create A1 Policies. This is a feature that is optional to use.<\/p>", + "description": "

      General<\/h2>

      The O-RAN Non-RT RIC Policy Management Service provides a REST API for management of A1 policies.
      The main tasks of the service are:<\/p>

      • A1 Policy creation, modification and deletion.<\/li>
      • Monitoring and maintaining consistency of the SMO view of A1 policies and the Near-RT RICs<\/li>
      • Maintaining a view of supported Near-RT RIC policy types<\/li>
      • Supervision of using services (R-APPs). When a service is unavailable, its policies are removed.<\/li><\/ul>

        APIs provided by the service<\/h2>

        A1 Policy Management<\/h3>

        This is an API for management of A1 Policies.<\/p>

        • A1 Policy retrieval, creation, modification and deletion.<\/li>
        • Retrieval of supported A1 Policy types for a Near-RT RIC<\/li>
        • Retrieval of status for existing A1 policies<\/li><\/ul>

          Management of configuration<\/h3>

          API for updating and retrieval of the component configuration. Note that there other ways to maintain the configuration.<\/p>

          Callbacks<\/h3>

          These are endpoints that are invoked by this service. The callbacks are registered in this service at service registration.<\/p>

          NearRT-RIC Repository<\/h3>

          This is an API that provides support for looking up a NearRT-RIC. Each A1 policy is targeted for one Near-RT RIC.<\/p>

          Health Check<\/h3>

          API used for supervision of the PMS component.<\/p>

          Service Registry and Supervision<\/h3>

          API used for registering services that uses PMS. Each A1 policy is optionally owned by a service. PMS can supervise each registered service by a heart-beat supervision and will automatically remove policies for unavailable services. Note that a service does not need to be registered in order to create A1 Policies. This is a feature that is optional to use.<\/p>

          Spring Boot Actuator<\/h3>

          Provides generic functions used to monitor and manage the Spring web application.<\/p>", "title": "A1 Policy Management Service", "version": "1.1.0" }, diff --git a/a1-policy-management/api/pms-api.yaml b/a1-policy-management/api/pms-api.yaml index 6d620c23..2c692de2 100644 --- a/a1-policy-management/api/pms-api.yaml +++ b/a1-policy-management/api/pms-api.yaml @@ -21,9 +21,11 @@ info: Each A1 policy is optionally owned by a service. PMS can supervise each registered service by a heart-beat supervision and will automatically remove policies for unavailable services. Note that a service does not need to be registered in order - to create A1 Policies. This is a feature that is optional to use.

          + to create A1 Policies. This is a feature that is optional to use.

          Spring + Boot Actuator

          Provides generic functions used to monitor and manage the + Spring web application.

          license: - name: Copyright (C) 2020-2022 Nordix Foundation. Licensed under the Apache License. + name: Copyright (C) 2020-2023 Nordix Foundation. Licensed under the Apache License. url: http://www.apache.org/licenses/LICENSE-2.0 version: 1.1.0 servers: @@ -189,6 +191,19 @@ paths: application/json: schema: $ref: '#/components/schemas/error_information' + /actuator/shutdown: + post: + tags: + - Actuator + summary: Actuator web endpoint 'shutdown' + operationId: shutdown + responses: + 200: + description: OK + content: + '*/*': + schema: + type: object /a1-policy/v2/policy-types: get: tags: diff --git a/a1-policy-management/config/application.yaml b/a1-policy-management/config/application.yaml index 2bd8d83d..8f37aaa5 100644 --- a/a1-policy-management/config/application.yaml +++ b/a1-policy-management/config/application.yaml @@ -31,7 +31,12 @@ management: web: exposure: # Enabling of springboot actuator features. See springboot documentation. - include: "loggers,logfile,health,info,metrics,threaddump,heapdump" + include: "loggers,logfile,health,info,metrics,threaddump,heapdump,shutdown" + endpoint: + shutdown: + enabled: true +lifecycle: + timeout-per-shutdown-phase: "20s" springdoc: show-actuator: true logging: @@ -53,6 +58,7 @@ server: # See springboot documentation. port : 8433 http-port: 8081 + shutdown: "graceful" ssl: key-store-type: JKS key-store-password: policy_agent diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/Application.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/Application.java index ae114f67..259a5ba9 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/Application.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/Application.java @@ -20,13 +20,18 @@ package org.onap.ccsdk.oran.a1policymanagementservice; +import java.lang.invoke.MethodHandles; + import org.onap.ccsdk.oran.a1policymanagementservice.dmaap.DmaapMessageConsumer; import org.onap.ccsdk.oran.a1policymanagementservice.tasks.RefreshConfigTask; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; @SpringBootApplication @@ -38,8 +43,18 @@ public class Application { @Autowired private DmaapMessageConsumer dmaapMessageConsumer; + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + public static void main(String[] args) { - SpringApplication.run(Application.class); + 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); + } + }); } /** diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/SwaggerConfig.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/SwaggerConfig.java index 4c3a0c79..b6d3a076 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/SwaggerConfig.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/SwaggerConfig.java @@ -43,7 +43,7 @@ import org.onap.ccsdk.oran.a1policymanagementservice.controllers.v2.StatusContro version = SwaggerConfig.VERSION, // description = SwaggerConfig.DESCRIPTION, // license = @License( - name = "Copyright (C) 2020-2022 Nordix Foundation. Licensed under the Apache License.", // + name = "Copyright (C) 2020-2023 Nordix Foundation. Licensed under the Apache License.", // url = "http://www.apache.org/licenses/LICENSE-2.0")) // ) public class SwaggerConfig { @@ -83,10 +83,15 @@ public class SwaggerConfig { + H3 + StatusController.API_NAME + H3_END + // "

          API used for supervision of the PMS component.

          " + // H3 + ServiceController.API_NAME + H3_END + // - "

          " + "API used for registering services that uses PMS." + "

          " // + + "API used for registering services that uses PMS." + " Each A1 policy is optionally owned by a service. PMS can supervise each registered service by a heart-beat supervision and will automatically remove policies for unavailable services." + " Note that a service does not need to be registered in order to create A1 Policies. This is a feature that is optional to use." - + "

          "; + + "

          " + // + H3 + "Spring Boot Actuator" + H3_END + // + "

          " // + + "Provides generic functions used to monitor and manage the Spring web application." + // + "

          "; public static final String VERSION = "1.1.0"; } diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/aspect/LogAspect.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/aspect/LogAspect.java index 16f4a7f8..1c40f04f 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/aspect/LogAspect.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/aspect/LogAspect.java @@ -20,6 +20,8 @@ package org.onap.ccsdk.oran.a1policymanagementservice.aspect; +import java.lang.invoke.MethodHandles; + import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; @@ -36,7 +38,7 @@ import org.springframework.util.StopWatch; @Component public class LogAspect { - private static final Logger logger = LoggerFactory.getLogger(LogAspect.class); + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); @Around("execution(* org.onap.ccsdk.oran.a1policymanagementservice..*(..)))") public void executimeTime(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactory.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactory.java index 45c0bc42..0956aa13 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactory.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactory.java @@ -20,6 +20,7 @@ package org.onap.ccsdk.oran.a1policymanagementservice.clients; +import java.lang.invoke.MethodHandles; import java.lang.reflect.Constructor; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1Client.A1ProtocolType; @@ -38,7 +39,7 @@ import reactor.core.publisher.Mono; */ public class A1ClientFactory { - private static final Logger logger = LoggerFactory.getLogger(A1ClientFactory.class); + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private final ApplicationConfig appConfig; diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ConfigurationFile.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ConfigurationFile.java index 4af39c92..9db66202 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ConfigurationFile.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ConfigurationFile.java @@ -30,6 +30,7 @@ import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.lang.invoke.MethodHandles; import java.util.Optional; import javax.validation.constraints.NotNull; @@ -41,7 +42,7 @@ import org.springframework.stereotype.Component; @Component public class ConfigurationFile { - private static final Logger logger = LoggerFactory.getLogger(ConfigurationFile.class); + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); final ApplicationConfig appConfig; final Gson gson = new Gson(); diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/datastore/S3ObjectStore.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/datastore/S3ObjectStore.java index 4c7c3c3e..5b81f756 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/datastore/S3ObjectStore.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/datastore/S3ObjectStore.java @@ -20,6 +20,7 @@ package org.onap.ccsdk.oran.a1policymanagementservice.datastore; +import java.lang.invoke.MethodHandles; import java.net.URI; import java.util.concurrent.CompletableFuture; @@ -53,7 +54,7 @@ import software.amazon.awssdk.services.s3.model.PutObjectResponse; import software.amazon.awssdk.services.s3.model.S3Object; class S3ObjectStore implements DataStore { - private static final Logger logger = LoggerFactory.getLogger(S3ObjectStore.class); + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private final ApplicationConfig applicationConfig; private static S3AsyncClient s3AsynchClient; diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/dmaap/DmaapMessageConsumer.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/dmaap/DmaapMessageConsumer.java index 47c73506..94888c38 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/dmaap/DmaapMessageConsumer.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/dmaap/DmaapMessageConsumer.java @@ -26,6 +26,7 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonParser; +import java.lang.invoke.MethodHandles; import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -63,7 +64,7 @@ public class DmaapMessageConsumer { protected static final Duration TIME_BETWEEN_DMAAP_RETRIES = Duration.ofSeconds(10); - private static final Logger logger = LoggerFactory.getLogger(DmaapMessageConsumer.class); + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private final ApplicationConfig applicationConfig; diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/dmaap/DmaapMessageHandler.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/dmaap/DmaapMessageHandler.java index d0354174..022dec05 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/dmaap/DmaapMessageHandler.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/dmaap/DmaapMessageHandler.java @@ -24,6 +24,8 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; +import java.lang.invoke.MethodHandles; + import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClient; import org.onap.ccsdk.oran.a1policymanagementservice.dmaap.DmaapRequestMessage.Operation; import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException; @@ -42,7 +44,7 @@ import reactor.core.publisher.Mono; * response though DMAAP */ public class DmaapMessageHandler { - private static final Logger logger = LoggerFactory.getLogger(DmaapMessageHandler.class); + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private static Gson gson = new GsonBuilder().create(); private final AsyncRestClient dmaapClient; private final AsyncRestClient pmsClient; diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/exceptions/GlobalExceptionHandler.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/exceptions/GlobalExceptionHandler.java index 547cd6b0..77d01969 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/exceptions/GlobalExceptionHandler.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/exceptions/GlobalExceptionHandler.java @@ -20,6 +20,8 @@ package org.onap.ccsdk.oran.a1policymanagementservice.exceptions; +import java.lang.invoke.MethodHandles; + import org.onap.ccsdk.oran.a1policymanagementservice.controllers.v2.ErrorResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,7 +35,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExcep @ControllerAdvice(annotations = RestController.class) public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { - private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class); + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); @ExceptionHandler(ServiceException.class) public final ResponseEntity handleServiceException(ServiceException ex) { diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Lock.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Lock.java index 46033a4a..c40bf504 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Lock.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Lock.java @@ -20,6 +20,7 @@ package org.onap.ccsdk.oran.a1policymanagementservice.repository; +import java.lang.invoke.MethodHandles; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -39,7 +40,7 @@ import reactor.core.publisher.MonoSink; * resource (for shared usage). */ public class Lock { - private static final Logger logger = LoggerFactory.getLogger(Lock.class); + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); boolean isExclusive = false; private int lockCounter = 0; diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Ric.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Ric.java index 2971feb2..290b109b 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Ric.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Ric.java @@ -20,6 +20,7 @@ package org.onap.ccsdk.oran.a1policymanagementservice.repository; +import java.lang.invoke.MethodHandles; import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -37,7 +38,7 @@ import org.slf4j.LoggerFactory; * Holds information about a Near-RT RIC. */ public class Ric { - private static final Logger logger = LoggerFactory.getLogger(Ric.class); + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); @Setter private RicConfig ricConfig; diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Services.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Services.java index 9c2846a9..d8a902e9 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Services.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Services.java @@ -22,6 +22,7 @@ package org.onap.ccsdk.oran.a1policymanagementservice.repository; import com.google.gson.Gson; +import java.lang.invoke.MethodHandles; import java.util.HashMap; import java.util.Map; import java.util.Vector; @@ -37,7 +38,7 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; public class Services { - private static final Logger logger = LoggerFactory.getLogger(Services.class); + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private static Gson gson = Service.createGson(); private final DataStore dataStore; diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTask.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTask.java index 978ae1c0..b3023f84 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTask.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTask.java @@ -22,6 +22,7 @@ package org.onap.ccsdk.oran.a1policymanagementservice.tasks; import com.google.gson.JsonObject; +import java.lang.invoke.MethodHandles; import java.time.Duration; import java.util.Optional; import java.util.Properties; @@ -59,7 +60,7 @@ import reactor.util.annotation.Nullable; @SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally public class RefreshConfigTask { - private static final Logger logger = LoggerFactory.getLogger(RefreshConfigTask.class); + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); @Value("#{systemEnvironment}") public Properties systemEnvironment; diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervision.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervision.java index 1f612e42..3f0d3a0c 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervision.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSupervision.java @@ -20,6 +20,7 @@ package org.onap.ccsdk.oran.a1policymanagementservice.tasks; +import java.lang.invoke.MethodHandles; import java.util.Collection; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1Client; @@ -53,7 +54,7 @@ import reactor.core.publisher.Mono; @EnableScheduling @SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally public class RicSupervision { - private static final Logger logger = LoggerFactory.getLogger(RicSupervision.class); + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private static final int CONCURRENCY = 50; // Number of RIC checked in paralell private final Rics rics; diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTask.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTask.java index d1bd433b..c07cf2cd 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTask.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTask.java @@ -22,6 +22,7 @@ package org.onap.ccsdk.oran.a1policymanagementservice.tasks; import static org.onap.ccsdk.oran.a1policymanagementservice.repository.Ric.RicState; +import java.lang.invoke.MethodHandles; import java.util.Set; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1Client; @@ -58,7 +59,7 @@ import reactor.core.publisher.SignalType; @SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally public class RicSynchronizationTask { - private static final Logger logger = LoggerFactory.getLogger(RicSynchronizationTask.class); + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); static final int CONCURRENCY_RIC = 1; // How many paralell requests that is sent to one NearRT RIC private final A1ClientFactory a1ClientFactory; diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/ServiceSupervision.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/ServiceSupervision.java index e40634e2..f9853af9 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/ServiceSupervision.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/ServiceSupervision.java @@ -20,6 +20,7 @@ package org.onap.ccsdk.oran.a1policymanagementservice.tasks; +import java.lang.invoke.MethodHandles; import java.time.Duration; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1ClientFactory; @@ -49,7 +50,7 @@ import reactor.core.publisher.Mono; @EnableScheduling @SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally public class ServiceSupervision { - private static final Logger logger = LoggerFactory.getLogger(ServiceSupervision.class); + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); static final int CONCURRENCY_RIC = 1; // How may paralell requests that is sent private final Services services; private final Policies policies; diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/MockPolicyManagementService.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/MockPolicyManagementService.java index 3b7695e8..d60c4322 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/MockPolicyManagementService.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/MockPolicyManagementService.java @@ -27,6 +27,7 @@ import com.google.gson.JsonParser; import java.io.File; import java.io.IOException; +import java.lang.invoke.MethodHandles; import java.net.URL; import java.nio.file.Files; import java.time.Instant; @@ -61,7 +62,7 @@ import org.springframework.util.StringUtils; // but a mock // of the server. class MockPolicyManagementService { - private static final Logger logger = LoggerFactory.getLogger(MockPolicyManagementService.class); + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); @Autowired Rics rics; diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ApplicationTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ApplicationTest.java index bec55735..1e8278a9 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ApplicationTest.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ApplicationTest.java @@ -33,6 +33,7 @@ import com.google.gson.GsonBuilder; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; +import java.lang.invoke.MethodHandles; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -46,7 +47,9 @@ import java.util.List; import org.json.JSONObject; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1ClientFactory; import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClient; import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClientFactory; @@ -89,12 +92,14 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.test.context.TestPropertySource; import org.springframework.util.FileSystemUtils; +import org.springframework.web.reactive.function.client.WebClientRequestException; import org.springframework.web.reactive.function.client.WebClientResponseException; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import reactor.util.annotation.Nullable; +@TestMethodOrder(MethodOrderer.MethodName.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @TestPropertySource(properties = { // "server.ssl.key-store=./config/keystore.jks", // @@ -105,7 +110,7 @@ import reactor.util.annotation.Nullable; "app.s3.bucket=" // If this is set, S3 will be used to store data. }) class ApplicationTest { - private static final Logger logger = LoggerFactory.getLogger(ApplicationTest.class); + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); @Autowired ApplicationContext context; @@ -200,6 +205,33 @@ class ApplicationTest { } } + @Test + @SuppressWarnings("squid:S2925") // "Thread.sleep" should not be used in tests. + void testZZActuator() throws Exception { + // The test must be run last, hence the "ZZ" in the name. All succeeding tests + // will fail. + AsyncRestClient client = restClient(baseUrl(), false); + + client.post("/actuator/loggers/org.onap.ccsdk.oran.a1policymanagementservice", + "{\"configuredLevel\":\"trace\"}").block(); + + String resp = client.get("/actuator/loggers/org.onap.ccsdk.oran.a1policymanagementservice").block(); + assertThat(resp).contains("TRACE"); + + client.post("/actuator/loggers/org.springframework.boot.actuate", "{\"configuredLevel\":\"trace\"}").block(); + + // This will stop the web server and all coming tests will fail. + client.post("/actuator/shutdown", "").block(); + + Thread.sleep(1000); + + StepVerifier.create(restClient().get("/rics")) // Any call + .expectSubscription() // + .expectErrorMatches(t -> t instanceof WebClientRequestException) // + .verify(); + + } + @Test void generateApiDoc() throws IOException { String url = "https://localhost:" + this.port + "/v3/api-docs"; diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConcurrencyTestRunnable.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConcurrencyTestRunnable.java index 3a4aae86..4e535ab2 100644 --- a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConcurrencyTestRunnable.java +++ b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConcurrencyTestRunnable.java @@ -23,6 +23,7 @@ package org.onap.ccsdk.oran.a1policymanagementservice.controllers.v2; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import java.lang.invoke.MethodHandles; import java.time.Instant; import java.util.concurrent.atomic.AtomicInteger; @@ -44,7 +45,7 @@ import org.springframework.http.ResponseEntity; * thread. For test of robustness using concurrent clients. */ class ConcurrencyTestRunnable implements Runnable { - private static final Logger logger = LoggerFactory.getLogger(ConcurrencyTestRunnable.class); + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private final AsyncRestClient webClient; static AtomicInteger nextCount = new AtomicInteger(0); private final int count; diff --git a/docs/offeredapis/swagger/pms-api.json b/docs/offeredapis/swagger/pms-api.json index ce2d9aa8..b8a9b955 100644 --- a/docs/offeredapis/swagger/pms-api.json +++ b/docs/offeredapis/swagger/pms-api.json @@ -471,6 +471,21 @@ ], "tags": ["NearRT-RIC Repository"] }}, + "/actuator/shutdown": {"post": { + "summary": "Actuator web endpoint 'shutdown'", + "operationId": "shutdown", + "responses": {"200": { + "description": "OK", + "content": {"*/*": { + "schema": { + "type": "object", + "example": null + }, + "example": null + }} + }}, + "tags": ["Actuator"] + }}, "/a1-policy/v2/policy-types": {"get": { "summary": "Query policy type identities", "operationId": "getPolicyTypes", @@ -1221,10 +1236,10 @@ }, "info": { "license": { - "name": "Copyright (C) 2020-2022 Nordix Foundation. Licensed under the Apache License.", + "name": "Copyright (C) 2020-2023 Nordix Foundation. Licensed under the Apache License.", "url": "http://www.apache.org/licenses/LICENSE-2.0" }, - "description": "

          General<\/h2>

          The O-RAN Non-RT RIC Policy Management Service provides a REST API for management of A1 policies.
          The main tasks of the service are:<\/p>

          • A1 Policy creation, modification and deletion.<\/li>
          • Monitoring and maintaining consistency of the SMO view of A1 policies and the Near-RT RICs<\/li>
          • Maintaining a view of supported Near-RT RIC policy types<\/li>
          • Supervision of using services (R-APPs). When a service is unavailable, its policies are removed.<\/li><\/ul>

            APIs provided by the service<\/h2>

            A1 Policy Management<\/h3>

            This is an API for management of A1 Policies.<\/p>

            • A1 Policy retrieval, creation, modification and deletion.<\/li>
            • Retrieval of supported A1 Policy types for a Near-RT RIC<\/li>
            • Retrieval of status for existing A1 policies<\/li><\/ul>

              Management of configuration<\/h3>

              API for updating and retrieval of the component configuration. Note that there other ways to maintain the configuration.<\/p>

              Callbacks<\/h3>

              These are endpoints that are invoked by this service. The callbacks are registered in this service at service registration.<\/p>

              NearRT-RIC Repository<\/h3>

              This is an API that provides support for looking up a NearRT-RIC. Each A1 policy is targeted for one Near-RT RIC.<\/p>

              Health Check<\/h3>

              API used for supervision of the PMS component.<\/p>

              Service Registry and Supervision<\/h3>

              API used for registering services that uses PMS. Each A1 policy is optionally owned by a service. PMS can supervise each registered service by a heart-beat supervision and will automatically remove policies for unavailable services. Note that a service does not need to be registered in order to create A1 Policies. This is a feature that is optional to use.<\/p>", + "description": "

              General<\/h2>

              The O-RAN Non-RT RIC Policy Management Service provides a REST API for management of A1 policies.
              The main tasks of the service are:<\/p>

              • A1 Policy creation, modification and deletion.<\/li>
              • Monitoring and maintaining consistency of the SMO view of A1 policies and the Near-RT RICs<\/li>
              • Maintaining a view of supported Near-RT RIC policy types<\/li>
              • Supervision of using services (R-APPs). When a service is unavailable, its policies are removed.<\/li><\/ul>

                APIs provided by the service<\/h2>

                A1 Policy Management<\/h3>

                This is an API for management of A1 Policies.<\/p>

                • A1 Policy retrieval, creation, modification and deletion.<\/li>
                • Retrieval of supported A1 Policy types for a Near-RT RIC<\/li>
                • Retrieval of status for existing A1 policies<\/li><\/ul>

                  Management of configuration<\/h3>

                  API for updating and retrieval of the component configuration. Note that there other ways to maintain the configuration.<\/p>

                  Callbacks<\/h3>

                  These are endpoints that are invoked by this service. The callbacks are registered in this service at service registration.<\/p>

                  NearRT-RIC Repository<\/h3>

                  This is an API that provides support for looking up a NearRT-RIC. Each A1 policy is targeted for one Near-RT RIC.<\/p>

                  Health Check<\/h3>

                  API used for supervision of the PMS component.<\/p>

                  Service Registry and Supervision<\/h3>

                  API used for registering services that uses PMS. Each A1 policy is optionally owned by a service. PMS can supervise each registered service by a heart-beat supervision and will automatically remove policies for unavailable services. Note that a service does not need to be registered in order to create A1 Policies. This is a feature that is optional to use.<\/p>

                  Spring Boot Actuator<\/h3>

                  Provides generic functions used to monitor and manage the Spring web application.<\/p>", "title": "A1 Policy Management Service", "version": "1.1.0" }, diff --git a/docs/offeredapis/swagger/pms-api.yaml b/docs/offeredapis/swagger/pms-api.yaml index 6d620c23..2c692de2 100644 --- a/docs/offeredapis/swagger/pms-api.yaml +++ b/docs/offeredapis/swagger/pms-api.yaml @@ -21,9 +21,11 @@ info: Each A1 policy is optionally owned by a service. PMS can supervise each registered service by a heart-beat supervision and will automatically remove policies for unavailable services. Note that a service does not need to be registered in order - to create A1 Policies. This is a feature that is optional to use.

                  + to create A1 Policies. This is a feature that is optional to use.

                  Spring + Boot Actuator

                  Provides generic functions used to monitor and manage the + Spring web application.

                  license: - name: Copyright (C) 2020-2022 Nordix Foundation. Licensed under the Apache License. + name: Copyright (C) 2020-2023 Nordix Foundation. Licensed under the Apache License. url: http://www.apache.org/licenses/LICENSE-2.0 version: 1.1.0 servers: @@ -189,6 +191,19 @@ paths: application/json: schema: $ref: '#/components/schemas/error_information' + /actuator/shutdown: + post: + tags: + - Actuator + summary: Actuator web endpoint 'shutdown' + operationId: shutdown + responses: + 200: + description: OK + content: + '*/*': + schema: + type: object /a1-policy/v2/policy-types: get: tags: -- cgit 1.2.3-korg