Merge "Support for test of PMS persistency"
authorJohn Keeney <john.keeney@est.tech>
Tue, 27 Apr 2021 08:59:40 +0000 (08:59 +0000)
committerGerrit Code Review <gerrit@o-ran-sc.org>
Tue, 27 Apr 2021 08:59:40 +0000 (08:59 +0000)
13 files changed:
docker-compose/README.md
enrichment-coordinator-service/api/ecs-api.json
enrichment-coordinator-service/api/ecs-api.yaml
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/r1consumer/ConsumerConsts.java
enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/r1consumer/ConsumerController.java
enrichment-coordinator-service/src/test/java/org/oransc/enrichment/ApplicationTest.java
onap/oran
test/common/mr_api_functions.sh [changed mode: 0644->0755]
test/common/test_env-onap-guilin.sh [changed mode: 0644->0755]
test/common/test_env-onap-honolulu.sh [changed mode: 0644->0755]
test/common/test_env-oran-cherry.sh
test/common/test_env-oran-dawn.sh
test/mrstub/app/main.py

index e405131..d7a4f17 100644 (file)
@@ -14,10 +14,6 @@ limitations under the License.
 
 For more information about license please see the [LICENSE](LICENSE.txt) file for details.
 
-## O-RAN-SC ControlPanel Gateway:
-To view the policy or enrichment information in control panel gui along with Policy Management Service & Enrichment Coordinator Service you should also have nonrtric gateway because all the request from the gui is passed through this API gateway.
-To start all the necessary components,
-docker-compose -f docker-compose.yaml -f control-panel/docker-compose.yaml -f nonrtric-gateway/docker-compose.yaml -f policy-service/docker-compose.yaml -f ecs/docker-compose.yaml -f a1-sim/docker-compose.yaml up
 ## O-RAN-SC docker-compose files:
 The docker compose file helps the user to deploy all or partial components of nonrtric with one command.
 
@@ -73,4 +69,20 @@ prepareEcsData.sh
 This is to generate some data into the ECS microservice
 
 prepareDmaapMsg.sh
-This is to generate some data into the Dmaap MR, so that PMS reads message from MR
\ No newline at end of file
+This is to generate some data into the Dmaap MR, so that PMS reads message from MR
+
+## O-RAN-SC Control Panel
+
+The Non-RT RIC Control Panel is a graphical user interface that enables the user to view and manage the A1 policies in the RAN and also view producers and jobs for the Enrichement coordinator service.
+
+### O-RAN-SC Control Panel Gateway:
+
+To view the policy or enrichment information in control panel gui along with Policy Management Service & Enrichment Coordinator Service you should also have nonrtric gateway because all the request from the gui is passed through this API gateway.
+
+#### Prerequisite:
+
+Make sure to follow the section regarding sample data so there is data available to see in the interface.
+
+To start all the necessary components, run the following command:
+
+docker-compose -f docker-compose.yaml -f control-panel/docker-compose.yaml -f nonrtric-gateway/docker-compose.yaml -f policy-service/docker-compose.yaml -f ecs/docker-compose.yaml -f a1-sim/docker-compose.yaml up
\ No newline at end of file
index 06f6ac1..3d6882a 100644 (file)
                     "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Job"}}},
                     "required": true
                 },
+                "description": "The job will be enabled when a producer is available",
                 "operationId": "putIndividualInfoJob",
                 "responses": {
                     "200": {
                         "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProblemDetails"}}}
                     }
                 },
-                "parameters": [{
-                    "schema": {"type": "string"},
-                    "in": "path",
-                    "name": "infoJobId",
-                    "required": true
-                }],
+                "parameters": [
+                    {
+                        "schema": {"type": "string"},
+                        "in": "path",
+                        "name": "infoJobId",
+                        "required": true
+                    },
+                    {
+                        "schema": {
+                            "default": false,
+                            "type": "boolean"
+                        },
+                        "in": "query",
+                        "name": "typeCheck",
+                        "description": "when true, a validation of that the type exists and that the job matches the type schema.",
+                        "required": false
+                    }
+                ],
                 "tags": ["Data consumer"]
             }
         },
