From 2a88005a4b62628df36c8c187b435c2dda89828e Mon Sep 17 00:00:00 2001 From: PatrikBuhr Date: Mon, 19 Apr 2021 11:18:25 +0200 Subject: [PATCH] NONRTRIC - Adding information consumer before information type 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 Issue-ID: NONRTRIC-493 --- enrichment-coordinator-service/api/ecs-api.json | 25 +++++++++++++----- enrichment-coordinator-service/api/ecs-api.yaml | 11 ++++++++ .../controllers/r1consumer/ConsumerConsts.java | 6 +++++ .../controllers/r1consumer/ConsumerController.java | 30 ++++++++++++++++------ .../org/oransc/enrichment/ApplicationTest.java | 17 +++++++++++- 5 files changed, 74 insertions(+), 15 deletions(-) diff --git a/enrichment-coordinator-service/api/ecs-api.json b/enrichment-coordinator-service/api/ecs-api.json index 06f6ac14..3d6882aa 100644 --- a/enrichment-coordinator-service/api/ecs-api.json +++ b/enrichment-coordinator-service/api/ecs-api.json @@ -706,6 +706,7 @@ "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": { @@ -721,12 +722,24 @@ "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"] } }, diff --git a/enrichment-coordinator-service/api/ecs-api.yaml b/enrichment-coordinator-service/api/ecs-api.yaml index f94743e2..3eda306a 100644 --- a/enrichment-coordinator-service/api/ecs-api.yaml +++ b/enrichment-coordinator-service/api/ecs-api.yaml @@ -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: diff --git a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/r1consumer/ConsumerConsts.java b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/r1consumer/ConsumerConsts.java index 656808f9..6ddd5834 100644 --- a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/r1consumer/ConsumerConsts.java +++ b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/r1consumer/ConsumerConsts.java @@ -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() { } } diff --git a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/r1consumer/ConsumerController.java b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/r1consumer/ConsumerController.java index 7a1bf184..e93d9cbd 100644 --- a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/r1consumer/ConsumerController.java +++ b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/r1consumer/ConsumerController.java @@ -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> 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 validatePutInfoJob(String jobId, ConsumerJobInfo jobInfo) { + private Mono 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()); } diff --git a/enrichment-coordinator-service/src/test/java/org/oransc/enrichment/ApplicationTest.java b/enrichment-coordinator-service/src/test/java/org/oransc/enrichment/ApplicationTest.java index 45961416..9d55940e 100644 --- a/enrichment-coordinator-service/src/test/java/org/oransc/enrichment/ApplicationTest.java +++ b/enrichment-coordinator-service/src/test/java/org/oransc/enrichment/ApplicationTest.java @@ -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 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"); -- 2.16.6