From 5ae2c001f81caaa7d34d15249d370fae67864893 Mon Sep 17 00:00:00 2001 From: Ken Zangelin Date: Mon, 4 Dec 2023 11:33:25 +0100 Subject: [PATCH 1/2] New HTTP header 'aerOS' for aerOS special treatment. Fixed the problem with distop reaponse for aux regs being merged after all others --- src/lib/orionld/common/orionldState.h | 1 + src/lib/orionld/forwarding/distOpRequests.cpp | 2 +- src/lib/orionld/forwarding/distOpSend.cpp | 7 +- src/lib/orionld/forwarding/distOpSend.h | 2 +- src/lib/orionld/forwarding/distOpsSend.cpp | 6 +- src/lib/orionld/forwarding/distOpsSend.h | 2 +- .../orionld/rest/orionldMhdConnectionInit.cpp | 5 + .../orionldDeleteAttribute.cpp | 2 +- .../serviceRoutines/orionldDeleteEntity.cpp | 2 +- .../orionldGetEntitiesDistributed.cpp | 4 +- .../orionldGetEntitiesPage.cpp | 52 +- .../serviceRoutines/orionldGetEntity.cpp | 2 +- .../orionldPostBatchDelete.cpp | 2 +- ...sed_registrations_multiple_forwarding.test | 97 +-- ...ers_and_forwarding_loop_ALL-CONNECTED.test | 751 ++++++++++++++++++ ...ers_and_forwarding_loop_ALL-CONNECTED.test | 2 +- 16 files changed, 861 insertions(+), 78 deletions(-) create mode 100644 test/functionalTest/cases/0000_ngsild/ngsild_four_brokers_and_forwarding_loop_ALL-CONNECTED.test diff --git a/src/lib/orionld/common/orionldState.h b/src/lib/orionld/common/orionldState.h index 5d00c2175b..d1e3d4ab44 100644 --- a/src/lib/orionld/common/orionldState.h +++ b/src/lib/orionld/common/orionldState.h @@ -246,6 +246,7 @@ typedef struct OrionldStateIn char* tenant; char* legacy; // Use legacy mongodb driver / mongoBackend bool performance; + bool aerOS; // Special treatment for aerOS specific features // Incoming payload char* payload; diff --git a/src/lib/orionld/forwarding/distOpRequests.cpp b/src/lib/orionld/forwarding/distOpRequests.cpp index 7592cc3080..48978f433b 100644 --- a/src/lib/orionld/forwarding/distOpRequests.cpp +++ b/src/lib/orionld/forwarding/distOpRequests.cpp @@ -138,7 +138,7 @@ DistOp* distOpRequests(char* entityId, char* entityType, DistOpType operation, K // Send the forwarded request and await all responses if ((distOpP->regP != NULL) && (distOpP->error == false)) { - if (distOpSend(distOpP, dateHeader, xff) == 0) + if (distOpSend(distOpP, dateHeader, xff, false) == 0) { distOpP->error = false; orionldState.distOp.requests += 1; diff --git a/src/lib/orionld/forwarding/distOpSend.cpp b/src/lib/orionld/forwarding/distOpSend.cpp index 8a351142a5..698b7afff2 100644 --- a/src/lib/orionld/forwarding/distOpSend.cpp +++ b/src/lib/orionld/forwarding/distOpSend.cpp @@ -325,7 +325,7 @@ void bodyCompact(DistOpType operation, KjNode* requestBody, OrionldContext* fwdC // // distOpSend - // -bool distOpSend(DistOp* distOpP, const char* dateHeader, const char* xForwardedForHeader) +bool distOpSend(DistOp* distOpP, const char* dateHeader, const char* xForwardedForHeader, bool local) { // // Figure out the @context to use for the forwarded request @@ -408,6 +408,9 @@ bool distOpSend(DistOp* distOpP, const char* dateHeader, const char* xForwardedF if ((distOpP->operation == DoQueryEntity) && (distOpP->entityId != NULL)) uriParamAdd(&urlParts, "id", distOpP->entityId, -1); + if (local == true) + uriParamAdd(&urlParts, "local=true", NULL, 10); + // // If we know the Entity Type, we pass that piece of information as well // @@ -427,7 +430,7 @@ bool distOpSend(DistOp* distOpP, const char* dateHeader, const char* xForwardedF if (orionldState.uriParams.qCopy != NULL) { uriParamAdd(&urlParts, "q", orionldState.uriParams.qCopy, -1); - LM_T(LmtDistOpRequest, ("%s: orionldState.uriParams.q: '%s'", distOpP->regP->regId, orionldState.uriParams.qCopy)); + LM_T(LmtDistOpRequestHeaders, ("%s: orionldState.uriParams.q: '%s'", distOpP->regP->regId, orionldState.uriParams.qCopy)); } // diff --git a/src/lib/orionld/forwarding/distOpSend.h b/src/lib/orionld/forwarding/distOpSend.h index aae8f151e7..d4485390c2 100644 --- a/src/lib/orionld/forwarding/distOpSend.h +++ b/src/lib/orionld/forwarding/distOpSend.h @@ -33,6 +33,6 @@ // // distOpSend - // -extern bool distOpSend(DistOp* distOpP, const char* dateHeader, const char* xForwardedForHeader); +extern bool distOpSend(DistOp* distOpP, const char* dateHeader, const char* xForwardedForHeader, bool local); #endif // SRC_LIB_ORIONLD_FORWARDING_DISTOPSEND_H_ diff --git a/src/lib/orionld/forwarding/distOpsSend.cpp b/src/lib/orionld/forwarding/distOpsSend.cpp index 0a139cf535..b3bfe8aeca 100644 --- a/src/lib/orionld/forwarding/distOpsSend.cpp +++ b/src/lib/orionld/forwarding/distOpsSend.cpp @@ -36,7 +36,7 @@ // // distOpsSend - // -int distOpsSend(DistOp* distOpList) +int distOpsSend(DistOp* distOpList, bool local) { char* xff = xForwardedForCompose(orionldState.in.xForwardedFor, localIpAndPort); @@ -51,7 +51,7 @@ int distOpsSend(DistOp* distOpList) { distOpP->onlyIds = true; - if (distOpSend(distOpP, dateHeader, xff) == 0) + if (distOpSend(distOpP, dateHeader, xff, local) == 0) distOpP->error = false; else distOpP->error = true; @@ -118,7 +118,7 @@ int distOpsSend2(DistOpListItem* distOpList) { distOpP->onlyIds = false; - if (distOpSend(distOpP, dateHeader, xff) == 0) + if (distOpSend(distOpP, dateHeader, xff, false) == 0) distOpP->error = false; else distOpP->error = true; diff --git a/src/lib/orionld/forwarding/distOpsSend.h b/src/lib/orionld/forwarding/distOpsSend.h index 9f5eaf641a..a80a8e3542 100644 --- a/src/lib/orionld/forwarding/distOpsSend.h +++ b/src/lib/orionld/forwarding/distOpsSend.h @@ -33,7 +33,7 @@ // // distOpsSend - // -extern int distOpsSend(DistOp* distOpList); +extern int distOpsSend(DistOp* distOpList, bool local); diff --git a/src/lib/orionld/rest/orionldMhdConnectionInit.cpp b/src/lib/orionld/rest/orionldMhdConnectionInit.cpp index b29f6c426f..40010aab9c 100644 --- a/src/lib/orionld/rest/orionldMhdConnectionInit.cpp +++ b/src/lib/orionld/rest/orionldMhdConnectionInit.cpp @@ -433,6 +433,11 @@ static MHD_Result orionldHttpHeaderReceive(void* cbDataP, MHD_ValueKind kind, co } else if (strcasecmp(key, "Performance") == 0) orionldState.in.performance = true; + else if (strcasecmp(key, "aerOS") == 0) + { + if (strcasecmp(value, "true") == 0) + orionldState.in.aerOS = true; + } else if (strcasecmp(key, "NGSILD-Scope") == 0) { orionldState.scopes = strSplit((char*) value, ',', orionldState.scopeV, K_VEC_SIZE(orionldState.scopeV)); diff --git a/src/lib/orionld/serviceRoutines/orionldDeleteAttribute.cpp b/src/lib/orionld/serviceRoutines/orionldDeleteAttribute.cpp index 697901a81e..5d4192769d 100644 --- a/src/lib/orionld/serviceRoutines/orionldDeleteAttribute.cpp +++ b/src/lib/orionld/serviceRoutines/orionldDeleteAttribute.cpp @@ -95,7 +95,7 @@ static DistOp* distributedDelete(KjNode* responseBody, char* entityId, char* ent char dateHeader[70]; snprintf(dateHeader, sizeof(dateHeader), "Date: %s", orionldState.requestTimeString); - if (distOpSend(distOpP, dateHeader, xff) == 0) + if (distOpSend(distOpP, dateHeader, xff, false) == 0) { ++forwards; distOpP->error = false; diff --git a/src/lib/orionld/serviceRoutines/orionldDeleteEntity.cpp b/src/lib/orionld/serviceRoutines/orionldDeleteEntity.cpp index 6e2f4f9d30..376401a228 100644 --- a/src/lib/orionld/serviceRoutines/orionldDeleteEntity.cpp +++ b/src/lib/orionld/serviceRoutines/orionldDeleteEntity.cpp @@ -122,7 +122,7 @@ static DistOp* distributedDelete(char* entityId, char* entityTypeExpanded, char* char dateHeader[70]; snprintf(dateHeader, sizeof(dateHeader), "Date: %s", orionldState.requestTimeString); - if (distOpSend(distOpP, dateHeader, xff) == 0) + if (distOpSend(distOpP, dateHeader, xff, false) == 0) { ++forwards; distOpP->error = false; diff --git a/src/lib/orionld/serviceRoutines/orionldGetEntitiesDistributed.cpp b/src/lib/orionld/serviceRoutines/orionldGetEntitiesDistributed.cpp index 6d33b60a70..b92cff04b1 100644 --- a/src/lib/orionld/serviceRoutines/orionldGetEntitiesDistributed.cpp +++ b/src/lib/orionld/serviceRoutines/orionldGetEntitiesDistributed.cpp @@ -281,13 +281,11 @@ static void distOpMatchIdsRequest(DistOp* distOpList) distOpListDebug2(distOpList, "DistOps before sending the onlyId=true requests"); // Send all distributed requests - int forwards = distOpsSend(distOpList); + int forwards = distOpsSend(distOpList, orionldState.in.aerOS); // Await all responses, if any if (forwards > 0) distOpsReceive(distOpList, idListResponse, orionldEntityMap, forwards); - - } diff --git a/src/lib/orionld/serviceRoutines/orionldGetEntitiesPage.cpp b/src/lib/orionld/serviceRoutines/orionldGetEntitiesPage.cpp index c76662ae2a..cf7efe5e11 100644 --- a/src/lib/orionld/serviceRoutines/orionldGetEntitiesPage.cpp +++ b/src/lib/orionld/serviceRoutines/orionldGetEntitiesPage.cpp @@ -125,12 +125,20 @@ DistOpListItem* distOpListItemCreate(const char* distOpId, char* idString) if (distOpP == NULL) { +#if 0 // // I think this LM_RE here is incorrect. // The DistOps are for one request only. // So, create a new DistOp if it does not exist. // LM_RE(NULL, ("Internal Error (unable to find the DistOp '%s'", distOpId)); +#else + RegCacheItem* rciP = regCacheItemLookup(orionldState.tenantP->regCache, distOpId); + distOpP = distOpCreate(DoQueryEntity, rciP, NULL, NULL, NULL); + // Add DistOp to the linked list of DistOps + distOpP->next = orionldState.distOpList; + orionldState.distOpList = distOpP; +#endif } DistOpListItem* itemP = (DistOpListItem*) kaAlloc(&orionldState.kalloc, sizeof(DistOpListItem)); @@ -169,18 +177,12 @@ DistOpListItem* distOpListItemAdd(DistOpListItem* distOpList, const char* distOp // ----------------------------------------------------------------------------- // -// queryResponse - -// -// FIXME: -// I have a problem here with responses for requests forwarded due to Auxiliary Registrations. -// They can't be taken into account until AFTER all other responses have been dealt with, -// So, unless all other responses have been treated (merging entities), responses from Aux Regs must be delayed. -// They must be kept in a list and treated once no other responses are left. +// responseMerge - // -static int queryResponse(DistOp* distOpP, void* callbackParam) +static void responseMerge(DistOp* distOpP, KjNode* entityArray) { - LM_T(LmtSR, ("Got a response. status code: %d. callbackParam: %p", distOpP->httpResponseCode, callbackParam)); - KjNode* entityArray = (KjNode*) callbackParam; + LM_W(("Merging entities for DistOp '%s' (aux: %s)", distOpP->id, (distOpP->regP->mode == RegModeAuxiliary)? "YES" : "NO")); + LM_T(LmtSR, ("Got a response. status code: %d. entityArray: %p", distOpP->httpResponseCode, entityArray)); kjTreeLog(distOpP->responseBody, "Response", LmtSR); @@ -214,9 +216,8 @@ static int queryResponse(DistOp* distOpP, void* callbackParam) } else { - bool auxiliary = distOpP->regP->mode == RegModeAuxiliary; LM_T(LmtDistOpMerge, ("Existing Entity '%s' - merging it in the entity array (reg-mode: %s)", entityId, registrationModeToString(distOpP->regP->mode))); - distOpEntityMerge(baseEntityP, entityP, orionldState.uriParamOptions.sysAttrs, auxiliary); + distOpEntityMerge(baseEntityP, entityP, orionldState.uriParamOptions.sysAttrs, distOpP->regP->mode == RegModeAuxiliary); } } else @@ -225,7 +226,19 @@ static int queryResponse(DistOp* distOpP, void* callbackParam) entityP = next; } } +} + + +// ----------------------------------------------------------------------------- +// +// queryResponse - +// +static int queryResponse(DistOp* distOpP, void* callbackParam) +{ + KjNode* entityArray = (KjNode*) callbackParam; + + responseMerge(distOpP, entityArray); return 0; } @@ -243,7 +256,7 @@ typedef int (*DistOpResponseTreatFunction)(DistOp* distOpP, void* callbackParam) // // distOpsReceive2 - FIXME: move to orionld/forwarding/distOpsReceive.cpp/h // -void distOpsReceive2(DistOpResponseTreatFunction treatFunction, void* callbackParam) +void distOpsReceive2(DistOpListItem* distOpList, DistOpResponseTreatFunction treatFunction, void* callbackParam) { LM_T(LmtSR, ("Receiving responses")); // @@ -275,9 +288,18 @@ void distOpsReceive2(DistOpResponseTreatFunction treatFunction, void* callbackPa LM_T(LmtDistOpResponse, ("%s: received a response for a forwarded request", distOpP->regP->regId, distOpP->httpResponseCode)); LM_T(LmtDistOpResponse, ("%s: response for a forwarded request: %s", distOpP->regP->regId, distOpP->rawResponse)); - treatFunction(distOpP, callbackParam); + if (distOpP->regP->mode == RegModeAuxiliary) + LM_W(("%s: Aux registration - merge is delayed", distOpP->regP->regId)); + else + treatFunction(distOpP, callbackParam); } } + + for (DistOp* distOpP = orionldState.distOpList; distOpP != NULL; distOpP = distOpP->next) + { + if ((distOpP->regP != NULL) && (distOpP->regP->mode == RegModeAuxiliary)) + responseMerge(distOpP, (KjNode*) callbackParam); + } } @@ -294,7 +316,7 @@ static void distOpQueryRequest(DistOpListItem* distOpList, KjNode* entityArray) // Await all responses, if any if (forwards > 0) - distOpsReceive2(queryResponse, entityArray); + distOpsReceive2(distOpList, queryResponse, entityArray); } diff --git a/src/lib/orionld/serviceRoutines/orionldGetEntity.cpp b/src/lib/orionld/serviceRoutines/orionldGetEntity.cpp index 50f06938f0..97d18a4291 100644 --- a/src/lib/orionld/serviceRoutines/orionldGetEntity.cpp +++ b/src/lib/orionld/serviceRoutines/orionldGetEntity.cpp @@ -190,7 +190,7 @@ bool orionldGetEntity(void) if (distOpP->regP != NULL) { LM_T(LmtDistOpAttributes, ("distOp::attrsParam: '%s'", distOpP->attrsParam)); - if (distOpSend(distOpP, dateHeader, xff) == 0) + if (distOpSend(distOpP, dateHeader, xff, false) == 0) { ++forwards; distOpP->error = false; diff --git a/src/lib/orionld/serviceRoutines/orionldPostBatchDelete.cpp b/src/lib/orionld/serviceRoutines/orionldPostBatchDelete.cpp index dde4614a9b..41cb414453 100644 --- a/src/lib/orionld/serviceRoutines/orionldPostBatchDelete.cpp +++ b/src/lib/orionld/serviceRoutines/orionldPostBatchDelete.cpp @@ -478,7 +478,7 @@ bool orionldPostBatchDelete(void) char dateHeader[70]; snprintf(dateHeader, sizeof(dateHeader), "Date: %s", orionldState.requestTimeString); - if (distOpSend(distReqP, dateHeader, xff) == 0) + if (distOpSend(distReqP, dateHeader, xff, false) == 0) { ++forwards; distReqP->error = false; diff --git a/test/functionalTest/cases/0000_ngsild/ngsild_entityMap_crossed_registrations_multiple_forwarding.test b/test/functionalTest/cases/0000_ngsild/ngsild_entityMap_crossed_registrations_multiple_forwarding.test index 4617b57ac1..170eaa7eff 100644 --- a/test/functionalTest/cases/0000_ngsild/ngsild_entityMap_crossed_registrations_multiple_forwarding.test +++ b/test/functionalTest/cases/0000_ngsild/ngsild_entityMap_crossed_registrations_multiple_forwarding.test @@ -55,7 +55,7 @@ orionldStart CP2 -experimental -forwarding # echo "01. In CB, create an entity urn:E1 with attributes P1+R1" -echo "=========================================================" +echo "========================================================" payload='{ "id": "urn:E1", "type": "T", @@ -68,7 +68,7 @@ echo echo "02. In CB, create an entity urn:E2 with attributes P1+R1" -echo "=========================================================" +echo "========================================================" payload='{ "id": "urn:E2", "type": "T", @@ -133,7 +133,7 @@ echo echo "07. Create an inclusive registration R1 in CB on entities of type T pointing to CP1" -echo "=========================================================" +echo "===================================================================================" payload='{ "id": "urn:R1", "type": "ContextSourceRegistration", @@ -156,7 +156,7 @@ echo echo "08. Create an inclusive registration R2 in CB on entities of type T pointing to CP2" -echo "=========================================================" +echo "===================================================================================" payload='{ "id": "urn:R2", "type": "ContextSourceRegistration", @@ -179,7 +179,7 @@ echo echo "09. Create an inclusive registration R1 in CP1 on entities of type T pointing to CB" -echo "=========================================================" +echo "===================================================================================" payload='{ "id": "urn:R1", "type": "ContextSourceRegistration", @@ -202,7 +202,7 @@ echo echo "10. Create an inclusive registration R2 in CP1 on entities of type T pointing to CP2" -echo "=========================================================" +echo "====================================================================================" payload='{ "id": "urn:R2", "type": "ContextSourceRegistration", @@ -225,7 +225,7 @@ echo echo "11. Create an inclusive registration R1 in CP2 on entities of type T pointing to CB" -echo "=========================================================" +echo "===================================================================================" payload='{ "id": "urn:R1", "type": "ContextSourceRegistration", @@ -248,7 +248,7 @@ echo echo "12. Create an inclusive registration R2 in CP2 on entities of type T pointing to CP1" -echo "=========================================================" +echo "====================================================================================" payload='{ "id": "urn:R2", "type": "ContextSourceRegistration", @@ -271,54 +271,53 @@ echo echo "13. Create an entity map for a GET /entities?type=T in CB" -echo "===================================================" -orionCurl --url '/ngsi-ld/v1/entities?type=T&count=true' +echo "=========================================================" +orionCurl --url '/ngsi-ld/v1/entities?type=T&count=true' -H "aerOS: true" entityMap=$(echo "$_responseHeaders" | grep Entity-Map: | awk -F ': ' '{ print $2 }' | tr -d "\r\n") echo echo echo '14. GET the entity map - see E1 and E2 are local entities and E3 and E4 are in CP1' -echo '=================================================================' -orionCurl --url /ngsi-ld/v1/entityMaps/$entityMap --noPayloadCheck +echo '==================================================================================' +orionCurl --url /ngsi-ld/v1/entityMaps/$entityMap echo echo echo "15. Create an entity map for a GET /entities?type=T in CP1" -echo "===================================================" -orionCurl --url '/ngsi-ld/v1/entities?type=T&count=true' --port $CP1_PORT +echo "==========================================================" +orionCurl --url '/ngsi-ld/v1/entities?type=T&count=true&reset=true' -H "aerOS: true" --port $CP1_PORT entityMap=$(echo "$_responseHeaders" | grep Entity-Map: | awk -F ': ' '{ print $2 }' | tr -d "\r\n") echo echo echo '16. GET the entity map - see E3 and E4 are local entities and E1 and E2 are in CB' -echo '=================================================================' +echo '=================================================================================' orionCurl --url /ngsi-ld/v1/entityMaps/$entityMap --port $CP1_PORT echo echo echo "17. Create an entity map for a GET /entities?type=T in CP2" -echo "===================================================" -orionCurl --url '/ngsi-ld/v1/entities?type=T&count=true' --port $CP2_PORT +echo "==========================================================" +orionCurl --url '/ngsi-ld/v1/entities?type=T&count=true&reset=true' -H "aerOS: true" --port $CP2_PORT entityMap=$(echo "$_responseHeaders" | grep Entity-Map: | awk -F ': ' '{ print $2 }' | tr -d "\r\n") echo echo echo '18. GET the entity map - see E3 and E4 are local entities and E1 and E2 are in CB' -echo '=================================================================' +echo '=================================================================================' orionCurl --url /ngsi-ld/v1/entityMaps/$entityMap --port $CP2_PORT echo echo - --REGEXPECT-- 01. In CB, create an entity urn:E1 with attributes P1+R1 -========================================================= +======================================================== HTTP/1.1 201 Created Content-Length: 0 Date: REGEX(.*) @@ -327,7 +326,7 @@ Location: /ngsi-ld/v1/entities/urn:E1 02. In CB, create an entity urn:E2 with attributes P1+R1 -========================================================= +======================================================== HTTP/1.1 201 Created Content-Length: 0 Date: REGEX(.*) @@ -372,7 +371,7 @@ Location: /ngsi-ld/v1/entities/urn:E6 07. Create an inclusive registration R1 in CB on entities of type T pointing to CP1 -========================================================= +=================================================================================== HTTP/1.1 201 Created Content-Length: 0 Date: REGEX(.*) @@ -381,7 +380,7 @@ Location: /ngsi-ld/v1/csourceRegistrations/urn:R1 08. Create an inclusive registration R2 in CB on entities of type T pointing to CP2 -========================================================= +=================================================================================== HTTP/1.1 201 Created Content-Length: 0 Date: REGEX(.*) @@ -390,7 +389,7 @@ Location: /ngsi-ld/v1/csourceRegistrations/urn:R2 09. Create an inclusive registration R1 in CP1 on entities of type T pointing to CB -========================================================= +=================================================================================== HTTP/1.1 201 Created Content-Length: 0 Date: REGEX(.*) @@ -399,7 +398,7 @@ Location: /ngsi-ld/v1/csourceRegistrations/urn:R1 10. Create an inclusive registration R2 in CP1 on entities of type T pointing to CP2 -========================================================= +==================================================================================== HTTP/1.1 201 Created Content-Length: 0 Date: REGEX(.*) @@ -408,7 +407,7 @@ Location: /ngsi-ld/v1/csourceRegistrations/urn:R2 11. Create an inclusive registration R1 in CP2 on entities of type T pointing to CB -========================================================= +=================================================================================== HTTP/1.1 201 Created Content-Length: 0 Date: REGEX(.*) @@ -417,7 +416,7 @@ Location: /ngsi-ld/v1/csourceRegistrations/urn:R1 12. Create an inclusive registration R2 in CP2 on entities of type T pointing to CP1 -========================================================= +==================================================================================== HTTP/1.1 201 Created Content-Length: 0 Date: REGEX(.*) @@ -426,9 +425,9 @@ Location: /ngsi-ld/v1/csourceRegistrations/urn:R2 13. Create an entity map for a GET /entities?type=T in CB -=================================================== +========================================================= HTTP/1.1 200 OK -Content-Length: REGEX(.*) +Content-Length: 781 Content-Type: application/json Date: REGEX(.*) Entity-Map: urn:ngsi-ld:entity-map:REGEX(.*) @@ -512,9 +511,9 @@ NGSILD-Results-Count: 6 14. GET the entity map - see E1 and E2 are local entities and E3 and E4 are in CP1 -================================================================= +================================================================================== HTTP/1.1 200 OK -Content-Length: REGEX(.*) +Content-Length: 155 Content-Type: application/json Date: REGEX(.*) @@ -526,22 +525,26 @@ Date: REGEX(.*) "@none" ], "urn:E3": [ - "http://orionld-dev:9801" + "urn:R1", + "urn:R2" ], "urn:E4": [ - "http://orionld-dev:9801" + "urn:R1", + "urn:R2" ], "urn:E5": [ - "http://orionld-dev:9802" + "urn:R1", + "urn:R2" ], "urn:E6": [ - "http://orionld-dev:9802" + "urn:R1", + "urn:R2" ] } 15. Create an entity map for a GET /entities?type=T in CP1 -================================================================= +========================================================== HTTP/1.1 200 OK Content-Length: REGEX(.*) Content-Type: application/json @@ -626,7 +629,7 @@ NGSILD-Results-Count: 6 ] 16. GET the entity map - see E3 and E4 are local entities and E1 and E2 are in CB -=================================================== +================================================================================= HTTP/1.1 200 OK Content-Length: REGEX(.*) Content-Type: application/json @@ -634,10 +637,10 @@ Date: REGEX(.*) { "urn:E1": [ - "http://orionld-dev:9999" + "urn:R1" ], "urn:E2": [ - "http://orionld-dev:9999" + "urn:R1" ], "urn:E3": [ "@none" @@ -646,16 +649,16 @@ Date: REGEX(.*) "@none" ], "urn:E5": [ - "http://orionld-dev:9802" + "urn:R2" ], "urn:E6": [ - "http://orionld-dev:9802" + "urn:R2" ] } 17. Create an entity map for a GET /entities?type=T in CP2 -================================================================= +========================================================== HTTP/1.1 200 OK Content-Length: REGEX(.*) Content-Type: application/json @@ -741,7 +744,7 @@ NGSILD-Results-Count: 6 18. GET the entity map - see E3 and E4 are local entities and E1 and E2 are in CB -================================================================= +================================================================================= HTTP/1.1 200 OK Content-Length: REGEX(.*) Content-Type: application/json @@ -749,16 +752,16 @@ Date: REGEX(.*) { "urn:E1": [ - "http://orionld-dev:9999" + "urn:R1" ], "urn:E2": [ - "http://orionld-dev:9999" + "urn:R1" ], "urn:E3": [ - "http://orionld-dev:9801" + "urn:R2" ], "urn:E4": [ - "http://orionld-dev:9801" + "urn:R2" ], "urn:E5": [ "@none" diff --git a/test/functionalTest/cases/0000_ngsild/ngsild_four_brokers_and_forwarding_loop_ALL-CONNECTED.test b/test/functionalTest/cases/0000_ngsild/ngsild_four_brokers_and_forwarding_loop_ALL-CONNECTED.test new file mode 100644 index 0000000000..31ac5dd580 --- /dev/null +++ b/test/functionalTest/cases/0000_ngsild/ngsild_four_brokers_and_forwarding_loop_ALL-CONNECTED.test @@ -0,0 +1,751 @@ +# 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-- +GET /entities with four brokers all connected via registrations + +--SHELL-INIT-- +dbInit CB +dbInit CP1 +dbInit CP2 +dbInit CP3 +orionldStart CB -experimental -forwarding +orionldStart CP1 -experimental -forwarding +orionldStart CP2 -experimental -forwarding +orionldStart CP3 -experimental -forwarding + +--SHELL-- + +# +# 01. In CB, create an entity urn:E1 with attributes P1+R1 +# 02. In CB, create an entity urn:E2 with attributes P1+R1 +# 03. In CP1, create an entity urn:E3 with attributes P1+R1 +# 04. In CP1, create an entity urn:E4 with attributes P1+R1 +# 05. In CP2, create an entity urn:E5 with attributes P1+R1 +# 06. In CP2, create an entity urn:E6 with attributes P1+R1 +# 07. In CP3, create an entity urn:E7 with attributes P1+R1 +# 08. In CP3, create an entity urn:E8 with attributes P1+R1 +# 09. Create an inclusive registration R01 in CB on entities of type T pointing to CP1 +# 10. Create an inclusive registration R02 in CB on entities of type T pointing to CP2 +# 12. Create an inclusive registration R03 in CB on entities of type T pointing to CP3 +# 12. Create an inclusive registration R04 in CP1 on entities of type T pointing to CB +# 13. Create an inclusive registration R05 in CP1 on entities of type T pointing to CP2 +# 14. Create an inclusive registration R06 in CP1 on entities of type T pointing to CP3 +# 15. Create an inclusive registration R07 in CP2 on entities of type T pointing to CB +# 16. Create an inclusive registration R08 in CP2 on entities of type T pointing to CP1 +# 17. Create an inclusive registration R09 in CP2 on entities of type T pointing to CP3 +# 18. Create an inclusive registration R10 in CP3 on entities of type T pointing to CB +# 19. Create an inclusive registration R11 in CP3 on entities of type T pointing to CP1 +# 20. Create an inclusive registration R12 in CP3 on entities of type T pointing to CP2 +# 21. GET /entities?type=T in CB - see 8 entities +# + +echo "01. In CB, create an entity urn:E1 with attributes P1+R1" +echo "=========================================================" +payload='{ + "id": "urn:E1", + "type": "T", + "P1": "Entity E1 in Orion A", + "R1": { "object": "urn:E0" } +}' +orionCurl --url /ngsi-ld/v1/entities --payload "$payload" +echo +echo + + +echo "02. In CB, create an entity urn:E2 with attributes P1+R1" +echo "=========================================================" +payload='{ + "id": "urn:E2", + "type": "T", + "P1": "Entity E2 in Orion A", + "R1": { "object": "urn:E1" } +}' +orionCurl --url /ngsi-ld/v1/entities --payload "$payload" +echo +echo + + +echo "03. In CP1, create an entity urn:E3 with attributes P1+R1" +echo "=========================================================" +payload='{ + "id": "urn:E3", + "type": "T", + "P1": "Entity E3 in Orion B", + "R1": { "object": "urn:E2" } +}' +orionCurl --url /ngsi-ld/v1/entities --payload "$payload" --port $CP1_PORT +echo +echo + + +echo "04. In CP1, create an entity urn:E4 with attributes P1+R1" +echo "=========================================================" +payload='{ + "id": "urn:E4", + "type": "T", + "P1": "Entity E4 in Orion B", + "R1": { "object": "urn:E3" } +}' +orionCurl --url /ngsi-ld/v1/entities --payload "$payload" --port $CP1_PORT +echo +echo + + +echo "05. In CP2, create an entity urn:E5 with attributes P1+R1" +echo "=========================================================" +payload='{ + "id": "urn:E5", + "type": "T", + "P1": "Entity E5 in Orion C", + "R1": { "object": "urn:E4" } +}' +orionCurl --url /ngsi-ld/v1/entities --payload "$payload" --port $CP2_PORT +echo +echo + + +echo "06. In CP2, create an entity urn:E6 with attributes P1+R1" +echo "=========================================================" +payload='{ + "id": "urn:E6", + "type": "T", + "P1": "Entity E6 in Orion C", + "R1": { "object": "urn:E5" } +}' +orionCurl --url /ngsi-ld/v1/entities --payload "$payload" --port $CP2_PORT +echo +echo + + +echo "07. In CP3, create an entity urn:E7 with attributes P1+R1" +echo "=========================================================" +payload='{ + "id": "urn:E7", + "type": "T", + "P1": "Entity E7 in Orion D", + "R1": { "object": "urn:E6" } +}' +orionCurl --url /ngsi-ld/v1/entities --payload "$payload" --port $CP3_PORT +echo +echo + + +echo "08. In CP3, create an entity urn:E8 with attributes P1+R1" +echo "=========================================================" +payload='{ + "id": "urn:E8", + "type": "T", + "P1": "Entity E8 in Orion D", + "R1": { "object": "urn:E7" } +}' +orionCurl --url /ngsi-ld/v1/entities --payload "$payload" --port $CP3_PORT +echo +echo + + +echo "09. Create an inclusive registration R01 in CB on entities of type T pointing to CP1" +echo "====================================================================================" +payload='{ + "id": "urn:R01", + "type": "ContextSourceRegistration", + "information": [ + { + "entities": [ + { + "type": "T" + } + ] + } + ], + "mode": "inclusive", + "operations": [ "retrieveOps" ], + "endpoint": "http://'$(hostname)':'$CP1_PORT'" +}' +orionCurl --url /ngsi-ld/v1/csourceRegistrations --payload "$payload" +echo +echo + + +echo "10. Create an inclusive registration R02 in CB on entities of type T pointing to CP2" +echo "====================================================================================" +payload='{ + "id": "urn:R02", + "type": "ContextSourceRegistration", + "information": [ + { + "entities": [ + { + "type": "T" + } + ] + } + ], + "mode": "inclusive", + "operations": [ "retrieveOps" ], + "endpoint": "http://'$(hostname)':'$CP2_PORT'" +}' +orionCurl --url /ngsi-ld/v1/csourceRegistrations --payload "$payload" +echo +echo + + +echo "11. Create an inclusive registration R03 in CB on entities of type T pointing to CP3" +echo "====================================================================================" +payload='{ + "id": "urn:R03", + "type": "ContextSourceRegistration", + "information": [ + { + "entities": [ + { + "type": "T" + } + ] + } + ], + "mode": "inclusive", + "operations": [ "retrieveOps" ], + "endpoint": "http://'$(hostname)':'$CP3_PORT'" +}' +orionCurl --url /ngsi-ld/v1/csourceRegistrations --payload "$payload" +echo +echo + + +echo "12. Create an inclusive registration R04 in CP1 on entities of type T pointing to CB" +echo "====================================================================================" +payload='{ + "id": "urn:R04", + "type": "ContextSourceRegistration", + "information": [ + { + "entities": [ + { + "type": "T" + } + ] + } + ], + "mode": "inclusive", + "operations": [ "retrieveOps" ], + "endpoint": "http://'$(hostname)':'$CB_PORT'" +}' +orionCurl --url /ngsi-ld/v1/csourceRegistrations --payload "$payload" --port $CP1_PORT +echo +echo + + +echo "13. Create an inclusive registration R05 in CP1 on entities of type T pointing to CP2" +echo "=====================================================================================" +payload='{ + "id": "urn:R05", + "type": "ContextSourceRegistration", + "information": [ + { + "entities": [ + { + "type": "T" + } + ] + } + ], + "mode": "inclusive", + "operations": [ "retrieveOps" ], + "endpoint": "http://'$(hostname)':'$CP2_PORT'" +}' +orionCurl --url /ngsi-ld/v1/csourceRegistrations --payload "$payload" --port $CP1_PORT +echo +echo + + +echo "14. Create an inclusive registration R06 in CP1 on entities of type T pointing to CP3" +echo "=====================================================================================" +payload='{ + "id": "urn:R06", + "type": "ContextSourceRegistration", + "information": [ + { + "entities": [ + { + "type": "T" + } + ] + } + ], + "mode": "inclusive", + "operations": [ "retrieveOps" ], + "endpoint": "http://'$(hostname)':'$CP3_PORT'" +}' +orionCurl --url /ngsi-ld/v1/csourceRegistrations --payload "$payload" --port $CP1_PORT +echo +echo + + +echo "15. Create an inclusive registration R07 in CP2 on entities of type T pointing to CB" +echo "====================================================================================" +payload='{ + "id": "urn:R07", + "type": "ContextSourceRegistration", + "information": [ + { + "entities": [ + { + "type": "T" + } + ] + } + ], + "mode": "inclusive", + "operations": [ "retrieveOps" ], + "endpoint": "http://'$(hostname)':'$CB_PORT'" +}' +orionCurl --url /ngsi-ld/v1/csourceRegistrations --payload "$payload" --port $CP2_PORT +echo +echo + + +echo "16. Create an inclusive registration R08 in CP2 on entities of type T pointing to CP1" +echo "=====================================================================================" +payload='{ + "id": "urn:R08", + "type": "ContextSourceRegistration", + "information": [ + { + "entities": [ + { + "type": "T" + } + ] + } + ], + "mode": "inclusive", + "operations": [ "retrieveOps" ], + "endpoint": "http://'$(hostname)':'$CP1_PORT'" +}' +orionCurl --url /ngsi-ld/v1/csourceRegistrations --payload "$payload" --port $CP2_PORT +echo +echo + + +echo "17. Create an inclusive registration R09 in CP2 on entities of type T pointing to CP3" +echo "=====================================================================================" +payload='{ + "id": "urn:R09", + "type": "ContextSourceRegistration", + "information": [ + { + "entities": [ + { + "type": "T" + } + ] + } + ], + "mode": "inclusive", + "operations": [ "retrieveOps" ], + "endpoint": "http://'$(hostname)':'$CP3_PORT'" +}' +orionCurl --url /ngsi-ld/v1/csourceRegistrations --payload "$payload" --port $CP2_PORT +echo +echo + + +echo "18. Create an inclusive registration R10 in CP3 on entities of type T pointing to CB" +echo "====================================================================================" +payload='{ + "id": "urn:R10", + "type": "ContextSourceRegistration", + "information": [ + { + "entities": [ + { + "type": "T" + } + ] + } + ], + "mode": "inclusive", + "operations": [ "retrieveOps" ], + "endpoint": "http://'$(hostname)':'$CB_PORT'" +}' +orionCurl --url /ngsi-ld/v1/csourceRegistrations --payload "$payload" --port $CP3_PORT +echo +echo + + +echo "19. Create an inclusive registration R11 in CP3 on entities of type T pointing to CP1" +echo "=====================================================================================" +payload='{ + "id": "urn:R11", + "type": "ContextSourceRegistration", + "information": [ + { + "entities": [ + { + "type": "T" + } + ] + } + ], + "mode": "inclusive", + "operations": [ "retrieveOps" ], + "endpoint": "http://'$(hostname)':'$CP1_PORT'" +}' +orionCurl --url /ngsi-ld/v1/csourceRegistrations --payload "$payload" --port $CP3_PORT +echo +echo + + +echo "20. Create an inclusive registration R12 in CP3 on entities of type T pointing to CP2" +echo "=====================================================================================" +payload='{ + "id": "urn:R12", + "type": "ContextSourceRegistration", + "information": [ + { + "entities": [ + { + "type": "T" + } + ] + } + ], + "mode": "inclusive", + "operations": [ "retrieveOps" ], + "endpoint": "http://'$(hostname)':'$CP2_PORT'" +}' +orionCurl --url /ngsi-ld/v1/csourceRegistrations --payload "$payload" --port $CP3_PORT +echo +echo + + +echo "21. GET /entities?type=T in CB - see 8 entities" +echo "===============================================" +orionCurl --url '/ngsi-ld/v1/entities?type=T&count=true' -H "aerOS: true" +entityMap=$(echo "$_responseHeaders" | grep Entity-Map: | awk -F ': ' '{ print $2 }' | tr -d "\r\n") +echo +echo + + +--REGEXPECT-- +01. In CB, create an entity urn:E1 with attributes P1+R1 +========================================================= +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/entities/urn:E1 + + + +02. In CB, create an entity urn:E2 with attributes P1+R1 +========================================================= +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/entities/urn:E2 + + + +03. In CP1, create an entity urn:E3 with attributes P1+R1 +========================================================= +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/entities/urn:E3 + + + +04. In CP1, create an entity urn:E4 with attributes P1+R1 +========================================================= +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/entities/urn:E4 + + + +05. In CP2, create an entity urn:E5 with attributes P1+R1 +========================================================= +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/entities/urn:E5 + + + +06. In CP2, create an entity urn:E6 with attributes P1+R1 +========================================================= +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/entities/urn:E6 + + + +07. In CP3, create an entity urn:E7 with attributes P1+R1 +========================================================= +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/entities/urn:E7 + + + +08. In CP3, create an entity urn:E8 with attributes P1+R1 +========================================================= +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/entities/urn:E8 + + + +09. Create an inclusive registration R01 in CB on entities of type T pointing to CP1 +==================================================================================== +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/csourceRegistrations/urn:R01 + + + +10. Create an inclusive registration R02 in CB on entities of type T pointing to CP2 +==================================================================================== +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/csourceRegistrations/urn:R02 + + + +11. Create an inclusive registration R03 in CB on entities of type T pointing to CP3 +==================================================================================== +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/csourceRegistrations/urn:R03 + + + +12. Create an inclusive registration R04 in CP1 on entities of type T pointing to CB +==================================================================================== +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/csourceRegistrations/urn:R04 + + + +13. Create an inclusive registration R05 in CP1 on entities of type T pointing to CP2 +===================================================================================== +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/csourceRegistrations/urn:R05 + + + +14. Create an inclusive registration R06 in CP1 on entities of type T pointing to CP3 +===================================================================================== +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/csourceRegistrations/urn:R06 + + + +15. Create an inclusive registration R07 in CP2 on entities of type T pointing to CB +==================================================================================== +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/csourceRegistrations/urn:R07 + + + +16. Create an inclusive registration R08 in CP2 on entities of type T pointing to CP1 +===================================================================================== +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/csourceRegistrations/urn:R08 + + + +17. Create an inclusive registration R09 in CP2 on entities of type T pointing to CP3 +===================================================================================== +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/csourceRegistrations/urn:R09 + + + +18. Create an inclusive registration R10 in CP3 on entities of type T pointing to CB +==================================================================================== +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/csourceRegistrations/urn:R10 + + + +19. Create an inclusive registration R11 in CP3 on entities of type T pointing to CP1 +===================================================================================== +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/csourceRegistrations/urn:R11 + + + +20. Create an inclusive registration R12 in CP3 on entities of type T pointing to CP2 +===================================================================================== +HTTP/1.1 201 Created +Content-Length: 0 +Date: REGEX(.*) +Location: /ngsi-ld/v1/csourceRegistrations/urn:R12 + + + +21. GET /entities?type=T in CB - see 8 entities +=============================================== +HTTP/1.1 200 OK +Content-Length: REGEX(.*) +Content-Type: application/json +Date: REGEX(.*) +Entity-Map: urn:ngsi-ld:entity-map:REGEX(.*) +Link: Date: Mon, 4 Dec 2023 11:37:47 +0100 Subject: [PATCH 2/2] Fixed a functest --- test/functionalTest/cases/0000_ngsild/ngsild_new_forward_q.test | 1 + 1 file changed, 1 insertion(+) diff --git a/test/functionalTest/cases/0000_ngsild/ngsild_new_forward_q.test b/test/functionalTest/cases/0000_ngsild/ngsild_new_forward_q.test index 1721fd8f2f..39b50fa87b 100644 --- a/test/functionalTest/cases/0000_ngsild/ngsild_new_forward_q.test +++ b/test/functionalTest/cases/0000_ngsild/ngsild_new_forward_q.test @@ -90,6 +90,7 @@ HTTP/1.1 200 OK Content-Length: 2 Content-Type: application/json Date: REGEX(.*) +Entity-Map: urn:ngsi-ld:entity-map:REGEX(.*) []