Request multiple elements from Adobe's SiteCatalyst using Java - java

Here's my Java code in order to extract data from Adobe Analytics: (cloned from GitHub repository)
public static AnalyticsClient SecretAuthentication(String endpoint,String username,String password){
AnalyticsClient client = new AnalyticsClientBuilder()
.setEndpoint(endpoint)
.authenticateWithSecret(username, password)
.build();
return client;
}
public static void main(String[] args) throws IOException, InterruptedException{
AnalyticsClient client = SecretAuthentication("api.omniture.com","username","my_secret_pass");
ReportDescription desc = new ReportDescription();
String rsid="my_rs_id";
desc.setReportSuiteID(rsid);
desc.setDateFrom("2016-10-12"); // YYYY-MM-DD
desc.setDateTo("2016-10-13");
desc.setMetricIds("entries","orders","pageviews","visits","visitors");
String[] elements = new String[2];
elements[0]="prop3";
elements[1]="prop33";
desc.setElementIds(elements);
//Pass the description to the API queue method, which will start the process of preparing the report:
ReportMethods reportMethods = new ReportMethods(client);
int reportId = reportMethods.queue(desc);
System.out.println(reportId);
//The received integer is a report id, which can be used to receive the actual report using the get() method.
//Preparing report takes some time, and the get() method will throw an exception with appropriate message if the report is not ready yet.
//Following code runs the get() method in a loop, waiting until the report is ready:
ReportResponse response = null;
while (response == null) {
try {
response = reportMethods.get(reportId);
//System.out.println(response.toString());
} catch (ApiException e) {
System.out.println(e.toString());
Thread.sleep(3000);
continue;
}
}
List<ReportData> responseData = response.getReport().getData();
System.out.println("Is there data in the report? "+responseData.size());
for (int j = 0; j < responseData.size(); j++)
{
System.out.println(responseData.get(j).getName()+ " has :");
System.out.println(responseData.get(j).getCounts());
}
}
An example output of the last "for" statement is:
FR has :
[35732.0, 0.0, 115146.0, 36402.0, 32111.0]
The 5-sized vector includes the metric values ("entries","orders","pageviews","visits","visitors")
The "FR" (France) is the value of the first element (prop3) which is actually the "Country" variable.
The problem is that I have no information about the second element, prop33 (prop33 is "Device Type").
String[] elements = new String[2];
elements[0]="prop3";
elements[1]="prop33";
The most important is that Adobe seems to ignore the second element (prop33) and considers only the first one (prop3) for its search. I can prove this by changing the order of the two elements in elements array.
String[] elements = new String[2];
elements[0]="prop33";
elements[1]="prop3";
If I place prop33 first the output lines are different and Adobe responds as if prop33(Device Type) were the only criterion. For example:
iPhone has :
[47636.0, 6.0, 107440.0, 47729.0, 42330.0]
So, how can I send two or more elements as a matching criterion??

I figured it out. The "problem" has nothing to do with the parameter format!! The Adobe response follows the json format too. In order to see all response data you need to call the "getBreakdown()" method in order to discover the "lower" layers of the json response tree! In my attached code the "for" statement prints only data for the prop3 json element because this is the first layer of Adobe's response. If someone wants to see prop33 element should do the following:
for (int j = 0; j < responseData.size(); j++)
{
System.out.println(responseData.get(j).getName()+ " has :");
System.out.println(responseData.get(j).getCounts());
List<ReportData>reportData;
reportData = responseData.get(j).getBreakdown();//<---Here's what is needed!!
for (int i = 0; i < reportData.size(); i++)
{
System.out.println(" "+reportData.get(i).getName());
System.out.println(" "+reportData.get(i).getCounts());
}
System.out.println("===============================================");
}
In general you need one of the many and handy json reader java libraries to traverse the json tree!!

