如何在 Java 中使用 Google API 服务 SDK 构建计算客户端

How to build a Compute client using the Google API Services SDK in Java

我正在尝试基于密钥 .JSON 文件构建计算客户端。我正在查看 the examples found here,但它们已过时且不再有效。

我在 current offical docs here 中找不到任何示例。

这是我目前正在尝试的:

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.jackson2.JacksonFactory;
import com.google.api.services.compute.Compute;
import com.google.api.services.compute.model.Instance;
import com.google.api.services.compute.model.InstanceList;

import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;

public class Application {
    private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

    public static void main(String[] args) throws IOException, GeneralSecurityException {
        InputStream credentialsJSON = Application.class.getClassLoader().getResourceAsStream("mykey.json");
        JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
        HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
        GoogleCredential cred = GoogleCredential.fromStream(credentialsJSON ,httpTransport,JSON_FACTORY);

        // Create Compute Engine object for listing instances.
        Compute compute = new Compute.Builder(httpTransport, JSON_FACTORY, cred.getRequestInitializer())
                .setApplicationName("myapplication")
                .build();

        InstanceList instanceList = compute.instances().list("PROJECT_NAME", "europe-west3-a").execute();
        for (Instance instance : instanceList.getItems()) {
            System.out.println(instance.getId());
        }
    }
}

但它抛出以下错误:

Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
{
  "code" : 401,
  "errors" : [ {
    "domain" : "global",
    "location" : "Authorization",
    "locationType" : "header",
    "message" : "Login Required.",
    "reason" : "required"
  } ],
  "message" : "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
  "status" : "UNAUTHENTICATED"
}

我不明白,因为文件已正确解析。另外,我使用的 GoogleCredential 模型似乎已被弃用。

您需要这两个依赖项:

<dependencies>
    <dependency>
        <groupId>com.google.apis</groupId>
        <artifactId>google-api-services-compute</artifactId>
        <version>v1-rev20200311-1.30.9</version>
    </dependency>

    <dependency>
        <groupId>com.google.auth</groupId>
        <artifactId>google-auth-library-oauth2-http</artifactId>
        <version>0.20.0</version>
    </dependency>
</dependencies>

可以找到 google-auth-library-oauth2-http 依赖库 here。切换到这种新方法对我有用。

这是工作代码:

import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.compute.Compute;
import com.google.api.services.compute.ComputeScopes;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;

import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;

public class GCPComputeClientHelper {
    private static Compute compute = null;

    protected GCPComputeClientHelper() {
        // Exists only to defeat instantiation
    }

    public static Compute getComputeInstance() throws GeneralSecurityException, IOException {
        if (compute == null) {
            compute = build();
        }
        return compute;
    }

    private static Compute build() throws GeneralSecurityException, IOException {
        // Create http transporter needed for Compute client
        HttpTransport HTTP_TRANSPORTER = GoogleNetHttpTransport.newTrustedTransport();

        // Read GCP service account credentials JSON key file
        InputStream serviceAccountJsonKey = GCPComputeClientHelper.class.getClassLoader().getResourceAsStream("mykeyfile.json");

        // Authenticate based on the JSON key file
        GoogleCredentials credentials = GoogleCredentials.fromStream(serviceAccountJsonKey);
        credentials = credentials.createScoped(ComputeScopes.CLOUD_PLATFORM);
        HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials);

        // Create and return GCP Compute client
        return new Compute.Builder(HTTP_TRANSPORTER, JacksonFactory.getDefaultInstance(), requestInitializer)
                .setApplicationName("myapplication")
                .build();
    }

}