index f94743e..3eda306 100644 (file)
@@ -602,6 +602,7 @@ paths:
       tags:
       - Data consumer
       summary: Individual data subscription job
+      description: The job will be enabled when a producer is available
       operationId: putIndividualInfoJob
       parameters:
       - name: infoJobId
@@ -611,6 +612,16 @@ paths:
         explode: false
         schema:
           type: string
+      - name: typeCheck
+        in: query
+        description: when true, a validation of that the type exists and that the
+          job matches the type schema.
+        required: false
+        style: form
+        explode: true
+        schema:
+          type: boolean
+          default: false
       requestBody:
         content:
           application/json:
index 656808f..6ddd583 100644 (file)
@@ -32,10 +32,16 @@ public class ConsumerConsts {
 
     public static final String INDIVIDUAL_JOB = "Individual data subscription job";
 
+    public static final String PUT_INDIVIDUAL_JOB_DESCRIPTION = "The job will be enabled when a producer is available";
+
     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 PERFORM_TYPE_CHECK_PARAM = "typeCheck";
+    public static final String PERFORM_TYPE_CHECK_PARAM_DESCRIPTION =
+        "when true, a validation of that the type exists and that the job matches the type schema.";
+
     private ConsumerConsts() {
     }
 }
index 7a1bf18..e93d9cb 100644 (file)
@@ -262,7 +262,7 @@ public class ConsumerController {
         path = "/info-jobs/{infoJobId}", //
         produces = MediaType.APPLICATION_JSON_VALUE, //
         consumes = MediaType.APPLICATION_JSON_VALUE)
