1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: Apache-2.0
5 package Arvados::ResourceMethod;
13 bless ($self, $class);
14 return $self->_init(@_);
20 $self->{'resourceAccessor'} = shift;
21 $self->{'method'} = shift;
28 my $method = $self->{'method'};
30 my $path = $method->{'path'};
33 my %given_params = @_;
34 my %extra_params = %given_params;
35 my %method_params = %{$method->{'parameters'}};
36 if ($method->{'request'}->{'properties'}) {
37 while (my ($prop_name, $prop_value) =
38 each %{$method->{'request'}->{'properties'}}) {
39 if (ref($prop_value) eq 'HASH' && $prop_value->{'$ref'}) {
40 $method_params{$prop_name} = { 'type' => 'object' };
44 while (my ($param_name, $param) = each %method_params) {
45 delete $extra_params{$param_name};
46 if ($param->{'required'} && !exists $given_params{$param_name}) {
47 croak("Required parameter not supplied: $param_name");
49 elsif ($param->{'location'} eq 'path') {
50 $path =~ s/{\Q$param_name\E}/$given_params{$param_name}/eg;
52 elsif (!exists $given_params{$param_name}) {
55 elsif ($param->{'type'} eq 'object') {
58 if (exists $param->{'properties'}) {
59 while (my ($property_name, $property) =
60 each %{$param->{'properties'}}) {
61 # if the discovery doc specifies object structure,
62 # convert to true/false depending on supplied type
63 if (!exists $given_params{$param_name}->{$property_name}) {
66 elsif (!defined $given_params{$param_name}->{$property_name}) {
67 $param_value{$property_name} = JSON::null;
69 elsif ($property->{'type'} eq 'boolean') {
70 $param_value{$property_name} = $given_params{$param_name}->{$property_name} ? JSON::true : JSON::false;
73 $param_value{$property_name} = $given_params{$param_name}->{$property_name};
78 while (my ($property_name, $property) =
79 each %{$given_params{$param_name}}) {
80 if (ref $property eq '' || $property eq undef) {
81 $param_value{$property_name} = $property;
83 elsif (ref $property eq 'HASH') {
84 $param_value{$property_name} = {};
85 while (my ($k, $v) = each %$property) {
86 $param_value{$property_name}->{$k} = $v;
91 $body_params{$param_name} = \%param_value;
92 } elsif ($param->{'type'} eq 'boolean') {
93 $body_params{$param_name} = $given_params{$param_name} ? JSON::true : JSON::false;
95 $body_params{$param_name} = $given_params{$param_name};
99 croak("Unsupported parameter(s) passed to API call /$path: \"" . join('", "', keys %extra_params) . '"');
101 my $r = $self->{'resourceAccessor'}->{'api'}->new_request;
102 my $base_uri = $self->{'resourceAccessor'}->{'api'}->{'discoveryDocument'}->{'baseUrl'};
104 $r->set_uri($base_uri . "/" . $path);
105 $r->set_method($method->{'httpMethod'});
106 $r->set_auth_token($self->{'resourceAccessor'}->{'api'}->{'authToken'});
107 $r->set_query_params(\%body_params) if %body_params;
108 $r->process_request();
110 my ($status_number, $status_phrase) = $r->get_status();
111 if ($status_number != 200) {
112 croak("API call /$path failed: $status_number $status_phrase\n". $r->get_body());
114 $data = $r->get_body();
115 $headers = $r->get_headers();
116 my $result = JSON::decode_json($data);
117 if ($method->{'response'}->{'$ref'} =~ /List$/) {
118 Arvados::ResourceProxyList->new($result, $self->{'resourceAccessor'});
120 Arvados::ResourceProxy->new($result, $self->{'resourceAccessor'});