After some hours spent reading Zabbix Api's documentation, I haven't found a way of doing a search by key with more than one possible value.
So, with this code:
{
"jsonrpc": "2.0",
"method": "item.get",
"params": {
"output": "extend",
"hostids": " 10355",
"search": {
"key_": "[in_*|out_*]"
},
"sortfield": "name"
},
"auth": "15729708df1f5936f6ea840ae1b41cb6",
"id": 0
}
I'm trying to get every item which key is in_<anything> OR out_<anything> so, the output would be the combination of all the items related to the interfaces. Instead, I get this:
{"jsonrpc":"2.0","result":[],"id":0}
I know that there's the possibility to use filter instead of search but, from what I read, it is used when you want exact match, which is not the case.
Zabbix API (and filtering in other places) does not support regexp. In some versions you could pass wildcards, but that won't solve your current issue. You will have to do two separate API queries.
To answer the question in the comment here, search can be negated with the excludeSearch parameter - see the API documentation for more detail.
To this work you need put this key searchWildcardsEnabled
{
"jsonrpc": "2.0",
"method": "item.get",
"params": {
"output": "extend",
"hostids": " 10355",
"searchWildcardsEnabled": "true",
"search": {
"key_": "[in_*|out_*]"
},
"sortfield": "name"
},
"auth": "15729708df1f5936f6ea840ae1b41cb6",
"id": 0
}
I think you should consider using the searchByAny parameter that let's you find items that matchs any of the search criteria. Here is the correct json that you should try :
{
"jsonrpc": "2.0",
"method": "item.get",
"params": {
"output": "extend",
"hostids": " 10355",
"searchWildcardsEnabled": "true",
"search": {
"key_": [
"in_*",
"out_*"
]
},
"sortfield": "name"
},
"auth": "15729708df1f5936f6ea840ae1b41cb6",
"id": 1
}
Related
I have noticed that upon querying Orion CB, while it is working with provisioned devices and having IoT Agent receive HTTP and MQTT messages, it will always output all the values written in the quotation marks:
{
"id": "sensor_data",
"type": "Sensor",
"ActiveTime": {
"type": "Seconds",
"value": "17703",
"metadata": {
"TimeInstant": {
"type": "ISO8601",
"value": "2018-07-04T13:32:27.357Z"
}
}
},
"Distance": {
"type": "Number",
"value": "312",
"metadata": {
"TimeInstant": {
"type": "ISO8601",
"value": "2018-07-04T13:32:27.413Z"
}
}
}
}
However, if to work with only entities in Orion CB, it is possible to receive actual values (like in the example in the manual):
{
"id": "Room1",
"pressure": {
"metadata": {},
"type": "Integer",
"value": 720
},
"temperature": {
"metadata": {},
"type": "Float",
"value": 23
},
"type": "Room"
}
Sometimes, I need to receive the actual value from my sensor in order to format it and use in further applications, but they are in quotation marks, which makes it a little difficult.
Is it possible to somehow change?(maybe in device provisioning), or it really should be that way regarding devices?
Thanks in advance!
EDIT 1
This is the way I provisioned the device:
{
"devices": [
{
"device_id": "sensor_data",
"entity_name": "sensor_data",
"entity_type": "Sensor",
"transport": "MQTT",
"timezone": "Europe/Helsinki",
"attributes": [
{ "object_id": "act", "name": "ActiveTime", "type": "Seconds"},
{ "object_id": "dst", "name": "Distance", "type": "Number"}
]
}
]
}
And this is how the MQTT messages are sent from my sensor (I have set up the topics for IoT Agent to understand them)
/123456789/sensor_data/attrs/act 12
/123456789/sensor_data/attrs/dst 322
123456789 is the API Key I have set here.
This situation tipycally happens when IoT Agents uses NGSIv1 to push data to Context Broker, given that NGSIv1 always "string-fy" any attribute value. Recently, the ability to use NGSIv2 (which doesn't have this limitatino) was introduced in IoT Agents.
In order to solve your problem you have to:
Use a recent IOTA-UL version (the current one from master branch will work)
Enable NGSIv2 in configuration as explained in documentation. This is done in the config.js file:
config.iota = {
...
contextBroker: {
...
ngsiVersion: 'v2'
}
...
}
or using environament variable IOTA_CB_NGSI_VERSION=v2 for the IOTA-UL process.
Enable autocast as explained in documentation. This is done in config.js file:
config.iota = {
...
autocast: true,
...
}
or using environament variable IOTA_AUTOCAST=true for the IOTA-UL process.
Set the right type for each attribute at provision time. The documentation here) provides the right types:
Type "Number" for integer or float numbers
Type "Boolean" for boolean
Type "None" for null
Thus, in your case the provisioning for Distance is ok, but for ActiveTime you should use also Number as type.
I am familiar with creating a calculated item with the GUI, but now I want to do it with the API. There is a "formula" field for an item object, but its type is int/float as stated in the document. So where do I put the formula needed by a calculated item?enter image description here
As per the Zabbix manual, it's the params field.
The string that you fill in "params" goes to "Formula"
Tested on version 6
"params": "last(//mysql.innodb_buffer_pool_pages_total) -
last(//mysql.innodb_buffer_pool_pages_free)"
Full context:
{
"jsonrpc": "2.0",
"method": "item.create",
"params": {
"name": "MySQL: Buffer pool utilization",
"key_": "mysql.buffer_pool_utilization",
"params": "last(//mysql.innodb_buffer_pool_pages_total) -
last(//mysql.innodb_buffer_pool_pages_free)"
"hostid": "30074",
"type": 15,
"value_type": 3,
"interfaceid": "30084",
"tags": [
{
"tag": "Disc usage"
},
{
"tag": "Equipment",
"value": "Workstation"
}
],
"delay": "30s"
},
"auth": "038e1d7b1735c6a5436ee9eae095879e",
"id": 1
}
I have a multidimensional array that I want to index with CouchDB (really using Cloudant). I have users which have a list of the teams that they belong to. I want to search to find every member of that team. So, get me all the User objects that have a team object with id 79d25d41d991890350af672e0b76faed. I tried to make a json index on "Teams.id", but it didn't work because it isn't a straight array but a multidimensional array.
User
{
"_id": "683be6c086381d3edc8905dc9e948da8",
"_rev": "238-963e54ab838935f82f54e834f501dd99",
"type": "Feature",
"Kind": "Profile",
"Email": "gc#gmail.com",
"FirstName": "George",
"LastName": "Castanza",
"Teams": [
{
"id": "79d25d41d991890350af672e0b76faed",
"name": "First Team",
"level": "123"
},
{
"id": "e500c1bf691b9cfc99f05634da80b6d1",
"name": "Second Team Name",
"level": ""
},
{
"id": "4645e8a4958421f7d843d9b34c4cd9fe",
"name": "Third Team Name",
"level": "123"
}
],
"LastTeam": "79d25d41d991890350af672e0b76faed"
}
This is a lot like my response at Cloudant Selector Query but here's the deal, applied to your question:
The easiest way to run this query is using "Cloudant Query" (or "Mango", as it's called in the forthcoming CouchDB 2.0 release) -- and not the traditional MapReduce view indexing system in CouchDB. (This blog covers the differences: https://cloudant.com/blog/mango-json-vs-text-indexes/ and this one is an overview: https://developer.ibm.com/clouddataservices/2015/11/24/cloudant-query-json-index-arrays/).
Here's what your CQ index should look like:
{
"index": {
"fields": [
{"name": "Teams.[].id", "type": "string"}
]
},
"type": "text"
}
And what the subsequent query looks like:
{
"selector": {
"Teams": {"$elemMatch": {"id": "79d25d41d991890350af672e0b76faed"}}
},
"fields": [
"_id",
"FirstName",
"LastName"
]
}
You can try it yourself in the "Query" section of the Cloudant dashboard or via curl with something like this:
curl -H "Content-Type: application/json" -X POST -d '{"selector":{"Teams":{"$elemMatch":{"id":"79d25d41d991890350af672e0b76faed"}}},"fields":["_id","FirstName","LastName"]}' https://broberg.cloudant.com/teams_test/_find
That database is world-readable, so you can see the sample documents I created in there here: https://broberg.cloudant.com/teams_test/_all_docs?include_docs=true
Dig the Seinfeld theme :D
You simply need to loop through the Teams array and emit a view entry for each of the teams.
function (doc) {
if(doc.Kind === "Profile"){
for (var i=0; i<doc.Teams.length; i++) {
var team = doc.Teams[i];
emit(team.id, [doc.FirstName, doc.LastName]);
}
}
}
You can then query for all profiles with a specific team id by keying on the team id like this
.../view?key="79d25d41d991890350af672e0b76faed"
giving
{"total_rows":7,"offset":2,"rows":[
{"id":"0d15041f43b43ae07e8faa737f00032c","key":"79d25d41d991890350af672e0b76faed","value":["Adam","Alpha"]},
{"id":"68779729be3610fd8b52b22574000ae8","key":"79d25d41d991890350af672e0b76faed","value":["Bob","Bravo"]},
{"id":"9f97f1565f03aebae9ca73e207001ee1","key":"79d25d41d991890350af672e0b76faed","value":["Chuck","Charlie"]}
]}
or you can include the actual profiles in the result by adding &include_docs=true to the query.
Question title pretty much self explanatory. It is possible to create an id-less entity in Orion. An id = .* query returns normally as an id-less, although existing entity. But how can someone delete that entity? This request didn't work obviously:
{
"contextElements": [
{
"type": "",
"isPattern": "false",
"id": ""
}
],
"updateAction": "DELETE"
}
This is the returned query:
{
"contextElement": {
"type": "",
"isPattern": "false",
"id": "",
"attributes": [
{
"name": "temp",
"type": "integer",
"value": "15"
},
{
"name": "pressure",
"type": "integer",
"value": "720"
}
]
},
"statusCode": {
"code": "200",
"reasonPhrase": "OK"
}
}
There is a known bug (now fixed) in Orion that seems to be causing your issue. Basically Orion interprets the final "/" at the end of an URL as an empty element.
For example (as documented in the issue):
v1/contextEntityTypes queries for all types, while
v1/contextEntityTypes/ queries only for the empty type
In your particular case, something similar happens with some REST operations. If you do a GET /v1/contextEntities you will see all entities, including the empty-id one. You can query that particular entity with GET /v1/contextEntity/ (note the final "/").
And then, the DELETE method doesn't seem to use the same pattern. So if you do DELETE /v1/contextEntity/ You get a No context element found.
So, basically, this is another manifestation of a known bug.
I have a large JSON file that I'm trying to parse with JSON Slurper. The JSON file consists of information about bugs so it has things like issue keys, descriptions, and comments. Not every issue has a comment though. For example, here is a sample of what the JSON input looks like:
{
"projects": [
{
"name": "Test Project",
"key": "TEST",
"issues": [
{
"key": "BUG-1",
"priority": "Major",
"comments": [
{
"author": "a1",
"created": "d1",
"body": "comment 1"
},
{
"author": "a2",
"created": "d2",
"body": "comment 2"
}
]
},
{
"key": "BUG-2",
"priority": "Major"
},
{
"key": "BUG-3",
"priority": "Major",
"comments": [
{
"author": "a3",
"created": "d3",
"body": "comment 3"
}
]
}
]
}
]
}
I have a method that creates Issue objects based on the JSON parse. Everything works well when every issue has at least one comment, but, once an issue comes up that has no comments, the rest of the issues get the wrong comments. I am currently looping through the JSON file based on the total number of issues and then looking for comments using how far along in the number of issues I've gotten. So, for example,
parsedData.issues.comments.body[0][0][0]
returns "comment 1". However,
parsedData.issues.comments.body[0][1][0]
returns "comment 3", which is incorrect. Is there a way I can see if a particular issue has any comments? I'd rather not have to edit the JSON file to add empty comment fields, but would that even help?
You can do this:
parsedData.issues.comments.collect { it?.body ?: [] }
So it checks for a body and if none exists, returns an empty list
UPDATE
Based on the update to the question, you can do:
parsedData.projects.collectMany { it.issues.comments.collect { it?.body ?: [] } }