Issue deleting instances with google API Explorer - google-compute-engine

I have tried deleting instances using https://cloud.google.com/compute/docs/reference/beta/instanceGroupManagers/deleteInstances but it's not working.
In the request body, I am entering
{
"instances": [
"scaler-group-instance-1"
]
}
For project, I used project-name-1
For zone, I used us-west1-a
For instanceGroupManager I am using scaling-group-manager
In response, I am receiving
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Invalid value for field 'instances[0]': 'scaler-group-instance-1'. The URL is malformed.",
"reason" : "invalid"
} ],
"message" : "Invalid value for field 'instances[0]': 'scaler-group-instance-1'. The URL is malformed."
}
I have also tried this in Java as well using this code snippet and have also received a 400 Bad Request
String projectId = "project-name-1";
String zoneName = "us-west1-a";
String instanceGroupName = "scaling-group-manager";
List<String> instancesToDelete = new ArrayList<>();
instancesToDelete.add("scaler-group-instance-1");
InstanceGroupManagersDeleteInstancesRequest deleteInstancesRequest = new InstanceGroupManagersDeleteInstancesRequest().setInstances(instancesToDelete);
Compute.InstanceGroupManagers.DeleteInstances deleteInstances = compute.instanceGroupManagers().deleteInstances(projectId, zoneName, instanceGroupName, deleteInstancesRequest).execute();
Is there something wrong with my request that I'm not seeing?

I found the issue. This request expects the instance string to be a URL and not an instance name.
The instance can be found in the selfLink value in the listInstances requests.
Entering the selfLink URL into the request caused the server to reply correctly.

Related

Data won't post correctly

