Byron / google-apis-rs

A binding and CLI generator for all Google APIs
http://byron.github.io/google-apis-rs
Other
1.01k stars 131 forks source link

Google-cloudtasks2 - Error on trying to create queue and adding tasks to existing queue #300

Open ViniciusSossela opened 2 years ago

ViniciusSossela commented 2 years ago

I am getting stuck trying to create a new Queue and also trying to add a Task to an existing Queue with the following code. Am I missing something?

The service account below has all the Cloud Tasks API permissions setup.

google-cloudtasks2 = "*"
let service_account = yup_oauth2::ServiceAccountKey {
        key_type: Some(String::from("service_account")),
        project_id: Some(String::from("xxxx")),
        private_key_id: Some(String::from("67fxxxxxx7")),
        private_key: String::from("-----BEGIN PRIVATE KEY-----xxxxxxxxE=\n-----END PRIVATE KEY-----\n"),
        client_email: String::from("xxxxx@xxxxx.iam.gserviceaccount.com"),
        client_id: Some(String::from("11xxxxxxxxxxxx82")),
        auth_uri: Some(String::from("https://accounts.google.com/o/oauth2/auth")),
        token_uri: String::from("https://oauth2.googleapis.com/token"),
        auth_provider_x509_cert_url: Some(String::from("https://www.googleapis.com/oauth2/v1/certs")),
        client_x509_cert_url: Some(String::from("https://www.googleapis.com/robot/v1/metadata/x509/xx%40xxx.iam.gserviceaccount.com")),
    };

    let auth = yup_oauth2::ServiceAccountAuthenticator::builder(service_account)
        .build()
        .await
        .unwrap();

    let hub = CloudTasks::new(
        hyper::Client::builder().build(hyper_rustls::HttpsConnector::with_native_roots()),
        auth,
    );

    let parent = "projects/MY_PROJECT/locations/MY_LOCATION/queues";
    let mut create_queue_req = Queue::default();
    create_queue_req.name = Some(String::from(
        "projects/MY_PROJECT/locations/MY_LOCATION/queues/mynewqueue",
    ));

    let result_create_queue = hub
        .projects()
        .locations_queues_create(create_queue_req, parent)
        .doit()
        .await;

    println!("result_create_queue ------- {:?}.", result_create_queue);

Result:

Err(Failure(Response { status: 404, version: HTTP/2.0, headers: {"date": "Sat, 02 Oct 2021 18:59:36 GMT", "content-type": "text/html; charset=UTF-8", "server": "ESF", "content-length": "1642", "x-xss-protection": "0", "x-frame-options": "SAMEORIGIN", "x-content-type-options": "nosniff", "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""}, body: Body(Streaming) })).

Adding task code:

let service_account = yup_oauth2::ServiceAccountKey {
        key_type: Some(String::from("service_account")),
        project_id: Some(String::from("xxxx")),
        private_key_id: Some(String::from("67fxxxxxx7")),
        private_key: String::from("-----BEGIN PRIVATE KEY-----xxxxxxxxE=\n-----END PRIVATE KEY-----\n"),
        client_email: String::from("xxxxx@xxxxx.iam.gserviceaccount.com"),
        client_id: Some(String::from("11xxxxxxxxxxxx82")),
        auth_uri: Some(String::from("https://accounts.google.com/o/oauth2/auth")),
        token_uri: String::from("https://oauth2.googleapis.com/token"),
        auth_provider_x509_cert_url: Some(String::from("https://www.googleapis.com/oauth2/v1/certs")),
        client_x509_cert_url: Some(String::from("https://www.googleapis.com/robot/v1/metadata/x509/xx%40xxx.iam.gserviceaccount.com")),
    };

    let auth = yup_oauth2::ServiceAccountAuthenticator::builder(service_account)
        .build()
        .await
        .unwrap();

    let hub = CloudTasks::new(
        hyper::Client::builder().build(hyper_rustls::HttpsConnector::with_native_roots()),
        auth,
    );

let mut create_task_req = CreateTaskRequest::default();
    let mut http_req_headers = HashMap::new();
    http_req_headers
        .entry(String::from("Content-Type"))
        .or_insert(String::from("application/json"));

    let mut task = Task::default();
    let mut http_req = HttpRequest::default();
    http_req.url = Some(String::from("https://example.com/task_handler"));
    http_req.http_method = Some(String::from("POST"));
    http_req.headers = Some(http_req_headers);

    task.name = Some(String::from("my-task"));
    task.http_request = Some(http_req);

    create_task_req.task = Some(task);

   let parent = "projects/MY_PROJECT/locations/MY_LOCATION/queues/MY_QUEUE";
   let result_create_task = hub
        .projects()
        .locations_queues_tasks_create(create_task_req.clone(), parent)
        .doit()
        .await;

Result:

Err(Failure(Response { status: 400, version: HTTP/2.0, headers: {"vary": "X-Origin", "vary": "Referer", "vary": "Origin,Accept-Encoding", "content-type": "application/json; charset=UTF-8", "date": "Sat, 02 Oct 2021 19:21:32 GMT", "server": "ESF", "cache-control": "private", "x-xss-protection": "0", "x-frame-options": "SAMEORIGIN", "x-content-type-options": "nosniff", "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"", "accept-ranges": "none"}, body: Body(Streaming) })).
Byron commented 2 years ago

I wish I knew every Google API, but know enough to say that they may all have their own subtle requirements which can lead to surprising behaviour. There was a version of the accompanying CLIs which could display all HTTP communication, but that feature unfortunately fell victim to getting the crates through the years.

All there is to do is to study the official documentation or use a JS-in-browser binding to see what actually happens under the hood. Maybe such insight would help to make the 'right' calls through this API binding, too.

I hope that helps.

ViniciusSossela commented 2 years ago

@Byron Thanks for replying.

Gonna find out what is really happening under the hood.

If I find out some solution, Can we improve the documentation for a better understanding of Google Cloud Task use?

Byron commented 2 years ago

It's possible to customize per API data that is the input of the code generation stage, even though the particular capability of customizing documentation isn't implemented yet. Doing so won't be hard, either, but certainly needs some contribution effort to get there.