From 1b8d76de3262675c5afe45351929b0d5d2c0bab1 Mon Sep 17 00:00:00 2001 From: PatrikBuhr Date: Thu, 30 Jan 2020 16:10:19 +0100 Subject: [PATCH] Running Dmaap consumer in a seprate thread Fixed some potential threading problems Enabled spring boot actuator for REST API to control traces, diagnostics etc. API documentation updates Added GET policy_status in the agent NBI Change-Id: Ied170bb1e8f350f17b385a0ef1def87cc6ec8750 Issue-ID: NONRTRIC-107 Signed-off-by: PatrikBuhr --- docs/api-docs.rst | 3 +- policy-agent/docs/{api.doc => api.yaml} | 433 ++++++++++++++-- policy-agent/pom.xml | 554 +++++++++++---------- .../java/org/oransc/policyagent/SwaggerConfig.java | 48 +- .../org/oransc/policyagent/clients/A1Client.java | 2 + .../oransc/policyagent/clients/OscA1Client.java | 7 + .../policyagent/clients/SdncOscA1Client.java | 5 + .../policyagent/clients/SdnrOnapA1Client.java | 5 + .../oransc/policyagent/clients/StdA1Client.java | 5 + .../configuration/ApplicationConfig.java | 8 +- .../configuration/ApplicationConfigParser.java | 31 +- .../policyagent/controllers/PolicyController.java | 27 +- .../controllers/RicRepositoryController.java | 2 +- .../dmaap/DmaapMessageConsumerImpl.java | 92 ++-- .../policyagent/dmaap/DmaapMessageHandler.java | 50 +- .../org/oransc/policyagent/repository/Ric.java | 37 +- .../policyagent/tasks/RefreshConfigTask.java | 4 +- .../oransc/policyagent/tasks/RicRecoveryTask.java | 3 +- .../org/oransc/policyagent/ApplicationTest.java | 13 + .../configuration/ApplicationConfigParserTest.java | 3 + .../configuration/ApplicationConfigTest.java | 1 + .../policyagent/dmaap/DmaapMessageHandlerTest.java | 4 + .../org/oransc/policyagent/utils/MockA1Client.java | 5 + 23 files changed, 904 insertions(+), 438 deletions(-) rename policy-agent/docs/{api.doc => api.yaml} (55%) diff --git a/docs/api-docs.rst b/docs/api-docs.rst index 7365572a..acfe38cf 100644 --- a/docs/api-docs.rst +++ b/docs/api-docs.rst @@ -68,8 +68,7 @@ See the README.md file in the nonrtric/policy-agent repo for info about how to u API Functions ------------- - -See the following document for the Policy Agent API: nonrtric/policy-agent/docs/api.doc. +See the following document for the Policy Agent API: nonrtric/policy-agent/docs/api.yaml Near-RT RIC Simulator ===================== diff --git a/policy-agent/docs/api.doc b/policy-agent/docs/api.yaml similarity index 55% rename from policy-agent/docs/api.doc rename to policy-agent/docs/api.yaml index e3f44ed2..14162989 100644 --- a/policy-agent/docs/api.doc +++ b/policy-agent/docs/api.yaml @@ -1,16 +1,13 @@ swagger: '2.0' info: - description: Api Documentation + description: This page lists all the rest apis for Policy server. version: '1.0' - title: Api Documentation - termsOfService: 'urn:tos' - contact: {} - license: - name: Apache 2.0 - url: 'http://www.apache.org/licenses/LICENSE-2.0' + title: Policy server host: 'localhost:8081' basePath: / tags: + - name: operation-handler + description: Operation Handler - name: policy-controller description: Policy Controller - name: ric-repository-controller @@ -19,21 +16,324 @@ tags: description: Service Controller - name: status-controller description: Status Controller + - name: web-mvc-links-handler + description: Web Mvc Links Handler paths: + /actuator: + get: + tags: + - web-mvc-links-handler + summary: links + operationId: linksUsingGET + produces: + - application/vnd.spring-boot.actuator.v3+json + - application/json + - application/vnd.spring-boot.actuator.v2+json + responses: + '200': + description: OK + schema: + type: object + additionalProperties: + type: object + additionalProperties: + $ref: '#/definitions/Link' + '401': + description: Unauthorized + '403': + description: Forbidden + '404': + description: Not Found + deprecated: false + /actuator/health: + get: + tags: + - operation-handler + summary: handle + operationId: handleUsingGET_1 + produces: + - application/vnd.spring-boot.actuator.v3+json + - application/json + - application/vnd.spring-boot.actuator.v2+json + parameters: + - in: body + name: body + description: body + required: false + schema: + type: object + additionalProperties: + type: string + responses: + '200': + description: OK + schema: + type: object + '401': + description: Unauthorized + '403': + description: Forbidden + '404': + description: Not Found + deprecated: false + /actuator/health/**: + get: + tags: + - operation-handler + summary: handle + operationId: handleUsingGET + produces: + - application/vnd.spring-boot.actuator.v3+json + - application/json + - application/vnd.spring-boot.actuator.v2+json + parameters: + - in: body + name: body + description: body + required: false + schema: + type: object + additionalProperties: + type: string + responses: + '200': + description: OK + schema: + type: object + '401': + description: Unauthorized + '403': + description: Forbidden + '404': + description: Not Found + deprecated: false + /actuator/info: + get: + tags: + - operation-handler + summary: handle + operationId: handleUsingGET_2 + produces: + - application/vnd.spring-boot.actuator.v3+json + - application/json + - application/vnd.spring-boot.actuator.v2+json + parameters: + - in: body + name: body + description: body + required: false + schema: + type: object + additionalProperties: + type: string + responses: + '200': + description: OK + schema: + type: object + '401': + description: Unauthorized + '403': + description: Forbidden + '404': + description: Not Found + deprecated: false + /actuator/logfile: + get: + tags: + - operation-handler + summary: handle + operationId: handleUsingGET_3 + produces: + - text/plain;charset=UTF-8 + parameters: + - in: body + name: body + description: body + required: false + schema: + type: object + additionalProperties: + type: string + responses: + '200': + description: OK + schema: + type: object + '401': + description: Unauthorized + '403': + description: Forbidden + '404': + description: Not Found + deprecated: false + /actuator/loggers: + get: + tags: + - operation-handler + summary: handle + operationId: handleUsingGET_5 + produces: + - application/vnd.spring-boot.actuator.v3+json + - application/json + - application/vnd.spring-boot.actuator.v2+json + parameters: + - in: body + name: body + description: body + required: false + schema: + type: object + additionalProperties: + type: string + responses: + '200': + description: OK + schema: + type: object + '401': + description: Unauthorized + '403': + description: Forbidden + '404': + description: Not Found + deprecated: false + '/actuator/loggers/{name}': + get: + tags: + - operation-handler + summary: handle + operationId: handleUsingGET_4 + produces: + - application/vnd.spring-boot.actuator.v3+json + - application/json + - application/vnd.spring-boot.actuator.v2+json + parameters: + - in: body + name: body + description: body + required: false + schema: + type: object + additionalProperties: + type: string + responses: + '200': + description: OK + schema: + type: object + '401': + description: Unauthorized + '403': + description: Forbidden + '404': + description: Not Found + deprecated: false + post: + tags: + - operation-handler + summary: handle + operationId: handleUsingPOST + consumes: + - application/vnd.spring-boot.actuator.v3+json + - application/json + - application/vnd.spring-boot.actuator.v2+json + produces: + - '*/*' + parameters: + - in: body + name: body + description: body + required: false + schema: + type: object + additionalProperties: + type: string + responses: + '200': + description: OK + schema: + type: object + '201': + description: Created + '401': + description: Unauthorized + '403': + description: Forbidden + '404': + description: Not Found + deprecated: false + /actuator/metrics: + get: + tags: + - operation-handler + summary: handle + operationId: handleUsingGET_7 + produces: + - application/vnd.spring-boot.actuator.v3+json + - application/json + - application/vnd.spring-boot.actuator.v2+json + parameters: + - in: body + name: body + description: body + required: false + schema: + type: object + additionalProperties: + type: string + responses: + '200': + description: OK + schema: + type: object + '401': + description: Unauthorized + '403': + description: Forbidden + '404': + description: Not Found + deprecated: false + '/actuator/metrics/{requiredMetricName}': + get: + tags: + - operation-handler + summary: handle + operationId: handleUsingGET_6 + produces: + - application/vnd.spring-boot.actuator.v3+json + - application/json + - application/vnd.spring-boot.actuator.v2+json + parameters: + - in: body + name: body + description: body + required: false + schema: + type: object + additionalProperties: + type: string + responses: + '200': + description: OK + schema: + type: object + '401': + description: Unauthorized + '403': + description: Forbidden + '404': + description: Not Found + deprecated: false /policies: get: tags: - policy-controller - summary: Returns the policies + summary: Query policies operationId: getPoliciesUsingGET produces: - '*/*' parameters: - - name: type - in: query - description: type - required: false - type: string - name: ric in: query description: ric @@ -44,6 +344,11 @@ paths: description: service required: false type: string + - name: type + in: query + description: type + required: false + type: string responses: '200': description: Policies @@ -57,6 +362,7 @@ paths: description: Forbidden '404': description: Not Found + deprecated: false /policy: get: tags: @@ -86,6 +392,7 @@ paths: description: Forbidden '404': description: Not Found + deprecated: false put: tags: - policy-controller @@ -96,16 +403,17 @@ paths: produces: - '*/*' parameters: - - name: type - in: query - description: type - required: true - type: string - name: instance in: query description: instance required: true type: string + - in: body + name: jsonBody + description: jsonBody + required: true + schema: + type: object - name: ric in: query description: ric @@ -116,12 +424,11 @@ paths: description: service required: true type: string - - in: body - name: jsonBody - description: jsonBody + - name: type + in: query + description: type required: true - schema: - type: object + type: string responses: '200': description: Policy created or updated @@ -135,10 +442,11 @@ paths: description: Forbidden '404': description: Not Found + deprecated: false delete: tags: - policy-controller - summary: Deletes the policy + summary: Delete a policy operationId: deletePolicyUsingDELETE produces: - '*/*' @@ -152,15 +460,16 @@ paths: '200': description: OK schema: - $ref: '#/definitions/Mono«ResponseEntity«Void»»' + type: object '204': description: Policy deleted schema: - $ref: '#/definitions/Mono«ResponseEntity«Void»»' + type: object '401': description: Unauthorized '403': description: Forbidden + deprecated: false /policy_schema: get: tags: @@ -186,6 +495,7 @@ paths: description: Forbidden '404': description: Not Found + deprecated: false /policy_schemas: get: tags: @@ -213,11 +523,42 @@ paths: description: Forbidden '404': description: Not Found + deprecated: false + /policy_status: + get: + tags: + - policy-controller + summary: Returns a policy status + operationId: getPolicyStatusUsingGET + produces: + - '*/*' + parameters: + - name: instance + in: query + description: instance + required: true + type: string + responses: + '200': + description: Policy status + schema: + type: object + '204': + description: Policy is not found + schema: + type: string + '401': + description: Unauthorized + '403': + description: Forbidden + '404': + description: Not Found + deprecated: false /policy_types: get: tags: - policy-controller - summary: Returns policy types + summary: Query policy type names operationId: getPolicyTypesUsingGET produces: - '*/*' @@ -240,6 +581,7 @@ paths: description: Forbidden '404': description: Not Found + deprecated: false /ric: get: tags: @@ -267,11 +609,12 @@ paths: description: RIC is not fond schema: type: string + deprecated: false /rics: get: tags: - ric-repository-controller - summary: Returns NearRT RIC information + summary: Query NearRT RIC information operationId: getRicsUsingGET produces: - '*/*' @@ -294,6 +637,7 @@ paths: description: Forbidden '404': description: Not Found + deprecated: false /service: put: tags: @@ -324,6 +668,7 @@ paths: description: Forbidden '404': description: Not Found + deprecated: false /services: get: tags: @@ -351,6 +696,7 @@ paths: description: Forbidden '404': description: Not Found + deprecated: false delete: tags: - service-controller @@ -375,6 +721,7 @@ paths: description: Unauthorized '403': description: Forbidden + deprecated: false /services/keepalive: post: tags: @@ -404,6 +751,7 @@ paths: description: Forbidden '404': description: 'The service is not found, needs re-registration' + deprecated: false /status: get: tags: @@ -423,7 +771,21 @@ paths: description: Forbidden '404': description: Not Found + deprecated: false definitions: + Link: + type: object + properties: + href: + type: string + templated: + type: boolean + title: Link + 'Map«string,Link»': + type: object + title: 'Map«string,Link»' + additionalProperties: + $ref: '#/definitions/Link' Mono«ResponseEntity«Void»»: type: object title: Mono«ResponseEntity«Void»» @@ -436,27 +798,21 @@ definitions: id: type: string description: identity of the policy - allowEmptyValue: false json: type: string description: the configuration of the policy - allowEmptyValue: false lastModified: type: string description: 'timestamp, last modification time' - allowEmptyValue: false ric: type: string description: identity the target NearRT RIC - allowEmptyValue: false service: type: string description: the name of the service owning the policy - allowEmptyValue: false type: type: string description: name of the policy type - allowEmptyValue: false title: PolicyInfo RicInfo: type: object @@ -464,17 +820,14 @@ definitions: managedElementIds: type: array description: O1 identities for managed entities - allowEmptyValue: false items: type: string name: type: string description: identity of the ric - allowEmptyValue: false policyTypes: type: array description: supported policy types - allowEmptyValue: false items: type: string title: RicInfo @@ -484,16 +837,13 @@ definitions: callbackUrl: type: string description: callback for notifying of RIC recovery - allowEmptyValue: false keepAliveIntervalSeconds: type: integer format: int64 description: keep alive interval for policies owned by the service. 0 means no timeout supervision. Polcies that are not refreshed within this time are removed - allowEmptyValue: false name: type: string description: identity of the service - allowEmptyValue: false title: ServiceRegistrationInfo ServiceStatus: type: object @@ -502,15 +852,12 @@ definitions: type: integer format: int64 description: policy keep alive timeout - allowEmptyValue: false name: type: string description: identity of the service - allowEmptyValue: false timeSincePingSeconds: type: integer format: int64 description: time since last invocation by the service - allowEmptyValue: false title: ServiceStatus diff --git a/policy-agent/pom.xml b/policy-agent/pom.xml index 311229fd..daad4188 100644 --- a/policy-agent/pom.xml +++ b/policy-agent/pom.xml @@ -18,174 +18,180 @@ * limitations under the License. * ========================LICENSE_END=================================== --> - - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.2.4.RELEASE - - - org.o-ran-sc.nonrtric - policy-agent - 1.0.0-SNAPSHOT - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - - - - - onap-releases - onap-releases - https://nexus.onap.org/content/repositories/releases/ - - - - 11 - 2.8.0 - 2.7.1 - 1.1.6 - 2.0.0 - 20180130 + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.2.4.RELEASE + + + org.o-ran-sc.nonrtric + policy-agent + 1.0.0-SNAPSHOT + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + + + + + onap-releases + onap-releases + https://nexus.onap.org/content/repositories/releases/ + + + + 11 + 2.9.2 + 2.7.1 + 1.1.6 + 2.0.0 + 20180130 3.3 - 4.0.1 - 3.8.0 - 2.8.1 - 1.18.0 - 0.30.0 - 1.1.9 + 4.0.1 + 3.8.0 + 2.8.1 + 1.18.0 + 0.30.0 + 1.1.9 2.1.1 - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-thymeleaf - - - org.springframework.boot - spring-boot-starter-webflux - - - org.springframework.boot - spring-boot-devtools - true - - - org.springframework - spring-webflux - - - io.swagger.core.v3 - swagger-jaxrs2 - ${swagger.version} - - - io.swagger.core.v3 - swagger-jaxrs2-servlet-initializer - ${swagger.version} - - - javax.xml.bind - jaxb-api - - - org.immutables - value - ${immutable.version} - provided - - - org.immutables - gson - ${immutable.version} - - - org.json - json - ${json.version} - + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.boot + spring-boot-devtools + true + + + org.springframework + spring-webflux + + + io.swagger.core.v3 + swagger-jaxrs2 + ${swagger.version} + + + io.swagger.core.v3 + swagger-jaxrs2-servlet-initializer + ${swagger.version} + + + javax.xml.bind + jaxb-api + + + org.immutables + value + ${immutable.version} + provided + + + org.immutables + gson + ${immutable.version} + + + org.json + json + ${json.version} + commons-net commons-net ${commons-net.version} - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.onap.dcaegen2.services.sdk.rest.services - cbs-client + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.onap.dcaegen2.services.sdk.rest.services + cbs-client ${sdk.version} org.onap.dcaegen2.services.sdk.rest.services dmaap-client - ${sdk.version} - + ${sdk.version} + org.projectlombok lombok provided - - - io.springfox - springfox-swagger2 - ${springfox.version} - - - io.springfox - springfox-swagger-ui - ${springfox.version} - - - - org.awaitility - awaitility - ${awaitility.version} - test - - - io.projectreactor - reactor-test - test - - - org.junit.jupiter - junit-jupiter-engine - test - - - org.mockito - mockito-junit-jupiter - test - - - org.mockito - mockito-core - test - - - org.onap.dmaap.messagerouter.dmaapclient - dmaapClient - ${version.dmaap} - + + + io.springfox + springfox-swagger2 + ${springfox.version} + + + io.springfox + springfox-swagger-ui + ${springfox.version} + + + + org.awaitility + awaitility + ${awaitility.version} + test + + + io.projectreactor + reactor-test + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.mockito + mockito-junit-jupiter + test + + + org.mockito + mockito-core + test + + + org.onap.dmaap.messagerouter.dmaapclient + dmaapClient + ${version.dmaap} + javax.ws.rs javax.ws.rs-api @@ -195,131 +201,131 @@ org.glassfish.jersey.inject jersey-hk2 - - - - - org.springframework.boot - spring-boot-maven-plugin - - - net.revelc.code.formatter - formatter-maven-plugin - ${formatter-maven-plugin.version} - - ${project.basedir}/eclipse-formatter.xml - - - - - com.diffplug.spotless - spotless-maven-plugin - ${spotless-maven-plugin.version} - - - - - com,java,javax,org - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - false - - - - maven-failsafe-plugin - - - org.codehaus.mojo - build-helper-maven-plugin - - - add-source - generate-sources - - add-source - - - - ${project.build.directory}/generated-sources/annotations/ - - - - - - - io.fabric8 - docker-maven-plugin - ${docker-maven-plugin} - false - - - generate-policy-agent-image - package - - build - - - ${env.CONTAINER_PULL_REGISTRY} - - - o-ran-sc/nonrtric-policy-agent:${project.version} - - try - ${basedir} - Dockerfile - - ${project.build.finalName}.jar - - - ${project.version} - - - - - - - - push-policy-agent-image - - build - push - - - ${env.CONTAINER_PULL_REGISTRY} - ${env.CONTAINER_PUSH_REGISTRY} - - - o-ran-sc/nonrtric-policy-agent:${project.version} - - ${basedir} - Dockerfile - - ${project.build.finalName}.jar - - - ${project.version} - - - - - - - - - - - - JIRA - https://jira.o-ran-sc.org/ - + + + org.apache.maven.plugins + maven-surefire-plugin + + false + + + + maven-failsafe-plugin + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-source + generate-sources + + add-source + + + + ${project.build.directory}/generated-sources/annotations/ + + + + + + + io.fabric8 + docker-maven-plugin + ${docker-maven-plugin} + false + + + generate-policy-agent-image + package + + build + + + ${env.CONTAINER_PULL_REGISTRY} + + + o-ran-sc/nonrtric-policy-agent:${project.version} + + try + ${basedir} + Dockerfile + + ${project.build.finalName}.jar + + + ${project.version} + + + + + + + + push-policy-agent-image + + build + push + + + ${env.CONTAINER_PULL_REGISTRY} + ${env.CONTAINER_PUSH_REGISTRY} + + + o-ran-sc/nonrtric-policy-agent:${project.version} + + ${basedir} + Dockerfile + + ${project.build.finalName}.jar + + + ${project.version} + + + + + + + + + + + + JIRA + https://jira.o-ran-sc.org/ + diff --git a/policy-agent/src/main/java/org/oransc/policyagent/SwaggerConfig.java b/policy-agent/src/main/java/org/oransc/policyagent/SwaggerConfig.java index f3b4a5a4..df5e7b4f 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/SwaggerConfig.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/SwaggerConfig.java @@ -20,11 +20,17 @@ package org.oransc.policyagent; +import com.google.common.base.Predicates; + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; +import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @@ -37,12 +43,48 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2; */ @Configuration @EnableSwagger2 -public class SwaggerConfig { +public class SwaggerConfig extends WebMvcConfigurationSupport { + + static final String API_TITLE = "Policy server"; + static final String DESCRIPTION = "This page lists all the rest apis for Policy server."; + static final String VERSION = "1.0"; + static final String RESOURCES_PATH = "classpath:/META-INF/resources/"; + static final String WEBJARS_PATH = RESOURCES_PATH + "webjars/"; + static final String SWAGGER_UI = "swagger-ui.html"; + static final String WEBJARS = "/webjars/**"; + + /** + * Gets the API info. + * + * @return the API info. + */ @Bean public Docket api() { - return new Docket(DocumentationType.SWAGGER_2).select() // - .apis(RequestHandlerSelectors.basePackage("org.oransc.policyagent.controllers")) // + return new Docket(DocumentationType.SWAGGER_2) // + .apiInfo(apiInfo()) // + .select() // + .apis(RequestHandlerSelectors.any()) // .paths(PathSelectors.any()) // + .paths(Predicates.not(PathSelectors.regex("/error"))) // + // this endpoint is not implemented, but was visible for Swagger + .build(); + } + + private static ApiInfo apiInfo() { + return new ApiInfoBuilder() // + .title(API_TITLE) // + .description(DESCRIPTION) // + .version(VERSION) // .build(); } + + @Override + protected void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler(SWAGGER_UI) // + .addResourceLocations(RESOURCES_PATH); + + registry.addResourceHandler(WEBJARS) // + .addResourceLocations(WEBJARS_PATH); + } + } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/A1Client.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/A1Client.java index 0a2bc8ed..0b181048 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/clients/A1Client.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/clients/A1Client.java @@ -47,4 +47,6 @@ public interface A1Client { public Flux deleteAllPolicies(); + public Mono getPolicyStatus(Policy policy); + } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/OscA1Client.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/OscA1Client.java index dd77504d..5c18103d 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/clients/OscA1Client.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/clients/OscA1Client.java @@ -130,4 +130,11 @@ public class OscA1Client implements A1Client { return Mono.error(ex); } } + + @Override + public Mono getPolicyStatus(Policy policy) { + // /a1-p/policytypes/{policy_type_id}/policies/{policy_instance_id}/status + return restClient.get("/policytypes/" + policy.type().name() + "/policies/" + policy.id() + "/status"); + + } } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOscA1Client.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOscA1Client.java index 2f8fab48..ff6e8573 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOscA1Client.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOscA1Client.java @@ -200,4 +200,9 @@ public class SdncOscA1Client implements A1Client { return Mono.error(ex); } } + + @Override + public Mono getPolicyStatus(Policy policy) { + return Mono.error(new Exception("Status not implemented in the SDNC controller")); + } } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/SdnrOnapA1Client.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/SdnrOnapA1Client.java index 1993be76..248c2189 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/clients/SdnrOnapA1Client.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/clients/SdnrOnapA1Client.java @@ -205,4 +205,9 @@ public class SdnrOnapA1Client implements A1Client { return Mono.error(ex); } } + + @Override + public Mono getPolicyStatus(Policy policy) { + return Mono.error(new Exception("Status not implemented in the controller")); + } } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/StdA1Client.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/StdA1Client.java index 1c40308a..702658e8 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/clients/StdA1Client.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/clients/StdA1Client.java @@ -130,4 +130,9 @@ public class StdA1Client implements A1Client { } } + @Override + public Mono getPolicyStatus(Policy policy) { + return restClient.get("/policies/" + policy.id() + "/status"); + } + } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfig.java b/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfig.java index 1e8c6d47..a48e5918 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfig.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfig.java @@ -134,8 +134,12 @@ public class ApplicationConfig { public void setConfiguration(@NotNull Collection ricConfigs, Properties dmaapPublisherConfig, Properties dmaapConsumerConfig) { + Collection notifications = new Vector<>(); synchronized (this) { + this.dmaapPublisherConfig = dmaapPublisherConfig; + this.dmaapConsumerConfig = dmaapConsumerConfig; + Map newRicConfigs = new HashMap<>(); for (RicConfig newConfig : ricConfigs) { RicConfig oldConfig = this.ricConfigs.get(newConfig.name()); @@ -156,10 +160,8 @@ public class ApplicationConfig { } this.ricConfigs = newRicConfigs; } - notifyObservers(notifications); - this.dmaapPublisherConfig = dmaapPublisherConfig; - this.dmaapConsumerConfig = dmaapConsumerConfig; + notifyObservers(notifications); } private void notifyObservers(Collection notifications) { diff --git a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigParser.java b/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigParser.java index 1ffe9c8e..c21af839 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigParser.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigParser.java @@ -25,14 +25,18 @@ import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; + import java.net.MalformedURLException; import java.net.URL; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import java.util.Vector; + import javax.validation.constraints.NotNull; + import lombok.Getter; + import org.onap.dmaap.mr.test.clients.ProtocolTypeConstants; import org.oransc.policyagent.exceptions.ServiceException; import org.springframework.http.MediaType; @@ -48,25 +52,24 @@ public class ApplicationConfigParser { @Getter private Vector ricConfigs; @Getter - private Properties dmaapPublisherConfig; + private Properties dmaapPublisherConfig = new Properties(); @Getter - private Properties dmaapConsumerConfig; + private Properties dmaapConsumerConfig = new Properties(); public void parse(JsonObject root) throws ServiceException { JsonObject agentConfigJson = root.getAsJsonObject(CONFIG); ricConfigs = parseRics(agentConfigJson); - JsonObject dmaapPublisherConfigJson = agentConfigJson.getAsJsonObject("streams_publishes"); - if (dmaapPublisherConfigJson == null) { - dmaapPublisherConfig = new Properties(); - } else { - dmaapPublisherConfig = parseDmaapConfig(dmaapPublisherConfigJson); + + JsonObject json = agentConfigJson.getAsJsonObject("streams_publishes"); + if (json != null) { + this.dmaapPublisherConfig = parseDmaapConfig(json); } - JsonObject dmaapConsumerConfigJson = agentConfigJson.getAsJsonObject("streams_subscribes"); - if (dmaapConsumerConfigJson == null) { - dmaapConsumerConfig = new Properties(); - } else { - dmaapConsumerConfig = parseDmaapConfig(dmaapConsumerConfigJson); + + json = agentConfigJson.getAsJsonObject("streams_subscribes"); + if (json != null) { + this.dmaapConsumerConfig = parseDmaapConfig(json); } + } private Vector parseRics(JsonObject config) throws ServiceException { @@ -99,8 +102,8 @@ public class ApplicationConfigParser { JsonObject dmaapInfo = get(streamConfigEntry, "dmaap_info").getAsJsonObject(); String topicUrl = getAsString(dmaapInfo, "topic_url"); - Properties dmaapProps = new Properties(); try { + Properties dmaapProps = new Properties(); URL url = new URL(topicUrl); String passwd = ""; String userName = ""; @@ -127,11 +130,11 @@ public class ApplicationConfigParser { dmaapProps.put("maxAgeMs", "10000"); dmaapProps.put("compress", true); dmaapProps.put("MessageSentThreadOccurance", "2"); + return dmaapProps; } catch (MalformedURLException e) { throw new ServiceException("Could not parse the URL", e); } - return dmaapProps; } private static @NotNull String getAsString(JsonObject obj, String memberName) throws ServiceException { diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyController.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyController.java index 12deb819..e0971c50 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyController.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyController.java @@ -108,7 +108,7 @@ public class PolicyController { } @GetMapping("/policy_types") - @ApiOperation(value = "Returns policy types") + @ApiOperation(value = "Query policy type names") @ApiResponses( value = {@ApiResponse( code = 200, @@ -138,7 +138,6 @@ public class PolicyController { @ApiResponse(code = 200, message = "Policy found", response = Object.class), // @ApiResponse(code = 204, message = "Policy is not found")} // ) - public ResponseEntity getPolicy( // @RequestParam(name = "instance", required = true) String instance) { try { @@ -150,7 +149,7 @@ public class PolicyController { } @DeleteMapping("/policy") - @ApiOperation(value = "Deletes the policy", response = Object.class) + @ApiOperation(value = "Delete a policy", response = Object.class) @ApiResponses(value = {@ApiResponse(code = 204, message = "Policy deleted", response = Object.class)}) public Mono> deletePolicy( // @RequestParam(name = "instance", required = true) String id) { @@ -201,7 +200,7 @@ public class PolicyController { } @GetMapping("/policies") - @ApiOperation(value = "Returns the policies") + @ApiOperation(value = "Query policies") @ApiResponses( value = { @ApiResponse(code = 200, message = "Policies", response = PolicyInfo.class, responseContainer = "List")}) @@ -230,6 +229,26 @@ public class PolicyController { } } + @GetMapping("/policy_status") + @ApiOperation(value = "Returns a policy status") // + @ApiResponses( + value = { // + @ApiResponse(code = 200, message = "Policy status", response = Object.class), // + @ApiResponse(code = 204, message = "Policy is not found", response = String.class)} // + ) + public Mono> getPolicyStatus( // + @RequestParam(name = "instance", required = true) String instance) { + try { + Policy policy = policies.getPolicy(instance); + + return a1ClientFactory.createA1Client(policy.ric()) // + .flatMap(client -> client.getPolicyStatus(policy)) // + .flatMap(status -> Mono.just(new ResponseEntity(status, HttpStatus.OK))); + } catch (ServiceException e) { + return Mono.just(new ResponseEntity(e.getMessage(), HttpStatus.NO_CONTENT)); + } + } + private boolean include(String filter, String value) { return filter == null || value.equals(filter); } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicRepositoryController.java b/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicRepositoryController.java index a5667816..bb3b735f 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicRepositoryController.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/controllers/RicRepositoryController.java @@ -83,7 +83,7 @@ public class RicRepositoryController { * Example: http://localhost:8080/ric */ @GetMapping("/rics") - @ApiOperation(value = "Returns NearRT RIC information") + @ApiOperation(value = "Query NearRT RIC information") @ApiResponses( value = { // @ApiResponse(code = 200, message = "OK", response = RicInfo.class, responseContainer = "List") // diff --git a/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapMessageConsumerImpl.java b/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapMessageConsumerImpl.java index db4956ab..4a2605b6 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapMessageConsumerImpl.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapMessageConsumerImpl.java @@ -21,32 +21,35 @@ package org.oransc.policyagent.dmaap; import com.google.common.collect.Iterables; + +import java.io.FileNotFoundException; import java.io.IOException; +import java.time.Duration; import java.util.Properties; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + import org.onap.dmaap.mr.client.MRBatchingPublisher; import org.onap.dmaap.mr.client.MRClientFactory; import org.onap.dmaap.mr.client.MRConsumer; import org.onap.dmaap.mr.client.response.MRConsumerResponse; import org.oransc.policyagent.clients.AsyncRestClient; import org.oransc.policyagent.configuration.ApplicationConfig; +import org.oransc.policyagent.exceptions.ServiceException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component -@EnableScheduling -public class DmaapMessageConsumerImpl implements DmaapMessageConsumer { +public class DmaapMessageConsumerImpl implements Runnable { private static final Logger logger = LoggerFactory.getLogger(DmaapMessageConsumerImpl.class); - private boolean alive = false; + final Duration ERROR_TIMEOUT = Duration.ofSeconds(30); + final Duration TIME_BETWEEN_DMAAP_POLLS = Duration.ofSeconds(10); private final ApplicationConfig applicationConfig; - protected MRConsumer consumer; - private MRBatchingPublisher producer; @Value("${server.port}") private int localServerPort; @@ -54,15 +57,20 @@ public class DmaapMessageConsumerImpl implements DmaapMessageConsumer { @Autowired public DmaapMessageConsumerImpl(ApplicationConfig applicationConfig) { this.applicationConfig = applicationConfig; + + Thread thread = new Thread(this); + thread.start(); + } + + private boolean isDmaapConfigured() { + Properties consumerCfg = applicationConfig.getDmaapConsumerConfig(); + Properties producerCfg = applicationConfig.getDmaapPublisherConfig(); + return (consumerCfg != null && consumerCfg.size() > 0 && producerCfg != null && producerCfg.size() > 0); } - @Scheduled(fixedRate = 1000 * 40) @Override public void run() { - if (!alive) { - init(); - } - if (this.alive) { + while (sleep(TIME_BETWEEN_DMAAP_POLLS) && isDmaapConfigured()) { try { Iterable dmaapMsgs = fetchAllMessages(); if (dmaapMsgs != null && Iterables.size(dmaapMsgs) > 0) { @@ -73,61 +81,45 @@ public class DmaapMessageConsumerImpl implements DmaapMessageConsumer { } } catch (Exception e) { logger.error("{}: cannot fetch because of ", this, e.getMessage(), e); + sleep(ERROR_TIMEOUT); } } } - private Iterable fetchAllMessages() { - MRConsumerResponse response = null; - try { - response = consumer.fetchWithReturnConsumerResponse(); - } catch (Exception e) { - logger.error("Failed to get message from DMAAP", e); - } + private Iterable fetchAllMessages() throws ServiceException, FileNotFoundException, IOException { + Properties dmaapConsumerProperties = this.applicationConfig.getDmaapConsumerConfig(); + MRConsumer consumer = MRClientFactory.createConsumer(dmaapConsumerProperties); + MRConsumerResponse response = consumer.fetchWithReturnConsumerResponse(); if (response == null || !"200".equals(response.getResponseCode())) { - logger.warn("{}: DMaaP NULL response received", this); + throw new ServiceException("DMaaP NULL response received"); } else { logger.debug("DMaaP consumer received {} : {}", response.getResponseCode(), response.getResponseMessage()); + return response.getActualMessages(); } - return response.getActualMessages(); } - @Override - public void init() { - Properties dmaapConsumerProperties = applicationConfig.getDmaapConsumerConfig(); - Properties dmaapPublisherProperties = applicationConfig.getDmaapPublisherConfig(); - // No need to start if there is no configuration. - if (dmaapConsumerProperties == null || dmaapPublisherProperties == null || dmaapConsumerProperties.size() == 0 - || dmaapPublisherProperties.size() == 0) { - logger.error("DMaaP properties Failed to Load"); - return; - } - try { - logger.debug("Creating DMAAP Client"); - logger.debug("dmaapConsumerProperties---> {}", dmaapConsumerProperties.getProperty("topic")); - logger.debug("dmaapPublisherProperties---> {}", dmaapPublisherProperties.getProperty("topic")); - consumer = MRClientFactory.createConsumer(dmaapConsumerProperties); - producer = MRClientFactory.createBatchingPublisher(dmaapPublisherProperties); - this.alive = true; - } catch (IOException e) { - logger.error("Exception occurred while creating Dmaap Consumer", e); - } - } - - @Override - public void processMsg(String msg) throws Exception { + private void processMsg(String msg) throws Exception { logger.debug("Message Reveived from DMAAP : {}", msg); createDmaapMessageHandler().handleDmaapMsg(msg); } - protected DmaapMessageHandler createDmaapMessageHandler() { + private DmaapMessageHandler createDmaapMessageHandler() throws FileNotFoundException, IOException { String agentBaseUrl = "http://localhost:" + this.localServerPort; AsyncRestClient agentClient = new AsyncRestClient(agentBaseUrl); - return new DmaapMessageHandler(this.producer, this.applicationConfig, agentClient); + Properties dmaapPublisherProperties = applicationConfig.getDmaapPublisherConfig(); + MRBatchingPublisher producer = MRClientFactory.createBatchingPublisher(dmaapPublisherProperties); + + return new DmaapMessageHandler(producer, this.applicationConfig, agentClient); } - @Override - public boolean isAlive() { - return alive; + private boolean sleep(Duration duration) { + CountDownLatch sleep = new CountDownLatch(1); + try { + sleep.await(duration.toMillis(), TimeUnit.MILLISECONDS); + return true; + } catch (Exception e) { + logger.error("msg", e); + return false; + } } } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapMessageHandler.java b/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapMessageHandler.java index 2d963c35..9b0c809c 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapMessageHandler.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/dmaap/DmaapMessageHandler.java @@ -22,7 +22,9 @@ package org.oransc.policyagent.dmaap; import com.google.gson.Gson; import com.google.gson.GsonBuilder; + import java.io.IOException; + import org.onap.dmaap.mr.client.MRBatchingPublisher; import org.oransc.policyagent.clients.AsyncRestClient; import org.oransc.policyagent.configuration.ApplicationConfig; @@ -37,27 +39,23 @@ public class DmaapMessageHandler { private static final Logger logger = LoggerFactory.getLogger(DmaapMessageHandler.class); private static Gson gson = new GsonBuilder() // - .serializeNulls() // - .create(); // + .serializeNulls() // + .create(); // private final MRBatchingPublisher dmaapClient; private final AsyncRestClient agentClient; public DmaapMessageHandler(MRBatchingPublisher dmaapClient, ApplicationConfig applicationConfig, - AsyncRestClient agentClient) { + AsyncRestClient agentClient) { this.agentClient = agentClient; this.dmaapClient = dmaapClient; } public void handleDmaapMsg(String msg) { - try { - this.createTask(msg) // - .subscribe(x -> logger.debug("handleDmaapMsg: " + x), // - throwable -> logger.warn("handleDmaapMsg failure ", throwable), // - () -> logger.debug("handleDmaapMsg complete")); - } catch (Exception e) { - logger.warn("Received unparsable message from DMAAP: {}", msg); - } + this.createTask(msg) // + .subscribe(x -> logger.debug("handleDmaapMsg: " + x), // + throwable -> logger.warn("handleDmaapMsg failure ", throwable), // + () -> logger.debug("handleDmaapMsg complete")); } Mono createTask(String msg) { @@ -65,8 +63,8 @@ public class DmaapMessageHandler { DmaapRequestMessage dmaapRequestMessage = gson.fromJson(msg, ImmutableDmaapRequestMessage.class); return this.invokePolicyAgent(dmaapRequestMessage) // - .onErrorResume(t -> handleAgentCallError(t, dmaapRequestMessage)) // - .flatMap(response -> sendDmaapResponse(response, dmaapRequestMessage, HttpStatus.OK)); + .onErrorResume(t -> handleAgentCallError(t, dmaapRequestMessage)) // + .flatMap(response -> sendDmaapResponse(response, dmaapRequestMessage, HttpStatus.OK)); } catch (Exception e) { logger.warn("Received unparsable message from DMAAP: {}", msg); @@ -77,7 +75,7 @@ public class DmaapMessageHandler { private Mono handleAgentCallError(Throwable t, DmaapRequestMessage dmaapRequestMessage) { logger.debug("Agent call failed: " + t.getMessage()); return sendDmaapResponse(t.toString(), dmaapRequestMessage, HttpStatus.NOT_FOUND) // - .flatMap(s -> Mono.empty()); + .flatMap(s -> Mono.empty()); } private Mono invokePolicyAgent(DmaapRequestMessage dmaapRequestMessage) { @@ -99,10 +97,10 @@ public class DmaapMessageHandler { } private Mono sendDmaapResponse(String response, DmaapRequestMessage dmaapRequestMessage, - HttpStatus status) { + HttpStatus status) { return getDmaapResponseMessage(dmaapRequestMessage, response, status) // - .flatMap(body -> sendToDmaap(body)) // - .onErrorResume(t -> handleResponseCallError(t, dmaapRequestMessage)); + .flatMap(body -> sendToDmaap(body)) // + .onErrorResume(t -> handleResponseCallError(t, dmaapRequestMessage)); } private Mono sendToDmaap(String body) { @@ -122,16 +120,16 @@ public class DmaapMessageHandler { } private Mono getDmaapResponseMessage(DmaapRequestMessage dmaapRequestMessage, String response, - HttpStatus status) { + HttpStatus status) { DmaapResponseMessage dmaapResponseMessage = ImmutableDmaapResponseMessage.builder() // - .status(status.toString()) // - .message(response) // - .type("response") // - .correlationId(dmaapRequestMessage.correlationId()) // - .originatorId(dmaapRequestMessage.originatorId()) // - .requestId(dmaapRequestMessage.requestId()) // - .timestamp(dmaapRequestMessage.timestamp()) // - .build(); + .status(status.toString()) // + .message(response) // + .type("response") // + .correlationId(dmaapRequestMessage.correlationId()) // + .originatorId(dmaapRequestMessage.originatorId()) // + .requestId(dmaapRequestMessage.requestId()) // + .timestamp(dmaapRequestMessage.timestamp()) // + .build(); String str = gson.toJson(dmaapResponseMessage); return Mono.just(str); diff --git a/policy-agent/src/main/java/org/oransc/policyagent/repository/Ric.java b/policy-agent/src/main/java/org/oransc/policyagent/repository/Ric.java index 220477f0..e50a98ce 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/repository/Ric.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/repository/Ric.java @@ -36,8 +36,7 @@ import org.oransc.policyagent.configuration.RicConfig; */ public class Ric { private final RicConfig ricConfig; - @Getter - @Setter + private RicState state = RicState.UNDEFINED; private Map supportedPolicyTypes = new HashMap<>(); @Getter @@ -61,13 +60,21 @@ public class Ric { return this.ricConfig; } + public synchronized RicState getState() { + return this.state; + } + + public synchronized void setState(RicState state) { + this.state = state; + } + /** * Gets the nodes managed by this Ric. * * @return a vector containing the nodes managed by this Ric. */ - public Vector getManagedElementIds() { - return ricConfig.managedElementIds(); + public synchronized Collection getManagedElementIds() { + return new Vector<>(ricConfig.managedElementIds()); } /** @@ -76,7 +83,7 @@ public class Ric { * @param managedElementId the node name to check. * @return true if the given node is managed by this Ric. */ - public boolean isManaging(String managedElementId) { + public synchronized boolean isManaging(String managedElementId) { return ricConfig.managedElementIds().contains(managedElementId); } @@ -85,7 +92,7 @@ public class Ric { * * @param managedElementId the node to add. */ - public void addManagedElement(String managedElementId) { + public synchronized void addManagedElement(String managedElementId) { if (!ricConfig.managedElementIds().contains(managedElementId)) { ricConfig.managedElementIds().add(managedElementId); } @@ -96,7 +103,7 @@ public class Ric { * * @param managedElementId the node to remove. */ - public void removeManagedElement(String managedElementId) { + public synchronized void removeManagedElement(String managedElementId) { ricConfig.managedElementIds().remove(managedElementId); } @@ -105,12 +112,12 @@ public class Ric { * * @return the policy types supported by this Ric in an unmodifiable list. */ - public Collection getSupportedPolicyTypes() { - return supportedPolicyTypes.values(); + public synchronized Collection getSupportedPolicyTypes() { + return new Vector<>(supportedPolicyTypes.values()); } - public Collection getSupportedPolicyTypeNames() { - return supportedPolicyTypes.keySet(); + public synchronized Collection getSupportedPolicyTypeNames() { + return new Vector<>(supportedPolicyTypes.keySet()); } /** @@ -118,14 +125,14 @@ public class Ric { * * @param type the policy type to support. */ - public void addSupportedPolicyType(PolicyType type) { + public synchronized void addSupportedPolicyType(PolicyType type) { supportedPolicyTypes.put(type.name(), type); } /** * Removes all policy type as supported by this Ric. */ - public void clearSupportedPolicyTypes() { + public synchronized void clearSupportedPolicyTypes() { supportedPolicyTypes.clear(); } @@ -136,12 +143,12 @@ public class Ric { * * @return true if the given type is supported by this Ric, false otherwise. */ - public boolean isSupportingType(String typeName) { + public synchronized boolean isSupportingType(String typeName) { return supportedPolicyTypes.containsKey(typeName); } @Override - public String toString() { + public synchronized String toString() { return Ric.class.getSimpleName() + ": " + "name: " + name() + ", state: " + state + ", baseUrl: " + ricConfig.baseUrl() + ", managedNodes: " + ricConfig.managedElementIds(); } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/tasks/RefreshConfigTask.java b/policy-agent/src/main/java/org/oransc/policyagent/tasks/RefreshConfigTask.java index 267fc1f1..f5834e35 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/tasks/RefreshConfigTask.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/tasks/RefreshConfigTask.java @@ -81,9 +81,9 @@ public class RefreshConfigTask { stop(); loadConfigurationFromFile(); refreshTask = createRefreshTask() // - .subscribe(notUsed -> logger.info("Refreshed configuration data"), + .subscribe(notUsed -> logger.debug("Refreshed configuration data"), throwable -> logger.error("Configuration refresh terminated due to exception", throwable), - () -> logger.error("Configuration refresh terminated")); + () -> logger.debug("Configuration refresh completed")); } public void stop() { diff --git a/policy-agent/src/main/java/org/oransc/policyagent/tasks/RicRecoveryTask.java b/policy-agent/src/main/java/org/oransc/policyagent/tasks/RicRecoveryTask.java index ab25eab4..c88eb6c9 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/tasks/RicRecoveryTask.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/tasks/RicRecoveryTask.java @@ -70,7 +70,8 @@ public class RicRecoveryTask { synchronized (ric) { if (ric.getState() == Ric.RicState.RECOVERING) { - return; // Already running + logger.debug("Recovery ric: {} is already running", ric.getConfig().name()); + return; } ric.setState(Ric.RicState.RECOVERING); } diff --git a/policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java b/policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java index 847cde19..aeeb19af 100644 --- a/policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java +++ b/policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java @@ -195,6 +195,7 @@ public class ApplicationTest { Policy policy = addPolicy("policyId", "typeName", "service", "ric"); // This should be created in the RIC supervision.checkAllRics(); // The created policy should be put in the RIC + await().untilAsserted(() -> RicState.RECOVERING.equals(rics.getRic("ric").getState())); await().untilAsserted(() -> RicState.IDLE.equals(rics.getRic("ric").getState())); Policies ricPolicies = getA1Client("ric").getPolicies(); @@ -464,6 +465,18 @@ public class ApplicationTest { assertThat(entity.getStatusCode().equals(HttpStatus.NOT_FOUND)); } + @Test + public void testGetPolicyStatus() throws Exception { + reset(); + Policy policy = addPolicy("id", "typeName", "service1", "ric1"); + policy.ric().setState(Ric.RicState.IDLE); + assertThat(policies.size()).isEqualTo(1); + + String url = baseUrl() + "/policy_status?instance=id"; + String rsp = this.restTemplate.getForObject(url, String.class); + assertThat(rsp.equals("OK")); + } + private static List parseList(String jsonString, Class clazz) { List result = new ArrayList<>(); JsonArray jsonArr = JsonParser.parseString(jsonString).getAsJsonArray(); diff --git a/policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigParserTest.java b/policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigParserTest.java index 3444540b..531f1e8e 100644 --- a/policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigParserTest.java +++ b/policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigParserTest.java @@ -22,12 +22,14 @@ package org.oransc.policyagent.configuration; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; + import com.google.common.base.Charsets; import com.google.common.io.Resources; import com.google.gson.JsonIOException; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonSyntaxException; + import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; @@ -35,6 +37,7 @@ import java.io.InputStreamReader; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Properties; + import org.junit.jupiter.api.Test; import org.onap.dmaap.mr.test.clients.ProtocolTypeConstants; import org.springframework.http.MediaType; diff --git a/policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigTest.java b/policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigTest.java index 257776db..c6546206 100644 --- a/policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigTest.java +++ b/policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigTest.java @@ -123,4 +123,5 @@ public class ApplicationConfigTest { assertEquals("Could not find ric: name", exception.getMessage()); } + } diff --git a/policy-agent/src/test/java/org/oransc/policyagent/dmaap/DmaapMessageHandlerTest.java b/policy-agent/src/test/java/org/oransc/policyagent/dmaap/DmaapMessageHandlerTest.java index 5aeb2404..71c85003 100644 --- a/policy-agent/src/test/java/org/oransc/policyagent/dmaap/DmaapMessageHandlerTest.java +++ b/policy-agent/src/test/java/org/oransc/policyagent/dmaap/DmaapMessageHandlerTest.java @@ -27,9 +27,12 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; + import com.google.gson.Gson; import com.google.gson.GsonBuilder; + import java.io.IOException; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.onap.dmaap.mr.client.MRBatchingPublisher; @@ -37,6 +40,7 @@ import org.onap.dmaap.mr.client.response.MRPublisherResponse; import org.oransc.policyagent.clients.AsyncRestClient; import org.oransc.policyagent.configuration.ApplicationConfig; import org.oransc.policyagent.dmaap.DmaapRequestMessage.Operation; + import reactor.core.publisher.Mono; import reactor.test.StepVerifier; diff --git a/policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1Client.java b/policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1Client.java index 1151dd20..f10c66ff 100644 --- a/policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1Client.java +++ b/policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1Client.java @@ -99,4 +99,9 @@ public class MockA1Client implements A1Client { return Flux.empty(); } + @Override + public Mono getPolicyStatus(Policy policy) { + return Mono.just("OK"); + } + } -- 2.16.6