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!