This isn't an answer more of a response to your last comment that's too long for a comment that should hopefully help you figure out what the problem is. Again disclaimer that I'm not an actual java coder so take that for what it's worth. But..
Firstly, just to be clear, you did try this, right?
desc.setElementIds("prop3", "prop33");
And you say that doesn't work? Because looking at setElementIds I see
public void setElementIds(String... elementIds) { .. }
My 5 minute understanding of java is String... is basically syntactic sugar for String[] (array) but it's to accept the strings as multiple arguments passed, not a single array of strings, so it looks to me that passing multiple args is indeed the way to go.
But overall you should check what is actually being sent to Adobe in the request. I expect the requirements are similar for the soap/xml version, but I don't know really know the soap/xml version so here's the JSON version. Based on what you posted (Report.Queue) JSON object payload hould look like this:
{
"reportDescription":{
"reportSuiteID":"my_rs_id",
"dateFrom":"2016-10-12",
"dateTo":"2016-10-13",
"metrics":[
{
"id":"entries"
},
{
"id":"orders"
},
{
"id":"pageviews"
},
{
"id":"visits"
},
{
"id":"visitors"
}
],
"elements":[
{
"id":"prop3"
},
{
"id":"prop33"
}
]
}
}
So check the http(s) request to make sure it looks like that (or soap/xml equiv).
And your (JSON) response (Report.Get) should look something like this:
{
"report":{
"type":"ranked",
"elements":[
{
"id":"prop3",
"name":"prop3 name here"
},
{
"id":"prop33",
"name":"prop33 name here"
}
],
"reportSuite":{
"id":"my_rs_id",
"name":"rsid name here"
},
"period":"Wed. 12 Oct. 2016 - Thu. 13 Oct. 2016",
"metrics":[
{
"id":"entries",
"name":"Entries",
"type":"number",
"decimals":0,
"latency":4599,
"current":false
},
{
"id":"orders",
"name":"Orders",
"type":"number",
"decimals":0,
"latency":4599,
"current":false
},
{
"id":"pageviews",
"name":"Page Views",
"type":"number",
"decimals":0,
"latency":4599,
"current":false
},
{
"id":"visits",
"name":"Visits",
"type":"number",
"decimals":0,
"latency":4599,
"current":false
},
{
"id":"visitors",
"name":"Visitors",
"type":"number",
"decimals":0,
"latency":4599,
"current":false
}
],
"data":[
{
"name":"<first prop3 value>",
"url":"",
"counts":[
"246944",
"0",
"494509",
"251168",
"200670"
],
"breakdown":[
{
"name":"<first breakdown prop33 value>",
"url":"",
"counts":[
"226556",
"0",
"460021",
"231637",
"184294"
]
},
{
"name":"<second breakdown prop33 value>",
"url":"",
"counts":[
"17058",
"0",
"23930",
"17628",
"15085"
]
} //, etc...
]
},
{
"name":"<second prop3 value>",
"url":"",
"counts":[
"246944",
"0",
"494509",
"251168",
"200670"
],
"breakdown":[
{
"name":"<first breakdown prop33 value>",
"url":"",
"counts":[
"226556",
"0",
"460021",
"231637",
"184294"
]
},
{
"name":"<second breakdown prop33 value>",
"url":"",
"counts":[
"17058",
"0",
"23930",
"17628",
"15085"
]
} //, etc...
]
} //,etc..
],
"totals":[
"253490",
"0",
"503495",
"253490",
"201190"
],
"version":"1.4.16.10"
},
"waitSeconds":0,
"runSeconds":0
}

Related

Cucumber:Assert values irrespective of Index

I am working on updating functional test suites using Cucumber feature file.The issue my output is an array which is not sorted.Index of the object may change.
Array:
[{
"id": "12",
"name": "Something"
},
{
"id": "13",
"name": "Another Something"
}
]
Here I wanna assert name when Id=13 only.Any help would be appreciated.
The Json is list of objects within an Array so you need parse them and validate the each Object. You can do like below,
Code:
JSONArray jsonArray = new JSONArray(JsonAsString);
JSONObject jsonObject;
for (int i = 0; i < jsonArray.length(); i++) {
jsonObject = new JSONObject(jsonArray.get(i).toString());
if (jsonObject.get("id").toString().equalsIgnoreCase("13")) {
System.out.println("Name: " + jsonObject.get("name"));
//do your thing...
}
}
Output:
Name: Another Something

How to structure Multiple array of JSON in the beanshell sampler

