I am passing a JSON array object in the HTTP POST as
[{"level":"INFO","data": "Test 1"},{"level":"INFO","data": "Test 2"}]
This message is seen as 1 object/log message in SumoLogic. How can I tell SumoLogic to consider each JSON object as an independent object and show 2 log messages instead of one?
I believe this can't be done with the json operator. But, have a look at the docs for the "parse regex" operator. There's an option called "multi" which creates a new message for each match of the regex. In your case, something like this might do the trick:
parse regex "\{?<fieldname>.*?\}" multi
I didn't try this in the product itself, but here is Regex101 link to play with the regex.
I believe the actual answer to this is to not send your logs as an array. Instead include each json object in your body with a '\n' at the end for Sumo to consider these as individual log messages.
{"level":"INFO","data": "Test 1"}\n
{"level":"INFO","data": "Test 2"}\n
Related
In sandbox, I am attempting to gather the information from https://data.nasdaq.com/api/v3/datasets/USTREASURY/YIELD.json
I used the beta feature of creating an HTTP callout right from the flow. It creates an external service based on the sample response you provide.
My problem is that within the JSON created, there is an array within an array; because the response is like
"data":[["2023-02-02","4.62","4.65","4.66","4.76","4.64","4.09","3.75","3.49","3.44","3.4","3.67","3.55"]],
When I access the response from the callout within the flow, the array column_names is available, but not the array data.
The JSON created is:
{"openapi":"3.0.1",
"info":{"title":"dataNasdaqGetRates"
,"description":""},
"paths":{"":{"get":{"description":"",
"operationId":"getRates",
"parameters":[{"name":"api_key","in":"query","required":true,"allowEmptyValue":false,
"schema":{"type":"string"}},
{"name":"order","in":"query","required":true,"allowEmptyValue":false,
"schema":{"type":"string"}},
{"name":"limit","in":"query","required":true,"allowEmptyValue":false,
"schema":{"type":"integer","format":"int32"}}],
"responses":{"2XX":{"description":"",
"content":{"application/json":{"schema":{"type":"object",
"properties":{"dataset":{"type":"object",
"properties":{"end_date":{"type":"string"},
"data":{"type":"array",
"items":{"type":"array",
"items":{"type":"string"}}},
"description":{"type":"string"},
"newest_available_date":{"type":"string"},
"type":{"type":"string"},
"dataset_code":{"type":"string"},
"column_index":{"type":"string"},
"frequency":{"type":"string"},
"oldest_available_date":{"type":"string"},
"transform":{"type":"string"},
"premium":{"type":"boolean"},
"refreshed_at":{"type":"string"},
"database_id":{"type":"integer",
"format":"int64"},
"database_code":{"type":"string"},
"name":{"type":"string"},
"limit":{"type":"integer","format":"int64"},
"id":{"type":"integer","format":"int64"},
"column_names":{"type":"array",
"items":{"type":"string"}},
"collapse":{"type":"string"},
"start_date":{"type":"string"},
"order":{"type":"string"}
}}}}}}}}}}}}
I've attempted to tweak the JSON to remove the nested array, hoping it might just work. I've attempted to add additional "type": to the nested array (technically the first item is a string and the rest are integers).
I was expecting there to be another apex-defined list called "data" listed after columnx5fnames; or even just a text collection or anything at all that I could add to a variable and access.
response items menu from flow
I am posting the following object
{
skillName : "Professional Skills"
_id : {$oid: "5adf23946ab671bf6cb36aff"}
}
to the DjangoService given below:
#csrf_exempt
#api_view(['GET','POST'])
def saveSubjectView(request): #this service will add & update Subject
if request.method == 'POST':
try:
stream = StringIO(request.body)
subject = JSONParser().parse(stream)
print("The subejct is ")
pp.pprint(subject)
serializedsubject = json.loads(json_util.dumps(subject))
print("serializedsubject")
pp.pprint(serializedsubject)
The output that I am getting is
'skillType': { u'_id': { }, u'skillName': u'Professional Skills'}
The ObjectId posted from the front end (AngularJS) is not printed in the service. I know that I can fix it by removing the $oid while posting from the AngularJS application. But I would like to know why this is not happening. I have searched the documents and I couldn't get a proper reply. May be the keywords I used are wrong. Keywords used are : "JSON serialisation of ObjectId", "$oid json serialization using Django".
The complete object I am posting to the Django service is given below:
Exactly. $oid or anything prefixed with $ is an internal format and reserved, so you cannot post field names. The convention is from MongoDB Extended JSON where such prefixes are used to identify the BSON Type for proper conversion, and used as a serializable transport since these "types" are not supported in basic JSON.
So the solution is to actually use the bson.json_util to "deserialize" the JSON string right from the start:
from bson import json_util
# serializedsubject = json.loads(json_util.dumps(subject))
serializedsubject = json_util.loads(request.body) # correct usage
Or more succinctly self contained:
input = '{ "skillName" : "Professional Skills" ,"_id" : { "$oid": "5adf23946ab671bf6cb36aff"} }'
json_util.loads(input)
Returns
{u'skillName': u'Professional Skills', u'_id': ObjectId('5adf23946ab671bf6cb36aff')}
This correctly casts objects from any keys notated with the Extended JSON Syntax to their correct BSON Type, as also supported in the driver functions. And naturally the driver will then convert back to BSON when sending to MongoDB.
If for some reason your request.body contains anything other than a "string" which is valid for input to the function, then it is up to your code to convert it to that point. But there should be no need to "parse to JSON" and then "stringify" again just to input to the function.
NOTE: If you have not already done so within your JavaScript client side of the application, there is also the bson package available. This would allow where such Extended JSON is "received" from the server the translation into the BSON Types as JavaScript Objects, and of course then the serialization of such objects back into the Extended JSON Format.
This would in fact be recommended where "type" information needs to be maintained with the data transmitted and kept between client and server.
I have this code for compose and send MQTT payload.
snprintf_P(mqtt_data,
sizeof(mqtt_data),
PSTR("{\"" D_JSON_SYNC "\":%d,\"" D_JSON_LOW "\":%d,\"" D_JSON_HIGH "\":%d,\"" D_JSON_DATA "\":\"%06X\",\"" D_CMND_RFKEY "\":%s, \"" D_TOPIC "\":%s}"),
sync_time,
low_time,
high_time,
received_id,
rfkey,
Settings.mqtt_topic);
MqttPublishPrefixTopic_P(6, PSTR(D_RFRECEIVED));
You can see "Settings.mqtt_topic" is the value for "topic" included in message.
this is mesage received
{"Sync":12230,"Low":390,"High":1190,"Data":"596F91","RfKey":1, "Topic":10101019}
And I have this another code for MQTT payload.
snprintf_P(mqtt_data,
sizeof(mqtt_data),
S_JSON_COMMAND_INDEX_SVALUE,
D_CMND_RFKEY,
sonoff_bridge_learn_key,
D_LEARNED);
MqttPublishPrefixTopic_P(5, PSTR(D_CMND_RFKEY));
this is message received
{"Rfkey1":Learned}
Can somebody give me an approach to get "topic" included in the payload in the second code?
I need to receive message like this
{"Rfkey1":Learned, "Topic":10101019}
I have tried several ways without success.
I tried something like this
snprintf_P(mqtt_data,
sizeof(mqtt_data),
S_JSON_COMMAND_INDEX_SVALUE,
D_CMND_RFKEY,
D_TOPIC,
sonoff_bridge_learn_key,
D_LEARNED,
Settings.mqtt_topic);
This looks to be just using snprintf (doc here)
This takes 3 initial arguments
Output buffer
Size of the output buffer
A format string to use to build the output
The arguments following these 3 are the values to be inserted into the format string. You can not just add extra values on the end without updating the format string with where to put them and what format they should take.
You have not included the format string for your second example so I can't suggest how to edit it.
Is there anyway of uploading Custom Slot Types values via an API, so that you do not need to type them in manually using the new Alexa Skill Builder interface (if you have many of them):
I haven't found anything.
My recommendation is to get the model via SMAPI first, edit the json file with your new values and update it via SMAPI again.
ask api get-model -s "enter your skill id here" --stage development -l en-US > model.json
in the model.json file you can see the slots definition. Change it (with a script or manually) and update the model again
Reference to both commands:
https://developer.amazon.com/docs/smapi/ask-cli-command-reference.html#update-model-subcommand
https://developer.amazon.com/docs/smapi/ask-cli-command-reference.html#update-model-subcommand
It seems not (after searching). There is a feature request logged here with Amazon:
https://forums.developer.amazon.com/questions/9640/api-to-upload-intent-schema-and-sample-utterances.html#answer-77902
Yes you can do this via the SMAPI API/CLI. Take a look at https://developer.amazon.com/docs/smapi/ask-cli-intro.html for a full detail - it allows for full model editing via JSON.
In the left bar bellow the "Intents" and "Slot" is the option "JSON Editor". There you can write a JSON for the new intents you want to add.
Example without slot type
{
"name":"YesIntent",
"samples":[
"Yes",
"Yeah",
"I do",
"I am"
]
}
Example with slot type
{
"name":"NumberIntent",
"slots":[
{
"name":"number",
"type":"AMAZON.NUMBER"
}
],
"samples":[
"{number} is my number",
"{number}",
"my number is {number}"
]
}
As other answers suggest, you can use the SMAPI.
Alternatively, you can select the "code editor" tab on the left and drag/drop or copy/paste your schema json code.
https://github.com/williamwdu/Alexa-Custom-Slot-Generator
I wrote this to convert csv/excel to JSON format so you can paste it into code editor.
Let me know if you have any question.
There is no README for the code coz I have no time these days
In JMeter I want to check the number of objects in a JSON array, which I receive from the server.
For example, on a certain request I expect an array with 5 objects.
[{...},{...},{...},{...},{...}]
After reading this: count members with jsonpath?, I tried using the following JSON Path Assertion:
JSON Path: $
Expected value: hasSize(5)
Validate against expected value = checked
However, this doesn't seem to work properly. When I actually do receive 5 objects in the array, the response assertion says it doesn't match.
What am I doing wrong?
Or how else can I do this?
Although JSONPath Extractor doesn't provide hasSize function it still can be done.
Given the example JSON from the answer by PMD UBIK-INGENIERIE, you can get matches number on book array in at least 2 ways:
1. Easiest (but fragile) way - using Regular Expression Extractor.
As you can see, there are 4 entries for category like:
{ "category": "reference",
{ \"category\": \"fiction\"
...
If you add a Regular Expression Extractor configured as follows:
It'll capture all the category entries and return matches number as below:
So you will be able to use this ${matches_matchNr} variable wherever required.
This approach is straightforward and easy to implement but it's very vulnerable to any changes in the response format. If you expect that JSON data may change in the foreseeable future continue with the next option.
2. Harder (but more stable) way - calling JsonPath methods from Beanshell PostProcessor
JMeter has a Beanshell scripting extension mechanism which has access to all variables/properties in scope as well as to the underlying JMeter and 3rd-party dependencies APIs. In this case you can call JsonPath library (which is under the hood of JsonPath Extractor) directly from Beanshell PostProcessor.
import com.jayway.jsonpath.Criteria;
import com.jayway.jsonpath.Filter;
import com.jayway.jsonpath.JsonPath;
Object json = new String(data);
List categories = new ArrayList();
categories.add("fiction");
categories.add("reference");
Filter filter = Filter.filter(Criteria.where("category").in(categories));
List books = JsonPath.read(json, "$.store.book[?]", new Filter[] {filter});
vars.put("JSON_ARRAY_SIZE", String.valueOf(books.size()));
The code above evaluates JSONPath expression of $.store.book[?] against parent sampler response, counts matches number and stores it into ${JSON_ARRAY_SIZE} JMeter Variable
which can later be reused in an if clause or an assertion.
References:
JMeter – Working with JSON – Extract JSON response
JMeter's User Manual Regular Expressions entry
JSON Path Documentation and Examples
How to use BeanShell: JMeter's favorite built-in component
This is not possible with the plugin you are using (JMeter-plugins).
But it can be done with JSON Extractor since JMeter 3.0, this plugin has been donated by UbikLoadPack (http://jmeter.apache.org/changes_history.html)
Example:
Say you have this JSON that contains an array of books:
{ "store": {"book": [
{ "category": "reference","author": "Nigel Rees","title": "Sayings of the Century","price": 8.95},
{ "category": "fiction","author": "Evelyn Waugh","title": "Sword of Honour","price": 12.99},
{ "category": "fiction","author": "Herman Melville","title": "Moby Dick","isbn": "0-553-21311-3","price": 8.99},
{ "category": "fiction","author": "J. R. R. Tolkien","title": "The Lord of the Rings","isbn": "0-395-19395-8","price": 22.99}
],
"bicycle": {"color": "red","price": 19.95}} }
To have this count:
1/ Add JSON Extractor:
The count will be then available bookTitle_matchNr which you can access through:
${bookTitle_matchNr}
Running this Test Plan would display this:
As you can see, Debug Sampler-${bookTitle_matchNr} shows Debug Sampler-4