NONRTRIC - Adding information consumer before information type 06/5906/1
authorPatrikBuhr <patrik.buhr@est.tech>
Mon, 19 Apr 2021 09:18:25 +0000 (11:18 +0200)
committerPatrikBuhr <patrik.buhr@est.tech>
Mon, 19 Apr 2021 09:20:22 +0000 (11:20 +0200)
Adding support for adding data consumers before the data type is
registered. When the information type unknown for ECS, the parameters of the subscription cannot be valid.
Turning on/off this type, check is controlled by a query parameter in the
PUT consumer primitive.

Change-Id: I8279351633e8bead89d965df723de745b05f5ba4
Signed-off-by: PatrikBuhr <patrik.buhr@est.tech>
Issue-ID: NONRTRIC-493

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

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");