Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Orion container crashes when user tries to add data to an entity that doesnt exist. #1714

Closed
AizenvoltPrime opened this issue Nov 29, 2024 · 22 comments

Comments

@AizenvoltPrime
Copy link

services:
    orion:
        labels:
            org.fiware: "tutorial"
        image: fiware/orion-ld:${ORION_LD_VERSION}
        hostname: orion
        container_name: fiware-orion
        depends_on:
            - mongo-db
        networks:
            - default
        ports:
            - "${ORION_LD_PORT}:${ORION_LD_PORT}"
        command: -dbhost mongo-db -logLevel DEBUG -forwarding -mongocOnly -wip entityMaps
        healthcheck:
            test: curl --fail -s http://orion:${ORION_LD_PORT}/version || exit 1
            interval: 5s

    # Quantum Leap is persisting Short Term History to Crate-DB
    quantumleap:
        image: orchestracities/quantumleap:${QUANTUMLEAP_VERSION}
        labels:
            org.fiware: "tutorial"
        hostname: quantumleap
        container_name: fiware-quantumleap
        ports:
            - "${QUANTUMLEAP_PORT}:${QUANTUMLEAP_PORT}"
        depends_on:
            - crate-db
            - redis-db
        environment:
            - CRATE_HOST=crate-db
            - REDIS_HOST=redis-db
            - REDIS_PORT=${REDIS_PORT}
            - REDIS_USERNAME=${REDIS_USERNAME}
            - REDIS_PASSWORD=${REDIS_PASSWORD}
            - LOGLEVEL=DEBUG
        healthcheck:
            test: curl --fail -s http://quantumleap:${QUANTUMLEAP_PORT}/version || exit 1

    # Databases
    mongo-db:
        labels:
            org.fiware: "tutorial"
        image: mongo:${MONGO_DB_VERSION}
        hostname: mongo-db
        container_name: db-mongo
        expose:
            - "${MONGO_DB_PORT}"
        ports:
            - "${MONGO_DB_PORT}:${MONGO_DB_PORT}" # localhost:27017
        networks:
            - default
        volumes:
            - mongo-db:/data
        healthcheck:
            test:
                [
                    "CMD",
                    "mongo",
                    "--quiet",
                    "127.0.0.1/test",
                    "--eval",
                    "'quit(db.runCommand({ ping: 1 }).ok ? 0 : 2)'",
                ]
            interval: 5s

    crate-db:
        labels:
            org.fiware: "tutorial"
        image: crate:${CRATE_VERSION}
        hostname: crate-db
        container_name: db-crate
        networks:
            - default
        ports:
            # Admin UI
            - "4200:4200"
            # Transport protocol
            - "4300:4300"
        command: crate -Cauth.host_based.enabled=false  -Ccluster.name=democluster -Chttp.cors.enabled=true -Chttp.cors.allow-origin="*" -Cdiscovery.type=single-node
        environment:
            - CRATE_HEAP_SIZE=2g # see https://crate.io/docs/crate/howtos/en/latest/deployment/containers/docker.html#troubleshooting
        volumes:
            - crate-db:/data

    redis-db:
        labels:
            org.fiware: "tutorial"
        image: redis:${REDIS_VERSION}
        hostname: redis-db
        container_name: db-redis
        networks:
            - default
        ports:
            - "${REDIS_PORT}:${REDIS_PORT}"
        volumes:
            - redis-db:/data
            - ./redis.conf:/usr/local/etc/redis/redis.conf
        command: redis-server /usr/local/etc/redis/redis.conf
        environment:
            - REDIS_USERNAME=${REDIS_USERNAME}
            - REDIS_PASSWORD=${REDIS_PASSWORD}
        healthcheck:
            test: >
                sh -c 'export REDISCLI_AUTH="${REDIS_PASSWORD}" &&
                redis-cli -h redis-db -p ${REDIS_PORT} --user ${REDIS_USERNAME} ping'
            interval: 10s


networks:
    default:
        labels:
            org.fiware: "tutorial"
        ipam:
            config:
                - subnet: 172.18.1.0/24

