From f53d60d874beacb9225eeb1f75be0d91f21ebaa0 Mon Sep 17 00:00:00 2001 From: Ken Zangelin Date: Tue, 5 Dec 2023 16:12:04 +0100 Subject: [PATCH] Support for multiple entity maps --- CMakeLists.txt | 2 + src/lib/orionld/common/CMakeLists.txt | 1 - src/lib/orionld/common/orionldState.cpp | 6 +- src/lib/orionld/common/orionldState.h | 13 +- src/lib/orionld/entityMaps/CMakeLists.txt | 39 +++ .../orionld/entityMaps/entityMapCreate.cpp | 268 ++++++++++++++++ src/lib/orionld/entityMaps/entityMapCreate.h | 41 +++ .../orionld/entityMaps/entityMapItemAdd.cpp | 68 ++++ src/lib/orionld/entityMaps/entityMapItemAdd.h | 39 +++ .../orionld/entityMaps/entityMapLookup.cpp | 50 +++ src/lib/orionld/entityMaps/entityMapLookup.h | 38 +++ .../entityMapRelease.cpp} | 23 +- src/lib/orionld/entityMaps/entityMapRelease.h | 38 +++ .../orionld/entityMaps/entityMapRemove.cpp | 63 ++++ .../entityMapRemove.h} | 10 +- .../orionld/entityMaps/entityMapsRelease.cpp | 48 +++ .../orionld/entityMaps/entityMapsRelease.h | 38 +++ .../orionld/rest/orionldMhdConnectionInit.cpp | 10 +- .../orionldDeleteEntityMap.cpp | 11 +- .../serviceRoutines/orionldGetEntities.cpp | 33 +- .../orionldGetEntitiesDistributed.cpp | 291 ++---------------- .../orionldGetEntitiesPage.cpp | 28 +- .../serviceRoutines/orionldGetEntityMap.cpp | 15 +- src/lib/orionld/types/EntityMap.h | 49 +++ src/lib/orionld/types/OrionldHeader.cpp | 2 +- .../0000_ngsild/ngsild_entityMap-errors.test | 10 +- .../0000_ngsild/ngsild_entityMap_GET.test | 4 +- ...sed_registrations_multiple_forwarding.test | 64 +--- .../0000_ngsild/ngsild_entityMap_get.test | 8 +- ...tities-entity-split-over-many-brokers.test | 2 +- .../ngsild_forward_get_entities.test | 9 +- ...ers_and_forwarding_loop_ALL-CONNECTED.test | 4 +- .../cases/0000_ngsild/ngsild_issue_1466.test | 2 +- ...gsild_new_GET_entities-with-entityMap.test | 6 +- .../0000_ngsild/ngsild_new_forward_q.test | 2 +- ...ngsild_new_uri_params_in_orionldState.test | 4 +- ...ild_three_brokers_and_forwarding_loop.test | 2 +- ...ers_and_forwarding_loop_ALL-CONNECTED.test | 4 +- ...ers_and_forwarding_loop_ALL-CONNECTED.test | 4 +- 39 files changed, 924 insertions(+), 425 deletions(-) create mode 100644 src/lib/orionld/entityMaps/CMakeLists.txt create mode 100644 src/lib/orionld/entityMaps/entityMapCreate.cpp create mode 100644 src/lib/orionld/entityMaps/entityMapCreate.h create mode 100644 src/lib/orionld/entityMaps/entityMapItemAdd.cpp create mode 100644 src/lib/orionld/entityMaps/entityMapItemAdd.h create mode 100644 src/lib/orionld/entityMaps/entityMapLookup.cpp create mode 100644 src/lib/orionld/entityMaps/entityMapLookup.h rename src/lib/orionld/{common/orionldEntityMapRelease.cpp => entityMaps/entityMapRelease.cpp} (68%) create mode 100644 src/lib/orionld/entityMaps/entityMapRelease.h create mode 100644 src/lib/orionld/entityMaps/entityMapRemove.cpp rename src/lib/orionld/{common/orionldEntityMapRelease.h => entityMaps/entityMapRemove.h} (80%) create mode 100644 src/lib/orionld/entityMaps/entityMapsRelease.cpp create mode 100644 src/lib/orionld/entityMaps/entityMapsRelease.h create mode 100644 src/lib/orionld/types/EntityMap.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 217c8c80f7..6467ee2697 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -236,6 +236,7 @@ SET (ORION_LIBS orionld_dbModel orionld_apiModel orionld_common + orionld_entityMaps orionld_types parse apiTypesV2 @@ -367,6 +368,7 @@ if (error EQUAL 0) ADD_SUBDIRECTORY(src/lib/jsonParse) ADD_SUBDIRECTORY(src/lib/jsonParseV2) ADD_SUBDIRECTORY(src/lib/rest) + ADD_SUBDIRECTORY(src/lib/orionld/entityMaps) ADD_SUBDIRECTORY(src/lib/orionld/pernot) ADD_SUBDIRECTORY(src/lib/orionld/socketService) ADD_SUBDIRECTORY(src/lib/orionld/notifications) diff --git a/src/lib/orionld/common/CMakeLists.txt b/src/lib/orionld/common/CMakeLists.txt index ce987d6d8d..adc7b8a51b 100644 --- a/src/lib/orionld/common/CMakeLists.txt +++ b/src/lib/orionld/common/CMakeLists.txt @@ -68,7 +68,6 @@ SET (SOURCES curlToBrokerStrerror.cpp fileName.cpp responseFix.cpp - orionldEntityMapRelease.cpp ) # Include directories diff --git a/src/lib/orionld/common/orionldState.cpp b/src/lib/orionld/common/orionldState.cpp index 4ec0117233..df95ca2624 100644 --- a/src/lib/orionld/common/orionldState.cpp +++ b/src/lib/orionld/common/orionldState.cpp @@ -108,11 +108,7 @@ char hostHeaderNoLF[128]; char hostHeader[256]; // Host: xxx size_t hostHeaderLen; PernotSubCache pernotSubCache; - - -char orionldEntityMapId[64]; // Used by GET /entities in the distributed case, for pagination -KjNode* orionldEntityMap = NULL; -int orionldEntityMapCount = 0; +EntityMap* entityMaps = NULL; // Used by GET /entities in the distributed case, for pagination diff --git a/src/lib/orionld/common/orionldState.h b/src/lib/orionld/common/orionldState.h index d1e3d4ab44..a1f7e580b1 100644 --- a/src/lib/orionld/common/orionldState.h +++ b/src/lib/orionld/common/orionldState.h @@ -60,6 +60,7 @@ extern "C" #include "orionld/types/OrionldHeader.h" // OrionldHeaderSet #include "orionld/types/OrionldAlteration.h" // OrionldAlteration #include "orionld/types/StringArray.h" // StringArray +#include "orionld/types/EntityMap.h" // EntityMap #include "orionld/forwarding/DistOp.h" // DistOp #include "orionld/troe/troe.h" // TroeMode #include "orionld/pernot/PernotSubCache.h" // PernotSubCache @@ -168,7 +169,7 @@ typedef struct OrionldUriParams char* lang; bool local; bool onlyIds; - char* entityMap; + bool entityMap; double observedAtAsDouble; uint64_t mask; @@ -264,6 +265,9 @@ typedef struct OrionldStateIn StringArray typeList; StringArray attrList; + // Entity Map + EntityMap* entityMap; + // Processed wildcards char* pathAttrExpanded; } OrionldStateIn; @@ -615,12 +619,11 @@ extern bool debugCurl; // From orionld.cpp extern bool noCache; // From orionld.cpp extern uint32_t cSubCounters; // Number of subscription counter updates before flush from sub-cache to DB extern PernotSubCache pernotSubCache; -extern char localIpAndPort[135]; // Local address for X-Forwarded-For (from orionld.cpp) +extern EntityMap* entityMaps; // Used by GET /entities in the distributed case, for pagination + +extern char localIpAndPort[135]; // Local address for X-Forwarded-For (from orionld.cpp) extern unsigned long long inReqPayloadMaxSize; extern unsigned long long outReqMsgMaxSize; -extern char orionldEntityMapId[64]; // Used by GET /entities in the distributed case, for pagination -extern KjNode* orionldEntityMap; -extern int orionldEntityMapCount; diff --git a/src/lib/orionld/entityMaps/CMakeLists.txt b/src/lib/orionld/entityMaps/CMakeLists.txt new file mode 100644 index 0000000000..fbf50f6a7d --- /dev/null +++ b/src/lib/orionld/entityMaps/CMakeLists.txt @@ -0,0 +1,39 @@ +# 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 + +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) + +SET (SOURCES + entityMapCreate.cpp + entityMapRemove.cpp + entityMapLookup.cpp + entityMapItemAdd.cpp + entityMapRelease.cpp + entityMapsRelease.cpp +) + +# Include directories +# ----------------------------------------------------------------- +include_directories("${PROJECT_SOURCE_DIR}/src/lib") + + +# Library declaration +# ----------------------------------------------------------------- +ADD_LIBRARY(orionld_entityMaps STATIC ${SOURCES}) diff --git a/src/lib/orionld/entityMaps/entityMapCreate.cpp b/src/lib/orionld/entityMaps/entityMapCreate.cpp new file mode 100644 index 0000000000..ca55b85970 --- /dev/null +++ b/src/lib/orionld/entityMaps/entityMapCreate.cpp @@ -0,0 +1,268 @@ +/* +* +* 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 +* +* Author: Ken Zangelin +*/ +#include // malloc + +extern "C" +{ +#include "kjson/KjNode.h" // KjNode +#include "kjson/kjParse.h" // kjParse +#include "kjson/kjBuilder.h" // kjObject +#include "kjson/kjLookup.h" // kjLookup +#include "kjson/kjRender.h" // kjFastRender (for debugging purposes - LM_T) +} + +#include "logMsg/logMsg.h" // LM_* + +#include "orionld/common/orionldState.h" // orionldState +#include "orionld/common/uuidGenerate.h" // uuidGenerate +#include "orionld/types/EntityMap.h" // EntityMap +#include "orionld/types/OrionldGeoInfo.h" // OrionldGeoInfo +#include "orionld/q/QNode.h" // QNode +#include "orionld/kjTree/kjChildCount.h" // kjChildCount +#include "orionld/forwarding/DistOp.h" // DistOp +#include "orionld/forwarding/distOpLookupByCurlHandle.h" // distOpLookupByCurlHandle +#include "orionld/forwarding/distOpListDebug.h" // distOpListDebug2 +#include "orionld/forwarding/distOpsSend.h" // distOpsSend +#include "orionld/mongoc/mongocEntitiesQuery.h" // mongocEntitiesQuery +#include "orionld/dbModel/dbModelToEntityIdAndTypeObject.h" // dbModelToEntityIdAndTypeObject +#include "orionld/entityMaps/entityMapItemAdd.h" // entityMapItemAdd +#include "orionld/entityMaps/entityMapCreate.h" // Own interface + + + +// ----------------------------------------------------------------------------- +// +// DistOpResponseTreatFunction - +// +typedef int (*DistOpResponseTreatFunction)(DistOp* distOpP, void* callbackParam); + + + +// ----------------------------------------------------------------------------- +// +// distOpsReceive - FIXME: move to orionld/forwarding/distOpsReceive.cpp/h +// +void distOpsReceive(DistOp* distOpList, DistOpResponseTreatFunction treatFunction, void* callbackParam, int requestsSent) +{ + LM_T(LmtCount, ("Receiving %d responses", requestsSent)); + // + // Read the responses to the forwarded requests + // + CURLMsg* msgP; + int msgsLeft; + int responses = 0; + + while ((msgP = curl_multi_info_read(orionldState.curlDoMultiP, &msgsLeft)) != NULL) + { + if (msgP->msg != CURLMSG_DONE) + continue; + + if (msgP->data.result == CURLE_OK) + { + DistOp* distOpP = distOpLookupByCurlHandle(distOpList, msgP->easy_handle); + + if (distOpP == NULL) + { + LM_E(("Unable to find the curl handle of a message, presumably a response to a forwarded request")); + continue; + } + + curl_easy_getinfo(msgP->easy_handle, CURLINFO_RESPONSE_CODE, &distOpP->httpResponseCode); + + LM_T(LmtDistOpResponse, ("%s: received a %d response for a forwarded request; %s", distOpP->regP->regId, distOpP->httpResponseCode, distOpP->rawResponse)); + + if ((distOpP->rawResponse != NULL) && (distOpP->rawResponse[0] != 0)) + distOpP->responseBody = kjParse(orionldState.kjsonP, distOpP->rawResponse); + + treatFunction(distOpP, callbackParam); + ++responses; + } + } + + LM_W(("********************** Expected %d responses, got %d", requestsSent, responses)); +} + + + +// ----------------------------------------------------------------------------- +// +// idListResponse - callback function for distOpMatchIdsGet +// +static int idListResponse(DistOp* distOpP, void* callbackParam) +{ + EntityMap* entityMap = (EntityMap*) callbackParam; + + if ((distOpP->httpResponseCode == 200) && (distOpP->responseBody != NULL)) + { + kjTreeLog(distOpP->responseBody, "DistOp RESPONSE", LmtCount); + for (KjNode* eIdNodeP = distOpP->responseBody->value.firstChildP; eIdNodeP != NULL; eIdNodeP = eIdNodeP->next) + { + // FIXME: The response is supposed to be an array of entity ids + // However, when 3 inter-registered brokers run, I get the second response instead of + // the first - the first response seems to go missing somewhere... + // This is an UGLY attempt to "make it work" + // + KjNode* eP = (eIdNodeP->type == KjObject)? kjLookup(eIdNodeP, "id") : eIdNodeP; + LM_T(LmtCount, ("JSON Type of array item: %s", kjValueType(eIdNodeP->type))); + + char* entityId = eP->value.s; + + LM_T(LmtEntityMap, ("o Entity '%s', distOp '%s', registration '%s'", entityId, distOpP->id, distOpP->regP->regId)); + entityMapItemAdd(entityMap, entityId, distOpP); + } + } + + return 0; +} + + + +// ----------------------------------------------------------------------------- +// +// distOpMatchIdsRequest - +// +static void distOpMatchIdsRequest(DistOp* distOpList, EntityMap* entityMap) +{ + if (distOpList == NULL) + return; + + distOpListDebug2(distOpList, "DistOps before sending the onlyId=true requests"); + // Send all distributed requests + int forwards = distOpsSend(distOpList, orionldState.in.aerOS); + + // Await all responses, if any + if (forwards > 0) + distOpsReceive(distOpList, idListResponse, entityMap, forwards); +} + + + +// ----------------------------------------------------------------------------- +// +// entityMapCreate +// +EntityMap* entityMapCreate(DistOp* distOpList, char* idPattern, QNode* qNode, OrionldGeoInfo* geoInfoP) +{ + EntityMap* entityMap = (EntityMap*) malloc(sizeof(EntityMap)); + if (entityMap == NULL) + LM_X(1, ("Out of memory allocating a memory map")); + + entityMap->map = kjObject(NULL, "EntityMap"); + if (entityMap->map == NULL) + LM_X(1, ("Out of memory allocating a memory map")); + + uuidGenerate(entityMap->id, sizeof(entityMap->id), "urn:ngsi-ld:entity-map:"); + + LM_T(LmtDistOpList, ("Created an entity map at %p (%s)", entityMap, entityMap->id)); + + // + // Send requests to all matching registration-endpoints, to fill in the entity map + // + distOpMatchIdsRequest(distOpList, entityMap); // Not including local hits + + kjTreeLog(entityMap->map, "entityMap", LmtSR); + +#if 0 + // + // if there are no entity hits to the matching registrations, the request is treated as a local request + // + if (entityMap->map->value.firstChildP == NULL) + return NULL; // leaks ... +#endif + + char* geojsonGeometryLongName = NULL; + if (orionldState.out.contentType == GEOJSON) + geojsonGeometryLongName = orionldState.in.geometryPropertyExpanded; + + // Get the local matches + KjNode* localEntityV = NULL; + LM_T(LmtMongoc, ("orionldState.in.attrList.items: %d", orionldState.in.attrList.items)); + LM_T(LmtMongoc, ("Calling mongocEntitiesQuery")); + + // + // Can't do any pagination in this step, and we only really need the Entity ID + // Need to teporarily modify the users input for that + // + int offset = orionldState.uriParams.offset; + int limit = orionldState.uriParams.limit; + + orionldState.uriParams.offset = 0; + orionldState.uriParams.limit = 1000; + + KjNode* localDbMatches = mongocEntitiesQuery(&orionldState.in.typeList, + &orionldState.in.idList, + idPattern, + &orionldState.in.attrList, + qNode, + geoInfoP, + NULL, + geojsonGeometryLongName, + true); + + orionldState.uriParams.offset = offset; + orionldState.uriParams.limit = limit; + + kjTreeLog(localDbMatches, "localDbMatches", LmtSR); + if (localDbMatches != NULL) + { + localEntityV = dbModelToEntityIdAndTypeObject(localDbMatches); + LM_T(LmtEntityMap, ("Adding local entities to the entityMap")); + kjTreeLog(localEntityV, "localEntityV", LmtEntityMap); + for (KjNode* eidNodeP = localEntityV->value.firstChildP; eidNodeP != NULL; eidNodeP = eidNodeP->next) + { + const char* entityId = eidNodeP->value.s; + + LM_T(LmtEntityMap, ("o Entity '%s', distOp 'local'", entityId)); + entityMapItemAdd(entityMap, entityId, NULL); + } + } + + entityMap->count = kjChildCount(entityMap->map); + kjTreeLog(entityMap->map, "EntityMap", LmtCount); + LM_T(LmtCount, ("COUNT: Items in Entity Map: %d", entityMap->count)); + + // + if (lmTraceIsSet(LmtEntityMap) == true) + { + int ix = 0; + + LM_T(LmtEntityMap, ("Entity Maps (%d):", entityMap->count)); + kjTreeLog(entityMap->map, "EntityMap", LmtEntityMap); + + for (KjNode* entityP = entityMap->map->value.firstChildP; entityP != NULL; entityP = entityP->next) + { + char rBuf[1024]; + + bzero(rBuf, 1024); + kjFastRender(entityP, rBuf); + LM_T(LmtEntityMap, (" %03d '%s': %s", ix, entityP->name, rBuf)); + ++ix; + } + } + kjTreeLog(entityMap->map, "EntityMap", LmtSR); + // + + return entityMap; +} diff --git a/src/lib/orionld/entityMaps/entityMapCreate.h b/src/lib/orionld/entityMaps/entityMapCreate.h new file mode 100644 index 0000000000..b956d32351 --- /dev/null +++ b/src/lib/orionld/entityMaps/entityMapCreate.h @@ -0,0 +1,41 @@ +#ifndef SRC_LIB_ORIONLD_ENTITYMAP_ENTITYMAPCREATE_H_ +#define SRC_LIB_ORIONLD_ENTITYMAP_ENTITYMAPCREATE_H_ + +/* +* +* 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 +* +* Author: Ken Zangelin +*/ +#include "orionld/types/EntityMap.h" // EntityMap +#include "orionld/forwarding/DistOp.h" // DistOp +#include "orionld/types/OrionldGeoInfo.h" // OrionldGeoInfo +#include "orionld/q/QNode.h" // QNode + + + +// ----------------------------------------------------------------------------- +// +// entityMapCreate +// +extern EntityMap* entityMapCreate(DistOp* distOpList, char* idPattern, QNode* qNode, OrionldGeoInfo* geoInfoP); + +#endif // SRC_LIB_ORIONLD_ENTITYMAP_ENTITYMAPCREATE_H_ diff --git a/src/lib/orionld/entityMaps/entityMapItemAdd.cpp b/src/lib/orionld/entityMaps/entityMapItemAdd.cpp new file mode 100644 index 0000000000..d74c3702f1 --- /dev/null +++ b/src/lib/orionld/entityMaps/entityMapItemAdd.cpp @@ -0,0 +1,68 @@ +/* +* +* 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 +* +* Author: Ken Zangelin +*/ +extern "C" +{ +#include "kjson/KjNode.h" // KjNode +#include "kjson/kjLookup.h" // kjLookup +#include "kjson/kjBuilder.h" // kjChildAdd +} + +#include "logMsg/logMsg.h" // LM_* + +#include "orionld/types/EntityMap.h" // EntityMap +#include "orionld/forwarding/DistOp.h" // DistOp +#include "orionld/entityMaps/entityMapItemAdd.h" // Own interface + + + +// ----------------------------------------------------------------------------- +// +// entityMapItemAdd - +// +void entityMapItemAdd(EntityMap* entityMap, const char* entityId, DistOp* distOpP) +{ + KjNode* matchP = kjLookup(entityMap->map, entityId); + + LM_T(LmtCount, ("entity id: '%s'", entityId)); + + if (matchP == NULL) + { + // + // The entity ID is not present in the list - must be added + // + LM_T(LmtEntityMap, ("The entity ID '%s' is not present in the list - adding it", entityId)); + matchP = kjArray(NULL, entityId); + kjChildAdd(entityMap->map, matchP); + } + + // + // Add DistOp ID to matchP's array - remember it's a global variable, can't use kaAlloc + // + const char* distOpId = (distOpP != NULL)? distOpP->regP->regId : "@none"; + KjNode* distOpIdNodeP = kjString(NULL, NULL, distOpId); + + LM_T(LmtEntityMap, ("Adding DistOp '%s' to entity '%s'", distOpId, matchP->name)); + kjChildAdd(matchP, distOpIdNodeP); +} diff --git a/src/lib/orionld/entityMaps/entityMapItemAdd.h b/src/lib/orionld/entityMaps/entityMapItemAdd.h new file mode 100644 index 0000000000..2326cc98f6 --- /dev/null +++ b/src/lib/orionld/entityMaps/entityMapItemAdd.h @@ -0,0 +1,39 @@ +#ifndef SRC_LIB_ORIONLD_ENTITYMAP_ENTITYMAPITEMADD_H_ +#define SRC_LIB_ORIONLD_ENTITYMAP_ENTITYMAPITEMADD_H_ + +/* +* +* 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 +* +* Author: Ken Zangelin +*/ +#include "orionld/types/EntityMap.h" // EntityMap +#include "orionld/forwarding/DistOp.h" // DistOp + + + +// ----------------------------------------------------------------------------- +// +// entityMapItemAdd - +// +extern void entityMapItemAdd(EntityMap* entityMap, const char* entityId, DistOp* distOpP); + +#endif // SRC_LIB_ORIONLD_ENTITYMAP_ENTITYMAPITEMADD_H_ diff --git a/src/lib/orionld/entityMaps/entityMapLookup.cpp b/src/lib/orionld/entityMaps/entityMapLookup.cpp new file mode 100644 index 0000000000..0ed42c2b8d --- /dev/null +++ b/src/lib/orionld/entityMaps/entityMapLookup.cpp @@ -0,0 +1,50 @@ +/* +* +* 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 +* +* Author: Ken Zangelin +*/ +#include // strcmp + +#include "orionld/common/orionldState.h" // entityMaps +#include "orionld/types/EntityMap.h" // EntityMap +#include "orionld/entityMaps/entityMapLookup.h" // Own interface + + + +// ----------------------------------------------------------------------------- +// +// entityMapLookup +// +EntityMap* entityMapLookup(const char* mapId) +{ + EntityMap* emP = entityMaps; + + while (emP != NULL) + { + if (strcmp(emP->id, mapId) == 0) + return emP; + + emP = emP->next; + } + + return NULL; +} diff --git a/src/lib/orionld/entityMaps/entityMapLookup.h b/src/lib/orionld/entityMaps/entityMapLookup.h new file mode 100644 index 0000000000..54990fb969 --- /dev/null +++ b/src/lib/orionld/entityMaps/entityMapLookup.h @@ -0,0 +1,38 @@ +#ifndef SRC_LIB_ORIONLD_ENTITYMAP_ENTITYMAPLOOKUP_H_ +#define SRC_LIB_ORIONLD_ENTITYMAP_ENTITYMAPLOOKUP_H_ + +/* +* +* 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 +* +* Author: Ken Zangelin +*/ +#include "orionld/types/EntityMap.h" // EntityMap + + + +// ----------------------------------------------------------------------------- +// +// entityMapLookup +// +extern EntityMap* entityMapLookup(const char* mapId); + +#endif // SRC_LIB_ORIONLD_ENTITYMAP_ENTITYMAPLOOKUP_H_ diff --git a/src/lib/orionld/common/orionldEntityMapRelease.cpp b/src/lib/orionld/entityMaps/entityMapRelease.cpp similarity index 68% rename from src/lib/orionld/common/orionldEntityMapRelease.cpp rename to src/lib/orionld/entityMaps/entityMapRelease.cpp index 3d4c354743..2199049ef8 100644 --- a/src/lib/orionld/common/orionldEntityMapRelease.cpp +++ b/src/lib/orionld/entityMaps/entityMapRelease.cpp @@ -1,6 +1,6 @@ /* * -* Copyright 2022 FIWARE Foundation e.V. +* Copyright 2023 FIWARE Foundation e.V. * * This file is part of Orion-LD Context Broker. * @@ -22,29 +22,24 @@ * * Author: Ken Zangelin */ -#include // bzero +#include // free extern "C" { -#include "kjson/kjFree.h" // kjFree +#include "kjson/kjFree.h" // kjFree } -#include "orionld/common/orionldState.h" // orionldEntityMap +#include "orionld/types/EntityMap.h" // EntityMap +#include "orionld/entityMaps/entityMapRelease.h" // Own interface // ----------------------------------------------------------------------------- // -// orionldEntityMapRelease - +// entityMapsRelease - // -void orionldEntityMapRelease(void) +void entityMapRelease(EntityMap* emP) { - if (orionldEntityMap != NULL) - { - kjFree(orionldEntityMap); - bzero(orionldEntityMapId, sizeof(orionldEntityMapId)); - - orionldEntityMap = NULL; - orionldEntityMapCount = 0; - } + kjFree(emP->map); + free(emP); } diff --git a/src/lib/orionld/entityMaps/entityMapRelease.h b/src/lib/orionld/entityMaps/entityMapRelease.h new file mode 100644 index 0000000000..afd3b5d333 --- /dev/null +++ b/src/lib/orionld/entityMaps/entityMapRelease.h @@ -0,0 +1,38 @@ +#ifndef SRC_LIB_ORIONLD_ENTITYMAP_ENTITYMAPRELEASE_H_ +#define SRC_LIB_ORIONLD_ENTITYMAP_ENTITYMAPRELEASE_H_ + +/* +* +* 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 +* +* Author: Ken Zangelin +*/ +#include "orionld/types/EntityMap.h" // EntityMap + + + +// ----------------------------------------------------------------------------- +// +// entityMapRelease - +// +extern void entityMapRelease(EntityMap* entityMap); + +#endif // SRC_LIB_ORIONLD_ENTITYMAP_ENTITYMAPRELEASE_H_ diff --git a/src/lib/orionld/entityMaps/entityMapRemove.cpp b/src/lib/orionld/entityMaps/entityMapRemove.cpp new file mode 100644 index 0000000000..0722f662ce --- /dev/null +++ b/src/lib/orionld/entityMaps/entityMapRemove.cpp @@ -0,0 +1,63 @@ +/* +* +* 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 +* +* Author: Ken Zangelin +*/ +#include // strcmp + +#include "orionld/common/orionldState.h" // entityMaps +#include "orionld/types/EntityMap.h" // EntityMap +#include "orionld/entityMaps/entityMapRemove.h" // Own interface + + + +// ----------------------------------------------------------------------------- +// +// entityMapRemove - +// +EntityMap* entityMapRemove(const char* mapId) +{ + EntityMap* emP = entityMaps; + EntityMap* prev = NULL; + + while (emP != NULL) + { + if (strcmp(emP->id, mapId) == 0) + break; + prev = emP; + + emP = emP->next; + } + + if (emP == NULL) + LM_RE(NULL, ("Internal Error (can't remove the entity map '%s' - not found", mapId)); + + // First? + if (emP == entityMaps) + entityMaps = emP->next; + else if (emP->next == NULL) + prev->next = NULL; + else + prev->next = emP->next; + + return emP; +} diff --git a/src/lib/orionld/common/orionldEntityMapRelease.h b/src/lib/orionld/entityMaps/entityMapRemove.h similarity index 80% rename from src/lib/orionld/common/orionldEntityMapRelease.h rename to src/lib/orionld/entityMaps/entityMapRemove.h index 1057aedded..834f6f1869 100644 --- a/src/lib/orionld/common/orionldEntityMapRelease.h +++ b/src/lib/orionld/entityMaps/entityMapRemove.h @@ -1,5 +1,5 @@ -#ifndef SRC_LIB_ORIONLD_COMMON_ORIONLDENTITYMAPRELEASE_H_ -#define SRC_LIB_ORIONLD_COMMON_ORIONLDENTITYMAPRELEASE_H_ +#ifndef SRC_LIB_ORIONLD_ENTITYMAP_ENTITYMAPREMOVE_H_ +#define SRC_LIB_ORIONLD_ENTITYMAP_ENTITYMAPREMOVE_H_ /* * @@ -30,8 +30,8 @@ // ----------------------------------------------------------------------------- // -// orionldEntityMapRelease - +// entityMapRemove - // -extern void orionldEntityMapRelease(void); +extern EntityMap* entityMapRemove(const char* mapId); -#endif // SRC_LIB_ORIONLD_COMMON_ORIONLDENTITYMAPRELEASE_H_ +#endif // SRC_LIB_ORIONLD_ENTITYMAP_ENTITYMAPREMOVE_H_ diff --git a/src/lib/orionld/entityMaps/entityMapsRelease.cpp b/src/lib/orionld/entityMaps/entityMapsRelease.cpp new file mode 100644 index 0000000000..dd4d210203 --- /dev/null +++ b/src/lib/orionld/entityMaps/entityMapsRelease.cpp @@ -0,0 +1,48 @@ +/* +* +* 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 +* +* Author: Ken Zangelin +*/ +#include // NULL + +#include "orionld/common/orionldState.h" // entityMaps +#include "orionld/types/EntityMap.h" // EntityMap +#include "orionld/entityMaps/entityMapRelease.h" // entityMapRelease +#include "orionld/entityMaps/entityMapsRelease.h" // Own interface + + + +// ----------------------------------------------------------------------------- +// +// entityMapsRelease - +// +void entityMapsRelease(void) +{ + EntityMap* emP = entityMaps; + + while (emP != NULL) + { + EntityMap* next = emP->next; + entityMapRelease(emP); + emP = next; + } +} diff --git a/src/lib/orionld/entityMaps/entityMapsRelease.h b/src/lib/orionld/entityMaps/entityMapsRelease.h new file mode 100644 index 0000000000..a5a0da496d --- /dev/null +++ b/src/lib/orionld/entityMaps/entityMapsRelease.h @@ -0,0 +1,38 @@ +#ifndef SRC_LIB_ORIONLD_ENTITYMAP_ENTITYMAPSRELEASE_H_ +#define SRC_LIB_ORIONLD_ENTITYMAP_ENTITYMAPSRELEASE_H_ + +/* +* +* 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 +* +* Author: Ken Zangelin +*/ +#include "orionld/types/EntityMap.h" // EntityMap + + + +// ----------------------------------------------------------------------------- +// +// entityMapsRelease - +// +extern void entityMapsRelease(void); + +#endif // SRC_LIB_ORIONLD_ENTITYMAP_ENTITYMAPRELEASE_H_ diff --git a/src/lib/orionld/rest/orionldMhdConnectionInit.cpp b/src/lib/orionld/rest/orionldMhdConnectionInit.cpp index 40010aab9c..e4f315ac18 100644 --- a/src/lib/orionld/rest/orionldMhdConnectionInit.cpp +++ b/src/lib/orionld/rest/orionldMhdConnectionInit.cpp @@ -53,6 +53,7 @@ extern "C" #include "orionld/common/orionldTenantLookup.h" // orionldTenantLookup #include "orionld/serviceRoutines/orionldBadVerb.h" // orionldBadVerb #include "orionld/payloadCheck/pCheckUri.h" // pCheckUri +#include "orionld/entityMaps/entityMapLookup.h" // entityMapLookup #include "orionld/rest/orionldServiceInit.h" // orionldRestServiceV #include "orionld/rest/orionldServiceLookup.h" // orionldServiceLookup #include "orionld/rest/OrionLdRestService.h" // ORIONLD_URIPARAM_LIMIT, ... @@ -447,6 +448,12 @@ static MHD_Result orionldHttpHeaderReceive(void* cbDataP, MHD_ValueKind kind, co orionldError(OrionldBadRequestData, "Bad value for HTTP header /NGSILD-Scope/", value, 400); } } + else if (strcasecmp(key, "NGSILD-EntityMap") == 0) + { + orionldState.in.entityMap = entityMapLookup(value); + if (orionldState.in.entityMap == NULL) + orionldError(OrionldResourceNotFound, "Entity-Map not found", value, 404); + } else if (strcasecmp(key, "Accept") == 0) { orionldState.out.contentType = acceptHeaderParse((char*) value, false); @@ -961,7 +968,8 @@ MHD_Result orionldUriArgumentGet(void* cbDataP, MHD_ValueKind kind, const char* } else if (strcmp(key, "entityMap") == 0) { - orionldState.uriParams.entityMap = (char*) value; + if (strcmp(value, "true") == 0) + orionldState.uriParams.entityMap = true; orionldState.uriParams.mask |= ORIONLD_URIPARAM_ENTITYMAP; } diff --git a/src/lib/orionld/serviceRoutines/orionldDeleteEntityMap.cpp b/src/lib/orionld/serviceRoutines/orionldDeleteEntityMap.cpp index 31818bc06c..2c22f2a2ac 100644 --- a/src/lib/orionld/serviceRoutines/orionldDeleteEntityMap.cpp +++ b/src/lib/orionld/serviceRoutines/orionldDeleteEntityMap.cpp @@ -26,7 +26,9 @@ #include "orionld/common/orionldState.h" // orionldState, orionldEntityMapId #include "orionld/common/orionldError.h" // orionldError -#include "orionld/common/orionldEntityMapRelease.h" // orionldEntityMapRelease +#include "orionld/types/EntityMap.h" // EntityMap +#include "orionld/entityMaps/entityMapRemove.h" // entityMapRemove +#include "orionld/entityMaps/entityMapRelease.h" // entityMapRelease #include "orionld/serviceRoutines/orionldDeleteEntityMap.h" // Own interface @@ -38,15 +40,16 @@ bool orionldDeleteEntityMap(void) { const char* entityMapId = orionldState.wildcard[0]; + EntityMap* entityMap = entityMapRemove(entityMapId); - if (strcmp(entityMapId, orionldEntityMapId) != 0) // For now we only have one single entity map + if (entityMap == NULL) { orionldError(OrionldResourceNotFound, "EntityMap Not Found", entityMapId, 404); return false; } - LM_T(LmtSR, ("Deleting entity map '%s'", orionldEntityMapId)); - orionldEntityMapRelease(); + LM_T(LmtSR, ("Deleting entity map '%s'", entityMapId)); + entityMapRelease(entityMap); return true; } diff --git a/src/lib/orionld/serviceRoutines/orionldGetEntities.cpp b/src/lib/orionld/serviceRoutines/orionldGetEntities.cpp index 1e2c066634..28b3ba4f10 100644 --- a/src/lib/orionld/serviceRoutines/orionldGetEntities.cpp +++ b/src/lib/orionld/serviceRoutines/orionldGetEntities.cpp @@ -33,7 +33,6 @@ extern "C" #include "orionld/common/orionldState.h" // orionldState #include "orionld/common/orionldError.h" // orionldError -#include "orionld/common/orionldEntityMapRelease.h" // orionldEntityMapRelease #include "orionld/types/OrionldGeoInfo.h" // OrionldGeoInfo #include "orionld/legacyDriver/legacyGetEntities.h" // legacyGetEntities #include "orionld/kjTree/kjTreeLog.h" // kjTreeLog @@ -89,7 +88,7 @@ static QNode* qCheck(char* qString) // // pCheckQueryParams - // -bool pCheckQueryParams(char* id, char* type, char* idPattern, char* q, char* geometry, char* attrs, bool local, char* entityMap, QNode** qNodeP, OrionldGeoInfo* geoInfoP) +bool pCheckQueryParams(char* id, char* type, char* idPattern, char* q, char* geometry, char* attrs, bool local, EntityMap* entityMap, QNode** qNodeP, OrionldGeoInfo* geoInfoP) { // // URI param validity check @@ -102,11 +101,11 @@ bool pCheckQueryParams(char* id, char* type, char* idPattern, char* q, char* geo (attrs == NULL) && (q == NULL) && (local == false) && - (entityMap == NULL)) + (orionldState.in.entityMap == NULL)) { orionldError(OrionldBadRequestData, "Too broad query", - "Need at least one of: entity-id, entity-type, geo-location, attribute-list, Q-filter, local=true", + "Need at least one of: entity-id, entity-type, geo-location, attribute-list, Q-filter, local=true, or an entity map", 400); return false; @@ -237,7 +236,6 @@ bool orionldGetEntities(void) char* geometry = orionldState.uriParams.geometry; char* attrs = orionldState.uriParams.attrs; // Validity checked in orionldMhdConnectionTreat.cpp (pCheckAttrsParam) bool local = orionldState.uriParams.local; - char* entityMap = orionldState.uriParams.entityMap; QNode* qNode = NULL; LM_T(LmtEntityMap, ("onlyIds: %s", (orionldState.uriParams.onlyIds == true)? "TRUE" : "FALSE")); @@ -247,29 +245,10 @@ bool orionldGetEntities(void) idPattern = NULL; OrionldGeoInfo geoInfo; - if (pCheckQueryParams(id, type, idPattern, q, geometry, attrs, local, entityMap, &qNode, &geoInfo) == false) + if (pCheckQueryParams(id, type, idPattern, q, geometry, attrs, local, orionldState.in.entityMap, &qNode, &geoInfo) == false) return false; - // Is an entity map in use? - if (orionldState.uriParams.entityMap != NULL) - { - if (strcmp(orionldState.uriParams.entityMap, orionldEntityMapId) != 0) - { - orionldError(OrionldResourceNotFound, "Entity Map Not Found", orionldState.uriParams.entityMap, 404); - return false; - } - } - - if (orionldState.uriParams.reset == true) - { - LM_T(LmtSR, ("Deleting entity map '%s'", orionldEntityMapId)); - orionldEntityMapRelease(); - orionldEntityMap = NULL; - orionldEntityMapCount = 0; - orionldState.uriParams.entityMap = NULL; - entityMap = NULL; - } - else if (orionldState.uriParams.entityMap != NULL) + if (orionldState.in.entityMap != NULL) { // No query params can be used when asking for pages in an entity map if ((id != NULL) || (type != NULL) || (idPattern != NULL) || (q != NULL) || @@ -293,7 +272,7 @@ bool orionldGetEntities(void) orionldState.uriParams.onlyIds, false); - if (orionldState.uriParams.entityMap == NULL) + if (orionldState.in.entityMap == NULL) // No prior entity map is requested - must create a new one { // // Find matching registrations diff --git a/src/lib/orionld/serviceRoutines/orionldGetEntitiesDistributed.cpp b/src/lib/orionld/serviceRoutines/orionldGetEntitiesDistributed.cpp index b92cff04b1..479cc83aa1 100644 --- a/src/lib/orionld/serviceRoutines/orionldGetEntitiesDistributed.cpp +++ b/src/lib/orionld/serviceRoutines/orionldGetEntitiesDistributed.cpp @@ -28,24 +28,15 @@ extern "C" #include "kjson/kjFree.h" // kjFree #include "kjson/kjLookup.h" // kjLookup #include "kjson/kjBuilder.h" // kjChildRemove, kjChildAdd, kjArray -#include "kjson/kjParse.h" // kjParse -#include "kjson/kjRender.h" // kjRender (for debugging purposes - LM_T) } #include "logMsg/logMsg.h" // LM_* -#include "logMsg/traceLevels.h" // LmtMongoc #include "orionld/common/orionldState.h" // orionldState -#include "orionld/common/uuidGenerate.h" // uuidGenerate #include "orionld/types/OrionldGeoInfo.h" // OrionldGeoInfo #include "orionld/q/QNode.h" // QNode -#include "orionld/mongoc/mongocEntitiesQuery.h" // mongocEntitiesQuery -#include "orionld/dbModel/dbModelToEntityIdAndTypeObject.h" // dbModelToEntityIdAndTypeObject #include "orionld/forwarding/DistOp.h" // DistOp -#include "orionld/forwarding/distOpsSend.h" // distOpsSend -#include "orionld/forwarding/distOpLookupByCurlHandle.h" // distOpLookupByCurlHandle -#include "orionld/forwarding/distOpListDebug.h" // distOpListDebug2 -#include "orionld/kjTree/kjChildCount.h" // kjChildCount +#include "orionld/entityMaps/entityMapCreate.h" // entityMapCreate #include "orionld/serviceRoutines/orionldGetEntitiesLocal.h" // orionldGetEntitiesLocal #include "orionld/serviceRoutines/orionldGetEntitiesPage.h" // orionldGetEntitiesPage #include "orionld/serviceRoutines/orionldGetEntitiesDistributed.h" // Own interface @@ -58,7 +49,7 @@ extern "C" // // - To be able to do pagination, we need a list of all matching entities: // -// "orionldEntityMap": { +// "EntityMap": { // "urn:E1": [ null ], # null indicates it was found locally // "urn:E2": [ null ], // "urn:E3": [ null ], @@ -78,9 +69,9 @@ extern "C" // Mechanism: // 1. GET a list of all matching registrations. // 2. Query them all (locally as well) for their 'Entity Id Array' -// 3. Merge all the reponses into one single array (orionldEntityMap) +// 3. Merge all the reponses into one single array (orionldState,in.EntityMap) // 4. Now we have a list and we can do pagination. -// 5. Just pick the start index and end index of orionldEntityMap and: +// 5. Just pick the start index and end index of the EntityMap and: // - Identify each registered endpoint to be queried (from start index to end index) // - Gather all entity ids for each registered endpoint // - query using (GET /entities?id=E1,E2,E3,...En) @@ -92,60 +83,6 @@ extern "C" -// ----------------------------------------------------------------------------- -// -// DistOpResponseTreatFunction - -// -typedef int (*DistOpResponseTreatFunction)(DistOp* distOpP, void* callbackParam); - - - -// ----------------------------------------------------------------------------- -// -// distOpsReceive - FIXME: move to orionld/forwarding/distOpsReceive.cpp/h -// -void distOpsReceive(DistOp* distOpList, DistOpResponseTreatFunction treatFunction, void* callbackParam, int requestsSent) -{ - LM_T(LmtCount, ("Receiving %d responses", requestsSent)); - // - // Read the responses to the forwarded requests - // - CURLMsg* msgP; - int msgsLeft; - int responses = 0; - - while ((msgP = curl_multi_info_read(orionldState.curlDoMultiP, &msgsLeft)) != NULL) - { - if (msgP->msg != CURLMSG_DONE) - continue; - - if (msgP->data.result == CURLE_OK) - { - DistOp* distOpP = distOpLookupByCurlHandle(distOpList, msgP->easy_handle); - - if (distOpP == NULL) - { - LM_E(("Unable to find the curl handle of a message, presumably a response to a forwarded request")); - continue; - } - - curl_easy_getinfo(msgP->easy_handle, CURLINFO_RESPONSE_CODE, &distOpP->httpResponseCode); - - LM_T(LmtDistOpResponse, ("%s: received a %d response for a forwarded request; %s", distOpP->regP->regId, distOpP->httpResponseCode, distOpP->rawResponse)); - - if ((distOpP->rawResponse != NULL) && (distOpP->rawResponse[0] != 0)) - distOpP->responseBody = kjParse(orionldState.kjsonP, distOpP->rawResponse); - - treatFunction(distOpP, callbackParam); - ++responses; - } - } - - LM_W(("********************** Expected %d responses, got %d", requestsSent, responses)); -} - - - // // Entity Map // @@ -206,186 +143,6 @@ void distOpsReceive(DistOp* distOpList, DistOpResponseTreatFunction treatFunctio // It will need to - the URL params from the first request (when the Entity Map was created) must be saved // -// ----------------------------------------------------------------------------- -// -// entityMapItemAdd - -// -static void entityMapItemAdd(const char* entityId, DistOp* distOpP) -{ - KjNode* matchP = kjLookup(orionldEntityMap, entityId); - - LM_T(LmtCount, ("entity id: '%s'", entityId)); - - if (matchP == NULL) - { - // - // The entity ID is not present in the list - must be added - // - LM_T(LmtEntityMap, ("The entity ID '%s' is not present in the list - adding it", entityId)); - matchP = kjArray(NULL, entityId); - kjChildAdd(orionldEntityMap, matchP); - } - - // - // Add DistOp ID to matchP's array - remember it's a global variable, can't use kaAlloc - // - // const char* distOpId = (distOpP != NULL)? distOpP->id : "@none"; - const char* distOpId = (distOpP != NULL)? distOpP->regP->regId : "@none"; - KjNode* distOpIdNodeP = kjString(NULL, NULL, distOpId); - - LM_T(LmtEntityMap, ("Adding DistOp '%s' to entity '%s'", distOpId, matchP->name)); - kjChildAdd(matchP, distOpIdNodeP); -} - - - -// ----------------------------------------------------------------------------- -// -// idListResponse - callback function for distOpMatchIdsGet -// -int idListResponse(DistOp* distOpP, void* callbackParam) -{ - if ((distOpP->httpResponseCode == 200) && (distOpP->responseBody != NULL)) - { - kjTreeLog(distOpP->responseBody, "DistOp RESPONSE", LmtCount); - for (KjNode* eIdNodeP = distOpP->responseBody->value.firstChildP; eIdNodeP != NULL; eIdNodeP = eIdNodeP->next) - { - // FIXME: The response is supposed to be an array of entity ids - // However, when 3 inter-registered brokers run, I get the second response instead of - // the first - the first response seems to go missing somewhere... - // This is an UGLY attempt to "make it work" - // - KjNode* eP = (eIdNodeP->type == KjObject)? kjLookup(eIdNodeP, "id") : eIdNodeP; - LM_T(LmtCount, ("JSON Type of array item: %s", kjValueType(eIdNodeP->type))); - - char* entityId = eP->value.s; - - LM_T(LmtEntityMap, ("o Entity '%s', distOp '%s', registration '%s'", entityId, distOpP->id, distOpP->regP->regId)); - entityMapItemAdd(entityId, distOpP); - } - } - - return 0; -} - - - -// ----------------------------------------------------------------------------- -// -// distOpMatchIdsRequest - -// -static void distOpMatchIdsRequest(DistOp* distOpList) -{ - if (distOpList == NULL) - return; - - distOpListDebug2(distOpList, "DistOps before sending the onlyId=true requests"); - // Send all distributed requests - int forwards = distOpsSend(distOpList, orionldState.in.aerOS); - - // Await all responses, if any - if (forwards > 0) - distOpsReceive(distOpList, idListResponse, orionldEntityMap, forwards); -} - - - -// ----------------------------------------------------------------------------- -// -// entityMapCreate - -// -static void entityMapCreate(DistOp* distOpList, char* idPattern, QNode* qNode, OrionldGeoInfo* geoInfoP) -{ - orionldEntityMap = kjObject(NULL, "orionldEntityMap"); - LM_T(LmtDistOpList, ("Created an entity map at %p", orionldEntityMap)); - - // - // Send requests to all matching registration-endpoints, to fill in the entity map - // - distOpMatchIdsRequest(distOpList); // Not including local hits - - kjTreeLog(orionldEntityMap, "orionldEntityMap", LmtSR); - - // - // if there are no entity hits to the matching registrations, the request is treated as a local request - // - if (orionldEntityMap->value.firstChildP == NULL) - return; - - char* geojsonGeometryLongName = NULL; - if (orionldState.out.contentType == GEOJSON) - geojsonGeometryLongName = orionldState.in.geometryPropertyExpanded; - - // Get the local matches - KjNode* localEntityV = NULL; - LM_T(LmtMongoc, ("orionldState.in.attrList.items: %d", orionldState.in.attrList.items)); - LM_T(LmtMongoc, ("Calling mongocEntitiesQuery")); - - // - // Can't do any pagination in this step, and we only really need the Entity ID - // Need to teporarily modify the users input for that - // - int offset = orionldState.uriParams.offset; - int limit = orionldState.uriParams.limit; - - orionldState.uriParams.offset = 0; - orionldState.uriParams.limit = 1000; - - KjNode* localDbMatches = mongocEntitiesQuery(&orionldState.in.typeList, - &orionldState.in.idList, - idPattern, - &orionldState.in.attrList, - qNode, - geoInfoP, - NULL, - geojsonGeometryLongName, - true); - - orionldState.uriParams.offset = offset; - orionldState.uriParams.limit = limit; - - kjTreeLog(localDbMatches, "localDbMatches", LmtSR); - if (localDbMatches != NULL) - { - localEntityV = dbModelToEntityIdAndTypeObject(localDbMatches); - LM_T(LmtEntityMap, ("Adding local entities to the entityMap")); - kjTreeLog(localEntityV, "localEntityV", LmtEntityMap); - for (KjNode* eidNodeP = localEntityV->value.firstChildP; eidNodeP != NULL; eidNodeP = eidNodeP->next) - { - const char* entityId = eidNodeP->value.s; - - LM_T(LmtEntityMap, ("o Entity '%s', distOp 'local'", entityId)); - entityMapItemAdd(entityId, NULL); - } - } - - orionldEntityMapCount = kjChildCount(orionldEntityMap); - kjTreeLog(orionldEntityMap, "orionldEntityMap", LmtCount); - LM_T(LmtCount, ("COUNT: Items in orionldEntityMap: %d", orionldEntityMapCount)); - - // - if (lmTraceIsSet(LmtEntityMap) == true) - { - int ix = 0; - - LM_T(LmtEntityMap, ("Entity Maps (%d):", orionldEntityMapCount)); - kjTreeLog(orionldEntityMap, "orionldEntityMap", LmtEntityMap); - - for (KjNode* entityP = orionldEntityMap->value.firstChildP; entityP != NULL; entityP = entityP->next) - { - char rBuf[1024]; - - bzero(rBuf, 1024); - kjFastRender(entityP, rBuf); - LM_T(LmtEntityMap, (" %03d '%s': %s", ix, entityP->name, rBuf)); - ++ix; - } - } - kjTreeLog(orionldEntityMap, "orionldEntityMap", LmtSR); - // -} - - // ---------------------------------------------------------------------------- // @@ -393,32 +150,40 @@ static void entityMapCreate(DistOp* distOpList, char* idPattern, QNode* qNode, O // bool orionldGetEntitiesDistributed(DistOp* distOpList, char* idPattern, QNode* qNode, OrionldGeoInfo* geoInfoP) { - if (orionldEntityMap != NULL) - { - LM_T(LmtMongoc, ("Calling orionldGetEntitiesPage")); + if (orionldState.in.entityMap != NULL) return orionldGetEntitiesPage(); - } LM_T(LmtCount, ("--------------------------- Creating entity map")); - entityMapCreate(distOpList, idPattern, qNode, geoInfoP); - LM_T(LmtCount, ("--------------------------- Created entity map")); - kjTreeLog(orionldEntityMap, "orionldEntityMap excl local entities", LmtCount); + orionldState.in.entityMap = entityMapCreate(distOpList, idPattern, qNode, geoInfoP); + LM_T(LmtCount, ("--------------------------- entity map at %p", orionldState.in.entityMap)); + if (orionldState.in.entityMap != NULL) + { + LM_T(LmtCount, ("--------------------------- Created entity map")); + kjTreeLog(orionldState.in.entityMap->map, "EntityMap excl local entities", LmtCount); - // Must return the ID of the entity map as an HTTP header - uuidGenerate(orionldEntityMapId, sizeof(orionldEntityMapId), "urn:ngsi-ld:entity-map:"); - orionldHeaderAdd(&orionldState.out.headers, HttpEntityMap, orionldEntityMapId, 0); + // Add the new entity map to the global list of entity maps + // sem-take + orionldState.in.entityMap->next = entityMaps; + entityMaps = orionldState.in.entityMap; + // sem-give - if (orionldState.uriParams.limit == 0) - { - orionldHeaderAdd(&orionldState.out.headers, HttpResultsCount, NULL, orionldEntityMapCount); - orionldState.responseTree = kjArray(orionldState.kjsonP, NULL); - return true; + // Must return the ID of the entity map as an HTTP header + orionldHeaderAdd(&orionldState.out.headers, HttpEntityMap, orionldState.in.entityMap->id, 0); + + if (orionldState.uriParams.limit == 0) + { + orionldHeaderAdd(&orionldState.out.headers, HttpResultsCount, NULL, orionldState.in.entityMap->count); + orionldState.responseTree = kjArray(orionldState.kjsonP, NULL); + return true; + } } + else + LM_E(("entityMapCreate returned NULL")); // // if there are no entity hits to the matching registrations, the request is treated as a local request // - if (orionldEntityMap->value.firstChildP == NULL) + if ((orionldState.in.entityMap == NULL) || (orionldState.in.entityMap->map->value.firstChildP == NULL)) return orionldGetEntitiesLocal(&orionldState.in.typeList, &orionldState.in.idList, &orionldState.in.attrList, diff --git a/src/lib/orionld/serviceRoutines/orionldGetEntitiesPage.cpp b/src/lib/orionld/serviceRoutines/orionldGetEntitiesPage.cpp index cf7efe5e11..9b158700a4 100644 --- a/src/lib/orionld/serviceRoutines/orionldGetEntitiesPage.cpp +++ b/src/lib/orionld/serviceRoutines/orionldGetEntitiesPage.cpp @@ -34,7 +34,7 @@ extern "C" #include "logMsg/logMsg.h" // LM_* #include "logMsg/traceLevels.h" // LmtMongoc -#include "orionld/common/orionldState.h" // orionldState, orionldEntityMapCount +#include "orionld/common/orionldState.h" // orionldState, entityMaps #include "orionld/common/orionldError.h" // orionldError #include "orionld/kjTree/kjChildCount.h" // kjChildCount #include "orionld/kjTree/kjEntityIdLookupInEntityArray.h" // kjEntityIdLookupInEntityArray @@ -373,14 +373,14 @@ static void cleanupSysAttrs(void) // bool orionldGetEntitiesPage(void) { - int offset = orionldState.uriParams.offset; - int limit = orionldState.uriParams.limit; + uint32_t offset = orionldState.uriParams.offset; + uint32_t limit = orionldState.uriParams.limit; KjNode* entityArray = kjArray(orionldState.kjsonP, NULL); LM_T(LmtDistOpResponseDetail, ("entityArray at %p", entityArray)); - LM_T(LmtEntityMap, ("entity map: '%s'", orionldEntityMapId)); - LM_T(LmtEntityMap, ("items in entity map: %d", orionldEntityMapCount)); + LM_T(LmtEntityMap, ("entity map: '%s'", orionldState.in.entityMap->id)); + LM_T(LmtEntityMap, ("items in entity map: %d", orionldState.in.entityMap->count)); LM_T(LmtEntityMap, ("offset: %d", offset)); LM_T(LmtEntityMap, ("limit: %d", limit)); @@ -391,29 +391,29 @@ bool orionldGetEntitiesPage(void) if (orionldState.uriParams.count == true) { - LM_T(LmtEntityMap, ("%d entities match, in the entire federation", orionldEntityMapCount)); - LM_T(LmtEntityMap, ("COUNT: Adding HttpResultsCount header: %d", orionldEntityMapCount)); - orionldHeaderAdd(&orionldState.out.headers, HttpResultsCount, NULL, orionldEntityMapCount); + LM_T(LmtEntityMap, ("%d entities match, in the entire federation", orionldState.in.entityMap->count)); + LM_T(LmtEntityMap, ("COUNT: Adding HttpResultsCount header: %d", orionldState.in.entityMap->count)); + orionldHeaderAdd(&orionldState.out.headers, HttpResultsCount, NULL, orionldState.in.entityMap->count); } - if (offset >= orionldEntityMapCount) + if (offset >= orionldState.in.entityMap->count) { - LM_T(LmtEntityMap, ("offset (%d) >= orionldEntityMapCount (%d)", offset, orionldEntityMapCount)); + LM_T(LmtEntityMap, ("offset (%d) >= orionldState.in.entityMap->count (%d)", offset, orionldState.in.entityMap->count)); return true; } // // Fast forward to offset index in the KJNode array that is the entity map // - KjNode* entityMap = orionldEntityMap->value.firstChildP; - for (int ix = 0; ix < offset; ix++) + KjNode* entityMap = orionldState.in.entityMap->map->value.firstChildP; + for (uint32_t ix = 0; ix < offset; ix++) { entityMap = entityMap->next; } // // entityMap now points to the first entity to give back. - // Must extract all parts of the entities, according to their array inside orionldEntityMap, + // Must extract all parts of the entities, according to their array inside the Entity Map, // and merge them together (in case of distributed entities // @@ -436,7 +436,7 @@ bool orionldGetEntitiesPage(void) // KjNode* sources = kjObject(orionldState.kjsonP, NULL); - for (int ix = 0; ix < limit; ix++) + for (uint32_t ix = 0; ix < limit; ix++) { if (entityMap == NULL) // in case we have less than "limit" break; diff --git a/src/lib/orionld/serviceRoutines/orionldGetEntityMap.cpp b/src/lib/orionld/serviceRoutines/orionldGetEntityMap.cpp index 089052b154..7fc9f0b5c1 100644 --- a/src/lib/orionld/serviceRoutines/orionldGetEntityMap.cpp +++ b/src/lib/orionld/serviceRoutines/orionldGetEntityMap.cpp @@ -30,8 +30,10 @@ extern "C" #include "kjson/kjBuilder.h" // kjObject, kjArray, kjChildAdd, ... } -#include "orionld/common/orionldState.h" // orionldState, orionldEntityMap, orionldEntityMapId +#include "orionld/common/orionldState.h" // orionldState, entityMaps #include "orionld/common/orionldError.h" // orionldError +#include "orionld/types/EntityMap.h" // EntityMap +#include "orionld/entityMaps/entityMapLookup.h" // entityMapLookup #include "orionld/kjTree/kjSort.h" // kjStringArraySort #include "orionld/serviceRoutines/orionldGetEntityMap.h" // Own interface @@ -43,18 +45,17 @@ extern "C" // bool orionldGetEntityMap(void) { - const char* entityMapId = orionldState.wildcard[0]; + const char* entityMapId = orionldState.wildcard[0]; + EntityMap* entityMap = entityMapLookup(entityMapId); - if (strcmp(entityMapId, orionldEntityMapId) != 0) // For now we only have one single entity map + if (entityMap == NULL) { orionldError(OrionldResourceNotFound, "EntityMap Not Found", entityMapId, 404); return false; } - // Cloning the entityMap - to later modify it - // orionldState.responseTree = kjClone(orionldState.kjsonP, orionldEntityMap); - orionldState.responseTree = orionldEntityMap; - kjTreeLog(orionldEntityMap, "orionldEntityMap", LmtSR); + orionldState.responseTree = entityMap->map; + kjTreeLog(entityMap->map, "EntityMap", LmtSR); // Sort all entity arrays in alphabetic order (for functests to work ...) // NOTE; diff --git a/src/lib/orionld/types/EntityMap.h b/src/lib/orionld/types/EntityMap.h new file mode 100644 index 0000000000..1b8b683d98 --- /dev/null +++ b/src/lib/orionld/types/EntityMap.h @@ -0,0 +1,49 @@ +#ifndef SRC_LIB_ORIONLD_TYPES_ENTITYMAP_H_ +#define SRC_LIB_ORIONLD_TYPES_ENTITYMAP_H_ + +/* +* +* 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 +* +* Author: Ken Zangelin +*/ +#include // types: uint32_t, ... + +extern "C" +{ +#include "kjson/KjNode.h" // KjNode +} + + + +// ----------------------------------------------------------------------------- +// +// EntityMap - +// +typedef struct EntityMap +{ + char id[64]; + KjNode* map; + uint32_t count; + struct EntityMap* next; +} EntityMap; + +#endif // SRC_LIB_ORIONLD_TYPES_ENTITYMAP_H_ diff --git a/src/lib/orionld/types/OrionldHeader.cpp b/src/lib/orionld/types/OrionldHeader.cpp index 0899c12691..e3502df758 100644 --- a/src/lib/orionld/types/OrionldHeader.cpp +++ b/src/lib/orionld/types/OrionldHeader.cpp @@ -72,7 +72,7 @@ const char* orionldHeaderName[] = { "Access-Control-Expose-Headers", "Accept-Patch", "Performance", - "Entity-Map" + "NGSILD-EntityMap" }; diff --git a/test/functionalTest/cases/0000_ngsild/ngsild_entityMap-errors.test b/test/functionalTest/cases/0000_ngsild/ngsild_entityMap-errors.test index 1bef4d091c..3173980dd7 100644 --- a/test/functionalTest/cases/0000_ngsild/ngsild_entityMap-errors.test +++ b/test/functionalTest/cases/0000_ngsild/ngsild_entityMap-errors.test @@ -52,7 +52,7 @@ orionldStart CP1 -experimental echo "01. Query the CB with an entity map that doesn't exist - see error" echo "==================================================================" -orionCurl --url /ngsi-ld/v1/entities?entityMap=abc +orionCurl --url /ngsi-ld/v1/entities -H "NGSILD-EntityMap: abc" echo echo @@ -112,14 +112,14 @@ echo echo "05. Query the CB with type=T, to get urn:E1 and the entity map" echo "==============================================================" orionCurl --url /ngsi-ld/v1/entities?type=T -entityMap=$(echo "$_responseHeaders" | grep Entity-Map: | awk -F ': ' '{ print $2 }' | tr -d "\r\n") +entityMap=$(echo "$_responseHeaders" | grep NGSILD-EntityMap: | awk -F ': ' '{ print $2 }' | tr -d "\r\n") echo echo echo "06. Query the CB using the correct entity map but with offset=10 (we don't have that many entities in the map)" echo "==============================================================================================================" -orionCurl --url '/ngsi-ld/v1/entities?entityMap=$entityMap&offset=10' +orionCurl --url '/ngsi-ld/v1/entities?offset=10' -H "NGSILD-EntityMap: $entityMap" echo echo @@ -134,7 +134,7 @@ Date: REGEX(.*) { "detail": "abc", - "title": "Entity Map Not Found", + "title": "Entity-Map not found", "type": "https://uri.etsi.org/ngsi-ld/errors/ResourceNotFound" } @@ -172,8 +172,8 @@ HTTP/1.1 200 OK Content-Length: 114 Content-Type: application/json Date: REGEX(.*) -Entity-Map: urn:ngsi-ld:entity-map:REGEX(.*) Link: >>>>>> feature/entityMaps "urn:R2" ] } @@ -676,12 +662,11 @@ HTTP/1.1 200 OK Content-Length: 781 Content-Type: application/json Date: REGEX(.*) -Entity-Map: urn:ngsi-ld:entity-map:REGEX(.*) Link: >>>>>> feature/entityMaps "urn:R2" ], "urn:E5": [ diff --git a/test/functionalTest/cases/0000_ngsild/ngsild_entityMap_get.test b/test/functionalTest/cases/0000_ngsild/ngsild_entityMap_get.test index 7ea267c7c5..5823352b97 100644 --- a/test/functionalTest/cases/0000_ngsild/ngsild_entityMap_get.test +++ b/test/functionalTest/cases/0000_ngsild/ngsild_entityMap_get.test @@ -232,7 +232,7 @@ echo echo "10. GET /entities, only to create the entityMap" echo "===============================================" orionCurl --url "/ngsi-ld/v1/entities?type=T&limit=0&count=true" -entityMap=$(echo "$_responseHeaders" | grep Entity-Map: | awk -F ': ' '{ print $2 }' | tr -d "\r\n") +entityMap=$(echo "$_responseHeaders" | grep NGSILD-EntityMap: | awk -F ': ' '{ print $2 }' | tr -d "\r\n") echo echo @@ -314,7 +314,7 @@ echo echo "18. GET /entities, only to create a new entityMap" echo "=================================================" orionCurl --url "/ngsi-ld/v1/entities?type=T&count=true&limit=0" -entityMap=$(echo "$_responseHeaders" | grep Entity-Map: | awk -F ': ' '{ print $2 }' | tr -d "\r\n") +entityMap=$(echo "$_responseHeaders" | grep NGSILD-EntityMap: | awk -F ': ' '{ print $2 }' | tr -d "\r\n") echo echo @@ -414,8 +414,8 @@ HTTP/1.1 200 OK Content-Length: 2 Content-Type: application/json Date: REGEX(.*) -Entity-Map: urn:ngsi-ld:entity-map:REGEX(.*) Link: ; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json" +NGSILD-EntityMap: urn:ngsi-ld:entity-map:REGEX(.*) NGSILD-Results-Count: 1 [] @@ -498,8 +498,8 @@ HTTP/1.1 200 OK Content-Length: 2 Content-Type: application/json Date: REGEX(.*) -Entity-Map: urn:ngsi-ld:entity-map:REGEX(.*) Link: ; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json" +NGSILD-EntityMap: urn:ngsi-ld:entity-map:REGEX(.*) NGSILD-Results-Count: 3 [] diff --git a/test/functionalTest/cases/0000_ngsild/ngsild_forward_get_entities-entity-split-over-many-brokers.test b/test/functionalTest/cases/0000_ngsild/ngsild_forward_get_entities-entity-split-over-many-brokers.test index cde70220a2..9299cd7d72 100644 --- a/test/functionalTest/cases/0000_ngsild/ngsild_forward_get_entities-entity-split-over-many-brokers.test +++ b/test/functionalTest/cases/0000_ngsild/ngsild_forward_get_entities-entity-split-over-many-brokers.test @@ -314,8 +314,8 @@ HTTP/1.1 200 OK Content-Length: 351 Content-Type: application/json Date: REGEX(.*) -Entity-Map: urn:ngsi-ld:entity-map:REGEX(.*) Link: ; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json" +NGSILD-EntityMap: urn:ngsi-ld:entity-map:REGEX(.*) [ { diff --git a/test/functionalTest/cases/0000_ngsild/ngsild_three_brokers_and_forwarding_loop_ALL-CONNECTED.test b/test/functionalTest/cases/0000_ngsild/ngsild_three_brokers_and_forwarding_loop_ALL-CONNECTED.test index 27c327adb5..d4091ab05f 100644 --- a/test/functionalTest/cases/0000_ngsild/ngsild_three_brokers_and_forwarding_loop_ALL-CONNECTED.test +++ b/test/functionalTest/cases/0000_ngsild/ngsild_three_brokers_and_forwarding_loop_ALL-CONNECTED.test @@ -295,7 +295,7 @@ echo echo "13. GET /entities?type=T in CB" 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") +entityMap=$(echo "$_responseHeaders" | grep NGSILD-EntityMap: | awk -F ': ' '{ print $2 }' | tr -d "\r\n") echo echo @@ -415,8 +415,8 @@ HTTP/1.1 200 OK Content-Length: REGEX(.*) Content-Type: application/json Date: REGEX(.*) -Entity-Map: urn:ngsi-ld:entity-map:REGEX(.*) Link: