4062: update python testing to handle the multiple fixture object creation, similar...
[arvados.git] / sdk / perl / lib / Arvados / ResourceMethod.pm
1 package Arvados::ResourceMethod;
2 use Carp;
3 use Data::Dumper;
4
5 sub new
6 {
7     my $class = shift;
8     my $self = {};
9     bless ($self, $class);
10     return $self->_init(@_);
11 }
12
13 sub _init
14 {
15     my $self = shift;
16     $self->{'resourceAccessor'} = shift;
17     $self->{'method'} = shift;
18     return $self;
19 }
20
21 sub execute
22 {
23     my $self = shift;
24     my $method = $self->{'method'};
25
26     my $path = $method->{'path'};
27
28     my %body_params;
29     my %given_params = @_;
30     my %extra_params = %given_params;
31     my %method_params = %{$method->{'parameters'}};
32     if ($method->{'request'}->{'properties'}) {
33         while (my ($prop_name, $prop_value) =
34                each %{$method->{'request'}->{'properties'}}) {
35             if (ref($prop_value) eq 'HASH' && $prop_value->{'$ref'}) {
36                 $method_params{$prop_name} = { 'type' => 'object' };
37             }
38         }
39     }
40     while (my ($param_name, $param) = each %method_params) {
41         delete $extra_params{$param_name};
42         if ($param->{'required'} && !exists $given_params{$param_name}) {
43             croak("Required parameter not supplied: $param_name");
44         }
45         elsif ($param->{'location'} eq 'path') {
46             $path =~ s/{\Q$param_name\E}/$given_params{$param_name}/eg;
47         }
48         elsif (!exists $given_params{$param_name}) {
49             ;
50         }
51         elsif ($param->{'type'} eq 'object') {
52             my %param_value;
53             my ($p, $v);
54             if (exists $param->{'properties'}) {
55                 while (my ($property_name, $property) =
56                        each %{$param->{'properties'}}) {
57                     # if the discovery doc specifies object structure,
58                     # convert to true/false depending on supplied type
59                     if (!exists $given_params{$param_name}->{$property_name}) {
60                         ;
61                     }
62                     elsif (!defined $given_params{$param_name}->{$property_name}) {
63                         $param_value{$property_name} = JSON::null;
64                     }
65                     elsif ($property->{'type'} eq 'boolean') {
66                         $param_value{$property_name} = $given_params{$param_name}->{$property_name} ? JSON::true : JSON::false;
67                     }
68                     else {
69                         $param_value{$property_name} = $given_params{$param_name}->{$property_name};
70                     }
71                 }
72             }
73             else {
74                 while (my ($property_name, $property) =
75                        each %{$given_params{$param_name}}) {
76                     if (ref $property eq '' || $property eq undef) {
77                         $param_value{$property_name} = $property;
78                     }
79                     elsif (ref $property eq 'HASH') {
80                         $param_value{$property_name} = {};
81                         while (my ($k, $v) = each %$property) {
82                             $param_value{$property_name}->{$k} = $v;
83                         }
84                     }
85                 }
86             }
87             $body_params{$param_name} = \%param_value;
88         } elsif ($param->{'type'} eq 'boolean') {
89             $body_params{$param_name} = $given_params{$param_name} ? JSON::true : JSON::false;
90         } else {
91             $body_params{$param_name} = $given_params{$param_name};
92         }
93     }
94     if (%extra_params) {
95         croak("Unsupported parameter(s) passed to API call /$path: \"" . join('", "', keys %extra_params) . '"');
96     }
97     my $r = $self->{'resourceAccessor'}->{'api'}->new_request;
98     my $base_uri = $self->{'resourceAccessor'}->{'api'}->{'discoveryDocument'}->{'baseUrl'};
99     $base_uri =~ s:/$::;
100     $r->set_uri($base_uri . "/" . $path);
101     $r->set_method($method->{'httpMethod'});
102     $r->set_auth_token($self->{'resourceAccessor'}->{'api'}->{'authToken'});
103     $r->set_query_params(\%body_params) if %body_params;
104     $r->process_request();
105     my $data, $headers;
106     my ($status_number, $status_phrase) = $r->get_status();
107     if ($status_number != 200) {
108         croak("API call /$path failed: $status_number $status_phrase\n". $r->get_body());
109     }
110     $data = $r->get_body();
111     $headers = $r->get_headers();
112     my $result = JSON::decode_json($data);
113     if ($method->{'response'}->{'$ref'} =~ /List$/) {
114         Arvados::ResourceProxyList->new($result, $self->{'resourceAccessor'});
115     } else {
116         Arvados::ResourceProxy->new($result, $self->{'resourceAccessor'});
117     }
118 }
119
120 1;