volumes:
    mongo-db: ~
    crate-db: ~
    redis-db: ~

Also for the variables in docker compose:
ORION_LD_PORT=1026
ORION_LD_VERSION=1.7.0
QUANTUMLEAP_VERSION=1.0.0
QUANTUMLEAP_PORT=8668
CRATE_VERSION=latest
MONGO_DB_PORT=27017
MONGO_DB_VERSION=latest
REDIS_PORT=6380
REDIS_VERSION=6
for REDIS_USERNAME and REDIS_PASSWORD put whatever

If you just start all the containers and then try to add data to an entity that doesnt exist the orion container crashes. You could say I could run a cron job to check if the orion container stopped working for some reason and work around this issue but I dont think the intended functionality is for the container to crash every time someone does a wrong request. This was how I discovered the other issue with subscriptions I posted last week.

curl --location 'http://SERVER_IP:1026/ngsi-ld/v1/entities/urn:ngsi-ld:test_entity_id/attrs' \
--header 'Content-Type: application/ld+json' \
--header 'NGSILD-Tenant: openiot' \
--data-raw '{
    "temperature": {
        "type": "Property",
        "value": 2.5
    },
    "@context": {
        "temperature": "https://iemis-demo.indigital.gr/api/ngsi-ld-attributes/temperature"
    }
}
'
@kzangeli kzangeli self-assigned this Nov 29, 2024
@kzangeli
Copy link
Collaborator

That sounds like an old issue Infixed some time ago.
Is it an entity that is registered "elsewhere" but doesn't exist locally?

What is the tag of the broker? (not clear ...)

@AizenvoltPrime
Copy link
Author

AizenvoltPrime commented Nov 29, 2024

No, just think of the example I gave you on the subscriptions issue, where you skip the entity creation and subscription requests and just do the add data when the entity and subscriptions dont exist yet. In the app I am developing I have made a frontend form for users to create orion entities for iot devices dynamically and I discovered that issue in the process of developing the app. I don't think that it was intended for the container to crash if somehow, because of a bug in code a wrong post request was made.

@kzangeli
Copy link
Collaborator

Ok.
There is a known bug in the "/attrs" service.
I haven't spent any time on it as that API endpoint is to be deprecated soon (the sooner the better).

Try PATCH /entities/[entityId].
Definitely preferable.
Also, if you can, please stop using application/ld+json.
It only gives the broker unnecessary work and extra code to execute

@AizenvoltPrime
Copy link
Author

AizenvoltPrime commented Nov 29, 2024

Ok I will try to add data using PATCH then. In regards to the application/ld+json, I tried doing something like

curl --location 'http://SERVER_IP:1026/ngsi-ld/v1/entities/' \
--header 'Content-Type: application/json' \
--header 'NGSILD-Tenant: openiot' \
--header 'Link: <https://mysite.com/api/ngsi-ld-attributes>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
--data '{
  "id": "urn:ngsi-ld:test_entity_id2",
  "type": "test_entity_type",
  "temperature": {
    "type": "Property",
    "value": 23.4
  }
}'

the link has content like:

{
  "@context": {
    "attributes": "https://mysite.com/api/ngsi-ld-attributes/",
    "temperature": { "@id": "attributes:temperature", "@type": "xsd:float", "unit": "°C", "en": "Temperature", "el": "Θερμοκρασία" },
    "humidity": { "@id": "attributes:humidity", "@type": "xsd:integer", "unit": "%", "en": "Humidity", "el": "Υγρασία" }
  }
}

but the entities dont get saved correctly in mongo. They look like:

{
  "_id": {
    "id": "urn:ngsi-ld:test_entity_id",
    "type": "https://uri.etsi.org/ngsi-ld/default-context/test_entity_type",
    "servicePath": "/"
  },
  "attrNames": [
    "https://uri.etsi.org/ngsi-ld/attributestemperature"
  ],
  "attrs": {
    "https://uri=etsi=org/ngsi-ld/attributestemperature": {
      "type": "Property",
      "creDate": 1732901606.1755981,
      "modDate": 1732901606.1755981,
      "value": 23.4,
      "mdNames": []
    }
  },
  "creDate": 1732901606.1755981,
  "modDate": 1732901606.1755981,
  "lastCorrelator": ""
}

