Увеличьте время ожидания чтения API Google Analytics, конвертируйте Java-код в coldfusion

Dec 23 2020

Короткий вопрос: как преобразовать следующий код Java в код ColdFusion?

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
        }};

 }

Объяснение: я использую компонент для связи с Google Analytics API. Это отлично работает, однако иногда происходит таймаут чтения. Хочу увеличить связь и тайм-аут чтения. Я нашел здесь сообщение в StackOverflow, объясняющее, как это сделать в Java (https://stackoverflow.com/a/30721185/2482184). Однако у меня возникают проблемы с преобразованием кода Java в код ColdFusion. Ниже компонента ColdFusion, который я сейчас использую для связи с 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>

Код Java, объясняющий, как увеличить соединение и время ожидания чтения:

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();
  }

Если я правильно понимаю, мне нужно изменить эту строку кода:

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

Что-то вроде:

<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() />
>

Однако мне не удалось включить функцию java setHttpTimeout в coldfusion. Любая помощь будет принята с благодарностью.

Ответы

user12031119 Dec 23 2020 at 23:00

Чтобы создать 3-минутный тайм-аут запроса, вы можете вызвать эту строку кода перед отправкой http-запроса.

Формат тега

<cfsetting RequestTimeout = 3 * 60>

Формат CFScript

setting requesttimeout = 3 * 60;