Request multiple elements from Adobe's SiteCatalyst using Java

544 views Asked by At

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??

2

There are 2 answers

1
CrayonViolent On

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
}
0
P. Str On

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!!