when they should be like:

{
  "_id": {
    "id": "urn:ngsi-ld:test_entity_id",
    "type": "https://uri.etsi.org/ngsi-ld/default-context/test_entity_type",
    "servicePath": "/"
  },
  "attrNames": [
    "https://mysite.com/api/ngsi-ld-attributes/temperature"
  ],
  "attrs": {
    "https://mysite=com/api/ngsi-ld-attributes/temperature": {
      "type": "Property",
      "creDate": 1732901686.2456894,
      "modDate": 1732901686.2456894,
      "value": 23.4,
      "mdNames": []
    }
  },
  "creDate": 1732901686.2456894,
  "modDate": 1732901686.2456894,
  "lastCorrelator": ""
}

which is done with the initial way I create entities that I showed in the example above.

@kzangeli
Copy link
Collaborator

kzangeli commented Dec 2, 2024

ok, that's funny ...

The long name "https://uri.etsi.org/ngsi-ld/attributes" is part of the core context. Its short name is "attributes".
The expansion you have "accomplished" :) would be done with "prefix expansion".

But, only if you use the attribute name "attributes:temperature".
Well, either that or you've found a bug in the broker.

Show me the exact URL, payload body, and headers you used when creating this entity.
If this is a bug, I'd need to be able to reproduce the error.

@AizenvoltPrime
Copy link
Author

AizenvoltPrime commented Dec 2, 2024

This is the exact post request I make to create an entity using the method you suggested:

curl --location 'http://SERVER_IP:1026/ngsi-ld/v1/entities/' \
--header 'Content-Type: application/json' \
--header 'NGSILD-Tenant: openiot' \
--header 'Link: <https://mysite.com/api/ngsi-ld-attributes>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
--data '{
  "id": "urn:ngsi-ld:test_entity_id2",
  "type": "test_entity_type",
  "temperature": {
    "type": "Property",
    "value": 23.4
  }
}

the only real difference is the server IP which is something like 11.100.0.35
and the link which instead of mysite it has the name of the domain.

the link with the context I mentioned in my previous response

{
  "@context": {
    "attributes": "https://mysite.com/api/ngsi-ld-attributes/",
    "temperature": { "@id": "attributes:temperature", "@type": "xsd:float", "unit": "°C", "en": "Temperature", "el": "Θερμοκρασία" },
    "humidity": { "@id": "attributes:humidity", "@type": "xsd:integer", "unit": "%", "en": "Humidity", "el": "Υγρασία" }
  }
}

has real data, the only difference is I have even more context attributes on my real link but thats it.

@kzangeli
Copy link
Collaborator

kzangeli commented Dec 2, 2024

