diff --git a/src/lib/orionld/forwarding/distOpResponses.cpp b/src/lib/orionld/forwarding/distOpResponses.cpp index e14b5a8749..763af3d081 100644 --- a/src/lib/orionld/forwarding/distOpResponses.cpp +++ b/src/lib/orionld/forwarding/distOpResponses.cpp @@ -333,7 +333,7 @@ void distOpResponseAccumulate(DistOp* distOpP, KjNode* responseBody, KjNode* suc if (msgP->data.result == CURLE_OK) { if ((httpResponseCode >= 200) && (httpResponseCode <= 299)) - distOpSuccess(responseBody, distOpP, NULL); + distOpSuccess(responseBody, distOpP, NULL, NULL); else if (httpResponseCode == 404) distOpFailure(responseBody, distOpP, "Not Found", NULL, 404, NULL); } diff --git a/src/lib/orionld/forwarding/distOpSuccess.cpp b/src/lib/orionld/forwarding/distOpSuccess.cpp index e841f4b4eb..eb50936fdb 100644 --- a/src/lib/orionld/forwarding/distOpSuccess.cpp +++ b/src/lib/orionld/forwarding/distOpSuccess.cpp @@ -70,7 +70,7 @@ static void attrNameToSuccess(KjNode* successV, KjNode* failureV, char* attrName // // distOpSuccess - // -void distOpSuccess(KjNode* responseBody, DistOp* distOpP, char* attrName) +void distOpSuccess(KjNode* responseBody, DistOp* distOpP, const char* entityId, char* attrName) { KjNode* successV = kjLookup(responseBody, "success"); KjNode* failureV = kjLookup(responseBody, "failure"); @@ -81,13 +81,19 @@ void distOpSuccess(KjNode* responseBody, DistOp* distOpP, char* attrName) kjChildAdd(responseBody, successV); } + if ((distOpP == NULL) && (attrName == NULL)) + { + KjNode* entityIdNodeP = kjString(orionldState.kjsonP, NULL, entityId); + kjChildAdd(successV, entityIdNodeP); + } + if (attrName != NULL) attrNameToSuccess(successV, failureV, attrName); else if (distOpP != NULL) { if (distOpP->attrName != NULL) attrNameToSuccess(successV, failureV, distOpP->attrName); - else + else if (distOpP->requestBody != NULL) { for (KjNode* attrNameP = distOpP->requestBody->value.firstChildP; attrNameP != NULL; attrNameP = attrNameP->next) { diff --git a/src/lib/orionld/forwarding/distOpSuccess.h b/src/lib/orionld/forwarding/distOpSuccess.h index 36db330fff..8d5fd75534 100644 --- a/src/lib/orionld/forwarding/distOpSuccess.h +++ b/src/lib/orionld/forwarding/distOpSuccess.h @@ -41,8 +41,9 @@ extern "C" // PARAMETERS // responseBody a KjNode object with two fields: "success" and "failure" // distOpP linked list of DistOp's +// entityId the id of the entity // attrName instead of 'distOp', here's the only attribute name already // -extern void distOpSuccess(KjNode* responseBody, DistOp* distOpP, char* attrName); +extern void distOpSuccess(KjNode* responseBody, DistOp* distOpP, const char* entityId, char* attrName); #endif // SRC_LIB_ORIONLD_FORWARDING_DISTOPSUCCESS_H_ diff --git a/src/lib/orionld/rest/orionldServiceInit.cpp b/src/lib/orionld/rest/orionldServiceInit.cpp index 5b3b6611a0..658e3f5c5b 100644 --- a/src/lib/orionld/rest/orionldServiceInit.cpp +++ b/src/lib/orionld/rest/orionldServiceInit.cpp @@ -247,6 +247,8 @@ static void restServicePrepare(OrionLdRestService* serviceP, OrionLdRestServiceS else if (serviceP->serviceRoutine == orionldDeleteEntity) { serviceP->options |= ORIONLD_SERVICE_OPTION_NO_CONTEXT_NEEDED; + + serviceP->uriParams |= ORIONLD_URIPARAM_TYPELIST; } else if (serviceP->serviceRoutine == orionldPostEntity) { diff --git a/src/lib/orionld/serviceRoutines/orionldDeleteAttribute.cpp b/src/lib/orionld/serviceRoutines/orionldDeleteAttribute.cpp index 8ac82a4b5e..2e2cdf933e 100644 --- a/src/lib/orionld/serviceRoutines/orionldDeleteAttribute.cpp +++ b/src/lib/orionld/serviceRoutines/orionldDeleteAttribute.cpp @@ -266,7 +266,7 @@ bool orionldDeleteAttribute(void) distOpFailure(responseBody, NULL, "Database Error", "(ToDo: get error from mongoc)", 500, attrName); } else - distOpSuccess(responseBody, NULL, attrName); + distOpSuccess(responseBody, NULL, entityId, attrName); } if (distOpList != NULL) diff --git a/src/lib/orionld/serviceRoutines/orionldDeleteEntity.cpp b/src/lib/orionld/serviceRoutines/orionldDeleteEntity.cpp index 767fa819eb..cbd7db4085 100644 --- a/src/lib/orionld/serviceRoutines/orionldDeleteEntity.cpp +++ b/src/lib/orionld/serviceRoutines/orionldDeleteEntity.cpp @@ -219,10 +219,15 @@ bool orionldDeleteEntity(void) // Delete the entity in the local DB // - Error if the entity is not found locally, and not subject to forwarding // - if ((dbEntityP == NULL) && (distOpList == NULL)) + if (dbEntityP == NULL) { - orionldError(OrionldResourceNotFound, "Entity not found", entityId, 404); - return false; + if (distOpList == NULL) + { + orionldError(OrionldResourceNotFound, "Entity not found", entityId, 404); + return false; + } + else + distOpFailure(responseBody, NULL, "Not Found", entityId, 404, NULL); } // @@ -230,15 +235,23 @@ bool orionldDeleteEntity(void) // Give 404 if the entity is not present locally nor triggered any forwarded requests // char* detail = NULL; - if ((dbEntityP != NULL) && (mongocEntityDelete(entityId, &detail) == false)) + if (dbEntityP != NULL) { - if (distOpList == NULL) // pure local request + if (mongocEntityDelete(entityId, &detail) == true) { - orionldError(OrionldInternalError, "Database Error", detail, 500); - return false; + // Add a success to the "success" member + distOpSuccess(responseBody, NULL, entityId, NULL); } else - distOpFailure(responseBody, NULL, "Database Error", detail, 500, NULL); + { + if (distOpList == NULL) // pure local request + { + orionldError(OrionldInternalError, "Database Error", detail, 500); + return false; + } + else + distOpFailure(responseBody, NULL, "Database Error", detail, 500, NULL); + } } if (dbEntityP != NULL) @@ -250,6 +263,7 @@ bool orionldDeleteEntity(void) distOpListRelease(distOpList); } + kjTreeLog(responseBody, "responseBody", LmtSR); responseFix(responseBody, DoDeleteEntity, 204, entityId); return true; diff --git a/src/lib/orionld/serviceRoutines/orionldPatchEntity.cpp b/src/lib/orionld/serviceRoutines/orionldPatchEntity.cpp index ad819f829e..965c8a3eaa 100644 --- a/src/lib/orionld/serviceRoutines/orionldPatchEntity.cpp +++ b/src/lib/orionld/serviceRoutines/orionldPatchEntity.cpp @@ -384,7 +384,7 @@ bool orionldPatchEntity(void) bzero(&local, sizeof(local)); local.requestBody = orionldState.requestTree; - distOpSuccess(responseBody, &local, NULL); + distOpSuccess(responseBody, &local, entityId, NULL); } // diff --git a/src/lib/orionld/serviceRoutines/orionldPatchEntity2.cpp b/src/lib/orionld/serviceRoutines/orionldPatchEntity2.cpp index 6efc1b905f..20ceb39bfb 100644 --- a/src/lib/orionld/serviceRoutines/orionldPatchEntity2.cpp +++ b/src/lib/orionld/serviceRoutines/orionldPatchEntity2.cpp @@ -729,7 +729,7 @@ bool orionldPatchEntity2(void) local.requestBody = requestForLocal; if (dbUpdateResult == true) - distOpSuccess(responseBody, &local, NULL); + distOpSuccess(responseBody, &local, entityId, NULL); } responseFix(responseBody, DoMergeEntity, 204, entityId); diff --git a/src/lib/orionld/serviceRoutines/orionldPostEntities.cpp b/src/lib/orionld/serviceRoutines/orionldPostEntities.cpp index 5ec5ba91c6..c6c9ea506e 100644 --- a/src/lib/orionld/serviceRoutines/orionldPostEntities.cpp +++ b/src/lib/orionld/serviceRoutines/orionldPostEntities.cpp @@ -234,7 +234,7 @@ bool orionldPostEntities(void) DistOp local; bzero(&local, sizeof(local)); local.requestBody = cloneForTroeP; - distOpSuccess(responseBody, &local, NULL); + distOpSuccess(responseBody, &local, NULL, NULL); } // diff --git a/src/lib/orionld/serviceRoutines/orionldPostEntity.cpp b/src/lib/orionld/serviceRoutines/orionldPostEntity.cpp index d4f12d1c7a..2a4611bbb2 100644 --- a/src/lib/orionld/serviceRoutines/orionldPostEntity.cpp +++ b/src/lib/orionld/serviceRoutines/orionldPostEntity.cpp @@ -262,7 +262,7 @@ bool orionldPostEntity(void) kjChildRemove(orionldState.requestTree, attrP); } else - distOpSuccess(responseBody, NULL, attrP->name); + distOpSuccess(responseBody, NULL, entityId, attrP->name); } } else @@ -274,7 +274,7 @@ bool orionldPostEntity(void) kjChildRemove(orionldState.requestTree, attrP); } else - distOpSuccess(responseBody, NULL, attrP->name); + distOpSuccess(responseBody, NULL, entityId, attrP->name); } attrP = next; diff --git a/test/functionalTest/cases/0000_ngsild/ngsild_three_brokers_and_forwarding_loop.test b/test/functionalTest/cases/0000_ngsild/ngsild_three_brokers_and_forwarding_loop.test index a84c7242d1..8a332a2241 100644 --- a/test/functionalTest/cases/0000_ngsild/ngsild_three_brokers_and_forwarding_loop.test +++ b/test/functionalTest/cases/0000_ngsild/ngsild_three_brokers_and_forwarding_loop.test @@ -41,7 +41,10 @@ orionldStart CP2 -experimental -forwarding -wip entityMaps # 05. Create an entity urn:E2, type IE in CP1 # 06. Create an entity urn:E3, type IE in CP2 # 07. GET all entity of type IE from CB - see all three entities +# 08. DELETE urn:E2 via CB (forwarded message to both CP1 and CP2 - success from CP1, 404 from CP2) +# 09. DELETE urn:E1 via CB (forwarded message to both CP1 and CP2 - 404 from both of them) # + HOST=$(hostname) echo "01. Create an inclusive registration for entity type IE in CB, for CP1" echo "======================================================================" @@ -58,7 +61,7 @@ payload='{ } ], "endpoint": "'$HOST:$CP1_PORT'", - "operations": [ "queryEntity" ] + "operations": [ "queryEntity", "deleteEntity" ] }' orionCurl --url /ngsi-ld/v1/csourceRegistrations --payload "$payload" echo @@ -68,7 +71,7 @@ echo echo "02. Create an inclusive registration for entity type IE in CP1, for CP2" echo "=======================================================================" payload='{ - "id": "urn:R1", + "id": "urn:R2", "type": "ContextSourceRegistration", "information": [ { @@ -80,7 +83,7 @@ payload='{ } ], "endpoint": "'$HOST:$CP2_PORT'", - "operations": [ "queryEntity" ] + "operations": [ "queryEntity", "deleteEntity" ] }' orionCurl --url /ngsi-ld/v1/csourceRegistrations --payload "$payload" --port $CP1_PORT echo @@ -90,7 +93,7 @@ echo echo "03. Create an inclusive registration for entity type IE in CP2, for CB" echo "======================================================================" payload='{ - "id": "urn:R1", + "id": "urn:R3", "type": "ContextSourceRegistration", "information": [ { @@ -102,7 +105,7 @@ payload='{ } ], "endpoint": "'$HOST:$CB_PORT'", - "operations": [ "queryEntity" ] + "operations": [ "queryEntity", "deleteEntity" ] }' orionCurl --url /ngsi-ld/v1/csourceRegistrations --payload "$payload" --port $CP2_PORT echo @@ -161,6 +164,20 @@ echo echo +echo "08. DELETE urn:E2 via CB (forwarded message to both CP1 and CP2 - success from CP1, 404 from CP2)" +echo "=================================================================================================" +orionCurl --url /ngsi-ld/v1/entities/urn:E2?type=IE -X DELETE +echo +echo + + +echo "09. DELETE urn:E1 via CB (forwarded message to both CP1 and CP2 - 404 from both of them)" +echo "========================================================================================" +orionCurl --url /ngsi-ld/v1/entities/urn:E1?type=IE -X DELETE +echo +echo + + --REGEXPECT-- 01. Create an inclusive registration for entity type IE in CB, for CP1 ====================================================================== @@ -176,7 +193,7 @@ Location: /ngsi-ld/v1/csourceRegistrations/urn:R1 HTTP/1.1 201 Created Content-Length: 0 Date: REGEX(.*) -Location: /ngsi-ld/v1/csourceRegistrations/urn:R1 +Location: /ngsi-ld/v1/csourceRegistrations/urn:R2 @@ -185,7 +202,7 @@ Location: /ngsi-ld/v1/csourceRegistrations/urn:R1 HTTP/1.1 201 Created Content-Length: 0 Date: REGEX(.*) -Location: /ngsi-ld/v1/csourceRegistrations/urn:R1 +Location: /ngsi-ld/v1/csourceRegistrations/urn:R3 @@ -253,6 +270,63 @@ NGSILD-EntityMap: urn:ngsi-ld:entity-map:REGEX(.*) ] +08. DELETE urn:E2 via CB (forwarded message to both CP1 and CP2 - success from CP1, 404 from CP2) +================================================================================================= +HTTP/1.1 207 Multi-Status +Content-Length: 184 +Content-Type: application/json +Date: REGEX(.*) +Link: ; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json" + +{ + "notUpdated": [ + { + "detail": "urn:E2", + "statusCode": 404, + "title": "Not Found" + }, + { + "detail": "urn:E2", + "registrationId": "urn:R1", + "statusCode": 404, + "title": "Entity not found" + } + ], + "updated": [ + "urn:E2" + ] +} + + +09. DELETE urn:E1 via CB (forwarded message to both CP1 and CP2 - 404 from both of them) +======================================================================================== +HTTP/1.1 207 Multi-Status +Content-Length: 210 +Content-Type: application/json +Date: REGEX(.*) +Link: ; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json" + +{ + "notUpdated": [ + { + "detail": "urn:E1", + "registrationId": "urn:R1", + "statusCode": 404, + "title": "Not Found" + }, + { + "detail": "urn:E1", + "registrationId": "urn:R1", + "statusCode": 404, + "title": "Entity not found" + } + ], + "updated": [ + "urn:E1" + ] +} + + --TEARDOWN-- brokerStop CB brokerStop CP1