I'm trying to use Google Apps Scripts to post to Salesforce to create a new account. I'm able to use my credentials fine to query with SOQL. When I try to post, it basically returns data as if I'm describing the Account, and the new account doesn't get created. I tried using the workbench rest API with this payload and can create an account no problem, so I know it's not an issue with fields/values.
function pushToSalesforce(){
var userProperties = PropertiesService.getUserProperties();
var instance_url = "https://na9.salesforce.com";
var access_token = userProperties.getProperty('access_token');
var payload = {
"Name" : "testaccount",
"Website" : "testaccountstuff.com",
"Platform__c" : "API",
"Industry" : "Apparel"
};
var queryUrl = instance_url + '/services/data/v26.0/sobjects/account/';
var headers =
{
"method" : "POST",
"contentType" : "application/json",
"payload": JSON.stringify(payload),
"headers": {
"Authorization" : "Bearer "+access_token,
"Accept": "application/json"
}
};
var response = UrlFetchApp.fetch(queryUrl, headers);
}
I'm going nuts trying to figure out what the issue is. Anybody have an idea?
Sounds like your app is making a GET instead of POST. Is this language / HTTP library case-sensitive? Documentation seems to use lowercase
You are supposed to send a POST to /services/data/v49.0/sobjects/Account (you're using very old API version but that shouldn't matter). What exactly do you see in response? It may look "describe'ish" but it's unlikely to be a real describe result unless you explicitly call /services/data/v49.0/sobjects/Account/describe.
A GET call to /services/data/v49.0/sobjects/Account is a discovery, a way for the API to self-document. Returns very basic info about the object, something like
{
"objectDescribe" : {
"activateable" : false,
"createable" : true,
"custom" : false,
(... snip...)
"updateable" : true,
"urls" : {
"compactLayouts" : "/services/data/v48.0/sobjects/Account/describe/compactLayouts",
"rowTemplate" : "/services/data/v48.0/sobjects/Account/{ID}",
"approvalLayouts" : "/services/data/v48.0/sobjects/Account/describe/approvalLayouts",
"defaultValues" : "/services/data/v48.0/sobjects/Account/defaultValues?recordTypeId&fields",
"listviews" : "/services/data/v48.0/sobjects/Account/listviews",
"describe" : "/services/data/v48.0/sobjects/Account/describe",
"quickActions" : "/services/data/v48.0/sobjects/Account/quickActions",
"layouts" : "/services/data/v48.0/sobjects/Account/describe/layouts",
"sobject" : "/services/data/v48.0/sobjects/Account"
}
},
"recentItems" : [ ]
}
A proper describe call would instead return info about all columns you can see in the table, all relations (foreign keys) to this object...
In my actual script was the "my domain" custom instance_url for my company (but didn't want to broadcast it), e.g. "https://companyname.lightning.force.com". I tried using my server instance "na85" instead and it worked fine! Super weird because I have another function using the other instance_url with a GET and it worked no problem. Thanks for your help!

Error when deserializing to ProblemDetails with System.Text.Json.JsonSerializer. .Net Core 3.0

Consider the following json:
{
"title": "SOME TITEL",
"status": 500,
"detail": "Some detail",
"errors": [
{
"Parameter": "SOME VALUE",
"Code": "SOME CODE",
"Message": "SOME MESSAGE",
"Details": "SOME EXTRA DETAILS"
}
]
}
It is generated by an API response that construct a problem details like this:
var problemDetails = new ProblemDetails
{
Status = StatusCodes.Status500InternalServerError;
Detail = "DETAIL";
Title = "TITLE";
};
var customClass = new CustomCalss
{
Code = "INTERNAL_SERVER_ERROR",
Message = "Some message",
Details = "Extra details"
};
problemDetails.Extensions.Add(new KeyValuePair<string, object>("errors", new [] { customClass }));
When trying to deserialize the json to a problem details using System.Text.JsonSerialiser i found the following issues:
Status, Code and Title are not deserialised to the problem details properties, they are null
Extension data is not deserialized.
I'm testing this behavior like this:
var json = #"{
""title"": ""SOME TITLE"",
""status"": 500,
""detail"": ""Some detail"",
""errors"": [
{
""Parameter"": null,
""Code"": ""SOME CODE"",
""Message"": ""SOME MESSAGE"",
""Details"": ""SOME EXTRA DETAILS""
}
]
}";
var result = JsonSerializer.Deserialize<ProblemDetails>(json);
Assert.NotNull(result.Detail);
Assert.NotNull(result.Title);
var customClass = Assert.IsType<CustomCalss[]>(result.Extensions["errors"]);
var error = customClass.First();
Assert.Equal("INTERNAL_SERVER_ERROR", error.Code);
Any insights?
C# is a case sensitive language, something wrong with your JSON string, the key must exactly same with the property of the target class. I changed the "title" to "Title" and then got the correct value, attached here for your reference:
Updated on 11/20:
Did not noticed that it is a MVC internal class, we can simple reproduce this issue in local box now, but checked the source codes and known issues online, no existing related issue there. So I reported a new bug for this issue, attached here for your reference
https://github.com/aspnet/AspNetCore/issues/17250
Updated on 11/22:
This has been confirmed as a bug in ASP.NET Core 3.0, and fixed in 3.1 version, please upgrade to 3.1-preview2. Alternatively you could specify a custom JsonConverter based on the implementation we have in 3.1 as part of the JsonSerializerOptions that you pass when deserializing - https://github.com/aspnet/AspNetCore/blob/release/3.1/src/Mvc/Mvc.Core/src/Infrastructure/ValidationProblemDetailsJsonConverter.cs

With Vimeo API, unable to create new album even with access token and create scope