-    @Operation(summary = ConsumerConsts.INDIVIDUAL_JOB)
+    @Operation(summary = ConsumerConsts.INDIVIDUAL_JOB, description = ConsumerConsts.PUT_INDIVIDUAL_JOB_DESCRIPTION)
     @ApiResponses(
         value = { //
             @ApiResponse(
@@ -280,11 +280,19 @@ public class ConsumerController {
         })
     public Mono<ResponseEntity<Object>> putIndividualInfoJob( //
         @PathVariable("infoJobId") String jobId, //
+        @Parameter(
+            name = ConsumerConsts.PERFORM_TYPE_CHECK_PARAM,
+            required = false, //
+            description = ConsumerConsts.PERFORM_TYPE_CHECK_PARAM_DESCRIPTION) //
+        @RequestParam(
+            name = ConsumerConsts.PERFORM_TYPE_CHECK_PARAM,
+            required = false,
+            defaultValue = "false") boolean performTypeCheck,
         @RequestBody ConsumerJobInfo informationJobObject) {
 
         final boolean isNewJob = this.jobs.get(jobId) == null;
 
-        return validatePutInfoJob(jobId, informationJobObject) //
+        return validatePutInfoJob(jobId, informationJobObject, performTypeCheck) //
             .flatMap(this::startInfoSubscriptionJob) //
             .doOnNext(newEiJob -> this.jobs.put(newEiJob)) //
             .flatMap(newEiJob -> Mono.just(new ResponseEntity<>(isNewJob ? HttpStatus.CREATED : HttpStatus.OK)))
@@ -298,16 +306,18 @@ public class ConsumerController {
             .flatMap(noOfAcceptingProducers -> Mono.just(newInfoJob));
     }
 
-    private Mono<EiJob> validatePutInfoJob(String jobId, ConsumerJobInfo jobInfo) {
+    private Mono<EiJob> validatePutInfoJob(String jobId, ConsumerJobInfo jobInfo, boolean performTypeCheck) {
         try {
-            EiType infoType = this.infoTypes.getType(jobInfo.infoTypeId);
-            validateJsonObjectAgainstSchema(infoType.getJobDataSchema(), jobInfo.jobDefinition);
+            if (performTypeCheck) {
+                EiType infoType = this.infoTypes.getType(jobInfo.infoTypeId);
+                validateJsonObjectAgainstSchema(infoType.getJobDataSchema(), jobInfo.jobDefinition);
+            }
             EiJob existingEiJob = this.jobs.get(jobId);
 
             if (existingEiJob != null && !existingEiJob.getTypeId().equals(jobInfo.infoTypeId)) {
                 throw new ServiceException("Not allowed to change type for existing job", HttpStatus.CONFLICT);
             }
-            return Mono.just(toEiJob(jobInfo, jobId, infoType));
+            return Mono.just(toEiJob(jobInfo, jobId, jobInfo.infoTypeId));
         } catch (Exception e) {
             return Mono.error(e);
         }
@@ -331,10 +341,10 @@ public class ConsumerController {
         }
     }
 
-    private EiJob toEiJob(ConsumerJobInfo info, String id, EiType type) {
+    private EiJob toEiJob(ConsumerJobInfo info, String id, String typeId) {
         return EiJob.builder() //
             .id(id) //
-            .typeId(type.getId()) //
+            .typeId(typeId) //
             .owner(info.owner) //
             .jobData(info.jobDefinition) //
             .targetUrl(info.jobResultUri) //
@@ -342,6 +352,10 @@ public class ConsumerController {
             .build();
     }
 
+    private EiJob toEiJob(ConsumerJobInfo info, String id, EiType type) {
+        return toEiJob(info, id, type.getId());
+    }
+
     private ConsumerInfoTypeInfo toInfoTypeInfo(EiType type) {
         return new ConsumerInfoTypeInfo(type.getJobDataSchema());
     }
index 4596141..9d55940 100644 (file)
@@ -449,6 +449,21 @@ class ApplicationTest {
         verifyJobStatus(EI_JOB_ID, "ENABLED");
     }
 
+    @Test
+    void consumerPutInformationJob_noType() throws JsonMappingException, JsonProcessingException, ServiceException {
+        String url = ConsumerConsts.API_ROOT + "/info-jobs/jobId?typeCheck=false";
+        String body = gson.toJson(consumerJobInfo());
+        ResponseEntity<String> resp = restClient().putForEntity(url, body).block();
+        assertThat(this.eiJobs.size()).isEqualTo(1);
+        assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.CREATED);
+        verifyJobStatus(EI_JOB_ID, "DISABLED");
+
+        putEiProducerWithOneType(PRODUCER_ID, TYPE_ID);
+
+        verifyJobStatus(EI_JOB_ID, "ENABLED");
+
+    }
+
     @Test
     void a1ePutEiJob_jsonSchemavalidationError() throws Exception {
         putEiProducerWithOneType(PRODUCER_ID, TYPE_ID);
@@ -466,7 +481,7 @@ class ApplicationTest {
     void consumerPutJob_jsonSchemavalidationError() throws Exception {
         putEiProducerWithOneType(PRODUCER_ID, TYPE_ID);
 
-        String url = ConsumerConsts.API_ROOT + "/info-jobs/jobId";
+        String url = ConsumerConsts.API_ROOT + "/info-jobs/jobId?typeCheck=true";
         // The element with name "property1" is mandatory in the schema
         ConsumerJobInfo jobInfo = new ConsumerJobInfo("typeId", jsonObject("{ \"XXstring\" : \"value\" }"), "owner",
             "targetUri", "jobStatusUrl");
index ab7baa0..b28e811 160000 (submodule)
--- a/onap/oran
+++ b/onap/oran
@@ -1 +1 @@
-Subproject commit ab7baa0563069bc403c840b39f22a9e7e900fb72
+Subproject commit b28e811178bf9d828615f62c67f30a78c0414eb1
old mode 100644 (file)
new mode 100755 (executable)
index 25b5172..3569f6c
@@ -580,9 +580,9 @@ start_mr() {
 
                        __create_topic $MR_WRITE_TOPIC "Topic for writing policy messages"
 
-                       __dmaap_pipeclean $MR_READ_TOPIC "/events/A1-POLICY-AGENT-READ" "/events/A1-POLICY-AGENT-READ/users/policy-agent?timeout=1000&limit=100"
+                       __dmaap_pipeclean $MR_READ_TOPIC "/events/$MR_READ_TOPIC" "/events/$MR_READ_TOPIC/users/policy-agent?timeout=1000&limit=100"
 
-                       __dmaap_pipeclean $MR_WRITE_TOPIC "/events/A1-POLICY-AGENT-WRITE" "/events/A1-POLICY-AGENT-WRITE/users/mr-stub?timeout=1000&limit=100"
+                       __dmaap_pipeclean $MR_WRITE_TOPIC "/events/$MR_WRITE_TOPIC" "/events/$MR_WRITE_TOPIC/users/mr-stub?timeout=1000&limit=100"
 
                        echo " Current topics:"
                        curlString="$MR_DMAAP_PATH/topics"
old mode 100644 (file)
new mode 100755 (executable)
index f5cf837..0895947
@@ -195,10 +195,10 @@ MR_DMAAP_LOCALHOST_PORT=3904                             # MR stub container ext
 MR_STUB_LOCALHOST_PORT=3908                              # MR stub container external port (host -> container)
 MR_DMAAP_LOCALHOST_SECURE_PORT=3905                      # MR stub container internal port (container -> container)
 MR_STUB_LOCALHOST_SECURE_PORT=3909                       # MR stub container external secure port (host -> container)
-MR_READ_URL="/events/A1-POLICY-AGENT-READ/users/policy-agent?timeout=15000&limit=100" # Path to read messages from MR
-MR_WRITE_URL="/events/A1-POLICY-AGENT-WRITE"             # Path write messages to MR
 MR_READ_TOPIC="A1-POLICY-AGENT-READ"                     # Read topic
 MR_WRITE_TOPIC="A1-POLICY-AGENT-WRITE"                   # Write topic
+MR_READ_URL="/events/$MR_READ_TOPIC/users/policy-agent?timeout=15000&limit=100" # Path to read messages from MR
+MR_WRITE_URL="/events/$MR_WRITE_TOPIC"                   # Path to write messages to MR
 MR_STUB_ALIVE_URL="/"                                    # Base path for mr stub alive check
 MR_DMAAP_ALIVE_URL="/topics"                             # Base path for dmaap-mr alive check
 MR_DMAAP_COMPOSE_DIR="dmaapmr"                           # Dir in simulator_group for dmaap mr for - docker-compose
old mode 100644 (file)
new mode 100755 (executable)
index 8ab85f0..b738755
@@ -237,10 +237,10 @@ MR_DMAAP_LOCALHOST_PORT=3904                             # MR stub container ext
 MR_STUB_LOCALHOST_PORT=3908                              # MR stub container external port (host -> container)
 MR_DMAAP_LOCALHOST_SECURE_PORT=3905                      # MR stub container internal port (container -> container)
 MR_STUB_LOCALHOST_SECURE_PORT=3909                       # MR stub container external secure port (host -> container)
-MR_READ_URL="/events/A1-POLICY-AGENT-READ/users/policy-agent?timeout=15000&limit=100" # Path to read messages from MR
-MR_WRITE_URL="/events/A1-POLICY-AGENT-WRITE"             # Path write messages to MR
 MR_READ_TOPIC="A1-POLICY-AGENT-READ"                     # Read topic
 MR_WRITE_TOPIC="A1-POLICY-AGENT-WRITE"                   # Write topic
+MR_READ_URL="/events/$MR_READ_TOPIC/users/policy-agent?timeout=15000&limit=100" # Path to read messages from MR
+MR_WRITE_URL="/events/$MR_WRITE_TOPIC"                   # Path to write messages to MR
 MR_STUB_ALIVE_URL="/"                                    # Base path for mr stub alive check
 MR_DMAAP_ALIVE_URL="/topics"                             # Base path for dmaap-mr alive check
 MR_DMAAP_COMPOSE_DIR="dmaapmr"                           # Dir in simulator_group for dmaap mr for - docker-compose
index a59c0e0..9039b8d 100755 (executable)
@@ -240,10 +240,10 @@ MR_DMAAP_LOCALHOST_PORT=3904                             # MR stub container ext
 MR_STUB_LOCALHOST_PORT=3908                              # MR stub container external port (host -> container)
 MR_DMAAP_LOCALHOST_SECURE_PORT=3905                      # MR stub container internal port (container -> container)
 MR_STUB_LOCALHOST_SECURE_PORT=3909                       # MR stub container external secure port (host -> container)
-MR_READ_URL="/events/A1-POLICY-AGENT-READ/users/policy-agent?timeout=15000&limit=100" # Path to read messages from MR
-MR_WRITE_URL="/events/A1-POLICY-AGENT-WRITE"             # Path write messages to MR
 MR_READ_TOPIC="A1-POLICY-AGENT-READ"                     # Read topic
 MR_WRITE_TOPIC="A1-POLICY-AGENT-WRITE"                   # Write topic
+MR_READ_URL="/events/$MR_READ_TOPIC/users/policy-agent?timeout=15000&limit=100" # Path to read messages from MR
+MR_WRITE_URL="/events/$MR_WRITE_TOPIC"                   # Path to write messages to MR
 MR_STUB_ALIVE_URL="/"                                    # Base path for mr stub alive check
 MR_DMAAP_ALIVE_URL="/topics"                             # Base path for dmaap-mr alive check
 MR_DMAAP_COMPOSE_DIR="dmaapmr"                           # Dir in simulator_group for dmaap mr for - docker-compose
index 7ecd434..9dedf75 100755 (executable)
@@ -260,10 +260,10 @@ MR_DMAAP_LOCALHOST_PORT=3904                             # MR stub container ext
 MR_STUB_LOCALHOST_PORT=3908                              # MR stub container external port (host -> container)
 MR_DMAAP_LOCALHOST_SECURE_PORT=3905                      # MR stub container internal port (container -> container)
 MR_STUB_LOCALHOST_SECURE_PORT=3909                       # MR stub container external secure port (host -> container)
-MR_READ_URL="/events/A1-POLICY-AGENT-READ/users/policy-agent?timeout=15000&limit=100" # Path to read messages from MR
-MR_WRITE_URL="/events/A1-POLICY-AGENT-WRITE"             # Path write messages to MR
 MR_READ_TOPIC="A1-POLICY-AGENT-READ"                     # Read topic
 MR_WRITE_TOPIC="A1-POLICY-AGENT-WRITE"                   # Write topic
+MR_READ_URL="/events/$MR_READ_TOPIC/users/policy-agent?timeout=15000&limit=100" # Path to read messages from MR
+MR_WRITE_URL="/events/$MR_WRITE_TOPIC"                   # Path to write messages to MR
 MR_STUB_ALIVE_URL="/"                                    # Base path for mr stub alive check
 MR_DMAAP_ALIVE_URL="/topics"                             # Base path for dmaap-mr alive check
 MR_DMAAP_COMPOSE_DIR="dmaapmr"                           # Dir in simulator_group for dmaap mr for - docker-compose
index db13fc0..40707d6 100644 (file)
@@ -168,7 +168,7 @@ def create_message(operation, correlation_id, payload, url):
 ### MR-stub interface, for MR control
 
 # Send a message to MR
-# URI and parameters (GET): /send-request?operation=<GET|PUT|POST|DELETE>&url=<url>
+# URI and parameters (PUT or POST): /send-request?operation=<GET|PUT|POST|DELETE>&url=<url>
 # response: <correlation-id> (http 200) o4 400 for parameter error or 500 for other errors
 @app.route(APP_WRITE_URL,
     methods=['PUT','POST'])
@@ -421,4 +421,4 @@ else:
     print("No env variables - OK")
 
 if __name__ == "__main__":
-    app.run(port=HOST_PORT, host=HOST_IP)
\ No newline at end of file
+    app.run(port=HOST_PORT, host=HOST_IP)