Skip to content

Commit 3d16d8b

Browse files
committed
fix header
1 parent 699f6ff commit 3d16d8b

File tree

10 files changed

+553
-64
lines changed

10 files changed

+553
-64
lines changed

:w

Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
package WWW::{{invokerPackage}}::ApiClient;
2+
3+
use strict;
4+
use warnings;
5+
use utf8;
6+
7+
use MIME::Base64;
8+
use LWP::UserAgent;
9+
use HTTP::Headers;
10+
use HTTP::Response;
11+
use HTTP::Request::Common qw(DELETE POST GET HEAD PUT);
12+
use HTTP::Status;
13+
use URI::Query;
14+
use JSON;
15+
use URI::Escape;
16+
use Scalar::Util;
17+
use Log::Any qw($log);
18+
use Carp;
19+
use Module::Runtime qw(use_module);
20+
21+
use WWW::{{invokerPackage}}::Configuration;
22+
23+
sub new
24+
{
25+
my $class = shift;
26+
my (%args) = (
27+
'ua' => LWP::UserAgent->new,
28+
'base_url' => '{{basePath}}',
29+
@_
30+
);
31+
32+
return bless \%args, $class;
33+
}
34+
35+
# Set the user agent of the API client
36+
#
37+
# @param string $user_agent The user agent of the API client
38+
#
39+
sub set_user_agent {
40+
my ($self, $user_agent) = @_;
41+
$self->{http_user_agent}= $user_agent;
42+
}
43+
44+
# Set timeout
45+
#
46+
# @param integer $seconds Number of seconds before timing out [set to 0 for no timeout]
47+
#
48+
sub set_timeout {
49+
my ($self, $seconds) = @_;
50+
if (!looks_like_number($seconds)) {
51+
croak('Timeout variable must be numeric.');
52+
}
53+
$self->{http_timeout} = $seconds;
54+
}
55+
56+
# make the HTTP request
57+
# @param string $resourcePath path to method endpoint
58+
# @param string $method method to call
59+
# @param array $queryParams parameters to be place in query URL
60+
# @param array $postData parameters to be placed in POST body
61+
# @param array $headerParams parameters to be place in request header
62+
# @return mixed
63+
sub call_api {
64+
my $self = shift;
65+
my ($resource_path, $method, $query_params, $post_params, $header_params, $body_data, $auth_settings) = @_;
66+
67+
my $headers = HTTP::Headers->new(%$header_params);
68+
69+
my $_url = $self->{base_url} . $resource_path;
70+
71+
# build query
72+
if (%$query_params) {
73+
$_url = ($_url . '?' . eval { URI::Query->new($query_params)->stringify });
74+
}
75+
76+
# update parameters based on authentication settings
77+
update_params_for_auth(\$query_params, \$header_params, \$auth_settings);
78+
79+
# body data
80+
$body_data = to_json($body_data->to_hash) if defined $body_data && $body_data->can('to_hash'); # model to json string
81+
my $_body_data = %$post_params ? $post_params : $body_data;
82+
83+
# Make the HTTP request
84+
my $_request;
85+
if ($method eq 'POST') {
86+
# multipart
87+
my $_content_type = lc $header_params->{'Content-Type'} eq 'multipart/form' ?
88+
'form-data' : $header_params->{'Content-Type'};
89+
90+
$_request = POST($_url, Accept => $header_params->{Accept},
91+
Content_Type => $_content_type, Content => $_body_data);
92+
}
93+
elsif ($method eq 'PUT') {
94+
# multipart
95+
my $_content_type = lc $header_params->{'Content-Type'} eq 'multipart/form' ?
96+
'form-data' : $header_params->{'Content-Type'};
97+
$_request = PUT($_url, Accept => $header_params->{Accept},
98+
Content_Type => $_content_type, Content => $_body_data);
99+
}
100+
elsif ($method eq 'GET') {
101+
$_request = GET($_url, Accept => $header_params->{'Accept'},
102+
Content_Type => $header_params->{'Content-Type'});
103+
}
104+
elsif ($method eq 'HEAD') {
105+
$_request = HEAD($_url, Accept => $header_params->{'Accept'},
106+
Content_Type => $header_params->{'Content-Type'});
107+
}
108+
elsif ($method eq 'DELETE') { #TODO support form data
109+
$_request = DELETE($_url, Accept => $header_params->{'Accept'},
110+
Content_Type => $header_params->{'Content-Type'}, Content => $_body_data);
111+
}
112+
elsif ($method eq 'PATCH') { #TODO
113+
}
114+
else {
115+
}
116+
117+
$self->{ua}->timeout($self->{http_timeout} || $WWW::{{invokerPackage}}::Configuration::http_timeout);
118+
$self->{ua}->agent($self->{http_user_agent} || $WWW::{{invokerPackage}}::Configuration::http_user_agent);
119+
120+
my $_response = $self->{ua}->request($_request);
121+
122+
unless ($_response->is_success) {
123+
croak("API Exception(".$_response->code."): ".$_response->message);
124+
}
125+
126+
return $_response->content;
127+
128+
}
129+
130+
# Take value and turn it into a string suitable for inclusion in
131+
# the path, by url-encoding.
132+
# @param string $value a string which will be part of the path
133+
# @return string the serialized object
134+
sub to_path_value {
135+
my ($self, $value) = @_;
136+
return uri_escape($self->to_string($value));
137+
}
138+
139+
140+
# Take value and turn it into a string suitable for inclusion in
141+
# the query, by imploding comma-separated if it's an object.
142+
# If it's a string, pass through unchanged. It will be url-encoded
143+
# later.
144+
# @param object $object an object to be serialized to a string
145+
# @return string the serialized object
146+
sub to_query_value {
147+
my ($self, $object) = @_;
148+
if (is_array($object)) {
149+
return implode(',', $object);
150+
} else {
151+
return $self->to_string($object);
152+
}
153+
}
154+
155+
156+
# Take value and turn it into a string suitable for inclusion in
157+
# the header. If it's a string, pass through unchanged
158+
# If it's a datetime object, format it in ISO8601
159+
# @param string $value a string which will be part of the header
160+
# @return string the header string
161+
sub to_header_value {
162+
my ($self, $value) = @_;
163+
return $self->to_string($value);
164+
}
165+
166+
# Take value and turn it into a string suitable for inclusion in
167+
# the http body (form parameter). If it's a string, pass through unchanged
168+
# If it's a datetime object, format it in ISO8601
169+
# @param string $value the value of the form parameter
170+
# @return string the form string
171+
sub to_form_value {
172+
my ($self, $value) = @_;
173+
return $self->to_string($value);
174+
}
175+
176+
# Take value and turn it into a string suitable for inclusion in
177+
# the parameter. If it's a string, pass through unchanged
178+
# If it's a datetime object, format it in ISO8601
179+
# @param string $value the value of the parameter
180+
# @return string the header string
181+
sub to_string {
182+
my ($self, $value) = @_;
183+
if (ref($value) eq "DateTime") { # datetime in ISO8601 format
184+
return $value->datetime();
185+
}
186+
else {
187+
return $value;
188+
}
189+
}
190+
191+
# Deserialize a JSON string into an object
192+
#
193+
# @param string $class class name is passed as a string
194+
# @param string $data data of the body
195+
# @return object an instance of $class
196+
sub deserialize
197+
{
198+
my ($self, $class, $data) = @_;
199+
$log->debugf("deserializing %s for %s", $data, $class);
200+
my $_result;
201+
202+
if (not defined $data) {
203+
return undef;
204+
} elsif ( lc(substr($class, 0, 4)) eq 'map[') { #hash
205+
$_result = \(json_decode $data);
206+
} elsif ( lc(substr($class, 0, 6)) eq 'array[' ) { # array of data
207+
return $data if $data eq '[]'; # return if empty array
208+
209+
my $_sub_class = substr($class, 6, -1);
210+
my @_json_data = json_decode $data;
211+
my @_values = ();
212+
foreach my $_value (@_json_data) {
213+
push @_values, $self->deserialize($_sub_class, $_value);
214+
}
215+
$_result = \@_values;
216+
} elsif ($class eq 'DateTime') {
217+
$_result = DateTime->from_epoch(epoch => str2time($data));
218+
} elsif (grep /^$data$/, ('string', 'int', 'float', 'bool')) { #TODO revise the primitive type
219+
$_result= $data;
220+
} else { # model
221+
my $_instance = use_module("WWW::{{invokerPackage}}::Object::$class")->new;
222+
$_result = $_instance->from_hash(decode_json $data);
223+
}
224+
225+
return $_result;
226+
227+
}
228+
229+
# return 'Accept' based on an array of accept provided
230+
# @param [Array] header_accept_array Array fo 'Accept'
231+
# @return String Accept (e.g. application/json)
232+
sub select_header_accept
233+
{
234+
my ($self, @header) = @_;
235+
236+
if (@header == 0 || (@header == 1 && $header[0] eq '')) {
237+
return undef;
238+
} elsif (grep(/^application\/json$/i, @header)) {
239+
return 'application/json';
240+
} else {
241+
return join(',', @header);
242+
}
243+
244+
}
245+
246+
# return the content type based on an array of content-type provided
247+
# @param [Array] content_type_array Array fo content-type
248+
# @return String Content-Type (e.g. application/json)
249+
sub select_header_content_type
250+
{
251+
my ($self, @header) = @_;
252+
253+
if (@header == 0 || (@header == 1 && $header[0] eq '')) {
254+
return 'application/json'; # default to application/json
255+
} elsif (grep(/^application\/json$/i, @header)) {
256+
return 'application/json';
257+
} else {
258+
return join(',', @header);
259+
}
260+
261+
}
262+
263+
# update hearder and query param based on authentication setting
264+
#
265+
# @param array $headerParams header parameters (by ref)
266+
# @param array $queryParams query parameters (by ref)
267+
# @param array $authSettings array of authentication scheme (e.g ['api_key'])
268+
sub update_params_for_auth {
269+
my ($self, $header_params, $query_params, $auth_settings) = @_;
270+
271+
return if (scalar(@$auth_settings) == 0)
272+
273+
# one endpoint can have more than 1 auth settings
274+
foreach my $auth (@$auth_settings) {
275+
# determine which one to use
276+
if (!defined($auth)) {
277+
}
278+
{{#authMethods}}
279+
elsif ($auth eq '{{name}}') {
280+
{{#isApiKey}}{{#isKeyInHeader}}$header_params->{'{{keyParamName}}'} = $self->get_api_key_with_prefix('{{keyParamName}}');{{/isKeyInHeader}}{{#isKeyInQuery}}$query_params->{'{{keyParamName}}'} = $self->get_api_key_with_prefix('{{keyParamName}}');{{/isKeyInQuery}}{{/isApiKey}}{{#isBasic}}$header_params->{'Authorization'} = 'Basic '.encode_base64(Configuration::username.":".Configuration::password);{{/isBasic}}
281+
{{#isOAuth}}//TODO support oauth{{/isOAuth}}
282+
}{{/authMethods}}
283+
else {
284+
//TODO show warning about security definition not found
285+
}
286+
}
287+
}
288+
289+
290+
1;

0 commit comments

Comments
 (0)