How to structure Multiple array of JSON in the beanshell sampler
for example i need to pass N number of articles to a loop , so i have created a for loop to fetch the articles. here i have mentioned 3 articles as an example. but i need to fetch N number of articles in a loop.
The output should be like :
"itemLines": {
"itemLine": [
{
"bundleParentId": "",
"id": "1",
"itemType": "ART",
"itemNo": "1234",
},
{
"bundleParentId": "",
"id": "2",
"itemType": "ART",
"itemNo": "2021",
},{
"bundleParentId": "",
"id": "3",
"itemType": "ART",
"itemNo": "2023",
}
]
}
My code in the beanshell smpler is : For example here i have mentioned in the array list with 3 article numbers.
public void createJsonStructure() {
try
{
JSONObject rootObject = new JSONObject();
JSONArray articleArr = new JSONArray();
String[] article_list = {"00258882", "70234185", "00258882"};
log.info(article_list.length);
for (i=0;i<=article_list.length;i++)
{
JSONObject article_list= new JSONObject();
article_list.put("id", "i+1");
article_list.put("itemNo",article_list[i]);
article_list.put("requiredQty", "1");
articleArr.put(article_list);
}
log.info(articleArr);
rootObject.put("itemLines", articleArr);
log.info("rootObject is"+rootObject.toString(4));
props.put("JsonObjectoutput", rootObject.toString(4));
}
catch (Exception ex)
{
ex.printStackTrace();
log.info("notes");
}
}
I could see the output is not retrieved in the jmeter logs . Here output should be printed in the logs , but i could see output is not printed.

Second JSONArray in JSONObject somehow is empty

