diff --git a/.github/workflows/valgrind.yml b/.github/workflows/valgrind.yml
index b80f593fe7..68217a0699 100644
--- a/.github/workflows/valgrind.yml
+++ b/.github/workflows/valgrind.yml
@@ -24,6 +24,7 @@ jobs:
services:
mongodb:
image: mongo:7.0
+
ports:
- 27017:27017
diff --git a/CHANGES_NEXT_RELEASE b/CHANGES_NEXT_RELEASE
index c3b7ccea03..0c8dcd255b 100644
--- a/CHANGES_NEXT_RELEASE
+++ b/CHANGES_NEXT_RELEASE
@@ -1,9 +1,12 @@
- Add: servicePath field to builtin attributes (#2877)
- Add: notification.mqtt.retain and notification.mqttCustom.retain flag for MQTT retain in notifications (#4388)
+- Fix: correctly detect JSON attribute and metadata value changes in subscription triggering logic (#4211, #4434, #643)
+- Fix: DateTime and geo:json types were not supported in custom notifications using ngsi patching (#4435)
- Fix: logDeprecate not working correctly (`geo:json` wrongly considered as deprecated)
- Fix: improve error traces (#4387)
- Add: CLI parameter -dbUri / env var ORION_MONGO_URI (#3794)
- Fix: improve logs in MongoDB query logic
- Upgrade Debian version from 11.6 to 12.1 in Dockerfile
- Hardening: upgrade libmongoc dependency from 1.23.1 to 1.24.3
+- Reference MongoDB version changed from 4.4 to 6.0
- Reference distribution changed from Debian 11 to Debian 12
diff --git a/README.md b/README.md
index 47282d99be..71526c8105 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,8 @@
[![FIWARE Core Context Management](https://nexus.lab.fiware.org/repository/raw/public/badges/chapters/core.svg)](https://www.fiware.org/developers/catalogue/)
[![License badge](https://img.shields.io/github/license/telefonicaid/fiware-orion.svg)](https://opensource.org/licenses/AGPL-3.0)
-[![Docker badge](https://img.shields.io/docker/pulls/fiware/orion.svg)](https://hub.docker.com/r/fiware/orion/)
+[![Quay badge](https://img.shields.io/badge/quay.io-fiware%2Forion-grey?logo=red%20hat&labelColor=EE0000)](https://quay.io/repository/fiware/orion)
+[![Docker badge](https://img.shields.io/badge/docker-telefonicaiot%2Ffiware--orion-blue?logo=docker)](https://registry.hub.docker.com/r/telefonicaiot/fiware-orion)
[![Support badge](https://img.shields.io/badge/tag-fiware--orion-orange.svg?logo=stackoverflow)](http://stackoverflow.com/questions/tagged/fiware-orion)
[![NGSI v2](https://img.shields.io/badge/NGSI-V2-red.svg)](doc/manuals/orion-api.md)
@@ -34,8 +35,8 @@ This project is part of [FIWARE](https://www.fiware.org/). For more information
check the FIWARE Catalogue entry for
[Core Context Management](https://github.com/Fiware/catalogue/tree/master/core).
-| :books: [Documentation](https://fiware-orion.rtfd.io) | :mortar_board: [Academy](https://fiware-academy.readthedocs.io/en/latest/core/orion) | :whale: [Docker Hub](https://hub.docker.com/r/fiware/orion/) | :dart: [Roadmap](doc/roadmap.md) |
-|---|---|---|---|
+| :books: [Documentation](https://fiware-orion.rtfd.io) | :mortar_board: [Academy](https://fiware-academy.readthedocs.io/en/latest/core/orion) | [quay.io](https://quay.io/repository/fiware/orion) | :whale: [Docker Hub](https://registry.hub.docker.com/r/telefonicaiot/fiware-orion) | :dart: [Roadmap](doc/roadmap.md) |
+|---|---|---|---|--|
## Content
@@ -263,6 +264,9 @@ version 3](./LICENSE).
© 2023 Telefonica Investigación y Desarrollo, S.A.U
+
+Further information on the use of the AGPL open source license
+
### Are there any legal issues with AGPL 3.0? Is it safe for me to use?
There is absolutely no problem in using a product licensed under AGPL 3.0. Issues with GPL
@@ -280,3 +284,4 @@ wish to make a clarifying public statement as follows:
> unmodified version of existing software is not considered a derivative work, and therefore
> it does not need to be released as under the same license, or even released as open source.
+
diff --git a/ci/deb/build-dep.sh b/ci/deb/build-dep.sh
index 5ee98b8e5e..ea8531172a 100755
--- a/ci/deb/build-dep.sh
+++ b/ci/deb/build-dep.sh
@@ -49,21 +49,18 @@ apt-get -y install \
libsasl2-dev \
libgcrypt-dev
-## FIXME: check note in build_source.md about the libssl1 installation hack. It will be no longer needed from MongoDB 6.0 on
echo "INSTALL: MongoDB shell" \
-&& curl -L http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2_amd64.deb --output libssl1.1_1.1.1f-1ubuntu2_amd64.deb \
-&& dpkg -i libssl1.1_1.1.1f-1ubuntu2_amd64.deb \
-&& rm libssl1.1_1.1.1f-1ubuntu2_amd64.deb \
-&& curl -L https://www.mongodb.org/static/pgp/server-4.4.asc | apt-key add - \
-&& echo "deb http://repo.mongodb.org/apt/debian buster/mongodb-org/4.4 main" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list \
+&& curl -L https://www.mongodb.org/static/pgp/server-6.0.asc | apt-key add - \
+&& echo "deb http://repo.mongodb.org/apt/debian buster/mongodb-org/6.0 main" | tee /etc/apt/sources.list.d/mongodb-org-6.0.list \
&& apt-get -y update \
-&& apt-get -y install mongodb-org-shell
+&& apt-get -y install mongodb-mongosh
echo "INSTALL: python special dependencies" \
&& cd /opt \
&& python3 -m venv /opt/ft_env \
&& . /opt/ft_env/bin/activate \
&& pip install Flask==2.0.2 \
+&& pip install Werkzeug==2.0.2 \
&& pip install paho-mqtt==1.6.1 \
&& pip install amqtt==0.11.0b1 \
&& deactivate
diff --git a/doc/manuals.jp/admin/build_source.md b/doc/manuals.jp/admin/build_source.md
index ee4a300150..8b6936c127 100644
--- a/doc/manuals.jp/admin/build_source.md
+++ b/doc/manuals.jp/admin/build_source.md
@@ -132,7 +132,7 @@ aarch64 アーキテクチャの場合、apt-get を使用して libxslt をイ
. scripts/testEnv.sh
python3 -m venv /opt/ft_env # or 'virtualenv /opt/ft_env --python=/usr/bin/python3' in some systems
. /opt/ft_env/bin/activate
- pip install Flask==2.0.2 paho-mqtt==1.6.1 amqtt==0.11.0b1
+ pip install Flask==2.0.2 Werkzeug==2.0.2 paho-mqtt==1.6.1 amqtt==0.11.0b1
* この環境でテスト・ハーネスを実行してください (時間がかかりますので、気をつけてください)
diff --git a/doc/manuals.jp/devel/cookbook.md b/doc/manuals.jp/devel/cookbook.md
index 5da690df72..f25aa69f26 100644
--- a/doc/manuals.jp/devel/cookbook.md
+++ b/doc/manuals.jp/devel/cookbook.md
@@ -122,8 +122,7 @@ typedef struct RestService
{
RequestType request; // The type of the request
int components; // Number of components in the URL path
- std::string compV[10]; // Vector of URL path components. E.g. { "v2", "entities" }
- std::string payloadWord; // No longer used, should be removed ... ?
+ std::string compV[10]; // Vector of URL path components. E.g. { "v2", "entities" }
RestTreat treat; // service function pointer
} RestService;
```
diff --git a/doc/manuals.jp/orion-api.md b/doc/manuals.jp/orion-api.md
index b2687f966b..bc4a4f0c7d 100644
--- a/doc/manuals.jp/orion-api.md
+++ b/doc/manuals.jp/orion-api.md
@@ -2125,7 +2125,8 @@ Content-Length: 0
同時に使用できるのは、`payload`, `json` また `ngsi` のうちの1つだけであることに注意してください。
- [一般的な構文制限](#general-syntax-restrictions) は、`POST /v2/subscription` や `GET /v2/subscriptions`
- などの API オペレーションの `httpCustom.payload` フィールドにも適用されます。以下に例を示します
+ などの API オペレーションの `httpCustom.payload` フィールドにも適用されます。ただし、通知時には、`payload`
+ 内の URL エンコードされた文字はすべてデコードされます。以下に例を示します
- `headers` フィールドによって上書きされる場合を除き、`Content-Type` ヘッダは `text/plain` に設定されます
例:
@@ -3697,7 +3698,7 @@ _**レスポンス・ペイロード**_
| パラメータ | オプション | タイプ | 説明 |
|-------------------|------------|--------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `attrs` | ✓ | array | 通知をトリガーする属性名の配列。空のリストは許可されていません |
-| `expression` | ✓ | object | `q`, `mq`, `georel`, `geometry`, `coords` で構成される式 (このフィールドについては、上記の [エンティティをリスト](#list-entities-get-v2entities)操作を参照してください)。`expression` とサブ要素 (つまり `q`) にはコンテンツが必要です。つまり、`{}` または `""` は許可されません |
+| `expression` | ✓ | object | `q`, `mq`, `georel`, `geometry`, `coords` で構成される式 (このフィールドについては、上記の [エンティティをリスト](#list-entities-get-v2entities)操作を参照してください)。`expression` とサブ要素 (つまり `q`) にはコンテンツが必要です。つまり、`{}` または `""` は許可されません。`georel`, `geometry`, および `coords` は一緒に使用する必要があります (つまり、"全てか無しか")。 geoquery を式として使用する例は下記(#create-subscription-post-v2subscriptions) を確認してください |
| `alterationTypes` | ✓ | array | サブスクリプションがトリガーされる変更 (エンティティの作成、エンティティの変更など) を指定します ([変更タイプに基づくサブスクリプション](#subscriptions-based-in-alteration-type)のセクションを参照) |
| `notifyOnMetadataChange` | ✓ | boolean | `true` の場合、メタデータは通知のコンテキストで属性の値の一部と見なされるため、値が変更されずにメタデータが変更された場合、通知がトリガーされます。`false` の場合、メタデータは通知のコンテキストで属性の値の一部と見なされないため、値が変更されずにメタデータが変更された場合、通知はトリガーされません。デフォルト値は `true` です |
@@ -3926,7 +3927,7 @@ _**リクエスト・ペイロード**_
ペイロードは、JSON サブスクリプション表現形式 ([サブスクリプション・ペイロード・データモデル](#subscription-payload-datamodel)
セクションで説明されています) に従うサブスクリプションを含む JSON オブジェクトです。
-例:
+属性フィルタを使用した例:
```json
{
@@ -3951,8 +3952,38 @@ _**リクエスト・ペイロード**_
},
"attrs": ["temperature", "humidity"]
},
- "expires": "2025-04-05T14:00:00.00Z",
- "throttling": 5
+ "expires": "2025-04-05T14:00:00.00Z"
+}
+```
+
+条件としてジオクエリを使用する例:
+
+```json
+{
+ "description": "One subscription to rule them all",
+ "subject": {
+ "entities": [
+ {
+ "idPattern": ".*",
+ "type": "Room"
+ }
+ ],
+ "condition": {
+ "attrs": [ "temperature" ],
+ "expression": {
+ "georel": "near;maxDistance:15000",
+ "geometry": "point",
+ "coords": "37.407804,-6.004552"
+ }
+ }
+ },
+ "notification": {
+ "http": {
+ "url": "http://localhost:1234"
+ },
+ "attrs": ["temperature", "humidity"]
+ },
+ "expires": "2025-04-05T14:00:00.00Z"
}
```
@@ -4480,7 +4511,7 @@ _**リクエスト・ペイロード**_
- `appendStrict`: `POST /v2/entities` (エンティティがまだ存在しない場合) または
`POST /v2/entities//attrs?options=append` (エンティティが既に存在する場合) にマップします
- `update`: `PATCH /v2/entities//attrs` にマップされます
-- `delete`: エンティティに含まれているすべての属性に対して、`DELETE /v2/entities//attrs/`
+- `delete`: エンティティに含まれているすべての属性に対して (この場合、属性の実際の値は関係ありません)、`DELETE /v2/entities//attrs/`
にマッピングし、エンティティに属性が含まれていない場合は、`DELETE /v2/entities/` にマッピングします
- `replace`: `PUT /v2/entities//attrs` にマッピングします
diff --git a/doc/manuals.jp/user/walkthrough_apiv2.md b/doc/manuals.jp/user/walkthrough_apiv2.md
index 20be5b6399..433f3231b0 100644
--- a/doc/manuals.jp/user/walkthrough_apiv2.md
+++ b/doc/manuals.jp/user/walkthrough_apiv2.md
@@ -92,8 +92,8 @@ broker を再起動するには、*root* として実行するか、`sudo` コ
# ./accumulator-server.py --port 1028 --url /accumulate --host ::1 --pretty-print -v
```
-このスクリプトには Flask version 2.0.2 と paho-mqtt version 1.6.1 が必要であることに注意してください。
-これらは、`pip install Flask==2.0.2` と `pip install paho-mqtt==1.6.1` を使用してインストールできます。
+このスクリプトには Flask version 2.0.2 (Werkzeug 2.0.2 とともに) と paho-mqtt version 1.6.1 が必要であることに注意してください。
+これらは、それぞれ、`pip install Flask==2.0.2 Werkzeug==2.0.2` と `pip install paho-mqtt==1.6.1` を使用してインストールできます。
さらに、Python 3.10.x を使用することをお勧めします。ベース・オペレーティングシステムの Python
インストールと競合する場合は、[virtualenv](https://virtualenv.pypa.io/en/latest/) を使用することを
お勧めします。
diff --git a/doc/manuals/admin/build_source.md b/doc/manuals/admin/build_source.md
index 38bbca42cc..b534e0b2db 100644
--- a/doc/manuals/admin/build_source.md
+++ b/doc/manuals/admin/build_source.md
@@ -107,13 +107,7 @@ The Orion Context Broker comes with a suite of unit, valgrind and end-to-end tes
In the case of the aarch64 architecture, install libxslt using apt-get, and run `./configure` with `--build=arm-linux` option.
-* Install MongoDB (tests rely on mongod running in localhost). Check [the official MongoDB documentation](hhttps://www.mongodb.com/docs/manual/tutorial/install-mongodb-on-debian/) for details. Recommended version is 4.4 (it may work with previous versions, but we don't recommend it).
- * Note that mongo legacy shell (the `mongo` command) has been deprecated in MongoDB 5 and removed in MongoDB 6 in favour of the new shell (`mongosh` command). Some functional tests (ftest) will fail due to this if you use MongoDB 6 or beyond, as they are suited to use `mongo` and not `mongosh`.
- * Debian 12 has stepped to libssl3 but some MongoDB versions may require libssl1. In the case you get a `Depends: libssl1.1 (>= 1.1.1) but it is not installable` error, you can test the following (reference [here](https://askubuntu.com/a/1421959))
-
- wget http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2_amd64.deb
- sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2_amd64.deb
- rm libssl1.1_1.1.1f-1ubuntu2_amd64.deb # optional, for cleanness
+* Install MongoDB (tests rely on mongod running in localhost). Check [the official MongoDB documentation](hhttps://www.mongodb.com/docs/manual/tutorial/install-mongodb-on-debian/) for details. Recommended version is 6.0 (it may work with previous versions, but we don't recommend it).
* Run unit test
@@ -131,7 +125,7 @@ In the case of the aarch64 architecture, install libxslt using apt-get, and run
. scripts/testEnv.sh
python3 -m venv /opt/ft_env # or 'virtualenv /opt/ft_env --python=/usr/bin/python3' in some systems
. /opt/ft_env/bin/activate
- pip install Flask==2.0.2 paho-mqtt==1.6.1 amqtt==0.11.0b1
+ pip install Flask==2.0.2 Werkzeug==2.0.2 paho-mqtt==1.6.1 amqtt==0.11.0b1
* Run test harness in this environment (it takes some time, please be patient).
diff --git a/doc/manuals/admin/install.md b/doc/manuals/admin/install.md
index 80fdf6b09f..13da6cc513 100644
--- a/doc/manuals/admin/install.md
+++ b/doc/manuals/admin/install.md
@@ -26,7 +26,7 @@ In the case you are installing Orion building from sources you need:
* Operating system: Debian. The reference operating system is Debian 12.1
but it should work also in any later Debian 12 version.
* Database: MongoDB is required to run either in the same host where Orion Context Broker is to be installed or in a different host accessible through the network. The recommended MongoDB version
- is 4.4 (Orion may work with older versions but we don't recommend it at all!).
+ is 6.0 (Orion may work with older versions but we don't recommend it at all!).
For system resources (CPUs, RAM, etc.) see [these recommendations](diagnosis.md#resource-availability).
diff --git a/doc/manuals/admin/perf_tuning.md b/doc/manuals/admin/perf_tuning.md
index e3f6ab0c94..a06795f0c2 100644
--- a/doc/manuals/admin/perf_tuning.md
+++ b/doc/manuals/admin/perf_tuning.md
@@ -20,7 +20,7 @@
## MongoDB configuration
-From a performance point of view, it is recommended to use MongoDB 4.4 with WireTiger, especially
+From a performance point of view, it is recommended to use MongoDB 6.0 with WireTiger, especially
in update-intensive scenarios.
In addition, take into account the following information from the official MongoDB documentation, as it may have
diff --git a/doc/manuals/devel/cookbook.md b/doc/manuals/devel/cookbook.md
index 5d75a4ddff..6af4ee7b8f 100644
--- a/doc/manuals/devel/cookbook.md
+++ b/doc/manuals/devel/cookbook.md
@@ -118,8 +118,7 @@ typedef struct RestService
{
RequestType request; // The type of the request
int components; // Number of components in the URL path
- std::string compV[10]; // Vector of URL path components. E.g. { "v2", "entities" }
- std::string payloadWord; // No longer used, should be removed ... ?
+ std::string compV[10]; // Vector of URL path components. E.g. { "v2", "entities" }
RestTreat treat; // service function pointer
} RestService;
```
diff --git a/doc/manuals/orion-api.md b/doc/manuals/orion-api.md
index 23ecd1f5c0..d45e1305f6 100644
--- a/doc/manuals/orion-api.md
+++ b/doc/manuals/orion-api.md
@@ -2131,10 +2131,11 @@ For instance:
### Text based payload
If `payload` is used in `httpCustom` or `mqttCustom` the following considerations apply.
-Note that only one of the following can be used a the same time: `payload`, `json` or `ngsi.
+Note that only one of the following can be used a the same time: `payload`, `json` or `ngsi`.
* [General syntax restrictions](#general-syntax-restrictions) also apply to the `httpCustom.payload`
- field in the API operations, such as `POST /v2/subscription` or `GET /v2/subscriptions`. An example
+ field in the API operations, such as `POST /v2/subscription` or `GET /v2/subscriptions`. However,
+ at notification time, any URL encoded characters in `payload` is decoded. An example
is shown below.
* `Content-Type` header is set to `text/plain`, except if overwritten by `headers` field
@@ -3651,7 +3652,7 @@ A `condition` contains the following subfields:
| Parameter | Optional | Type | Description |
|--------------|----------|-------|-------------------------------------------------------------------------------------------------------------------------------|
| `attrs` | ✓ | array | Array of attribute names that will trigger the notification. Empty list is not allowed. |
-| `expression` | ✓ | object| An expression composed of `q`, `mq`, `georel`, `geometry` and `coords` (see [List Entities](#list-entities-get-v2entities) operation above about this field). `expression` and sub elements (i.e. `q`) must have content, i.e. `{}` or `""` is not allowed |
+| `expression` | ✓ | object| An expression composed of `q`, `mq`, `georel`, `geometry` and `coords` (see [List Entities](#list-entities-get-v2entities) operation above about this field). `expression` and sub elements (i.e. `q`) must have content, i.e. `{}` or `""` is not allowed. `georel`, `geometry` and `coords` have to be used together (i.e. "all or nothing"). Check the example using geoquery as expression [below](#create-subscription-post-v2subscriptions).|
| `alterationTypes` | ✓ | array | Specify under which alterations (entity creation, entity modification, etc.) the subscription is triggered (see section [Subscriptions based in alteration type](#subscriptions-based-in-alteration-type)) |
| `notifyOnMetadataChange` | ✓ | boolean | If `true` then metadata is considered part of the value of the attribute in the context of notification, so if the value doesn't change but the metadata changes, then a notification is triggered. If `false` then the metadata is not considered part of the value of the attribute in the context of notification, so if the value doesn't change but the metadata changes, then a notification is not triggered. Default value is `true`. |
@@ -3862,7 +3863,7 @@ _**Request payload**_
The payload is a JSON object containing a subscription that follows the JSON subscription representation
format (described in ["Subscription payload datamodel](#subscription-payload-datamodel) section).
-Example:
+Example using attribute filter:
```json
{
@@ -3887,8 +3888,38 @@ Example:
},
"attrs": ["temperature", "humidity"]
},
- "expires": "2025-04-05T14:00:00.00Z",
- "throttling": 5
+ "expires": "2025-04-05T14:00:00.00Z"
+}
+```
+
+Example using geoquery as condition:
+
+```json
+{
+ "description": "One subscription to rule them all",
+ "subject": {
+ "entities": [
+ {
+ "idPattern": ".*",
+ "type": "Room"
+ }
+ ],
+ "condition": {
+ "attrs": [ "temperature" ],
+ "expression": {
+ "georel": "near;maxDistance:15000",
+ "geometry": "point",
+ "coords": "37.407804,-6.004552"
+ }
+ }
+ },
+ "notification": {
+ "http": {
+ "url": "http://localhost:1234"
+ },
+ "attrs": ["temperature", "humidity"]
+ },
+ "expires": "2025-04-05T14:00:00.00Z"
}
```
@@ -4375,7 +4406,7 @@ regular non-batch operations can be done:
* `appendStrict`: maps to `POST /v2/entities` (if the entity does not already exist) or
`POST /v2/entities//attrs?options=append` (if the entity already exists).
* `update`: maps to `PATCH /v2/entities//attrs`.
-* `delete`: maps to `DELETE /v2/entities//attrs/` on every attribute included in the entity or
+* `delete`: maps to `DELETE /v2/entities//attrs/` on every attribute included in the entity (in this case the actual value of the attribute is not relevant) or
to `DELETE /v2/entities/` if no attribute were included in the entity.
* `replace`: maps to `PUT /v2/entities//attrs`.
diff --git a/doc/manuals/user/walkthrough_apiv2.md b/doc/manuals/user/walkthrough_apiv2.md
index 65b4baf8cd..9ffbf6407a 100644
--- a/doc/manuals/user/walkthrough_apiv2.md
+++ b/doc/manuals/user/walkthrough_apiv2.md
@@ -123,8 +123,8 @@ command:
# ./accumulator-server.py --port 1028 --url /accumulate --host ::1 --pretty-print -v
```
-Note this script requires Flask version 2.0.2 and paho-mqtt version 1.6.1, which can be installed using
-`pip install Flask==2.0.2` and `pip install paho-mqtt==1.6.1`. In addition, it is recommended to use
+Note this script requires Flask version 2.0.2 (along with Werkzeug 2.0.2) and paho-mqtt version 1.6.1, which can be installed using
+`pip install Flask==2.0.2 Werkzeug==2.0.2` and `pip install paho-mqtt==1.6.1` respectively. In addition, it is recommended to use
Python 3.10.x In case of conflict with your base operating system Python installation, we recommend to use [virtualenv](https://virtualenv.pypa.io/en/latest/).
More information about installing the accumulator (including an alternative based in docker) can be checked
diff --git a/doc/roadmap.md b/doc/roadmap.md
index 9dbf7b976f..96fc7a5121 100644
--- a/doc/roadmap.md
+++ b/doc/roadmap.md
@@ -32,7 +32,8 @@ Disclaimer:
The following list of features are planned to be addressed in the short term,
and incorporated into the coming release(s) of the product:
-- MQTT Retain flag [#4388](https://github.com/telefonicaid/fiware-orion/issues/4388)
+- MQTT Retain flag ([#4388](https://github.com/telefonicaid/fiware-orion/issues/4388))
+- MQTT notification retrial ([#4439](https://github.com/telefonicaid/fiware-orion/issues/4439))
- Allow multiple types in entity to support UNE 178503 requirements ([#3638](https://github.com/telefonicaid/fiware-orion/issues/3638))
- Pattern/filter batch updates ([#2389](https://github.com/telefonicaid/fiware-orion/issues/2389))
- Notification endpoint alias ([#3655](https://github.com/telefonicaid/fiware-orion/issues/3655))
@@ -52,8 +53,7 @@ after next planned release:
supported by a Expressions Language - help wanted
([#4004](https://github.com/telefonicaid/fiware-orion/issues/4004)),
([#3815](https://github.com/telefonicaid/fiware-orion/issues/3815))
-- Service provisioning API (pools, etc.)
-(based in [#3843](https://github.com/telefonicaid/fiware-orion/issues/3843))
+- Service provisioning API (pools, etc.) ([#4442](https://github.com/telefonicaid/fiware-orion/issues/4442))
- Advanced subscription management
- Subscription debug mode (precise statistics consolidation, keep recent history of notifications sent, etc.) ([#4399](https://github.com/telefonicaid/fiware-orion/issues/4399))
- Custom ID subscription ([#4400](https://github.com/telefonicaid/fiware-orion/issues/4400))
diff --git a/docker/README.md b/docker/README.md
index 07d9452258..e8cc578dce 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -38,7 +38,7 @@ Follow these steps:
command: -dbhost mongo
mongo:
- image: mongo:4.4
+ image: mongo:6.0
command: --nojournal
3. Using the command-line and within the directory you created type: `sudo docker-compose up`.
@@ -77,7 +77,7 @@ Check that everything works with
### 2B. MongoDB runs on another docker container
In case you want to run MongoDB on another container you can launch it like this
- sudo docker run --name mongodb -d mongo:4.4
+ sudo docker run --name mongodb -d mongo:6.0
And then run Orion with this command
@@ -111,7 +111,7 @@ Steps:
4. Run Orion...
* Using an automated scenario with docker-compose and building your new image: `sudo docker-compose up`. You may also modify the provided `docker-compose.yml` file if you need so.
* Manually, running MongoDB on another container:
- 1. `sudo docker run --name mongodb -d mongo:4.4`
+ 1. `sudo docker run --name mongodb -d mongo:6.0`
2. `sudo docker build -t orion .`
3. `sudo docker run -d --name orion1 --link mongodb:mongodb -p 1026:1026 orion -dbhost mongodb`.
* Manually, specifying where to find your MongoDB host:
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
index cec2de0556..4587af3990 100644
--- a/docker/docker-compose.yml
+++ b/docker/docker-compose.yml
@@ -10,6 +10,6 @@ services:
command: -dbhost mongo
mongo:
- image: mongo:4.4
+ image: mongo:6.0
command: --nojournal
diff --git a/docker/docker_swarm.md b/docker/docker_swarm.md
index 867a7ee6da..ef30a5b5a4 100644
--- a/docker/docker_swarm.md
+++ b/docker/docker_swarm.md
@@ -86,7 +86,7 @@ Details on how to deploy a MongoDB ReplicaSet in Docker Swarm are available
services:
mongo:
- image: mongo:4.4
+ image: mongo:6.0
entrypoint: [ "/usr/bin/mongod", "--replSet", "rs", "--journal", "--smallfiles", "--bind_ip", "0.0.0.0"]
volumes:
- mongodata:/data/db
diff --git a/docker/raspberry_pi.md b/docker/raspberry_pi.md
index 500e5f9894..bbc3615ac6 100644
--- a/docker/raspberry_pi.md
+++ b/docker/raspberry_pi.md
@@ -49,7 +49,7 @@ services:
command: -dbhost mongo
mongo:
- image: mongo:4.4
+ image: mongo:6.0
command: --nojournal
```
diff --git a/scripts/dbList.sh b/scripts/dbList.sh
index 7156d90279..de3931276c 100755
--- a/scripts/dbList.sh
+++ b/scripts/dbList.sh
@@ -24,6 +24,4 @@ then
exit 1
fi
-mongo --quiet << EOF
- show dbs
-EOF
+mongosh --eval 'show dbs' --quiet
diff --git a/scripts/dbReset.sh b/scripts/dbReset.sh
index 05ca42318e..1e3f15cf4f 100755
--- a/scripts/dbReset.sh
+++ b/scripts/dbReset.sh
@@ -32,11 +32,11 @@ then
db=testharness
fi
- echo 'db.dropDatabase()' | mongo $db --quiet
+ mongosh $db --eval 'db.dropDatabase()' --quiet
else
while [ "$#" != 0 ]
do
- echo 'db.dropDatabase()' | mongo $1 --quiet
+ mongosh $1 --eval 'db.dropDatabase()' --quiet
shift
done
fi
diff --git a/scripts/managedb/do_in_all_orion_dbs.sh b/scripts/managedb/do_in_all_orion_dbs.sh
index 0d084b47b9..79f4bbd274 100755
--- a/scripts/managedb/do_in_all_orion_dbs.sh
+++ b/scripts/managedb/do_in_all_orion_dbs.sh
@@ -22,7 +22,7 @@
MONGO_URI="mongodb://127.0.0.1:27017"
#MONGO_URI="mongodb://mongodb1:27017,mongodb2:27017,mongodb3:27017/?replicaSet=cb_rs0"
-for db in $(echo 'show dbs' | mongo $MONGO_URI | grep '^orion' | awk -F ' ' '{print $1}')
+for db in $(mongosh $MONGO_URI --eval 'show dbs' --quiet | grep '^orion' | awk -F ' ' '{print $1}')
do
echo "Processing $db db"
# Edit next line to set the script you want
diff --git a/src/lib/jsonParseV2/jsonRequestTreat.cpp b/src/lib/jsonParseV2/jsonRequestTreat.cpp
index f0cb326947..def0d2b519 100644
--- a/src/lib/jsonParseV2/jsonRequestTreat.cpp
+++ b/src/lib/jsonParseV2/jsonRequestTreat.cpp
@@ -102,7 +102,7 @@ std::string jsonRequestTreat
case EntityAttributeRequest:
releaseP->attribute = &parseDataP->attr.attribute;
releaseP->attribute->name = compV[4];
- answer = parseContextAttribute(ciP, &parseDataP->attr.attribute);
+ answer = parseContextAttribute(ciP, &parseDataP->attr.attribute, true);
if (answer != "OK")
{
return answer;
diff --git a/src/lib/jsonParseV2/parseContextAttribute.cpp b/src/lib/jsonParseV2/parseContextAttribute.cpp
index 95bb1a26dd..751dfb66d3 100644
--- a/src/lib/jsonParseV2/parseContextAttribute.cpp
+++ b/src/lib/jsonParseV2/parseContextAttribute.cpp
@@ -105,7 +105,8 @@ static std::string parseContextAttributeObject
(
const rapidjson::Value& start,
ContextAttribute* caP,
- bool* compoundVector
+ bool* compoundVector,
+ bool checkAttrSpecialTypes
)
{
// This is NGSIv2 parsing and in NGSIv2, no value means implicit null. Note that
@@ -215,7 +216,7 @@ static std::string parseContextAttributeObject
}
// Is it a (not null) date?
- if (((caP->type == DATE_TYPE) || (caP->type == DATE_TYPE_ALT)) && (caP->valueType != orion::ValueTypeNull))
+ if (checkAttrSpecialTypes && ((caP->type == DATE_TYPE) || (caP->type == DATE_TYPE_ALT)) && (caP->valueType != orion::ValueTypeNull))
{
caP->numberValue = parse8601Time(caP->stringValue);
@@ -230,7 +231,7 @@ static std::string parseContextAttributeObject
}
// It is a safe GeoJSON?
- if (caP->type == GEO_JSON)
+ if (checkAttrSpecialTypes && caP->type == GEO_JSON)
{
std::string r = checkGeoJson(caP);
if (r != "OK")
@@ -252,7 +253,8 @@ std::string parseContextAttribute
(
ConnectionInfo* ciP,
const rapidjson::Value::ConstMemberIterator& iter,
- ContextAttribute* caP
+ ContextAttribute* caP,
+ bool checkAttrSpecialTypes
)
{
std::string name = iter->name.GetString();
@@ -354,7 +356,7 @@ std::string parseContextAttribute
// Attribute has a regular structure, in which 'value' is mandatory (except in v2)
if (iter->value.HasMember("value") || ciP->apiVersion == V2)
{
- std::string r = parseContextAttributeObject(iter->value, caP, &compoundVector);
+ std::string r = parseContextAttributeObject(iter->value, caP, &compoundVector, checkAttrSpecialTypes);
if (r == "max deep reached")
{
alarmMgr.badInput(clientIp, "max deep reached", "found in ContextAttributeObject::Object");
@@ -398,7 +400,7 @@ std::string parseContextAttribute
*
* parseContextAttribute -
*/
-std::string parseContextAttribute(ConnectionInfo* ciP, ContextAttribute* caP)
+std::string parseContextAttribute(ConnectionInfo* ciP, ContextAttribute* caP, bool checkAttrSpecialTypes)
{
rapidjson::Document document;
@@ -426,7 +428,7 @@ std::string parseContextAttribute(ConnectionInfo* ciP, ContextAttribute* caP)
}
bool compoundVector = false;
- std::string r = parseContextAttributeObject(document, caP, &compoundVector);
+ std::string r = parseContextAttributeObject(document, caP, &compoundVector, checkAttrSpecialTypes);
if (r == "max deep reached")
{
diff --git a/src/lib/jsonParseV2/parseContextAttribute.h b/src/lib/jsonParseV2/parseContextAttribute.h
index ac92ad5eaa..e3210e9403 100644
--- a/src/lib/jsonParseV2/parseContextAttribute.h
+++ b/src/lib/jsonParseV2/parseContextAttribute.h
@@ -41,7 +41,8 @@ extern std::string parseContextAttribute
(
ConnectionInfo* ciP,
const rapidjson::Value::ConstMemberIterator& iter,
- ContextAttribute* caP
+ ContextAttribute* caP,
+ bool checkAttrSpecialTypes
);
@@ -50,6 +51,6 @@ extern std::string parseContextAttribute
*
* parseContextAttribute -
*/
-extern std::string parseContextAttribute(ConnectionInfo* ciP, ContextAttribute* caP);
+extern std::string parseContextAttribute(ConnectionInfo* ciP, ContextAttribute* caP, bool checkAttrSpecialTypes);
#endif // SRC_LIB_JSONPARSEV2_PARSECONTEXTATTRIBUTE_H_
diff --git a/src/lib/jsonParseV2/parseEntity.cpp b/src/lib/jsonParseV2/parseEntity.cpp
index 46b9909314..c47c3116a8 100644
--- a/src/lib/jsonParseV2/parseEntity.cpp
+++ b/src/lib/jsonParseV2/parseEntity.cpp
@@ -235,7 +235,7 @@ std::string parseEntity(ConnectionInfo* ciP, Entity* eP, bool eidInURL)
eP->attributeVector.push_back(caP);
- std::string r = parseContextAttribute(ciP, iter, caP);
+ std::string r = parseContextAttribute(ciP, iter, caP, true);
if (r == "max deep reached")
{
OrionError oe(SccBadRequest, ERROR_DESC_PARSE_MAX_JSON_NESTING, ERROR_PARSE);
diff --git a/src/lib/jsonParseV2/parseEntityObject.cpp b/src/lib/jsonParseV2/parseEntityObject.cpp
index 9d54d5e7ca..aa6cc8b665 100644
--- a/src/lib/jsonParseV2/parseEntityObject.cpp
+++ b/src/lib/jsonParseV2/parseEntityObject.cpp
@@ -157,7 +157,7 @@ std::string parseEntityObject
ContextAttribute* caP = new ContextAttribute();
- r = parseContextAttribute(ciP, iter, caP);
+ r = parseContextAttribute(ciP, iter, caP, true);
if (r == "OK")
{
eP->attributeVector.push_back(caP);
diff --git a/src/lib/jsonParseV2/parseSubscription.cpp b/src/lib/jsonParseV2/parseSubscription.cpp
index f68e11c259..3724528ba1 100644
--- a/src/lib/jsonParseV2/parseSubscription.cpp
+++ b/src/lib/jsonParseV2/parseSubscription.cpp
@@ -546,7 +546,7 @@ static std::string parseCustomPayload
ngsi->attributeVector.push_back(caP);
- std::string r = parseContextAttribute(ciP, iter, caP);
+ std::string r = parseContextAttribute(ciP, iter, caP, false);
if (r == "max deep reached")
{
diff --git a/src/lib/mongoBackend/MongoCommonUpdate.cpp b/src/lib/mongoBackend/MongoCommonUpdate.cpp
index e00218931b..afdec2510f 100644
--- a/src/lib/mongoBackend/MongoCommonUpdate.cpp
+++ b/src/lib/mongoBackend/MongoCommonUpdate.cpp
@@ -136,7 +136,7 @@ static bool hasMetadata(std::string name, std::string type, ContextAttribute* ca
*
* equalMetadataValues -
*/
-static bool equalMetadataValues(const orion::BSONObj& md1, const orion::BSONObj& md2)
+static bool equalMetadataItems(const orion::BSONObj& md1, const orion::BSONObj& md2)
{
bool md1TypeExist = md1.hasField(ENT_ATTRS_MD_TYPE);
bool md2TypeExist = md2.hasField(ENT_ATTRS_MD_TYPE);
@@ -147,58 +147,23 @@ static bool equalMetadataValues(const orion::BSONObj& md1, const orion::BSONObj&
return false;
}
- // If type exists in both metadata elments, check if they are the same
+ // If type exists in both metadata elements, check if they are the same
if (md1TypeExist && md2TypeExist)
{
- if (getFieldF(md1, ENT_ATTRS_MD_TYPE).type() != getFieldF(md2, ENT_ATTRS_MD_TYPE).type())
+ if ((getFieldF(md1, ENT_ATTRS_MD_TYPE).type() != orion::String))
{
+ LM_E(("Runtime Error (unallowed JSON type for metadata NGSI type: %d)", getFieldF(md1, ENT_ATTRS_MD_TYPE).type()));
return false;
}
- switch (getFieldF(md1, ENT_ATTRS_MD_TYPE).type())
+ if ((getFieldF(md2, ENT_ATTRS_MD_TYPE).type() != orion::String))
{
- /* FIXME #643 P6: metadata array/object are now supported, but we haven't
- implemented yet the logic to compare compounds between them
- case Object:
- ...
- break;
-
- case Array:
- ...
- break;
- */
-
- case orion::NumberDouble:
- if (getNumberFieldF(md1, ENT_ATTRS_MD_TYPE) != getNumberFieldF(md2, ENT_ATTRS_MD_TYPE))
- {
- return false;
- }
- break;
-
- case orion::Bool:
- if (getBoolFieldF(md1, ENT_ATTRS_MD_TYPE) != getBoolFieldF(md2, ENT_ATTRS_MD_TYPE))
- {
- return false;
- }
- break;
-
- case orion::String:
- if (getStringFieldF(md1, ENT_ATTRS_MD_TYPE) != getStringFieldF(md2, ENT_ATTRS_MD_TYPE))
- {
- return false;
- }
- break;
-
- case orion::jstNULL:
- if (!getFieldF(md2, ENT_ATTRS_MD_TYPE).isNull())
- {
- return false;
- }
- break;
+ LM_E(("Runtime Error (unallowed JSON type for metadata NGSI type: %d)", getFieldF(md2, ENT_ATTRS_MD_TYPE).type()));
+ return false;
+ }
- default:
- LM_E(("Runtime Error (unknown JSON type for metadata NGSI type: %d)", getFieldF(md1, ENT_ATTRS_MD_TYPE).type()));
+ if (getStringFieldF(md1, ENT_ATTRS_MD_TYPE) != getStringFieldF(md2, ENT_ATTRS_MD_TYPE))
+ {
return false;
- break;
}
}
@@ -210,15 +175,11 @@ static bool equalMetadataValues(const orion::BSONObj& md1, const orion::BSONObj&
switch (getFieldF(md1, ENT_ATTRS_MD_VALUE).type())
{
- /* FIXME not yet
case orion::Object:
- ...
- break;
+ return getObjectFieldF(md1, ENT_ATTRS_MD_VALUE).equal(getObjectFieldF(md2, ENT_ATTRS_MD_VALUE));
case orion::Array:
- ...
- break;
- */
+ return getArrayFieldF(md1, ENT_ATTRS_MD_VALUE).equal(getArrayFieldF(md2, ENT_ATTRS_MD_VALUE));
case orion::NumberDouble:
return getNumberFieldF(md1, ENT_ATTRS_MD_VALUE) == getNumberFieldF(md2, ENT_ATTRS_MD_VALUE);
@@ -266,7 +227,7 @@ static bool equalMetadata(const orion::BSONObj& md1, const orion::BSONObj& md2)
orion::BSONObj md1Item = getObjectFieldF(md1, currentMd);
orion::BSONObj md2Item = getObjectFieldF(md2, currentMd);
- if (!equalMetadataValues(md1Item, md2Item))
+ if (!equalMetadataItems(md1Item, md2Item))
{
return false;
}
@@ -281,7 +242,7 @@ static bool equalMetadata(const orion::BSONObj& md1, const orion::BSONObj& md2)
*
* changedAttr -
*/
-static bool attrValueChanges(const orion::BSONObj& attr, ContextAttribute* caP, const bool& forcedUpdate, ApiVersion apiVersion)
+static bool attrValueChanges(const orion::BSONObj& attr, ContextAttribute* caP)
{
/* Not finding the attribute field at MongoDB is considered as an implicit "" */
if (!attr.hasField(ENT_ATTRS_VALUE))
@@ -304,13 +265,13 @@ static bool attrValueChanges(const orion::BSONObj& attr, ContextAttribute* caP,
return true;
case orion::NumberDouble:
- return caP->valueType != orion::ValueTypeNumber || caP->numberValue != getNumberFieldF(attr, ENT_ATTRS_VALUE) || forcedUpdate;
+ return caP->valueType != orion::ValueTypeNumber || caP->numberValue != getNumberFieldF(attr, ENT_ATTRS_VALUE);
case orion::Bool:
- return caP->valueType != orion::ValueTypeBoolean || caP->boolValue != getBoolFieldF(attr, ENT_ATTRS_VALUE) || forcedUpdate;
+ return caP->valueType != orion::ValueTypeBoolean || caP->boolValue != getBoolFieldF(attr, ENT_ATTRS_VALUE);
case orion::String:
- return caP->valueType != orion::ValueTypeString || caP->stringValue != getStringFieldF(attr, ENT_ATTRS_VALUE) || forcedUpdate;
+ return caP->valueType != orion::ValueTypeString || caP->stringValue != getStringFieldF(attr, ENT_ATTRS_VALUE);
case orion::jstNULL:
return caP->valueType != orion::ValueTypeNull;
@@ -529,48 +490,50 @@ static ChangeType mergeAttrInfo
/* Was it an actual update? */
ChangeType changeType = NO_CHANGE;
+ /* We consider there is a change in the value if one or more of the following are true:
+ *
+ * 1) forcedUpdate is enabled
+ * 2) the value of the attribute changed (see attrValueChanges or CompoundValueNode::equal() for details)
+ * 3) the type of the attribute changed (in this case, !attr.hasField(ENT_ATTRS_TYPE) is needed, as attribute
+ * type is optional according to NGSI and the attribute may not have that field in the BSON)
+ *
+ * In addition, we consider there is change in the metadata if:
+ *
+ * 3) the metadata changed (this is done checking if the size of the original and final metadata vectors is
+ * different and, if they are of the same size, checking if the vectors are not equal)
+ */
+ bool valueChanged;
+ bool typeChanged;
+ bool mdChanged;
if (caP->compoundValueP == NULL)
{
- /* In the case of simple value, we consider there is a change in the value if one or more of the following are true:
- *
- * 1) the value of the attribute changed (see attrValueChanges for details)
- * 2) the type of the attribute changed (in this case, !attr.hasField(ENT_ATTRS_TYPE) is needed, as attribute
- * type is optional according to NGSI and the attribute may not have that field in the BSON)
- *
- * In addition, we consider there is change in the metadata if:
- *
- * 3) the metadata changed (this is done checking if the size of the original and final metadata vectors is
- * different and, if they are of the same size, checking if the vectors are not equal)
- */
- bool valueChanged = attrValueChanges(attr, caP, forcedUpdate, apiVersion) ||
- ((!caP->type.empty()) && (!attr.hasField(ENT_ATTRS_TYPE) || getStringFieldF(attr, ENT_ATTRS_TYPE) != caP->type) );
- bool mdChanged = (mdNew.nFields() != mdSize || !equalMetadata(md, mdNew));
-
- if (valueChanged && !mdChanged)
- {
- changeType = CHANGE_ONLY_VALUE;
- }
- else if (!valueChanged && mdChanged)
- {
- changeType = CHANGE_ONLY_MD;
- }
- else if (valueChanged && mdChanged)
- {
- changeType = CHANGE_VALUE_AND_MD;
- }
- else // !valueChanged && !mdChanged
- {
- changeType = NO_CHANGE;
- }
+ valueChanged = forcedUpdate || attrValueChanges(attr, caP);
}
else
{
- // FIXME #643 P6: in the case of compound value, it's more difficult to know if an attribute
- // has really changed its value (many levels have to be traversed). Until we can develop the
- // matching logic, we consider CHANGE_VALUE_AND_MD always.
- //
+ valueChanged = forcedUpdate || !caP->compoundValueP->equal(getFieldF(attr, ENT_ATTRS_VALUE));
+ }
+ typeChanged = ((!caP->type.empty()) && (!attr.hasField(ENT_ATTRS_TYPE) || getStringFieldF(attr, ENT_ATTRS_TYPE) != caP->type));
+ mdChanged = (mdNew.nFields() != mdSize || !equalMetadata(md, mdNew));
+
+ valueChanged = valueChanged || typeChanged;
+
+ if (valueChanged && !mdChanged)
+ {
+ changeType = CHANGE_ONLY_VALUE;
+ }
+ else if (!valueChanged && mdChanged)
+ {
+ changeType = CHANGE_ONLY_MD;
+ }
+ else if (valueChanged && mdChanged)
+ {
changeType = CHANGE_VALUE_AND_MD;
}
+ else // !valueChanged && !mdChanged
+ {
+ changeType = NO_CHANGE;
+ }
/* 5. Add modification date (actual change only if actual update) */
if (changeType)
diff --git a/src/lib/mongoDriver/BSONArray.cpp b/src/lib/mongoDriver/BSONArray.cpp
index 7e69099455..afef83670e 100644
--- a/src/lib/mongoDriver/BSONArray.cpp
+++ b/src/lib/mongoDriver/BSONArray.cpp
@@ -87,6 +87,17 @@ std::string BSONArray::toString(void) const
+/* ****************************************************************************
+*
+* BSONArray::equal -
+*/
+bool BSONArray::equal(const BSONArray& ba)
+{
+ return (bson_compare(this->b, ba.b) == 0);
+}
+
+
+
/* ****************************************************************************
*
* BSONArray::operator= -
diff --git a/src/lib/mongoDriver/BSONArray.h b/src/lib/mongoDriver/BSONArray.h
index d0e8b52c3f..098ac3520c 100644
--- a/src/lib/mongoDriver/BSONArray.h
+++ b/src/lib/mongoDriver/BSONArray.h
@@ -46,6 +46,7 @@ class BSONArray
BSONArray(const BSONArray& _ba);
int nFields(void) const;
std::string toString(void) const;
+ bool equal(const BSONArray& ba);
BSONArray& operator= (const BSONArray& rhs);
// methods to be used only by mongoDriver/ code (with references to low-level driver code)
diff --git a/src/lib/mongoDriver/BSONObj.cpp b/src/lib/mongoDriver/BSONObj.cpp
index ad1ad1efb7..d7fcad2a49 100644
--- a/src/lib/mongoDriver/BSONObj.cpp
+++ b/src/lib/mongoDriver/BSONObj.cpp
@@ -192,6 +192,17 @@ void BSONObj::toElementsVector(std::vector* v)
+/* ****************************************************************************
+*
+* BSONObj::equal -
+*/
+bool BSONObj::equal(const BSONObj& bo)
+{
+ return (bson_compare(this->b, bo.b) == 0);
+}
+
+
+
/* ****************************************************************************
*
* BSONObj::operator= -
diff --git a/src/lib/mongoDriver/BSONObj.h b/src/lib/mongoDriver/BSONObj.h
index d8b35f2c0b..473e974c01 100644
--- a/src/lib/mongoDriver/BSONObj.h
+++ b/src/lib/mongoDriver/BSONObj.h
@@ -59,6 +59,7 @@ class BSONObj
bool isEmpty(void) const;
void toStringMap(std::map* m);
void toElementsVector(std::vector* v);
+ bool equal(const BSONObj& bo);
BSONObj& operator= (const BSONObj& rhs);
// methods to be used only by mongoDriver/ code (with references to low-level driver code)
diff --git a/src/lib/parse/CompoundValueNode.cpp b/src/lib/parse/CompoundValueNode.cpp
index f26209f7a9..454c239383 100644
--- a/src/lib/parse/CompoundValueNode.cpp
+++ b/src/lib/parse/CompoundValueNode.cpp
@@ -33,6 +33,7 @@
#include "common/JsonHelper.h"
#include "common/macroSubstitute.h"
#include "alarmMgr/alarmMgr.h"
+#include "mongoDriver/safeMongo.h"
#include "parse/forbiddenChars.h"
#include "orionTypes/OrionValueType.h"
@@ -522,6 +523,90 @@ std::string CompoundValueNode::check(const std::string& path)
+/* ****************************************************************************
+*
+* CompoundValueNode::equal
+*
+*/
+bool CompoundValueNode::equal(const orion::BSONElement& be)
+{
+ // Note objects cannot be declared inside switch block
+ std::vector ba;
+ orion::BSONObj bo;
+
+ switch (valueType)
+ {
+ case orion::ValueTypeString:
+ return (be.type() == orion::String) && (stringValue == be.String());
+
+ case orion::ValueTypeNumber:
+ // FIXME P2: according to regression tests, this seems to work with all number types (int32/int64/double)
+ // However, let's keep an eye on this in the case some day it fails...
+ return (be.type() == orion::NumberDouble && numberValue == be.Number());
+
+ case orion::ValueTypeBoolean:
+ return (be.type() == orion::Bool) && (boolValue == be.Bool());
+
+ case orion::ValueTypeNull:
+ return (be.type() == orion::jstNULL);
+
+ case orion::ValueTypeVector:
+ // nodeP must be a vector
+ if (be.type() != orion::Array)
+ {
+ return false;
+ }
+ ba = be.Array();
+ // nodeP must have the same number of elements
+ if (childV.size() != ba.size())
+ {
+ return false;
+ }
+ for (unsigned int ix = 0; ix < childV.size(); ix++)
+ {
+ if (!(childV[ix]->equal(ba[ix])))
+ {
+ return false;
+ }
+ }
+ return true;
+
+ case orion::ValueTypeObject:
+ // nodeP must be a object
+ if (be.type() != orion::Object)
+ {
+ return false;
+ }
+ bo = be.embeddedObject();
+ if ((int) childV.size() != bo.nFields())
+ {
+ return false;
+ }
+ for (unsigned int ix = 0; ix < childV.size(); ix++)
+ {
+ if (!bo.hasField(childV[ix]->name))
+ {
+ return false;
+ }
+ if (!(childV[ix]->equal(getFieldF(bo, childV[ix]->name))))
+ {
+ return false;
+ }
+ }
+ return true;
+
+ case orion::ValueTypeNotGiven:
+ LM_E(("Runtime Error (value type not given (%s))", name.c_str()));
+ return false;
+
+ default:
+ LM_E(("Runtime Error (value type unknown (%s))", name.c_str()));
+ return false;
+ }
+}
+
+
+
/* ****************************************************************************
*
* CompoundValueNode:toJson
diff --git a/src/lib/parse/CompoundValueNode.h b/src/lib/parse/CompoundValueNode.h
index 98f65b38a4..b46aa2c461 100644
--- a/src/lib/parse/CompoundValueNode.h
+++ b/src/lib/parse/CompoundValueNode.h
@@ -33,6 +33,8 @@
#include "orionTypes/OrionValueType.h"
+#include "mongoDriver/BSONElement.h"
+
namespace orion
{
@@ -112,6 +114,7 @@ class CompoundValueNode
CompoundValueNode* add(const orion::ValueType _type, const std::string& _name, double _value);
CompoundValueNode* add(const orion::ValueType _type, const std::string& _name, bool _value);
std::string check(const std::string& path);
+ bool equal(const orion::BSONElement& be);
std::string finish(void);
std::string toJson(std::map* replacementsP = NULL);
diff --git a/test/functionalTest/README.jp.md b/test/functionalTest/README.jp.md
index b744839cea..2af29f123f 100644
--- a/test/functionalTest/README.jp.md
+++ b/test/functionalTest/README.jp.md
@@ -27,6 +27,7 @@ virtualenv --python=/usr/bin/python3 /path/to/ft_env
```
pip install Flask==2.0.2
+pip install Werkzeug==2.0.2
pip install paho-mqtt==1.6.1
pip install amqtt==0.11.0b1 # Not actually an accumulator-server.py dependency, but needed by some tests
```
@@ -52,10 +53,15 @@ accumulator-server.py -u
```
FROM debian:stable
RUN apt-get update -y
-RUN apt-get install -y python3
-RUN apt-get install -y python3-pip
-RUN pip install Flask==2.0.2
-RUN pip install paho-mqtt==1.6.1
+RUN apt-get install -y python3 python3-venv python3-pip
+
+# Create a virtual environment
+RUN python3 -m venv /venv
+ENV PATH="/venv/bin:$PATH"
+
+# Install required packages within the virtual environment
+RUN pip install Flask==2.0.2 Werkzeug==2.0.2 paho-mqtt==1.6.1
+
COPY . /app
WORKDIR /app
ENTRYPOINT [ "python3", "./accumulator-server.py"]
diff --git a/test/functionalTest/README.md b/test/functionalTest/README.md
index 541e1f02bc..8fbe8e57d8 100644
--- a/test/functionalTest/README.md
+++ b/test/functionalTest/README.md
@@ -25,6 +25,7 @@ Next install accumulator-server.py depencencies:
```
pip install Flask==2.0.2
+pip install Werkzeug==2.0.2
pip install paho-mqtt==1.6.1
pip install amqtt==0.11.0b1 # Not actually an accumulator-server.py dependency, but needed by some tests
```
@@ -57,7 +58,7 @@ RUN python3 -m venv /venv
ENV PATH="/venv/bin:$PATH"
# Install required packages within the virtual environment
-RUN pip install Flask==2.0.2 paho-mqtt==1.6.1
+RUN pip install Flask==2.0.2 Werkzeug==2.0.2 paho-mqtt==1.6.1
COPY . /app
WORKDIR /app
diff --git a/test/functionalTest/cases/0725_multiservice_ignore/service_ignore_without_multiservice.test b/test/functionalTest/cases/0725_multiservice_ignore/service_ignore_without_multiservice.test
index 20b21596de..100bea14eb 100644
--- a/test/functionalTest/cases/0725_multiservice_ignore/service_ignore_without_multiservice.test
+++ b/test/functionalTest/cases/0725_multiservice_ignore/service_ignore_without_multiservice.test
@@ -27,7 +27,7 @@ Ignoring service header when not running in multiservice mode
dbInit CB
dbInit ${CB_DB_NAME}-foo
dbResetAll
-echo "show dbs" | mongo | grep ${CB_DB_NAME} | awk '{ print $1 }'
+mongosh --eval 'show dbs' | grep ${CB_DB_NAME} | awk '{ print $1 }'
brokerStart CB 0-255 IPV4
@@ -59,14 +59,14 @@ echo
echo "2. Check that the number of orion databases is just 1"
echo "====================================================="
# In this case mongoCmd helper is not used, due to we don't have
-# a particular database for mongo command and the output could be
+# a particular database for mongosh command and the output could be
# multiline in a general case
-echo "show dbs" | mongo | grep ${CB_DB_NAME} | wc -l
-echo "show dbs" | mongo | grep ${CB_DB_NAME}-foo | wc -l
+mongosh --eval 'show dbs' | grep ${CB_DB_NAME} | wc -l
+mongosh --eval 'show dbs' | grep ${CB_DB_NAME}-foo | wc -l
# Next line was added in PR https://github.com/telefonicaid/fiware-orion/pull/1184/files#r37738638
# in order to help us to detect where the ftest-ftest-ftest-... problem is. It could happen that
# after fixing #1186 this is no longer needed, but let's keep it for a while as a "quarentine" measure...
-echo "show dbs" | mongo | grep ${CB_DB_NAME} | awk '{ print $1 }'
+mongosh --eval 'show dbs' | grep ${CB_DB_NAME} | awk '{ print $1 }'
--REGEXPECT--
1. Create an entity using foo as tenant
diff --git a/test/functionalTest/cases/1048_subscription_cache/get_subscription_before_and_after_cache_refresh.test b/test/functionalTest/cases/1048_subscription_cache/get_subscription_before_and_after_cache_refresh.test
index 0f616583fe..4ed5c6ef33 100644
--- a/test/functionalTest/cases/1048_subscription_cache/get_subscription_before_and_after_cache_refresh.test
+++ b/test/functionalTest/cases/1048_subscription_cache/get_subscription_before_and_after_cache_refresh.test
@@ -26,7 +26,7 @@ Get subscription before and after cache refresh
--SHELL-INIT--
dbInit CB
-mongoCmd ${CB_DB_NAME} 'db.csubs.insert({
+mongoCmd ${CB_DB_NAME} 'db.csubs.insertOne({
"_id" : ObjectId("61960a51596aa2623032357d"),
"expiration" : NumberLong("9223372036854775807"),
"reference" : "http://localhost:1028/accumulate",
@@ -134,15 +134,15 @@ echo
echo "02. Set dynamic fields in DB to set B"
echo "====================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.update({_id: ObjectId("61960a51596aa2623032357d")}, {
+mongoCmd ${CB_DB_NAME} 'db.csubs.updateOne({_id: ObjectId("61960a51596aa2623032357d")}, {
$set: {
- lastNotification: NumberLong(1577876400),
- lastSuccess: NumberLong(1577876400),
- lastFailure: NumberLong(1577872800),
- lastSuccessCode: NumberLong(204),
+ lastNotification: NumberLong("1577876400"),
+ lastSuccess: NumberLong("1577876400"),
+ lastFailure: NumberLong("1577872800"),
+ lastSuccessCode: NumberLong("204"),
lastFailureReason: "Timeout",
- count: NumberLong(25),
- failsCounter: NumberLong(8),
+ count: NumberLong("25"),
+ failsCounter: NumberLong("8"),
status: "inactive",
statusLastChange: 1578733200
}
@@ -217,7 +217,7 @@ Content-Length: 551
02. Set dynamic fields in DB to set B
=====================================
-WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
+{"acknowledged":true,"insertedId":null,"matchedCount":1,"modifiedCount":1,"upsertedCount":0}
03. GET /v2/subscriptions and see dynamic fields set B although cache has not been synched yet
diff --git a/test/functionalTest/cases/1048_subscription_cache/get_subscription_before_and_after_cache_refresh_status_in_db_older.test b/test/functionalTest/cases/1048_subscription_cache/get_subscription_before_and_after_cache_refresh_status_in_db_older.test
index f377701aee..157a789900 100644
--- a/test/functionalTest/cases/1048_subscription_cache/get_subscription_before_and_after_cache_refresh_status_in_db_older.test
+++ b/test/functionalTest/cases/1048_subscription_cache/get_subscription_before_and_after_cache_refresh_status_in_db_older.test
@@ -26,7 +26,7 @@ Get subscription before and after cache refresh with status older in DB during r
--SHELL-INIT--
dbInit CB
-mongoCmd ${CB_DB_NAME} 'db.csubs.insert({
+mongoCmd ${CB_DB_NAME} 'db.csubs.insertOne({
"_id" : ObjectId("61960a51596aa2623032357d"),
"expiration" : NumberLong("9223372036854775807"),
"reference" : "http://localhost:1028/accumulate",
@@ -99,15 +99,15 @@ echo
echo "02. Set dynamic fields in DB to set B"
echo "====================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.update({_id: ObjectId("61960a51596aa2623032357d")}, {
+mongoCmd ${CB_DB_NAME} 'db.csubs.updateOne({_id: ObjectId("61960a51596aa2623032357d")}, {
$set: {
- lastNotification: NumberLong(1577876400),
- lastSuccess: NumberLong(1577876400),
- lastFailure: NumberLong(1577872800),
- lastSuccessCode: NumberLong(204),
+ lastNotification: NumberLong("1577876400"),
+ lastSuccess: NumberLong("1577876400"),
+ lastFailure: NumberLong("1577872800"),
+ lastSuccessCode: NumberLong("204"),
lastFailureReason: "Timeout",
- count: NumberLong(25),
- failsCounter: NumberLong(8),
+ count: NumberLong("25"),
+ failsCounter: NumberLong("8"),
status: "inactive",
statusLastChange: 1577869200
}
@@ -182,7 +182,7 @@ Content-Length: 551
02. Set dynamic fields in DB to set B
=====================================
-WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
+{"acknowledged":true,"insertedId":null,"matchedCount":1,"modifiedCount":1,"upsertedCount":0}
03. GET /v2/subscriptions and see dynamic fields set B although cache has not been synched yet
diff --git a/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_disabled.test b/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_disabled.test
index b9f43ee4f1..1202288ba8 100644
--- a/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_disabled.test
+++ b/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_disabled.test
@@ -26,7 +26,7 @@ Cache refresh keeps newer information from cache in disabled notification scenar
--SHELL-INIT--
dbInit CB
-mongoCmd ${CB_DB_NAME} 'db.csubs.insert({
+mongoCmd ${CB_DB_NAME} 'db.csubs.insertOne({
"_id" : ObjectId("61960a51596aa2623032357d"),
"expiration" : NumberLong("9223372036854775807"),
"reference" : "http://localhost:9997/notify",
@@ -131,7 +131,7 @@ echo
echo "05. Get doc in DB before cache refresh and see status active changed in the past and without count and without failsCounter"
echo "==========================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -146,7 +146,7 @@ echo
echo "07. Get doc in DB after cache refresh and see status inactive changed in the present and count 2, failsCounter 2"
echo "================================================================================================================"
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
diff --git a/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_disabled_with_update_in_the_middle.test b/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_disabled_with_update_in_the_middle.test
index 7b037d9373..384ede8153 100644
--- a/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_disabled_with_update_in_the_middle.test
+++ b/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_disabled_with_update_in_the_middle.test
@@ -26,7 +26,7 @@ Cache refresh keeps newer information from cache in disabled notification scenar
--SHELL-INIT--
dbInit CB
-mongoCmd ${CB_DB_NAME} 'db.csubs.insert({
+mongoCmd ${CB_DB_NAME} 'db.csubs.insertOne({
"_id" : ObjectId("61960a51596aa2623032357d"),
"expiration" : NumberLong("9223372036854775807"),
"reference" : "http://localhost:9997/notify",
@@ -133,7 +133,7 @@ echo
echo "05. Get doc in DB before cache refresh and see status active changed in the past and without count and without failsCounter"
echo "==========================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -150,7 +150,7 @@ echo
echo "07. Get doc in DB before cache refresh and see status active changed in the past and without count and without failsCounter + description"
echo "========================================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -165,7 +165,7 @@ echo
echo "09. Get doc in DB after cache refresh and see status inactive changed in the present and count 2, failsCounter 2 + description"
echo "=============================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
diff --git a/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_fail.test b/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_fail.test
index f0a00408b0..7272205b19 100644
--- a/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_fail.test
+++ b/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_fail.test
@@ -26,7 +26,7 @@ Cache refresh keeps newer information from cache in failed notification scenario
--SHELL-INIT--
dbInit CB
-mongoCmd ${CB_DB_NAME} 'db.csubs.insert({
+mongoCmd ${CB_DB_NAME} 'db.csubs.insertOne({
"_id" : ObjectId("61960a51596aa2623032357d"),
"expiration" : NumberLong("9223372036854775807"),
"reference" : "http://localhost:9997/notify",
@@ -124,7 +124,7 @@ echo
echo "04. Get doc in DB before cache refresh and see lastNotification/Failure in a the past and reason 'some reason' but no count and no failsCounter"
echo "==============================================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -139,7 +139,7 @@ echo
echo "06. Get doc in DB after cache refresh and see lastNotification/Failure in the present and reason 'could not connect' and count 1 and failsCounter 1"
echo "==================================================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
diff --git a/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_fail_with_update_in_the_middle.test b/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_fail_with_update_in_the_middle.test
index d13bc3f79d..f602ba30b6 100644
--- a/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_fail_with_update_in_the_middle.test
+++ b/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_fail_with_update_in_the_middle.test
@@ -26,7 +26,7 @@ Cache refresh keeps newer information from cache in failed notification scenario
--SHELL-INIT--
dbInit CB
-mongoCmd ${CB_DB_NAME} 'db.csubs.insert({
+mongoCmd ${CB_DB_NAME} 'db.csubs.insertOne({
"_id" : ObjectId("61960a51596aa2623032357d"),
"expiration" : NumberLong("9223372036854775807"),
"reference" : "http://localhost:9997/notify",
@@ -126,7 +126,7 @@ echo
echo "04. Get doc in DB before cache refresh and see lastNotification/Failure in a the past and reason 'some reason' but no count and no failsCounter"
echo "==============================================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -143,7 +143,7 @@ echo
echo "06. Get doc in DB before cache refresh and see lastNotification/Failure in a the past and reason 'some reason' but no count and no failsCounter + description"
echo "============================================================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -158,7 +158,7 @@ echo
echo "08. Get doc in DB after cache refresh and see lastNotification/Failure in the present and reason 'could not connect' and count 1 and failsCounter 1 + description"
echo "================================================================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
diff --git a/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_success.test b/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_success.test
index e552f2aa5d..b39bae8cba 100644
--- a/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_success.test
+++ b/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_success.test
@@ -26,7 +26,7 @@ Cache refresh keeps newer information from cache in successfull notification sce
--SHELL-INIT--
dbInit CB
-mongoCmd ${CB_DB_NAME} 'db.csubs.insert({
+mongoCmd ${CB_DB_NAME} 'db.csubs.insertOne({
"_id" : ObjectId("61960a51596aa2623032357d"),
"expiration" : NumberLong("9223372036854775807"),
"reference" : "http://localhost:9997/notify",
@@ -126,7 +126,7 @@ echo
echo "04. Get doc in DB before cache refresh and see lastNotification/Success in the past and status code 211 but no count"
echo "===================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -141,7 +141,7 @@ echo
echo "06. Get doc in DB after cache refresh and see lastNotification/Success in the present and status code 200 and count 1"
echo "====================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
diff --git a/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_success_with_update_in_the_middle.test b/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_success_with_update_in_the_middle.test
index c4353bc50a..850b9d6765 100644
--- a/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_success_with_update_in_the_middle.test
+++ b/test/functionalTest/cases/1048_subscription_cache/refresh_cache_wins_notif_success_with_update_in_the_middle.test
@@ -26,7 +26,7 @@ Cache refresh keeps newer information from cache in successfull notification sce
--SHELL-INIT--
dbInit CB
-mongoCmd ${CB_DB_NAME} 'db.csubs.insert({
+mongoCmd ${CB_DB_NAME} 'db.csubs.insertOne({
"_id" : ObjectId("61960a51596aa2623032357d"),
"expiration" : NumberLong("9223372036854775807"),
"reference" : "http://localhost:9997/notify",
@@ -128,7 +128,7 @@ echo
echo "04. Get doc in DB before cache refresh and see lastNotification/Success in the past and status code 211 but no count"
echo "===================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -145,7 +145,7 @@ echo
echo "06. Get doc in DB before cache refresh and see lastNotification/Success in the past and status code 211 but no count + description"
echo "=================================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -160,7 +160,7 @@ echo
echo "08. Get doc in DB after cache refresh and see lastNotification/Success in the present and status code 200 and count 1 + description"
echo "==================================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
diff --git a/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_disabled.test b/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_disabled.test
index b4986ff145..d3ceaa5982 100644
--- a/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_disabled.test
+++ b/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_disabled.test
@@ -26,7 +26,7 @@ Cache refresh takes newer information from DB in disabled notification scenario
--SHELL-INIT--
dbInit CB
-mongoCmd ${CB_DB_NAME} 'db.csubs.insert({
+mongoCmd ${CB_DB_NAME} 'db.csubs.insertOne({
"_id" : ObjectId("61960a51596aa2623032357d"),
"expiration" : NumberLong("9223372036854775807"),
"reference" : "http://localhost:9997/notify",
@@ -128,7 +128,7 @@ echo
echo "05. Get doc in DB before cache refresh and see status active changed in a far future and without count and without failsCounter"
echo "==============================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -143,7 +143,7 @@ echo
echo "07. Get doc in DB after cache refresh and see status active changed in a far future and count 2, failsCounter 2"
echo "==============================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
diff --git a/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_disabled_with_update_in_the_middle.test b/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_disabled_with_update_in_the_middle.test
index 86c2f0cdc9..d93748cb57 100644
--- a/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_disabled_with_update_in_the_middle.test
+++ b/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_disabled_with_update_in_the_middle.test
@@ -26,7 +26,7 @@ Cache refresh takes newer information from DB in disabled notification scenario
--SHELL-INIT--
dbInit CB
-mongoCmd ${CB_DB_NAME} 'db.csubs.insert({
+mongoCmd ${CB_DB_NAME} 'db.csubs.insertOne({
"_id" : ObjectId("61960a51596aa2623032357d"),
"expiration" : NumberLong("9223372036854775807"),
"reference" : "http://localhost:9997/notify",
@@ -130,7 +130,7 @@ echo
echo "05. Get doc in DB before cache refresh and see status active changed in a far future and without count and without failsCounter"
echo "==============================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -147,7 +147,7 @@ echo
echo "07. Get doc in DB before cache refresh and see status active changed in a far future and without count and without failsCounter + description"
echo "============================================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -162,7 +162,7 @@ echo
echo "09. Get doc in DB after cache refresh and see status active changed in a far future and count 2, failsCounter 2 + description"
echo "============================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
diff --git a/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_fail.test b/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_fail.test
index 4dfe82b91c..032e2ed5d4 100644
--- a/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_fail.test
+++ b/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_fail.test
@@ -26,7 +26,7 @@ Cache refresh takes newer information from DB in failed notification scenario
--SHELL-INIT--
dbInit CB
-mongoCmd ${CB_DB_NAME} 'db.csubs.insert({
+mongoCmd ${CB_DB_NAME} 'db.csubs.insertOne({
"_id" : ObjectId("61960a51596aa2623032357d"),
"expiration" : NumberLong("9223372036854775807"),
"reference" : "http://localhost:9997/notify",
@@ -121,7 +121,7 @@ echo
echo "04. Get doc in DB before cache refresh and see lastNotification/Failure in a far future and reason 'some reason' but no count and no failsCounter"
echo "================================================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -136,7 +136,7 @@ echo
echo "06. Get doc in DB after cache refresh and see lastNotification/Failure in a far future and reason 'some reason' and count 1 and failsCounter 1"
echo "=============================================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
diff --git a/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_fail_with_update_in_the_middle.test b/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_fail_with_update_in_the_middle.test
index 9792d862f6..1a7e1a5093 100644
--- a/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_fail_with_update_in_the_middle.test
+++ b/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_fail_with_update_in_the_middle.test
@@ -26,7 +26,7 @@ Cache refresh takes newer information from DB in failed notification scenario wi
--SHELL-INIT--
dbInit CB
-mongoCmd ${CB_DB_NAME} 'db.csubs.insert({
+mongoCmd ${CB_DB_NAME} 'db.csubs.insertOne({
"_id" : ObjectId("61960a51596aa2623032357d"),
"expiration" : NumberLong("9223372036854775807"),
"reference" : "http://localhost:9997/notify",
@@ -123,7 +123,7 @@ echo
echo "04. Get doc in DB before cache refresh and see lastNotification/Failure in a far future and reason 'some reason' but no count and no failsCounter"
echo "================================================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -140,7 +140,7 @@ echo
echo "06. Get doc in DB before cache refresh and see lastNotification/Failure in a far future and reason 'some reason' but no count and no failsCounter + description"
echo "==============================================================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -155,7 +155,7 @@ echo
echo "08. Get doc in DB after cache refresh and see lastNotification/Failure in a far future and reason 'some reason' and count 1 and failsCounter 1 + description"
echo "============================================================================================================================================================"
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
diff --git a/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_success.test b/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_success.test
index 64d3648b08..51dff14bbc 100644
--- a/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_success.test
+++ b/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_success.test
@@ -26,7 +26,7 @@ Cache refresh takes newer information from DB in successfull notification scenar
--SHELL-INIT--
dbInit CB
-mongoCmd ${CB_DB_NAME} 'db.csubs.insert({
+mongoCmd ${CB_DB_NAME} 'db.csubs.insertOne({
"_id" : ObjectId("61960a51596aa2623032357d"),
"expiration" : NumberLong("9223372036854775807"),
"reference" : "http://localhost:9997/notify",
@@ -123,7 +123,7 @@ echo
echo "04. Get doc in DB before cache refresh and see lastNotification/Success in a far future and status code 211 but no count"
echo "========================================================================================================================"
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -138,7 +138,7 @@ echo
echo "06. Get doc in DB after cache refresh and see lastNotification/Success in a far future and status code 211 and count 1"
echo "======================================================================================================================"
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
diff --git a/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_success_with_update_in_the_middle.test b/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_success_with_update_in_the_middle.test
index eb2d3961d5..c20ce9479a 100644
--- a/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_success_with_update_in_the_middle.test
+++ b/test/functionalTest/cases/1048_subscription_cache/refresh_db_wins_notif_success_with_update_in_the_middle.test
@@ -26,7 +26,7 @@ Cache refresh takes newer information from DB in successfull notification scenar
--SHELL-INIT--
dbInit CB
-mongoCmd ${CB_DB_NAME} 'db.csubs.insert({
+mongoCmd ${CB_DB_NAME} 'db.csubs.insertOne({
"_id" : ObjectId("61960a51596aa2623032357d"),
"expiration" : NumberLong("9223372036854775807"),
"reference" : "http://localhost:9997/notify",
@@ -125,7 +125,7 @@ echo
echo "04. Get doc in DB before cache refresh and see lastNotification/Success in a far future and status code 211 but no count"
echo "========================================================================================================================"
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -142,7 +142,7 @@ echo
echo "06. Get doc in DB before cache refresh and see lastNotification/Success in a far future and status code 211 but no count + description"
echo "======================================================================================================================================"
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -157,7 +157,7 @@ echo
echo "08. Get doc in DB after cache refresh and see lastNotification/Success in a far future and status code 211 and count 1 + description"
echo "===================================================================================================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.find({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | sed 's/NumberLong(\([[:digit:]]\+\))/\1/g' | sed 's/NumberLong("\([[:digit:]]\+\)")/\1/g' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.csubs.findOne({ _id: ObjectId("61960a51596aa2623032357d")}, {_id:0, expiration: 0})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
diff --git a/test/functionalTest/cases/1112_metadata_as_keymap/metadata_with_dots_v2.test b/test/functionalTest/cases/1112_metadata_as_keymap/metadata_with_dots_v2.test
index a2c3e5a2d1..ddb7f001a0 100644
--- a/test/functionalTest/cases/1112_metadata_as_keymap/metadata_with_dots_v2.test
+++ b/test/functionalTest/cases/1112_metadata_as_keymap/metadata_with_dots_v2.test
@@ -68,7 +68,7 @@ echo
echo "03. Check the '=' in DB"
echo "======================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find({ "_id" : { "id" : "E", "type": "T", "servicePath" : "/" } }, {_id:0, attrs: 1})'
+mongoCmd ${CB_DB_NAME} 'db.entities.findOne({ "_id" : { "id" : "E", "type": "T", "servicePath" : "/" } }, {_id:0, attrs: 1})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -114,7 +114,30 @@ Content-Length: 139
03. Check the '=' in DB
=======================
-{ "attrs" : { "A" : { "value" : "foo", "type" : "T", "creDate" : REGEX(.*), "md" : { "m=x" : { "type" : "string", "value" : "black" }, "m=y" : { "type" : "double", "value" : 5 } }, "mdNames" : [ "m.x", "m.y" ] } } }
+{
+ "attrs": {
+ "A": {
+ "creDate": REGEX(.*),
+ "md": {
+ "m=x": {
+ "type": "string",
+ "value": "black"
+ },
+ "m=y": {
+ "type": "double",
+ "value": 5
+ }
+ },
+ "mdNames": [
+ "m.x",
+ "m.y"
+ ],
+ "modDate": REGEX(.*),
+ "type": "T",
+ "value": "foo"
+ }
+ }
+}
--TEARDOWN--
diff --git a/test/functionalTest/cases/1170_get_types_values_option/get_types_values_option_with_empty_type_entities.test b/test/functionalTest/cases/1170_get_types_values_option/get_types_values_option_with_empty_type_entities.test
index 4cd0acf465..dfd643fc66 100644
--- a/test/functionalTest/cases/1170_get_types_values_option/get_types_values_option_with_empty_type_entities.test
+++ b/test/functionalTest/cases/1170_get_types_values_option/get_types_values_option_with_empty_type_entities.test
@@ -72,7 +72,7 @@ echo "====================================="
# It seems that the ability to generate _id.type = "" was lost in some old Orion version
# (although some DB generated with old versions could persist nowadays). Thus, we need to
# createthis entity with a hack at MongoDB level
-mongoCmd ${CB_DB_NAME} 'db.entities.insert({
+mongoCmd ${CB_DB_NAME} 'db.entities.insertOne({
"_id": {
"id": "E2",
"type": "",
@@ -171,7 +171,7 @@ Content-Length: 6
04. Create E2/""/A1+A3 (using NGSIv1)
=====================================
-WriteResult({ "nInserted" : 1 })
+{"acknowledged":true,"insertedId":{"id":"E2","type":"","servicePath":"/"}}
05. Create E3/T3/A2+A4
diff --git a/test/functionalTest/cases/1170_get_types_values_option/get_types_values_option_with_null_and_empty_types.test b/test/functionalTest/cases/1170_get_types_values_option/get_types_values_option_with_null_and_empty_types.test
index fcee2f5939..8f9dd731a4 100644
--- a/test/functionalTest/cases/1170_get_types_values_option/get_types_values_option_with_null_and_empty_types.test
+++ b/test/functionalTest/cases/1170_get_types_values_option/get_types_values_option_with_null_and_empty_types.test
@@ -52,7 +52,7 @@ echo "======================"
# It seems that the ability to generate _id.type = "" was lost in some old Orion version
# (although some DB generated with old versions could persist nowadays). Thus, we need to
# createthis entity with a hack at MongoDB level
-mongoCmd ${CB_DB_NAME} 'db.entities.insert({
+mongoCmd ${CB_DB_NAME} 'db.entities.insertOne({
"_id": {
"id": "E1",
"type": "",
@@ -163,7 +163,7 @@ Content-Length: 2
02. Create E1/""/A1+A2
======================
-WriteResult({ "nInserted" : 1 })
+{"acknowledged":true,"insertedId":{"id":"E1","type":"","servicePath":"/"}}
03. GET /v2/types?options=values and get a non-empty list
diff --git a/test/functionalTest/cases/1323_put_replacing_dot_in_attrnames/put_replacing_dot_in_attrnames.test b/test/functionalTest/cases/1323_put_replacing_dot_in_attrnames/put_replacing_dot_in_attrnames.test
index 298850f82d..d34a341357 100644
--- a/test/functionalTest/cases/1323_put_replacing_dot_in_attrnames/put_replacing_dot_in_attrnames.test
+++ b/test/functionalTest/cases/1323_put_replacing_dot_in_attrnames/put_replacing_dot_in_attrnames.test
@@ -117,7 +117,7 @@ echo
echo "07. Check attributes in DB"
echo "=========================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find({ "_id" : { "id" : "E1", "type": "Thing", "servicePath" : "/" } }, {_id:0, attrNames: 1})'
+mongoCmd ${CB_DB_NAME} 'db.entities.findOne({ "_id" : { "id" : "E1", "type": "Thing", "servicePath" : "/" } }, {_id:0, attrNames: 1})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -279,7 +279,12 @@ Content-Length: 10
07. Check attributes in DB
==========================
-{ "attrNames" : [ "A2..y", "A3.Z" ] }
+{
+ "attrNames": [
+ "A2..y",
+ "A3.Z"
+ ]
+}
--TEARDOWN--
diff --git a/test/functionalTest/cases/1661_bad_input_on_notification_error/bad_input_on_notification_error.test b/test/functionalTest/cases/1661_bad_input_on_notification_error/bad_input_on_notification_error.test
index 91c152b1fe..c726bb7a88 100644
--- a/test/functionalTest/cases/1661_bad_input_on_notification_error/bad_input_on_notification_error.test
+++ b/test/functionalTest/cases/1661_bad_input_on_notification_error/bad_input_on_notification_error.test
@@ -168,7 +168,7 @@ echo
echo "07. Corrupt reference in subscription (using mongo)"
echo "==================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.update({_id: ObjectId("'$SUB_ID'")}, { $set: { "reference": "badReferenceForSubscription" }})'
+mongoCmd ${CB_DB_NAME} 'db.csubs.updateOne({_id: ObjectId("'$SUB_ID'")}, { $set: { "reference": "badReferenceForSubscription" }})'
echo
echo
@@ -265,7 +265,7 @@ Releasing alarm BadInput REGEX((0.0.0.0|127.0.0.1))
07. Corrupt reference in subscription (using mongo)
===================================================
-WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
+{"acknowledged":true,"insertedId":null,"matchedCount":1,"modifiedCount":1,"upsertedCount":0}
08. Wait six seconds to assure the subscription cache has been modified
diff --git a/test/functionalTest/cases/1661_bad_input_on_notification_error/bad_input_on_notification_error_with_relogged_alarms.test b/test/functionalTest/cases/1661_bad_input_on_notification_error/bad_input_on_notification_error_with_relogged_alarms.test
index 773ddecae9..c99478e16b 100644
--- a/test/functionalTest/cases/1661_bad_input_on_notification_error/bad_input_on_notification_error_with_relogged_alarms.test
+++ b/test/functionalTest/cases/1661_bad_input_on_notification_error/bad_input_on_notification_error_with_relogged_alarms.test
@@ -168,7 +168,7 @@ echo
echo "07. Corrupt reference in subscription (using mongo)"
echo "==================================================="
-mongoCmd ${CB_DB_NAME} 'db.csubs.update({_id: ObjectId("'$SUB_ID'")}, { $set: { "reference": "badReferenceForSubscription" }})'
+mongoCmd ${CB_DB_NAME} 'db.csubs.updateOne({_id: ObjectId("'$SUB_ID'")}, { $set: { "reference": "badReferenceForSubscription" }})'
echo
echo
@@ -269,7 +269,7 @@ Releasing alarm BadInput REGEX((0.0.0.0|127.0.0.1))
07. Corrupt reference in subscription (using mongo)
===================================================
-WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
+{"acknowledged":true,"insertedId":null,"matchedCount":1,"modifiedCount":1,"upsertedCount":0}
08. Wait six seconds to assure the subscription cache has been modified
diff --git a/test/functionalTest/cases/1715_batch_update/batch_update_DELETE.test b/test/functionalTest/cases/1715_batch_update/batch_update_DELETE.test
index ab5b5dcd56..8568b6fbfb 100644
--- a/test/functionalTest/cases/1715_batch_update/batch_update_DELETE.test
+++ b/test/functionalTest/cases/1715_batch_update/batch_update_DELETE.test
@@ -21,7 +21,7 @@
# VALGRIND_READY - to mark the test ready for valgrindTestSuite.sh
--NAME--
-V2 batch update REPLACE
+V2 batch update DELETE
--SHELL-INIT--
dbInit CB
diff --git a/test/functionalTest/cases/1715_batch_update/batch_update_DELETE_non_existing_and_existing.test b/test/functionalTest/cases/1715_batch_update/batch_update_DELETE_non_existing_and_existing.test
new file mode 100644
index 0000000000..8cd808c80b
--- /dev/null
+++ b/test/functionalTest/cases/1715_batch_update/batch_update_DELETE_non_existing_and_existing.test
@@ -0,0 +1,290 @@
+# Copyright 2023 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--
+V2 batch update DELETE in non existing and existing attribute
+
+--SHELL-INIT--
+dbInit CB
+brokerStart CB 0
+
+--SHELL--
+
+#
+# 01. Create E1/T/A1-A2-A3, E2/T/A1-A3 and E3/T/A1-A2-A3 using POST /v2/op/update with append
+# 02. GET /v2/entities to see E1/T/A1-A2-A3, E2/T/A1-A3 and E3/T/A1-A2-A3
+# 03. Delete E1-A1/A2=null, E2-A1/A2=null (A2 not existing) and E3-A1/A2=null using POST /v2/op/update with delete, get error
+# 04. GET /v2/entities to see E1/T/A3, E2/T/A1-A3 and E3/T/A3 in entities
+#
+
+echo "01. Create E1/T/A1-A2-A3, E2/T/A1-A3 and E3/T/A1-A2-A3 using POST /v2/op/update with append"
+echo "==========================================================================================="
+payload='{
+ "actionType": "append",
+ "entities": [
+ {
+ "id": "E1",
+ "type": "T",
+ "A1": {
+ "type": "Number",
+ "value": 11
+ },
+ "A2": {
+ "type": "Number",
+ "value": 12
+ },
+ "A3": {
+ "type": "Number",
+ "value": 13
+ }
+ },
+ {
+ "id": "E2",
+ "type": "T",
+ "A1": {
+ "type": "Number",
+ "value": 21
+ },
+ "A3": {
+ "type": "Number",
+ "value": 23
+ }
+ },
+ {
+ "id": "E3",
+ "type": "T",
+ "A1": {
+ "type": "Number",
+ "value": 31
+ },
+ "A2": {
+ "type": "Number",
+ "value": 32
+ },
+ "A3": {
+ "type": "Number",
+ "value": 33
+ }
+ }
+ ]
+}'
+orionCurl --url /v2/op/update --payload "$payload"
+echo
+echo
+
+
+echo "02. GET /v2/entities to see E1/T/A1-A2-A3, E2/T/A1-A3 and E3/T/A1-A2-A3"
+echo "======================================================================="
+orionCurl --url /v2/entities
+echo
+echo
+
+
+echo "03. Delete E1-A1/A2=null, E2-A1/A2=null (A2 not existing) and E3-A1/A2=null using POST /v2/op/update with delete, get error"
+echo "==========================================================================================================================="
+payload='{
+ "actionType": "delete",
+ "entities": [
+ {
+ "id": "E1",
+ "type": "T",
+ "A1": {
+ "type": "Number",
+ "value": null
+ },
+ "A2": {
+ "type": "Number",
+ "value": null
+ }
+ },
+ {
+ "id": "E2",
+ "type": "T",
+ "A1": {
+ "type": "Number",
+ "value": null
+ },
+ "A2": {
+ "type": "Number",
+ "value": null
+ }
+ },
+ {
+ "id": "E3",
+ "type": "T",
+ "A1": {
+ "type": "Number",
+ "value": null
+ },
+ "A2": {
+ "type": "Number",
+ "value": null
+ }
+ }
+ ]
+}'
+orionCurl --url /v2/op/update --payload "$payload"
+echo
+echo
+
+
+echo "04. GET /v2/entities to see E1/T/A3, E2/T/A1-A3 and E3/T/A3 in entities"
+echo "======================================================================="
+orionCurl --url /v2/entities
+echo
+echo
+
+
+--REGEXPECT--
+01. Create E1/T/A1-A2-A3, E2/T/A1-A3 and E3/T/A1-A2-A3 using POST /v2/op/update with append
+===========================================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+02. GET /v2/entities to see E1/T/A1-A2-A3, E2/T/A1-A3 and E3/T/A1-A2-A3
+=======================================================================
+HTTP/1.1 200 OK
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Content-Type: application/json
+Content-Length: 454
+
+[
+ {
+ "A1": {
+ "metadata": {},
+ "type": "Number",
+ "value": 11
+ },
+ "A2": {
+ "metadata": {},
+ "type": "Number",
+ "value": 12
+ },
+ "A3": {
+ "metadata": {},
+ "type": "Number",
+ "value": 13
+ },
+ "id": "E1",
+ "type": "T"
+ },
+ {
+ "A1": {
+ "metadata": {},
+ "type": "Number",
+ "value": 21
+ },
+ "A3": {
+ "metadata": {},
+ "type": "Number",
+ "value": 23
+ },
+ "id": "E2",
+ "type": "T"
+ },
+ {
+ "A1": {
+ "metadata": {},
+ "type": "Number",
+ "value": 31
+ },
+ "A2": {
+ "metadata": {},
+ "type": "Number",
+ "value": 32
+ },
+ "A3": {
+ "metadata": {},
+ "type": "Number",
+ "value": 33
+ },
+ "id": "E3",
+ "type": "T"
+ }
+]
+
+
+03. Delete E1-A1/A2=null, E2-A1/A2=null (A2 not existing) and E3-A1/A2=null using POST /v2/op/update with delete, get error
+===========================================================================================================================
+HTTP/1.1 404 Not Found
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Content-Type: application/json
+Content-Length: 79
+
+{
+ "description": "The entity does not have such an attribute",
+ "error": "NotFound"
+}
+
+
+04. GET /v2/entities to see E1/T/A3, E2/T/A1-A3 and E3/T/A3 in entities
+=======================================================================
+HTTP/1.1 200 OK
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Content-Type: application/json
+Content-Length: 262
+
+[
+ {
+ "A3": {
+ "metadata": {},
+ "type": "Number",
+ "value": 13
+ },
+ "id": "E1",
+ "type": "T"
+ },
+ {
+ "A1": {
+ "metadata": {},
+ "type": "Number",
+ "value": 21
+ },
+ "A3": {
+ "metadata": {},
+ "type": "Number",
+ "value": 23
+ },
+ "id": "E2",
+ "type": "T"
+ },
+ {
+ "A3": {
+ "metadata": {},
+ "type": "Number",
+ "value": 33
+ },
+ "id": "E3",
+ "type": "T"
+ }
+]
+
+
+--TEARDOWN--
+brokerStop CB
+dbDrop CB
diff --git a/test/functionalTest/cases/1715_batch_update/batch_update_DELETE_non_existing_attr.test b/test/functionalTest/cases/1715_batch_update/batch_update_DELETE_non_existing_attr.test
new file mode 100644
index 0000000000..76af634b17
--- /dev/null
+++ b/test/functionalTest/cases/1715_batch_update/batch_update_DELETE_non_existing_attr.test
@@ -0,0 +1,260 @@
+# Copyright 2023 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--
+V2 batch update DELETE in non existing attribute
+
+--SHELL-INIT--
+dbInit CB
+brokerStart CB 0
+
+--SHELL--
+
+#
+# 01. Create E1/T/A1-A2, E2/T/A1-A3 and E3/T/A1-A2 using POST /v2/op/update with append
+# 02. GET /v2/entities to see E1/T/A1-A2, E2/T/A1-A3 and E3/T/A1-A2
+# 03. Delete E1-A2=null, E2-A2=null (not existing) and E3-A2=null using POST /v2/op/update with delete, get error
+# 04. GET /v2/entities to see E1/T/A1, E2/T/A1-A3 and E3/T/A1 in entities
+#
+
+echo "01. Create E1/T/A1-A2, E2/T/A1-A3 and E3/T/A1-A2 using POST /v2/op/update with append"
+echo "====================================================================================="
+payload='{
+ "actionType": "append",
+ "entities": [
+ {
+ "id": "E1",
+ "type": "T",
+ "A1": {
+ "type": "Number",
+ "value": 11
+ },
+ "A2": {
+ "type": "Number",
+ "value": 12
+ }
+ },
+ {
+ "id": "E2",
+ "type": "T",
+ "A1": {
+ "type": "Number",
+ "value": 21
+ },
+ "A3": {
+ "type": "Number",
+ "value": 23
+ }
+ },
+ {
+ "id": "E3",
+ "type": "T",
+ "A1": {
+ "type": "Number",
+ "value": 31
+ },
+ "A2": {
+ "type": "Number",
+ "value": 32
+ }
+ }
+ ]
+}'
+orionCurl --url /v2/op/update --payload "$payload"
+echo
+echo
+
+
+echo "02. GET /v2/entities to see E1/T/A1-A2, E2/T/A1-A3 and E3/T/A1-A2"
+echo "================================================================="
+orionCurl --url /v2/entities
+echo
+echo
+
+
+echo "03. Delete E1-A2=null, E2-A2=null (not existing) and E3-A2=null using POST /v2/op/update with delete, get error"
+echo "==============================================================================================================="
+payload='{
+ "actionType": "delete",
+ "entities": [
+ {
+ "id": "E1",
+ "type": "T",
+ "A2": {
+ "type": "Number",
+ "value": null
+ }
+ },
+ {
+ "id": "E2",
+ "type": "T",
+ "A2": {
+ "type": "Number",
+ "value": null
+ }
+ },
+ {
+ "id": "E3",
+ "type": "T",
+ "A2": {
+ "type": "Number",
+ "value": null
+ }
+ }
+ ]
+}'
+orionCurl --url /v2/op/update --payload "$payload"
+echo
+echo
+
+
+echo "04. GET /v2/entities to see E1/T/A1, E2/T/A1-A3 and E3/T/A1 in entities"
+echo "======================================================================="
+orionCurl --url /v2/entities
+echo
+echo
+
+
+--REGEXPECT--
+01. Create E1/T/A1-A2, E2/T/A1-A3 and E3/T/A1-A2 using POST /v2/op/update with append
+=====================================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+02. GET /v2/entities to see E1/T/A1-A2, E2/T/A1-A3 and E3/T/A1-A2
+=================================================================
+HTTP/1.1 200 OK
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Content-Type: application/json
+Content-Length: 358
+
+[
+ {
+ "A1": {
+ "metadata": {},
+ "type": "Number",
+ "value": 11
+ },
+ "A2": {
+ "metadata": {},
+ "type": "Number",
+ "value": 12
+ },
+ "id": "E1",
+ "type": "T"
+ },
+ {
+ "A1": {
+ "metadata": {},
+ "type": "Number",
+ "value": 21
+ },
+ "A3": {
+ "metadata": {},
+ "type": "Number",
+ "value": 23
+ },
+ "id": "E2",
+ "type": "T"
+ },
+ {
+ "A1": {
+ "metadata": {},
+ "type": "Number",
+ "value": 31
+ },
+ "A2": {
+ "metadata": {},
+ "type": "Number",
+ "value": 32
+ },
+ "id": "E3",
+ "type": "T"
+ }
+]
+
+
+03. Delete E1-A2=null, E2-A2=null (not existing) and E3-A2=null using POST /v2/op/update with delete, get error
+===============================================================================================================
+HTTP/1.1 404 Not Found
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Content-Type: application/json
+Content-Length: 79
+
+{
+ "description": "The entity does not have such an attribute",
+ "error": "NotFound"
+}
+
+
+04. GET /v2/entities to see E1/T/A1, E2/T/A1-A3 and E3/T/A1 in entities
+=======================================================================
+HTTP/1.1 200 OK
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Content-Type: application/json
+Content-Length: 262
+
+[
+ {
+ "A1": {
+ "metadata": {},
+ "type": "Number",
+ "value": 11
+ },
+ "id": "E1",
+ "type": "T"
+ },
+ {
+ "A1": {
+ "metadata": {},
+ "type": "Number",
+ "value": 21
+ },
+ "A3": {
+ "metadata": {},
+ "type": "Number",
+ "value": 23
+ },
+ "id": "E2",
+ "type": "T"
+ },
+ {
+ "A1": {
+ "metadata": {},
+ "type": "Number",
+ "value": 31
+ },
+ "id": "E3",
+ "type": "T"
+ }
+]
+
+
+--TEARDOWN--
+brokerStop CB
+dbDrop CB
diff --git a/test/functionalTest/cases/1715_batch_update/batch_update_DELETE_with_nulls.test b/test/functionalTest/cases/1715_batch_update/batch_update_DELETE_with_nulls.test
new file mode 100644
index 0000000000..7aeff02697
--- /dev/null
+++ b/test/functionalTest/cases/1715_batch_update/batch_update_DELETE_with_nulls.test
@@ -0,0 +1,206 @@
+# Copyright 2023 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--
+V2 batch update DELETE with nulls
+
+--SHELL-INIT--
+dbInit CB
+brokerStart CB 0
+
+--SHELL--
+
+#
+# 01. Create E1/T/A1-A2 and E2/T/A1-A2 using POST /v2/op/update with append
+# 02. GET /v2/entities to see A1 and A2 in entities
+# 03. Delete E1-A1=null and E2-A1=null using POST /v2/op/update with delete
+# 04. GET /v2/entities to see A2 in entities
+#
+
+echo "01. Create E1/T/A1-A2 and E2/T/A1-A2 using POST /v2/op/update with append"
+echo "========================================================================="
+payload='{
+ "actionType": "append",
+ "entities": [
+ {
+ "id": "E1",
+ "type": "T",
+ "A1": {
+ "type": "Number",
+ "value": 11
+ },
+ "A2": {
+ "type": "Number",
+ "value": 12
+ }
+ },
+ {
+ "id": "E2",
+ "type": "T",
+ "A1": {
+ "type": "Number",
+ "value": 21
+ },
+ "A2": {
+ "type": "Number",
+ "value": 22
+ }
+ }
+ ]
+}'
+orionCurl --url /v2/op/update --payload "$payload"
+echo
+echo
+
+
+echo "02. GET /v2/entities to see A1 and A2 in entities"
+echo "================================================="
+orionCurl --url /v2/entities
+echo
+echo
+
+
+echo "03. Delete E1-A1=null and E2-A1=null using POST /v2/op/update with delete"
+echo "========================================================================="
+payload='{
+ "actionType": "delete",
+ "entities": [
+ {
+ "id": "E1",
+ "type": "T",
+ "A1": {
+ "type": "Number",
+ "value": null
+ }
+ },
+ {
+ "id": "E2",
+ "type": "T",
+ "A1": {
+ "type": "Number",
+ "value": null
+ }
+ }
+ ]
+}'
+orionCurl --url /v2/op/update --payload "$payload"
+echo
+echo
+
+
+echo "04. GET /v2/entities to see A2 in entities"
+echo "=========================================="
+orionCurl --url /v2/entities
+echo
+echo
+
+
+--REGEXPECT--
+01. Create E1/T/A1-A2 and E2/T/A1-A2 using POST /v2/op/update with append
+=========================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+02. GET /v2/entities to see A1 and A2 in entities
+=================================================
+HTTP/1.1 200 OK
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Content-Type: application/json
+Content-Length: 239
+
+[
+ {
+ "A1": {
+ "metadata": {},
+ "type": "Number",
+ "value": 11
+ },
+ "A2": {
+ "metadata": {},
+ "type": "Number",
+ "value": 12
+ },
+ "id": "E1",
+ "type": "T"
+ },
+ {
+ "A1": {
+ "metadata": {},
+ "type": "Number",
+ "value": 21
+ },
+ "A2": {
+ "metadata": {},
+ "type": "Number",
+ "value": 22
+ },
+ "id": "E2",
+ "type": "T"
+ }
+]
+
+
+03. Delete E1-A1=null and E2-A1=null using POST /v2/op/update with delete
+=========================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+04. GET /v2/entities to see A2 in entities
+==========================================
+HTTP/1.1 200 OK
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Content-Type: application/json
+Content-Length: 143
+
+[
+ {
+ "A2": {
+ "metadata": {},
+ "type": "Number",
+ "value": 12
+ },
+ "id": "E1",
+ "type": "T"
+ },
+ {
+ "A2": {
+ "metadata": {},
+ "type": "Number",
+ "value": 22
+ },
+ "id": "E2",
+ "type": "T"
+ }
+]
+
+
+--TEARDOWN--
+brokerStop CB
+dbDrop CB
diff --git a/test/functionalTest/cases/2394_inconsistent_mdnames_after_update/inconsistent_mdnames_after_update.test b/test/functionalTest/cases/2394_inconsistent_mdnames_after_update/inconsistent_mdnames_after_update.test
index e88e74907b..ba822b78d1 100644
--- a/test/functionalTest/cases/2394_inconsistent_mdnames_after_update/inconsistent_mdnames_after_update.test
+++ b/test/functionalTest/cases/2394_inconsistent_mdnames_after_update/inconsistent_mdnames_after_update.test
@@ -61,7 +61,7 @@ echo
echo "02. Get from Database, only 2 metadata"
echo "======================================"
-mongoCmd ${CB_DB_NAME} "db.entities.find({}, {_id:0, \"attrs.temperature.mdNames\":1})"
+mongoCmd ${CB_DB_NAME} "db.entities.find({}, {_id:0, \"attrs.temperature.mdNames\":1}).toArray()"
echo
echo
@@ -88,7 +88,7 @@ echo
echo "04. Get from Database, only 2 metadata"
echo "======================================"
-mongoCmd ${CB_DB_NAME} "db.entities.find({}, {_id:0, \"attrs.temperature.mdNames\":1})"
+mongoCmd ${CB_DB_NAME} "db.entities.find({}, {_id:0, \"attrs.temperature.mdNames\":1}).toArray()"
echo
echo
@@ -106,7 +106,7 @@ Content-Length: 0
02. Get from Database, only 2 metadata
======================================
-{ "attrs" : { "temperature" : { "mdNames" : [ "34.4E-34_1", "34.4E-34_0" ] } } }
+[{"attrs":{"temperature":{"mdNames":["34.4E-34_1","34.4E-34_0"]}}}]
03. Update E-temperature, including metatata
@@ -119,7 +119,7 @@ Fiware-Correlator: REGEX([0-9a-f\-]{36})
04. Get from Database, only 2 metadata
======================================
-{ "attrs" : { "temperature" : { "mdNames" : [ "34.4E-34_1", "34.4E-34_0" ] } } }
+[{"attrs":{"temperature":{"mdNames":["34.4E-34_1","34.4E-34_0"]}}}]
--TEARDOWN--
diff --git a/test/functionalTest/cases/2770_v1_append_not_updates_geo_point/v1_append_not_updates_geo_point.test b/test/functionalTest/cases/2770_v1_append_not_updates_geo_point/v1_append_not_updates_geo_point.test
index 6b6aee38df..cf183f4d39 100644
--- a/test/functionalTest/cases/2770_v1_append_not_updates_geo_point/v1_append_not_updates_geo_point.test
+++ b/test/functionalTest/cases/2770_v1_append_not_updates_geo_point/v1_append_not_updates_geo_point.test
@@ -54,7 +54,7 @@ echo
echo "02. Check location field at DB is -4.33, 36.12"
echo "=============================================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find({"_id.id": "line1"}, {_id: 0, location: 1})'
+mongoCmd ${CB_DB_NAME} 'db.entities.find({"_id.id": "line1"}, {_id: 0, location: 1}).toArray()'
echo
echo
@@ -84,7 +84,7 @@ echo
echo "04. Check location field at DB is -11.22, 22.33"
echo "==============================================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find({"_id.id": "line1"}, {_id: 0, location: 1})'
+mongoCmd ${CB_DB_NAME} 'db.entities.find({"_id.id": "line1"}, {_id: 0, location: 1}).toArray()'
echo
echo
@@ -102,7 +102,7 @@ Content-Length: 0
02. Check location field at DB is -4.33, 36.12
==============================================
-{ "location" : { "attrName" : "loc", "coords" : { "type" : "Point", "coordinates" : [ -4.33, 36.12 ] } } }
+[{"location":{"attrName":"loc","coords":{"type":"Point","coordinates":[-4.33,36.12]}}}]
03. Update entity using v1 updateContext APPEND
@@ -139,7 +139,7 @@ Content-Length: 197
04. Check location field at DB is -11.22, 22.33
===============================================
-{ "location" : { "attrName" : "loc", "coords" : { "type" : "Point", "coordinates" : [ -11.22, 22.33 ] } } }
+[{"location":{"attrName":"loc","coords":{"type":"Point","coordinates":[-11.22,22.33]}}}]
--TEARDOWN--
diff --git a/test/functionalTest/cases/2871_fwd_update_ok_but_not_found_response/fwd_update_ok_but_not_found_response.test b/test/functionalTest/cases/2871_fwd_update_ok_but_not_found_response/fwd_update_ok_but_not_found_response.test
index 7a7b1c567e..a5595702d1 100644
--- a/test/functionalTest/cases/2871_fwd_update_ok_but_not_found_response/fwd_update_ok_but_not_found_response.test
+++ b/test/functionalTest/cases/2871_fwd_update_ok_but_not_found_response/fwd_update_ok_but_not_found_response.test
@@ -49,7 +49,7 @@ echo "01. Create registration directly in DB"
echo "======================================"
doc='{
"_id":ObjectId("5b1ff2ee49597334c9b5efc7"),
- "expiration":NumberLong(1845053934),
+ "expiration":NumberLong("1845053934"),
"servicePath":"/ss1",
"format":"JSON",
"contextRegistration":[
@@ -70,7 +70,7 @@ doc='{
}
]
}'
-mongoCmd ${CB_DB_NAME} "db.registrations.insert($doc)"
+mongoCmd ${CB_DB_NAME} "db.registrations.insertOne($doc)"
echo
echo
@@ -131,7 +131,7 @@ doc='{
"modDate": 1528820541,
"lastCorrelator": "c8bcef8a-6e5c-11e8-a06c-0242ac11000b"
}'
-mongoCmd ${CB_DB_NAME} "db.entities.insert($doc)"
+mongoCmd ${CB_DB_NAME} "db.entities.insertOne($doc)"
echo
echo
@@ -222,12 +222,12 @@ echo
--REGEXPECT--
01. Create registration directly in DB
======================================
-WriteResult({ "nInserted" : 1 })
+{"acknowledged":true,"insertedId":{"$oid":"5b1ff2ee49597334c9b5efc7"}}
02. Create entity directly in DB
================================
-WriteResult({ "nInserted" : 1 })
+{"acknowledged":true,"insertedId":{"id":"entity1","type":"device","servicePath":"/ss1"}}
03. Update turn attribute using PATCH on entity
diff --git a/test/functionalTest/cases/3122_location_metadata_issues/create_location_attr_V2.test b/test/functionalTest/cases/3122_location_metadata_issues/create_location_attr_V2.test
index 496b530cec..be79908420 100644
--- a/test/functionalTest/cases/3122_location_metadata_issues/create_location_attr_V2.test
+++ b/test/functionalTest/cases/3122_location_metadata_issues/create_location_attr_V2.test
@@ -80,14 +80,14 @@ echo
echo "03. Check E1 entity in DB has location metadata but no location GeoJSON field"
echo "============================================================================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find({ "_id" : { "id" : "E1", "type": "T", "servicePath" : "/" } }, {_id:0, attrs: 1, location: 1})' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.entities.findOne({ "_id" : { "id" : "E1", "type": "T", "servicePath" : "/" } }, {_id:0, attrs: 1, location: 1})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
echo "04. Check E2 entity in DB has no location metadata but location GeoJSON field"
echo "============================================================================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find({ "_id" : { "id" : "E2", "type": "T", "servicePath" : "/" } }, {_id:0, attrs: 1, location: 1})' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.entities.findOne({ "_id" : { "id" : "E2", "type": "T", "servicePath" : "/" } }, {_id:0, attrs: 1, location: 1})' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
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
index 377cf618be..40c7feed77 100644
--- 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
@@ -86,7 +86,7 @@ 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" : "/" }})')
+m=$(mongoCmd ${CB_DB_NAME} 'db.entities.findOne({ "_id" : { "id" : "urn:ngsi-ld:Store:004", "type": "Store", "servicePath" : "/" }})')
echo $m | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -128,7 +128,7 @@ 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" : "/" }})')
+m=$(mongoCmd ${CB_DB_NAME} 'db.entities.findOne({ "_id" : { "id" : "urn:ngsi-ld:Store:004", "type": "Store", "servicePath" : "/" }})')
echo $m | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
diff --git a/test/functionalTest/cases/3162_context_providers_legacy_non_primitive/query_for_arrays.test b/test/functionalTest/cases/3162_context_providers_legacy_non_primitive/query_for_arrays.test
index 67bffeca00..f6db6dcf1a 100644
--- a/test/functionalTest/cases/3162_context_providers_legacy_non_primitive/query_for_arrays.test
+++ b/test/functionalTest/cases/3162_context_providers_legacy_non_primitive/query_for_arrays.test
@@ -51,7 +51,7 @@ payload='{
"entities": [
{
"id": "E1",
- "type": "E"
+ "type": "T"
}
],
"attrs": [
@@ -75,7 +75,7 @@ echo "=================================="
payload='{
"contextElements": [
{
- "type": "E",
+ "type": "T",
"isPattern": "false",
"id": "E1",
"attributes": [
@@ -99,7 +99,7 @@ echo "======================"
payload='{
"entities": [
{
- "type": "E",
+ "type": "T",
"isPattern": "false",
"id": "E1"
}
@@ -125,7 +125,7 @@ echo "=========================================="
payload='{
"contextElements": [
{
- "type": "E",
+ "type": "T",
"isPattern": "false",
"id": "E1",
"attributes": [
@@ -190,7 +190,7 @@ Content-Length: 187
],
"id": "E1",
"isPattern": "false",
- "type": "E"
+ "type": "T"
},
"statusCode": {
"code": "200",
@@ -225,7 +225,7 @@ Content-Length: 203
],
"id": "E1",
"isPattern": "false",
- "type": "E"
+ "type": "T"
},
"statusCode": {
"code": "200",
@@ -271,7 +271,7 @@ Content-Length: 187
],
"id": "E1",
"isPattern": "false",
- "type": "E"
+ "type": "T"
},
"statusCode": {
"code": "200",
@@ -319,7 +319,7 @@ Content-Length: 148
]
},
"id": "E1",
- "type": "E"
+ "type": "T"
}
diff --git a/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geobox_create_does_not_break_location.test b/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geobox_create_does_not_break_location.test
index cf68b94d8c..dcd6943251 100644
--- a/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geobox_create_does_not_break_location.test
+++ b/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geobox_create_does_not_break_location.test
@@ -40,7 +40,7 @@ echo "==================================================="
payload='{
"contextElements": [
{
- "type": "E",
+ "type": "T",
"isPattern": "false",
"id": "E1",
"attributes": [
@@ -61,7 +61,7 @@ echo
echo "02. Check location field is not broken in database"
echo "=================================================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find()' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.entities.find().toArray()' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -89,7 +89,7 @@ Content-Length: 195
],
"id": "E1",
"isPattern": "false",
- "type": "E"
+ "type": "T"
},
"statusCode": {
"code": "200",
@@ -102,61 +102,63 @@ Content-Length: 195
02. Check location field is not broken in database
==================================================
-{
- "_id": {
- "id": "E1",
- "servicePath": "/",
- "type": "E"
- },
- "attrNames": [
- "position"
- ],
- "attrs": {
- "position": {
- "creDate": REGEX(\d+\.\d+),
- "mdNames": [],
- "modDate": REGEX(\d+\.\d+),
- "type": "geo:box",
- "value": [
- "7.7, 8.8",
- "9.9, -10.10"
- ]
- }
- },
- "creDate": REGEX(\d+\.\d+),
- "lastCorrelator": "REGEX(.*)",
- "location": {
- "attrName": "position",
- "coords": {
- "coordinates": [
- [
- [
- -10.1,
- 7.7
- ],
- [
- -10.1,
- 9.9
- ],
- [
- 8.8,
- 9.9
- ],
- [
- 8.8,
- 7.7
- ],
+[
+ {
+ "_id": {
+ "id": "E1",
+ "servicePath": "/",
+ "type": "T"
+ },
+ "attrNames": [
+ "position"
+ ],
+ "attrs": {
+ "position": {
+ "creDate": REGEX(\d+\.\d+),
+ "mdNames": [],
+ "modDate": REGEX(\d+\.\d+),
+ "type": "geo:box",
+ "value": [
+ "7.7, 8.8",
+ "9.9, -10.10"
+ ]
+ }
+ },
+ "creDate": REGEX(\d+\.\d+),
+ "lastCorrelator": "REGEX(.*)",
+ "location": {
+ "attrName": "position",
+ "coords": {
+ "coordinates": [
[
- -10.1,
- 7.7
+ [
+ -10.1,
+ 7.7
+ ],
+ [
+ -10.1,
+ 9.9
+ ],
+ [
+ 8.8,
+ 9.9
+ ],
+ [
+ 8.8,
+ 7.7
+ ],
+ [
+ -10.1,
+ 7.7
+ ]
]
- ]
- ],
- "type": "Polygon"
- }
- },
- "modDate": REGEX(\d+\.\d+)
-}
+ ],
+ "type": "Polygon"
+ }
+ },
+ "modDate": REGEX(\d+\.\d+)
+ }
+]
--TEARDOWN--
diff --git a/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geobox_update_does_not_break_location.test b/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geobox_update_does_not_break_location.test
index 8ffdc90cac..2d0ba1d089 100644
--- a/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geobox_update_does_not_break_location.test
+++ b/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geobox_update_does_not_break_location.test
@@ -57,12 +57,12 @@ echo "==================================================="
payload='{
"contextElements": [
{
- "type": "E",
+ "type": "T",
"isPattern": "false",
- "id": "E1",
+ "id": "E",
"attributes": [
{
- "name": "position",
+ "name": "location",
"type": "geo:box",
"value": ["-3.3, 4.4", "5.5, -6.6"]
}
@@ -78,7 +78,7 @@ echo
echo "03. Check location field is not broken in database"
echo "=================================================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find()' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.entities.find().toArray()' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -88,12 +88,12 @@ echo "==================================================="
payload='{
"contextElements": [
{
- "type": "E",
+ "type": "T",
"isPattern": "false",
- "id": "E1",
+ "id": "E",
"attributes": [
{
- "name": "position",
+ "name": "location",
"type": "geo:box",
"value": ["7.7, 8.8", "9.9, -10.10"]
}
@@ -109,7 +109,7 @@ echo
echo "05. Check location field is not broken in database"
echo "=================================================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find()' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.entities.find().toArray()' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -132,7 +132,7 @@ HTTP/1.1 200 OK
Date: REGEX(.*)
Fiware-Correlator: REGEX([0-9a-f\-]{36})
Content-Type: application/json
-Content-Length: 195
+Content-Length: 194
{
"contextResponses": [
@@ -140,14 +140,14 @@ Content-Length: 195
"contextElement": {
"attributes": [
{
- "name": "position",
+ "name": "location",
"type": "geo:box",
"value": ""
}
],
- "id": "E1",
+ "id": "E",
"isPattern": "false",
- "type": "E"
+ "type": "T"
},
"statusCode": {
"code": "200",
@@ -160,61 +160,63 @@ Content-Length: 195
03. Check location field is not broken in database
==================================================
-{
- "_id": {
- "id": "E1",
- "servicePath": "/",
- "type": "E"
- },
- "attrNames": [
- "position"
- ],
- "attrs": {
- "position": {
- "creDate": REGEX(\d+\.\d+),
- "mdNames": [],
- "modDate": REGEX(\d+\.\d+),
- "type": "geo:box",
- "value": [
- "-3.3, 4.4",
- "5.5, -6.6"
- ]
- }
- },
- "creDate": REGEX(\d+\.\d+),
- "lastCorrelator": "REGEX(.*)",
- "location": {
- "attrName": "position",
- "coords": {
- "coordinates": [
- [
- [
- -6.6,
- -3.3
- ],
- [
- -6.6,
- 5.5
- ],
- [
- 4.4,
- 5.5
- ],
- [
- 4.4,
- -3.3
- ],
+[
+ {
+ "_id": {
+ "id": "E",
+ "servicePath": "/",
+ "type": "T"
+ },
+ "attrNames": [
+ "location"
+ ],
+ "attrs": {
+ "location": {
+ "creDate": REGEX(\d+\.\d+),
+ "mdNames": [],
+ "modDate": REGEX(\d+\.\d+),
+ "type": "geo:box",
+ "value": [
+ "-3.3, 4.4",
+ "5.5, -6.6"
+ ]
+ }
+ },
+ "creDate": REGEX(\d+\.\d+),
+ "lastCorrelator": "REGEX(.*)",
+ "location": {
+ "attrName": "location",
+ "coords": {
+ "coordinates": [
[
- -6.6,
- -3.3
+ [
+ -6.6,
+ -3.3
+ ],
+ [
+ -6.6,
+ 5.5
+ ],
+ [
+ 4.4,
+ 5.5
+ ],
+ [
+ 4.4,
+ -3.3
+ ],
+ [
+ -6.6,
+ -3.3
+ ]
]
- ]
- ],
- "type": "Polygon"
- }
- },
- "modDate": REGEX(\d+\.\d+)
-}
+ ],
+ "type": "Polygon"
+ }
+ },
+ "modDate": REGEX(\d+\.\d+)
+ }
+]
04. Update entity with geo:box with NGSIv1 (UPDATE)
@@ -223,7 +225,7 @@ HTTP/1.1 200 OK
Date: REGEX(.*)
Fiware-Correlator: REGEX([0-9a-f\-]{36})
Content-Type: application/json
-Content-Length: 195
+Content-Length: 194
{
"contextResponses": [
@@ -231,14 +233,14 @@ Content-Length: 195
"contextElement": {
"attributes": [
{
- "name": "position",
+ "name": "location",
"type": "geo:box",
"value": ""
}
],
- "id": "E1",
+ "id": "E",
"isPattern": "false",
- "type": "E"
+ "type": "T"
},
"statusCode": {
"code": "200",
@@ -251,61 +253,63 @@ Content-Length: 195
05. Check location field is not broken in database
==================================================
-{
- "_id": {
- "id": "E1",
- "servicePath": "/",
- "type": "E"
- },
- "attrNames": [
- "position"
- ],
- "attrs": {
- "position": {
- "creDate": REGEX(\d+\.\d+),
- "mdNames": [],
- "modDate": REGEX(\d+\.\d+),
- "type": "geo:box",
- "value": [
- "7.7, 8.8",
- "9.9, -10.10"
- ]
- }
- },
- "creDate": REGEX(\d+\.\d+),
- "lastCorrelator": "REGEX(.*)",
- "location": {
- "attrName": "position",
- "coords": {
- "coordinates": [
- [
- [
- -10.1,
- 7.7
- ],
- [
- -10.1,
- 9.9
- ],
- [
- 8.8,
- 9.9
- ],
- [
- 8.8,
- 7.7
- ],
+[
+ {
+ "_id": {
+ "id": "E",
+ "servicePath": "/",
+ "type": "T"
+ },
+ "attrNames": [
+ "location"
+ ],
+ "attrs": {
+ "location": {
+ "creDate": REGEX(\d+\.\d+),
+ "mdNames": [],
+ "modDate": REGEX(\d+\.\d+),
+ "type": "geo:box",
+ "value": [
+ "7.7, 8.8",
+ "9.9, -10.10"
+ ]
+ }
+ },
+ "creDate": REGEX(\d+\.\d+),
+ "lastCorrelator": "REGEX(.*)",
+ "location": {
+ "attrName": "location",
+ "coords": {
+ "coordinates": [
[
- -10.1,
- 7.7
+ [
+ -10.1,
+ 7.7
+ ],
+ [
+ -10.1,
+ 9.9
+ ],
+ [
+ 8.8,
+ 9.9
+ ],
+ [
+ 8.8,
+ 7.7
+ ],
+ [
+ -10.1,
+ 7.7
+ ]
]
- ]
- ],
- "type": "Polygon"
- }
- },
- "modDate": REGEX(\d+\.\d+)
-}
+ ],
+ "type": "Polygon"
+ }
+ },
+ "modDate": REGEX(\d+\.\d+)
+ }
+]
--TEARDOWN--
diff --git a/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geojson_create_does_not_break_location.test b/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geojson_create_does_not_break_location.test
index 17ea8ae9f8..143371555b 100644
--- a/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geojson_create_does_not_break_location.test
+++ b/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geojson_create_does_not_break_location.test
@@ -40,7 +40,7 @@ echo "===================================================="
payload='{
"contextElements": [
{
- "type": "E",
+ "type": "T",
"isPattern": "false",
"id": "E1",
"attributes": [
@@ -64,7 +64,7 @@ echo
echo "02. Check location field is not broken in database"
echo "=================================================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find()' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.entities.find().toArray()' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -92,7 +92,7 @@ Content-Length: 196
],
"id": "E1",
"isPattern": "false",
- "type": "E"
+ "type": "T"
},
"statusCode": {
"code": "200",
@@ -105,44 +105,46 @@ Content-Length: 196
02. Check location field is not broken in database
==================================================
-{
- "_id": {
- "id": "E1",
- "servicePath": "/",
- "type": "E"
- },
- "attrNames": [
- "position"
- ],
- "attrs": {
- "position": {
- "creDate": REGEX(\d+\.\d+),
- "mdNames": [],
- "modDate": REGEX(\d+\.\d+),
- "type": "geo:json",
- "value": {
+[
+ {
+ "_id": {
+ "id": "E1",
+ "servicePath": "/",
+ "type": "T"
+ },
+ "attrNames": [
+ "position"
+ ],
+ "attrs": {
+ "position": {
+ "creDate": REGEX(\d+\.\d+),
+ "mdNames": [],
+ "modDate": REGEX(\d+\.\d+),
+ "type": "geo:json",
+ "value": {
+ "coordinates": [
+ "5.5",
+ "-6.6"
+ ],
+ "type": "Point"
+ }
+ }
+ },
+ "creDate": REGEX(\d+\.\d+),
+ "lastCorrelator": "REGEX(.*)",
+ "location": {
+ "attrName": "position",
+ "coords": {
"coordinates": [
- "5.5",
- "-6.6"
+ 5.5,
+ -6.6
],
"type": "Point"
}
- }
- },
- "creDate": REGEX(\d+\.\d+),
- "lastCorrelator": "REGEX(.*)",
- "location": {
- "attrName": "position",
- "coords": {
- "coordinates": [
- 5.5,
- -6.6
- ],
- "type": "Point"
- }
- },
- "modDate": REGEX(\d+\.\d+)
-}
+ },
+ "modDate": REGEX(\d+\.\d+)
+ }
+]
--TEARDOWN--
diff --git a/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geojson_update_does_not_break_location.test b/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geojson_update_does_not_break_location.test
index 064a19243c..a441e56954 100644
--- a/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geojson_update_does_not_break_location.test
+++ b/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geojson_update_does_not_break_location.test
@@ -57,12 +57,12 @@ echo "===================================================="
payload='{
"contextElements": [
{
- "type": "E",
+ "type": "T",
"isPattern": "false",
- "id": "E1",
+ "id": "E",
"attributes": [
{
- "name": "position",
+ "name": "location",
"type": "geo:json",
"value": {
"type": "Point",
@@ -81,7 +81,7 @@ echo
echo "03. Check location field is not broken in database"
echo "=================================================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find()' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.entities.find().toArray()' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -91,12 +91,12 @@ echo "===================================================="
payload='{
"contextElements": [
{
- "type": "E",
+ "type": "T",
"isPattern": "false",
- "id": "E1",
+ "id": "E",
"attributes": [
{
- "name": "position",
+ "name": "location",
"type": "geo:json",
"value": {
"type": "Point",
@@ -115,7 +115,7 @@ echo
echo "05. Check location field is not broken in database"
echo "=================================================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find()' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.entities.find().toArray()' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -138,7 +138,7 @@ HTTP/1.1 200 OK
Date: REGEX(.*)
Fiware-Correlator: REGEX([0-9a-f\-]{36})
Content-Type: application/json
-Content-Length: 196
+Content-Length: 195
{
"contextResponses": [
@@ -146,14 +146,14 @@ Content-Length: 196
"contextElement": {
"attributes": [
{
- "name": "position",
+ "name": "location",
"type": "geo:json",
"value": ""
}
],
- "id": "E1",
+ "id": "E",
"isPattern": "false",
- "type": "E"
+ "type": "T"
},
"statusCode": {
"code": "200",
@@ -166,44 +166,46 @@ Content-Length: 196
03. Check location field is not broken in database
==================================================
-{
- "_id": {
- "id": "E1",
- "servicePath": "/",
- "type": "E"
- },
- "attrNames": [
- "position"
- ],
- "attrs": {
- "position": {
- "creDate": REGEX(\d+\.\d+),
- "mdNames": [],
- "modDate": REGEX(\d+\.\d+),
- "type": "geo:json",
- "value": {
+[
+ {
+ "_id": {
+ "id": "E",
+ "servicePath": "/",
+ "type": "T"
+ },
+ "attrNames": [
+ "location"
+ ],
+ "attrs": {
+ "location": {
+ "creDate": REGEX(\d+\.\d+),
+ "mdNames": [],
+ "modDate": REGEX(\d+\.\d+),
+ "type": "geo:json",
+ "value": {
+ "coordinates": [
+ "-3.3",
+ "4.4"
+ ],
+ "type": "Point"
+ }
+ }
+ },
+ "creDate": REGEX(\d+\.\d+),
+ "lastCorrelator": "REGEX(.*)",
+ "location": {
+ "attrName": "location",
+ "coords": {
"coordinates": [
- "-3.3",
- "4.4"
+ -3.3,
+ 4.4
],
"type": "Point"
}
- }
- },
- "creDate": REGEX(\d+\.\d+),
- "lastCorrelator": "REGEX(.*)",
- "location": {
- "attrName": "position",
- "coords": {
- "coordinates": [
- -3.3,
- 4.4
- ],
- "type": "Point"
- }
- },
- "modDate": REGEX(\d+\.\d+)
-}
+ },
+ "modDate": REGEX(\d+\.\d+)
+ }
+]
04. Update entity with geo:json with NGSIv1 (UPDATE)
@@ -212,7 +214,7 @@ HTTP/1.1 200 OK
Date: REGEX(.*)
Fiware-Correlator: REGEX([0-9a-f\-]{36})
Content-Type: application/json
-Content-Length: 196
+Content-Length: 195
{
"contextResponses": [
@@ -220,14 +222,14 @@ Content-Length: 196
"contextElement": {
"attributes": [
{
- "name": "position",
+ "name": "location",
"type": "geo:json",
"value": ""
}
],
- "id": "E1",
+ "id": "E",
"isPattern": "false",
- "type": "E"
+ "type": "T"
},
"statusCode": {
"code": "200",
@@ -240,44 +242,46 @@ Content-Length: 196
05. Check location field is not broken in database
==================================================
-{
- "_id": {
- "id": "E1",
- "servicePath": "/",
- "type": "E"
- },
- "attrNames": [
- "position"
- ],
- "attrs": {
- "position": {
- "creDate": REGEX(\d+\.\d+),
- "mdNames": [],
- "modDate": REGEX(\d+\.\d+),
- "type": "geo:json",
- "value": {
+[
+ {
+ "_id": {
+ "id": "E",
+ "servicePath": "/",
+ "type": "T"
+ },
+ "attrNames": [
+ "location"
+ ],
+ "attrs": {
+ "location": {
+ "creDate": REGEX(\d+\.\d+),
+ "mdNames": [],
+ "modDate": REGEX(\d+\.\d+),
+ "type": "geo:json",
+ "value": {
+ "coordinates": [
+ "5.5",
+ "-6.6"
+ ],
+ "type": "Point"
+ }
+ }
+ },
+ "creDate": REGEX(\d+\.\d+),
+ "lastCorrelator": "REGEX(.*)",
+ "location": {
+ "attrName": "location",
+ "coords": {
"coordinates": [
- "5.5",
- "-6.6"
+ 5.5,
+ -6.6
],
"type": "Point"
}
- }
- },
- "creDate": REGEX(\d+\.\d+),
- "lastCorrelator": "REGEX(.*)",
- "location": {
- "attrName": "position",
- "coords": {
- "coordinates": [
- 5.5,
- -6.6
- ],
- "type": "Point"
- }
- },
- "modDate": REGEX(\d+\.\d+)
-}
+ },
+ "modDate": REGEX(\d+\.\d+)
+ }
+]
--TEARDOWN--
diff --git a/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geoline_create_does_not_break_location.test b/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geoline_create_does_not_break_location.test
index 3871ac0398..c210466a92 100644
--- a/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geoline_create_does_not_break_location.test
+++ b/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geoline_create_does_not_break_location.test
@@ -40,7 +40,7 @@ echo "===================================================="
payload='{
"contextElements": [
{
- "type": "E",
+ "type": "T",
"isPattern": "false",
"id": "E1",
"attributes": [
@@ -61,7 +61,7 @@ echo
echo "02. Check location field is not broken in database"
echo "=================================================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find()' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.entities.find().toArray()' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -89,7 +89,7 @@ Content-Length: 196
],
"id": "E1",
"isPattern": "false",
- "type": "E"
+ "type": "T"
},
"statusCode": {
"code": "200",
@@ -102,47 +102,49 @@ Content-Length: 196
02. Check location field is not broken in database
==================================================
-{
- "_id": {
- "id": "E1",
- "servicePath": "/",
- "type": "E"
- },
- "attrNames": [
- "position"
- ],
- "attrs": {
- "position": {
- "creDate": REGEX(\d+\.\d+),
- "mdNames": [],
- "modDate": REGEX(\d+\.\d+),
- "type": "geo:line",
- "value": [
- "7.7, 8.8",
- "9.9, -10.10"
- ]
- }
- },
- "creDate": REGEX(\d+\.\d+),
- "lastCorrelator": "REGEX(.*)",
- "location": {
- "attrName": "position",
- "coords": {
- "coordinates": [
- [
- 8.8,
- 7.7
- ],
- [
- -10.1,
- 9.9
+[
+ {
+ "_id": {
+ "id": "E1",
+ "servicePath": "/",
+ "type": "T"
+ },
+ "attrNames": [
+ "position"
+ ],
+ "attrs": {
+ "position": {
+ "creDate": REGEX(\d+\.\d+),
+ "mdNames": [],
+ "modDate": REGEX(\d+\.\d+),
+ "type": "geo:line",
+ "value": [
+ "7.7, 8.8",
+ "9.9, -10.10"
]
- ],
- "type": "LineString"
- }
- },
- "modDate": REGEX(\d+\.\d+)
-}
+ }
+ },
+ "creDate": REGEX(\d+\.\d+),
+ "lastCorrelator": "REGEX(.*)",
+ "location": {
+ "attrName": "position",
+ "coords": {
+ "coordinates": [
+ [
+ 8.8,
+ 7.7
+ ],
+ [
+ -10.1,
+ 9.9
+ ]
+ ],
+ "type": "LineString"
+ }
+ },
+ "modDate": REGEX(\d+\.\d+)
+ }
+]
--TEARDOWN--
diff --git a/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geoline_update_does_not_break_location.test b/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geoline_update_does_not_break_location.test
index 60f3a45428..c3c8e42075 100644
--- a/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geoline_update_does_not_break_location.test
+++ b/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geoline_update_does_not_break_location.test
@@ -57,12 +57,12 @@ echo "===================================================="
payload='{
"contextElements": [
{
- "type": "E",
+ "type": "T",
"isPattern": "false",
- "id": "E1",
+ "id": "E",
"attributes": [
{
- "name": "position",
+ "name": "location",
"type": "geo:line",
"value": ["-3.3, 4.4", "5.5, -6.6"]
}
@@ -78,7 +78,7 @@ echo
echo "03. Check location field is not broken in database"
echo "=================================================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find()' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.entities.find().toArray()' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -88,12 +88,12 @@ echo "===================================================="
payload='{
"contextElements": [
{
- "type": "E",
+ "type": "T",
"isPattern": "false",
- "id": "E1",
+ "id": "E",
"attributes": [
{
- "name": "position",
+ "name": "location",
"type": "geo:line",
"value": ["7.7, 8.8", "9.9, -10.10"]
}
@@ -109,7 +109,7 @@ echo
echo "05. Check location field is not broken in database"
echo "=================================================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find()' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.entities.find().toArray()' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -132,7 +132,7 @@ HTTP/1.1 200 OK
Date: REGEX(.*)
Fiware-Correlator: REGEX([0-9a-f\-]{36})
Content-Type: application/json
-Content-Length: 196
+Content-Length: 195
{
"contextResponses": [
@@ -140,14 +140,14 @@ Content-Length: 196
"contextElement": {
"attributes": [
{
- "name": "position",
+ "name": "location",
"type": "geo:line",
"value": ""
}
],
- "id": "E1",
+ "id": "E",
"isPattern": "false",
- "type": "E"
+ "type": "T"
},
"statusCode": {
"code": "200",
@@ -160,47 +160,49 @@ Content-Length: 196
03. Check location field is not broken in database
==================================================
-{
- "_id": {
- "id": "E1",
- "servicePath": "/",
- "type": "E"
- },
- "attrNames": [
- "position"
- ],
- "attrs": {
- "position": {
- "creDate": REGEX(\d+\.\d+),
- "mdNames": [],
- "modDate": REGEX(\d+\.\d+),
- "type": "geo:line",
- "value": [
- "-3.3, 4.4",
- "5.5, -6.6"
- ]
- }
- },
- "creDate": REGEX(\d+\.\d+),
- "lastCorrelator": "REGEX(.*)",
- "location": {
- "attrName": "position",
- "coords": {
- "coordinates": [
- [
- 4.4,
- -3.3
- ],
- [
- -6.6,
- 5.5
+[
+ {
+ "_id": {
+ "id": "E",
+ "servicePath": "/",
+ "type": "T"
+ },
+ "attrNames": [
+ "location"
+ ],
+ "attrs": {
+ "location": {
+ "creDate": REGEX(\d+\.\d+),
+ "mdNames": [],
+ "modDate": REGEX(\d+\.\d+),
+ "type": "geo:line",
+ "value": [
+ "-3.3, 4.4",
+ "5.5, -6.6"
]
- ],
- "type": "LineString"
- }
- },
- "modDate": REGEX(\d+\.\d+)
-}
+ }
+ },
+ "creDate": REGEX(\d+\.\d+),
+ "lastCorrelator": "REGEX(.*)",
+ "location": {
+ "attrName": "location",
+ "coords": {
+ "coordinates": [
+ [
+ 4.4,
+ -3.3
+ ],
+ [
+ -6.6,
+ 5.5
+ ]
+ ],
+ "type": "LineString"
+ }
+ },
+ "modDate": REGEX(\d+\.\d+)
+ }
+]
04. Update entity with geo:line with NGSIv1 (UPDATE)
@@ -209,7 +211,7 @@ HTTP/1.1 200 OK
Date: REGEX(.*)
Fiware-Correlator: REGEX([0-9a-f\-]{36})
Content-Type: application/json
-Content-Length: 196
+Content-Length: 195
{
"contextResponses": [
@@ -217,14 +219,14 @@ Content-Length: 196
"contextElement": {
"attributes": [
{
- "name": "position",
+ "name": "location",
"type": "geo:line",
"value": ""
}
],
- "id": "E1",
+ "id": "E",
"isPattern": "false",
- "type": "E"
+ "type": "T"
},
"statusCode": {
"code": "200",
@@ -237,47 +239,49 @@ Content-Length: 196
05. Check location field is not broken in database
==================================================
-{
- "_id": {
- "id": "E1",
- "servicePath": "/",
- "type": "E"
- },
- "attrNames": [
- "position"
- ],
- "attrs": {
- "position": {
- "creDate": REGEX(\d+\.\d+),
- "mdNames": [],
- "modDate": REGEX(\d+\.\d+),
- "type": "geo:line",
- "value": [
- "7.7, 8.8",
- "9.9, -10.10"
- ]
- }
- },
- "creDate": REGEX(\d+\.\d+),
- "lastCorrelator": "REGEX(.*)",
- "location": {
- "attrName": "position",
- "coords": {
- "coordinates": [
- [
- 8.8,
- 7.7
- ],
- [
- -10.1,
- 9.9
+[
+ {
+ "_id": {
+ "id": "E",
+ "servicePath": "/",
+ "type": "T"
+ },
+ "attrNames": [
+ "location"
+ ],
+ "attrs": {
+ "location": {
+ "creDate": REGEX(\d+\.\d+),
+ "mdNames": [],
+ "modDate": REGEX(\d+\.\d+),
+ "type": "geo:line",
+ "value": [
+ "7.7, 8.8",
+ "9.9, -10.10"
]
- ],
- "type": "LineString"
- }
- },
- "modDate": REGEX(\d+\.\d+)
-}
+ }
+ },
+ "creDate": REGEX(\d+\.\d+),
+ "lastCorrelator": "REGEX(.*)",
+ "location": {
+ "attrName": "location",
+ "coords": {
+ "coordinates": [
+ [
+ 8.8,
+ 7.7
+ ],
+ [
+ -10.1,
+ 9.9
+ ]
+ ],
+ "type": "LineString"
+ }
+ },
+ "modDate": REGEX(\d+\.\d+)
+ }
+]
--TEARDOWN--
diff --git a/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geopoint_create_does_not_break_location.test b/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geopoint_create_does_not_break_location.test
index 3d6563b108..de3fa48d9e 100644
--- a/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geopoint_create_does_not_break_location.test
+++ b/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geopoint_create_does_not_break_location.test
@@ -40,7 +40,7 @@ echo "====================================================="
payload='{
"contextElements": [
{
- "type": "E",
+ "type": "T",
"isPattern": "false",
"id": "E1",
"attributes": [
@@ -61,7 +61,7 @@ echo
echo "02. Check location field is not broken in database"
echo "=================================================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find()' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.entities.find().toArray()' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -89,7 +89,7 @@ Content-Length: 197
],
"id": "E1",
"isPattern": "false",
- "type": "E"
+ "type": "T"
},
"statusCode": {
"code": "200",
@@ -102,38 +102,40 @@ Content-Length: 197
02. Check location field is not broken in database
==================================================
-{
- "_id": {
- "id": "E1",
- "servicePath": "/",
- "type": "E"
- },
- "attrNames": [
- "position"
- ],
- "attrs": {
- "position": {
- "creDate": REGEX(\d+\.\d+),
- "mdNames": [],
- "modDate": REGEX(\d+\.\d+),
- "type": "geo:point",
- "value": "5.5, -6.6"
- }
- },
- "creDate": REGEX(\d+\.\d+),
- "lastCorrelator": "REGEX(.*)",
- "location": {
- "attrName": "position",
- "coords": {
- "coordinates": [
- -6.6,
- 5.5
- ],
- "type": "Point"
- }
- },
- "modDate": REGEX(\d+\.\d+)
-}
+[
+ {
+ "_id": {
+ "id": "E1",
+ "servicePath": "/",
+ "type": "T"
+ },
+ "attrNames": [
+ "position"
+ ],
+ "attrs": {
+ "position": {
+ "creDate": REGEX(\d+\.\d+),
+ "mdNames": [],
+ "modDate": REGEX(\d+\.\d+),
+ "type": "geo:point",
+ "value": "5.5, -6.6"
+ }
+ },
+ "creDate": REGEX(\d+\.\d+),
+ "lastCorrelator": "REGEX(.*)",
+ "location": {
+ "attrName": "position",
+ "coords": {
+ "coordinates": [
+ -6.6,
+ 5.5
+ ],
+ "type": "Point"
+ }
+ },
+ "modDate": REGEX(\d+\.\d+)
+ }
+]
--TEARDOWN--
diff --git a/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geopoint_update_does_not_break_location.test b/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geopoint_update_does_not_break_location.test
index 141019e70f..6fabd5604c 100644
--- a/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geopoint_update_does_not_break_location.test
+++ b/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geopoint_update_does_not_break_location.test
@@ -57,12 +57,12 @@ echo "====================================================="
payload='{
"contextElements": [
{
- "type": "E",
+ "type": "T",
"isPattern": "false",
- "id": "E1",
+ "id": "E",
"attributes": [
{
- "name": "position",
+ "name": "location",
"type": "geo:point",
"value": "-3.3, 4.4"
}
@@ -78,7 +78,7 @@ echo
echo "03. Check location field is not broken in database"
echo "=================================================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find()' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.entities.find().toArray()' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -88,12 +88,12 @@ echo "====================================================="
payload='{
"contextElements": [
{
- "type": "E",
+ "type": "T",
"isPattern": "false",
- "id": "E1",
+ "id": "E",
"attributes": [
{
- "name": "position",
+ "name": "location",
"type": "geo:point",
"value": "5.5, -6.6"
}
@@ -109,7 +109,7 @@ echo
echo "05. Check location field is not broken in database"
echo "=================================================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find()' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.entities.find().toArray()' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -132,7 +132,7 @@ HTTP/1.1 200 OK
Date: REGEX(.*)
Fiware-Correlator: REGEX([0-9a-f\-]{36})
Content-Type: application/json
-Content-Length: 197
+Content-Length: 196
{
"contextResponses": [
@@ -140,14 +140,14 @@ Content-Length: 197
"contextElement": {
"attributes": [
{
- "name": "position",
+ "name": "location",
"type": "geo:point",
"value": ""
}
],
- "id": "E1",
+ "id": "E",
"isPattern": "false",
- "type": "E"
+ "type": "T"
},
"statusCode": {
"code": "200",
@@ -160,38 +160,40 @@ Content-Length: 197
03. Check location field is not broken in database
==================================================
-{
- "_id": {
- "id": "E1",
- "servicePath": "/",
- "type": "E"
- },
- "attrNames": [
- "position"
- ],
- "attrs": {
- "position": {
- "creDate": REGEX(\d+\.\d+),
- "mdNames": [],
- "modDate": REGEX(\d+\.\d+),
- "type": "geo:point",
- "value": "-3.3, 4.4"
- }
- },
- "creDate": REGEX(\d+\.\d+),
- "lastCorrelator": "REGEX(.*)",
- "location": {
- "attrName": "position",
- "coords": {
- "coordinates": [
- 4.4,
- -3.3
- ],
- "type": "Point"
- }
- },
- "modDate": REGEX(\d+\.\d+)
-}
+[
+ {
+ "_id": {
+ "id": "E",
+ "servicePath": "/",
+ "type": "T"
+ },
+ "attrNames": [
+ "location"
+ ],
+ "attrs": {
+ "location": {
+ "creDate": REGEX(\d+\.\d+),
+ "mdNames": [],
+ "modDate": REGEX(\d+\.\d+),
+ "type": "geo:point",
+ "value": "-3.3, 4.4"
+ }
+ },
+ "creDate": REGEX(\d+\.\d+),
+ "lastCorrelator": "REGEX(.*)",
+ "location": {
+ "attrName": "location",
+ "coords": {
+ "coordinates": [
+ 4.4,
+ -3.3
+ ],
+ "type": "Point"
+ }
+ },
+ "modDate": REGEX(\d+\.\d+)
+ }
+]
04. Update entity with geo:point with NGSIv1 (UPDATE)
@@ -200,7 +202,7 @@ HTTP/1.1 200 OK
Date: REGEX(.*)
Fiware-Correlator: REGEX([0-9a-f\-]{36})
Content-Type: application/json
-Content-Length: 197
+Content-Length: 196
{
"contextResponses": [
@@ -208,14 +210,14 @@ Content-Length: 197
"contextElement": {
"attributes": [
{
- "name": "position",
+ "name": "location",
"type": "geo:point",
"value": ""
}
],
- "id": "E1",
+ "id": "E",
"isPattern": "false",
- "type": "E"
+ "type": "T"
},
"statusCode": {
"code": "200",
@@ -228,38 +230,40 @@ Content-Length: 197
05. Check location field is not broken in database
==================================================
-{
- "_id": {
- "id": "E1",
- "servicePath": "/",
- "type": "E"
- },
- "attrNames": [
- "position"
- ],
- "attrs": {
- "position": {
- "creDate": REGEX(\d+\.\d+),
- "mdNames": [],
- "modDate": REGEX(\d+\.\d+),
- "type": "geo:point",
- "value": "5.5, -6.6"
- }
- },
- "creDate": REGEX(\d+\.\d+),
- "lastCorrelator": "REGEX(.*)",
- "location": {
- "attrName": "position",
- "coords": {
- "coordinates": [
- -6.6,
- 5.5
- ],
- "type": "Point"
- }
- },
- "modDate": REGEX(\d+\.\d+)
-}
+[
+ {
+ "_id": {
+ "id": "E",
+ "servicePath": "/",
+ "type": "T"
+ },
+ "attrNames": [
+ "location"
+ ],
+ "attrs": {
+ "location": {
+ "creDate": REGEX(\d+\.\d+),
+ "mdNames": [],
+ "modDate": REGEX(\d+\.\d+),
+ "type": "geo:point",
+ "value": "5.5, -6.6"
+ }
+ },
+ "creDate": REGEX(\d+\.\d+),
+ "lastCorrelator": "REGEX(.*)",
+ "location": {
+ "attrName": "location",
+ "coords": {
+ "coordinates": [
+ -6.6,
+ 5.5
+ ],
+ "type": "Point"
+ }
+ },
+ "modDate": REGEX(\d+\.\d+)
+ }
+]
--TEARDOWN--
diff --git a/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geopolygon_create_does_not_break_location.test b/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geopolygon_create_does_not_break_location.test
index 9de8bd322b..56e69a6734 100644
--- a/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geopolygon_create_does_not_break_location.test
+++ b/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geopolygon_create_does_not_break_location.test
@@ -40,7 +40,7 @@ echo "======================================================="
payload='{
"contextElements": [
{
- "type": "E",
+ "type": "T",
"isPattern": "false",
"id": "E1",
"attributes": [
@@ -61,7 +61,7 @@ echo
echo "02. Check location field is not broken in database"
echo "=================================================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find()' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.entities.find().toArray()' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -89,7 +89,7 @@ Content-Length: 199
],
"id": "E1",
"isPattern": "false",
- "type": "E"
+ "type": "T"
},
"statusCode": {
"code": "200",
@@ -102,59 +102,61 @@ Content-Length: 199
02. Check location field is not broken in database
==================================================
-{
- "_id": {
- "id": "E1",
- "servicePath": "/",
- "type": "E"
- },
- "attrNames": [
- "position"
- ],
- "attrs": {
- "position": {
- "creDate": REGEX(\d+\.\d+),
- "mdNames": [],
- "modDate": REGEX(\d+\.\d+),
- "type": "geo:polygon",
- "value": [
- "7.7, 8.8",
- "9.9, -10.10",
- "3.3, 2.2",
- "7.7, 8.8"
- ]
- }
- },
- "creDate": REGEX(\d+\.\d+),
- "lastCorrelator": "REGEX(.*)",
- "location": {
- "attrName": "position",
- "coords": {
- "coordinates": [
- [
- [
- 8.8,
- 7.7
- ],
- [
- -10.1,
- 9.9
- ],
- [
- 2.2,
- 3.3
- ],
+[
+ {
+ "_id": {
+ "id": "E1",
+ "servicePath": "/",
+ "type": "T"
+ },
+ "attrNames": [
+ "position"
+ ],
+ "attrs": {
+ "position": {
+ "creDate": REGEX(\d+\.\d+),
+ "mdNames": [],
+ "modDate": REGEX(\d+\.\d+),
+ "type": "geo:polygon",
+ "value": [
+ "7.7, 8.8",
+ "9.9, -10.10",
+ "3.3, 2.2",
+ "7.7, 8.8"
+ ]
+ }
+ },
+ "creDate": REGEX(\d+\.\d+),
+ "lastCorrelator": "REGEX(.*)",
+ "location": {
+ "attrName": "position",
+ "coords": {
+ "coordinates": [
[
- 8.8,
- 7.7
+ [
+ 8.8,
+ 7.7
+ ],
+ [
+ -10.1,
+ 9.9
+ ],
+ [
+ 2.2,
+ 3.3
+ ],
+ [
+ 8.8,
+ 7.7
+ ]
]
- ]
- ],
- "type": "Polygon"
- }
- },
- "modDate": REGEX(\d+\.\d+)
-}
+ ],
+ "type": "Polygon"
+ }
+ },
+ "modDate": REGEX(\d+\.\d+)
+ }
+]
--TEARDOWN--
diff --git a/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geopolygon_update_does_not_break_location.test b/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geopolygon_update_does_not_break_location.test
index 5e25fef048..0810506047 100644
--- a/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geopolygon_update_does_not_break_location.test
+++ b/test/functionalTest/cases/3442_ngsiv1_interop_location_fix/ngsiv1_geopolygon_update_does_not_break_location.test
@@ -57,12 +57,12 @@ echo "======================================================="
payload='{
"contextElements": [
{
- "type": "E",
+ "type": "T",
"isPattern": "false",
- "id": "E1",
+ "id": "E",
"attributes": [
{
- "name": "position",
+ "name": "location",
"type": "geo:polygon",
"value": ["-3.3, 4.4", "5.5, -6.6", "1.1, 2.2", "-3.3, 4.4"]
}
@@ -78,7 +78,7 @@ echo
echo "03. Check location field is not broken in database"
echo "=================================================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find()' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.entities.find().toArray()' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -88,12 +88,12 @@ echo "===================================================="
payload='{
"contextElements": [
{
- "type": "E",
+ "type": "T",
"isPattern": "false",
- "id": "E1",
+ "id": "E",
"attributes": [
{
- "name": "position",
+ "name": "location",
"type": "geo:polygon",
"value": ["7.7, 8.8", "9.9, -10.10", "3.3, 2.2", "7.7, 8.8"]
}
@@ -109,7 +109,7 @@ echo
echo "05. Check location field is not broken in database"
echo "=================================================="
-mongoCmd ${CB_DB_NAME} 'db.entities.find()' | python ${SCRIPT_HOME}/jsonBeautifier.py
+mongoCmd ${CB_DB_NAME} 'db.entities.find().toArray()' | python ${SCRIPT_HOME}/jsonBeautifier.py
echo
echo
@@ -132,7 +132,7 @@ HTTP/1.1 200 OK
Date: REGEX(.*)
Fiware-Correlator: REGEX([0-9a-f\-]{36})
Content-Type: application/json
-Content-Length: 199
+Content-Length: 198
{
"contextResponses": [
@@ -140,14 +140,14 @@ Content-Length: 199
"contextElement": {
"attributes": [
{
- "name": "position",
+ "name": "location",
"type": "geo:polygon",
"value": ""
}
],
- "id": "E1",
+ "id": "E",
"isPattern": "false",
- "type": "E"
+ "type": "T"
},
"statusCode": {
"code": "200",
@@ -160,59 +160,61 @@ Content-Length: 199
03. Check location field is not broken in database
==================================================
-{
- "_id": {
- "id": "E1",
- "servicePath": "/",
- "type": "E"
- },
- "attrNames": [
- "position"
- ],
- "attrs": {
- "position": {
- "creDate": REGEX(\d+\.\d+),
- "mdNames": [],
- "modDate": REGEX(\d+\.\d+),
- "type": "geo:polygon",
- "value": [
- "-3.3, 4.4",
- "5.5, -6.6",
- "1.1, 2.2",
- "-3.3, 4.4"
- ]
- }
- },
- "creDate": REGEX(\d+\.\d+),
- "lastCorrelator": "REGEX(.*)",
- "location": {
- "attrName": "position",
- "coords": {
- "coordinates": [
- [
- [
- 4.4,
- -3.3
- ],
- [
- -6.6,
- 5.5
- ],
- [
- 2.2,
- 1.1
- ],
+[
+ {
+ "_id": {
+ "id": "E",
+ "servicePath": "/",
+ "type": "T"
+ },
+ "attrNames": [
+ "location"
+ ],
+ "attrs": {
+ "location": {
+ "creDate": REGEX(\d+\.\d+),
+ "mdNames": [],
+ "modDate": REGEX(\d+\.\d+),
+ "type": "geo:polygon",
+ "value": [
+ "-3.3, 4.4",
+ "5.5, -6.6",
+ "1.1, 2.2",
+ "-3.3, 4.4"
+ ]
+ }
+ },
+ "creDate": REGEX(\d+\.\d+),
+ "lastCorrelator": "REGEX(.*)",
+ "location": {
+ "attrName": "location",
+ "coords": {
+ "coordinates": [
[
- 4.4,
- -3.3
+ [
+ 4.4,
+ -3.3
+ ],
+ [
+ -6.6,
+ 5.5
+ ],
+ [
+ 2.2,
+ 1.1
+ ],
+ [
+ 4.4,
+ -3.3
+ ]
]
- ]
- ],
- "type": "Polygon"
- }
- },
- "modDate": REGEX(\d+\.\d+)
-}
+ ],
+ "type": "Polygon"
+ }
+ },
+ "modDate": REGEX(\d+\.\d+)
+ }
+]
04. Update entity with geo:polygon with NGSIv1 (UPDATE)
@@ -221,7 +223,7 @@ HTTP/1.1 200 OK
Date: REGEX(.*)
Fiware-Correlator: REGEX([0-9a-f\-]{36})
Content-Type: application/json
-Content-Length: 199
+Content-Length: 198
{
"contextResponses": [
@@ -229,14 +231,14 @@ Content-Length: 199
"contextElement": {
"attributes": [
{
- "name": "position",
+ "name": "location",
"type": "geo:polygon",
"value": ""
}
],
- "id": "E1",
+ "id": "E",
"isPattern": "false",
- "type": "E"
+ "type": "T"
},
"statusCode": {
"code": "200",
@@ -249,59 +251,61 @@ Content-Length: 199
05. Check location field is not broken in database
==================================================
-{
- "_id": {
- "id": "E1",
- "servicePath": "/",
- "type": "E"
- },
- "attrNames": [
- "position"
- ],
- "attrs": {
- "position": {
- "creDate": REGEX(\d+\.\d+),
- "mdNames": [],
- "modDate": REGEX(\d+\.\d+),
- "type": "geo:polygon",
- "value": [
- "7.7, 8.8",
- "9.9, -10.10",
- "3.3, 2.2",
- "7.7, 8.8"
- ]
- }
- },
- "creDate": REGEX(\d+\.\d+),
- "lastCorrelator": "REGEX(.*)",
- "location": {
- "attrName": "position",
- "coords": {
- "coordinates": [
- [
- [
- 8.8,
- 7.7
- ],
- [
- -10.1,
- 9.9
- ],
- [
- 2.2,
- 3.3
- ],
+[
+ {
+ "_id": {
+ "id": "E",
+ "servicePath": "/",
+ "type": "T"
+ },
+ "attrNames": [
+ "location"
+ ],
+ "attrs": {
+ "location": {
+ "creDate": REGEX(\d+\.\d+),
+ "mdNames": [],
+ "modDate": REGEX(\d+\.\d+),
+ "type": "geo:polygon",
+ "value": [
+ "7.7, 8.8",
+ "9.9, -10.10",
+ "3.3, 2.2",
+ "7.7, 8.8"
+ ]
+ }
+ },
+ "creDate": REGEX(\d+\.\d+),
+ "lastCorrelator": "REGEX(.*)",
+ "location": {
+ "attrName": "location",
+ "coords": {
+ "coordinates": [
[
- 8.8,
- 7.7
+ [
+ 8.8,
+ 7.7
+ ],
+ [
+ -10.1,
+ 9.9
+ ],
+ [
+ 2.2,
+ 3.3
+ ],
+ [
+ 8.8,
+ 7.7
+ ]
]
- ]
- ],
- "type": "Polygon"
- }
- },
- "modDate": REGEX(\d+\.\d+)
-}
+ ],
+ "type": "Polygon"
+ }
+ },
+ "modDate": REGEX(\d+\.\d+)
+ }
+]
--TEARDOWN--
diff --git a/test/functionalTest/cases/3706_incorrect_location_processing/incorrect_location_processing.test b/test/functionalTest/cases/3706_incorrect_location_processing/incorrect_location_processing.test
index 64e62982bd..ec5a7c49d2 100644
--- a/test/functionalTest/cases/3706_incorrect_location_processing/incorrect_location_processing.test
+++ b/test/functionalTest/cases/3706_incorrect_location_processing/incorrect_location_processing.test
@@ -239,9 +239,7 @@ doc='{
"modDate": 1603273111.6493506,
"lastCorrelator": "2e7b6c36-1381-11eb-a1f0-0242ac110013"
}'
-# FIXME P3: not sure why mongCmd() doesn't work this time... maybe $doc is too long?
-#mongoCmd ${CB_DB_NAME} "db.entities.insert($doc)"
-echo "db.entities.insert($doc)" | mongo mongodb://localhost:27017/${CB_DB_NAME} | tail -n 2 | head -n 1
+mongoCmd ${CB_DB_NAME} "db.entities.insertOne($doc)"
echo
echo
@@ -264,7 +262,7 @@ echo
--REGEXPECT--
01. Create entity directly in DB
================================
-WriteResult({ "nInserted" : 1 })
+{"acknowledged":true,"insertedId":{"id":"ES0021000001111111AA","type":"SupplyPoint","servicePath":"/energia"}}
02. Update the entity as described in #3706 and check we don't get 413 error
diff --git a/test/functionalTest/cases/3914_mqtt_notifications_auth/mqtt_custom_notifications_auth.test b/test/functionalTest/cases/3914_mqtt_notifications_auth/mqtt_custom_notifications_auth.test
index 95d03e9ebd..59a65b45f0 100644
--- a/test/functionalTest/cases/3914_mqtt_notifications_auth/mqtt_custom_notifications_auth.test
+++ b/test/functionalTest/cases/3914_mqtt_notifications_auth/mqtt_custom_notifications_auth.test
@@ -353,8 +353,8 @@ Content-Length: 366
06. Get sub password pass1 from DB
==================================
-user1
-pass1
+"user1"
+"pass1"
07. PATCH sub changing password to user10 and pass10
@@ -407,8 +407,8 @@ Content-Length: 367
09. Get sub password pass10 from DB
===================================
-user10
-pass10
+"user10"
+"pass10"
10. PATCH sub removing auth parameters
@@ -513,8 +513,8 @@ Content-Length: 366
15. Get sub password pass1 from DB
==================================
-user1
-pass1
+"user1"
+"pass1"
--TEARDOWN--
diff --git a/test/functionalTest/cases/3914_mqtt_notifications_auth/mqtt_notifications_auth.test b/test/functionalTest/cases/3914_mqtt_notifications_auth/mqtt_notifications_auth.test
index 2b149a5221..f165102fb6 100644
--- a/test/functionalTest/cases/3914_mqtt_notifications_auth/mqtt_notifications_auth.test
+++ b/test/functionalTest/cases/3914_mqtt_notifications_auth/mqtt_notifications_auth.test
@@ -353,8 +353,8 @@ Content-Length: 360
06. Get sub password pass1 from DB
==================================
-user1
-pass1
+"user1"
+"pass1"
07. PATCH sub changing password to user10 and pass10
@@ -407,8 +407,8 @@ Content-Length: 361
09. Get sub password pass10 from DB
===================================
-user10
-pass10
+"user10"
+"pass10"
10. PATCH sub removing auth parameters
@@ -513,8 +513,8 @@ Content-Length: 360
15. Get sub password pass1 from DB
==================================
-user1
-pass1
+"user1"
+"pass1"
--TEARDOWN--
diff --git a/test/functionalTest/cases/4069_status_inactive_not_working_with_cache_in_ha/status_inactive_not_working_with_cache_in_ha.test b/test/functionalTest/cases/4069_status_inactive_not_working_with_cache_in_ha/status_inactive_not_working_with_cache_in_ha.test
index 7940e619b1..971e0151e9 100644
--- a/test/functionalTest/cases/4069_status_inactive_not_working_with_cache_in_ha/status_inactive_not_working_with_cache_in_ha.test
+++ b/test/functionalTest/cases/4069_status_inactive_not_working_with_cache_in_ha/status_inactive_not_working_with_cache_in_ha.test
@@ -26,7 +26,7 @@ Status inactive was not working in HA scenario when cache is used
--SHELL-INIT--
dbInit CB
-mongoCmd ${CB_DB_NAME} 'db.csubs.insert({
+mongoCmd ${CB_DB_NAME} 'db.csubs.insertOne({
"_id" : ObjectId("620e0d04219c8378695c822b"),
"expiration" : NumberLong("9223372036854775807"),
"reference" : "http://localhost:1234",
diff --git a/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_geojson.test b/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_geojson.test
new file mode 100644
index 0000000000..a540d7c043
--- /dev/null
+++ b/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_geojson.test
@@ -0,0 +1,226 @@
+# Copyright 2023 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--
+Right JSON change evaluation in subs (GeoJson case)
+
+--SHELL-INIT--
+dbInit CB
+brokerStart CB
+accumulatorStart --pretty-print
+
+--SHELL--
+
+#
+# 01. Create subscription covering E-A
+# 02. Create E-A entity with geo:json (notification)
+# 03. Update E-A entity with same geo:json object (no notification)
+# 04. Update E-A entity with different geo:json (notification)
+# 05. Dump accumulator, see 2 notifications
+#
+
+echo "01. Create subscription covering E-A"
+echo "===================================="
+payload='{
+ "subject": {
+ "entities": [
+ {
+ "id" : "E",
+ "type": "T"
+ }
+ ]
+ },
+ "notification": {
+ "http": {
+ "url": "http://127.0.0.1:'${LISTENER_PORT}'/notify"
+ }
+ }
+}'
+orionCurl --url /v2/subscriptions --payload "$payload"
+echo
+echo
+
+
+echo "02. Create E-A entity with geo:json (notification)"
+echo "=================================================="
+payload='{
+ "id": "E",
+ "type": "T",
+ "A": {
+ "type": "geo:json",
+ "value": {
+ "type": "Point",
+ "coordinates": [10.2, 10.0]
+ }
+ }
+}'
+orionCurl --url /v2/entities --payload "$payload"
+echo
+echo
+
+
+echo "03. Update E-A entity with same geo:json (no notification)"
+echo "=========================================================="
+payload='{
+ "A": {
+ "type": "geo:json",
+ "value": {
+ "type": "Point",
+ "coordinates": [10.2, 10.0]
+ }
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "04. Update E-A entity with different geo:json (notification)"
+echo "============================================================"
+payload='{
+ "A": {
+ "type": "geo:json",
+ "value": {
+ "type": "Point",
+ "coordinates": [11.2, -10.0]
+ }
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "05. Dump accumulator, see 2 notifications"
+echo "========================================="
+accumulatorDump
+echo
+echo
+
+
+--REGEXPECT--
+01. Create subscription covering E-A
+====================================
+HTTP/1.1 201 Created
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Location: /v2/subscriptions/REGEX([0-9a-f]{24})
+Content-Length: 0
+
+
+
+02. Create E-A entity with geo:json (notification)
+==================================================
+HTTP/1.1 201 Created
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Location: /v2/entities/E?type=T
+Content-Length: 0
+
+
+
+03. Update E-A entity with same geo:json (no notification)
+==========================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+04. Update E-A entity with different geo:json (notification)
+============================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+05. Dump accumulator, see 2 notifications
+=========================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 163
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {},
+ "type": "geo:json",
+ "value": {
+ "coordinates": [
+ 10.2,
+ 10
+ ],
+ "type": "Point"
+ }
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 164
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {},
+ "type": "geo:json",
+ "value": {
+ "coordinates": [
+ 11.2,
+ -10
+ ],
+ "type": "Point"
+ }
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+
+
+--TEARDOWN--
+brokerStop CB
+dbDrop CB
+accumulatorStop
diff --git a/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_metadata_object_and_array.test b/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_metadata_object_and_array.test
new file mode 100644
index 0000000000..6fd56fd903
--- /dev/null
+++ b/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_metadata_object_and_array.test
@@ -0,0 +1,600 @@
+# Copyright 2023 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--
+Right JSON change evaluation in subs (objects and arrays in metadata case)
+
+--SHELL-INIT--
+dbInit CB
+brokerStart CB
+accumulatorStart --pretty-print
+
+--SHELL--
+
+#
+# 01. Create subscription covering E-A
+# 02. Create E-A entity with JSON object in metadata (notification)
+# 03. Update E-A entity with same JSON object in metadata (no notification)
+# 04. Update E-A entity with different JSON object in metadata (notification)
+# 05. Update E-A entity with JSON array in metadata (notification)
+# 06. Update E-A entity with same JSON array in metadata (no notification)
+# 07. Update E-A entity with different JSON array in metadata (notification)
+# 08. Update E-A entity with same string in metadata (notification)
+# 09. Dump accumulator, see 5 notifications
+#
+
+echo "01. Create subscription covering E-A"
+echo "===================================="
+payload='{
+ "subject": {
+ "entities": [
+ {
+ "id" : "E",
+ "type": "T"
+ }
+ ]
+ },
+ "notification": {
+ "http": {
+ "url": "http://127.0.0.1:'${LISTENER_PORT}'/notify"
+ }
+ }
+}'
+orionCurl --url /v2/subscriptions --payload "$payload"
+echo
+echo
+
+
+echo "02. Create E-A entity with JSON object in metadata (notification)"
+echo "================================================================="
+payload='{
+ "id": "E",
+ "type": "T",
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": {
+ "text": "foo",
+ "number": 10,
+ "bool": true,
+ "null": null,
+ "array": [
+ "22",
+ {
+ "x" : [ "x1", "x2" ],
+ "y" : 3
+ },
+ [ "z1", "z2" ]
+ ],
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [ "y1", "y2" ]
+ }
+ },
+ "type": "Json"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities --payload "$payload"
+echo
+echo
+
+
+echo "03. Update E-A entity with same JSON object in metadata (no notification)"
+echo "========================================================================="
+payload='{
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": {
+ "text": "foo",
+ "number": 10,
+ "bool": true,
+ "null": null,
+ "array": [
+ "22",
+ {
+ "x" : [ "x1", "x2" ],
+ "y" : 3
+ },
+ [ "z1", "z2" ]
+ ],
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [ "y1", "y2" ]
+ }
+ },
+ "type": "Json"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "04. Update E-A entity with different JSON object in metadata (notification)"
+echo "==========================================================================="
+payload='{
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": {
+ "text": "foo",
+ "number": 10,
+ "bool": true,
+ "null": null,
+ "array": [
+ "22",
+ {
+ "x" : [ "x1", "x2" ],
+ "y" : 3
+ },
+ [ "z1", "z2" ]
+ ],
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [ "y1", "y_new" ]
+ }
+ },
+ "type": "Json"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "05. Update E-A entity with JSON array in metadata (notification)"
+echo "================================================================"
+payload='{
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": [
+ "",
+ {
+ "x": [ "x1", "x2" ],
+ "y": "3"
+ },
+ [ "z1", "z2" ]
+ ],
+ "type": "Array"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "06. Update E-A entity with same JSON array in metadata (no notification)"
+echo "========================================================================"
+payload='{
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": [
+ "",
+ {
+ "x": [ "x1", "x2" ],
+ "y": "3"
+ },
+ [ "z1", "z2" ]
+ ],
+ "type": "Array"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "07. Update E-A entity with different JSON array in metadata (notification)"
+echo "=========================================================================="
+payload='{
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": [
+ "",
+ {
+ "x": [ "x1", "x_new" ],
+ "y": "3"
+ },
+ [ "z1", "z2" ]
+ ],
+ "type": "Array"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "08. Update E-A entity with same string in metadata (notification)"
+echo "================================================================="
+payload='{
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": "foo",
+ "type": "Text"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "09. Dump accumulator, see 5 notifications"
+echo "========================================="
+accumulatorDump
+echo
+echo
+
+
+--REGEXPECT--
+01. Create subscription covering E-A
+====================================
+HTTP/1.1 201 Created
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Location: /v2/subscriptions/REGEX([0-9a-f]{24})
+Content-Length: 0
+
+
+
+02. Create E-A entity with JSON object in metadata (notification)
+=================================================================
+HTTP/1.1 201 Created
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Location: /v2/entities/E?type=T
+Content-Length: 0
+
+
+
+03. Update E-A entity with same JSON object in metadata (no notification)
+=========================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+04. Update E-A entity with different JSON object in metadata (notification)
+===========================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+05. Update E-A entity with JSON array in metadata (notification)
+================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+06. Update E-A entity with same JSON array in metadata (no notification)
+========================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+07. Update E-A entity with different JSON array in metadata (notification)
+==========================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+08. Update E-A entity with same string in metadata (notification)
+=================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+09. Dump accumulator, see 5 notifications
+=========================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 302
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {
+ "M": {
+ "type": "Json",
+ "value": {
+ "array": [
+ "22",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": 3
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ],
+ "bool": true,
+ "null": null,
+ "number": 10,
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [
+ "y1",
+ "y2"
+ ]
+ },
+ "text": "foo"
+ }
+ }
+ },
+ "type": "Number",
+ "value": 1
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 305
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {
+ "M": {
+ "type": "Json",
+ "value": {
+ "array": [
+ "22",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": 3
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ],
+ "bool": true,
+ "null": null,
+ "number": 10,
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [
+ "y1",
+ "y_new"
+ ]
+ },
+ "text": "foo"
+ }
+ }
+ },
+ "type": "Number",
+ "value": 1
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 193
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {
+ "M": {
+ "type": "Array",
+ "value": [
+ "",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": "3"
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ]
+ }
+ },
+ "type": "Number",
+ "value": 1
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 196
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {
+ "M": {
+ "type": "Array",
+ "value": [
+ "",
+ {
+ "x": [
+ "x1",
+ "x_new"
+ ],
+ "y": "3"
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ]
+ }
+ },
+ "type": "Number",
+ "value": 1
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 155
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {
+ "M": {
+ "type": "Text",
+ "value": "foo"
+ }
+ },
+ "type": "Number",
+ "value": 1
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+
+
+--TEARDOWN--
+brokerStop CB
+dbDrop CB
+accumulatorStop
diff --git a/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_metadata_object_and_array_with_entityUpdate.test b/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_metadata_object_and_array_with_entityUpdate.test
new file mode 100644
index 0000000000..54ee0e648b
--- /dev/null
+++ b/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_metadata_object_and_array_with_entityUpdate.test
@@ -0,0 +1,649 @@
+# Copyright 2023 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--
+Right JSON change evaluation in subs (objects and arrays in metadata case with entityUpdate)
+
+--SHELL-INIT--
+dbInit CB
+brokerStart CB
+accumulatorStart --pretty-print
+
+--SHELL--
+
+#
+# Same as change_evaluation_metadata_object_and_array.test but using entityUpdate in the subscription
+#
+#
+# 01. Create subscription covering E-A
+# 02. Create E-A entity with JSON object in metadata (no notification)
+# 03. Update E-A entity with same JSON object in metadata (notification)
+# 04. Update E-A entity with different JSON object in metadata (notification)
+# 05. Update E-A entity with JSON array in metadata (notification)
+# 06. Update E-A entity with same JSON array in metadata (notification)
+# 07. Update E-A entity with different JSON array in metadata (notification)
+# 08. Update E-A entity with same string in metadata (notification)
+# 09. Dump accumulator, see 6 notifications
+#
+
+echo "01. Create subscription covering E-A"
+echo "===================================="
+payload='{
+ "subject": {
+ "entities": [
+ {
+ "id" : "E",
+ "type": "T"
+ }
+ ],
+ "condition": {
+ "alterationTypes": [ "entityUpdate" ]
+ }
+ },
+ "notification": {
+ "http": {
+ "url": "http://127.0.0.1:'${LISTENER_PORT}'/notify"
+ }
+ }
+}'
+orionCurl --url /v2/subscriptions --payload "$payload"
+echo
+echo
+
+
+echo "02. Create E-A entity with JSON object in metadata (no notification)"
+echo "===================================================================="
+payload='{
+ "id": "E",
+ "type": "T",
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": {
+ "text": "foo",
+ "number": 10,
+ "bool": true,
+ "null": null,
+ "array": [
+ "22",
+ {
+ "x" : [ "x1", "x2" ],
+ "y" : 3
+ },
+ [ "z1", "z2" ]
+ ],
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [ "y1", "y2" ]
+ }
+ },
+ "type": "Json"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities --payload "$payload"
+echo
+echo
+
+
+echo "03. Update E-A entity with same JSON object in metadata (notification)"
+echo "======================================================================"
+payload='{
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": {
+ "text": "foo",
+ "number": 10,
+ "bool": true,
+ "null": null,
+ "array": [
+ "22",
+ {
+ "x" : [ "x1", "x2" ],
+ "y" : 3
+ },
+ [ "z1", "z2" ]
+ ],
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [ "y1", "y2" ]
+ }
+ },
+ "type": "Json"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "04. Update E-A entity with different JSON object in metadata (notification)"
+echo "==========================================================================="
+payload='{
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": {
+ "text": "foo",
+ "number": 10,
+ "bool": true,
+ "null": null,
+ "array": [
+ "22",
+ {
+ "x" : [ "x1", "x2" ],
+ "y" : 3
+ },
+ [ "z1", "z2" ]
+ ],
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [ "y1", "y_new" ]
+ }
+ },
+ "type": "Json"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "05. Update E-A entity with JSON array in metadata (notification)"
+echo "================================================================"
+payload='{
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": [
+ "",
+ {
+ "x": [ "x1", "x2" ],
+ "y": "3"
+ },
+ [ "z1", "z2" ]
+ ],
+ "type": "Array"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "06. Update E-A entity with same JSON array in metadata (notification)"
+echo "====================================================================="
+payload='{
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": [
+ "",
+ {
+ "x": [ "x1", "x2" ],
+ "y": "3"
+ },
+ [ "z1", "z2" ]
+ ],
+ "type": "Array"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "07. Update E-A entity with different JSON array in metadata (notification)"
+echo "=========================================================================="
+payload='{
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": [
+ "",
+ {
+ "x": [ "x1", "x_new" ],
+ "y": "3"
+ },
+ [ "z1", "z2" ]
+ ],
+ "type": "Array"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "08. Update E-A entity with same string in metadata (notification)"
+echo "================================================================="
+payload='{
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": "foo",
+ "type": "Text"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "09. Dump accumulator, see 6 notifications"
+echo "========================================="
+accumulatorDump
+echo
+echo
+
+
+--REGEXPECT--
+01. Create subscription covering E-A
+====================================
+HTTP/1.1 201 Created
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Location: /v2/subscriptions/REGEX([0-9a-f]{24})
+Content-Length: 0
+
+
+
+02. Create E-A entity with JSON object in metadata (no notification)
+====================================================================
+HTTP/1.1 201 Created
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Location: /v2/entities/E?type=T
+Content-Length: 0
+
+
+
+03. Update E-A entity with same JSON object in metadata (notification)
+======================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+04. Update E-A entity with different JSON object in metadata (notification)
+===========================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+05. Update E-A entity with JSON array in metadata (notification)
+================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+06. Update E-A entity with same JSON array in metadata (notification)
+=====================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+07. Update E-A entity with different JSON array in metadata (notification)
+==========================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+08. Update E-A entity with same string in metadata (notification)
+=================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+09. Dump accumulator, see 6 notifications
+=========================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 302
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {
+ "M": {
+ "type": "Json",
+ "value": {
+ "array": [
+ "22",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": 3
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ],
+ "bool": true,
+ "null": null,
+ "number": 10,
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [
+ "y1",
+ "y2"
+ ]
+ },
+ "text": "foo"
+ }
+ }
+ },
+ "type": "Number",
+ "value": 1
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 305
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {
+ "M": {
+ "type": "Json",
+ "value": {
+ "array": [
+ "22",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": 3
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ],
+ "bool": true,
+ "null": null,
+ "number": 10,
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [
+ "y1",
+ "y_new"
+ ]
+ },
+ "text": "foo"
+ }
+ }
+ },
+ "type": "Number",
+ "value": 1
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 193
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {
+ "M": {
+ "type": "Array",
+ "value": [
+ "",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": "3"
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ]
+ }
+ },
+ "type": "Number",
+ "value": 1
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 193
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {
+ "M": {
+ "type": "Array",
+ "value": [
+ "",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": "3"
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ]
+ }
+ },
+ "type": "Number",
+ "value": 1
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 196
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {
+ "M": {
+ "type": "Array",
+ "value": [
+ "",
+ {
+ "x": [
+ "x1",
+ "x_new"
+ ],
+ "y": "3"
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ]
+ }
+ },
+ "type": "Number",
+ "value": 1
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 155
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {
+ "M": {
+ "type": "Text",
+ "value": "foo"
+ }
+ },
+ "type": "Number",
+ "value": 1
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+
+
+--TEARDOWN--
+brokerStop CB
+dbDrop CB
+accumulatorStop
diff --git a/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_metadata_object_and_array_with_forcedUpdate.test b/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_metadata_object_and_array_with_forcedUpdate.test
new file mode 100644
index 0000000000..6a54735e5e
--- /dev/null
+++ b/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_metadata_object_and_array_with_forcedUpdate.test
@@ -0,0 +1,705 @@
+# Copyright 2023 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--
+Right JSON change evaluation in subs (objects and arrays in metadata case with forcedUpdate)
+
+--SHELL-INIT--
+dbInit CB
+brokerStart CB
+accumulatorStart --pretty-print
+
+--SHELL--
+
+#
+# Same as change_evaluation_metadata_object_and_array.test but using forcedUpdate un update operations
+#
+#
+# 01. Create subscription covering E-A
+# 02. Create E-A entity with JSON object in metadata (notification)
+# 03. Update E-A entity with same JSON object in metadata (notification)
+# 04. Update E-A entity with different JSON object in metadata (notification)
+# 05. Update E-A entity with JSON array in metadata (notification)
+# 06. Update E-A entity with same JSON array in metadata (notification)
+# 07. Update E-A entity with different JSON array in metadata (notification)
+# 08. Update E-A entity with same string in metadata (notification)
+# 09. Dump accumulator, see 7 notifications
+#
+
+echo "01. Create subscription covering E-A"
+echo "===================================="
+payload='{
+ "subject": {
+ "entities": [
+ {
+ "id" : "E",
+ "type": "T"
+ }
+ ]
+ },
+ "notification": {
+ "http": {
+ "url": "http://127.0.0.1:'${LISTENER_PORT}'/notify"
+ }
+ }
+}'
+orionCurl --url /v2/subscriptions --payload "$payload"
+echo
+echo
+
+
+echo "02. Create E-A entity with JSON object in metadata (notification)"
+echo "================================================================="
+payload='{
+ "id": "E",
+ "type": "T",
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": {
+ "text": "foo",
+ "number": 10,
+ "bool": true,
+ "null": null,
+ "array": [
+ "22",
+ {
+ "x" : [ "x1", "x2" ],
+ "y" : 3
+ },
+ [ "z1", "z2" ]
+ ],
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [ "y1", "y2" ]
+ }
+ },
+ "type": "Json"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities --payload "$payload"
+echo
+echo
+
+
+echo "03. Update E-A entity with same JSON object in metadata (notification)"
+echo "======================================================================"
+payload='{
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": {
+ "text": "foo",
+ "number": 10,
+ "bool": true,
+ "null": null,
+ "array": [
+ "22",
+ {
+ "x" : [ "x1", "x2" ],
+ "y" : 3
+ },
+ [ "z1", "z2" ]
+ ],
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [ "y1", "y2" ]
+ }
+ },
+ "type": "Json"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities/E/attrs?options=forcedUpdate --payload "$payload"
+echo
+echo
+
+
+echo "04. Update E-A entity with different JSON object in metadata (notification)"
+echo "==========================================================================="
+payload='{
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": {
+ "text": "foo",
+ "number": 10,
+ "bool": true,
+ "null": null,
+ "array": [
+ "22",
+ {
+ "x" : [ "x1", "x2" ],
+ "y" : 3
+ },
+ [ "z1", "z2" ]
+ ],
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [ "y1", "y_new" ]
+ }
+ },
+ "type": "Json"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities/E/attrs?options=forcedUpdate --payload "$payload"
+echo
+echo
+
+
+echo "05. Update E-A entity with JSON array in metadata (notification)"
+echo "================================================================"
+payload='{
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": [
+ "",
+ {
+ "x": [ "x1", "x2" ],
+ "y": "3"
+ },
+ [ "z1", "z2" ]
+ ],
+ "type": "Array"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities/E/attrs?options=forcedUpdate --payload "$payload"
+echo
+echo
+
+
+echo "06. Update E-A entity with same JSON array in metadata (notification)"
+echo "====================================================================="
+payload='{
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": [
+ "",
+ {
+ "x": [ "x1", "x2" ],
+ "y": "3"
+ },
+ [ "z1", "z2" ]
+ ],
+ "type": "Array"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities/E/attrs?options=forcedUpdate --payload "$payload"
+echo
+echo
+
+
+echo "07. Update E-A entity with different JSON array in metadata (notification)"
+echo "=========================================================================="
+payload='{
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": [
+ "",
+ {
+ "x": [ "x1", "x_new" ],
+ "y": "3"
+ },
+ [ "z1", "z2" ]
+ ],
+ "type": "Array"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities/E/attrs?options=forcedUpdate --payload "$payload"
+echo
+echo
+
+
+echo "08. Update E-A entity with same string in metadata (notification)"
+echo "================================================================="
+payload='{
+ "A": {
+ "value": 1,
+ "type": "Number",
+ "metadata": {
+ "M": {
+ "value": "foo",
+ "type": "Text"
+ }
+ }
+ }
+}'
+orionCurl --url /v2/entities/E/attrs?options=forcedUpdate --payload "$payload"
+echo
+echo
+
+
+echo "09. Dump accumulator, see 7 notifications"
+echo "========================================="
+accumulatorDump
+echo
+echo
+
+
+--REGEXPECT--
+01. Create subscription covering E-A
+====================================
+HTTP/1.1 201 Created
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Location: /v2/subscriptions/REGEX([0-9a-f]{24})
+Content-Length: 0
+
+
+
+02. Create E-A entity with JSON object in metadata (notification)
+=================================================================
+HTTP/1.1 201 Created
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Location: /v2/entities/E?type=T
+Content-Length: 0
+
+
+
+03. Update E-A entity with same JSON object in metadata (notification)
+======================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+04. Update E-A entity with different JSON object in metadata (notification)
+===========================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+05. Update E-A entity with JSON array in metadata (notification)
+================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+06. Update E-A entity with same JSON array in metadata (notification)
+=====================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+07. Update E-A entity with different JSON array in metadata (notification)
+==========================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+08. Update E-A entity with same string in metadata (notification)
+=================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+09. Dump accumulator, see 7 notifications
+=========================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 302
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {
+ "M": {
+ "type": "Json",
+ "value": {
+ "array": [
+ "22",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": 3
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ],
+ "bool": true,
+ "null": null,
+ "number": 10,
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [
+ "y1",
+ "y2"
+ ]
+ },
+ "text": "foo"
+ }
+ }
+ },
+ "type": "Number",
+ "value": 1
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 302
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {
+ "M": {
+ "type": "Json",
+ "value": {
+ "array": [
+ "22",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": 3
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ],
+ "bool": true,
+ "null": null,
+ "number": 10,
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [
+ "y1",
+ "y2"
+ ]
+ },
+ "text": "foo"
+ }
+ }
+ },
+ "type": "Number",
+ "value": 1
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 305
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {
+ "M": {
+ "type": "Json",
+ "value": {
+ "array": [
+ "22",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": 3
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ],
+ "bool": true,
+ "null": null,
+ "number": 10,
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [
+ "y1",
+ "y_new"
+ ]
+ },
+ "text": "foo"
+ }
+ }
+ },
+ "type": "Number",
+ "value": 1
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 193
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {
+ "M": {
+ "type": "Array",
+ "value": [
+ "",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": "3"
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ]
+ }
+ },
+ "type": "Number",
+ "value": 1
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 193
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {
+ "M": {
+ "type": "Array",
+ "value": [
+ "",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": "3"
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ]
+ }
+ },
+ "type": "Number",
+ "value": 1
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 196
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {
+ "M": {
+ "type": "Array",
+ "value": [
+ "",
+ {
+ "x": [
+ "x1",
+ "x_new"
+ ],
+ "y": "3"
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ]
+ }
+ },
+ "type": "Number",
+ "value": 1
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 155
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {
+ "M": {
+ "type": "Text",
+ "value": "foo"
+ }
+ },
+ "type": "Number",
+ "value": 1
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+
+
+--TEARDOWN--
+brokerStop CB
+dbDrop CB
+accumulatorStop
diff --git a/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_value_object_and_array.test b/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_value_object_and_array.test
new file mode 100644
index 0000000000..cc664dd6cd
--- /dev/null
+++ b/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_value_object_and_array.test
@@ -0,0 +1,533 @@
+# Copyright 2023 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--
+Right JSON change evaluation in subs (objects and arrays in attribute value case)
+
+--SHELL-INIT--
+dbInit CB
+brokerStart CB
+accumulatorStart --pretty-print
+
+--SHELL--
+
+#
+# 01. Create subscription covering E-A
+# 02. Create E-A entity with JSON object (notification)
+# 03. Update E-A entity with same JSON object (no notification)
+# 04. Update E-A entity with different JSON object (notification)
+# 05. Update E-A entity with JSON array (notification)
+# 06. Update E-A entity with same JSON array (no notification)
+# 07. Update E-A entity with different JSON array (notification)
+# 08. Update E-A entity with same string (notification)
+# 09. Dump accumulator, see 5 notifications
+#
+
+echo "01. Create subscription covering E-A"
+echo "===================================="
+payload='{
+ "subject": {
+ "entities": [
+ {
+ "id" : "E",
+ "type": "T"
+ }
+ ]
+ },
+ "notification": {
+ "http": {
+ "url": "http://127.0.0.1:'${LISTENER_PORT}'/notify"
+ }
+ }
+}'
+orionCurl --url /v2/subscriptions --payload "$payload"
+echo
+echo
+
+
+echo "02. Create E-A entity with JSON object (notification)"
+echo "====================================================="
+payload='{
+ "id": "E",
+ "type": "T",
+ "A": {
+ "value": {
+ "text": "foo",
+ "number": 10,
+ "bool": true,
+ "null": null,
+ "array": [
+ "22",
+ {
+ "x" : [ "x1", "x2" ],
+ "y" : 3
+ },
+ [ "z1", "z2" ]
+ ],
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [ "y1", "y2" ]
+ }
+ },
+ "type": "Json"
+ }
+}'
+orionCurl --url /v2/entities --payload "$payload"
+echo
+echo
+
+
+echo "03. Update E-A entity with same JSON object (no notification)"
+echo "============================================================="
+payload='{
+ "A": {
+ "value": {
+ "text": "foo",
+ "number": 10,
+ "bool": true,
+ "null": null,
+ "array": [
+ "22",
+ {
+ "x" : [ "x1", "x2" ],
+ "y" : 3
+ },
+ [ "z1", "z2" ]
+ ],
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [ "y1", "y2" ]
+ }
+ },
+ "type": "Json"
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "04. Update E-A entity with different JSON object (notification)"
+echo "==============================================================="
+payload='{
+ "A": {
+ "value": {
+ "text": "foo",
+ "number": 10,
+ "bool": true,
+ "null": null,
+ "array": [
+ "22",
+ {
+ "x" : [ "x1", "x2" ],
+ "y" : 3
+ },
+ [ "z1", "z2" ]
+ ],
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [ "y1", "y_new" ]
+ }
+ },
+ "type": "Json"
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "05. Update E-A entity with JSON array (notification)"
+echo "===================================================="
+payload='{
+ "A": {
+ "value": [
+ "",
+ {
+ "x": [ "x1", "x2" ],
+ "y": "3"
+ },
+ [ "z1", "z2" ]
+ ],
+ "type": "Array"
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "06. Update E-A entity with same JSON array (no notification)"
+echo "============================================================"
+payload='{
+ "A": {
+ "value": [
+ "",
+ {
+ "x": [ "x1", "x2" ],
+ "y": "3"
+ },
+ [ "z1", "z2" ]
+ ],
+ "type": "Array"
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "07. Update E-A entity with different JSON array (notification)"
+echo "=============================================================="
+payload='{
+ "A": {
+ "value": [
+ "",
+ {
+ "x": [ "x1", "x_new" ],
+ "y": "3"
+ },
+ [ "z1", "z2" ]
+ ],
+ "type": "Array"
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "08. Update E-A entity with same string (notification)"
+echo "====================================================="
+payload='{
+ "A": {
+ "value": "foo",
+ "type": "Text"
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "09. Dump accumulator, see 5 notifications"
+echo "========================================="
+accumulatorDump
+echo
+echo
+
+
+--REGEXPECT--
+01. Create subscription covering E-A
+====================================
+HTTP/1.1 201 Created
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Location: /v2/subscriptions/REGEX([0-9a-f]{24})
+Content-Length: 0
+
+
+
+02. Create E-A entity with JSON object (notification)
+=====================================================
+HTTP/1.1 201 Created
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Location: /v2/entities/E?type=T
+Content-Length: 0
+
+
+
+03. Update E-A entity with same JSON object (no notification)
+=============================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+04. Update E-A entity with different JSON object (notification)
+===============================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+05. Update E-A entity with JSON array (notification)
+====================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+06. Update E-A entity with same JSON array (no notification)
+============================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+07. Update E-A entity with different JSON array (notification)
+==============================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+08. Update E-A entity with same string (notification)
+=====================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+09. Dump accumulator, see 5 notifications
+=========================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 271
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {},
+ "type": "Json",
+ "value": {
+ "array": [
+ "22",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": 3
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ],
+ "bool": true,
+ "null": null,
+ "number": 10,
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [
+ "y1",
+ "y2"
+ ]
+ },
+ "text": "foo"
+ }
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 274
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {},
+ "type": "Json",
+ "value": {
+ "array": [
+ "22",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": 3
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ],
+ "bool": true,
+ "null": null,
+ "number": 10,
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [
+ "y1",
+ "y_new"
+ ]
+ },
+ "text": "foo"
+ }
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 162
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {},
+ "type": "Array",
+ "value": [
+ "",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": "3"
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ]
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 165
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {},
+ "type": "Array",
+ "value": [
+ "",
+ {
+ "x": [
+ "x1",
+ "x_new"
+ ],
+ "y": "3"
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ]
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 124
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {},
+ "type": "Text",
+ "value": "foo"
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+
+
+--TEARDOWN--
+brokerStop CB
+dbDrop CB
+accumulatorStop
diff --git a/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_value_object_and_array_with_entityUpdate.test b/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_value_object_and_array_with_entityUpdate.test
new file mode 100644
index 0000000000..a0befc27d9
--- /dev/null
+++ b/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_value_object_and_array_with_entityUpdate.test
@@ -0,0 +1,577 @@
+# Copyright 2023 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--
+Right JSON change evaluation in subs (objects and arrays in attribute value case with entityUpdate)
+
+--SHELL-INIT--
+dbInit CB
+brokerStart CB
+accumulatorStart --pretty-print
+
+--SHELL--
+
+#
+# Same as change_evaluation_value_object_and_array.test but using entityUpdate in the subscription
+#
+#
+# 01. Create subscription covering E-A
+# 02. Create E-A entity with JSON object (no notification)
+# 03. Update E-A entity with same JSON object (notification)
+# 04. Update E-A entity with different JSON object (notification)
+# 05. Update E-A entity with JSON array (notification)
+# 06. Update E-A entity with same JSON array (notification)
+# 07. Update E-A entity with different JSON array (notification)
+# 08. Update E-A entity with same string (notification)
+# 09. Dump accumulator, see 6 notifications
+#
+
+echo "01. Create subscription covering E-A"
+echo "===================================="
+payload='{
+ "subject": {
+ "entities": [
+ {
+ "id" : "E",
+ "type": "T"
+ }
+ ],
+ "condition": {
+ "alterationTypes": [ "entityUpdate" ]
+ }
+ },
+ "notification": {
+ "http": {
+ "url": "http://127.0.0.1:'${LISTENER_PORT}'/notify"
+ }
+ }
+}'
+orionCurl --url /v2/subscriptions --payload "$payload"
+echo
+echo
+
+
+echo "02. Create E-A entity with JSON object (no notification)"
+echo "========================================================"
+payload='{
+ "id": "E",
+ "type": "T",
+ "A": {
+ "value": {
+ "text": "foo",
+ "number": 10,
+ "bool": true,
+ "null": null,
+ "array": [
+ "22",
+ {
+ "x" : [ "x1", "x2" ],
+ "y" : 3
+ },
+ [ "z1", "z2" ]
+ ],
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [ "y1", "y2" ]
+ }
+ },
+ "type": "Json"
+ }
+}'
+orionCurl --url /v2/entities --payload "$payload"
+echo
+echo
+
+
+echo "03. Update E-A entity with same JSON object (notification)"
+echo "=========================================================="
+payload='{
+ "A": {
+ "value": {
+ "text": "foo",
+ "number": 10,
+ "bool": true,
+ "null": null,
+ "array": [
+ "22",
+ {
+ "x" : [ "x1", "x2" ],
+ "y" : 3
+ },
+ [ "z1", "z2" ]
+ ],
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [ "y1", "y2" ]
+ }
+ },
+ "type": "Json"
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "04. Update E-A entity with different JSON object (notification)"
+echo "==============================================================="
+payload='{
+ "A": {
+ "value": {
+ "text": "foo",
+ "number": 10,
+ "bool": true,
+ "null": null,
+ "array": [
+ "22",
+ {
+ "x" : [ "x1", "x2" ],
+ "y" : 3
+ },
+ [ "z1", "z2" ]
+ ],
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [ "y1", "y_new" ]
+ }
+ },
+ "type": "Json"
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "05. Update E-A entity with JSON array (notification)"
+echo "===================================================="
+payload='{
+ "A": {
+ "value": [
+ "",
+ {
+ "x": [ "x1", "x2" ],
+ "y": "3"
+ },
+ [ "z1", "z2" ]
+ ],
+ "type": "Array"
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "06. Update E-A entity with same JSON array (notification)"
+echo "========================================================="
+payload='{
+ "A": {
+ "value": [
+ "",
+ {
+ "x": [ "x1", "x2" ],
+ "y": "3"
+ },
+ [ "z1", "z2" ]
+ ],
+ "type": "Array"
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "07. Update E-A entity with different JSON array (notification)"
+echo "=============================================================="
+payload='{
+ "A": {
+ "value": [
+ "",
+ {
+ "x": [ "x1", "x_new" ],
+ "y": "3"
+ },
+ [ "z1", "z2" ]
+ ],
+ "type": "Array"
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "08. Update E-A entity with same string (notification)"
+echo "====================================================="
+payload='{
+ "A": {
+ "value": "foo",
+ "type": "Text"
+ }
+}'
+orionCurl --url /v2/entities/E/attrs --payload "$payload"
+echo
+echo
+
+
+echo "09. Dump accumulator, see 6 notifications"
+echo "========================================="
+accumulatorDump
+echo
+echo
+
+
+--REGEXPECT--
+01. Create subscription covering E-A
+====================================
+HTTP/1.1 201 Created
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Location: /v2/subscriptions/REGEX([0-9a-f]{24})
+Content-Length: 0
+
+
+
+02. Create E-A entity with JSON object (no notification)
+========================================================
+HTTP/1.1 201 Created
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Location: /v2/entities/E?type=T
+Content-Length: 0
+
+
+
+03. Update E-A entity with same JSON object (notification)
+==========================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+04. Update E-A entity with different JSON object (notification)
+===============================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+05. Update E-A entity with JSON array (notification)
+====================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+06. Update E-A entity with same JSON array (notification)
+=========================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+07. Update E-A entity with different JSON array (notification)
+==============================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+08. Update E-A entity with same string (notification)
+=====================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+09. Dump accumulator, see 6 notifications
+=========================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 271
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {},
+ "type": "Json",
+ "value": {
+ "array": [
+ "22",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": 3
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ],
+ "bool": true,
+ "null": null,
+ "number": 10,
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [
+ "y1",
+ "y2"
+ ]
+ },
+ "text": "foo"
+ }
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 274
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {},
+ "type": "Json",
+ "value": {
+ "array": [
+ "22",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": 3
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ],
+ "bool": true,
+ "null": null,
+ "number": 10,
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [
+ "y1",
+ "y_new"
+ ]
+ },
+ "text": "foo"
+ }
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 162
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {},
+ "type": "Array",
+ "value": [
+ "",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": "3"
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ]
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 162
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {},
+ "type": "Array",
+ "value": [
+ "",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": "3"
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ]
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 165
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {},
+ "type": "Array",
+ "value": [
+ "",
+ {
+ "x": [
+ "x1",
+ "x_new"
+ ],
+ "y": "3"
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ]
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 124
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {},
+ "type": "Text",
+ "value": "foo"
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+
+
+--TEARDOWN--
+brokerStop CB
+dbDrop CB
+accumulatorStop
diff --git a/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_value_object_and_array_with_forcedUpdate.test b/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_value_object_and_array_with_forcedUpdate.test
new file mode 100644
index 0000000000..150035d985
--- /dev/null
+++ b/test/functionalTest/cases/4211_right_json_change_evaluation_in_subs/change_evaluation_value_object_and_array_with_forcedUpdate.test
@@ -0,0 +1,628 @@
+# Copyright 2023 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--
+Right JSON change evaluation in subs (objects and arrays in attribute value case with forcedUpdate)
+
+--SHELL-INIT--
+dbInit CB
+brokerStart CB
+accumulatorStart --pretty-print
+
+--SHELL--
+
+#
+# Same as change_evaluation_value_object_and_array.test but using forcedUpdate un update operations
+#
+#
+# 01. Create subscription covering E-A
+# 02. Create E-A entity with JSON object (notification)
+# 03. Update E-A entity with same JSON object (notification)
+# 04. Update E-A entity with different JSON object (notification)
+# 05. Update E-A entity with JSON array (notification)
+# 06. Update E-A entity with same JSON array (notification)
+# 07. Update E-A entity with different JSON array (notification)
+# 08. Update E-A entity with same string (notification)
+# 09. Dump accumulator, see 7 notifications
+#
+
+echo "01. Create subscription covering E-A"
+echo "===================================="
+payload='{
+ "subject": {
+ "entities": [
+ {
+ "id" : "E",
+ "type": "T"
+ }
+ ]
+ },
+ "notification": {
+ "http": {
+ "url": "http://127.0.0.1:'${LISTENER_PORT}'/notify"
+ }
+ }
+}'
+orionCurl --url /v2/subscriptions --payload "$payload"
+echo
+echo
+
+
+echo "02. Create E-A entity with JSON object (notification)"
+echo "====================================================="
+payload='{
+ "id": "E",
+ "type": "T",
+ "A": {
+ "value": {
+ "text": "foo",
+ "number": 10,
+ "bool": true,
+ "null": null,
+ "array": [
+ "22",
+ {
+ "x" : [ "x1", "x2" ],
+ "y" : 3
+ },
+ [ "z1", "z2" ]
+ ],
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [ "y1", "y2" ]
+ }
+ },
+ "type": "Json"
+ }
+}'
+orionCurl --url /v2/entities --payload "$payload"
+echo
+echo
+
+
+echo "03. Update E-A entity with same JSON object (notification)"
+echo "=========================================================="
+payload='{
+ "A": {
+ "value": {
+ "text": "foo",
+ "number": 10,
+ "bool": true,
+ "null": null,
+ "array": [
+ "22",
+ {
+ "x" : [ "x1", "x2" ],
+ "y" : 3
+ },
+ [ "z1", "z2" ]
+ ],
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [ "y1", "y2" ]
+ }
+ },
+ "type": "Json"
+ }
+}'
+orionCurl --url /v2/entities/E/attrs?options=forcedUpdate --payload "$payload"
+echo
+echo
+
+
+echo "04. Update E-A entity with different JSON object (notification)"
+echo "==============================================================="
+payload='{
+ "A": {
+ "value": {
+ "text": "foo",
+ "number": 10,
+ "bool": true,
+ "null": null,
+ "array": [
+ "22",
+ {
+ "x" : [ "x1", "x2" ],
+ "y" : 3
+ },
+ [ "z1", "z2" ]
+ ],
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [ "y1", "y_new" ]
+ }
+ },
+ "type": "Json"
+ }
+}'
+orionCurl --url /v2/entities/E/attrs?options=forcedUpdate --payload "$payload"
+echo
+echo
+
+
+echo "05. Update E-A entity with JSON array (notification)"
+echo "===================================================="
+payload='{
+ "A": {
+ "value": [
+ "",
+ {
+ "x": [ "x1", "x2" ],
+ "y": "3"
+ },
+ [ "z1", "z2" ]
+ ],
+ "type": "Array"
+ }
+}'
+orionCurl --url /v2/entities/E/attrs?options=forcedUpdate --payload "$payload"
+echo
+echo
+
+
+echo "06. Update E-A entity with same JSON array (notification)"
+echo "========================================================="
+payload='{
+ "A": {
+ "value": [
+ "",
+ {
+ "x": [ "x1", "x2" ],
+ "y": "3"
+ },
+ [ "z1", "z2" ]
+ ],
+ "type": "Array"
+ }
+}'
+orionCurl --url /v2/entities/E/attrs?options=forcedUpdate --payload "$payload"
+echo
+echo
+
+
+echo "07. Update E-A entity with different JSON array (notification)"
+echo "=============================================================="
+payload='{
+ "A": {
+ "value": [
+ "",
+ {
+ "x": [ "x1", "x_new" ],
+ "y": "3"
+ },
+ [ "z1", "z2" ]
+ ],
+ "type": "Array"
+ }
+}'
+orionCurl --url /v2/entities/E/attrs?options=forcedUpdate --payload "$payload"
+echo
+echo
+
+
+echo "08. Update E-A entity with same string (notification)"
+echo "====================================================="
+payload='{
+ "A": {
+ "value": "foo",
+ "type": "Text"
+ }
+}'
+orionCurl --url /v2/entities/E/attrs?options=forcedUpdate --payload "$payload"
+echo
+echo
+
+
+echo "09. Dump accumulator, see 7 notifications"
+echo "========================================="
+accumulatorDump
+echo
+echo
+
+
+--REGEXPECT--
+01. Create subscription covering E-A
+====================================
+HTTP/1.1 201 Created
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Location: /v2/subscriptions/REGEX([0-9a-f]{24})
+Content-Length: 0
+
+
+
+02. Create E-A entity with JSON object (notification)
+=====================================================
+HTTP/1.1 201 Created
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Location: /v2/entities/E?type=T
+Content-Length: 0
+
+
+
+03. Update E-A entity with same JSON object (notification)
+==========================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+04. Update E-A entity with different JSON object (notification)
+===============================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+05. Update E-A entity with JSON array (notification)
+====================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+06. Update E-A entity with same JSON array (notification)
+=========================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+07. Update E-A entity with different JSON array (notification)
+==============================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+08. Update E-A entity with same string (notification)
+=====================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+09. Dump accumulator, see 7 notifications
+=========================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 271
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {},
+ "type": "Json",
+ "value": {
+ "array": [
+ "22",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": 3
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ],
+ "bool": true,
+ "null": null,
+ "number": 10,
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [
+ "y1",
+ "y2"
+ ]
+ },
+ "text": "foo"
+ }
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 271
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {},
+ "type": "Json",
+ "value": {
+ "array": [
+ "22",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": 3
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ],
+ "bool": true,
+ "null": null,
+ "number": 10,
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [
+ "y1",
+ "y2"
+ ]
+ },
+ "text": "foo"
+ }
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 274
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {},
+ "type": "Json",
+ "value": {
+ "array": [
+ "22",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": 3
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ],
+ "bool": true,
+ "null": null,
+ "number": 10,
+ "object": {
+ "x": {
+ "x1": "a",
+ "x2": "b"
+ },
+ "y": [
+ "y1",
+ "y_new"
+ ]
+ },
+ "text": "foo"
+ }
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 162
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {},
+ "type": "Array",
+ "value": [
+ "",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": "3"
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ]
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 162
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {},
+ "type": "Array",
+ "value": [
+ "",
+ {
+ "x": [
+ "x1",
+ "x2"
+ ],
+ "y": "3"
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ]
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 165
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {},
+ "type": "Array",
+ "value": [
+ "",
+ {
+ "x": [
+ "x1",
+ "x_new"
+ ],
+ "y": "3"
+ },
+ [
+ "z1",
+ "z2"
+ ]
+ ]
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+POST http://127.0.0.1:REGEX(\d+)/notify
+Fiware-Servicepath: /
+Content-Length: 124
+User-Agent: orion/REGEX(\d+\.\d+\.\d+.*)
+Ngsiv2-Attrsformat: normalized
+Host: 127.0.0.1:REGEX(\d+)
+Accept: application/json
+Content-Type: application/json; charset=utf-8
+Fiware-Correlator: REGEX([0-9a-f\-]{36}); cbnotif=1
+
+{
+ "data": [
+ {
+ "A": {
+ "metadata": {},
+ "type": "Text",
+ "value": "foo"
+ },
+ "id": "E",
+ "type": "T"
+ }
+ ],
+ "subscriptionId": "REGEX([0-9a-f]{24})"
+}
+=======================================
+
+
+--TEARDOWN--
+brokerStop CB
+dbDrop CB
+accumulatorStop
diff --git a/test/functionalTest/cases/4435_ngsi_patching_special_attr_types/ngsi_patching_special_attr_types.test b/test/functionalTest/cases/4435_ngsi_patching_special_attr_types/ngsi_patching_special_attr_types.test
new file mode 100644
index 0000000000..8352a77b7b
--- /dev/null
+++ b/test/functionalTest/cases/4435_ngsi_patching_special_attr_types/ngsi_patching_special_attr_types.test
@@ -0,0 +1,255 @@
+# Copyright 2023 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--
+Custom notification NGSI patching special attr types
+
+--SHELL-INIT--
+dbInit CB
+brokerStart CB 0-255
+
+--SHELL--
+
+#
+# 01. Create custom subscription with ngsi patching with DateTime and geo:json
+# 02. Get subscription
+# 03. Update custom subscription with ngsi patching with DateTime and geo:json
+# 04. Get subscription
+#
+
+echo "01. Create custom subscription with ngsi patching with DateTime and geo:json"
+echo "============================================================================"
+payload='{
+ "description": "DateTime test",
+ "status": "active",
+ "subject": {
+ "entities": [
+ {
+ "idPattern": ".*",
+ "type": "NoiseLevelObserved"
+ }
+ ],
+ "condition": {
+ "attrs": [
+ "TimeInstant"
+ ],
+ "notifyOnMetadataChange": true
+ }
+ },
+ "notification": {
+ "attrs": [
+ "dateobservedto",
+ "mylocation"
+ ],
+ "onlyChangedAttrs": false,
+ "attrsFormat": "normalized",
+ "httpCustom": {
+ "url": "http://127.0.0.1:'${LISTENER_PORT}'/notify",
+ "ngsi": {
+ "dateobservedto": {
+ "type": "DateTime",
+ "value": "${TimeInstant}"
+ },
+ "mylocation": {
+ "type": "geo:json",
+ "value": "${location}"
+ }
+ }
+ }
+ }
+}'
+orionCurl --url /v2/subscriptions --payload "$payload"
+echo
+echo
+
+
+SUB_ID=$(echo "$_responseHeaders" | grep Location | awk -F/ '{ print $4 }' | tr -d "\r\n")
+
+
+echo "02. Get subscriptions"
+echo "====================="
+orionCurl --url /v2/subscriptions/$SUB_ID
+echo
+echo
+
+
+echo "03. Update custom subscription with ngsi patching with DateTime and geo:json"
+echo "============================================================================"
+payload='{
+ "notification": {
+ "attrs": [
+ "dateobservedto2",
+ "mylocation2"
+ ],
+ "onlyChangedAttrs": false,
+ "attrsFormat": "normalized",
+ "httpCustom": {
+ "url": "http://127.0.0.1:'${LISTENER_PORT}'/notify",
+ "ngsi": {
+ "dateobservedto2": {
+ "type": "DateTime",
+ "value": "${TimeInstant}"
+ },
+ "mylocation2": {
+ "type": "geo:json",
+ "value": "${location}"
+ }
+ }
+ }
+ }
+}'
+orionCurl --url /v2/subscriptions/$SUB_ID -X PATCH --payload "$payload"
+echo
+echo
+
+
+echo "04. Get subscriptions"
+echo "====================="
+orionCurl --url /v2/subscriptions/$SUB_ID
+echo
+echo
+
+
+--REGEXPECT--
+01. Create custom subscription with ngsi patching with DateTime and geo:json
+============================================================================
+HTTP/1.1 201 Created
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Location: /v2/subscriptions/REGEX([0-9a-f]{24})
+Content-Length: 0
+
+
+
+02. Get subscriptions
+=====================
+HTTP/1.1 200 OK
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Content-Type: application/json
+Content-Length: 524
+
+{
+ "description": "DateTime test",
+ "id": "REGEX([0-9a-f]{24})",
+ "notification": {
+ "attrs": [
+ "dateobservedto",
+ "mylocation"
+ ],
+ "attrsFormat": "normalized",
+ "covered": false,
+ "httpCustom": {
+ "ngsi": {
+ "dateobservedto": {
+ "type": "DateTime",
+ "value": "${TimeInstant}"
+ },
+ "mylocation": {
+ "type": "geo:json",
+ "value": "${location}"
+ }
+ },
+ "url": "http://127.0.0.1:9997/notify"
+ },
+ "onlyChangedAttrs": false
+ },
+ "status": "active",
+ "subject": {
+ "condition": {
+ "attrs": [
+ "TimeInstant"
+ ],
+ "notifyOnMetadataChange": true
+ },
+ "entities": [
+ {
+ "idPattern": ".*",
+ "type": "NoiseLevelObserved"
+ }
+ ]
+ }
+}
+
+
+03. Update custom subscription with ngsi patching with DateTime and geo:json
+============================================================================
+HTTP/1.1 204 No Content
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+
+
+
+04. Get subscriptions
+=====================
+HTTP/1.1 200 OK
+Date: REGEX(.*)
+Fiware-Correlator: REGEX([0-9a-f\-]{36})
+Content-Type: application/json
+Content-Length: 528
+
+{
+ "description": "DateTime test",
+ "id": "REGEX([0-9a-f]{24})",
+ "notification": {
+ "attrs": [
+ "dateobservedto2",
+ "mylocation2"
+ ],
+ "attrsFormat": "normalized",
+ "covered": false,
+ "httpCustom": {
+ "ngsi": {
+ "dateobservedto2": {
+ "type": "DateTime",
+ "value": "${TimeInstant}"
+ },
+ "mylocation2": {
+ "type": "geo:json",
+ "value": "${location}"
+ }
+ },
+ "url": "http://127.0.0.1:9997/notify"
+ },
+ "onlyChangedAttrs": false
+ },
+ "status": "active",
+ "subject": {
+ "condition": {
+ "attrs": [
+ "TimeInstant"
+ ],
+ "notifyOnMetadataChange": true
+ },
+ "entities": [
+ {
+ "idPattern": ".*",
+ "type": "NoiseLevelObserved"
+ }
+ ]
+ }
+}
+
+
+--TEARDOWN--
+brokerStop CB
+dbDrop CB
diff --git a/test/functionalTest/harnessFunctions.sh b/test/functionalTest/harnessFunctions.sh
index 08df1697f3..d1de8a684d 100644
--- a/test/functionalTest/harnessFunctions.sh
+++ b/test/functionalTest/harnessFunctions.sh
@@ -145,7 +145,7 @@ function dbInit()
fi
dMsg "database to drop: <$db>"
- echo 'db.dropDatabase()' | mongo mongodb://$host:$port/$db --quiet
+ mongosh mongodb://$host:$port/$db --eval 'db.dropDatabase()' --quiet
}
@@ -186,9 +186,9 @@ function dbList
if [ "$name" != "" ]
then
- echo show dbs | mongo mongodb://$host:$port --quiet | grep "$name" | awk '{ print $1 }'
+ mongosh mongodb://$host:$port --eval 'show dbs' --quiet | grep "$name" | awk '{ print $1 }'
else
- echo show dbs | mongo mongodb://$host:$port --quiet | awk '{ print $1 }'
+ mongosh mongodb://$host:$port --eval 'show dbs' --quiet | awk '{ print $1 }'
fi
}
@@ -212,7 +212,7 @@ function dbResetAll()
port="27017"
fi
- all=$(echo show dbs | mongo mongodb://$host:$port --quiet | grep ftest | awk '{ print $1 }')
+ all=$(mongosh mongodb://$host:$port --eval 'show dbs' --quiet | grep ftest | awk '{ print $1 }')
for db in $all
do
dbDrop $db
@@ -1040,17 +1040,7 @@ function valgrindSleep()
# ------------------------------------------------------------------------------
#
-# mongoCmd -
-#
-# This functions is needed due to some problems with jenkins that seems to avoid
-# the usage of 'mongo --quiet ...' directly. Thus, we need to use mongo without
-# --quiet, but we need to get rid of some preamble lines about mongo version and
-# connection information and a final 'bye' line
-#
-# NOTE: this will no longer work with new mongosh shell. Note that legacy shell
-# (the 'mongo' command) has been deprecated in MongoDB 5.0 and removed in MongoDB 6.0.
-# This function (and many .test using mongoCmd) would need fixing after stepping to
-# MongoDB 6.0
+# mongoCmd -
#
function mongoCmd()
{
@@ -1066,35 +1056,12 @@ function mongoCmd()
port="27017"
fi
- db=$1
- cmd=$2
- echo $cmd | mongo mongodb://$host:$port/$db | tail -n 2 | head -n 1
-}
-
-
-
-# ------------------------------------------------------------------------------
-#
-# mongoCmdLong - like mongoCmd but showing all the output, not just the last line.
-# Meant to be used in conjunction with 'grep'
-#
-function mongoCmdLong()
-{
- host="${CB_DATABASE_HOST}"
- if [ "$host" == "" ]
- then
- host="localhost"
- fi
-
- port="${CB_DATABASE_PORT}"
- if [ "$port" == "" ]
- then
- port="27017"
- fi
+ # Why to use EJSON.stringfiy() instead of JSON.stringfly()?
+ # See https://stackoverflow.com/q/77678898/1485926
db=$1
- cmd=$2
- echo $cmd | mongo mongodb://$host:$port/$db
+ cmd="EJSON.stringify($2)"
+ mongosh mongodb://$host:$port/$db --eval "$cmd" --quiet
}
@@ -1158,7 +1125,7 @@ function dbInsertEntity()
port="27017"
fi
- echo "$jsCode ; $ent ; $doc ; $cmd" | mongo mongodb://$host:$port/$db
+ mongosh mongodb://$host:$port/$db --eval "$jsCode ; $ent ; $doc ; $cmd" --quiet
}
@@ -1426,7 +1393,6 @@ export -f accumulator3Reset
export -f orionCurl
export -f dbInsertEntity
export -f mongoCmd
-export -f mongoCmdLong
export -f vMsg
export -f dMsg
export -f valgrindSleep
diff --git a/test/loadTest/cache_refresh/drop_database_mongo.sh b/test/loadTest/cache_refresh/drop_database_mongo.sh
index 1857640035..1a4d50fad2 100644
--- a/test/loadTest/cache_refresh/drop_database_mongo.sh
+++ b/test/loadTest/cache_refresh/drop_database_mongo.sh
@@ -19,7 +19,7 @@
#
# For those usages not covered by this license please contact with
# iot_support at tid dot es
-# author: 'Ivn Arias Len (ivan dot ariasleon at telefonica dot com)'
+# author: 'Iván Arias León (ivan dot ariasleon at telefonica dot com)'
if [ "$1" == "" ]
then
@@ -41,7 +41,7 @@ fi
-
+# FIXME: use mongosh instead of mongo
dbs=(`(echo 'show databases' | mongo --host $host) | grep $prefix`)
for db in ${dbs[@]};
do
diff --git a/test/loadTest/perf/csub_clean.sh b/test/loadTest/perf/csub_clean.sh
index 7d46460fe1..5701af6a86 100755
--- a/test/loadTest/perf/csub_clean.sh
+++ b/test/loadTest/perf/csub_clean.sh
@@ -19,4 +19,5 @@
# For those usages not covered by this license please contact with
# iot_support at tid dot es
+# FIXME: use mongosh instead of mongo
echo 'db.csubs.drop()' | mongo --quiet orion
diff --git a/test/valgrind/valgrindTestSuite.sh b/test/valgrind/valgrindTestSuite.sh
index ee817af3cc..ce1501235c 100755
--- a/test/valgrind/valgrindTestSuite.sh
+++ b/test/valgrind/valgrindTestSuite.sh
@@ -103,7 +103,7 @@ function vMsg()
# -----------------------------------------------------------------------------
#
-# If any mongo database ftest-ftest exists, strange memory leaks appear ...
+# If any MongoDB database ftest-ftest exists, strange memory leaks appear ...
# So, before starting, it's important to remove all ftest DBs
#
function dbReset()