I'm using Vimeo's official NodeJS API module to build an app, and I can successfully upload a video without issue. I can also set the video's privacy property successfully. Now, I would like to move that uploaded video to an album, and if the album does not exist, I want to create one automatically. I have an access token stored in a file that my application reads from, and the scopes granted to the token are the following
"scope": "interact create edit upload delete video_files private public"
So, I've got the create scope which is needed to create a new album for a user. However, when I make the request to the Vimeo API, I am getting an error of which I cannot resolve or fix.
{
"invalid_parameters":[{
"field":"name",
"error_code":2204,
"error":"You have provided an invalid parameter. Please contact developer of this application.",
"developer_message":"The parameters passed to this API endpoint did not pass Vimeo's validation. Please check the invalid_parameters list for more information."
}]
}
Here is my code that is making the request:
if (!album_uri) {
console.log("Attempting to create a new album named `" + config.params.video.group + "`");
var req_make_album = {
"method" : "POST"
, "path" : "/me/albums"
, "name" : config.params.video.group
, "description" : config.params.video.group
};
api.request(req_make_album, function(error, body, status_code, headers) {
if (error)
throw new Error(error);
step();
})
}
To be sure, the config.params.video.group variable is a string and to be certain that it was in fact a string, I replaced the request options with literal ones as such:
var req_make_album = {
"method" : "POST"
, "path" : "/me/albums"
, "name" : "My First New Album"
, "description" : "My First New Album"
};
Still, I received the above error about the "name" field being invalid. What am I missing here? When I go to the Vimeo API "playground" for this particular endpoint, it does work (even when I authenticate via my app) but I don't understand why it won't work when I make the request via the NodeJS module. Why am I getting this error?
My mistake. The issue is that the Vimeo API requires that the items "name" and "description" to be passed as an object.
So, instead of
var req_make_album = {
"method" : "POST"
, "path" : "/me/albums"
, "name" : "My First New Album"
, "description" : "My First New Album"
};
It should actually be:
var req_make_album = {
"method" : "POST"
, "path" : "/me/albums"
, "query" : {"name" : "My First New Album", "description" : "My First Album's Description"
};
The more you know :)

What is the correct way to use the fields request parameter when getting a list of StorageObjects from Google Cloud Storage?

I would like to do a lookup in the storage using the JSON API client library and only retrieve the name and generation of each object matching a specific prefix but I am having issues with the fields request parameter.
Executing the following returns the expected objects.
Storage.Objects.List listObjects = null;
listObjects.setVersions(true);
listObjects.setPrefix(myprefix);
URL being created for the request in com.google.api.client.http.HttpRequest is https://www.googleapis.com/storage/v1beta2/b/mybucketname/o?prefix=myprefix&versions=true
However, when I add
listObjects.setFields("name,generation");
with URL created being https://www.googleapis.com/storage/v1beta2/b/mybucketname/o?fields=name,generation&prefix=myprefix&versions=true the below is returned:
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"location" : "fields",
"locationType" : "parameter",
"message" : "Invalid field selection name",
"reason" : "invalidParameter"
} ],
"message" : "Invalid field selection name"
}
How am I supposed to be specifying the fields I want returned? Is the hierarchy of the fields I'm specifying not correct?
Thank you!
Ref:
Verified the composition of the URL based on this: https://developers.google.com/storage/docs/json_api/v1/how-tos/performance#partial
I think what you want is:
fields=items(generation,name)
or with the full URL:
https://www.googleapis.com/storage/v1beta2/b/mybucketname/o?fields=items(generation,name)&prefix=myprefix&versions=true
The APIs Explorer is a great tool for experimenting with request fields like this. It will generate the proper fields for you.

New thumbnail feature - how to use in Java

I'd like to leverage the new thumbnail feature of Google Drive using the latest Java SDK.
But all I get is a bad request response.
Can someone post a working example of this feature?
I've been simply setting the mimetype and Base64-encoded image data but this does not work - at least for file.insert and file.patch.
Update:
This is my (simplified) code snippet. It works fine without the new thumbnail stuff - and the encoded image data looks ok as well:
...
Drive drive = getDrive(account);
File file = new File();
file.setTitle(name);
...
HTTPResponse response = urlFetch.fetch(new URL(imageUrl));
String encodedImage = new String(Base64.encodeBase64(response.getContent()));
Thumbnail thumbnail = new Thumbnail();
thumbnail.setImage(encodedImage);
thumbnail.setMimeType("image/png");
file.setThumbnail(thumbnail);
file = drive.files().insert(file).execute();
This is the response:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 OK
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Bad Request",
"reason" : "badRequest"
} ],
"message" : "Bad Request"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:143)
at com.google.api.client.googleapis.json.GoogleJsonResponseException.execute(GoogleJsonResponseException.java:187)
at com.google.api.client.googleapis.services.GoogleClient.executeUnparsed(GoogleClient.java:279)
at com.google.api.client.http.json.JsonHttpRequest.executeUnparsed(JsonHttpRequest.java:207)
The thumbnail image needs to be encoded as a Base64 UrlSafe String.
Using
String encodedImage = Base64.encodeBase64URLSafeString(response.getContent());
to encode the image fixed the issue.