From: PatrikBuhr Date: Thu, 21 Oct 2021 10:40:22 +0000 (+0200) Subject: NONRTRIC - Enrichment Coordinator Service, Changed error codes X-Git-Tag: 1.2.0~70^2 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=4cd9f067e6985a28c045dd672bd86581b8b5b1a9;p=nonrtric.git NONRTRIC - Enrichment Coordinator Service, Changed error codes Changed HTTP error codes Signed-off-by: PatrikBuhr Issue-ID: NONRTRIC-594 Change-Id: Ic82bc3ca39df3a4d63aac57becb4f8d4713933cd --- diff --git a/enrichment-coordinator-service/api/ecs-api.json b/enrichment-coordinator-service/api/ecs-api.json index 0e8164ef..7da2270b 100644 --- a/enrichment-coordinator-service/api/ecs-api.json +++ b/enrichment-coordinator-service/api/ecs-api.json @@ -421,7 +421,7 @@ "description": "Information type is not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProblemDetails"}}} }, - "406": { + "409": { "description": "The Information type has one or several active producers", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProblemDetails"}}} } @@ -451,7 +451,7 @@ "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Void"}}} }, "400": { - "description": "Bad request", + "description": "Input validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProblemDetails"}}} } }, @@ -635,8 +635,12 @@ "description": "Producer created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Void"}}} }, + "400": { + "description": "Input validation failed", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProblemDetails"}}} + }, "404": { - "description": "Producer not found", + "description": "Producer type not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProblemDetails"}}} } }, @@ -741,9 +745,17 @@ "description": "Job created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Void"}}} }, + "400": { + "description": "Input validation failed", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProblemDetails"}}} + }, "404": { "description": "Enrichment Information type is not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProblemDetails"}}} + }, + "409": { + "description": "Cannot modify job type", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProblemDetails"}}} } }, "parameters": [{ @@ -854,9 +866,17 @@ "description": "Job created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Void"}}} }, + "400": { + "description": "Input validation failed", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProblemDetails"}}} + }, "404": { "description": "Information type is not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProblemDetails"}}} + }, + "409": { + "description": "Cannot modify job type", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProblemDetails"}}} } }, "parameters": [ diff --git a/enrichment-coordinator-service/api/ecs-api.yaml b/enrichment-coordinator-service/api/ecs-api.yaml index 3445edee..c4463b02 100644 --- a/enrichment-coordinator-service/api/ecs-api.yaml +++ b/enrichment-coordinator-service/api/ecs-api.yaml @@ -189,7 +189,7 @@ paths: schema: $ref: '#/components/schemas/Void' 400: - description: Bad request + description: Input validation failed content: application/json: schema: @@ -226,7 +226,7 @@ paths: application/json: schema: $ref: '#/components/schemas/ProblemDetails' - 406: + 409: description: The Information type has one or several active producers content: application/json: @@ -429,8 +429,14 @@ paths: application/json: schema: $ref: '#/components/schemas/Void' + 400: + description: Input validation failed + content: + application/json: + schema: + $ref: '#/components/schemas/ProblemDetails' 404: - description: Producer not found + description: Producer type not found content: application/json: schema: @@ -564,12 +570,24 @@ paths: application/json: schema: $ref: '#/components/schemas/Void' + 400: + description: Input validation failed + content: + application/json: + schema: + $ref: '#/components/schemas/ProblemDetails' 404: description: Enrichment Information type is not found content: application/json: schema: $ref: '#/components/schemas/ProblemDetails' + 409: + description: Cannot modify job type + content: + application/json: + schema: + $ref: '#/components/schemas/ProblemDetails' delete: tags: - A1-EI (registration) @@ -711,12 +729,24 @@ paths: application/json: schema: $ref: '#/components/schemas/Void' + 400: + description: Input validation failed + content: + application/json: + schema: + $ref: '#/components/schemas/ProblemDetails' 404: description: Information type is not found content: application/json: schema: $ref: '#/components/schemas/ProblemDetails' + 409: + description: Cannot modify job type + content: + application/json: + schema: + $ref: '#/components/schemas/ProblemDetails' delete: tags: - Data consumer diff --git a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/a1e/A1eController.java b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/a1e/A1eController.java index 5f796b8d..9609e276 100644 --- a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/a1e/A1eController.java +++ b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/a1e/A1eController.java @@ -277,8 +277,18 @@ public class A1eController { @ApiResponse( responseCode = "404", description = "Enrichment Information type is not found", // - content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))) // + content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))), + @ApiResponse( + responseCode = "400", + description = "Input validation failed", // + content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))), // + @ApiResponse( + responseCode = "409", + description = "Cannot modify job type", // + content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))) + }) + public Mono> putIndividualEiJob( // @PathVariable("eiJobId") String eiJobId, // @RequestBody A1eEiJobInfo eiJobObject) { @@ -289,7 +299,7 @@ public class A1eController { .flatMap(this::startEiJob) // .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))); + .onErrorResume(throwable -> Mono.just(ErrorResponse.create(throwable, HttpStatus.INTERNAL_SERVER_ERROR))); } private Mono startEiJob(InfoJob newEiJob) { @@ -320,7 +330,7 @@ public class A1eController { if (url != null && !url.isEmpty()) { URI uri = new URI(url); if (!uri.isAbsolute()) { - throw new ServiceException("URI: " + url + " is not absolute", HttpStatus.CONFLICT); + throw new ServiceException("URI: " + url + " is not absolute", HttpStatus.BAD_REQUEST); } } } @@ -338,7 +348,7 @@ public class A1eController { JSONObject json = new JSONObject(objectAsString); schema.validate(json); } catch (Exception e) { - throw new ServiceException("Json validation failure " + e.toString(), HttpStatus.CONFLICT); + throw new ServiceException("Json validation failure " + e.toString(), HttpStatus.BAD_REQUEST); } } } 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 9de57d5b..47a4a2ec 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 @@ -282,8 +282,15 @@ public class ConsumerController { @ApiResponse( responseCode = "404", description = "Information type is not found", // - content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))) // - }) + content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))), // + @ApiResponse( + responseCode = "400", + description = "Input validation failed", // + content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))), // + @ApiResponse( + responseCode = "409", + description = "Cannot modify job type", // + content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class)))}) public Mono> putIndividualInfoJob( // @PathVariable("infoJobId") String jobId, // @Parameter( @@ -460,7 +467,7 @@ public class ConsumerController { if (url != null && !url.isEmpty()) { URI uri = new URI(url); if (!uri.isAbsolute()) { - throw new ServiceException("URI: " + url + " is not absolute", HttpStatus.CONFLICT); + throw new ServiceException("URI: " + url + " is not absolute", HttpStatus.BAD_REQUEST); } } } @@ -478,7 +485,7 @@ public class ConsumerController { JSONObject json = new JSONObject(objectAsString); schema.validate(json); } catch (Exception e) { - throw new ServiceException("Json validation failure " + e.toString(), HttpStatus.CONFLICT); + throw new ServiceException("Json validation failure " + e.toString(), HttpStatus.BAD_REQUEST); } } } diff --git a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/r1producer/ProducerController.java b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/r1producer/ProducerController.java index 0aa6974e..cad6a042 100644 --- a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/r1producer/ProducerController.java +++ b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/controllers/r1producer/ProducerController.java @@ -138,7 +138,7 @@ public class ProducerController { content = @Content(schema = @Schema(implementation = VoidResponse.class))), // @ApiResponse( responseCode = "400", - description = "Bad request", // + description = "Input validation failed", // content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class)))}) @Operation(summary = "Individual Information Type", description = "") public ResponseEntity putInfoType( // @@ -175,7 +175,7 @@ public class ProducerController { description = "Information type is not found", // content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))), // @ApiResponse( - responseCode = "406", + responseCode = "409", description = "The Information type has one or several active producers", // content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))) // }) @@ -188,7 +188,7 @@ public class ProducerController { } if (!this.infoProducers.getProducersForType(type).isEmpty()) { String firstProducerId = this.infoProducers.getProducersForType(type).iterator().next().getId(); - return ErrorResponse.create("The type has active producers: " + firstProducerId, HttpStatus.NOT_ACCEPTABLE); + return ErrorResponse.create("The type has active producers: " + firstProducerId, HttpStatus.CONFLICT); } this.infoTypes.remove(type); infoJobs.getJobsForType(type).forEach(job -> infoJobs.remove(job, infoProducers)); // Delete jobs for the type @@ -329,7 +329,11 @@ public class ProducerController { content = @Content(schema = @Schema(implementation = VoidResponse.class))), // @ApiResponse( responseCode = "404", - description = "Producer not found", // + description = "Producer type not found", // + content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))), // + @ApiResponse( + responseCode = "400", + description = "Input validation failed", // content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))) // }) public ResponseEntity putInfoProducer( // @@ -341,19 +345,23 @@ public class ProducerController { InfoProducer previousDefinition = this.infoProducers.get(infoProducerId); this.infoProducers.registerProducer(toProducerRegistrationInfo(infoProducerId, registrationInfo)); return new ResponseEntity<>(previousDefinition == null ? HttpStatus.CREATED : HttpStatus.OK); - } catch (Exception e) { - return ErrorResponse.create(e, HttpStatus.NOT_FOUND); + } catch (ServiceException e) { + return ErrorResponse.create(e, e.getHttpStatus()); } } - private void validateUri(String url) throws URISyntaxException, ServiceException { + private void validateUri(String url) throws ServiceException { if (url != null && !url.isEmpty()) { - URI uri = new URI(url); - if (!uri.isAbsolute()) { - throw new ServiceException("URI: " + url + " is not absolute", HttpStatus.CONFLICT); + try { + URI uri = new URI(url); + if (!uri.isAbsolute()) { + throw new ServiceException("URI: " + url + " is not absolute", HttpStatus.BAD_REQUEST); + } + } catch (URISyntaxException e) { + throw new ServiceException(e.getMessage(), HttpStatus.BAD_REQUEST); } } else { - throw new ServiceException("Missing required URL", HttpStatus.CONFLICT); + throw new ServiceException("Missing required URL", HttpStatus.BAD_REQUEST); } } @@ -381,8 +389,8 @@ public class ProducerController { final InfoProducer producer = this.infoProducers.getProducer(infoProducerId); this.infoProducers.deregisterProducer(producer); return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } catch (Exception e) { - return ErrorResponse.create(e, HttpStatus.NOT_FOUND); + } catch (ServiceException e) { + return ErrorResponse.create(e, e.getHttpStatus()); } } diff --git a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/exceptions/ServiceException.java b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/exceptions/ServiceException.java index ffccf806..bce786f9 100644 --- a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/exceptions/ServiceException.java +++ b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/exceptions/ServiceException.java @@ -28,11 +28,6 @@ public class ServiceException extends Exception { @Getter private final HttpStatus httpStatus; - public ServiceException(String message) { - super(message); - this.httpStatus = null; - } - public ServiceException(String message, Exception originalException) { super(message, originalException); this.httpStatus = null; diff --git a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/InfoJobs.java b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/InfoJobs.java index 52fa1d6d..7469e08f 100644 --- a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/InfoJobs.java +++ b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/InfoJobs.java @@ -43,6 +43,7 @@ import org.oransc.enrichment.controllers.r1producer.ProducerCallbacks; import org.oransc.enrichment.exceptions.ServiceException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; import org.springframework.util.FileSystemUtils; /** @@ -91,7 +92,7 @@ public class InfoJobs { public synchronized InfoJob getJob(String id) throws ServiceException { InfoJob ric = allEiJobs.get(id); if (ric == null) { - throw new ServiceException("Could not find Information job: " + id); + throw new ServiceException("Could not find Information job: " + id, HttpStatus.NOT_FOUND); } return ric; } diff --git a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/InfoProducers.java b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/InfoProducers.java index 57e7922c..1102e36a 100644 --- a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/InfoProducers.java +++ b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/InfoProducers.java @@ -36,6 +36,7 @@ import org.oransc.enrichment.exceptions.ServiceException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; /** @@ -110,7 +111,7 @@ public class InfoProducers { public synchronized InfoProducer getProducer(String id) throws ServiceException { InfoProducer p = allEiProducers.get(id); if (p == null) { - throw new ServiceException("Could not find Information Producer: " + id); + throw new ServiceException("Could not find Information Producer: " + id, HttpStatus.NOT_FOUND); } return p; } diff --git a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/InfoTypeSubscriptions.java b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/InfoTypeSubscriptions.java index 2d6da4f5..65978e15 100644 --- a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/InfoTypeSubscriptions.java +++ b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/InfoTypeSubscriptions.java @@ -47,6 +47,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpStatus; import org.springframework.util.FileSystemUtils; import reactor.core.publisher.Flux; @@ -118,7 +119,7 @@ public class InfoTypeSubscriptions { public synchronized SubscriptionInfo getSubscription(String id) throws ServiceException { SubscriptionInfo p = allSubscriptions.get(id); if (p == null) { - throw new ServiceException("Could not find Information subscription: " + id); + throw new ServiceException("Could not find Information subscription: " + id, HttpStatus.NOT_FOUND); } return p; } @@ -196,7 +197,8 @@ public class InfoTypeSubscriptions { private Mono error() { return Mono.error(new ServiceException( - "No notifyTypeRegistered handler found for interface version " + apiVersion)); + "No notifyTypeRegistered handler found for interface version " + apiVersion, + HttpStatus.INTERNAL_SERVER_ERROR)); } }; } diff --git a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/InfoTypes.java b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/InfoTypes.java index 85664f6b..c23875b6 100644 --- a/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/InfoTypes.java +++ b/enrichment-coordinator-service/src/main/java/org/oransc/enrichment/repository/InfoTypes.java @@ -42,6 +42,7 @@ import org.oransc.enrichment.configuration.ApplicationConfig; import org.oransc.enrichment.exceptions.ServiceException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; import org.springframework.util.FileSystemUtils; /** @@ -84,7 +85,7 @@ public class InfoTypes { public synchronized InfoType getType(String id) throws ServiceException { InfoType type = allEiTypes.get(id); if (type == null) { - throw new ServiceException("Information type not found: " + id); + throw new ServiceException("Information type not found: " + id, HttpStatus.NOT_FOUND); } return type; } 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 4d64ef65..44184296 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 @@ -490,7 +490,10 @@ class ApplicationTest { "targetUri", "jobStatusUrl"); String body = gson.toJson(jobInfo); - testErrorCode(restClient().put(url, body), HttpStatus.CONFLICT, "Json validation failure"); + testErrorCode(restClient().put(url, body), HttpStatus.BAD_REQUEST, "Json validation failure"); + + testErrorCode(restClient().put(url, "{jojo}"), HttpStatus.BAD_REQUEST, "", false); + } @Test @@ -503,7 +506,7 @@ class ApplicationTest { new ConsumerJobInfo("typeId", jsonObject("{ \"XXstring\" : \"value\" }"), "owner", "targetUri", null); String body = gson.toJson(jobInfo); - testErrorCode(restClient().put(url, body), HttpStatus.CONFLICT, "Json validation failure"); + testErrorCode(restClient().put(url, body), HttpStatus.BAD_REQUEST, "Json validation failure"); } @Test @@ -515,7 +518,7 @@ class ApplicationTest { ConsumerJobInfo jobInfo = new ConsumerJobInfo(TYPE_ID, jsonObject(), "owner", "junk", null); String body = gson.toJson(jobInfo); - testErrorCode(restClient().put(url, body), HttpStatus.CONFLICT, "URI: junk is not absolute"); + testErrorCode(restClient().put(url, body), HttpStatus.BAD_REQUEST, "URI: junk is not absolute"); } @Test @@ -552,6 +555,8 @@ class ApplicationTest { String url = ProducerConsts.API_ROOT + "/info-types/" + TYPE_ID; String body = "{}"; testErrorCode(restClient().put(url, body), HttpStatus.BAD_REQUEST, "No schema provided"); + + testErrorCode(restClient().post(url, body), HttpStatus.METHOD_NOT_ALLOWED, "", false); } @Test @@ -572,8 +577,7 @@ class ApplicationTest { void producerDeleteEiTypeExistingProducer() throws Exception { putInfoProducerWithOneType(PRODUCER_ID, TYPE_ID); String url = ProducerConsts.API_ROOT + "/info-types/" + TYPE_ID; - testErrorCode(restClient().delete(url), HttpStatus.NOT_ACCEPTABLE, - "The type has active producers: " + PRODUCER_ID); + testErrorCode(restClient().delete(url), HttpStatus.CONFLICT, "The type has active producers: " + PRODUCER_ID); assertThat(this.infoTypes.size()).isEqualTo(1); }