Приостановить экземпляр Google Cloud Platform с помощью Java

У меня есть веб-приложение Java, в котором я создаю экземпляры виртуальных машин GCP и выполняю над ними операции.

Я использую API Java Compute Engine для выполнения таких задач, как создание, запуск, остановка и т. Д.

Я хотел выполнить:

Compute compute = getComputeObj();
Suspend suspend = compute.instances().suspend(getProjectId(), getOrder().getAvailabilityZone(), getOrder().getMachineName());
Operation response = suspend .execute();

Однако я не могу "Приостановить" машину с этим API, поскольку "Приостановка" находится в бета-версии (она не является частью API Compute Engine v1, поэтому не является частью оболочки Java).

На мой взгляд, у меня есть два варианта решения этой проблемы, ни один из которых мне не удалось выполнить:

  1. Создайте Java-класс ComputeBeta, который наследует класс Compute, и реализуйте класс Suspend для выполнения операции. Это проблематично, поскольку поле URL-адреса в исходном классе Compute является последним полем, поэтому я не могу изменить URL-адрес с "v1" на "beta".

  2. Выполните "обычное" http-соединение с API бета-версии GCP, чтобы приостановить работу компьютера. Проблема здесь в том, что я не смог найти правильный синтаксис аутентификации для API и получил ответ 401. Что я пробовал до сих пор:

String serviceAccountKey = getServiceAccountKey();

String baseUrl = "https://compute.googleapis.com";

String endpoint = "/compute/beta/projects/" + getOrder().getProject() 
                + "/zones/" + getOrder().getAvailabilityZone() + "/instances/" 
                + getOrder().getMachineName() + "/suspend";

URL serverUrl = new URL(baseUrl + endpoint);

httpConnection = (HttpsURLConnection)serverUrl.openConnection();
httpConnection.setRequestMethod(HttpMethods.POST);
httpConnection.setDoOutput(true);
httpConnection.setDoInput(true);


httpConnection.setFixedLengthStreamingMode(length);

httpConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
httpConnection.setRequestProperty("Authorization", "Bearer " + serviceAccountKey);
httpConnection.connect();

int responseCode = httpConnection.getResponseCode();
String responseMessage = httpConnection.getResponseMessage();

Мы будем благодарны за любую помощь в продвижении вперед!

1 ответ

Решение

Вам не обязательно использовать ключ своей учетной записи таким образом. Этот ключ позволяет вам создать учетные данные, а затем сгенерировать с ними токен.

 GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
// You can use explicitly your service account key file like this
// GoogleCredentials credentials = GoogleCredentials.fromStream(this.getClass().getResourceAsStream("my_key_file.json"));

 String token = credentials.refreshAccessToken().getTokenValue();
...
 httpConnection.setRequestProperty("Authorization", "Bearer " + token);

Вы также можете использовать фабрику транспорта Google, чтобы не добавлять вручную заголовок авторизации.

 GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
// You can use explicitly your service account key file like this
// GoogleCredentials credentials = GoogleCredentials.fromStream(this.getClass().getResourceAsStream("my_key_file.json"));

HttpRequestFactory factory = new NetHttpTransport().createRequestFactory(new HttpCredentialsAdapter(credentials));
// Here a GET request, but you can build a POST request also
HttpRequest request = factory.buildGetRequest(new GenericUrl("YOUR_URL"));
HttpResponse httpResponse = request.execute();
System.out.println(CharStreams.toString(new InputStreamReader(httpResponse.getContent(), Charsets.UTF_8)));

Если у вас есть проблема с зависимостью (обычно не потому, что вы используете библиотеку вычислительного движка, которая ее включает), вы можете добавить эту зависимость

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