我需要一些关于从 App Engine 代码中调用 Google Compute Engine API 的帮助。以下是我用来获取计算引擎实例列表的部分代码(简化版)
try {
final AppIdentityService appIdService = AppIdentityServiceFactory
.getAppIdentityService();
AppIdentityService.GetAccessTokenResult result = appIdService
.getAccessTokenUncached(Collections
.singletonList(ComputeScopes.COMPUTE));
String accessToken = result.getAccessToken();
String url = "https://www.googleapis.com/compute/v1/projects/MYPROJECTID/zones/us-central1-b/instances";
String payload = "";
// Create HTTPRequest and set headers
HTTPRequest httpRequest = new HTTPRequest(new URL(url.toString()),
HTTPMethod.GET, FetchOptions.Builder.doNotFollowRedirects());
httpRequest.addHeader(new HTTPHeader("Authorization", "OAuth "
+ accessToken));
httpRequest.addHeader(new HTTPHeader("Host", "www.googleapis.com"));
httpRequest.addHeader(new HTTPHeader("Content-Length", Integer
.toString(payload.length())));
httpRequest.addHeader(new HTTPHeader("Content-Type",
"application/json"));
httpRequest.addHeader(new HTTPHeader("User-Agent",
"google-api-java-client/1.0"));
httpRequest.setPayload(payload.getBytes());
URLFetchService fetcher = URLFetchServiceFactory
.getURLFetchService();
HTTPResponse httpResponse = fetcher.fetch(httpRequest);
int responseCode = httpResponse.getResponseCode();
if ((responseCode == 200) || (responseCode == 204)) {
String contentStr = new String(httpResponse.getContent());
return extractIpsAndInstanceNames(contentStr, prefix);
} else {
logger.warning("Failed. Response code " + responseCode
+ " Reason: " + new String(httpResponse.getContent()));
}
如您所见,我正在使用 AppIdentity 获取访问 token 。然后在 API 调用的请求 header 中使用它。
基本上每次调用失败并出现以下错误
Failed. Response code 404 Reason: {
"error": {
"errors": [
{
"domain": "global",
"reason": "notFound",
"message": "The resource 'projects/MYPROJECTID' was not found"
}
],
"code": 404,
"message": "The resource 'projects/MYPROJECTID' was not found"
}
}
有趣的是,如果我使用以下 webapp https://developers.google.com/compute/docs/reference/latest/instances/list#try-it进行相同的 API 调用它会成功。
所以我查看了当这个网络应用发出请求时发送了哪些数据,并复制了不记名 token 字符串并将其用于“授权” header 中。奇怪的是,请求现在已成功完成,无需更改任何其他内容。基本上,该应用程序使用用户同意 Oauth2 类型的 token - 所以对我来说,通过 AppIdentity 获得的 token 似乎存在一些问题。 有人能指出我正确的方向吗?谢谢!
最佳答案
我遇到了同样的问题,并且能够解决它,或者我应该说解决方法,但对我来说并不完全有意义。希望对这个问题有真正了解的人可以进一步解释。此解决方案与 E. Anderson 的回答类似,但有所不同,因为 App Engine 和 Compute Engine 都在同一个项目中。
这是我做的:
- 在真正运行的 App Engine 中(不是在本地开发人员模式下)打印出服务帐户电子邮件。在 Go 运行时,我使用了
appengine.ServiceAccount(ctx)
。 - 在Google Developers Console ,转到项目的“权限”页面,并将您在上一步中获得的电子邮件地址添加为项目成员。
完成此操作后,我就能够从 App Engine 向 Compute Engine REST API 发出请求。我不知道为什么需要这一步。
关于google-app-engine - Compute Engine API 调用失败并显示 http 404,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21062286/