CloudHealth-API/lib/CloudHealth/API/CallObjectFormer.pm
package CloudHealth::API::CallObjectFormer;
use Moo;
use HTTP::Tiny;
use JSON::MaybeXS;
use Module::Runtime qw/require_module/;
use CloudHealth::API::Error;
use CloudHealth::API::HTTPRequest;
has _json => (is => 'ro', default => sub { JSON::MaybeXS->new });
sub callinfo_class {
my ($self, $call) = @_;
my $class = "CloudHealth::API::Call::$call";
require_module $class;
return $class;
}
sub params2request {
my ($self, $call, $creds, $user_params) = @_;
my $call_object = eval { $self->callinfo_class($call)->new(@$user_params) };
if ($@) {
my $msg = $@;
CloudHealth::API::Error->throw(
type => 'InvalidParameters',
message => "Error in parameters to method $call",
detail => $msg,
);
}
my $body_struct;
if ($call_object->can('_body_params')) {
$body_struct = {};
foreach my $param (@{ $call_object->_body_params }) {
my $key = $param->{ name };
my $value = $call_object->$key;
next if (not defined $value);
my $location = defined $param->{ location } ? $param->{ location } : $key;
$body_struct->{ $location } = $value;
}
}
CloudHealth::API::Error->throw(
type => 'NoCredentials',
message => 'Cannot find credentials for the request'
) if (not $creds->is_set);
my $params = {
api_key => $creds->api_key,
};
foreach my $param (@{ $call_object->_query_params }) {
my $key = $param->{ name };
my $value = $call_object->$key;
next if (not defined $value);
my $location = defined $param->{ location } ? $param->{ location } : $key;
$params->{ $location } = $value;
}
my $url_params = {};
foreach my $param (@{ $call_object->_url_params }) {
my $key = $param->{ name };
my $value = $call_object->$key;
next if (not defined $value);
my $location = defined $param->{ location } ? $param->{ location } : $key;
$url_params->{ $location } = $value;
}
my $url = $call_object->_url;
$url =~ s/\:([a-z0-9_-]+)/$url_params->{ $1 }/ge;
my $qstring = HTTP::Tiny->www_form_urlencode($params);
my $req = CloudHealth::API::HTTPRequest->new;
$req->method($call_object->_method);
$req->url(
"$url?$qstring",
);
$req->headers({
(defined $body_struct) ? ('Content-Type' => 'application/json') : (),
Accept => 'application/json',
});
$req->content($self->_json->encode($body_struct)) if (defined $body_struct);
return $req;
}
1;