From b091107d15598b61e8cb73b9d65c04c283830da1 Mon Sep 17 00:00:00 2001 From: Ken Zangelin Date: Thu, 31 Aug 2023 10:43:06 +0200 Subject: [PATCH] Changed all error codes from InvalidRequest to BadRequestData, except for JSON Parse Error that is still an InvalidRequest --- CHANGES_NEXT_RELEASE | 1 + .../httpStatusCodeToOrionldErrorType.cpp | 12 +- .../orionld/mongoc/mongocEntitiesQuery.cpp | 2 +- src/lib/orionld/payloadCheck/pCheckGeorel.cpp | 6 +- .../payloadCheck/pCheckGeorelString.cpp | 14 +- .../rest/orionldMhdConnectionTreat.cpp | 10 +- ...ions=replace_payload_error_validation.test | 2 +- ..._upsert-options=update_error_handling.test | 2 +- ...post_operations_create_error_handling.test | 2 +- ...post_operations_update_error_handling.test | 2 +- .../cases/0000_ngsild/ngsild_issue_0029.test | 8 +- .../cases/0000_ngsild/ngsild_issue_0504.test | 2 +- .../ngsild_issue_1419-patch_attributes.test | 159 ++++++++++++++++++ ...ions=replace_payload_error_validation.test | 2 +- ..._upsert-options=update_error_handling.test | 2 +- ...post_operations_create_error_handling.test | 2 +- ...post_operations_update_error_handling.test | 2 +- .../0000_ngsild/ngsild_new_issue_0504.test | 2 +- .../ngsild_new_post_query_error_handling.test | 2 +- .../0000_ngsild/ngsild_post_query_errors.test | 2 +- .../0000_ngsild/ngsild_put_entity-errors.test | 2 +- 21 files changed, 199 insertions(+), 39 deletions(-) create mode 100644 test/functionalTest/cases/0000_ngsild/ngsild_issue_1419-patch_attributes.test diff --git a/CHANGES_NEXT_RELEASE b/CHANGES_NEXT_RELEASE index 2638836662..9ce3b19d16 100644 --- a/CHANGES_NEXT_RELEASE +++ b/CHANGES_NEXT_RELEASE @@ -2,3 +2,4 @@ Fixed issues: * #1419 - Fixed a bug in the cleanup of the "URL being downloaded list" - not being cleaned up in case of an error * #280 - Added extensive logging for downloading of contexts * #280 - Fixed two erroneous type values in the response payload body (EntityTypeInformation => EntityTypeInfo and EntityAttributeList => AttributeList) + * #280 - Changed all error codes from InvalidRequest to BadRequestData, except for JSON Parse Error that is still an InvalidRequest diff --git a/src/lib/orionld/common/httpStatusCodeToOrionldErrorType.cpp b/src/lib/orionld/common/httpStatusCodeToOrionldErrorType.cpp index e92189fa53..48f72de945 100644 --- a/src/lib/orionld/common/httpStatusCodeToOrionldErrorType.cpp +++ b/src/lib/orionld/common/httpStatusCodeToOrionldErrorType.cpp @@ -43,12 +43,12 @@ OrionldResponseErrorType httpStatusCodeToOrionldErrorType(int httpStatusCode) case 400: return OrionldBadRequestData; case 403: return OrionldOperationNotSupported; case 404: return OrionldResourceNotFound; - case 405: return OrionldInvalidRequest; - case 406: return OrionldInvalidRequest; + case 405: return OrionldBadRequestData; + case 406: return OrionldBadRequestData; case 409: return OrionldAlreadyExists; - case 411: return OrionldInvalidRequest; - case 413: return OrionldInvalidRequest; - case 415: return OrionldInvalidRequest; + case 411: return OrionldBadRequestData; + case 413: return OrionldBadRequestData; + case 415: return OrionldBadRequestData; case 422: return OrionldOperationNotSupported; case 470: return OrionldResourceNotFound; case 471: return OrionldBadRequestData; @@ -56,7 +56,7 @@ OrionldResponseErrorType httpStatusCodeToOrionldErrorType(int httpStatusCode) case 473: return OrionldBadRequestData; case 480: return OrionldBadRequestData; case 481: return OrionldBadRequestData; - case 482: return OrionldInvalidRequest; + case 482: return OrionldBadRequestData; case 500: return OrionldInternalError; case 501: return OrionldOperationNotSupported; case 503: return OrionldInternalError; diff --git a/src/lib/orionld/mongoc/mongocEntitiesQuery.cpp b/src/lib/orionld/mongoc/mongocEntitiesQuery.cpp index 9b05ccb0ec..23f5c0ee4a 100644 --- a/src/lib/orionld/mongoc/mongocEntitiesQuery.cpp +++ b/src/lib/orionld/mongoc/mongocEntitiesQuery.cpp @@ -600,7 +600,7 @@ static bool geoOverlapsFilter(bson_t* mongoFilterP, OrionldGeoInfo* geoInfoP) // static bool geoContainsFilter(bson_t* mongoFilterP, OrionldGeoInfo* geoInfoP) { - orionldError(OrionldInvalidRequest, "Not Implemented", "georel 'contains' is not supported by mongodb and thus also not by Orion-LD", 501); + orionldError(OrionldOperationNotSupported, "Not Implemented", "georel 'contains' is not supported by mongodb and thus also not by Orion-LD", 501); return false; } diff --git a/src/lib/orionld/payloadCheck/pCheckGeorel.cpp b/src/lib/orionld/payloadCheck/pCheckGeorel.cpp index 3f90cd8545..fc67b4c113 100644 --- a/src/lib/orionld/payloadCheck/pCheckGeorel.cpp +++ b/src/lib/orionld/payloadCheck/pCheckGeorel.cpp @@ -44,17 +44,17 @@ bool pCheckGeorel(KjNode* georelP, OrionldGeoInfo* geoInfoP) { if (georelP == NULL) { - orionldError(OrionldInvalidRequest, "Invalid Geo-Spatial Filter", "georel missing", 400); + orionldError(OrionldBadRequestData, "Invalid Geo-Spatial Filter", "georel missing", 400); return false; } else if (georelP->type != KjString) { - orionldError(OrionldInvalidRequest, "Invalid Geo-Spatial Filter", "georel must be a string", 400); + orionldError(OrionldBadRequestData, "Invalid Geo-Spatial Filter", "georel must be a string", 400); return false; } else if (georelP->value.s[0] == 0) { - orionldError(OrionldInvalidRequest, "Invalid Geo-Spatial Filter", "georel value is empty", 400); + orionldError(OrionldBadRequestData, "Invalid Geo-Spatial Filter", "georel value is empty", 400); return false; } diff --git a/src/lib/orionld/payloadCheck/pCheckGeorelString.cpp b/src/lib/orionld/payloadCheck/pCheckGeorelString.cpp index b3122e1697..d98935832f 100644 --- a/src/lib/orionld/payloadCheck/pCheckGeorelString.cpp +++ b/src/lib/orionld/payloadCheck/pCheckGeorelString.cpp @@ -63,7 +63,7 @@ bool pCheckGeorelString(const char* georel, OrionldGeoInfo* geoInfoP) { if (geoInfoP->geometry != GeoPoint) { - orionldError(OrionldInvalidRequest, "Invalid Geo-Spatial filter", "Geometry must be 'Point' for georel 'near'", 400); + orionldError(OrionldBadRequestData, "Invalid Geo-Spatial filter", "Geometry must be 'Point' for georel 'near'", 400); return false; } } @@ -71,7 +71,7 @@ bool pCheckGeorelString(const char* georel, OrionldGeoInfo* geoInfoP) { if ((geoInfoP->geometry != GeoPolygon) && (geoInfoP->geometry != GeoMultiPolygon)) { - orionldError(OrionldInvalidRequest, "Invalid Geo-Spatial filter", "Geometry must be either 'Polygon' or 'MultiPolygon' for georel 'within'", 400); + orionldError(OrionldBadRequestData, "Invalid Geo-Spatial filter", "Geometry must be either 'Polygon' or 'MultiPolygon' for georel 'within'", 400); return false; } geoInfoP->georel = GeorelWithin; @@ -105,7 +105,7 @@ bool pCheckGeorelString(const char* georel, OrionldGeoInfo* geoInfoP) } else { - orionldError(OrionldInvalidRequest, "Invalid Geo-Spatial filter - invalid 'georel'", georel, 400); + orionldError(OrionldBadRequestData, "Invalid Geo-Spatial filter - invalid 'georel'", georel, 400); return false; } @@ -126,7 +126,7 @@ bool pCheckGeorelString(const char* georel, OrionldGeoInfo* geoInfoP) if (strcmp(grel, "near") != 0) { - orionldError(OrionldInvalidRequest, "Invalid Geo-Spatial filter", "invalid geo-relation for Point", 400); + orionldError(OrionldBadRequestData, "Invalid Geo-Spatial filter", "invalid geo-relation for Point", 400); return false; } geoInfoP->georel = GeorelNear; @@ -138,7 +138,7 @@ bool pCheckGeorelString(const char* georel, OrionldGeoInfo* geoInfoP) if (distance == NULL) { - orionldError(OrionldInvalidRequest, "Invalid Geo-Spatial filter", "no distance for georel 'near' for Point", 400); + orionldError(OrionldBadRequestData, "Invalid Geo-Spatial filter", "no distance for georel 'near' for Point", 400); return false; } *distance = 0; @@ -151,7 +151,7 @@ bool pCheckGeorelString(const char* georel, OrionldGeoInfo* geoInfoP) max = false; else { - orionldError(OrionldInvalidRequest, "Invalid Geo-Spatial filter", "no distance for georel 'near' for Point", 400); + orionldError(OrionldBadRequestData, "Invalid Geo-Spatial filter", "no distance for georel 'near' for Point", 400); return false; } @@ -163,7 +163,7 @@ bool pCheckGeorelString(const char* georel, OrionldGeoInfo* geoInfoP) { if ((*distance < '0') || (*distance > '9')) { - orionldError(OrionldInvalidRequest, "Invalid Geo-Spatial filter", "invalid number for distance for georel 'near' for Point", 400); + orionldError(OrionldBadRequestData, "Invalid Geo-Spatial filter", "invalid number for distance for georel 'near' for Point", 400); return false; } ++distance; diff --git a/src/lib/orionld/rest/orionldMhdConnectionTreat.cpp b/src/lib/orionld/rest/orionldMhdConnectionTreat.cpp index a35d38c7e2..46458f28aa 100644 --- a/src/lib/orionld/rest/orionldMhdConnectionTreat.cpp +++ b/src/lib/orionld/rest/orionldMhdConnectionTreat.cpp @@ -216,14 +216,14 @@ static bool payloadEmptyCheck(void) // No payload? if (orionldState.in.payload == NULL) { - orionldError(OrionldInvalidRequest, "payload missing", NULL, 400); + orionldError(OrionldBadRequestData, "payload missing", NULL, 400); return false; } // Empty payload? if (orionldState.in.payload[0] == 0) { - orionldError(OrionldInvalidRequest, "payload missing", NULL, 400); + orionldError(OrionldBadRequestData, "payload missing", NULL, 400); return false; } @@ -262,7 +262,7 @@ static bool payloadParseAndExtractSpecialFields(bool* contextToBeCashedP) // if ((orionldState.requestTree->type != KjArray) && (orionldState.requestTree->type != KjObject)) { - orionldError(OrionldInvalidRequest, "Invalid Payload", "The payload data must be either a JSON Array or a JSON Object", 400); + orionldError(OrionldBadRequestData, "Invalid Payload", "The payload data must be either a JSON Array or a JSON Object", 400); return false; } @@ -271,7 +271,7 @@ static bool payloadParseAndExtractSpecialFields(bool* contextToBeCashedP) // if ((orionldState.requestTree->type == KjObject) && (orionldState.requestTree->value.firstChildP == NULL)) { - orionldError(OrionldInvalidRequest, "Invalid Payload Body", "Empty Object", 400); + orionldError(OrionldBadRequestData, "Invalid Payload Body", "Empty Object", 400); return false; } @@ -280,7 +280,7 @@ static bool payloadParseAndExtractSpecialFields(bool* contextToBeCashedP) // if ((orionldState.requestTree->type == KjArray) && (orionldState.requestTree->value.firstChildP == NULL)) { - orionldError(OrionldInvalidRequest, "Invalid Payload Body", "Empty Array", 400); + orionldError(OrionldBadRequestData, "Invalid Payload Body", "Empty Array", 400); return false; } diff --git a/test/functionalTest/cases/0000_ngsild/ngsild_batch_upsert-options=replace_payload_error_validation.test b/test/functionalTest/cases/0000_ngsild/ngsild_batch_upsert-options=replace_payload_error_validation.test index deee00c341..5d122e6413 100644 --- a/test/functionalTest/cases/0000_ngsild/ngsild_batch_upsert-options=replace_payload_error_validation.test +++ b/test/functionalTest/cases/0000_ngsild/ngsild_batch_upsert-options=replace_payload_error_validation.test @@ -482,7 +482,7 @@ Date: REGEX(.*) { "detail": "Empty Array", "title": "Invalid Payload Body", - "type": "https://uri.etsi.org/ngsi-ld/errors/InvalidRequest" + "type": "https://uri.etsi.org/ngsi-ld/errors/BadRequestData" } diff --git a/test/functionalTest/cases/0000_ngsild/ngsild_batch_upsert-options=update_error_handling.test b/test/functionalTest/cases/0000_ngsild/ngsild_batch_upsert-options=update_error_handling.test index e9ac579fb3..c75d74b250 100644 --- a/test/functionalTest/cases/0000_ngsild/ngsild_batch_upsert-options=update_error_handling.test +++ b/test/functionalTest/cases/0000_ngsild/ngsild_batch_upsert-options=update_error_handling.test @@ -636,7 +636,7 @@ Date: REGEX(.*) { "detail": "Empty Array", "title": "Invalid Payload Body", - "type": "https://uri.etsi.org/ngsi-ld/errors/InvalidRequest" + "type": "https://uri.etsi.org/ngsi-ld/errors/BadRequestData" } diff --git a/test/functionalTest/cases/0000_ngsild/ngsild_entity_post_operations_create_error_handling.test b/test/functionalTest/cases/0000_ngsild/ngsild_entity_post_operations_create_error_handling.test index 7cf98f5727..4af3238036 100644 --- a/test/functionalTest/cases/0000_ngsild/ngsild_entity_post_operations_create_error_handling.test +++ b/test/functionalTest/cases/0000_ngsild/ngsild_entity_post_operations_create_error_handling.test @@ -558,7 +558,7 @@ Content-Type: application/json Date: REGEX(.*) { - "type": "https://uri.etsi.org/ngsi-ld/errors/InvalidRequest", + "type": "https://uri.etsi.org/ngsi-ld/errors/BadRequestData", "title": "Invalid Payload Body", "detail": "Empty Array" } diff --git a/test/functionalTest/cases/0000_ngsild/ngsild_entity_post_operations_update_error_handling.test b/test/functionalTest/cases/0000_ngsild/ngsild_entity_post_operations_update_error_handling.test index 75d91b5c68..6336e53f99 100644 --- a/test/functionalTest/cases/0000_ngsild/ngsild_entity_post_operations_update_error_handling.test +++ b/test/functionalTest/cases/0000_ngsild/ngsild_entity_post_operations_update_error_handling.test @@ -591,7 +591,7 @@ Content-Type: application/json Date: REGEX(.*) { - "type": "https://uri.etsi.org/ngsi-ld/errors/InvalidRequest", + "type": "https://uri.etsi.org/ngsi-ld/errors/BadRequestData", "title": "Invalid Payload Body", "detail": "Empty Array" } diff --git a/test/functionalTest/cases/0000_ngsild/ngsild_issue_0029.test b/test/functionalTest/cases/0000_ngsild/ngsild_issue_0029.test index 53f121eb79..ff269a2791 100644 --- a/test/functionalTest/cases/0000_ngsild/ngsild_issue_0029.test +++ b/test/functionalTest/cases/0000_ngsild/ngsild_issue_0029.test @@ -72,7 +72,7 @@ Content-Type: application/json Date: REGEX(.*) { - "type": "https://uri.etsi.org/ngsi-ld/errors/InvalidRequest", + "type": "https://uri.etsi.org/ngsi-ld/errors/BadRequestData", "title": "Invalid Payload Body", "detail": "Empty Object" } @@ -87,7 +87,7 @@ Content-Type: application/json Date: REGEX(.*) { - "type": "https://uri.etsi.org/ngsi-ld/errors/InvalidRequest", + "type": "https://uri.etsi.org/ngsi-ld/errors/BadRequestData", "title": "payload missing", "detail": "no detail" } @@ -102,7 +102,7 @@ Content-Type: application/json Date: REGEX(.*) { - "type": "https://uri.etsi.org/ngsi-ld/errors/InvalidRequest", + "type": "https://uri.etsi.org/ngsi-ld/errors/BadRequestData", "title": "payload missing", "detail": "no detail" } @@ -117,7 +117,7 @@ Content-Type: application/json Date: REGEX(.*) { - "type": "https://uri.etsi.org/ngsi-ld/errors/InvalidRequest", + "type": "https://uri.etsi.org/ngsi-ld/errors/BadRequestData", "title": "Invalid Payload Body", "detail": "Empty Array" } diff --git a/test/functionalTest/cases/0000_ngsild/ngsild_issue_0504.test b/test/functionalTest/cases/0000_ngsild/ngsild_issue_0504.test index 9927d0f923..9293313149 100644 --- a/test/functionalTest/cases/0000_ngsild/ngsild_issue_0504.test +++ b/test/functionalTest/cases/0000_ngsild/ngsild_issue_0504.test @@ -51,7 +51,7 @@ Date: REGEX(.*) { "detail": "The payload data must be either a JSON Array or a JSON Object", "title": "Invalid Payload", - "type": "https://uri.etsi.org/ngsi-ld/errors/InvalidRequest" + "type": "https://uri.etsi.org/ngsi-ld/errors/BadRequestData" } diff --git a/test/functionalTest/cases/0000_ngsild/ngsild_issue_1419-patch_attributes.test b/test/functionalTest/cases/0000_ngsild/ngsild_issue_1419-patch_attributes.test new file mode 100644 index 0000000000..29b6b27644 --- /dev/null +++ b/test/functionalTest/cases/0000_ngsild/ngsild_issue_1419-patch_attributes.test @@ -0,0 +1,159 @@ +# Copyright 2023 FIWARE Foundation e.V. +# +# This file is part of Orion-LD Context Broker. +# +# Orion-LD Context Broker is free software: you can redistribute it and/or +# modify it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# Orion-LD Context Broker is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero +# General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Orion-LD Context Broker. If not, see http://www.gnu.org/licenses/. +# +# For those usages not covered by this license please contact with +# orionld at fiware dot org + +# VALGRIND_READY - to mark the test ready for valgrindTestSuite.sh + +--NAME-- +Patching attributes for an entity using different contexts => different longnames for same shortname + +--SHELL-INIT-- +dbInit CB +orionldStart CB + +--SHELL-- + +# +# 01. Create an entity urn:ngsi-ld:Vehicle:4577314217839414 as in issue #1419 +# 02. PATCH the speed attribute using PATCH /entities/*/attrs as in issue #1419 +# 03. Health check, as the issue #1419 indicates the broker crashes during the PATCH +# + +echo "01. Create an entity urn:ngsi-ld:Vehicle:4577314217839414 as in issue #1419" +echo "===========================================================================" +payload='{ + "id": "urn:ngsi-ld:Vehicle:4577314217839414", + "type": "Vehicle", + "brandName": { + "type": "Property", + "value": "Mercedes" + }, + "isParked": { + "type": "Relationship", + "object": "urn:ngsi-ld:OffStreetParking:Downtown1", + "observedAt": "2017-07-29T12:00:04Z", + "providedBy": { + "type": "Relationship", + "object": "urn:ngsi-ld:Person:Bob" + }, + "datasetId": "urn:ngsi-ld:Relationship:parked12345" + }, + "speed": [ + { + "type": "Property", + "value": 55, + "source": { + "type": "Property", + "value": "Speedometer" + } + }, + { + "type": "Property", + "value": 54.5, + "source": { + "type": "Property", + "value": "GPS" + }, + "datasetId": "urn:ngsi-ld:Property:gpsBxyz123-speed" + } + ], + "@context": [ + "https://forge.etsi.org/rep/cim/ngsi-ld-test-suite/-/raw/develop/resources/jsonld-contexts/ngsi-ld-test-suite-compound.jsonld" + ] +}' +orionCurl --url /ngsi-ld/v1/entities --payload "$payload" --in application/ld+json +echo +echo + + +echo "02. PATCH the speed attribute using PATCH /entities/*/attrs as in issue #1419" +echo "=============================================================================" +payload='{ + "speed": { + "type": "Property", + "value": 99, + "source": { + "type": "Property", + "value": "Speedometer" + } + }, + "@context": [ + "https://forge.etsi.org/rep/cim/ngsi-ld-test-suite/-/raw/develop/resources/jsonld-contexts/ngsi-ld-test-suite-compound.jsonld" + ] +}' +orionCurl --url /ngsi-ld/v1/entities/urn:ngsi-ld:Vehicle:4577314217839414/attrs -X PATCH --payload "$payload" --in application/ld+json +echo +echo + + +echo "03. Health check, as the issue #1419 indicates the broker crashes during the PATCH" +echo "==================================================================================" +orionCurl --url /ngsi-ld/v1/entities?local=true +echo +echo + + +--REGEXPECT-- +01. Create an entity urn:ngsi-ld:Vehicle:4577314217839414 as in issue #1419 +=========================================================================== +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/entities/urn:ngsi-ld:Vehicle:4577314217839414 + + + +02. PATCH the speed attribute using PATCH /entities/*/attrs as in issue #1419 +============================================================================= +HTTP/1.1 204 No Content +Date: REGEX(.*) + + + +03. Health check, as the issue #1419 indicates the broker crashes during the PATCH +================================================================================== +HTTP/1.1 200 OK +Content-Length: 345 +Content-Type: application/json +Date: REGEX(.*) +Link: