X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=enrichment-coordinator-service%2Fsrc%2Fmain%2Fjava%2Forg%2Foransc%2Fenrichment%2Fcontrollers%2Fconsumer%2FConsumerController.java;h=39796ee1a2c7703718653d8f68e9dea5a2440577;hb=b5cb68ea0e77d0a1421b4f17cc58b981628c29f7;hp=a74e487494b0c61d12e885b32652adddef352507;hpb=a41966b2da6d7f74d4f486bc1492a5cbb5866583;p=nonrtric.git diff --git a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/consumer/ConsumerController.java b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/consumer/ConsumerController.java index a74e4874..39796ee1 100644 --- a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/consumer/ConsumerController.java +++ b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/consumer/ConsumerController.java @@ -1,9 +1,9 @@ /*- * ========================LICENSE_START================================= - * ONAP : ccsdk oran - * ====================================================================== - * Copyright (C) 2019-2020 Nordix Foundation. All rights reserved. - * ====================================================================== + * 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 @@ -30,7 +30,6 @@ import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; -import java.lang.invoke.MethodHandles; import java.util.ArrayList; import java.util.List; @@ -40,14 +39,13 @@ import org.json.JSONObject; import org.oransc.enrichment.clients.ProducerCallbacks; import org.oransc.enrichment.configuration.ApplicationConfig; import org.oransc.enrichment.controllers.ErrorResponse; +import org.oransc.enrichment.controllers.VoidResponse; import org.oransc.enrichment.exceptions.ServiceException; import org.oransc.enrichment.repository.EiJob; import org.oransc.enrichment.repository.EiJobs; import org.oransc.enrichment.repository.EiType; import org.oransc.enrichment.repository.EiTypes; import org.oransc.enrichment.repository.ImmutableEiJob; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -57,15 +55,15 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; @SuppressWarnings("java:S3457") // No need to call "toString()" method as formatting and string .. @RestController("ConsumerController") @Api(tags = {ConsumerConsts.CONSUMER_API_NAME}) public class ConsumerController { - private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - @Autowired ApplicationConfig applicationConfig; @@ -143,12 +141,20 @@ public class ConsumerController { name = ConsumerConsts.OWNER_PARAM, required = false, // value = ConsumerConsts.OWNER_PARAM_DESCRIPTION) // - String owner) { + @RequestParam(name = ConsumerConsts.OWNER_PARAM, required = false) String owner) { try { this.eiTypes.getType(eiTypeId); // Just to check that the type exists List result = new ArrayList<>(); - for (EiJob job : this.eiJobs.getJobsForType(eiTypeId)) { - result.add(job.id()); + if (owner != null) { + for (EiJob job : this.eiJobs.getJobsForOwner(owner)) { + if (eiTypeId == null || job.type().getId().equals(eiTypeId)) { + result.add(job.id()); + } + } + } else { + for (EiJob job : this.eiJobs.getJobsForType(eiTypeId)) { + result.add(job.id()); + } } return new ResponseEntity<>(gson.toJson(result), HttpStatus.OK); } catch (Exception e) { @@ -213,8 +219,8 @@ public class ConsumerController { @ApiOperation(value = "Individual EI Job", notes = "") @ApiResponses( value = { // - @ApiResponse(code = 200, message = "Not used", response = void.class), - @ApiResponse(code = 204, message = "Job deleted", response = void.class), + @ApiResponse(code = 200, message = "Not used", response = VoidResponse.class), + @ApiResponse(code = 204, message = "Job deleted", response = VoidResponse.class), @ApiResponse( code = 404, message = "Enrichment Information type or job is not found", @@ -239,47 +245,68 @@ public class ConsumerController { @ApiOperation(value = "Individual EI Job", notes = "") @ApiResponses( value = { // - @ApiResponse(code = 201, message = "Job created", response = void.class), // - @ApiResponse(code = 200, message = "Job updated", response = void.class), // , + @ApiResponse(code = 201, message = "Job created", response = VoidResponse.class), // + @ApiResponse(code = 200, message = "Job updated", response = VoidResponse.class), // , @ApiResponse( code = 404, message = "Enrichment Information type is not found", response = ErrorResponse.ErrorInfo.class)}) - public ResponseEntity putIndividualEiJob( // + public Mono> putIndividualEiJob( // @PathVariable("eiTypeId") String eiTypeId, // @PathVariable("eiJobId") String eiJobId, // @RequestBody ConsumerEiJobInfo eiJobInfo) { + + final boolean isNewJob = this.eiJobs.get(eiJobId) == null; + + return validatePutEiJob(eiTypeId, eiJobId, eiJobInfo) // + .flatMap(this::notifyProducersNewJob) // + .doOnNext(newEiJob -> this.eiJobs.put(newEiJob)) // + .flatMap(newEiJob -> Mono.just(new ResponseEntity<>(isNewJob ? HttpStatus.CREATED : HttpStatus.OK))) + .onErrorResume(throwable -> Mono.just(ErrorResponse.create(throwable, HttpStatus.NOT_FOUND))); + } + + private Mono notifyProducersNewJob(EiJob newEiJob) { + return this.producerCallbacks.notifyProducersJobStarted(newEiJob) // + .flatMap(noOfAcceptingProducers -> { + if (noOfAcceptingProducers.intValue() > 0) { + return Mono.just(newEiJob); + } else { + return Mono.error(new ServiceException("Job not accepted by any producers", HttpStatus.CONFLICT)); + } + }); + } + + private Mono validatePutEiJob(String eiTypeId, String eiJobId, ConsumerEiJobInfo eiJobInfo) { try { EiType eiType = this.eiTypes.getType(eiTypeId); - validateJobData(eiType.getJobDataSchema(), eiJobInfo.jobData); - final boolean newJob = this.eiJobs.get(eiJobId) == null; - EiJob eiJob = toEiJob(eiJobInfo, eiJobId, eiType); - this.eiJobs.put(eiJob); - this.producerCallbacks.notifyProducersJobCreated(eiJob); - return new ResponseEntity<>(newJob ? HttpStatus.CREATED : HttpStatus.OK); + validateJsonObjectAgainstSchema(eiType.getJobDataSchema(), eiJobInfo.jobData); + EiJob existingEiJob = this.eiJobs.get(eiJobId); + + if (existingEiJob != null && !existingEiJob.type().getId().equals(eiTypeId)) { + throw new ServiceException("Not allowed to change type for existing EI job", HttpStatus.CONFLICT); + } + return Mono.just(toEiJob(eiJobInfo, eiJobId, eiType)); } catch (Exception e) { - return ErrorResponse.create(e, HttpStatus.NOT_FOUND); + return Mono.error(e); } } - private void validateJobData(Object schemaObj, Object object) throws ServiceException { - if (schemaObj == null) { - return; // schema is optional for now - } - try { - ObjectMapper mapper = new ObjectMapper(); + private void validateJsonObjectAgainstSchema(Object schemaObj, Object object) throws ServiceException { + if (schemaObj != null) { // schema is optional for now + try { + ObjectMapper mapper = new ObjectMapper(); - String schemaAsString = mapper.writeValueAsString(schemaObj); - JSONObject schemaJSON = new JSONObject(schemaAsString); - Schema schema = SchemaLoader.load(schemaJSON); + String schemaAsString = mapper.writeValueAsString(schemaObj); + JSONObject schemaJSON = new JSONObject(schemaAsString); + Schema schema = SchemaLoader.load(schemaJSON); - String objectAsString = mapper.writeValueAsString(object); - JSONObject json = new JSONObject(objectAsString); - schema.validate(json); - } catch (Exception e) { - throw new ServiceException("Json validation failure", e); + String objectAsString = mapper.writeValueAsString(object); + JSONObject json = new JSONObject(objectAsString); + schema.validate(json); + } catch (Exception e) { + throw new ServiceException("Json validation failure " + e.toString(), HttpStatus.CONFLICT); + } } - } // Status TBD @@ -290,6 +317,7 @@ public class ConsumerController { .type(type) // .owner(info.owner) // .jobData(info.jobData) // + .targetUri(info.targetUri) // .build(); } @@ -298,6 +326,6 @@ public class ConsumerController { } private ConsumerEiJobInfo toEiJobInfo(EiJob s) { - return new ConsumerEiJobInfo(s.jobData(), s.owner()); + return new ConsumerEiJobInfo(s.jobData(), s.owner(), s.targetUri()); } }