暂停使用 Java 的 Google Cloud Platform 实例。

huangapple go评论108阅读模式
英文:

Suspend Google Cloud Platform instance using Java

问题

我有一个Java Web应用程序,在其中创建GCP虚拟机实例并对它们执行操作。

我使用Java Compute Engine API执行诸如创建、启动、停止等任务。

我想执行以下操作:

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

然而,我无法使用这个API来“暂停”虚拟机,因为“暂停”是测试版本(它不是Compute Engine v1 API的一部分,因此也不是Java封装的一部分)。

据我所见,我有两个选项来解决这个问题,但都没有成功完成:

  1. 创建一个Java类“ComputeBeta”,继承自Compute类,并实现一个Suspend类来执行操作。问题在于原始Compute类中的URL字段是final字段,因此无法将URL从“v1”更改为“beta” URL。

  2. 执行一个“常规”http连接到GCP beta API,以暂停虚拟机。问题在于我无法找到正确的API身份验证语法,并且一直收到401响应。我迄今为止尝试过以下内容:

  1. String serviceAccountKey = getServiceAccountKey();
  2. String baseUrl = "https://compute.googleapis.com";
  3. String endpoint = "/compute/beta/projects/" + getOrder().getProject()
  4. + "/zones/" + getOrder().getAvailabilityZone() + "/instances/"
  5. + getOrder().getMachineName() + "/suspend";
  6. URL serverUrl = new URL(baseUrl + endpoint);
  7. httpConnection = (HttpsURLConnection)serverUrl.openConnection();
  8. httpConnection.setRequestMethod(HttpMethods.POST);
  9. httpConnection.setDoOutput(true);
  10. httpConnection.setDoInput(true);
  11. httpConnection.setFixedLengthStreamingMode(length);
  12. httpConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
  13. httpConnection.setRequestProperty("Authorization", "Bearer " + serviceAccountKey);
  14. httpConnection.connect();
  15. int responseCode = httpConnection.getResponseCode();
  16. String responseMessage = httpConnection.getResponseMessage();

非常感谢您提供进一步的帮助!

英文:

I have a Java web application in which I create GCP VM instances and perform operations on them.

I use the Java Compute Engine API to perform tasks such as creation, start, stop etc.

I wanted to perfrom:

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

However, I cannot "Suspend" a machine with this API as "Suspend" is in beta version (it is not part of the Compute Engine v1 API so it is not part of the Java wrapper).

As I see it I have two options to solve this problem, neither of which I have been able to complete:

  1. Create a Java class "ComputeBeta" which inherits the Compute class and implement a Suspend class to execute the operation. This is problematic as the URL field in the original Compute class is a final field, so I can not change the URL from the "v1" to the "beta" url.

  2. Execute a "regular" httpconnection to the GCP beta API in order to suspend the machine. The problem here is that I have not been able to find the correct syntax of the authentication to the API and have been getting a 401 response. What I have tried so far:

  1. String serviceAccountKey = getServiceAccountKey();
  2. String baseUrl = "https://compute.googleapis.com";
  3. String endpoint = "/compute/beta/projects/" + getOrder().getProject()
  4. + "/zones/" + getOrder().getAvailabilityZone() + "/instances/"
  5. + getOrder().getMachineName() + "/suspend";
  6. URL serverUrl = new URL(baseUrl + endpoint);
  7. httpConnection = (HttpsURLConnection)serverUrl.openConnection();
  8. httpConnection.setRequestMethod(HttpMethods.POST);
  9. httpConnection.setDoOutput(true);
  10. httpConnection.setDoInput(true);
  11. httpConnection.setFixedLengthStreamingMode(length);
  12. httpConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
  13. httpConnection.setRequestProperty("Authorization", "Bearer " + serviceAccountKey);
  14. httpConnection.connect();
  15. int responseCode = httpConnection.getResponseCode();
  16. String responseMessage = httpConnection.getResponseMessage();

Any assistance on how to move forward will be greatly appreciated!

答案1

得分: 2

你不必像这样使用你的服务帐户密钥。这个密钥允许你创建凭据,然后用它生成令牌。

  1. GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
  2. // 你也可以像这样显式地使用你的服务帐户密钥文件
  3. // GoogleCredentials credentials = GoogleCredentials.fromStream(this.getClass().getResourceAsStream("my_key_file.json"));
  4. String token = credentials.refreshAccessToken().getTokenValue();
  5. ...
  6. httpConnection.setRequestProperty("Authorization", "Bearer " + token);

你还可以使用Google Transport工厂来避免手动添加授权头部

  1. GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
  2. // 你也可以像这样显式地使用你的服务帐户密钥文件
  3. // GoogleCredentials credentials = GoogleCredentials.fromStream(this.getClass().getResourceAsStream("my_key_file.json"));
  4. HttpRequestFactory factory = new NetHttpTransport().createRequestFactory(new HttpCredentialsAdapter(credentials));
  5. // 这里是一个GET请求,但你也可以构建一个POST请求
  6. HttpRequest request = factory.buildGetRequest(new GenericUrl("YOUR_URL"));
  7. HttpResponse httpResponse = request.execute();
  8. System.out.println(CharStreams.toString(new InputStreamReader(httpResponse.getContent(), Charsets.UTF_8)));

如果你遇到依赖问题(通常不会,因为你使用计算引擎库已经包括了它),你可以添加这个依赖

  1. <dependency>
  2. <groupId>com.google.auth</groupId>
  3. <artifactId>google-auth-library-oauth2-http</artifactId>
  4. <version>0.21.1</version>
  5. </dependency>
英文:

You don't have to use your service account key like this. This key allow you to create a credential and then to generate token with it.

  1. GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
  2. // You can use explicitly your service account key file like this
  3. // GoogleCredentials credentials = GoogleCredentials.fromStream(this.getClass().getResourceAsStream(&quot;my_key_file.json&quot;));
  4. String token = credentials.refreshAccessToken().getTokenValue();
  5. ...
  6. httpConnection.setRequestProperty(&quot;Authorization&quot;, &quot;Bearer &quot; + token);

You can also use the Google Transport factory to avoid to add manually the authorization header

  1. GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
  2. // You can use explicitly your service account key file like this
  3. // GoogleCredentials credentials = GoogleCredentials.fromStream(this.getClass().getResourceAsStream(&quot;my_key_file.json&quot;));
  4. HttpRequestFactory factory = new NetHttpTransport().createRequestFactory(new HttpCredentialsAdapter(credentials));
  5. // Here a GET request, but you can build a POST request also
  6. HttpRequest request = factory.buildGetRequest(new GenericUrl(&quot;YOUR_URL&quot;));
  7. HttpResponse httpResponse = request.execute();
  8. System.out.println(CharStreams.toString(new InputStreamReader(httpResponse.getContent(), Charsets.UTF_8)));

If you have dependency issue (normally not because you use the compute engine library that include it), you can add this dependency

  1. &lt;dependency&gt;
  2. &lt;groupId&gt;com.google.auth&lt;/groupId&gt;
  3. &lt;artifactId&gt;google-auth-library-oauth2-http&lt;/artifactId&gt;
  4. &lt;version&gt;0.21.1&lt;/version&gt;
  5. &lt;/dependency&gt;

huangapple
  • 本文由 发表于 2020年9月30日 15:31:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/64132859.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定