Using Java Callout to call Google analytics Reporting API v4

Hello everyone,

I try to call Reporting API v4

through Java Callout policy, but Apigee X returns this error :

 

{
    "fault": {
        "faultstring": "Failed to execute JavaCallout. com/google/api/client/googleapis/javanet/GoogleNetHttpTransport",
        "detail": {
            "errorcode": "steps.javacallout.ExecutionError"
        }
    }
}

 

Here is Java code i use :

 

package com.apigeesg.callout;

import com.apigee.flow.execution.ExecutionContext;
import com.apigee.flow.execution.ExecutionResult;
import com.apigee.flow.execution.spi.Execution;
import com.apigee.flow.message.MessageContext;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.analyticsreporting.v4.AnalyticsReporting;
import com.google.api.services.analyticsreporting.v4.AnalyticsReportingScopes;
import com.google.api.services.analyticsreporting.v4.model.*;

import java.io.FileInputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class HelloAnalyticsReporting implements Execution {
    private static final String APPLICATION_NAME = "Hello Analytics Reporting";
    private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
    private static final String KEY_FILE_LOCATION = "client_secrets.json";
    private static final String VIEW_ID = "26*********";
    
    public ExecutionResult execute(MessageContext messageContext, ExecutionContext executionContext) {

        try {

            AnalyticsReporting service = initializeAnalyticsReporting();

            GetReportsResponse response = getReport(service);
            printResponse(response);

            messageContext.setVariable("content.response", response);

            return ExecutionResult.SUCCESS;

        } catch (Exception e) {
            return ExecutionResult.ABORT;
        }
    }

    /**
     * Initializes an Analytics Reporting API V4 service object.
     *
     * @return An authorized Analytics Reporting API V4 service object.
     * @throws IOException
     * @throws GeneralSecurityException
     */
    private static AnalyticsReporting initializeAnalyticsReporting() throws GeneralSecurityException, IOException {

        HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
        GoogleCredential credential = GoogleCredential
                .fromStream(new FileInputStream(KEY_FILE_LOCATION))
                .createScoped(AnalyticsReportingScopes.all());

        // Construct the Analytics Reporting service object.
        return new AnalyticsReporting.Builder(httpTransport, JSON_FACTORY, credential)
                .setApplicationName(APPLICATION_NAME).build();
    }

    /**
     * Queries the Analytics Reporting API V4.
     *
     * @param service An authorized Analytics Reporting API V4 service object.
     * @return GetReportResponse The Analytics Reporting API V4 response.
     * @throws IOException
     */
    private static GetReportsResponse getReport(AnalyticsReporting service) throws IOException {
        // Create the DateRange object.
        DateRange dateRange = new DateRange();
        dateRange.setStartDate("7DaysAgo");
        dateRange.setEndDate("today");

        // Create the Metrics object.
        Metric sessions = new Metric()
                .setExpression("ga:sessions")
                .setAlias("sessions");

        Dimension pageTitle = new Dimension().setName("ga:pageTitle");

        // Create the ReportRequest object.
        ReportRequest request = new ReportRequest()
                .setViewId(VIEW_ID)
                .setDateRanges(Arrays.asList(dateRange))
                .setMetrics(Arrays.asList(sessions))
                .setDimensions(Arrays.asList(pageTitle));

        ArrayList<ReportRequest> requests = new ArrayList<ReportRequest>();
        requests.add(request);

        // Create the GetReportsRequest object.
        GetReportsRequest getReport = new GetReportsRequest()
                .setReportRequests(requests);

        // Call the batchGet method.
        GetReportsResponse response = service.reports().batchGet(getReport).execute();

        // Return the response.
        return response;
    }

    /**
     * Parses and prints the Analytics Reporting API V4 response.
     *
     * @param response An Analytics Reporting API V4 response.
     */
    private static void printResponse(GetReportsResponse response) {

        for (Report report: response.getReports()) {
            ColumnHeader header = report.getColumnHeader();
            List<String> dimensionHeaders = header.getDimensions();
            List<MetricHeaderEntry> metricHeaders = header.getMetricHeader().getMetricHeaderEntries();
            List<ReportRow> rows = report.getData().getRows();

            if (rows == null) {
                System.out.println("No data found for " + VIEW_ID);
                return;
            }

            for (ReportRow row: rows) {
                List<String> dimensions = row.getDimensions();
                List<DateRangeValues> metrics = row.getMetrics();

                for (int i = 0; i < dimensionHeaders.size() && i < dimensions.size(); i++) {
                    System.out.println(dimensionHeaders.get(i) + ": " + dimensions.get(i));
                }

                for (int j = 0; j < metrics.size(); j++) {
                    System.out.print("Date Range (" + j + "): ");
                    DateRangeValues values = metrics.get(j);
                    for (int k = 0; k < values.getValues().size() && k < metricHeaders.size(); k++) {
                        System.out.println(metricHeaders.get(k).getName() + ": " + values.getValues().get(k));
                    }
                }
            }
        }
    }

}

 

Anyone know how to resolve this ?
@dchiesa1  

 

Solved Solved
0 3 570
1 ACCEPTED SOLUTION

Yes - assuming you are using Apigee X, you can use GoogleAuthentication. Follow the steps mentioned here. You just need the service account with the role assigned to it and then configure the Service Account User permissions as described there. No need to download the JSON file. You will need to provide the Service account email when deploying the proxy. So the HTTPTargetConnection in the TargetEndpoint config will look something like this

 

<HTTPTargetConnection>
    <Authentication>
        <GoogleAccessToken>
            <Scopes>
                <Scope>https://www.googleapis.com/auth/analytics</Scope>
            </Scopes>
        </GoogleAccessToken>
    </Authentication>
    <URL>https://analyticsreporting.googleapis.com/v4/reports:batchGet</URL>
</HTTPTargetConnection>

 

 

View solution in original post

3 REPLIES 3

@Manu33 - Why does it have to be a Java callout?

Can you not hit the API directly - I found their REST documentation here

Hi @ssvaidyanathan , thanks for your response.

I tried to switch to the API directly, but i can't solve/handle the google OAuth2 authentication on Apigee.

That's why i used Java with a Json file (client_secrets) for authentication.

Do you have any idea of how to perform a google oauth2 authentication on Apigee in order to use API directly ?

Yes - assuming you are using Apigee X, you can use GoogleAuthentication. Follow the steps mentioned here. You just need the service account with the role assigned to it and then configure the Service Account User permissions as described there. No need to download the JSON file. You will need to provide the Service account email when deploying the proxy. So the HTTPTargetConnection in the TargetEndpoint config will look something like this

 

<HTTPTargetConnection>
    <Authentication>
        <GoogleAccessToken>
            <Scopes>
                <Scope>https://www.googleapis.com/auth/analytics</Scope>
            </Scopes>
        </GoogleAccessToken>
    </Authentication>
    <URL>https://analyticsreporting.googleapis.com/v4/reports:batchGet</URL>
</HTTPTargetConnection>