Using Json Slurper + Groovy + Azure answer - jenkins

So I am trying to write a Jenkins job using groovy to fetch me some data
The data inside the variable answer after the 3rd line would be some like
[
{
"endIpAddress": "11.21.115.9",
"id": "blabla1",
"name": "blabla",
"resourceGroup": "stg",
"startIpAddress": "11.12.115.9",
"type": "blablafirewallRules"
},
{
"endIpAddress": "1.2.15.9",
"id": "blabla2",
"name": "function1-blabla",
"resourceGroup": "stg",
"startIpAddress": "1.2.15.9",
"type": "blablafirewallRules"
},
{
"endIpAddress": "7.7.7.7",
"id": "blabla2",
"name": "function2-blabla",
"resourceGroup": "stg",
"startIpAddress": "7.7.7.7",
"type": "blablafirewallRules"
},
.
.
.
.
]
What id like to do is to build a list or a 2-dimentions-array that would parse this json and the it will hold all the startipaddress of all the items where name contains "function", so based on this JSON, the data should be
desiredData[0] = [function1-blabla, 1.2.15.9]
desiredData[1] = [function2-blabla, 7.7.7.7]
Up until now I wasn't using JsonSlurper and I was manipulating the text and building the array which is pretty stupid thing to do since this is kind of what JSON is all about I guess.
import groovy.json.JsonSlurper
command = "az mysql server firewall-rule list --resource-group ${rgNameSrvr} --server-name ${BLA} --output json"
answer = azure.executeAzureCliCommand(command, "BLA")
def jsonSlurper = new JsonSlurper()
def json = new JsonSlurper().parseText(answer)

def data = json.findAll{ it.name =~ /^function/ }.collectEntries{ [it.name, it.startIpAddress] }
Code above returns map where key=name and value=ip
If you want 2dim array:
def data = json.findAll{ it.name =~ /^function/ }.collect{ [it.name, it.startIpAddress] }

Related

All metrics are not show in influxdb from Telegraf

I have followed multiple documentation but I couldn't receive all the metrics from my JSON file to Influxdb.
My Input json file
{
"apBuildNumber": "04.04.01.0003.1f7fd3ce8896",
"version": "1.0.0",
"sentTimeMs": "1661678671000",
"sciSystemId": "scis1",
"apMac": "54:ec:2f:18:78:4d",
"apSerial": "281915001731",
"apVenue": "test",
"apName": "281915001731",
"apTenantId": "tenant",
"apReport": {},
"apNonCumulativeReport": {},
"apCumulativeReport": {
"cumulativeReportBins": [
{
"binStartTime": 123131232,
"binSampleDurationSec": "10",
"apCumulativeBinNetworksViews": [
{
"pci": [
123,
333
]
}
]
},
{
"binStartTime": 567567577,
"binSampleDurationSec": "10",
"apCumulativeBinNetworksViews": [
{
"pci": [
252,
124
]
}
]
}
]
},
"apAlarmsReport": {}
}
what I have tried :
My telegraf.conf is like this
data_format = "json_v2"
[[inputs.file.json_v2]]
[[inputs.file.json_v2.object]]
path = "apCumulativeReport"
disable_prepend_keys = true
tags = ["cumulativeReportBins_binStartTime"]
[[inputs.file.json_v2.object.field]]
path = "cumulativeReportBins_apCumulativeBinNetworksViews_pci"
type = "int"
Ideally I have to receive all the PCI values from the array but I can see only second element in each PCI array in InfluxDB.
Can someone identify what mistake I'm doing here.

Using data from the first response in the body of the second

I'm trying to combine requests from two services in one endpoint.
The first returns the list of users, like this:
{
"data": [
{ "id": 1, "name": "first", "photo": "employee_photos/key1.png" },
{ "id": 2, "name": "second", "photo": null },
{ "id": 3, "name": "third", "photo": "employee_photos/key3.png" }
]
}
The second is supposed to receive the POST request with the JSON listing photo keys to get the required version URLs.
Request:
{
"keys": [ "employee_photos/key1.png", "employee_photos/key3.png" ],
"versions": [ "small", "large" ]
}
I created a small Lua script to process the response of the first request and collect the list of keys. It looks like this:
function post_employees(request, employeesResponse)
local resp = employeesResponse.load()
local data = resp:data():get("data")
local photo_keys = {}
for i = 0, data:len() - 1, 1 do
local rec = data:get(i)
local id = rec:get("id")
local photo = rec:get("photo")
if photo then
table.insert(photo_keys, photo)
end
end
resp:data():set("photos", table.concat(photo_keys, ","))
end
But then... I can't find a way to use this list of keys in the second request. Is it even possible?