Here's what im trying to do. There are two arrays that i want to retrieve from my mysql database. These two arrays are echoed separately:
echo json_encode(array("friendrequest"=>$friendrequest));
echo json_encode(array("friendresult"=>$friendresult));
This is the code i use to process the resulting string:
public void onResponse(String response) {
Log.d("Response", response);
try {
JSONObject jsonObj = new JSONObject(response);
JSONArray ja_data = jsonObj.getJSONArray("friendresult");
String[] from = {
"first_name",
"anytimer_count",
"relationship_status"
}; //string array
int[] to = {
R.id.textListView1,
R.id.textListView2,
R.id.textListView3
}; //int array of views id's
JSONArrayAdapter arrayListAdapter = new JSONArrayAdapter(MyFriendsActivity.this, ja_data, R.layout.custom_list_items, from, to);
list.setAdapter(arrayListAdapter);
JSONArray ja_requests = jsonObj.getJSONArray("friendrequest");
int ja_lengths = ja_requests.length();
Log.d("Response", Integer.toString(ja_lengths));
} catch (JSONException e) {
Log.e("MyFriendsActivity", "unexpected JSON exception", e);
}
Now, the logged reponse from line 2 in the processing code gives me the following:
Response =
{
"friendrequest": [
{
"first_name": "Tom",
"anytimer_count": "0",
"relationship_status": "0"
},
{
"first_name": "Bert",
"anytimer_count": "0",
"relationship_status": "0"
}
]
}{
"friendresult": [
{
"first_name": "Luuk",
"anytimer_count": "0",
"relationship_status": "1"
}
]
}
This is contains all the values that should be sent and is correct.
The problem is that my processing code is only able to recognize the array that is encoded first in the php script. Basically if i swap the position of the two lines of code in the php script, 'friendrequest' will contain values, while 'friendresult' does not and vice versa. What am i doing wrong here?
The error im getting:
org.json.JSONException: No value for friendresult
at
com.example.tomva.anytimereverywhere.MyFriendsActivity$3.onResponse(MyFriendsActivity.java:84)
Line 84 is the following line:
JSONArray ja_data = jsonObj.getJSONArray("friendresult");
You have to pass yours json in a array to be able to extract them all.
Shold be:
[
<?php
echo json_encode(array("friendrequest"=>$friendrequest));
echo ",";
echo json_encode(array("friendresult"=>$friendresult));
?>
]
Related answer
or you can use following
echo json_encode(array("friendrequest"=>$friendrequest,"friendresult"=>$friendresult));
Replace
echo json_encode(array("friendrequest"=>$friendrequest));
echo json_encode(array("friendresult"=>$friendresult));
With this
echo json_encode(array("friendrequest"=>$friendrequest,"friendresult"=>$friendresult));
Your Response JSON is not valid as it has missing ","
try to change your response from
{"friendrequest": [{"first_name":"Tom","anytimer_count":"0","relationship_status":"0"},{"first_name":"Bert","anytimer_count":"0","relationship_status":"0"}]} {"friendresult": [{"first_name":"Luuk","anytimer_count":"0","relationship_status":"1"}]}
To
[{
"friendrequest": [{
"first_name": "Tom",
"anytimer_count": "0",
"relationship_status": "0"
}, {
"first_name": "Bert",
"anytimer_count": "0",
"relationship_status": "0"
}]
}, {
"friendresult": [{
"first_name": "Luuk",
"anytimer_count": "0",
"relationship_status": "1"
}]
}]
Common Errors
Expecting 'STRING' - You probably have an extra comma at the end of
your collection. Something like { "a": "b", }
Expecting 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '[' -
You probably have an extra comma at the end of your list.
Something like: ["a", "b", ]
Enclosing your collection keys in quotes. Proper format for a
collection is { "key": "value" }
Make sure you follow JSON's syntax properly. For example, always
use double quotes, always quotify your keys, and remove all
callback functions

Accessing json string in java and creating hashmap Android

I have a JSON string and I am trying to retrieve information from it. Json String looks like this.
JSON STRING :
{
"information": {
"device": {
"id": 0
},
"user": {
"id": 0
},
"data": [
{
"datum": {
"id": "00GF001",
"history_id": "9992BH",
"name": "abc",
"marks": 57,
"class": "B",
"type": "Student"
}
},
{
"datum": {
"id": "72BA9585",
"history_id": "78NAH2",
"name": "ndnmanet",
"marks": 70,
"class": "B",
"type": "Student"
}
},
{
"datum": {
"id": "69AHH85",
"history_id": "NN00E3006",
"name": "kit",
"department": "EF003",
"class": "A",
"type": "Employee"
}
},
{
"datum": {
"id": "09HL543",
"history_id": "34QWFTA",
"name": "jeff",
"department": "BH004",
"class": "A1",
"type": "Employee_HR"
}
}
]
}
}
I am trying to access data JSONArray and respective Datum from it. I differentiated each datum as per type such as student, employee etc and push information in hashmap.
I successfully did it in javascript but in Java I am struggle abit.
When I am trying to access JSONArray it throws exception
try {
JSONObject data = new JSONObject(dataInfo);
// Log.d(TAG, "CHECK"+data.toString());
JSONObject info = data.optJSONObject("information");
if(info.getJSONArray("data").getString(0).equals("Student") > 0) //exception here
Log.d(TAG, "Data"+ data.getJSONArray("data").length()); //exception here too
for(int m = 0; m < data.length(); m++){
// for(int s = 0; s < data[m].ge)
}
} catch (JSONException j){
j.printStackTrace();
}
Any pointers to create hashmap respective type I have. Appreciated
If you're trying to access the type field of a datum object, you'll want something like this:
JSONObject data = new JSONObject(dataInfo); // get the entire JSON into an object
JSONObject info = data.getJSONObject("information"); // get the 'information' object
JSONArray dataArray = info.getJSONArray("data"); // get the 'data' array
for (int i = 0; i < dataArray.length(); i++) {
// foreach element in the 'data' array
JSONObject dataObj = dataArray.getJSONObject(i); // get the object from the array
JSONObject datum = dataObj.getJSONObject("datum"); // get the 'datum' object
String type = datum.getString("type"); // get the 'type' string
if ("Student".equals(type)) {
// do your processing for 'Student' here
}
}
Note that you'll have to deal with exception handling, bad data, etc. This code just shows you the basics of how to get at the data that you're looking for. I separated each individual step into its own line of code so that I could clearly comment what is happening at each step, but you could combine some of the steps into a single line of code if that is easier for you.
if dataInfo is the json you posted, then you have to access information and from information, you can access data:
JSONObject data = new JSONObject(dataInfo);
JSONObject info = data.optJSONObject("information");
if (info != null) {
JSONArray dataArray = info.optJSONArray("data")
}

JSON different objects in an array

At the moment i'm trying to understand json and how it works.
But i have a problem with an array of objects.
all objects in the array have a key called "value" (i know it's weird, it's not my code) what also is an object.
And now to the problem: This object called "value" has always different key-values.
So i dont now how i can parse the json code to java object code, when it differ, every time.
Here some examples:
First object of the array:
"value":
{
"local":
[
"English", "Deutsch", Espanol"
],
"english":
[
"English", "Deutsch", Espanol"
],
},
Second object(now a string, not object) of the array:
"value" : "",
Third object of the array:
"value" : {},
...
Maybe I'm doing the parsing wrong.
First I have created the beans classes in java for the json code and then I'm using the automatic parser of google. (gson)
It works when only one of the examples above is inside the json code. (it should not differ, like changing from string to object...)
Gson gson = new Gson();
Output output = gson.fromJson(json, Output.class);
Output is the main class for the json stuff.
I have found out that maybe while parsing I could check a value called "id" first, and from that I could create another beans class with the right variables ...
Thats the code i need to parse to java objects and how do you do that??
The problem is the key called "value", because its always different.
With my method of using the google parser "gson" it wont work, because i'm getting exception that its an string but i was waiting for an object...
{
"status":"success",
"data":{
"panel":{
"title":{
"label":{ "local":"Tote Selection", "english":"Tote Selection" },
"image":"public/img/pick.jpg", "type":"default"
},
"isFirst":false, // currently not used
"isLast":false, // currently not used
"ownCount":0, // currently not used
"panelsCount":0, // currently not used
"elements":[
{
"type":"text",
"id":"1", "value":{ "local":"Scan next order tote",
"english":"Scan next order tote" },
"label":{ "local":"", "english":"" }, "color":"000000",
"fontsize":18, "fontstyle":"flat", "alignment":"left",
"rows":"undefined", "bgcolor":"", "isFocus":false
},
{
"type":"text",
"id":"4", "value":{ "local":"Scan tote: ", "english":"Scan tote: " },
"label":{ "local":"", "english":"" }, "color":"000000", "fontsize":20,
"fontstyle":"strong", "alignment":"left", "rows":"undefined",
"bgcolor":"", "isFocus":false
},
{
"type":"input",
"id":"6", "value":"", "label":{ "local":"", "english":"" },
"color":"000000", "fontsize":24, "fontstyle":"flat", "alignment":"left",
"rows":"undefined", "isFocus":true
},
{
"type":"button",
"id":"1", "value":{ "local":"", "english":"" },
"label":{ "local":"Menu", "english":"Menu" }, "color":"000000",
"fontsize":14, "fontstyle":"strong", "alignment":"left",
"rows":"undefined", "isFocus":false
},
{
"type":"button",
"id":"4", "value":{ "local":"", "english":"" },
"label":{ "local":"Enter", "english":"Enter" }, "color":"000000",
"fontsize":14, "fontstyle":"strong", "alignment":"right",18
"rows":"undefined", "isFocus":false
}
]
},
"authToken":"0fdd440a-619f-4936-ab74-d189accb5bd9",
"routing":{
"controller":"panel",
"action":"process",
"workflowId":"singlepicking",
"taskId":"orderSelection"
}
}
}
Thank you for your help!
it looks a little bit different but your answer helped me! Thx
JsonParser parser = new JsonParser();
JsonObject obj = parser.parse(br).getAsJsonObject();
//now getting all the json values
String status = obj.get("status").getAsString();
JsonObject data = obj.getAsJsonObject("data");
String authToken = data.get("authToken").getAsString();
JsonObject routing = data.getAsJsonObject("routing");
String controller = routing.get("controller").getAsString();
String action = routing.get("action").getAsString();
String workflowId = routing.get("taskId").getAsString();
If I understood ur question properly u can retrieve the values of the JSONArray as below
for (int i = 0; i < JArray.length(); i++) {
print(JArray.getJSONObject(i).tostring())
}
So if i am right u are getting the JSON from a String First?? so please try below first store the String in JSONObject as JSONObject obj = new JSONObject(str);//str is the string that u are getting
to get the valueenglish that are in data-panel-tittle-label is
String englishinLable=obj .getJSONObject("data").getJSONObject("panel").getJSONObject("title").getJSONObject("label").optString("english")

Categories

Resources