diff --git a/src/app/contextBroker/contextBroker.cpp b/src/app/contextBroker/contextBroker.cpp index da93b5ede6..e6f29e9916 100644 --- a/src/app/contextBroker/contextBroker.cpp +++ b/src/app/contextBroker/contextBroker.cpp @@ -823,6 +823,8 @@ int main(int argC, char* argV[]) paConfig("valid log level strings", validLogLevels); paConfig("default value", "-logLevel", "WARN"); + extern void compoundSaveInit(void); + compoundSaveInit(); // // If option '-fg' is set, print traces to stdout as well, otherwise, only to file diff --git a/src/lib/ngsi/ContextAttribute.cpp b/src/lib/ngsi/ContextAttribute.cpp index 7e743723f0..5918aec193 100644 --- a/src/lib/ngsi/ContextAttribute.cpp +++ b/src/lib/ngsi/ContextAttribute.cpp @@ -52,6 +52,79 @@ using namespace orion; +typedef struct CompoundSave +{ + std::string name; + ContextAttribute* aP; + orion::CompoundValueNode* compoundP; + ContextAttribute* aParentP; + std::string state; +} CompoundSave; + +static CompoundSave compoundSaveV[100]; +static int compoundSaveIx = 0; + +void compoundSaveInit(void) +{ + for (int ix = 0; ix < 100; ix++) + compoundSaveV[ix].state = "unused"; +} + +#if 0 +void compoundSaveReport(void) +{ + LM_TMP(("%-20s %-10s %-10s %-10s %s", "name", "attrP", "compoundP", "from Attr", "state")); + for (int ix = 0; ix < compoundSaveIx; ix++) + { + LM_TMP(("%-20s 0x%08x 0x%08x 0x%08x %s", + compoundSaveV[ix].name.c_str(), + compoundSaveV[ix].aP, + compoundSaveV[ix].compoundP, + compoundSaveV[ix].aParentP, + compoundSaveV[ix].state.c_str())); + // if (compoundSaveV[ix].compoundP != NULL) + // { + // delete compoundSaveV[ix].compoundP; + // compoundSaveV[ix].compoundP = NULL; + // } + } +} +#endif + +static void compoundSave(ContextAttribute* aP, ContextAttribute* aParentP) +{ + CompoundSave* csP = &compoundSaveV[compoundSaveIx]; + + csP->aP = aP; + csP->name = aP->name; + csP->compoundP = aP->compoundValueP; + csP->aParentP = aParentP; + csP->state = "used"; + + ++compoundSaveIx; +} + +static void compoundUnsave(ContextAttribute* aP) +{ + if (aP->compoundValueP != NULL) + { + for (int ix = 0; ix < compoundSaveIx; ix++) + { + if (aP->compoundValueP == compoundSaveV[ix].compoundP) + { + if (compoundSaveV[ix].state == "used") + compoundSaveV[ix].state = "usedAndFreed"; + else if (compoundSaveV[ix].state == "unused") + compoundSaveV[ix].state = "freedWhenUnused"; + else + compoundSaveV[ix].state = "freedWhen-" + compoundSaveV[ix].state; + } + } + } +} + + + /* **************************************************************************** * * ContextAttribute::bsonAppendAttrValue - @@ -253,14 +326,22 @@ ContextAttribute::ContextAttribute(ContextAttribute* caP, bool useDefaultType) stringValue = caP->stringValue; numberValue = caP->numberValue; boolValue = caP->boolValue; - compoundValueP = caP->compoundValueP; - caP->compoundValueP = NULL; found = caP->found; skip = false; typeGiven = caP->typeGiven; onlyValue = caP->onlyValue; previousValue = NULL; + if (caP->compoundValueP != NULL) + { + compoundValueP = caP->compoundValueP->clone(); + compoundSave(this, caP); + } + else + { + compoundValueP = NULL; + } + creDate = caP->creDate; modDate = caP->modDate; @@ -1189,6 +1270,7 @@ void ContextAttribute::present(const std::string& indent, int ix) */ void ContextAttribute::release(void) { + compoundUnsave(this); if (compoundValueP != NULL) { delete compoundValueP; diff --git a/src/lib/rest/rest.cpp b/src/lib/rest/rest.cpp index 4bcb33d267..cd6b851d01 100644 --- a/src/lib/rest/rest.cpp +++ b/src/lib/rest/rest.cpp @@ -569,6 +569,8 @@ static void requestCompleted std::string spath = (ciP->servicePathV.size() > 0)? ciP->servicePathV[0] : ""; struct timespec reqEndTime; + // compoundSaveReport(); + if ((ciP->payload != NULL) && (ciP->payload != static_buffer)) { free(ciP->payload); diff --git a/test/functionalTest/cases/3162_context_providers_legacy_non_primitive/blanked_out_attr.test b/test/functionalTest/cases/3162_context_providers_legacy_non_primitive/blanked_out_attr.test new file mode 100644 index 0000000000..d37b56db55 --- /dev/null +++ b/test/functionalTest/cases/3162_context_providers_legacy_non_primitive/blanked_out_attr.test @@ -0,0 +1,368 @@ + +# Copyright 2018 Telefonica Investigacion y Desarrollo, S.A.U +# +# This file is part of Orion Context Broker. +# +# Orion 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 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 Context Broker. If not, see http://www.gnu.org/licenses/. +# +# For those usages not covered by this license please contact with +# iot_support at tid dot es + +# VALGRIND_READY - to mark the test ready for valgrindTestSuite.sh + +--NAME-- +Federation Problem, basics + +--SHELL-INIT-- +dbInit CB +dbInit CP1 +brokerStart CB 0 +brokerStart CP1 0 + +--SHELL-- + +# +# +# 01. Create entity with geodata and string object +# 02. Check entity in CB +# 03. Get entity from mongodb +# 04. Register CP1 for Entity in step 01 +# 05. Check entity in CB +# 06. Get entity from mongodb +# + +echo "01. Create entity with geodata and string object" +echo "================================================" +payload='{ +"actionType": "APPEND", + "entities": [ + { + "id":"urn:ngsi-ld:Store:004", + "type":"Store", + "address": { + "type":"PostalAddress", + "value": { + "streetAddress":"Panoramastrasse 1A", + "addressRegion":"Berlin", + "addressLocality":"Mitte", + "postalCode":"10178" + } + }, + "location": { + "type":"geo:json", + "value": { + "type":"Point", + "coordinates": [13.4094,52.5208] + } + }, + "name": { + "type":"Text", + "value":"Tower Troddelmarkt" + } + } + ] +}' +orionCurl --url /v2/op/update --payload "$payload" +echo +echo + + +echo "02. Check entity in CB" +echo "======================" +orionCurl --url /v2/entities/urn:ngsi-ld:Store:004 +echo +echo + + +echo "03. Get entity from mongodb" +echo "===========================" +m=$(mongoCmd ${CB_DB_NAME} 'db.entities.find({ "_id" : { "id" : "urn:ngsi-ld:Store:004", "type": "Store", "servicePath" : "/" }})') +echo $m | python -mjson.tool +echo +echo + + +echo "04. Register CP1 for Entity in step 01" +echo "======================================" +payload='{ + "description": "Relative Humidity Context Source", + "dataProvided": { + "entities": [ + { + "id": "urn:ngsi-ld:Store:004", + "type": "Store" + } + ], + "attrs": [ + "temperature" + ] + }, + "provider": { + "http": { + "url": "http://localhost':$CP1_PORT'/v2" + }, + "legacyForwarding": true + } +}' +orionCurl --url /v2/registrations --payload "$payload" +echo +echo + + +echo "05. Check entity in CB" +echo "======================" +orionCurl --url /v2/entities/urn:ngsi-ld:Store:004 +echo +echo + + +echo "06. Get entity from mongodb" +echo "===========================" +m=$(mongoCmd ${CB_DB_NAME} 'db.entities.find({ "_id" : { "id" : "urn:ngsi-ld:Store:004", "type": "Store", "servicePath" : "/" }})') +echo $m | python -mjson.tool +echo +echo + + +--REGEXPECT-- +01. Create entity with geodata and string object +================================================ +HTTP/1.1 204 No Content +Content-Length: 0 +Fiware-Correlator: REGEX([0-9a-f\-]{36}) +Date: REGEX(.*) + + + +02. Check entity in CB +====================== +HTTP/1.1 200 OK +Content-Length: 381 +Content-Type: application/json +Fiware-Correlator: REGEX([0-9a-f\-]{36}) +Date: REGEX(.*) + +{ + "address": { + "metadata": {}, + "type": "PostalAddress", + "value": { + "addressLocality": "Mitte", + "addressRegion": "Berlin", + "postalCode": "10178", + "streetAddress": "Panoramastrasse 1A" + } + }, + "id": "urn:ngsi-ld:Store:004", + "location": { + "metadata": {}, + "type": "geo:json", + "value": { + "coordinates": [ + 13.4094, + 52.5208 + ], + "type": "Point" + } + }, + "name": { + "metadata": {}, + "type": "Text", + "value": "Tower Troddelmarkt" + }, + "type": "Store" +} + + +03. Get entity from mongodb +=========================== +{ + "_id": { + "id": "urn:ngsi-ld:Store:004", + "servicePath": "/", + "type": "Store" + }, + "attrNames": [ + "address", + "location", + "name" + ], + "attrs": { + "address": { + "creDate": REGEX([0-9]+), + "mdNames": [], + "modDate": REGEX([0-9]+), + "type": "PostalAddress", + "value": { + "addressLocality": "Mitte", + "addressRegion": "Berlin", + "postalCode": "10178", + "streetAddress": "Panoramastrasse 1A" + } + }, + "location": { + "creDate": REGEX([0-9]+), + "mdNames": [], + "modDate": REGEX([0-9]+), + "type": "geo:json", + "value": { + "coordinates": [ + 13.4094, + 52.5208 + ], + "type": "Point" + } + }, + "name": { + "creDate": REGEX([0-9]+), + "mdNames": [], + "modDate": REGEX([0-9]+), + "type": "Text", + "value": "Tower Troddelmarkt" + } + }, + "creDate": REGEX([0-9]+), + "lastCorrelator": "REGEX([0-9a-f\-]{36})", + "location": { + "attrName": "location", + "coords": { + "coordinates": [ + 13.4094, + 52.5208 + ], + "type": "Point" + } + }, + "modDate": REGEX([0-9]+) +} + + +04. Register CP1 for Entity in step 01 +====================================== +HTTP/1.1 201 Created +Content-Length: 0 +Location: /v2/registrations/REGEX([0-9a-f\-]{24}) +Fiware-Correlator: REGEX([0-9a-f\-]{36}) +Date: REGEX(.*) + + + +05. Check entity in CB +====================== +HTTP/1.1 200 OK +Content-Length: 381 +Content-Type: application/json +Fiware-Correlator: REGEX([0-9a-f\-]{36}) +Date: REGEX(.*) + +{ + "address": { + "metadata": {}, + "type": "PostalAddress", + "value": { + "addressLocality": "Mitte", + "addressRegion": "Berlin", + "postalCode": "10178", + "streetAddress": "Panoramastrasse 1A" + } + }, + "id": "urn:ngsi-ld:Store:004", + "location": { + "metadata": {}, + "type": "geo:json", + "value": { + "coordinates": [ + 13.4094, + 52.5208 + ], + "type": "Point" + } + }, + "name": { + "metadata": {}, + "type": "Text", + "value": "Tower Troddelmarkt" + }, + "type": "Store" +} + + +06. Get entity from mongodb +=========================== +{ + "_id": { + "id": "urn:ngsi-ld:Store:004", + "servicePath": "/", + "type": "Store" + }, + "attrNames": [ + "address", + "location", + "name" + ], + "attrs": { + "address": { + "creDate": REGEX([0-9]+), + "mdNames": [], + "modDate": REGEX([0-9]+), + "type": "PostalAddress", + "value": { + "addressLocality": "Mitte", + "addressRegion": "Berlin", + "postalCode": "10178", + "streetAddress": "Panoramastrasse 1A" + } + }, + "location": { + "creDate": REGEX([0-9]+), + "mdNames": [], + "modDate": REGEX([0-9]+), + "type": "geo:json", + "value": { + "coordinates": [ + 13.4094, + 52.5208 + ], + "type": "Point" + } + }, + "name": { + "creDate": REGEX([0-9]+), + "mdNames": [], + "modDate": REGEX([0-9]+), + "type": "Text", + "value": "Tower Troddelmarkt" + } + }, + "creDate": REGEX([0-9]+), + "lastCorrelator": "REGEX([0-9a-f\-]{36})", + "location": { + "attrName": "location", + "coords": { + "coordinates": [ + 13.4094, + 52.5208 + ], + "type": "Point" + } + }, + "modDate": REGEX([0-9]+) +} + + +--TEARDOWN-- +brokerStop CB +brokerStop CP1 +dbDrop CB +dbDrop CP1 diff --git a/test/functionalTest/cases/3162_context_providers_legacy_non_primitive/query_for_arrays.test.DISABLED b/test/functionalTest/cases/3162_context_providers_legacy_non_primitive/query_for_arrays.test similarity index 61% rename from test/functionalTest/cases/3162_context_providers_legacy_non_primitive/query_for_arrays.test.DISABLED rename to test/functionalTest/cases/3162_context_providers_legacy_non_primitive/query_for_arrays.test index 72a0acfac3..d4b8fc8075 100644 --- a/test/functionalTest/cases/3162_context_providers_legacy_non_primitive/query_for_arrays.test.DISABLED +++ b/test/functionalTest/cases/3162_context_providers_legacy_non_primitive/query_for_arrays.test @@ -23,15 +23,13 @@ # # Uncached/Cached query # -# 01. Start the contextBroker 'CB' -# 02. Start contextProvider 'CP' (contextBroker functioning as contextProvider) -# 03. Register an entity/attribute E1/A1 in broker, with CP as providing application -# 04. Update/APPEND E1/A1(=CP) in CP - this is a non-primitive element e.g. an Array -# 05. Query CP for E1/A1 -# 06. Query broker for E1/A1 (will go to CP and it will work, A1=CP is returned) -# 07. Update/APPEND E1/A2(=broker) in broker - this is also a non-primitive element e.g. an Array -# 08. Query broker for E1/A2 (broker's local info is returned (A2=broker)) -# 09. Query E1 in CB +# 01. Register an entity/attribute E1/A1 in broker, with CP as providing application +# 02. Update/APPEND E1/A1(=CP) in CP - this is a non-primitive element e.g. an Array +# 03. Query CP for E1/A1 +# 04. Query broker for E1/A1 (will go to CP and it should work, A1=CP array is returned) +# 05. Update/APPEND E1/A2(=broker) in broker - this is also a non-primitive element e.g. an Array +# 06. Query broker for E1/A2 (broker's local info is returned (A2=broker)) +# 07. Query E1 in CB --NAME-- Query Redirect Operation @@ -44,14 +42,10 @@ brokerStart CP1 0 --SHELL-- -echo "01. contextBroker running" -echo "02. contextProvider running (contextBroker functioning as contextProvider)" -echo -echo -echo "03. Register an entity/attribute E1/A1 in broker, with CP as providing application" -url3="/v2/registrations" -payload3='{ +echo "01. Register an entity/attribute E1/A1 in broker, with CP as providing application" +echo "==================================================================================" +payload='{ "description": "Register a E1/A1 with CP as provider", "dataProvided": { "entities": [ @@ -71,14 +65,14 @@ payload3='{ "legacyForwarding": true } }' -orionCurl --url "$url3" --payload "$payload3" +orionCurl --url /v2/registrations --payload "$payload" echo echo -echo "04. Update/APPEND E1/A1(=CP) in CP" -url4="/v1/updateContext" -payload4='{ +echo "02. Update/APPEND E1/A1(=CP) in CP" +echo "==================================" +payload='{ "contextElements": [ { "type": "E", @@ -95,14 +89,14 @@ payload4='{ ], "updateAction": "APPEND" }' -orionCurl --url "$url4" --payload "$payload4" --port $CP1_PORT +orionCurl --url /v1/updateContext --payload "$payload" --port $CP1_PORT echo echo -echo "05. Query CP for E1/A1" -url5="/v1/queryContext" -payload5='{ +echo "03. Query CP for E1/A1" +echo "======================" +payload='{ "entities": [ { "type": "E", @@ -114,20 +108,21 @@ payload5='{ "A1" ] }' -orionCurl --url "$url5" --payload "$payload5" --port $CP1_PORT +orionCurl --url /v1/queryContext --payload "$payload" --port $CP1_PORT echo echo -echo "06. Query broker for E1/A1 (will go to CP and it should work, A1=CP array is returned)" +echo "04. Query broker for E1/A1 (will go to CP and it should work, A1=CP array is returned)" +echo "======================================================================================" orionCurl --url /v2/entities/E1/attrs/A1/value echo echo -echo "07. Update/APPEND E1/A2(=broker) in broker" -url7="/v1/updateContext" -payload7='{ +echo "05. Update/APPEND E1/A2(=broker) in broker" +echo "==========================================" +payload='{ "contextElements": [ { "type": "E", @@ -144,44 +139,40 @@ payload7='{ ], "updateAction": "APPEND" }' -orionCurl --url "$url7" --payload "$payload7" +orionCurl --url /v1/updateContext --payload "$payload" echo echo -echo "08. Query broker for E1/A2 (will go to CB and should work, A2 array is returned)" +echo "06. Query broker for E1/A2 (will go to CB and should work, A2 array is returned)" +echo "================================================================================" orionCurl --url /v2/entities/E1/attrs/A2/value --out "text/plain" echo echo -echo "09. Query E1 in CB - expect two arrays returned" +echo "07. Query E1 in CB - expect two arrays returned" +echo "===============================================" orionCurl --url /v2/entities/E1 echo echo --REGEXPECT-- -01. contextBroker running -02. contextProvider running (contextBroker functioning as contextProvider) - - -03. Register an entity/attribute E1/A1 in broker, with CP as providing application -HTTP/1.1 200 OK -Content-Length: 64 -Content-Type: application/json +01. Register an entity/attribute E1/A1 in broker, with CP as providing application +================================================================================== +HTTP/1.1 201 Created +Content-Length: 0 +Location: /v2/registrations/REGEX([0-9a-f\-]{24}) Fiware-Correlator: REGEX([0-9a-f\-]{36}) Date: REGEX(.*) -{ - "duration": "PT24H", - "registrationId": "REGEX([0-9a-f]{24})" -} -04. Update/APPEND E1/A1(=CP) in CP +02. Update/APPEND E1/A1(=CP) in CP +================================== HTTP/1.1 200 OK -Content-Length: REGEX(\d+) +Content-Length: 187 Content-Type: application/json Fiware-Correlator: REGEX([0-9a-f\-]{36}) Date: REGEX(.*) @@ -194,7 +185,7 @@ Date: REGEX(.*) { "name": "A1", "type": "Array", - "value": ["Data", "from CP"] + "value": "" } ], "id": "E1", @@ -210,9 +201,10 @@ Date: REGEX(.*) } -05. Query CP for E1/A1 +03. Query CP for E1/A1 +====================== HTTP/1.1 200 OK -Content-Length: REGEX(\d+) +Content-Length: 203 Content-Type: application/json Fiware-Correlator: REGEX([0-9a-f\-]{36}) Date: REGEX(.*) @@ -225,7 +217,10 @@ Date: REGEX(.*) { "name": "A1", "type": "Array", - "value": ["Data", "from CP"] + "value": [ + "Data", + "from CP" + ] } ], "id": "E1", @@ -241,23 +236,24 @@ Date: REGEX(.*) } -06. Query broker for E1/A1 (will go to CP and it will work, A1=CP is returned) +04. Query broker for E1/A1 (will go to CP and it should work, A1=CP array is returned) +====================================================================================== HTTP/1.1 200 OK -Content-Length: REGEX(\d+) +Content-Length: 18 Content-Type: application/json Fiware-Correlator: REGEX([0-9a-f\-]{36}) Date: REGEX(.*) -{ - "metadata": {}, - "type": "Array", - "value": ["Data", "from CP"] -} +[ + "Data", + "from CP" +] -07. Update/APPEND E1/A2(=broker) in broker +05. Update/APPEND E1/A2(=broker) in broker +========================================== HTTP/1.1 200 OK -Content-Length: REGEX(\d+) +Content-Length: 187 Content-Type: application/json Fiware-Correlator: REGEX([0-9a-f\-]{36}) Date: REGEX(.*) @@ -270,7 +266,7 @@ Date: REGEX(.*) { "name": "A2", "type": "Array", - "value": ["Data", "from CB"] + "value": "" } ], "id": "E1", @@ -286,22 +282,21 @@ Date: REGEX(.*) } -08. Query broker for E1/A2 (will go to CB and should work, A2 array is returned) +06. Query broker for E1/A2 (will go to CB and should work, A2 array is returned) +================================================================================ HTTP/1.1 200 OK -Content-Length: REGEX(\d+) -Content-Type: application/json +Content-Length: 18 +Content-Type: text/plain Fiware-Correlator: REGEX([0-9a-f\-]{36}) Date: REGEX(.*) -{ - "metadata": {}, - "type": "Array", - "value": ["Data", "from CB"] -} +["Data","from CB"] + -09. Query E1 in CB - expect two arrays returned +07. Query E1 in CB - expect two arrays returned +=============================================== HTTP/1.1 200 OK -Content-Length: 80 +Content-Length: 148 Content-Type: application/json Fiware-Correlator: REGEX([0-9a-f\-]{36}) Date: REGEX(.*) @@ -309,22 +304,27 @@ Date: REGEX(.*) { "A1": { "metadata": {}, - "type": "string", - "value": ["Data", "from CP"] + "type": "Array", + "value": [ + "Data", + "from CP" + ] }, "A2": { "metadata": {}, - "type": "string", - "value": ["Data", "from CB"] + "type": "Array", + "value": [ + "Data", + "from CB" + ] }, "id": "E1", - "type": "T1" + "type": "E" } --TEARDOWN-- brokerStop CB brokerStop CP1 - dbDrop CB dbDrop CP1 diff --git a/test/functionalTest/cases/3162_context_providers_legacy_non_primitive/registration_without_provider.test b/test/functionalTest/cases/3162_context_providers_legacy_non_primitive/registration_without_provider.test new file mode 100644 index 0000000000..b7cb6595b0 --- /dev/null +++ b/test/functionalTest/cases/3162_context_providers_legacy_non_primitive/registration_without_provider.test @@ -0,0 +1,82 @@ +# Copyright 2016 Telefonica Investigacion y Desarrollo, S.A.U +# +# This file is part of Orion Context Broker. +# +# Orion 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 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 Context Broker. If not, see http://www.gnu.org/licenses/. +# +# For those usages not covered by this license please contact with +# iot_support at tid dot es + +# VALGRIND_READY - to mark the test ready for valgrindTestSuite.sh + +--NAME-- +BUG + +--SHELL-INIT-- +dbInit CB +brokerStart CB + +--SHELL-- + +# +# 01. Create entity E1 without attributes +# 02. Append new geo:box attribute (attr3) -> OK +# + +echo "01. Create entity E1 without attributes" +echo "=======================================" +payload='{ + "id": "E1" +}' +orionCurl --url /v2/entities --payload "$payload" +echo +echo + + +echo "02. Append new geo:box attribute (attr3) -> OK" +echo "==============================================" +payload='{ + "attr3": { + "value": [ "-1, 1", "2, 2" ], + "type": "geo:box" + } +}' +orionCurl --url /v2/entities/E1/attrs --payload "$payload" -X POST +echo +echo + + +--REGEXPECT-- +01. Create entity E1 without attributes +======================================= +HTTP/1.1 201 Created +Content-Length: 0 +Location: /v2/entities/E1?type=Thing +Fiware-Correlator: REGEX([0-9a-f\-]{36}) +Date: REGEX(.*) + + + +02. Append new geo:box attribute (attr3) -> OK +============================================== +HTTP/1.1 204 No Content +Content-Length: 0 +Fiware-Correlator: REGEX([0-9a-f\-]{36}) +Date: REGEX(.*) + + + +--TEARDOWN-- +brokerStop CB +dbDrop CB