From 721a0c1f9728a06c78edd75ba898bc67c4b82446 Mon Sep 17 00:00:00 2001 From: PatrikBuhr Date: Fri, 11 Feb 2022 15:58:16 +0100 Subject: [PATCH] NONRTRIC - 3PP dependency version update Updated generation of swagger documentation due to new swagger version. Made all parameters into constants. Renamed a parameter so it has the same name as elsewhere: /info-producers?info_type_id=xx -> /info-producers?infoTypeId=xx Signed-off-by: PatrikBuhr Issue-ID: NONRTRIC-721 Change-Id: I7d6feaa368e77a3b935ae098eb40bf56771cef58 --- information-coordinator-service/api/ics-api.json | 143 +++++++-------- information-coordinator-service/api/ics-api.yaml | 203 ++++++++++----------- .../main/java/org/oransc/ics/SwaggerConfig.java | 17 +- .../oransc/ics/controllers/StatusController.java | 2 +- .../oransc/ics/controllers/a1e/A1eController.java | 2 +- .../ics/controllers/r1consumer/ConsumerConsts.java | 5 + .../controllers/r1consumer/ConsumerController.java | 18 +- .../ics/controllers/r1producer/ProducerConsts.java | 7 + .../controllers/r1producer/ProducerController.java | 21 ++- .../test/java/org/oransc/ics/ApplicationTest.java | 55 +++--- .../A1eCallbacksSimulatorController.java | 94 ++++++++++ .../controller/ConsumerSimulatorController.java | 36 +--- .../controller/ProducerSimulatorController.java | 15 +- 13 files changed, 338 insertions(+), 280 deletions(-) create mode 100644 information-coordinator-service/src/test/java/org/oransc/ics/controller/A1eCallbacksSimulatorController.java diff --git a/information-coordinator-service/api/ics-api.json b/information-coordinator-service/api/ics-api.json index 69ad473b..082d42f5 100644 --- a/information-coordinator-service/api/ics-api.json +++ b/information-coordinator-service/api/ics-api.json @@ -327,22 +327,6 @@ }}, "openapi": "3.0.1", "paths": { - "/example_dataproducer/info_job/{infoJobId}": {"delete": { - "summary": "Callback for Information Job deletion", - "description": "The call is invoked to terminate a data subscription. The endpoint is provided by the Information Producer.", - "operationId": "jobDeletedCallback", - "responses": {"200": { - "description": "OK", - "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Void"}}} - }}, - "parameters": [{ - "schema": {"type": "string"}, - "in": "path", - "name": "infoJobId", - "required": true - }], - "tags": ["Data producer (callbacks)"] - }}, "/data-producer/v1/info-types": {"get": { "summary": "Info Type identifiers", "operationId": "getInfoTypdentifiers", @@ -385,20 +369,6 @@ }}, "tags": ["Actuator"] }}, - "/example_dataproducer/info_job": {"post": { - "summary": "Callback for Information Job creation/modification", - "requestBody": { - "content": {"application/json": {"schema": {"$ref": "#/components/schemas/producer_info_job_request"}}}, - "required": true - }, - "description": "The call is invoked to activate or to modify a data subscription. The endpoint is provided by the Information Producer.", - "operationId": "jobCreatedCallback", - "responses": {"200": { - "description": "OK", - "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Void"}}} - }}, - "tags": ["Data producer (callbacks)"] - }}, "/data-producer/v1/info-types/{infoTypeId}": { "get": { "summary": "Individual Information Type", @@ -554,6 +524,16 @@ "tags": ["Data consumer"] } }, + "/example-dataproducer/health-check": {"get": { + "summary": "Producer supervision", + "description": "The endpoint is provided by the Information Producer and is used for supervision of the producer.", + "operationId": "producerSupervision", + "responses": {"200": { + "description": "The producer is OK", + "content": {"application/json": {"schema": {"type": "string"}}} + }}, + "tags": ["Data producer (callbacks)"] + }}, "/actuator/loggers": {"get": { "summary": "Actuator web endpoint 'loggers'", "operationId": "loggers_2", @@ -584,6 +564,20 @@ }}, "tags": ["Data consumer"] }}, + "/example-dataconsumer/info-type-status": {"post": { + "summary": "Callback for changed Information type registration status", + "requestBody": { + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/consumer_type_registration_info"}}}, + "required": true + }, + "description": "The primitive is implemented by the data consumer and is invoked when a Information type status has been changed.
Subscription are managed by primitives in 'Data consumer'", + "operationId": "typeStatusCallback", + "responses": {"200": { + "description": "OK", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Void"}}} + }}, + "tags": ["Data consumer (callbacks)"] + }}, "/actuator/metrics/{requiredMetricName}": {"get": { "summary": "Actuator web endpoint 'metrics-requiredMetricName'", "operationId": "metrics-requiredMetricName_2", @@ -681,14 +675,24 @@ "tags": ["Actuator"] } }, - "/example_dataconsumer/info_jobs/{infoJobId}/status": {"post": { - "summary": "Callback for changed Information Job status", + "/example-dataproducer/info-job": {"post": { + "summary": "Callback for Information Job creation/modification", "requestBody": { - "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EiJobStatusObject"}}}, + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/producer_info_job_request"}}}, "required": true }, - "description": "The primitive is implemented by the data consumer and is invoked when a Information Job status has been changed.", - "operationId": "jobStatusCallback", + "description": "The call is invoked to activate or to modify a data subscription. The endpoint is provided by the Information Producer.", + "operationId": "jobCreatedCallback", + "responses": {"200": { + "description": "OK", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Void"}}} + }}, + "tags": ["Data producer (callbacks)"] + }}, + "/example-dataproducer/info-job/{infoJobId}": {"delete": { + "summary": "Callback for Information Job deletion", + "description": "The call is invoked to terminate a data subscription. The endpoint is provided by the Information Producer.", + "operationId": "jobDeletedCallback", "responses": {"200": { "description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Void"}}} @@ -699,7 +703,7 @@ "name": "infoJobId", "required": true }], - "tags": ["A1-EI (callbacks)"] + "tags": ["Data producer (callbacks)"] }}, "/A1-EI/v1/eijobs/{eiJobId}/status": {"get": { "summary": "EI job status", @@ -773,6 +777,26 @@ }}, "tags": ["Actuator"] }}, + "/example-dataconsumer/info-jobs/{infoJobId}/status": {"post": { + "summary": "Callback for changed Information Job status", + "requestBody": { + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EiJobStatusObject"}}}, + "required": true + }, + "description": "The primitive is implemented by the data consumer and is invoked when a Information Job status has been changed.", + "operationId": "jobStatusCallback", + "responses": {"200": { + "description": "OK", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Void"}}} + }}, + "parameters": [{ + "schema": {"type": "string"}, + "in": "path", + "name": "infoJobId", + "required": true + }], + "tags": ["A1-EI (callbacks)"] + }}, "/actuator/info": {"get": { "summary": "Actuator web endpoint 'info'", "operationId": "info_2", @@ -782,16 +806,6 @@ }}, "tags": ["Actuator"] }}, - "/example_dataproducer/health_check": {"get": { - "summary": "Producer supervision", - "description": "The endpoint is provided by the Information Producer and is used for supervision of the producer.", - "operationId": "producerSupervision", - "responses": {"200": { - "description": "The producer is OK", - "content": {"application/json": {"schema": {"type": "string"}}} - }}, - "tags": ["Data producer (callbacks)"] - }}, "/A1-EI/v1/eitypes": {"get": { "summary": "EI type identifiers", "operationId": "getEiTypeIdentifiers", @@ -1119,7 +1133,7 @@ "parameters": [{ "schema": {"type": "string"}, "in": "query", - "name": "info_type_id", + "name": "infoTypeId", "description": "If given, only the producers for the EI Data type is returned.", "required": false }], @@ -1215,20 +1229,6 @@ }], "tags": ["Data producer (registration)"] }}, - "/example_dataconsumer/info_type_status": {"post": { - "summary": "Callback for changed Information type registration status", - "requestBody": { - "content": {"application/json": {"schema": {"$ref": "#/components/schemas/consumer_type_registration_info"}}}, - "required": true - }, - "description": "The primitive is implemented by the data consumer and is invoked when a Information type status has been changed.
Subscription are managed by primitives in 'Data consumer'", - "operationId": "typeStatusCallback", - "responses": {"200": { - "description": "OK", - "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Void"}}} - }}, - "tags": ["Data consumer (callbacks)"] - }}, "/actuator/heapdump": {"get": { "summary": "Actuator web endpoint 'heapdump'", "operationId": "heapdump_2", @@ -1241,7 +1241,7 @@ }, "info": { "license": { - "name": "Copyright (C) 2020 Nordix Foundation. Licensed under the Apache License.", + "name": "Copyright (C) 2020-2022 Nordix Foundation. Licensed under the Apache License.", "url": "http://www.apache.org/licenses/LICENSE-2.0" }, "description": "

API documentation<\/h1>

General<\/h2>

The service is mainly a broker between data producers and data consumers. A data producer has the ability to produce one or several types of data (Information Type). One type of data can be produced by zero to many producers.

A data consumer can have several active data subscriptions (Information Job). One Information Job consists of the type of data to produce and additional parameters for filtering of the data. These parameters are different for different data types.<\/p>

APIs provided by the service<\/h2>

A1-EI<\/h4>

This API is between Near-RT RIC and the Non-RT RIC. The Near-RT RIC is a data consumer, which creates Information Jobs to subscribe for data. In this context, the information is referred to as 'Enrichment Information', EI.<\/p>

Data producer API<\/h4>

This API is provided by the Non-RT RIC platform and is intended to be part of the O-RAN R1 interface. The API is for use by different kinds of data producers and provides support for:

  • Registry of supported information types and which parameters needed to setup a subscription.<\/li>
  • Registry of existing data producers.<\/li>
  • Callback API provided by producers to setup subscriptions.<\/li><\/ul><\/p>

    Data consumer API<\/h4>

    This API is provided by the Non-RT RIC platform and is intended to be part of the O-RAN R1 interface. The API is for use by different kinds of data consumers and provides support for:

    • Querying of available types of data to consume.<\/li>
    • Management of data subscription jobs<\/li>
    • Optional callback API provided by consumers to get notification on added and removed information types.<\/li><\/ul><\/p>

      Service status<\/h4>

      This API provides a means to monitor the health of this service.<\/p>", @@ -1249,13 +1249,6 @@ "version": "1.0" }, "tags": [ - {"name": "A1-EI (callbacks)"}, - { - "name": "Data producer (callbacks)", - "description": "API implemented by data producers" - }, - {"name": "Data consumer"}, - {"name": "Data consumer (callbacks)"}, { "name": "A1-EI (registration)", "description": "Data consumer EI job registration" @@ -1264,14 +1257,18 @@ "name": "A1-EI (callbacks)", "description": "Data consumer EI job status callbacks" }, - {"name": "Service status"}, - {"name": "A1-EI (registration)"}, - {"name": "Data producer (registration)"}, - {"name": "Data producer (callbacks)"}, + { + "name": "Data consumer (callbacks)", + "description": "API for data consumers" + }, { "name": "Data producer (registration)", "description": "API for data producers" }, + { + "name": "Data producer (callbacks)", + "description": "API implemented by data producers" + }, { "name": "Data consumer", "description": "API for data consumers" diff --git a/information-coordinator-service/api/ics-api.yaml b/information-coordinator-service/api/ics-api.yaml index dafb0ffd..2d121934 100644 --- a/information-coordinator-service/api/ics-api.yaml +++ b/information-coordinator-service/api/ics-api.yaml @@ -24,27 +24,22 @@ info: added and removed information types.

    Service status

    This API provides a means to monitor the health of this service.

    license: - name: Copyright (C) 2020 Nordix Foundation. Licensed under the Apache License. + name: Copyright (C) 2020-2022 Nordix Foundation. Licensed under the Apache License. url: http://www.apache.org/licenses/LICENSE-2.0 version: "1.0" servers: - url: / tags: -- name: A1-EI (callbacks) -- name: Data producer (callbacks) - description: API implemented by data producers -- name: Data consumer -- name: Data consumer (callbacks) - name: A1-EI (registration) description: Data consumer EI job registration - name: A1-EI (callbacks) description: Data consumer EI job status callbacks -- name: Service status -- name: A1-EI (registration) -- name: Data producer (registration) -- name: Data producer (callbacks) +- name: Data consumer (callbacks) + description: API for data consumers - name: Data producer (registration) description: API for data producers +- name: Data producer (callbacks) + description: API implemented by data producers - name: Data consumer description: API for data consumers - name: Service status @@ -55,29 +50,6 @@ tags: description: Spring Boot Actuator Web API Documentation url: https://docs.spring.io/spring-boot/docs/current/actuator-api/html/ paths: - /example_dataproducer/info_job/{infoJobId}: - delete: - tags: - - Data producer (callbacks) - summary: Callback for Information Job deletion - description: The call is invoked to terminate a data subscription. The endpoint - is provided by the Information Producer. - operationId: jobDeletedCallback - parameters: - - name: infoJobId - in: path - required: true - style: simple - explode: false - schema: - type: string - responses: - 200: - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/Void' /data-producer/v1/info-types: get: tags: @@ -133,27 +105,6 @@ paths: '*/*': schema: type: object - /example_dataproducer/info_job: - post: - tags: - - Data producer (callbacks) - summary: Callback for Information Job creation/modification - description: The call is invoked to activate or to modify a data subscription. - The endpoint is provided by the Information Producer. - operationId: jobCreatedCallback - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/producer_info_job_request' - required: true - responses: - 200: - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/Void' /data-producer/v1/info-types/{infoTypeId}: get: tags: @@ -350,6 +301,21 @@ paths: application/json: schema: $ref: '#/components/schemas/ProblemDetails' + /example-dataproducer/health-check: + get: + tags: + - Data producer (callbacks) + summary: Producer supervision + description: The endpoint is provided by the Information Producer and is used + for supervision of the producer. + operationId: producerSupervision + responses: + 200: + description: The producer is OK + content: + application/json: + schema: + type: string /actuator/loggers: get: tags: @@ -391,6 +357,28 @@ paths: type: array items: type: string + /example-dataconsumer/info-type-status: + post: + tags: + - Data consumer (callbacks) + summary: Callback for changed Information type registration status + description: The primitive is implemented by the data consumer and is invoked + when a Information type status has been changed.
    Subscription are managed + by primitives in 'Data consumer' + operationId: typeStatusCallback + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/consumer_type_registration_info' + required: true + responses: + 200: + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Void' /actuator/metrics/{requiredMetricName}: get: tags: @@ -509,14 +497,35 @@ paths: '*/*': schema: type: object - /example_dataconsumer/info_jobs/{infoJobId}/status: + /example-dataproducer/info-job: post: tags: - - A1-EI (callbacks) - summary: Callback for changed Information Job status - description: The primitive is implemented by the data consumer and is invoked - when a Information Job status has been changed. - operationId: jobStatusCallback + - Data producer (callbacks) + summary: Callback for Information Job creation/modification + description: The call is invoked to activate or to modify a data subscription. + The endpoint is provided by the Information Producer. + operationId: jobCreatedCallback + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/producer_info_job_request' + required: true + responses: + 200: + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Void' + /example-dataproducer/info-job/{infoJobId}: + delete: + tags: + - Data producer (callbacks) + summary: Callback for Information Job deletion + description: The call is invoked to terminate a data subscription. The endpoint + is provided by the Information Producer. + operationId: jobDeletedCallback parameters: - name: infoJobId in: path @@ -525,12 +534,6 @@ paths: explode: false schema: type: string - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/EiJobStatusObject' - required: true responses: 200: description: OK @@ -632,6 +635,35 @@ paths: '*/*': schema: type: object + /example-dataconsumer/info-jobs/{infoJobId}/status: + post: + tags: + - A1-EI (callbacks) + summary: Callback for changed Information Job status + description: The primitive is implemented by the data consumer and is invoked + when a Information Job status has been changed. + operationId: jobStatusCallback + parameters: + - name: infoJobId + in: path + required: true + style: simple + explode: false + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/EiJobStatusObject' + required: true + responses: + 200: + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Void' /actuator/info: get: tags: @@ -645,21 +677,6 @@ paths: '*/*': schema: type: object - /example_dataproducer/health_check: - get: - tags: - - Data producer (callbacks) - summary: Producer supervision - description: The endpoint is provided by the Information Producer and is used - for supervision of the producer. - operationId: producerSupervision - responses: - 200: - description: The producer is OK - content: - application/json: - schema: - type: string /A1-EI/v1/eitypes: get: tags: @@ -1065,7 +1082,7 @@ paths: summary: Information producer identifiers operationId: getInfoProducerIdentifiers parameters: - - name: info_type_id + - name: infoTypeId in: query description: If given, only the producers for the EI Data type is returned. required: false @@ -1191,28 +1208,6 @@ paths: application/json: schema: $ref: '#/components/schemas/ProblemDetails' - /example_dataconsumer/info_type_status: - post: - tags: - - Data consumer (callbacks) - summary: Callback for changed Information type registration status - description: The primitive is implemented by the data consumer and is invoked - when a Information type status has been changed.
    Subscription are managed - by primitives in 'Data consumer' - operationId: typeStatusCallback - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/consumer_type_registration_info' - required: true - responses: - 200: - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/Void' /actuator/heapdump: get: tags: diff --git a/information-coordinator-service/src/main/java/org/oransc/ics/SwaggerConfig.java b/information-coordinator-service/src/main/java/org/oransc/ics/SwaggerConfig.java index 42ffe83f..4b225642 100644 --- a/information-coordinator-service/src/main/java/org/oransc/ics/SwaggerConfig.java +++ b/information-coordinator-service/src/main/java/org/oransc/ics/SwaggerConfig.java @@ -23,12 +23,7 @@ package org.oransc.ics; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.info.Info; import io.swagger.v3.oas.annotations.info.License; -import io.swagger.v3.oas.annotations.tags.Tag; -import org.oransc.ics.controllers.StatusController; -import org.oransc.ics.controllers.a1e.A1eConsts; -import org.oransc.ics.controllers.r1consumer.ConsumerConsts; -import org.oransc.ics.controllers.r1producer.ProducerConsts; /** * Swagger configuration class that uses swagger documentation type and scans @@ -37,22 +32,12 @@ import org.oransc.ics.controllers.r1producer.ProducerConsts; */ @OpenAPIDefinition( // - tags = { // - @Tag(name = A1eConsts.CONSUMER_API_NAME, description = A1eConsts.CONSUMER_API_DESCRIPTION), - @Tag(name = A1eConsts.CONSUMER_API_CALLBACKS_NAME, description = A1eConsts.CONSUMER_API_CALLBACKS_DESCRIPTION), - @Tag( - name = ProducerConsts.PRODUCER_API_CALLBACKS_NAME, - description = ProducerConsts.PRODUCER_API_CALLBACKS_DESCRIPTION), - @Tag(name = ProducerConsts.PRODUCER_API_NAME, description = ProducerConsts.PRODUCER_API_DESCRIPTION), // - @Tag(name = StatusController.API_NAME, description = StatusController.API_DESCRIPTION), // - @Tag(name = ConsumerConsts.CONSUMER_API_NAME, description = ConsumerConsts.CONSUMER_API_DESCRIPTION), // - }, // info = @Info( title = SwaggerConfig.API_TITLE, // version = "1.0", // description = SwaggerConfig.DESCRIPTION, // license = @License( - name = "Copyright (C) 2020 Nordix Foundation. Licensed under the Apache License.", + name = "Copyright (C) 2020-2022 Nordix Foundation. Licensed under the Apache License.", url = "http://www.apache.org/licenses/LICENSE-2.0"))) public class SwaggerConfig { private SwaggerConfig() { diff --git a/information-coordinator-service/src/main/java/org/oransc/ics/controllers/StatusController.java b/information-coordinator-service/src/main/java/org/oransc/ics/controllers/StatusController.java index 1e9cc980..0fe586cd 100644 --- a/information-coordinator-service/src/main/java/org/oransc/ics/controllers/StatusController.java +++ b/information-coordinator-service/src/main/java/org/oransc/ics/controllers/StatusController.java @@ -43,7 +43,7 @@ import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Mono; @RestController("StatusController") -@Tag(name = StatusController.API_NAME) +@Tag(name = StatusController.API_NAME, description = StatusController.API_DESCRIPTION) public class StatusController { public static final String API_NAME = "Service status"; diff --git a/information-coordinator-service/src/main/java/org/oransc/ics/controllers/a1e/A1eController.java b/information-coordinator-service/src/main/java/org/oransc/ics/controllers/a1e/A1eController.java index d6e7dc08..699308db 100644 --- a/information-coordinator-service/src/main/java/org/oransc/ics/controllers/a1e/A1eController.java +++ b/information-coordinator-service/src/main/java/org/oransc/ics/controllers/a1e/A1eController.java @@ -68,7 +68,7 @@ import reactor.core.publisher.Mono; @SuppressWarnings("java:S3457") // No need to call "toString()" method as formatting and string .. @RestController("A1-EI") -@Tag(name = A1eConsts.CONSUMER_API_NAME) +@Tag(name = A1eConsts.CONSUMER_API_NAME, description = A1eConsts.CONSUMER_API_DESCRIPTION) @RequestMapping(path = A1eConsts.API_ROOT, produces = MediaType.APPLICATION_JSON_VALUE) public class A1eController { diff --git a/information-coordinator-service/src/main/java/org/oransc/ics/controllers/r1consumer/ConsumerConsts.java b/information-coordinator-service/src/main/java/org/oransc/ics/controllers/r1consumer/ConsumerConsts.java index 30095798..7005a233 100644 --- a/information-coordinator-service/src/main/java/org/oransc/ics/controllers/r1consumer/ConsumerConsts.java +++ b/information-coordinator-service/src/main/java/org/oransc/ics/controllers/r1consumer/ConsumerConsts.java @@ -38,6 +38,11 @@ public class ConsumerConsts { public static final String INFO_TYPE_ID_PARAM = "infoTypeId"; public static final String INFO_TYPE_ID_PARAM_DESCRIPTION = "selects subscription jobs of matching information type"; + public static final String INFO_TYPE_ID_PATH = "infoTypeId"; + + public static final String INFO_JOB_ID_PATH = "infoJobId"; + + public static final String SUBSCRIPTION_ID_PATH = "subscriptionId"; public static final String PERFORM_TYPE_CHECK_PARAM = "typeCheck"; public static final String PERFORM_TYPE_CHECK_PARAM_DESCRIPTION = diff --git a/information-coordinator-service/src/main/java/org/oransc/ics/controllers/r1consumer/ConsumerController.java b/information-coordinator-service/src/main/java/org/oransc/ics/controllers/r1consumer/ConsumerController.java index 1a193693..fa335d9c 100644 --- a/information-coordinator-service/src/main/java/org/oransc/ics/controllers/r1consumer/ConsumerController.java +++ b/information-coordinator-service/src/main/java/org/oransc/ics/controllers/r1consumer/ConsumerController.java @@ -70,7 +70,7 @@ import reactor.core.publisher.Mono; @SuppressWarnings("java:S3457") // No need to call "toString()" method as formatting and string .. @RestController("Consumer API") -@Tag(name = ConsumerConsts.CONSUMER_API_NAME) +@Tag(name = ConsumerConsts.CONSUMER_API_NAME, description = ConsumerConsts.CONSUMER_API_DESCRIPTION) @RequestMapping(path = ConsumerConsts.API_ROOT, produces = MediaType.APPLICATION_JSON_VALUE) public class ConsumerController { @@ -125,7 +125,7 @@ public class ConsumerController { content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))) // }) public ResponseEntity getInfoType( // - @PathVariable("infoTypeId") String infoTypeId) { + @PathVariable(ConsumerConsts.INFO_TYPE_ID_PATH) String infoTypeId) { try { InfoType type = this.infoTypes.getType(infoTypeId); ConsumerInfoTypeInfo info = toInfoTypeInfo(type); @@ -194,7 +194,7 @@ public class ConsumerController { content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))) // }) public ResponseEntity getIndividualEiJob( // - @PathVariable("infoJobId") String infoJobId) { + @PathVariable(ConsumerConsts.INFO_JOB_ID_PATH) String infoJobId) { try { InfoJob job = this.infoJobs.getJob(infoJobId); return new ResponseEntity<>(gson.toJson(toInfoJobInfo(job)), HttpStatus.OK); @@ -217,7 +217,7 @@ public class ConsumerController { content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))) // }) public ResponseEntity getEiJobStatus( // - @PathVariable("infoJobId") String jobId) { + @PathVariable(ConsumerConsts.INFO_JOB_ID_PATH) String jobId) { try { InfoJob job = this.infoJobs.getJob(jobId); return new ResponseEntity<>(gson.toJson(toInfoJobStatus(job)), HttpStatus.OK); @@ -254,7 +254,7 @@ public class ConsumerController { content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))) // }) public ResponseEntity deleteIndividualEiJob( // - @PathVariable("infoJobId") String jobId) { + @PathVariable(ConsumerConsts.INFO_JOB_ID_PATH) String jobId) { try { InfoJob job = this.infoJobs.getJob(jobId); this.infoJobs.remove(job, this.infoProducers); @@ -292,7 +292,7 @@ public class ConsumerController { description = "Cannot modify job type", // content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class)))}) public Mono> putIndividualInfoJob( // - @PathVariable("infoJobId") String jobId, // + @PathVariable(ConsumerConsts.INFO_JOB_ID_PATH) String jobId, // @Parameter( name = ConsumerConsts.PERFORM_TYPE_CHECK_PARAM, required = false, // @@ -358,7 +358,7 @@ public class ConsumerController { content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))) // }) public ResponseEntity getIndividualTypeSubscription( // - @PathVariable("subscriptionId") String subscriptionId) { + @PathVariable(ConsumerConsts.SUBSCRIPTION_ID_PATH) String subscriptionId) { try { InfoTypeSubscriptions.SubscriptionInfo subscription = this.infoTypeSubscriptions.getSubscription(subscriptionId); @@ -387,7 +387,7 @@ public class ConsumerController { content = @Content(schema = @Schema(implementation = VoidResponse.class))) // }) public Mono> putIndividualTypeSubscription( // - @PathVariable("subscriptionId") String subscriptionId, // + @PathVariable(ConsumerConsts.SUBSCRIPTION_ID_PATH) String subscriptionId, // @RequestBody ConsumerTypeSubscriptionInfo subscription) { final boolean isNewSubscription = this.infoTypeSubscriptions.get(subscriptionId) == null; @@ -413,7 +413,7 @@ public class ConsumerController { content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))) // }) public ResponseEntity deleteIndividualTypeSubscription( // - @PathVariable("subscriptionId") String subscriptionId) { + @PathVariable(ConsumerConsts.SUBSCRIPTION_ID_PATH) String subscriptionId) { try { InfoTypeSubscriptions.SubscriptionInfo subscription = this.infoTypeSubscriptions.getSubscription(subscriptionId); diff --git a/information-coordinator-service/src/main/java/org/oransc/ics/controllers/r1producer/ProducerConsts.java b/information-coordinator-service/src/main/java/org/oransc/ics/controllers/r1producer/ProducerConsts.java index fee05e37..e3f667a9 100644 --- a/information-coordinator-service/src/main/java/org/oransc/ics/controllers/r1producer/ProducerConsts.java +++ b/information-coordinator-service/src/main/java/org/oransc/ics/controllers/r1producer/ProducerConsts.java @@ -20,6 +20,8 @@ package org.oransc.ics.controllers.r1producer; +import org.oransc.ics.controllers.r1consumer.ConsumerConsts; + public class ProducerConsts { public static final String PRODUCER_API_NAME = "Data producer (registration)"; public static final String API_ROOT = "/data-producer/v1"; @@ -28,6 +30,11 @@ public class ProducerConsts { public static final String PRODUCER_API_CALLBACKS_NAME = "Data producer (callbacks)"; public static final String PRODUCER_API_CALLBACKS_DESCRIPTION = "API implemented by data producers"; + public static final String INFO_TYPE_ID_PARAM = ConsumerConsts.INFO_TYPE_ID_PARAM; + public static final String INFO_TYPE_ID_PATH = ConsumerConsts.INFO_TYPE_ID_PATH; + + public static final String INFO_PRODUCER_ID_PATH = "infoProducerId"; + private ProducerConsts() { } diff --git a/information-coordinator-service/src/main/java/org/oransc/ics/controllers/r1producer/ProducerController.java b/information-coordinator-service/src/main/java/org/oransc/ics/controllers/r1producer/ProducerController.java index 5229176b..03722489 100644 --- a/information-coordinator-service/src/main/java/org/oransc/ics/controllers/r1producer/ProducerController.java +++ b/information-coordinator-service/src/main/java/org/oransc/ics/controllers/r1producer/ProducerController.java @@ -62,7 +62,7 @@ import org.springframework.web.bind.annotation.RestController; @SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally @RestController("Producer registry") -@Tag(name = ProducerConsts.PRODUCER_API_NAME) +@Tag(name = ProducerConsts.PRODUCER_API_NAME, description = ProducerConsts.PRODUCER_API_DESCRIPTION) public class ProducerController { private static Gson gson = new GsonBuilder().create(); @@ -113,7 +113,7 @@ public class ProducerController { description = "Information type is not found", // content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class)))}) public ResponseEntity getInfoType( // - @PathVariable("infoTypeId") String infoTypeId) { + @PathVariable(ProducerConsts.INFO_TYPE_ID_PATH) String infoTypeId) { try { InfoType t = this.infoTypes.getType(infoTypeId); ProducerInfoTypeInfo info = toInfoTypeInfo(t); @@ -142,7 +142,7 @@ public class ProducerController { content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class)))}) @Operation(summary = "Individual Information Type", description = "") public ResponseEntity putInfoType( // - @PathVariable("infoTypeId") String infoTypeId, // + @PathVariable(ProducerConsts.INFO_TYPE_ID_PATH) String infoTypeId, // @RequestBody ProducerInfoTypeInfo registrationInfo) { InfoType previousDefinition = this.infoTypes.get(infoTypeId); @@ -180,7 +180,7 @@ public class ProducerController { content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))) // }) public ResponseEntity deleteInfoType( // - @PathVariable("infoTypeId") String infoTypeId) { + @PathVariable(ProducerConsts.INFO_TYPE_ID_PATH) String infoTypeId) { InfoType type = this.infoTypes.get(infoTypeId); if (type == null) { @@ -207,10 +207,10 @@ public class ProducerController { }) public ResponseEntity getInfoProducerIdentifiers( // @Parameter( - name = "info_type_id", + name = ProducerConsts.INFO_TYPE_ID_PARAM, required = false, description = "If given, only the producers for the EI Data type is returned.") // - @RequestParam(name = "info_type_id", required = false) String typeId // + @RequestParam(name = ProducerConsts.INFO_TYPE_ID_PARAM, required = false) String typeId // ) { List result = new ArrayList<>(); for (InfoProducer infoProducer : typeId == null ? this.infoProducers.getAllProducers() @@ -237,7 +237,7 @@ public class ProducerController { content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class)))// }) public ResponseEntity getInfoProducer( // - @PathVariable("infoProducerId") String infoProducerId) { + @PathVariable(ProducerConsts.INFO_PRODUCER_ID_PATH) String infoProducerId) { try { InfoProducer producer = this.infoProducers.getProducer(infoProducerId); ProducerRegistrationInfo info = toProducerRegistrationInfo(producer); @@ -265,7 +265,7 @@ public class ProducerController { content = @Content(array = @ArraySchema(schema = @Schema(implementation = ProducerJobInfo.class)))), // }) public ResponseEntity getInfoProducerJobs( // - @PathVariable("infoProducerId") String infoProducerId) { + @PathVariable(ProducerConsts.INFO_PRODUCER_ID_PATH) String infoProducerId) { try { InfoProducer producer = this.infoProducers.getProducer(infoProducerId); Collection producerJobs = new ArrayList<>(); @@ -298,7 +298,7 @@ public class ProducerController { content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))) // }) public ResponseEntity getInfoProducerStatus( // - @PathVariable("infoProducerId") String infoProducerId) { + @PathVariable(ProducerConsts.INFO_PRODUCER_ID_PATH) String infoProducerId) { try { InfoProducer producer = this.infoProducers.getProducer(infoProducerId); return new ResponseEntity<>(gson.toJson(producerStatusInfo(producer)), HttpStatus.OK); @@ -384,7 +384,8 @@ public class ProducerController { description = "Producer is not found", // content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))) // }) - public ResponseEntity deleteInfoProducer(@PathVariable("infoProducerId") String infoProducerId) { + public ResponseEntity deleteInfoProducer( + @PathVariable(ProducerConsts.INFO_PRODUCER_ID_PATH) String infoProducerId) { try { final InfoProducer producer = this.infoProducers.getProducer(infoProducerId); this.infoProducers.deregisterProducer(producer); diff --git a/information-coordinator-service/src/test/java/org/oransc/ics/ApplicationTest.java b/information-coordinator-service/src/test/java/org/oransc/ics/ApplicationTest.java index 1d53403a..cc7e16ff 100644 --- a/information-coordinator-service/src/test/java/org/oransc/ics/ApplicationTest.java +++ b/information-coordinator-service/src/test/java/org/oransc/ics/ApplicationTest.java @@ -48,6 +48,7 @@ import org.oransc.ics.configuration.ImmutableHttpProxyConfig; import org.oransc.ics.configuration.ImmutableWebClientConfig; import org.oransc.ics.configuration.WebClientConfig; import org.oransc.ics.configuration.WebClientConfig.HttpProxyConfig; +import org.oransc.ics.controller.A1eCallbacksSimulatorController; import org.oransc.ics.controller.ConsumerSimulatorController; import org.oransc.ics.controller.ProducerSimulatorController; import org.oransc.ics.controllers.a1e.A1eConsts; @@ -132,6 +133,9 @@ class ApplicationTest { @Autowired ConsumerSimulatorController consumerSimulator; + @Autowired + A1eCallbacksSimulatorController a1eCallbacksSimulator; + @Autowired ProducerSupervision producerSupervision; @@ -165,6 +169,7 @@ class ApplicationTest { this.infoTypeSubscriptions.clear(); this.producerSimulator.getTestResults().reset(); this.consumerSimulator.getTestResults().reset(); + this.a1eCallbacksSimulator.getTestResults().reset(); } @AfterEach @@ -379,7 +384,7 @@ class ApplicationTest { assertThat(this.infoJobs.size()).isZero(); ProducerSimulatorController.TestResults simulatorResults = this.producerSimulator.getTestResults(); - await().untilAsserted(() -> assertThat(simulatorResults.jobsStopped.size()).isEqualTo(1)); + await().untilAsserted(() -> assertThat(simulatorResults.jobsStopped).hasSize(1)); assertThat(simulatorResults.jobsStopped.get(0)).isEqualTo("jobId"); } @@ -393,7 +398,7 @@ class ApplicationTest { assertThat(this.infoJobs.size()).isZero(); ProducerSimulatorController.TestResults simulatorResults = this.producerSimulator.getTestResults(); - await().untilAsserted(() -> assertThat(simulatorResults.jobsStopped.size()).isEqualTo(1)); + await().untilAsserted(() -> assertThat(simulatorResults.jobsStopped).hasSize(1)); assertThat(simulatorResults.jobsStopped.get(0)).isEqualTo("jobId"); testErrorCode(restClient().delete(url), HttpStatus.NOT_FOUND, "Could not find Information job: jobId"); @@ -426,7 +431,7 @@ class ApplicationTest { assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.CREATED); ProducerSimulatorController.TestResults simulatorResults = this.producerSimulator.getTestResults(); - await().untilAsserted(() -> assertThat(simulatorResults.jobsStarted.size()).isEqualTo(1)); + await().untilAsserted(() -> assertThat(simulatorResults.jobsStarted).hasSize(1)); ProducerJobInfo request = simulatorResults.jobsStarted.get(0); assertThat(request.id).isEqualTo("jobId"); @@ -454,7 +459,7 @@ class ApplicationTest { assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.CREATED); ProducerSimulatorController.TestResults simulatorResults = this.producerSimulator.getTestResults(); - await().untilAsserted(() -> assertThat(simulatorResults.jobsStarted.size()).isEqualTo(1)); + await().untilAsserted(() -> assertThat(simulatorResults.jobsStarted).hasSize(1)); ProducerJobInfo request = simulatorResults.jobsStarted.get(0); assertThat(request.id).isEqualTo("jobId"); @@ -647,7 +652,7 @@ class ApplicationTest { restClient().putForEntity(url, body).block(); ProducerSimulatorController.TestResults simulatorResults = this.producerSimulator.getTestResults(); - await().untilAsserted(() -> assertThat(simulatorResults.jobsStarted.size()).isEqualTo(2)); + await().untilAsserted(() -> assertThat(simulatorResults.jobsStarted).hasSize(2)); ProducerJobInfo request = simulatorResults.jobsStarted.get(0); assertThat(request.id).isEqualTo("jobId"); } @@ -673,7 +678,7 @@ class ApplicationTest { restClient().putForEntity(url, body).block(); ProducerSimulatorController.TestResults simulatorResults = this.producerSimulator.getTestResults(); - await().untilAsserted(() -> assertThat(simulatorResults.jobsStarted.size()).isEqualTo(1)); + await().untilAsserted(() -> assertThat(simulatorResults.jobsStarted).hasSize(1)); ProducerJobInfo request = simulatorResults.jobsStarted.get(0); assertThat(request.id).isEqualTo("jobId"); } @@ -726,25 +731,25 @@ class ApplicationTest { @Test void a1eJobStatusNotifications() throws JsonMappingException, JsonProcessingException, ServiceException { - ConsumerSimulatorController.TestResults consumerCalls = this.consumerSimulator.getTestResults(); + A1eCallbacksSimulatorController.TestResults consumerCalls = this.a1eCallbacksSimulator.getTestResults(); ProducerSimulatorController.TestResults producerCalls = this.producerSimulator.getTestResults(); putInfoProducerWithOneType("infoProducerId", TYPE_ID); putInfoJob(TYPE_ID, "jobId"); putInfoProducerWithOneType("infoProducerId2", TYPE_ID); - await().untilAsserted(() -> assertThat(producerCalls.jobsStarted.size()).isEqualTo(2)); + await().untilAsserted(() -> assertThat(producerCalls.jobsStarted).hasSize(2)); deleteInfoProducer("infoProducerId2"); assertThat(this.infoTypes.size()).isEqualTo(1); // The type remains, one producer left deleteInfoProducer("infoProducerId"); assertThat(this.infoTypes.size()).isEqualTo(1); // The type remains assertThat(this.infoJobs.size()).isEqualTo(1); // The job remains - await().untilAsserted(() -> assertThat(consumerCalls.eiJobStatusCallbacks.size()).isEqualTo(1)); + await().untilAsserted(() -> assertThat(consumerCalls.eiJobStatusCallbacks).hasSize(1)); assertThat(consumerCalls.eiJobStatusCallbacks.get(0).state) .isEqualTo(A1eEiJobStatus.EiJobStatusValues.DISABLED); putInfoProducerWithOneType("infoProducerId", TYPE_ID); - await().untilAsserted(() -> assertThat(consumerCalls.eiJobStatusCallbacks.size()).isEqualTo(2)); + await().untilAsserted(() -> assertThat(consumerCalls.eiJobStatusCallbacks).hasSize(2)); assertThat(consumerCalls.eiJobStatusCallbacks.get(1).state).isEqualTo(A1eEiJobStatus.EiJobStatusValues.ENABLED); } @@ -759,14 +764,14 @@ class ApplicationTest { // change the type for the producer, the job shall be disabled putInfoProducerWithOneType(PRODUCER_ID, "junk"); verifyJobStatus(EI_JOB_ID, "DISABLED"); - ConsumerSimulatorController.TestResults consumerCalls = this.consumerSimulator.getTestResults(); - await().untilAsserted(() -> assertThat(consumerCalls.eiJobStatusCallbacks.size()).isEqualTo(1)); + A1eCallbacksSimulatorController.TestResults consumerCalls = this.a1eCallbacksSimulator.getTestResults(); + await().untilAsserted(() -> assertThat(consumerCalls.eiJobStatusCallbacks).hasSize(1)); assertThat(consumerCalls.eiJobStatusCallbacks.get(0).state) .isEqualTo(A1eEiJobStatus.EiJobStatusValues.DISABLED); putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID); verifyJobStatus(EI_JOB_ID, "ENABLED"); - await().untilAsserted(() -> assertThat(consumerCalls.eiJobStatusCallbacks.size()).isEqualTo(2)); + await().untilAsserted(() -> assertThat(consumerCalls.eiJobStatusCallbacks).hasSize(2)); assertThat(consumerCalls.eiJobStatusCallbacks.get(1).state).isEqualTo(A1eEiJobStatus.EiJobStatusValues.ENABLED); } @@ -789,11 +794,11 @@ class ApplicationTest { ResponseEntity resp = restClient().getForEntity(url).block(); assertThat(resp.getBody()).contains(PRODUCER_ID); - url = ProducerConsts.API_ROOT + "/info-producers?info_type_id=" + TYPE_ID; + url = ProducerConsts.API_ROOT + "/info-producers?infoTypeId=" + TYPE_ID; resp = restClient().getForEntity(url).block(); assertThat(resp.getBody()).contains(PRODUCER_ID); - url = ProducerConsts.API_ROOT + "/info-producers?info_type_id=junk"; + url = ProducerConsts.API_ROOT + "/info-producers?infoTypeId=junk"; resp = restClient().getForEntity(url).block(); assertThat(resp.getBody()).isEqualTo("[]"); } @@ -801,7 +806,7 @@ class ApplicationTest { @Test void producerSupervision() throws JsonMappingException, JsonProcessingException, ServiceException { - ConsumerSimulatorController.TestResults consumerResults = this.consumerSimulator.getTestResults(); + A1eCallbacksSimulatorController.TestResults consumerResults = this.a1eCallbacksSimulator.getTestResults(); putInfoProducerWithOneTypeRejecting("simulateProducerError", TYPE_ID); { @@ -811,7 +816,7 @@ class ApplicationTest { verifyJobStatus(EI_JOB_ID, "ENABLED"); deleteInfoProducer(PRODUCER_ID); // A Job disabled status notification shall now be received - await().untilAsserted(() -> assertThat(consumerResults.eiJobStatusCallbacks.size()).isEqualTo(1)); + await().untilAsserted(() -> assertThat(consumerResults.eiJobStatusCallbacks).hasSize(1)); assertThat(consumerResults.eiJobStatusCallbacks.get(0).state) .isEqualTo(A1eEiJobStatus.EiJobStatusValues.DISABLED); verifyJobStatus(EI_JOB_ID, "DISABLED"); @@ -836,7 +841,7 @@ class ApplicationTest { // Now we have one disabled job, and no producer. // PUT a producer, then a Job ENABLED status notification shall be received putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID); - await().untilAsserted(() -> assertThat(consumerResults.eiJobStatusCallbacks.size()).isEqualTo(2)); + await().untilAsserted(() -> assertThat(consumerResults.eiJobStatusCallbacks).hasSize(2)); assertThat(consumerResults.eiJobStatusCallbacks.get(1).state) .isEqualTo(A1eEiJobStatus.EiJobStatusValues.ENABLED); verifyJobStatus(EI_JOB_ID, "ENABLED"); @@ -860,8 +865,8 @@ class ApplicationTest { // Run the supervision and wait for the job to get started in the producer this.producerSupervision.createTask().blockLast(); - ConsumerSimulatorController.TestResults consumerResults = this.consumerSimulator.getTestResults(); - await().untilAsserted(() -> assertThat(consumerResults.eiJobStatusCallbacks.size()).isEqualTo(1)); + A1eCallbacksSimulatorController.TestResults consumerResults = this.a1eCallbacksSimulator.getTestResults(); + await().untilAsserted(() -> assertThat(consumerResults.eiJobStatusCallbacks).hasSize(1)); assertThat(consumerResults.eiJobStatusCallbacks.get(0).state) .isEqualTo(A1eEiJobStatus.EiJobStatusValues.ENABLED); verifyJobStatus(EI_JOB_ID, "ENABLED"); @@ -909,7 +914,7 @@ class ApplicationTest { assertThat(this.infoJobs.size()).isEqualTo(1); ProducerSimulatorController.TestResults simulatorResults = this.producerSimulator.getTestResults(); - await().untilAsserted(() -> assertThat(simulatorResults.jobsStopped.size()).isEqualTo(3)); + await().untilAsserted(() -> assertThat(simulatorResults.jobsStopped).hasSize(3)); } @Test @@ -1001,13 +1006,13 @@ class ApplicationTest { // Test callback for PUT type this.putInfoType(TYPE_ID); - await().untilAsserted(() -> assertThat(consumerCalls.typeRegistrationInfoCallbacks.size()).isEqualTo(1)); + await().untilAsserted(() -> assertThat(consumerCalls.typeRegistrationInfoCallbacks).hasSize(1)); assertThat(consumerCalls.typeRegistrationInfoCallbacks.get(0).state) .isEqualTo(ConsumerTypeRegistrationInfo.ConsumerTypeStatusValues.REGISTERED); // Test callback for DELETE type this.deleteInfoType(TYPE_ID); - await().untilAsserted(() -> assertThat(consumerCalls.typeRegistrationInfoCallbacks.size()).isEqualTo(2)); + await().untilAsserted(() -> assertThat(consumerCalls.typeRegistrationInfoCallbacks).hasSize(2)); assertThat(consumerCalls.typeRegistrationInfoCallbacks.get(1).state) .isEqualTo(ConsumerTypeRegistrationInfo.ConsumerTypeStatusValues.DEREGISTERED); } @@ -1096,7 +1101,7 @@ class ApplicationTest { ConsumerJobInfo consumerJobInfo(String typeId, String infoJobId) throws JsonMappingException, JsonProcessingException { return new ConsumerJobInfo(typeId, jsonObject(), "owner", "https://junk.com", - baseUrl() + ConsumerSimulatorController.getJobStatusUrl(infoJobId)); + baseUrl() + A1eCallbacksSimulatorController.getJobStatusUrl(infoJobId)); } private A1eEiJobInfo infoJobInfo() throws JsonMappingException, JsonProcessingException { @@ -1105,7 +1110,7 @@ class ApplicationTest { A1eEiJobInfo infoJobInfo(String typeId, String infoJobId) throws JsonMappingException, JsonProcessingException { return new A1eEiJobInfo(typeId, jsonObject(), "owner", "https://junk.com", - baseUrl() + ConsumerSimulatorController.getJobStatusUrl(infoJobId)); + baseUrl() + A1eCallbacksSimulatorController.getJobStatusUrl(infoJobId)); } private Object jsonObject(String json) { diff --git a/information-coordinator-service/src/test/java/org/oransc/ics/controller/A1eCallbacksSimulatorController.java b/information-coordinator-service/src/test/java/org/oransc/ics/controller/A1eCallbacksSimulatorController.java new file mode 100644 index 00000000..8e09310e --- /dev/null +++ b/information-coordinator-service/src/test/java/org/oransc/ics/controller/A1eCallbacksSimulatorController.java @@ -0,0 +1,94 @@ +/*- + * ========================LICENSE_START================================= + * O-RAN-SC + * %% + * Copyright (C) 2020 Nordix Foundation + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================LICENSE_END=================================== + */ + +package org.oransc.ics.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; + +import java.lang.invoke.MethodHandles; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import lombok.Getter; + +import org.oransc.ics.controllers.VoidResponse; +import org.oransc.ics.controllers.a1e.A1eConsts; +import org.oransc.ics.controllers.a1e.A1eEiJobStatus; +import org.oransc.ics.controllers.r1consumer.ConsumerConsts; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController("A1eCallbacksSimulatorController") +@Tag(name = A1eConsts.CONSUMER_API_CALLBACKS_NAME, description = A1eConsts.CONSUMER_API_CALLBACKS_DESCRIPTION) +public class A1eCallbacksSimulatorController { + + private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + public static class TestResults { + + public List eiJobStatusCallbacks = + Collections.synchronizedList(new ArrayList()); + + public void reset() { + eiJobStatusCallbacks.clear(); + } + } + + @Getter + private TestResults testResults = new TestResults(); + + public static String getJobStatusUrl(String infoJobId) { + return "/example-dataconsumer/info-jobs/" + infoJobId + "/status"; + } + + @PostMapping( + path = "/example-dataconsumer/info-jobs/{infoJobId}/status", + produces = MediaType.APPLICATION_JSON_VALUE) + @Operation( + summary = "Callback for changed Information Job status", + description = "The primitive is implemented by the data consumer and is invoked when a Information Job status has been changed.") + @ApiResponses( + value = { // + @ApiResponse( + responseCode = "200", + description = "OK", // + content = @Content(schema = @Schema(implementation = VoidResponse.class))) // + }) + public ResponseEntity jobStatusCallback( // + @PathVariable(ConsumerConsts.INFO_JOB_ID_PATH) String infoJobId, // + @RequestBody A1eEiJobStatus status) { + logger.info("Job status callback status: {} infoJobId: {}", status.state, infoJobId); + this.testResults.eiJobStatusCallbacks.add(status); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/information-coordinator-service/src/test/java/org/oransc/ics/controller/ConsumerSimulatorController.java b/information-coordinator-service/src/test/java/org/oransc/ics/controller/ConsumerSimulatorController.java index 3d69ee69..4f2edcdc 100644 --- a/information-coordinator-service/src/test/java/org/oransc/ics/controller/ConsumerSimulatorController.java +++ b/information-coordinator-service/src/test/java/org/oransc/ics/controller/ConsumerSimulatorController.java @@ -35,8 +35,6 @@ import java.util.List; import lombok.Getter; import org.oransc.ics.controllers.VoidResponse; -import org.oransc.ics.controllers.a1e.A1eConsts; -import org.oransc.ics.controllers.a1e.A1eEiJobStatus; import org.oransc.ics.controllers.r1consumer.ConsumerConsts; import org.oransc.ics.controllers.r1consumer.ConsumerTypeRegistrationInfo; import org.slf4j.Logger; @@ -44,25 +42,22 @@ import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController("ConsumerSimulatorController") +@Tag(name = ConsumerConsts.CONSUMER_API_CALLBACKS_NAME, description = ConsumerConsts.CONSUMER_API_DESCRIPTION) public class ConsumerSimulatorController { private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); public static class TestResults { - public List eiJobStatusCallbacks = - Collections.synchronizedList(new ArrayList()); public List typeRegistrationInfoCallbacks = Collections.synchronizedList(new ArrayList()); public void reset() { - eiJobStatusCallbacks.clear(); typeRegistrationInfoCallbacks.clear(); } } @@ -70,39 +65,12 @@ public class ConsumerSimulatorController { @Getter private TestResults testResults = new TestResults(); - public static String getJobStatusUrl(String infoJobId) { - return "/example_dataconsumer/info_jobs/" + infoJobId + "/status"; - } - - @Tag(name = A1eConsts.CONSUMER_API_CALLBACKS_NAME) - @PostMapping( - path = "/example_dataconsumer/info_jobs/{infoJobId}/status", - produces = MediaType.APPLICATION_JSON_VALUE) - @Operation( - summary = "Callback for changed Information Job status", - description = "The primitive is implemented by the data consumer and is invoked when a Information Job status has been changed.") - @ApiResponses( - value = { // - @ApiResponse( - responseCode = "200", - description = "OK", // - content = @Content(schema = @Schema(implementation = VoidResponse.class))) // - }) - public ResponseEntity jobStatusCallback( // - @PathVariable("infoJobId") String infoJobId, // - @RequestBody A1eEiJobStatus status) { - logger.info("Job status callback status: {} infoJobId: {}", status.state, infoJobId); - this.testResults.eiJobStatusCallbacks.add(status); - return new ResponseEntity<>(HttpStatus.OK); - } - - private static final String TYPE_STATUS_CALLBACK_URL = "/example_dataconsumer/info_type_status"; + private static final String TYPE_STATUS_CALLBACK_URL = "/example-dataconsumer/info-type-status"; public static String getTypeStatusCallbackUrl() { return TYPE_STATUS_CALLBACK_URL; } - @Tag(name = ConsumerConsts.CONSUMER_API_CALLBACKS_NAME) @PostMapping(path = TYPE_STATUS_CALLBACK_URL, produces = MediaType.APPLICATION_JSON_VALUE) @Operation( summary = "Callback for changed Information type registration status", diff --git a/information-coordinator-service/src/test/java/org/oransc/ics/controller/ProducerSimulatorController.java b/information-coordinator-service/src/test/java/org/oransc/ics/controller/ProducerSimulatorController.java index 55d32b02..9e383949 100644 --- a/information-coordinator-service/src/test/java/org/oransc/ics/controller/ProducerSimulatorController.java +++ b/information-coordinator-service/src/test/java/org/oransc/ics/controller/ProducerSimulatorController.java @@ -36,6 +36,7 @@ import lombok.Getter; import org.oransc.ics.controllers.ErrorResponse; import org.oransc.ics.controllers.VoidResponse; +import org.oransc.ics.controllers.r1consumer.ConsumerConsts; import org.oransc.ics.controllers.r1producer.ProducerConsts; import org.oransc.ics.controllers.r1producer.ProducerJobInfo; import org.slf4j.Logger; @@ -51,16 +52,16 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController("ProducerSimulatorController") -@Tag(name = ProducerConsts.PRODUCER_API_CALLBACKS_NAME) +@Tag(name = ProducerConsts.PRODUCER_API_CALLBACKS_NAME, description = ProducerConsts.PRODUCER_API_CALLBACKS_DESCRIPTION) public class ProducerSimulatorController { private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - public static final String JOB_URL = "/example_dataproducer/info_job"; - public static final String JOB_ERROR_URL = "/example_dataproducer/info_job_error"; + public static final String JOB_URL = "/example-dataproducer/info-job"; + public static final String JOB_ERROR_URL = "/example-dataproducer/info-job-error"; - public static final String SUPERVISION_URL = "/example_dataproducer/health_check"; - public static final String SUPERVISION_ERROR_URL = "/example_dataproducer/health_check_error"; + public static final String SUPERVISION_URL = "/example-dataproducer/health-check"; + public static final String SUPERVISION_ERROR_URL = "/example-dataproducer/health-check-error"; public static class TestResults { @@ -123,7 +124,7 @@ public class ProducerSimulatorController { content = @Content(schema = @Schema(implementation = VoidResponse.class))) // }) public ResponseEntity jobDeletedCallback( // - @PathVariable("infoJobId") String infoJobId) { + @PathVariable(ConsumerConsts.INFO_JOB_ID_PATH) String infoJobId) { try { logger.info("Job deleted callback {}", infoJobId); this.testResults.jobsStopped.add(infoJobId); @@ -159,7 +160,7 @@ public class ProducerSimulatorController { content = @Content(schema = @Schema(implementation = VoidResponse.class))) // }) public ResponseEntity jobDeletedCallbackReturnError( // - @PathVariable("infoJobId") String infoJobId) { + @PathVariable(ConsumerConsts.INFO_JOB_ID_PATH) String infoJobId) { logger.info("Job created (returning error) callback {}", infoJobId); this.testResults.noOfRejectedDelete += 1; return ErrorResponse.create("Producer returns error on delete job", HttpStatus.NOT_FOUND); -- 2.16.6