3

Short question: How do I convert the following java code to ColdFusion code?

private static HttpRequestInitializer setHttpTimeout(final HttpRequestInitializer requestInitializer) {
      return new HttpRequestInitializer() {
        @Override
        public void initialize(HttpRequest httpRequest) throws IOException {
          requestInitializer.initialize(httpRequest);
          httpRequest.setConnectTimeout(3 * 60000);  // 3 minutes connect timeout
          httpRequest.setReadTimeout(3 * 60000);  // 3 minutes read timeout
        }};

 }

Explanation: I use a component to communicate with the google analytics API. This works great however sometimes a read timeout occurs. I would like to increase the connection and read time out. I found a post here on StackOverflow explaining how to do this in Java (https://stackoverflow.com/a/30721185/2482184). However, I am having trouble converting the java code to ColdFusion code. Below the ColdFusion component I currently use to communicate with Google Analytics API:

<cfcomponent displayname="cfanalyticsConnector" output="false">

    <cffunction name="init" access="public" output="false" returntype="cfanalyticsConnector">
        <cfargument name="serviceAccountId" type="string" required="true" />
        <cfargument name="pathToKeyFile" type="string" required="true" />
        <cfargument name="analyticsAppName" type="string" required="true" />
        <cfscript>
            variables.serviceAccountId         = arguments.serviceAccountId;
            variables.pathToKeyFile            = arguments.pathToKeyFile;
            variables.analyticsAppName         = arguments.analyticsAppName;

            variables.HTTP_Transport           = createObject("java", "com.google.api.client.http.javanet.NetHttpTransport").init();
            variables.JSON_Factory             = createObject("java", "com.google.api.client.json.jackson2.JacksonFactory").init();
            variables.HTTP_Request_Initializer = createObject("java", "com.google.api.client.http.HttpRequestInitializer");
            variables.Credential_Builder       = createObject("java", "com.google.api.client.googleapis.auth.oauth2.GoogleCredential$Builder");

            variables.Analytics_Scopes         = createObject("java", "com.google.api.services.analytics.AnalyticsScopes");
            variables.Analytics_Builder        = createObject("java", "com.google.api.services.analytics.Analytics$Builder").init(
                                                                         variables.HTTP_Transport, 
                                                                         variables.JSON_Factory, 
                                                                         javaCast("null", ""));
                                                                        
            variables.Collections              = createObject("java", "java.util.Collections");
            variables.File_Obj                 = createObject("java", "java.io.File");

            variables.credential               = "";
            variables.analytics                = "";
        </cfscript>
        <cfreturn this />
    </cffunction>

    <cffunction name="buildAnalytics" access="public" output="true" returntype="struct" hint="creates analytics object">
        <cfset local = {} />
        <cfset local.credential = "" />
        <cfset local.returnStruct = {} />
        <cfset local.returnStruct.success = true />
        <cfset local.returnStruct.error = "" />

        <!--- Access tokens issued by the Google OAuth 2.0 Authorization Server expire in one hour. 
        When an access token obtained using the assertion flow expires, then the application should 
        generate another JWT, sign it, and request another access token. 
        https://developers.google.com/accounts/docs/OAuth2ServiceAccount --->

        <cftry>
             <cfset local.credential = Credential_Builder
                            .setTransport(variables.HTTP_Transport)
                            .setJsonFactory(variables.JSON_Factory)
                            .setServiceAccountId(variables.serviceAccountId)
                            .setServiceAccountScopes(Collections.singleton(variables.Analytics_Scopes.ANALYTICS_READONLY))
                            .setServiceAccountPrivateKeyFromP12File(variables.File_Obj.Init(variables.pathToKeyFile))
                            .build() />

            <cfcatch type="any">
                <cfset local.returnStruct.error = "Credential Object Error: " & cfcatch.message & " - " & cfcatch.detail />
                <cfset local.returnStruct.success = false />
            </cfcatch>
        </cftry>

        <cfif  local.returnStruct.success>
            <cftry>
                <cfset variables.analytics = variables.Analytics_Builder
                                .setApplicationName(variables.analyticsAppName)
                                .setHttpRequestInitializer(local.credential)
                                .build() />

                <cfcatch type="any">
                    <cfset local.returnStruct.error = "Analytics Object Error: " & cfcatch.message & " - " & cfcatch.detail />
                    <cfset local.returnStruct.success = false />
                </cfcatch>
            </cftry>
        </cfif>
        
        <cfreturn local.returnStruct />
    </cffunction>
</cfcomponent>

The java code explaining how to increase the connection and read time out:

private static HttpRequestInitializer setHttpTimeout(final HttpRequestInitializer requestInitializer) {
      return new HttpRequestInitializer() {
        @Override
        public void initialize(HttpRequest httpRequest) throws IOException {
          requestInitializer.initialize(httpRequest);
          httpRequest.setConnectTimeout(3 * 60000);  // 3 minutes connect timeout
          httpRequest.setReadTimeout(3 * 60000);  // 3 minutes read timeout
        }};

 }

public static Analytics initializeAnalytics() throws Exception {
    // Initializes an authorized analytics service object.

    // Construct a GoogleCredential object with the service account email
    // and p12 file downloaded from the developer console.
    HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
    GoogleCredential credential = new GoogleCredential.Builder()
        .setTransport(httpTransport)
        .setJsonFactory(JSON_FACTORY)
        .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
        .setServiceAccountPrivateKeyFromP12File(new File(KEY_FILE_LOCATION))
        .setServiceAccountScopes(AnalyticsScopes.all())
        .build();

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

If I understand correctly I need to alter this line of code:

<cfset variables.analytics = variables.Analytics_Builder
    .setApplicationName(variables.analyticsAppName)
    .setHttpRequestInitializer(local.credential)
    .build() />

To something like:

<cfset variables.analytics = createObject("java",
    "com.google.api.services.analytics.Analytics$Builder").init(
        variables.HTTP_Transport, 
        variables.JSON_Factory, 
        setHttpTimeout(local.credential)
    )
    .setApplicationName(variables.analyticsAppName)
    .setHttpRequestInitializer(local.credential)
    .build() />
>

Howerer I have not been succesfull in coverting the java setHttpTimeout function to coldfusion. Any help would be greatly appreciated.

Nebu
  • 1,753
  • 1
  • 17
  • 33
  • 1
    The function implements a java *interface* `HttpRequestInitializer`. To do that in CF you must use a [dynamic proxy](https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-c-d/CreateDynamicProxy.html). Create a CFC which implements the function `public void initialize(HttpRequest httpRequest)....`. Then use `createDynamicProxy()` to create an instance of the CFC. Then use the instance instead of `setHttpTimeout(local.credential)`. – SOS Dec 23 '20 at 20:08
  • This thread looks old, but outlines the process https://stackoverflow.com/questions/28244067/how-can-i-implement-a-java-interface-from-coldfusion – SOS Dec 23 '20 at 20:09

1 Answers1

0

To create a 3 minute request timeout you can call this line of code prior to making your http request.

Tag format

<cfsetting RequestTimeout = 3 * 60>

CFScript format

setting requesttimeout = 3 * 60;
user12031119
  • 1,228
  • 4
  • 14
  • True for CF requests, but they're trying to do something different - modify the request settings of a separate java library. – SOS Dec 23 '20 at 20:11