And, in that context (https://mysite.com/api/ngsi-ld-attributes), "temperature" is present, with the long name that is already mentioned.
ok, good, I'll try to reproduce. If I'm successful to reproduce, the fix is typically quite simple.

@kzangeli
Copy link
Collaborator

kzangeli commented Dec 2, 2024

Ah, that last piece of information was interesting.
Be careful with terms from the core context. "attributes" is part of the core context.
So, this prefix expansion you're trying to accomplish will take the long name of "attributes" from the core context.
Hence the unwanted expansion.
All should work if you change your context to:

{
  "@context": {
    "myAttributes": "https://mysite.com/api/ngsi-ld-attributes/",
    "temperature": { "@id": "myAttributes:temperature", "@type": "xsd:float", "unit": "°C", "en": "Temperature", "el": "Θερμοκρασία" },
    "humidity": { "@id": "myAttributes:humidity", "@type": "xsd:integer", "unit": "%", "en": "Humidity", "el": "Υγρασία" }
  }
}```

Also, FYI, the terms "unit", "en" and "el" you define in the context are ignored by Orion-LD.
Sorry about that ...
It's a partial implementation of JSON-LD.

@AizenvoltPrime
Copy link
Author

Still face the same problem:

{
    "@context": {
        "myAttributes": "https://iemis-demo.indigital.gr/api/ngsi-ld-attributes/",
        "temperature": {
            "@id": "myAttributes::temperature",
            "@type": "xsd:float",
            "unit": "°C",
            "en": "Temperature",
            "el": "Θερμοκρασία"
        },
        "humidity": {
            "@id": "myAttributes::humidity",
            "@type": "xsd:integer",
            "unit": "%",
            "en": "Humidity",
            "el": "Υγρασία"
        }
       }
     }

with post request the same as before it saves the entity like:

{
  "_id": {
    "id": "urn:ngsi-ld:test_entity_id",
    "type": "https://uri.etsi.org/ngsi-ld/default-context/test_entity_type",
    "servicePath": "/"
  },
  "attrNames": [
    "https://uri.etsi.org/ngsi-ld/attributestemperature"
  ],
  "attrs": {
    "https://uri=etsi=org/ngsi-ld/attributestemperature": {
      "type": "Property",
      "creDate": 1733134465.8185349,
      "modDate": 1733134465.8185349,
      "value": 23.4,
      "mdNames": []
    }
  },
  "creDate": 1733134465.8185349,
  "modDate": 1733134465.8185349,
  "lastCorrelator": ""
}

@kzangeli
Copy link
Collaborator

kzangeli commented Dec 2, 2024

That's not possible! :)
My guess is that your old @context is still in the broker.
Or, the old entity is still there and the intent to create it again got a 409 ?
Something is wrong here, no doubt.

The "link" between "temperature" and "attributes" of the core context is still there, and it should not be.

@AizenvoltPrime
Copy link
Author

AizenvoltPrime commented Dec 2, 2024

ok fixed it. It turns out when using link it downloaded the context and saved it in mongo db. I had to manually delete it. One question, if I add more attributes to the context after I have used it to create an entity will it redownload it and save it to mongo?

Also is this normal:

{
  "_id": {
    "id": "urn:ngsi-ld:test_entity_id",
    "type": "https://uri.etsi.org/ngsi-ld/default-context/test_entity_type",
    "servicePath": "/"
  },
  "attrNames": [
    "https:\\/\\/mysite=com\\/api\\/ngsi-ld-attributes\\/temperature"
  ],
  "attrs": {
    "https:\\/\\/mysite=com\\/api\\/ngsi-ld-attributes\\/temperature": {
      "type": "Property",
      "creDate": 1733135660.858967,
      "modDate": 1733135660.858967,
      "value": 23.4,
      "mdNames": []
    }
  },
  "creDate": 1733135660.858967,
  "modDate": 1733135660.858967,
  "lastCorrelator": ""
}

I mean the way it saved the url

cause with the old method it saved it like:

{
  "_id": {
    "id": "urn:ngsi-ld:test_entity_id",
    "type": "https://uri.etsi.org/ngsi-ld/default-context/test_entity_type",
    "servicePath": "/"
  },
  "attrNames": [
    "https://mysite.com/api/ngsi-ld-attributes/temperature"
  ],
  "attrs": {
    "https://mysite=com/api/ngsi-ld-attributes/temperature": {
      "type": "Property",
      "creDate": 1732901686.2456894,
      "modDate": 1732901686.2456894,
      "value": 23.4,
      "mdNames": []
    }
  },
  "creDate": 1732901686.2456894,
  "modDate": 1732901686.2456894,
  "lastCorrelator": ""
}

@kzangeli
Copy link
Collaborator

kzangeli commented Dec 2, 2024

It turns out when using link it downloaded the context and saved it in mongo db. I had to manually delete it

Yes, that's what I was referring to when saying it was using the old context.
That explains everything.

@kzangeli
Copy link
Collaborator

kzangeli commented Dec 2, 2024

I had to manually delete it. One question, if I add more attributes to the context after I have used it to create an entity will it redownload it and save it to mongo?

The whole idea behind the context cache is to avoid to re-download what I already have. That's an extremely slow operation.

Look into the API endpoints fro /ngsi-ld/v1/jsonldContexts.
There are options to reload contexts.
Just, always user driven. The broker will just look up the URL in its context cache and use it if found.
If not found, it will download the context and add it to the cache.

@kzangeli
Copy link
Collaborator

kzangeli commented Dec 2, 2024

I looked up the service routine (endpoint) for you (much easier for me).

Try this:

 DELETE /ngsi-ld/v1/jsonldContexts/<id of your context>?reload=true

That operation is supposed to reload your context and persist the new content under the same context.

@AizenvoltPrime
Copy link
Author

Thanks for the info and the time.

@kzangeli
Copy link
Collaborator

kzangeli commented Dec 2, 2024

Very happy to help :)
When you're 100% happy with the help, please go ahead and close this issue.

@AizenvoltPrime
Copy link
Author

AizenvoltPrime commented Dec 2, 2024

I tried:
curl --location --request DELETE 'http://SERVER_IP:1026/ngsi-ld/v1/jsonldContexts/fdabaae4-b098-11ef-b78e-0242ac120106?reload=true'

where this fdabaae4-b098-11ef-b78e-0242ac120106 is the _id of the mongo entity that has the downloaded context but it wasnt deleted

@kzangeli
Copy link
Collaborator

kzangeli commented Dec 2, 2024

The Entity itself will not be deleted.
This service reloads the context, at whatever URL it resides. It gets deleted, then re-downloaded and put back in the context cash..
You can then GET the context and make sure it has been updated.

No entity will be touched

@AizenvoltPrime
Copy link
Author

AizenvoltPrime commented Dec 2, 2024

There is another bug I found regarding the method of creating entities with link.

Here are my requests:

Create entity:

curl --location 'http://SERVER_IP:1026/ngsi-ld/v1/entities/' \
--header 'Content-Type: application/json' \
--header 'NGSILD-Tenant: openiot' \
--header 'Link: <https://mysite.com/api/ngsi-ld-attributes>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
--data '{
  "id": "urn:ngsi-ld:test_entity_id",
  "type": "test_entity_type",
  "temperature": {
    "type": "Property",
    "value": 23.4
  }
}'

Create subscription:

curl --location 'http://SERVER_IP:1026/ngsi-ld/v1/subscriptions/' \
--header 'Content-Type: application/json' \
--header 'NGSILD-Tenant: openiot' \
--header 'Link: <https://mysite.com/api/ngsi-ld-attributes>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
--data '{
  "description": "Notify QuantumLeap of changes to test_entity_type",
  "type": "Subscription",
  "entities": [
    {
      "id": "urn:ngsi-ld:test_entity_id",
      "type": "test_entity_type"
    }
  ],
  "watchedAttributes": ["temperature"],
  "notification": {
    "attributes": ["temperature"],
    "format": "normalized",
    "endpoint": {
      "uri": "http://quantumleap:8668/v2/notify",
      "accept": "application/json",
      "receiverInfo": [
        {
          "key": "fiware-service",
          "value": "openiot"
        }
      ]
    }
  }
}'

the entity in mongo is saved like:

{
  "_id": {
    "id": "urn:ngsi-ld:test_entity_id",
    "type": "https://uri.etsi.org/ngsi-ld/default-context/test_entity_type",
    "servicePath": "/"
  },
  "attrNames": [
    "https:\\/\\/mysite.com\\/api\\/ngsi-ld-attributes\\/temperature"
  ],
  "attrs": {
    "https:\\/\\/mysite=com\\/api\\/ngsi-ld-attributes\\/temperature": {
      "type": "Property",
      "creDate": 1733158754.530026,
      "modDate": 1733158754.530026,
      "value": 23.4,
      "mdNames": []
    }
  },
  "creDate": 1733158754.530026,
  "modDate": 1733158754.530026,
  "lastCorrelator": ""
}

The problems start after I try to patch:

curl --location --request PATCH 'http://SERVER_IP:1026/ngsi-ld/v1/entities/urn:ngsi-ld:test_entity_id/' \
--header 'Content-Type: application/json' \
--header 'NGSILD-Tenant: openiot' \
--header 'Link: <https://mysite.com/api/ngsi-ld-attributes>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
--data '{
    "temperature": {
        "type": "Property",
        "value": 3.5
    }
}'

the mongo entity changes to:

{
  "_id": {
    "id": "urn:ngsi-ld:test_entity_id",
    "type": "https://uri.etsi.org/ngsi-ld/default-context/test_entity_type",
    "servicePath": "/"
  },
  "attrNames": [
    "https:\\/\\/mysite.com\\/api\\/ngsi-ld-attributes\\/temperature",
    "https:\\/\\/mysite.com\\/api\\/ngsi-ld-attributes\\/temperature"
  ],
  "attrs": {
    "https:\\/\\/iemis-demo=indigital=gr\\/api\\/ngsi-ld-attributes\\/temperature": {
      "type": "Property",
      "creDate": 1733159022.6124334,
      "modDate": 1733159022.6124334,
      "value": 12.5,
      "mdNames": []
    }
  },
  "creDate": 1733158754.530026,
  "modDate": 1733159022.6124334,
  "lastCorrelator": ""
}

notice how the attr names became 2:

 "https:\\/\\/mysite.com\\/api\\/ngsi-ld-attributes\\/temperature",
 "https:\\/\\/mysite.com\\/api\\/ngsi-ld-attributes\\/temperature"

Also if I patch again they will become 3 attr names instead of remaining one unique for each attribute like it happened with the old method of creating entities. I just wanted to replace with the latest value.

@kzangeli
Copy link
Collaborator

kzangeli commented Dec 2, 2024

Wow, weird things are happening to you!!! :))
How do you get those backslashes into the expanded names?
Must be from the context.
"attributes" is expanded using the context, so, show me again the context you're using.
There's really no other way to get this weird behaviour.
Well, or there is a bug, which frankly I doubt. The broker doesn't insert backslashes, as far as I can remember.

@kzangeli
Copy link
Collaborator

kzangeli commented Dec 2, 2024

There is another bug I found regarding the method of creating entities with link.

It's not about the mechanism of giving the context.
Via HTTP header or inside the payload body, doesn't matter.
There are advantages using the Link header instead of inline contexts inside the payload body.
But, after extracting the URL from the body, the source code is the exact same (naturally).

@AizenvoltPrime
Copy link
Author

AizenvoltPrime commented Dec 2, 2024

The context is like this:

{
    "@context": {
        "myAttributes": "https://mysite.com/api/ngsi-ld-attributes/",
        "temperature": {
            "@id": "myAttributes:temperature",
            "@type": "xsd:float",
            "unit": "°C",
            "en": "Temperature",
            "el": "Θερμοκρασία"
        },
        "humidity": {
            "@id": "myAttributes:humidity",
            "@type": "xsd:integer",
            "unit": "%",
            "en": "Humidity",
            "el": "Υγρασία"
        }
     }
  }

Also regarding the patch request I mentioned. Is creating duplicate entries in "attrNames": [ an intented functionality every time a patch request is made?
Another question about the

curl --location --request DELETE 'http://SERVER_IP:1026/ngsi-ld/v1/jsonldContexts/fdabaae4-b098-11ef-b78e-0242ac120106?reload=true'

I noticed and you mentioned it as well that the mongo entity of context doesnt change from the original one after running the delete request. The attributes that were added to the context after the initial load are expanded correctly after I update the context in the site page and run the delete request. The problem I have is since the mongo db entity for context doesnt change that means if orion container stops or is deleted the attributes that were added to the context after the initial download wont be included in the context anymore and if I try to create a new entity with those attributes without reloading the context again they wont have the correct url. Is there a way to force orion to recreate the context entity in mongo as well as refreshing its context cache? If there isn't I guess I have to go back to the previous way of creating entities without link because my context is dynamic since users in my app can add attributes to the context when they create a new entity that has an attribute that doesnt exist in the context. The old method didn't have any of these problems like the backslashes in link, the duplicate entries in attrNames array that get added every time on patch and also the problem with the context that there isn't a way to recreate the mongo entity after initial download and that means that if orion container stops then the additional context is lost and needs to be reloaded manually,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants