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

Possible Bug in IoT Agent (tested only with iotagent-json) #401

Open
jicarretero opened this issue May 9, 2019 · 6 comments
Open

Possible Bug in IoT Agent (tested only with iotagent-json) #401

jicarretero opened this issue May 9, 2019 · 6 comments

Comments

@jicarretero
Copy link

jicarretero commented May 9, 2019

Let's Imagine I have an office (with a sensor providing humidity and temperature) and a car (with a sensor providing speed and fuel). The default API Key is "1234". So I provision two groups:

curl -X POST \
  http://${IOTAGENT_IP}:4041/iot/services \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/json' \
  -H 'fiware-service: car' \
  -H 'fiware-servicepath: /car_measurement' \
  -d '{
    "services": [
        {
          "apikey":      "1234",
          "entity_type": "thing",
          "resource":    "/iot/car"
        }
    ]
}'

curl -X POST \
  http://${IOTAGENT_IP}:4041/iot/services \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/json' \
  -H 'fiware-service: office' \
  -H 'fiware-servicepath: /office_measurement' \
  -d '{
    "services": [
        {
          "apikey":      "1234",
          "entity_type": "thing",
          "resource":    "/iot/office"
        }
    ]
}'

Each group with one sensor:

curl -X POST \
  http://${IOTAGENT_IP}:4041/iot/devices \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/json' \
  -H 'fiware-service: car' \
  -H 'fiware-servicepath: /car_measurement' \
  -d '{
    "devices": [
        {
            "device_id": "car0001",
            "entity_name": "car0001",
            "entity_type": "thing",
            "attributes": [
                  {"object_id": "s", "name": "speed", "type": "Float"},
                  {"object_id": "f", "name": "fuel", "type": "Float"}
            ]
        }
    ]
}'

curl -X POST \
  http://${IOTAGENT_IP}:4041/iot/devices \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/json' \
  -H 'fiware-service: office' \
  -H 'fiware-servicepath: /office_measurement' \
  -d '{
    "devices": [
        {
            "device_id": "office0001",
            "entity_name": "office0001",
            "entity_type": "thing",
            "attributes": [
                  {"object_id": "h", "name": "humidity", "type": "Float"},
                  {"object_id": "t", "name": "temperature", "type": "Float"}
            ]
        }
    ]
}'

And I POST data to the second device (office) with this error:

curl -X POST \
  "http://${IOTAGENT_IP}:1884/iot/d?i=office0001&k=1234" \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/json' \
  -H 'fiware-service: office' \
  -H 'fiware-servicepath: /office_measurement' \
  -d '{
     "h": 57.0,
     "t": 24.3
}'

The response is:
{"name":"DEVICE_NOT_FOUND","message":"No device was found with id:thing:office0001"}

So, I try to find out why looking at the queries in MongoDB:
1. find { find: "groups", filter: { apikey: "1234" }, projection: { __v: 0 }, limit: 1, ...

The answer is (but it shouldn't be this one):
{ "_id" : ObjectId("5cd3fe60e6e14c017af932a8"), "resource" : "/iot/car", "apikey" : "1234", "type" : "thing", "service" : "car", "subservice" : "/car_measurement", "__v" : 0 }

2. find { find: "devices", filter: { id: "office0001", service: "car", subservice: "/car_measurement" }
That query is not the one that should be made, it doesn't correspond to my POST!!!

At this time I have a new Device in IoT Database (That I don't know why it is there), without Objects:
And I have a new device in my MongoDB:
{ "_id" : ObjectId("5cd4016fe6e14c017af932ac"), "subscriptions" : [ ], "creationDate" : ISODate("2019-05-09T10:31:11.301Z"), "id" : "office0001", "type" : "thing", "name" : "thing:office0001", "service" : "car", "subservice" : "/car_measurement", "transport" : "HTTP", "__v" : 0 }

@fgalan
Copy link
Member

fgalan commented May 9, 2019

Could you repeat the test using different api keys for the service? For instance:

        {
          "apikey":      "1234",
          "entity_type": "thing",
          "resource":    "/iot/car"
        }
        {
          "apikey":      "5678",
          "entity_type": "thing",
          "resource":    "/iot/office"
        }

In order to see if the problem also happens in this case.

@jicarretero
Copy link
Author

No, in this case, it works. The problem is the "apikey" which is queried before doing anything. If I have 2 groups with same apikey, it will always get the first one, since the 1st query to MongoDB is (as I explained before):

  • find { find: "groups", filter: { apikey: "1234" }, projection: { __v: 0 }, limit: 1, ...

However, May the IoTAgent be using a "Document Database" like MongoDB as some kind of relational database. Why not adding to the documents in the "device" collection the "resource" and "apiKey" fileds from the group collection and perform just one query on the device to MongoDB instead of the 3 that are currently happening (groups, devices, groups again)?

@fgalan
Copy link
Member

fgalan commented Jun 26, 2019

Which version of the IOTA agent did you use in your tests, please?

@AlvaroVega
Copy link
Member

And I POST data to the second device (office) with this error:

curl -X POST
"http://${IOTAGENT_IP}:1884/iot/d?i=office0001&k=1234"
-H 'cache-control: no-cache'
-H 'content-type: application/json'
-H 'fiware-service: office'
-H 'fiware-servicepath: /office_measurement'
-d '{
"h": 57.0,
"t": 24.3
}'

The response is:
{"name":"DEVICE_NOT_FOUND","message":"No device was found with id:thing:office0001"}

Probably is not found due to that POST does not contain a proper resource (that should be /iot/office), and agent is looking with default resource (/iot/d) and that apikey.

@fgalan
Copy link
Member

fgalan commented Jun 26, 2019

We have included recently some improvements related to apiKey management in the library (https://github.com/telefonicaid/iotagent-node-lib/blob/master/CHANGES_NEXT_RELEASE#L1):

ADD to use apikey to search group configuration at device registration time

Maybe it is not related with this problem but I'd recommend to use last version (fiware/iota-json:latest should work, as it bring lastest from library also) an test with it.

@fgalan
Copy link
Member

fgalan commented Jun 26, 2019

Anyway, looking to the queries you cite:

 1. find { find: "groups", filter: { apikey: "1234" }, projection: { __v: 0 }, limit: 1, ...

I think that if the query would include also the resource, i.e:

 1. find { find: "groups", filter: { apikey: "1234", resource: "xxxxx" }, projection: { __v: 0 }, limit: 1, ...

it will work

Note that according to model (https://github.com/telefonicaid/iotagent-node-lib/blob/master/lib/model/Group.js#L47) the combination of apiKey + resource is unique, so that query always return the right document, by definiton.

The problem here is how to get the resource. In theory the URL path can be taken as resource. So if the request is for instance POST http://${IOTAGENT_IP}:1884/iot/d?i=office0001&k=1234 then resource is "/iot/d". However, I think that appart of the default resource (especified in config.js/envars, using to be /iot/d for UL or /iot/json for JSON) current IOTAs doesn't start other endpoint to receive measures in the southbound (and it is not trivial, as it needs dynamically create/remove express routes for each resource as new services are provissioned/removed).

As workaround: ensure that all you services has different apiKeys and it should work.

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

No branches or pull requests

3 participants