2014-01-11 18 views
3

我需要在App Engine代碼中使用Google Compute Engine API調用的一些幫助。以下是代碼的一部分,我用它來獲取計算引擎實例的列表(簡體版)計算引擎API調用失敗,使用http 404

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獲得訪問令牌。然後在API調用的請求頭中使用它。每次調用失敗與以下錯誤時間

基本上

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調用它成功。

因此,我研究了當這個Web應用程序發出請求並複製持票人標記字符串並在「授權」標題中使用它時會發送什麼數據。奇怪的是,請求現在已經成功完成了,而沒有改變其他任何東西基本上,該應用程序使用用戶同意Oauth2類型的令牌 - 對我來說,它看起來像通過AppIdentity獲得的令牌有一些問題。 有人能指引我正確的方向嗎?謝謝!

+0

我已經看到與Go運行時完全相同的問題。我正在請求使用內置的應用程序引擎服務帳戶列出來自應用程序引擎的計算圖像,並且我得到了404。然而,使用API​​瀏覽器可以正常工作。 –

+0

你有沒有解決它的運氣?我還有一個想法 - 我們的App Engine項目是在一段時間之前創建的,因爲在同一個項目中不可能有apis - 我們在稍後可用時激活它們。你有類似的設置嗎? –

+0

是的,請參閱下面的答案。 –

回答

3

我遇到了同樣的問題,並能解決它,或者我應該說它的解決方法,以一種不完全適合我的方式。希望有這方面真正知識的人可以進一步解釋。這個解決方案類似於E.安德森的回答,但不同,因爲App Engine和Compute Engine都在同一個項目中。

這裏就是我所做的:

  1. 在真正的運行(而不是在本地開發模式)的應用程序引擎打印出來的服務帳戶的電子郵件。使用Go運行時,我使用了appengine.ServiceAccount(ctx)
  2. Google Developers Console中,轉到項目的權限頁面,並將您在上一步中獲得的電子郵件地址添加爲項目成員。

一旦我這樣做了,我就可以向App Engine發出Compute Engine REST API的請求。我不知道爲什麼這一步是必要的。

+0

非常感謝,像魅力一樣工作。我在同一個項目中使用了相同的設置 - App Engine和Compute Engine,並且我沒有考慮這樣做以使其工作。 –

+1

我也沒有。我的一個朋友建議。 Google的文檔不是很有幫助。 –

+1

嗯,它看起來像默認情況下AppEngine服務帳戶目前沒有添加到項目團隊中;您可以在GAE控制檯的「應用程序設置」下找到AppEngine服務帳戶ID。 它看起來像「[email protected]」 –

1

您是否在與您嘗試管理的GCE項目相同的項目中使用了appengine應用程序?如果沒有,您需要將AppEngine應用程序的服務帳戶標識添加到GCE項目的項目團隊;請在雲端控制檯的「權限」標籤下查看您的AppEngine應用是否可以訪問GCE項目。

0

提供關於Doug的answer變體:

  1. 轉到https://appengine.google.com,選擇您的應用程序,並轉到管理>「應用程序設置」頁面。在這裏您可以找到您的服務帳戶電子郵件地址如果你想明確地添加電子郵件地址,請使用它。即如果您的計算引擎項目與您的應用程序引擎項目不同。如果是這樣的話,請按照Doug的回答。

  2. 在應用程序設置頁面的最底部,找到「雲集成」一節。整合 - 這將需要一分鐘。

  3. 如果你去https://console.developers.google.com,選擇你的項目,然後進入你的項目的權限頁面(鏈接在左邊很遠),你會發現你的app引擎服務帳戶現在顯示在服務帳戶列表中,並具有編輯權限。 404應該解決。

如果你希望你的OAuth授權代碼從開發服務器以及工作,這個答案可能會幫助:https://stackoverflow.com/a/22723127