Remove metadata from json results

I'm using ActiveResource to establish a REST connection with rails 4.2 to an ADS Advantage server using the WebPlatform from ADS. It returns json with "__metadata". How can I remove the "__metadata"?
{
"__metadata": {
"uri": "http://.....",
"key_fields": "ID",
"rows_affected": 0,
"last_autoinc": 0
},
In my class I have added self.include_format_in_path = false, to remove the .json from the end of the uri.
Thanks.
you can achieve this in the following steps:
parse the JSON:
parsed_json = JSON.parse('{ "__metadata": { "uri": "http://.....", "key_fields": "ID", "rows_affected": 0, "last_autoinc": 0 }}')
then you will get a hash type and you just need to get the inside of __metadata:
result = parsed_json['__metadata']
then you can just return it or print it:
puts result.to_json
#=> {"uri"=>"http://.....", "key_fields"=>"ID", "rows_affected"=>0, "last_autoinc"=>0}

rails extract data from simple json response

I need to extract some data from a JSON response i'm serving up from curb.
Previously I wasn't calling symbolize_keys, but i thought that would make my attempt work.
The controller action:
http = Curl.get("http://api.foobar.com/thing/thing_name/catalog_items.json?per_page=1&page=1") do|http|
http.headers['X-Api-Key'] = 'georgeBushSucks'
end
pre_keys = http.body_str
#foobar = ActiveSupport::JSON.decode(pre_keys).symbolize_keys
In the view (getting undefined method `current_price' )
#foobar.current_price
I also tried #foobar.data[0]['current_price'] with the same result
JSON response from action:
{
"data": {
"catalog_items": [
{
"current_price": "9999.0",
"close_date": "2013-05-14T16:08:00-04:00",
"open_date": "2013-04-24T11:00:00-04:00",
"stuff_count": 82,
"minimum_price": "590000.0",
"id": 337478,
"estimated_price": "50000.0",
"name": "This is a really cool name",
"current_winner_id": 696969,
"images": [
{
"thumb_url": "http://foobar.com/images/93695/thumb.png?1365714300",
"detail_url": "http://foobar.com/images/93695/detail.png?1365714300",
"position": 1
},
{
"thumb_url": "http://foobar.com/images/95090/thumb.jpg?1366813823",
"detail_url": "http://foobar.com/images/95090/detail.jpg?1366813823",
"position": 2
}
]
}
]
},
"pagination": {
"per_page": 1,
"page": 1,
"total_pages": 131,
"total_objects": 131
}
}
Please note that accessing hash's element in Rails work in models. To use it on hash, you have to use OpenStruct object. It's part of standard library in rails.
Considering, #foobar has decoded JSON as you have.
obj = OpenStruct.new(#foobar)
obj.data
#=> Hash
But, note that, obj.data.catalog_items willn't work, because that is an hash, and again not an OpenStruct object. To aid this, we have recursive-open-struct, which will do the job for you.
Alternative solution [1]:
#foobar[:data]['catalog_items'].first['current_price']
But, ugly.
Alternative solution [2]:
Open Hash class, use method_missing ability as :
class Hash
def method_missing(key)
self[key.to_s]
end
end
Hope it helps. :)

rspec for testing json results

So I am basically trying to write rspec to test my json results:
patient_allergies = patient.patient_allergies
expect(response_body['allergies'].size).to eq(patient_allergies.size)
patient_allergies.each_with_index do |allergy, index|
expect(response_body['allergies'][index]['name']).to eq(allergy.name)
allergy.patient_allergy_reactions.each_with_index do |reaction, index|
expect(response_body['reactions'][index]['name']).to eq(reaction.name)
end
end
My tables above are patient_allergies and patient_allergy_reactions.
The above tests work fine. But the problem is I am comparing by index.
If the order of the json changes, the test would fail. Is there a better way to write tests for this?
my json looks like this:
"allergies": [
{
"name": "Allergy1",
"reactions": [
]
},
{
"name": "Allergy2",
"reactions": [
{
"name": "Reaction1",
"severity": "Medium"
}
]
}
],
Use detect and the include matcher to help you out here:
patient_allergies = patient.patient_allergies
response_allergies = response['allergies'] || []
expect(response_allergies.size).to eq(patient_allergies.size)
patient_allergies.each |allergy| do
response_allergy = response_allergies.detect{|a| a['name'] == allergy.name}
expect(response_allergy).to_not be_nil
patient_reactions = allergy.patient_allergy_reactions
response_reactions = (response_allergy['reactions'] || []).map{|r| r['name']}
expect(response_reactions.size).to eq(patient_reactions.size)
expect(response_reactions).to include(*patient_reactions.map(&:name))
end

Resources