计算引擎API调用失败,并使用http 404 [英] Compute Engine API call fails with http 404

查看:102
本文介绍了计算引擎API调用失败,并使用http 404的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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 =;

//创建HTTPRequest并设置标题
HTTPRequest httpRequest = new HTTPRequest(new URL(url.toString()),
HTTPMethod.GET,FetchOptions.Builder.doNotFollowRedirects() );

httpRequest.addHeader(新的HTTPHeader(Authorization,OAuth
+ accessToken));

httpRequest.addHeader(new HTTPHeader(Host,www.googleapis.com));
httpRequest.addHeader(new HTTPHeader(Content-Length,Integer
.toString(payload.length())));
httpRequest.addHeader(新的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(); $(b)if((responseCode == 200)||(responseCode == 204)){
String contentStr = new String(httpResponse.getContent());
返回extractIpsAndInstanceNames(contentStr,前缀);
} else {
logger.warning(Failed。Response code+ responseCode
+Reason:+ new String(httpResponse.getContent()));





$ b

正如你所看到的,我正在使用AppIdentity来获取访问令牌。然后在API调用的请求标头中使用它。



基本上每次调用失败时都会出现以下错误:

 失败。响应代码404原因:{
错误:{
errors:[
{
domain:global,
reason:
message:资源'projects / MYPROJECTID'未找到
}
],
code:404,
消息:找不到资源'projects / MYPROJECTID'
}
}

有趣的是,如果我使用以下webapp https://developers.google.com/compute/docs/reference/latest/instances/list#try-it ,以使相同的API调用成功。



因此,我研究了这个Web应用程序发出请求时发送的数据,并复制了不记名令牌字符串,并将其用于授权标题中。奇怪的是,请求现在已经成功完成了,而没有改变其他任何东西基本上,该应用程序使用用户同意Oauth2类型的令牌 - 对我来说,它看起来像通过AppIdentity获得的令牌有一些问题。
有人能指出我正确的方向吗?感谢!

解决方案

我碰到同样的问题,并能解决它,或者我应该说它的解决方法,在对我来说没有完全意义的方式。希望有这方面真正知识的人可以进一步解释。这个解决方案类似于E. Anderson所回答的,但与App Engine和Compute Engine在同一个项目中不同。



以下是我所做的:


  1. 在真实运行的应用程序引擎中(不是在本地开发人员模式下)打印服务帐户电子邮件。使用Go运行时,我使用 appengine.ServiceAccount(ctx)

  2. Google Developers Console ,进入您的项目的权限页面,并将您在上一步中获得的电子邮件地址添加为您项目的成员。

一旦我这样做了,我就可以从App Engine向Compute Engine REST API发出请求。我不知道为什么这一步是必要的。


I need a bit of help with Google Compute Engine API call from within App Engine code. Following is part of code that I use to get a list of compute engine instances (simplified version)

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

As you can see I am using AppIdentity to obtain access token. Then use it in request header in API call.

Basically every time the call fails with following error

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

What is interesting is that if I use following webapp https://developers.google.com/compute/docs/reference/latest/instances/list#try-it to make the same API call it succeeds.

So I looked into what data are sent when this web app makes request and copied bearer token string and used it in "Authorization" header. Strangely enough request now finished successfully without changing anything else. Basically that app uses user consent Oauth2 type of token - so for me it looks like there is some problem with token obtained via AppIdentity. Could someone point me in right direction? Thanks!

解决方案

I ran into the same issue and was able to solve it, or perhaps I should say workaround it, in a way that doesn't make complete sense to me. Hopefully someone with real knowledge on the subject can explain further. This solution is similar to what E. Anderson answered, but different because both App Engine and Compute Engine were in the same project.

Here's what I did:

  1. In app engine running for real (not in the local developer mode) print out the service account email. Using the Go runtime, I used appengine.ServiceAccount(ctx).
  2. In Google Developers Console, go to the Permissions page for your project and add the e-mail address you obtained in the previous step as a member of your project.

Once I did this, I was able to make requests to Compute Engine REST APIs from App Engine. I have no idea why this step was necessary.

这篇关于计算引擎API调用失败,并使用http 404的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