From 6c19f0c26ced406b7e0cfe2134c2cf79bb50615f Mon Sep 17 00:00:00 2001 From: Dave Baird Date: Sat, 7 Nov 2015 20:37:13 +0100 Subject: [PATCH 01/14] Flatten entire API into a single class Added a Moose role which flattens all the individual endpoint APIs into a single class. --- .gitignore | 4 ++ .../codegen/languages/PerlClientCodegen.java | 1 + .../main/resources/perl/ApiClient.mustache | 5 +- .../main/resources/perl/ApiFactory.mustache | 33 ++++++++---- .../src/main/resources/perl/Role.mustache | 54 +++++++++++++++++++ .../perl/lib/WWW/SwaggerClient/ApiClient.pm | 5 +- .../perl/lib/WWW/SwaggerClient/ApiFactory.pm | 33 ++++++++---- .../perl/lib/WWW/SwaggerClient/Role.pm | 54 +++++++++++++++++++ 8 files changed, 165 insertions(+), 24 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/perl/Role.mustache create mode 100644 samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm diff --git a/.gitignore b/.gitignore index c904ba4a5fe5..37b18e5e3cc1 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,7 @@ samples/client/petstore/python/.projectile samples/client/petstore/python/.venv/ */.settings + +*.mustache~ +*.java~ +*.pm~ \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java index ba03f3944c51..ee2fa0ddbf34 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java @@ -95,6 +95,7 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig { supportingFiles.add(new SupportingFile("Configuration.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "Configuration.pm")); supportingFiles.add(new SupportingFile("BaseObject.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "Object/BaseObject.pm")); supportingFiles.add(new SupportingFile("ApiFactory.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "ApiFactory.pm")); + supportingFiles.add(new SupportingFile("Role.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "Role.pm")); } public CodegenType getTag() { diff --git a/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache index 06aae8a0e55e..02f9ff2221fd 100644 --- a/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache @@ -305,8 +305,9 @@ sub update_params_for_auth { my ($self, $header_params, $query_params, $auth_settings) = @_; # we can defer to the application - if ($self->{auth_setup_handler} && ref($self->{auth_setup_handler}) eq 'CODE') { - $self->{auth_setup_handler}->( api_client => $self, + if ($self->{auth_setup_handler_object}) { + $self->{auth_setup_handler_object}->auth_setup_handler( + api_client => $self, header_params => $header_params, query_params => $query_params, auth_settings => $auth_settings, # presumably this won't be defined if we're doing it this way diff --git a/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache b/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache index fc309c91b9cf..724ad63b048d 100644 --- a/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache @@ -49,18 +49,17 @@ my %_apis = map { $_ =~ /^WWW::{{moduleName}}::(.*)$/; $1 => $_ } All parameters are optional, and are passed to and stored on the api_client object. - base_url: supply this to change the default base URL taken from the Swagger definition. + base_url: (optional) + supply this to change the default base URL taken from the Swagger definition. - auth_setup_handler: a coderef you can supply to set up authentication. - - The coderef receives a hashref with keys: api_client, query_params, header_params, auth_settings. + auth_setup_handler_object: (optional) + An object (or class name) that implements an auth_setup_handler() method. - my $api_factory = WWW::{{moduleName}}::ApiFactory->new( auth_setup_handler => \&setup_auth ); ); - - sub setup_auth { - my %p = @_; - $p{header_params}->{'X-SomeApp-FunkyKeyName'} = 'aaaaabbbbbcccccddddd'; - } + If set, the auth_setup_handler() method will be called on the object, and + passed a hashref with keys: api_client, query_params, header_params, auth_settings. + + The method should implement the required auth policy, for example, by setting + secret keys in the header, or username and password in the URL, etc. =cut @@ -95,4 +94,18 @@ sub get_api { sub api_client { $_[0]->{api_client} } +=head1 apis_available() +=cut + +sub apis_available { return map { $_ =~ s/Api$//; $_ } sort keys %_apis } + +=head1 classname_for() +=cut + +sub classname_for { + my ($self, $api_name) = @_; + return $_apis{"${api_name}Api"}; +} + + 1; diff --git a/modules/swagger-codegen/src/main/resources/perl/Role.mustache b/modules/swagger-codegen/src/main/resources/perl/Role.mustache new file mode 100644 index 000000000000..f349317c9ab7 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/perl/Role.mustache @@ -0,0 +1,54 @@ +package WWW::{{moduleName}}::Role; +use utf8; + +use Moose::Role; +use namespace::autoclean; +use Class::Inspector; + +use WWW::{{moduleName}}::ApiFactory; + +requires 'auth_setup_handler'; + +has base_url => ( is => 'ro', + required => 0, + isa => 'Str', + ); + +has api_factory => ( is => 'ro', + isa => 'WWW::{{moduleName}}::ApiFactory', + builder => '_build_af', + lazy => 1, + ); + +sub BUILD { + my $self = shift; + + my %outsiders = map {$_ => 1} qw( croak ); + + foreach my $name ($self->api_factory->apis_available) { + + my $att_name = sprintf "%s_api", lc($name); + my $api_class = $self->api_factory->classname_for($name); + my $methods = Class::Inspector->methods($api_class, 'expanded'); + my @local_methods = grep {! $outsiders{$_}} map {$_->[2]} grep {$_->[1] eq $api_class} @$methods; + + $self->meta->add_attribute( $att_name => ( + is => 'ro', + isa => $api_class, + default => sub {$self->api_factory->get_api($name)}, + lazy => 1, + handles => \@local_methods, + ) ); + } +} + +sub _build_af { + my $self = shift; + my %args = ( auth_setup_handler_object => $self ); + $args{base_url} = $self->base_url if $self->base_url; + return WWW::{{moduleName}}::ApiFactory->new(%args); +} + + + +1; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm index de4a3e2d2fb6..028b983808ae 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm @@ -305,8 +305,9 @@ sub update_params_for_auth { my ($self, $header_params, $query_params, $auth_settings) = @_; # we can defer to the application - if ($self->{auth_setup_handler} && ref($self->{auth_setup_handler}) eq 'CODE') { - $self->{auth_setup_handler}->( api_client => $self, + if ($self->{auth_setup_handler_object}) { + $self->{auth_setup_handler_object}->auth_setup_handler( + api_client => $self, header_params => $header_params, query_params => $query_params, auth_settings => $auth_settings, # presumably this won't be defined if we're doing it this way diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm index 701a22603c53..bf3617d86f1f 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm @@ -49,18 +49,17 @@ my %_apis = map { $_ =~ /^WWW::SwaggerClient::(.*)$/; $1 => $_ } All parameters are optional, and are passed to and stored on the api_client object. - base_url: supply this to change the default base URL taken from the Swagger definition. + base_url: (optional) + supply this to change the default base URL taken from the Swagger definition. - auth_setup_handler: a coderef you can supply to set up authentication. - - The coderef receives a hashref with keys: api_client, query_params, header_params, auth_settings. + auth_setup_handler_object: (optional) + An object (or class name) that implements an auth_setup_handler() method. - my $api_factory = WWW::SwaggerClient::ApiFactory->new( auth_setup_handler => \&setup_auth ); ); - - sub setup_auth { - my %p = @_; - $p{header_params}->{'X-SomeApp-FunkyKeyName'} = 'aaaaabbbbbcccccddddd'; - } + If set, the auth_setup_handler() method will be called on the object, and + passed a hashref with keys: api_client, query_params, header_params, auth_settings. + + The method should implement the required auth policy, for example, by setting + secret keys in the header, or username and password in the URL, etc. =cut @@ -95,4 +94,18 @@ sub get_api { sub api_client { $_[0]->{api_client} } +=head1 apis_available() +=cut + +sub apis_available { return map { $_ =~ s/Api$//; $_ } sort keys %_apis } + +=head1 classname_for() +=cut + +sub classname_for { + my ($self, $api_name) = @_; + return $_apis{"${api_name}Api"}; +} + + 1; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm new file mode 100644 index 000000000000..c47f09088442 --- /dev/null +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm @@ -0,0 +1,54 @@ +package WWW::SwaggerClient::Role; +use utf8; + +use Moose::Role; +use namespace::autoclean; +use Class::Inspector; + +use WWW::SwaggerClient::ApiFactory; + +requires 'auth_setup_handler'; + +has base_url => ( is => 'ro', + required => 0, + isa => 'Str', + ); + +has api_factory => ( is => 'ro', + isa => 'WWW::SwaggerClient::ApiFactory', + builder => '_build_af', + lazy => 1, + ); + +sub BUILD { + my $self = shift; + + my %outsiders = map {$_ => 1} qw( croak ); + + foreach my $name ($self->api_factory->apis_available) { + + my $att_name = sprintf "%s_api", lc($name); + my $api_class = $self->api_factory->classname_for($name); + my $methods = Class::Inspector->methods($api_class, 'expanded'); + my @local_methods = grep {! $outsiders{$_}} map {$_->[2]} grep {$_->[1] eq $api_class} @$methods; + + $self->meta->add_attribute( $att_name => ( + is => 'ro', + isa => $api_class, + default => sub {$self->api_factory->get_api($name)}, + lazy => 1, + handles => \@local_methods, + ) ); + } +} + +sub _build_af { + my $self = shift; + my %args = ( auth_setup_handler_object => $self ); + $args{base_url} = $self->base_url if $self->base_url; + return WWW::SwaggerClient::ApiFactory->new(%args); +} + + + +1; From f0f43f5fdf1af2e92ba04aab7cc7ecd83f7c06ff Mon Sep 17 00:00:00 2001 From: Dave Baird Date: Sun, 8 Nov 2015 21:51:26 +0100 Subject: [PATCH 02/14] Fix method names clash in Moose Role When flattening all endpoint API methods into a single class, some method names may clash, e.g. every API has a new() method. So we skip them, they must be accessed via the API method. Warnings are emitted to document skipped methods. --- .gitignore | 4 +- .../src/main/resources/perl/Role.mustache | 38 ++++++++++--- .../perl/lib/WWW/SwaggerClient/Role.pm | 38 ++++++++++--- samples/client/petstore/perl/pom.xml | 13 +++++ .../client/petstore/perl/t/03_api_factory.t | 14 ++++- samples/client/petstore/perl/t/04_role.t | 56 +++++++++++++++++++ 6 files changed, 143 insertions(+), 20 deletions(-) create mode 100644 samples/client/petstore/perl/t/04_role.t diff --git a/.gitignore b/.gitignore index 37b18e5e3cc1..d55a8014a342 100644 --- a/.gitignore +++ b/.gitignore @@ -58,4 +58,6 @@ samples/client/petstore/python/.venv/ *.mustache~ *.java~ -*.pm~ \ No newline at end of file +*.pm~ +*.xml~ +*.t~ \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/perl/Role.mustache b/modules/swagger-codegen/src/main/resources/perl/Role.mustache index f349317c9ab7..fee13feb040b 100644 --- a/modules/swagger-codegen/src/main/resources/perl/Role.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/Role.mustache @@ -4,7 +4,7 @@ use utf8; use Moose::Role; use namespace::autoclean; use Class::Inspector; - +use Log::Any qw($log); use WWW::{{moduleName}}::ApiFactory; requires 'auth_setup_handler'; @@ -23,21 +23,41 @@ has api_factory => ( is => 'ro', sub BUILD { my $self = shift; - my %outsiders = map {$_ => 1} qw( croak ); + # ignore these symbols imported into API namespaces + my %outsiders = map {$_ => 1} qw( new croak ); - foreach my $name ($self->api_factory->apis_available) { - - my $att_name = sprintf "%s_api", lc($name); - my $api_class = $self->api_factory->classname_for($name); + my %delegates; + + # collect the methods callable on each API + foreach my $api_name ($self->api_factory->apis_available) { + my $api_class = $self->api_factory->classname_for($api_name); my $methods = Class::Inspector->methods($api_class, 'expanded'); my @local_methods = grep {! $outsiders{$_}} map {$_->[2]} grep {$_->[1] eq $api_class} @$methods; - + push( @{$delegates{$_}}, {api_name => $api_name, api_class => $api_class} ) for @local_methods; + } + + # remove clashes + foreach my $method (keys %delegates) { + if ( @{$delegates{$method}} > 1 ) { + my ($apis) = delete $delegates{$method}; + foreach my $api (@$apis) { + warn sprintf "Cannot delegate %s (use \$self->%s_api->%s instead)\n", $method, lc($api->{api_name}), $method; + } + } + } + + # build the flattened API + foreach my $api_name ($self->api_factory->apis_available) { + my $att_name = sprintf "%s_api", lc($api_name); + my $api_class = $self->api_factory->classname_for($api_name); + my @delegated = grep { $delegates{$_}->[0]->{api_name} eq $api_name } keys %delegates; + $log->debugf("Adding API: '%s' handles %s", $att_name, join ', ', @delegated); $self->meta->add_attribute( $att_name => ( is => 'ro', isa => $api_class, - default => sub {$self->api_factory->get_api($name)}, + default => sub {$self->api_factory->get_api($api_name)}, lazy => 1, - handles => \@local_methods, + handles => \@delegated, ) ); } } diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm index c47f09088442..4b63a483eae4 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm @@ -4,7 +4,7 @@ use utf8; use Moose::Role; use namespace::autoclean; use Class::Inspector; - +use Log::Any qw($log); use WWW::SwaggerClient::ApiFactory; requires 'auth_setup_handler'; @@ -23,21 +23,41 @@ has api_factory => ( is => 'ro', sub BUILD { my $self = shift; - my %outsiders = map {$_ => 1} qw( croak ); + # ignore these symbols imported into API namespaces + my %outsiders = map {$_ => 1} qw( new croak ); - foreach my $name ($self->api_factory->apis_available) { - - my $att_name = sprintf "%s_api", lc($name); - my $api_class = $self->api_factory->classname_for($name); + my %delegates; + + # collect the methods callable on each API + foreach my $api_name ($self->api_factory->apis_available) { + my $api_class = $self->api_factory->classname_for($api_name); my $methods = Class::Inspector->methods($api_class, 'expanded'); my @local_methods = grep {! $outsiders{$_}} map {$_->[2]} grep {$_->[1] eq $api_class} @$methods; - + push( @{$delegates{$_}}, {api_name => $api_name, api_class => $api_class} ) for @local_methods; + } + + # remove clashes + foreach my $method (keys %delegates) { + if ( @{$delegates{$method}} > 1 ) { + my ($apis) = delete $delegates{$method}; + foreach my $api (@$apis) { + warn sprintf "Cannot delegate %s (use \$self->%s_api->%s instead)\n", $method, lc($api->{api_name}), $method; + } + } + } + + # build the flattened API + foreach my $api_name ($self->api_factory->apis_available) { + my $att_name = sprintf "%s_api", lc($api_name); + my $api_class = $self->api_factory->classname_for($api_name); + my @delegated = grep { $delegates{$_}->[0]->{api_name} eq $api_name } keys %delegates; + $log->debugf("Adding API: '%s' handles %s", $att_name, join ', ', @delegated); $self->meta->add_attribute( $att_name => ( is => 'ro', isa => $api_class, - default => sub {$self->api_factory->get_api($name)}, + default => sub {$self->api_factory->get_api($api_name)}, lazy => 1, - handles => \@local_methods, + handles => \@delegated, ) ); } } diff --git a/samples/client/petstore/perl/pom.xml b/samples/client/petstore/perl/pom.xml index 4034cf0a6871..4aa0040f82e7 100644 --- a/samples/client/petstore/perl/pom.xml +++ b/samples/client/petstore/perl/pom.xml @@ -65,6 +65,19 @@ + + Test::More for Role + integration-test + + exec + + + perl + + t/04_role.t + + + diff --git a/samples/client/petstore/perl/t/03_api_factory.t b/samples/client/petstore/perl/t/03_api_factory.t index f96bffa7a842..2e6ee6317f92 100644 --- a/samples/client/petstore/perl/t/03_api_factory.t +++ b/samples/client/petstore/perl/t/03_api_factory.t @@ -1,4 +1,4 @@ -use Test::More tests => 13; +use Test::More tests => 19; use Test::Exception; use lib 'lib'; @@ -32,3 +32,15 @@ is $pet->category->id, '22', 'got the proper category id'; is $pet->category->name, 'perl', 'got the proper category name'; is $pet->tags->[0]->name, 'just kidding', 'got the proper tag name'; is $pet->tags->[0]->id, '11', 'got the proper tag id'; + + +my $add_pet = $pet_api->add_pet(body => $pet); +my $get_pet = $pet_api->get_pet_by_id(pet_id => $pet_id); + +is $get_pet->id, '10008', 'stored and retrieved: got the proper pet id'; +is $get_pet->name, 'perl test', 'stored and retrieved: got the proper pet name'; +is $get_pet->category->id, '22', 'stored and retrieved: got the proper category id'; +is $get_pet->category->name, 'perl', 'stored and retrieved: got the proper category name'; +is $get_pet->tags->[0]->name, 'just kidding', 'stored and retrieved: got the proper tag name'; +is $get_pet->tags->[0]->id, '11', 'stored and retrieved: got the proper tag id'; + diff --git a/samples/client/petstore/perl/t/04_role.t b/samples/client/petstore/perl/t/04_role.t new file mode 100644 index 000000000000..b35149c9d837 --- /dev/null +++ b/samples/client/petstore/perl/t/04_role.t @@ -0,0 +1,56 @@ +use Test::More tests => 15; +use Test::Exception; + +use lib 'lib'; +use strict; +use warnings; + +use MooseX::amine; +use Class::Inspector; +use Data::Dumper; + +use Log::Any::Adapter ('File', '/home/dave/bookeo_api.log'); + + +SKIP: { + eval " + package MyApp; + use Moose; + with 'WWW::SwaggerClient::Role'; + + sub auth_setup_handler {} + "; + + skip 'Moose not installed', 15 if $@; + + +my $api = MyApp->new; + +my $pet_id = 10008; +# note - we don't need to 'use' these modules because they've already been loaded by ApiFactory +my ($category, $tag, $pet); +lives_ok { $category = WWW::SwaggerClient::Object::Category->new('id' => '22', 'name' => 'perl') } 'Category.pm loaded OK'; +lives_ok { $tag = WWW::SwaggerClient::Object::Tag->new('id' => '11', 'name' => 'just kidding') } 'Tag.pm loaded OK'; +lives_ok { $pet = WWW::SwaggerClient::Object::Pet->new('id' => $pet_id, 'name' => 'perl test', + "photoUrls" => ['123', 'oop'], 'tags' => [$tag], 'status' => 'pending', 'category' => $category) } 'Pet.pm loaded OK'; + +is $pet->id, '10008', 'got the proper pet id'; +is $pet->name, 'perl test', 'got the proper pet name'; +is $pet->category->id, '22', 'got the proper category id'; +is $pet->category->name, 'perl', 'got the proper category name'; +is $pet->tags->[0]->name, 'just kidding', 'got the proper tag name'; +is $pet->tags->[0]->id, '11', 'got the proper tag id'; + + +my $add_pet = $api->add_pet(body => $pet); +my $get_pet = $api->get_pet_by_id(pet_id => $pet_id); + +is $get_pet->id, '10008', 'stored and retrieved: got the proper pet id'; +is $get_pet->name, 'perl test', 'stored and retrieved: got the proper pet name'; +is $get_pet->category->id, '22', 'stored and retrieved: got the proper category id'; +is $get_pet->category->name, 'perl', 'stored and retrieved: got the proper category name'; +is $get_pet->tags->[0]->name, 'just kidding', 'stored and retrieved: got the proper tag name'; +is $get_pet->tags->[0]->id, '11', 'stored and retrieved: got the proper tag id'; + +} # / SKIP + From 49034946a065c7f4094349776ea042bf5c5b4f9d Mon Sep 17 00:00:00 2001 From: Dave Baird Date: Mon, 9 Nov 2015 17:04:19 +0100 Subject: [PATCH 03/14] Make class and method documentation available Documentation from the swagger spec is available via methods class_documentation() and method_documentation() on object and API classes. --- .../main/resources/perl/BaseObject.mustache | 6 +- .../src/main/resources/perl/Role.mustache | 4 +- .../src/main/resources/perl/api.mustache | 25 ++- .../src/main/resources/perl/object.mustache | 2 + .../WWW/SwaggerClient/Object/BaseObject.pm | 6 +- .../lib/WWW/SwaggerClient/Object/Category.pm | 2 + .../lib/WWW/SwaggerClient/Object/Order.pm | 2 + .../perl/lib/WWW/SwaggerClient/Object/Pet.pm | 2 + .../perl/lib/WWW/SwaggerClient/Object/Tag.pm | 2 + .../perl/lib/WWW/SwaggerClient/Object/User.pm | 2 + .../perl/lib/WWW/SwaggerClient/PetApi.pm | 143 ++++++++++++++++++ .../perl/lib/WWW/SwaggerClient/Role.pm | 4 +- .../perl/lib/WWW/SwaggerClient/StoreApi.pm | 57 +++++++ .../perl/lib/WWW/SwaggerClient/UserApi.pm | 123 +++++++++++++++ samples/client/petstore/perl/t/04_role.t | 42 ++++- 15 files changed, 406 insertions(+), 16 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache b/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache index f2a58efdb68f..2bc48770632d 100644 --- a/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache @@ -20,8 +20,10 @@ use base ("Class::Accessor", "Class::Data::Inheritable"); #NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. # -__PACKAGE__->mk_classdata('attribute_map'); -__PACKAGE__->mk_classdata('swagger_types'); +__PACKAGE__->mk_classdata('attribute_map' => {}); +__PACKAGE__->mk_classdata('swagger_types' => {}); +__PACKAGE__->mk_classdata('method_documentation' => {}); # TODO +__PACKAGE__->mk_classdata('class_documentation' => {}); # new object sub new { diff --git a/modules/swagger-codegen/src/main/resources/perl/Role.mustache b/modules/swagger-codegen/src/main/resources/perl/Role.mustache index fee13feb040b..be41efe44c55 100644 --- a/modules/swagger-codegen/src/main/resources/perl/Role.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/Role.mustache @@ -24,7 +24,7 @@ sub BUILD { my $self = shift; # ignore these symbols imported into API namespaces - my %outsiders = map {$_ => 1} qw( new croak ); + my %outsiders = map {$_ => 1} qw( croak ); my %delegates; @@ -32,7 +32,7 @@ sub BUILD { foreach my $api_name ($self->api_factory->apis_available) { my $api_class = $self->api_factory->classname_for($api_name); my $methods = Class::Inspector->methods($api_class, 'expanded'); - my @local_methods = grep {! $outsiders{$_}} map {$_->[2]} grep {$_->[1] eq $api_class} @$methods; + my @local_methods = grep {! /^_/} grep {! $outsiders{$_}} map {$_->[2]} grep {$_->[1] eq $api_class} @$methods; push( @{$delegates{$_}}, {api_name => $api_name, api_class => $api_class} ) for @local_methods; } diff --git a/modules/swagger-codegen/src/main/resources/perl/api.mustache b/modules/swagger-codegen/src/main/resources/perl/api.mustache index d305d69b7faa..7cdbc30aaf46 100644 --- a/modules/swagger-codegen/src/main/resources/perl/api.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/api.mustache @@ -30,6 +30,12 @@ use Log::Any qw($log); use WWW::{{moduleName}}::ApiClient; use WWW::{{moduleName}}::Configuration; +use base "Class::Data::Inheritable"; + +__PACKAGE__->mk_classdata('method_documentation' => {}); +__PACKAGE__->mk_classdata('class_documentation' => {}); # TODO + + sub new { my $class = shift; my $default_api_client = $WWW::{{moduleName}}::Configuration::api_client ? $WWW::{{moduleName}}::Configuration::api_client : WWW::{{moduleName}}::ApiClient->new; @@ -49,13 +55,30 @@ sub new { {{#operations}} {{#operation}} + # # {{{nickname}}} # # {{{summary}}} # {{#allParams}}# @param {{dataType}} ${{paramName}} {{description}} {{#required}}(required){{/required}}{{^required}}(optional){{/required}} -{{/allParams}}# @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} +{{/allParams}} +{ + my $params = { +{{#allParams}} + '{{paramName}}' => { + data_type => '{{dataType}}', + description => '{{description}}', + required => {{#required}}'1'{{/required}}{{^required}}'0'{{/required}}, + }, +{{/allParams}} + }; + __PACKAGE__->method_documentation->{ {{{nickname}}} } = { summary => '{{{summary}}}', + params => $params, + returns => {{#returnType}}'{{{returnType}}}'{{/returnType}}{{^returnType}}undef{{/returnType}}, + }; +} +# @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} # sub {{nickname}} { my ($self, %args) = @_; diff --git a/modules/swagger-codegen/src/main/resources/perl/object.mustache b/modules/swagger-codegen/src/main/resources/perl/object.mustache index bbddd3c7f32c..c397569c3962 100644 --- a/modules/swagger-codegen/src/main/resources/perl/object.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/object.mustache @@ -21,6 +21,8 @@ use base "WWW::{{moduleName}}::Object::BaseObject"; #NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. # +__PACKAGE__->class_documentation({description => '{{description}}'}); + __PACKAGE__->swagger_types( { {{#vars}}'{{name}}' => '{{{datatype}}}'{{#hasMore}}, {{/hasMore}}{{/vars}} diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/BaseObject.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/BaseObject.pm index fee2b06fb0ee..d85ecf8a749b 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/BaseObject.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/BaseObject.pm @@ -20,8 +20,10 @@ use base ("Class::Accessor", "Class::Data::Inheritable"); #NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. # -__PACKAGE__->mk_classdata('attribute_map'); -__PACKAGE__->mk_classdata('swagger_types'); +__PACKAGE__->mk_classdata('attribute_map' => {}); +__PACKAGE__->mk_classdata('swagger_types' => {}); +__PACKAGE__->mk_classdata('method_documentation' => {}); # TODO +__PACKAGE__->mk_classdata('class_documentation' => {}); # new object sub new { diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Category.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Category.pm index 1e0629250377..a08ae19ac433 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Category.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Category.pm @@ -19,6 +19,8 @@ use base "WWW::SwaggerClient::Object::BaseObject"; #NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. # +__PACKAGE__->class_documentation({description => ''}); + __PACKAGE__->swagger_types( { 'id' => 'int', 'name' => 'string' diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Order.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Order.pm index 70b3db2cfc00..fa411b8e2540 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Order.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Order.pm @@ -19,6 +19,8 @@ use base "WWW::SwaggerClient::Object::BaseObject"; #NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. # +__PACKAGE__->class_documentation({description => ''}); + __PACKAGE__->swagger_types( { 'id' => 'int', 'pet_id' => 'int', diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Pet.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Pet.pm index 3ff3f50b3999..58fc85d3f17e 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Pet.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Pet.pm @@ -19,6 +19,8 @@ use base "WWW::SwaggerClient::Object::BaseObject"; #NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. # +__PACKAGE__->class_documentation({description => ''}); + __PACKAGE__->swagger_types( { 'id' => 'int', 'category' => 'Category', diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Tag.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Tag.pm index bf97f210a379..c3e6ca993bad 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Tag.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Tag.pm @@ -19,6 +19,8 @@ use base "WWW::SwaggerClient::Object::BaseObject"; #NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. # +__PACKAGE__->class_documentation({description => ''}); + __PACKAGE__->swagger_types( { 'id' => 'int', 'name' => 'string' diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/User.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/User.pm index 36fc7baf6ee5..1da22e6431bd 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/User.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/User.pm @@ -19,6 +19,8 @@ use base "WWW::SwaggerClient::Object::BaseObject"; #NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. # +__PACKAGE__->class_documentation({description => ''}); + __PACKAGE__->swagger_types( { 'id' => 'int', 'username' => 'string', diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm index 26b9f42e620e..0404c9c74bed 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm @@ -30,6 +30,12 @@ use Log::Any qw($log); use WWW::SwaggerClient::ApiClient; use WWW::SwaggerClient::Configuration; +use base "Class::Data::Inheritable"; + +__PACKAGE__->mk_classdata('method_documentation' => {}); +__PACKAGE__->mk_classdata('class_documentation' => {}); # TODO + + sub new { my $class = shift; my $default_api_client = $WWW::SwaggerClient::Configuration::api_client ? $WWW::SwaggerClient::Configuration::api_client : WWW::SwaggerClient::ApiClient->new; @@ -47,12 +53,26 @@ sub new { } + # # update_pet # # Update an existing pet # # @param Pet $body Pet object that needs to be added to the store (optional) +{ + my $params = { + 'body' => { + data_type => 'Pet', + description => 'Pet object that needs to be added to the store', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ update_pet } = { summary => 'Update an existing pet', + params => $params, + returns => undef, + }; +} # @return void # sub update_pet { @@ -97,12 +117,26 @@ sub update_pet { return; } + # # add_pet # # Add a new pet to the store # # @param Pet $body Pet object that needs to be added to the store (optional) +{ + my $params = { + 'body' => { + data_type => 'Pet', + description => 'Pet object that needs to be added to the store', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ add_pet } = { summary => 'Add a new pet to the store', + params => $params, + returns => undef, + }; +} # @return void # sub add_pet { @@ -147,12 +181,26 @@ sub add_pet { return; } + # # find_pets_by_status # # Finds Pets by status # # @param ARRAY[string] $status Status values that need to be considered for filter (optional) +{ + my $params = { + 'status' => { + data_type => 'ARRAY[string]', + description => 'Status values that need to be considered for filter', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ find_pets_by_status } = { summary => 'Finds Pets by status', + params => $params, + returns => 'ARRAY[Pet]', + }; +} # @return ARRAY[Pet] # sub find_pets_by_status { @@ -200,12 +248,26 @@ sub find_pets_by_status { return $_response_object; } + # # find_pets_by_tags # # Finds Pets by tags # # @param ARRAY[string] $tags Tags to filter by (optional) +{ + my $params = { + 'tags' => { + data_type => 'ARRAY[string]', + description => 'Tags to filter by', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ find_pets_by_tags } = { summary => 'Finds Pets by tags', + params => $params, + returns => 'ARRAY[Pet]', + }; +} # @return ARRAY[Pet] # sub find_pets_by_tags { @@ -253,12 +315,26 @@ sub find_pets_by_tags { return $_response_object; } + # # get_pet_by_id # # Find pet by ID # # @param int $pet_id ID of pet that needs to be fetched (required) +{ + my $params = { + 'pet_id' => { + data_type => 'int', + description => 'ID of pet that needs to be fetched', + required => '1', + }, + }; + __PACKAGE__->method_documentation->{ get_pet_by_id } = { summary => 'Find pet by ID', + params => $params, + returns => 'Pet', + }; +} # @return Pet # sub get_pet_by_id { @@ -313,6 +389,7 @@ sub get_pet_by_id { return $_response_object; } + # # update_pet_with_form # @@ -321,6 +398,29 @@ sub get_pet_by_id { # @param string $pet_id ID of pet that needs to be updated (required) # @param string $name Updated name of the pet (optional) # @param string $status Updated status of the pet (optional) +{ + my $params = { + 'pet_id' => { + data_type => 'string', + description => 'ID of pet that needs to be updated', + required => '1', + }, + 'name' => { + data_type => 'string', + description => 'Updated name of the pet', + required => '0', + }, + 'status' => { + data_type => 'string', + description => 'Updated status of the pet', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ update_pet_with_form } = { summary => 'Updates a pet in the store with form data', + params => $params, + returns => undef, + }; +} # @return void # sub update_pet_with_form { @@ -382,6 +482,7 @@ sub update_pet_with_form { return; } + # # delete_pet # @@ -389,6 +490,24 @@ sub update_pet_with_form { # # @param int $pet_id Pet id to delete (required) # @param string $api_key (optional) +{ + my $params = { + 'pet_id' => { + data_type => 'int', + description => 'Pet id to delete', + required => '1', + }, + 'api_key' => { + data_type => 'string', + description => '', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ delete_pet } = { summary => 'Deletes a pet', + params => $params, + returns => undef, + }; +} # @return void # sub delete_pet { @@ -443,6 +562,7 @@ sub delete_pet { return; } + # # upload_file # @@ -451,6 +571,29 @@ sub delete_pet { # @param int $pet_id ID of pet to update (required) # @param string $additional_metadata Additional data to pass to server (optional) # @param file $file file to upload (optional) +{ + my $params = { + 'pet_id' => { + data_type => 'int', + description => 'ID of pet to update', + required => '1', + }, + 'additional_metadata' => { + data_type => 'string', + description => 'Additional data to pass to server', + required => '0', + }, + 'file' => { + data_type => 'file', + description => 'file to upload', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ upload_file } = { summary => 'uploads an image', + params => $params, + returns => undef, + }; +} # @return void # sub upload_file { diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm index 4b63a483eae4..c21c428b85f3 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm @@ -24,7 +24,7 @@ sub BUILD { my $self = shift; # ignore these symbols imported into API namespaces - my %outsiders = map {$_ => 1} qw( new croak ); + my %outsiders = map {$_ => 1} qw( croak ); my %delegates; @@ -32,7 +32,7 @@ sub BUILD { foreach my $api_name ($self->api_factory->apis_available) { my $api_class = $self->api_factory->classname_for($api_name); my $methods = Class::Inspector->methods($api_class, 'expanded'); - my @local_methods = grep {! $outsiders{$_}} map {$_->[2]} grep {$_->[1] eq $api_class} @$methods; + my @local_methods = grep {! /^_/} grep {! $outsiders{$_}} map {$_->[2]} grep {$_->[1] eq $api_class} @$methods; push( @{$delegates{$_}}, {api_name => $api_name, api_class => $api_class} ) for @local_methods; } diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm index a2ac9010e779..d8cd0cbff7dd 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm @@ -30,6 +30,12 @@ use Log::Any qw($log); use WWW::SwaggerClient::ApiClient; use WWW::SwaggerClient::Configuration; +use base "Class::Data::Inheritable"; + +__PACKAGE__->mk_classdata('method_documentation' => {}); +__PACKAGE__->mk_classdata('class_documentation' => {}); # TODO + + sub new { my $class = shift; my $default_api_client = $WWW::SwaggerClient::Configuration::api_client ? $WWW::SwaggerClient::Configuration::api_client : WWW::SwaggerClient::ApiClient->new; @@ -47,11 +53,20 @@ sub new { } + # # get_inventory # # Returns pet inventories by status # +{ + my $params = { + }; + __PACKAGE__->method_documentation->{ get_inventory } = { summary => 'Returns pet inventories by status', + params => $params, + returns => 'HASH[string,int]', + }; +} # @return HASH[string,int] # sub get_inventory { @@ -96,12 +111,26 @@ sub get_inventory { return $_response_object; } + # # place_order # # Place an order for a pet # # @param Order $body order placed for purchasing the pet (optional) +{ + my $params = { + 'body' => { + data_type => 'Order', + description => 'order placed for purchasing the pet', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ place_order } = { summary => 'Place an order for a pet', + params => $params, + returns => 'Order', + }; +} # @return Order # sub place_order { @@ -149,12 +178,26 @@ sub place_order { return $_response_object; } + # # get_order_by_id # # Find purchase order by ID # # @param string $order_id ID of pet that needs to be fetched (required) +{ + my $params = { + 'order_id' => { + data_type => 'string', + description => 'ID of pet that needs to be fetched', + required => '1', + }, + }; + __PACKAGE__->method_documentation->{ get_order_by_id } = { summary => 'Find purchase order by ID', + params => $params, + returns => 'Order', + }; +} # @return Order # sub get_order_by_id { @@ -209,12 +252,26 @@ sub get_order_by_id { return $_response_object; } + # # delete_order # # Delete purchase order by ID # # @param string $order_id ID of the order that needs to be deleted (required) +{ + my $params = { + 'order_id' => { + data_type => 'string', + description => 'ID of the order that needs to be deleted', + required => '1', + }, + }; + __PACKAGE__->method_documentation->{ delete_order } = { summary => 'Delete purchase order by ID', + params => $params, + returns => undef, + }; +} # @return void # sub delete_order { diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm index e1088a0839e0..18d69ed5883d 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm @@ -30,6 +30,12 @@ use Log::Any qw($log); use WWW::SwaggerClient::ApiClient; use WWW::SwaggerClient::Configuration; +use base "Class::Data::Inheritable"; + +__PACKAGE__->mk_classdata('method_documentation' => {}); +__PACKAGE__->mk_classdata('class_documentation' => {}); # TODO + + sub new { my $class = shift; my $default_api_client = $WWW::SwaggerClient::Configuration::api_client ? $WWW::SwaggerClient::Configuration::api_client : WWW::SwaggerClient::ApiClient->new; @@ -47,12 +53,26 @@ sub new { } + # # create_user # # Create user # # @param User $body Created user object (optional) +{ + my $params = { + 'body' => { + data_type => 'User', + description => 'Created user object', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ create_user } = { summary => 'Create user', + params => $params, + returns => undef, + }; +} # @return void # sub create_user { @@ -97,12 +117,26 @@ sub create_user { return; } + # # create_users_with_array_input # # Creates list of users with given input array # # @param ARRAY[User] $body List of user object (optional) +{ + my $params = { + 'body' => { + data_type => 'ARRAY[User]', + description => 'List of user object', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ create_users_with_array_input } = { summary => 'Creates list of users with given input array', + params => $params, + returns => undef, + }; +} # @return void # sub create_users_with_array_input { @@ -147,12 +181,26 @@ sub create_users_with_array_input { return; } + # # create_users_with_list_input # # Creates list of users with given input array # # @param ARRAY[User] $body List of user object (optional) +{ + my $params = { + 'body' => { + data_type => 'ARRAY[User]', + description => 'List of user object', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ create_users_with_list_input } = { summary => 'Creates list of users with given input array', + params => $params, + returns => undef, + }; +} # @return void # sub create_users_with_list_input { @@ -197,6 +245,7 @@ sub create_users_with_list_input { return; } + # # login_user # @@ -204,6 +253,24 @@ sub create_users_with_list_input { # # @param string $username The user name for login (optional) # @param string $password The password for login in clear text (optional) +{ + my $params = { + 'username' => { + data_type => 'string', + description => 'The user name for login', + required => '0', + }, + 'password' => { + data_type => 'string', + description => 'The password for login in clear text', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ login_user } = { summary => 'Logs user into the system', + params => $params, + returns => 'string', + }; +} # @return string # sub login_user { @@ -254,11 +321,20 @@ sub login_user { return $_response_object; } + # # logout_user # # Logs out current logged in user session # +{ + my $params = { + }; + __PACKAGE__->method_documentation->{ logout_user } = { summary => 'Logs out current logged in user session', + params => $params, + returns => undef, + }; +} # @return void # sub logout_user { @@ -300,12 +376,26 @@ sub logout_user { return; } + # # get_user_by_name # # Get user by user name # # @param string $username The name that needs to be fetched. Use user1 for testing. (required) +{ + my $params = { + 'username' => { + data_type => 'string', + description => 'The name that needs to be fetched. Use user1 for testing.', + required => '1', + }, + }; + __PACKAGE__->method_documentation->{ get_user_by_name } = { summary => 'Get user by user name', + params => $params, + returns => 'User', + }; +} # @return User # sub get_user_by_name { @@ -360,6 +450,7 @@ sub get_user_by_name { return $_response_object; } + # # update_user # @@ -367,6 +458,24 @@ sub get_user_by_name { # # @param string $username name that need to be deleted (required) # @param User $body Updated user object (optional) +{ + my $params = { + 'username' => { + data_type => 'string', + description => 'name that need to be deleted', + required => '1', + }, + 'body' => { + data_type => 'User', + description => 'Updated user object', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ update_user } = { summary => 'Updated user', + params => $params, + returns => undef, + }; +} # @return void # sub update_user { @@ -421,12 +530,26 @@ sub update_user { return; } + # # delete_user # # Delete user # # @param string $username The name that needs to be deleted (required) +{ + my $params = { + 'username' => { + data_type => 'string', + description => 'The name that needs to be deleted', + required => '1', + }, + }; + __PACKAGE__->method_documentation->{ delete_user } = { summary => 'Delete user', + params => $params, + returns => undef, + }; +} # @return void # sub delete_user { diff --git a/samples/client/petstore/perl/t/04_role.t b/samples/client/petstore/perl/t/04_role.t index b35149c9d837..6fd37afabda2 100644 --- a/samples/client/petstore/perl/t/04_role.t +++ b/samples/client/petstore/perl/t/04_role.t @@ -1,5 +1,7 @@ -use Test::More tests => 15; +use Test::More tests => 21; use Test::Exception; +use Test::Warnings 'warnings'; +use Test::Deep; use lib 'lib'; use strict; @@ -9,22 +11,33 @@ use MooseX::amine; use Class::Inspector; use Data::Dumper; -use Log::Any::Adapter ('File', '/home/dave/bookeo_api.log'); - - SKIP: { eval " package MyApp; use Moose; with 'WWW::SwaggerClient::Role'; - sub auth_setup_handler {} "; - skip 'Moose not installed', 15 if $@; + skip 'Moose not installed', 21 if $@; -my $api = MyApp->new; +my $api; +cmp_deeply( + [ warnings { $api = MyApp->new } ], + bag( + "Cannot delegate new (use \$self->pet_api->new instead)\n", + "Cannot delegate new (use \$self->store_api->new instead)\n", + "Cannot delegate new (use \$self->user_api->new instead)\n", + "Cannot delegate class_documentation (use \$self->pet_api->class_documentation instead)\n", + "Cannot delegate class_documentation (use \$self->store_api->class_documentation instead)\n", + "Cannot delegate class_documentation (use \$self->user_api->class_documentation instead)\n", + "Cannot delegate method_documentation (use \$self->pet_api->method_documentation instead)\n", + "Cannot delegate method_documentation (use \$self->store_api->method_documentation instead)\n", + "Cannot delegate method_documentation (use \$self->user_api->method_documentation instead)\n", + ), + 'got expected warnings about non-delegatable methods', + ); my $pet_id = 10008; # note - we don't need to 'use' these modules because they've already been loaded by ApiFactory @@ -52,5 +65,20 @@ is $get_pet->category->name, 'perl', 'stored and retrieved: got the proper categ is $get_pet->tags->[0]->name, 'just kidding', 'stored and retrieved: got the proper tag name'; is $get_pet->tags->[0]->id, '11', 'stored and retrieved: got the proper tag id'; +# documentation tests +TODO: { + local $TODO = "Swagger spec doesn't populate all the description fields"; + is $api->pet_api->class_documentation->{description}, 'Pet API description', 'got corrrect Pet API description'; + is $get_pet->method_documentation->{name}, 'Description of the Pet object name() method', 'Pet object method_documentation is available'; +} + +is_deeply( [sort keys %{$api->pet_api->method_documentation}], + [ 'add_pet', 'delete_pet', 'find_pets_by_status', 'find_pets_by_tags', 'get_pet_by_id', 'update_pet', 'update_pet_with_form', 'upload_file'], + "Pet API method_documentation has the correct keys"); + +my $pet_class_doco = { 'description' => '' }; +is_deeply($get_pet->class_documentation, $pet_class_doco, 'Pet object class_documentation is available'); +# / documentation tests + } # / SKIP From c06af6d14178885185d5b999e050a4952a44e039 Mon Sep 17 00:00:00 2001 From: Dave Baird Date: Mon, 9 Nov 2015 23:04:59 +0100 Subject: [PATCH 04/14] Documentation and automatic documentation - added POD to Role.pm - added README.md files translated from Role.pm POD - added an autodoc script (based on AutoDoc.pm role). The script prints a listing of the methods built in Role.pm - added class_documentation() and method_documentation() accessors on all object and API classes which return the documentation supplied in the Swagger spec for the API --- .../codegen/languages/PerlClientCodegen.java | 2 + .../src/main/resources/perl/AutoDoc.mustache | 156 ++++++++++++++++ .../src/main/resources/perl/README.md | 164 +++++++++++++++++ .../src/main/resources/perl/Role.mustache | 167 ++++++++++++++++++ .../src/main/resources/perl/api.mustache | 2 +- .../resources/perl/autodoc.script.mustache | 19 ++ samples/client/petstore/perl/README.md | 164 +++++++++++++++++ samples/client/petstore/perl/bin/autodoc | 19 ++ .../perl/lib/WWW/SwaggerClient/Role.pm | 167 ++++++++++++++++++ .../lib/WWW/SwaggerClient/Role/AutoDoc.pm | 156 ++++++++++++++++ samples/client/petstore/perl/t/04_role.t | 4 - 11 files changed, 1015 insertions(+), 5 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache create mode 100644 modules/swagger-codegen/src/main/resources/perl/README.md create mode 100644 modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache create mode 100644 samples/client/petstore/perl/README.md create mode 100644 samples/client/petstore/perl/bin/autodoc create mode 100644 samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java index 3213f0b97163..27f39f11ed0d 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PerlClientCodegen.java @@ -100,6 +100,8 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig { supportingFiles.add(new SupportingFile("BaseObject.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "Object/BaseObject.pm")); supportingFiles.add(new SupportingFile("ApiFactory.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "ApiFactory.pm")); supportingFiles.add(new SupportingFile("Role.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "Role.pm")); + supportingFiles.add(new SupportingFile("AutoDoc.mustache", ("lib/WWW/" + moduleName + "/Role").replace('/', File.separatorChar), "AutoDoc.pm")); + supportingFiles.add(new SupportingFile("autodoc.script.mustache", ("bin/").replace('/', File.separatorChar), "autodoc")); } public CodegenType getTag() { diff --git a/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache b/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache new file mode 100644 index 000000000000..c756915f80f0 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache @@ -0,0 +1,156 @@ +package WWW::{{moduleName}}::Role::AutoDoc; +use List::MoreUtils qw(uniq); + +use Moose::Role; + +sub autodoc { + my $self = shift; + + $self->_printisa; + $self->_printmethods; + $self->_printattrs; + print "\n"; +} + +sub _printisa { + my $self = shift; + my $meta = $self->meta; + + my $myclass = ref $self; + + my $super = join ', ', $meta->superclasses; + my @roles = $meta->calculate_all_roles; + shift(@roles); # the first is a composite, the rest are the roles + + my $isa = join ', ', $meta->linearized_isa; + my $sub = join ', ', $meta->subclasses; + my $dsub = join ', ', $meta->direct_subclasses; + + my ($rolepkg, $role_reqs); + + $~ = 'INHERIT'; + write; + + foreach my $role (@roles) { + $rolepkg = $role->{package}; + $role_reqs = join ', ', keys %{$role->{required_methods}}; + $~ = 'ROLES'; + write; + } + +# ----- format specs ----- + format INHERIT = + +@* - +$myclass + ISA: @* + $isa + Direct subclasses: @* + $dsub + All subclasses: @* + $sub +. + format ROLES = + Composes: @* + $rolepkg + requires: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $role_reqs +. +# ----- / format specs ----- +} + +sub _printmethods { + my $self = shift; + $~ = 'METHODHEAD'; + write; + $self->_printmethod($_) for uniq sort $self->meta->get_method_list, $self->meta->get_all_method_names; +} + +sub _printmethod { + my ($self, $methodname) = @_; + return if $methodname =~ /^_/; + return if $self->meta->has_attribute($methodname); + my %internal = map {$_ => 1} qw(BUILD BUILDARGS meta can new DEMOLISHALL DESTROY + DOES isa BUILDALL does VERSION dump + ); + return if $internal{$methodname}; + my $method = $self->meta->get_method($methodname) or return; # symbols imported into namespaces i.e. not known by Moose + + return if $method->original_package_name eq __PACKAGE__; + + my $delegation = ''; + my $delegate_to = ''; + my $via = ''; + my $on = ''; + if ($method->can('associated_attribute')) { + $delegate_to = $method->delegate_to_method; + my $aa = $method->associated_attribute; + $on = $aa->{isa}; + $via = $aa->{name}; + } + + $~ = 'METHOD'; + write; + +# ----- format specs ----- + format METHODHEAD = + +METHODS +------- +Name delegate to on via +=================================================================================================================================== +. + format METHOD = +@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<... +$methodname, $delegate_to, $on, $via +. +# ----- / format specs ----- +} + +sub _printattrs { + my $self = shift; + $~ = 'ATTRHEAD'; + write; + $self->_printattr($_) for sort $self->meta->get_attribute_list; +} + +sub _printattr { + my ($self, $attrname) = @_; + return if $attrname =~ /^_/; + my $attr = $self->meta->get_attribute($attrname) or die "No attr for $attrname"; + + my $is; + $is = 'rw' if $attr->get_read_method && $attr->get_write_method; + $is = 'ro' if $attr->get_read_method && ! $attr->get_write_method; + $is = 'wo' if $attr->get_write_method && ! $attr->get_read_method; + $is = '--' if ! $attr->get_write_method && ! $attr->get_read_method; + $is or die "No \$is for $attrname"; + + my $tc = $attr->type_constraint || ''; + my $from = $attr->associated_class->name || ''; + my $reqd = $attr->is_required ? 'reqd' : 'opt'; + my $lazy = $attr->is_lazy ? 'lazy' : ''; + my $doc = $attr->has_documentation ? 'yes' : ''; + my $handles = join ', ', sort @{$attr->handles || []}; + + $~ = 'ATTR'; + write; + +# ----- format specs ----- + format ATTRHEAD = + +ATTRIBUTES +---------- +Name is isa reqd lazy doc handles +============================================================================================================== +. + format ATTR = +@<<<<<<<<<<<<<<<<< @< @<<<<<<<<<<<<<<<<<<<<<<<< @<<< @<<< @<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +$attrname, $is, $tc, $reqd, $lazy, $doc, $handles + ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $handles +. +# ----- / format specs ----- +} + +1; \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/perl/README.md b/modules/swagger-codegen/src/main/resources/perl/README.md new file mode 100644 index 000000000000..3cc2fda6528f --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/perl/README.md @@ -0,0 +1,164 @@ +# NAME + +WWW::{{moduleName}}::Role - a Moose role for the Perl Swagger Codegen project + +## A note on Moose + +This role is the only component of the library that uses Moose. See +WWW::{{moduleName}}::ApiFactory for non-Moosey usage. + +# SYNOPSIS + +The Perl Swagger Codegen project builds a library of Perl modules to interact with +a web service defined by a Swagger specification. See below for how to build the +library. + +This module provides an interface to the generated library. All the classes, +objects, and methods (well, not quite \*all\*, see below) are flattened into this +role. + + package MyApp; + use Moose; + has [qw(username password)] => ( is => 'ro', required => 1, isa => 'Str' ); + with 'WWW::{{moduleName}}::Role'; + sub auth_setup_handler {...} + + package main; + + my $api = MyApp->new({username => $username, password => $password}); + + my $pet = $api->get_pet_by_id(pet_id => $pet_id); + + +Notice that you need to provide the code to accept the parameters passed in to `new()` +(by setting up attributes via the `has` keyword). They should be used by +`auth_setup_handler()` to configure authentication (see below). + +## Structure of the library + +The library consists of a set of API classes, one for each endpoint. These APIs +implement the method calls available on each endpoint. + +Additionally, there is a set of "object" classes, which represent the objects +returned by and sent to the methods on the endpoints. + +An API factory class is provided, which builds instances of each endpoint API. + +This Moose role flattens all the methods from the endpoint APIs onto the consuming +class. It also provides methods to retrieve the endpoint API objects, and the API +factory object, should you need it. + +For documentation of all these methods, see AUTOMATIC DOCUMENTATION below. + +# METHODS + +## `auth_setup_handler()` + +This method is NOT provided - you must write it yourself. Its task is to configure +authentication for each request. + +The method is called on your `$api` object and passed the following parameters: + +- `header_params` + + A hashref that will become the request headers. You can insert auth + parameters. + +- `query_params` + + A hashref that will be encoded into the request URL. You can insert auth + parameters. + +- `auth_settings` + + TODO. + +- `api_client` + + A reference to the `WWW::{{moduleName}}::ApiClient` object that is responsible + for communicating with the server. + +For example: + + sub auth_setup_handler { + my ($self, %p) = @_; + $p{header_params}->{'X-TargetApp-apiKey'} = $api_key; + $p{header_params}->{'X-TargetApp-secretKey'} = $secret_key; + } + +## base\_url + +The generated code has the `base_url` already set as a default value. This method +returns (and optionally sets) the current value of `base_url`. + +## api\_factory + +Returns an API factory object. You probably won't need to call this directly. + + $self->api_factory('Pet'); # returns a WWW::{{moduleName}}::PetApi instance + + $self->pet_api; # the same + +# MISSING METHODS + +Most of the methods on the API are delegated to individual sub-API objects (e.g. +Pet API, Store API, User API etc). Where different sub-APIs use the same method +name (e.g. `new()`), these methods can't be delegated. So you need to call +`$api->pet_api->new()`. + +In principle, every API is susceptible to the presence of a few, random, undelegatable +method names. In practice, because of the way method names are constructed, it's +unlikely in general that any methods will be undelegatable, except for: + + new() + class_documentation() + method_documentation() + +To call these methods, you need to get a handle on the relevant object, either +by calling `$api->foo_api` or by retrieving an object, e.g. +`$api->get_pet_by_id(pet_id => $pet_id)`. + +# BUILDING YOUR LIBRARY + +See the homepage `https://github.com/swagger-api/swagger-codegen` for full details. +But briefly, clone the git repository, build the codegen codebase, set up your build +config file, then run the API build script. You will need git, Java 7 and Apache +maven 3.0.3 or better already installed. + +The config file should specify the project name for the generated library: + + {"moduleName":"MyProjectName"} + +Your library files will be built under `WWW::MyProjectName`. + + $ git clone https://github.com/swagger-api/swagger-codegen.git + $ cd swagger-codegen + $ mvn package + $ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \ + -i [URL or file path to JSON swagger API spec] \ + -l perl \ + -c /path/to/config/file.json \ + -o /path/to/output/folder + +Bang, all done. Run the `autodoc` script in the `bin` directory to see the API +you just built. + +# AUTOMATIC DOCUMENTATION + +You can print out a summary of the generated API by running the included +`autodoc` script in the `bin` directory of your generated library. + +# DOCUMENTATION FROM THE SWAGGER SPEC + +Additional documentation for each class and method may be provided by the Swagger +spec. If so, this is available via the `class_documentation()` and +`method_documentation()` methods on each generated API and class: + + my $cdoc = $api->pet_api->class_documentation; + my $cmdoc = $api->pet_api->method_documentation->{$method_name}; + + my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation; + my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name}; + + +Each of these calls returns a hashref with various useful pieces of information. diff --git a/modules/swagger-codegen/src/main/resources/perl/Role.mustache b/modules/swagger-codegen/src/main/resources/perl/Role.mustache index be41efe44c55..951f05bab745 100644 --- a/modules/swagger-codegen/src/main/resources/perl/Role.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/Role.mustache @@ -69,6 +69,173 @@ sub _build_af { return WWW::{{moduleName}}::ApiFactory->new(%args); } +=head1 NAME +WWW::{{moduleName}}::Role - a Moose role for the Perl Swagger Codegen project + +=head2 A note on Moose + +This role is the only component of the library that uses Moose. See +WWW::{{moduleName}}::ApiFactory for non-Moosey usage. + +=head1 SYNOPSIS + +The Perl Swagger Codegen project builds a library of Perl modules to interact with +a web service defined by a Swagger specification. See below for how to build the +library. + +This module provides an interface to the generated library. All the classes, +objects, and methods (well, not quite *all*, see below) are flattened into this +role. + + package MyApp; + use Moose; + has [qw(username password)] => ( is => 'ro', required => 1, isa => 'Str' ); + with 'WWW::{{moduleName}}::Role'; + sub auth_setup_handler {...} + + package main; + + my $api = MyApp->new({username => $username, password => $password}); + + my $pet = $api->get_pet_by_id(pet_id => $pet_id); + +Notice that you need to provide the code to accept the parameters passed in to C +(by setting up attributes via the C keyword). They should be used by +C to configure authentication (see below). + +=head2 Structure of the library + +The library consists of a set of API classes, one for each endpoint. These APIs +implement the method calls available on each endpoint. + +Additionally, there is a set of "object" classes, which represent the objects +returned by and sent to the methods on the endpoints. + +An API factory class is provided, which builds instances of each endpoint API. + +This Moose role flattens all the methods from the endpoint APIs onto the consuming +class. It also provides methods to retrieve the endpoint API objects, and the API +factory object, should you need it. + +For documentation of all these methods, see AUTOMATIC DOCUMENTATION below. + +=head1 METHODS + +=head2 C + +This method is NOT provided - you must write it yourself. Its task is to configure +authentication for each request. + +The method is called on your C<$api> object and passed the following parameters: + +=over 4 + +=item C + +A hashref that will become the request headers. You can insert auth +parameters. + +=item C + +A hashref that will be encoded into the request URL. You can insert auth +parameters. + +=item C + +TODO. + +=item C + +A reference to the C object that is responsible +for communicating with the server. + +=back + +For example: + + sub auth_setup_handler { + my ($self, %p) = @_; + $p{header_params}->{'X-TargetApp-apiKey'} = $api_key; + $p{header_params}->{'X-TargetApp-secretKey'} = $secret_key; + } + +=head2 base_url + +The generated code has the C already set as a default value. This method +returns (and optionally sets) the current value of C. + +=head2 api_factory + +Returns an API factory object. You probably won't need to call this directly. + + $self->api_factory('Pet'); # returns a WWW::{{moduleName}}::PetApi instance + + $self->pet_api; # the same + +=head1 MISSING METHODS + +Most of the methods on the API are delegated to individual sub-API objects (e.g. +Pet API, Store API, User API etc). Where different sub-APIs use the same method +name (e.g. C), these methods can't be delegated. So you need to call +C<$api-Epet_api-Enew()>. + +In principle, every API is susceptible to the presence of a few, random, undelegatable +method names. In practice, because of the way method names are constructed, it's +unlikely in general that any methods will be undelegatable, except for: + + new() + class_documentation() + method_documentation() + +To call these methods, you need to get a handle on the relevant object, either +by calling C<$api-Efoo_api> or by retrieving an object, e.g. +C<$api-Eget_pet_by_id(pet_id =E $pet_id)>. + +=head1 BUILDING YOUR LIBRARY + +See the homepage C for full details. +But briefly, clone the git repository, build the codegen codebase, set up your build +config file, then run the API build script. You will need git, Java 7 and Apache +maven 3.0.3 or better already installed. + +The config file should specify the project name for the generated library: + + {"moduleName":"MyProjectName"} + +Your library files will be built under C. + + $ git clone https://github.com/swagger-api/swagger-codegen.git + $ cd swagger-codegen + $ mvn package + $ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \ + -i [URL or file path to JSON swagger API spec] \ + -l perl \ + -c /path/to/config/file.json \ + -o /path/to/output/folder + +Bang, all done. Run the C script in the C directory to see the API +you just built. + +=head1 AUTOMATIC DOCUMENTATION + +You can print out a summary of the generated API by running the included +C script in the C directory of your generated library. + +=head1 DOCUMENTATION FROM THE SWAGGER SPEC + +Additional documentation for each class and method may be provided by the Swagger +spec. If so, this is available via the C and +C methods on each generated API and class: + + my $cdoc = $api->pet_api->class_documentation; + my $cmdoc = $api->pet_api->method_documentation->{$method_name}; + + my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation; + my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name}; + +Each of these calls returns a hashref with various useful pieces of information. + +=cut 1; diff --git a/modules/swagger-codegen/src/main/resources/perl/api.mustache b/modules/swagger-codegen/src/main/resources/perl/api.mustache index 7cdbc30aaf46..a93cbc2b4a4c 100644 --- a/modules/swagger-codegen/src/main/resources/perl/api.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/api.mustache @@ -73,7 +73,7 @@ sub new { }, {{/allParams}} }; - __PACKAGE__->method_documentation->{ {{{nickname}}} } = { summary => '{{{summary}}}', + __PACKAGE__->method_documentation->{ {{nickname}} } = { summary => '{{summary}}', params => $params, returns => {{#returnType}}'{{{returnType}}}'{{/returnType}}{{^returnType}}undef{{/returnType}}, }; diff --git a/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache b/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache new file mode 100644 index 000000000000..b39bd8986471 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache @@ -0,0 +1,19 @@ +#!/usr/bin/perl +package MyAutodoc; +use FindBin; +use File::Spec; +use lib File::Spec->catdir($FindBin::Bin, '..', 'lib'); + +use Moose; + +with ('WWW::{{moduleName}}::Role', 'WWW::{{moduleName}}::Role::AutoDoc'); + +sub auth_setup_handler {} + +package main; + +my $api = MyAutodoc->new; + +print $api->autodoc; + +exit(0); diff --git a/samples/client/petstore/perl/README.md b/samples/client/petstore/perl/README.md new file mode 100644 index 000000000000..54c8b861eda8 --- /dev/null +++ b/samples/client/petstore/perl/README.md @@ -0,0 +1,164 @@ +# NAME + +WWW::SwaggerClient::Role - a Moose role for the Perl Swagger Codegen project + +## A note on Moose + +This role is the only component of the library that uses Moose. See +WWW::SwaggerClient::ApiFactory for non-Moosey usage. + +# SYNOPSIS + +The Perl Swagger Codegen project builds a library of Perl modules to interact with +a web service defined by a Swagger specification. See below for how to built the +library. + +This module provides an interface to the generated library. All the classes, +objects, and methods (well, not quite \*all\*, see below) are flattened into this +role. + + package MyApp; + use Moose; + has [qw(username password)] => ( is => 'ro', required => 1, isa => 'Str' ); + with 'WWW::SwaggerClient::Role'; + sub auth_setup_handler {...} + + package main; + + my $api = MyApp->new({username => $username, password => $password}); + + my $pet = $api->get_pet_by_id(pet_id => $pet_id); + + +Notice that you need to provide the code to accept the parameters passed in to `new()` +(by setting up attributes via the `has` keyword). They should be used by +`auth_setup_handler()` to configure authentication (see below). + +## Structure of the library + +The library consists of a set of API classes, one for each endpoint. These APIs +implement the method calls available on each endpoint. + +Additionally, there is a set of "object" classes, which represent the objects +returned by and sent to the methods on the endpoints. + +An API factory class is provided, which builds instances of each endpoint API. + +This Moose role flattens all the methods from the endpoint APIs onto the consuming +class. It also provides methods to retrieve the endpoint API objects, and the API +factory object, should you need it. + +For documentation of all these methods, see AUTOMATIC DOCUMENTATION below. + +# METHODS + +## `auth_setup_handler()` + +This method is NOT provided - you must write it yourself. Its task is to configure +authentication for each request. + +The method is called on your `$api` object and passed the following parameters: + +- `header_params` + + A hashref that will become the request headers. You can insert auth + parameters. + +- `query_params` + + A hashref that will be encoded into the request URL. You can insert auth + parameters. + +- `auth_settings` + + TODO. + +- `api_client` + + A reference to the `WWW::SwaggerClient::ApiClient` object that is responsible + for communicating with the server. + +For example: + + sub auth_setup_handler { + my ($self, %p) = @_; + $p{header_params}->{'X-TargetApp-apiKey'} = $api_key; + $p{header_params}->{'X-TargetApp-secretKey'} = $secret_key; + } + +## base\_url + +The generated code has the `base_url` already set as a default value. This method +returns (and optionally sets) the current value of `base_url`. + +## api\_factory + +Returns an API factory object. You probably won't need to call this directly. + + $self->api_factory('Pet'); # returns a WWW::SwaggerClient::PetApi instance + + $self->pet_api; # the same + +# MISSING METHODS + +Most of the methods on the API are delegated to individual sub-API objects (e.g. +Pet API, Store API, User API etc). Where different sub-APIs use the same method +name (e.g. `new()`), these methods can't be delegated. So you need to call +`$api->pet_api->new()`. + +In principle, every API is susceptible to the presence of a few, random, undelegatable +method names. In practice, because of the way method names are constructed, it's +unlikely in general that any methods will be undelegatable, except for: + + new() + class_documentation() + method_documentation() + +To call these methods, you need to get a handle on the relevant object, either +by calling `$api->foo_api` or by retrieving an object, e.g. +`$api->get_pet_by_id(pet_id => $pet_id)`. + +# BUILDING YOUR LIBRARY + +See the homepage `https://github.com/swagger-api/swagger-codegen` for full details. +But briefly, clone the git repository, build the codegen codebase, set up your build +config file, then run the API build script. You will need git, Java 7 and Apache +maven 3.0.3 or better already installed. + +The config file should specify the project name for the generated library: + + {"moduleName":"MyProjectName"} + +Your library files will be built under `WWW::MyProjectName`. + + $ git clone https://github.com/swagger-api/swagger-codegen.git + $ cd swagger-codegen + $ mvn package + $ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \ + -i [URL or file path to JSON swagger API spec] \ + -l perl \ + -c /path/to/config/file.json \ + -o /path/to/output/folder + +Bang, all done. Run the `autodoc` script in the `bin` directory to see the API +you just built. + +# AUTOMATIC DOCUMENTATION + +You can print out a summary of the generated API by running the included +`autodoc` script in the `bin` directory of your generated library. + +# DOCUMENTATION FROM THE SWAGGER SPEC + +Additional documentation for each class and method may be provided by the Swagger +spec. If so, this is available via the `class_documentation()` and +`method_documentation()` methods on each generated API and class: + + my $cdoc = $api->pet_api->class_documentation; + my $cmdoc = $api->pet_api->method_documentation->{$method_name}; + + my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation; + my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name}; + + +Each of these calls returns a hashref with various useful pieces of information. diff --git a/samples/client/petstore/perl/bin/autodoc b/samples/client/petstore/perl/bin/autodoc new file mode 100644 index 000000000000..0e9f893e642d --- /dev/null +++ b/samples/client/petstore/perl/bin/autodoc @@ -0,0 +1,19 @@ +#!/usr/bin/perl +package MyAutodoc; +use FindBin; +use File::Spec; +use lib File::Spec->catdir($FindBin::Bin, '..', 'lib'); + +use Moose; + +with ('WWW::SwaggerClient::Role', 'WWW::SwaggerClient::Role::AutoDoc'); + +sub auth_setup_handler {} + +package main; + +my $api = MyAutodoc->new; + +print $api->autodoc; + +exit(0); diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm index c21c428b85f3..2b8969b3e3f3 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm @@ -69,6 +69,173 @@ sub _build_af { return WWW::SwaggerClient::ApiFactory->new(%args); } +=head1 NAME +WWW::SwaggerClient::Role - a Moose role for the Perl Swagger Codegen project + +=head2 A note on Moose + +This role is the only component of the library that uses Moose. See +WWW::SwaggerClient::ApiFactory for non-Moosey usage. + +=head1 SYNOPSIS + +The Perl Swagger Codegen project builds a library of Perl modules to interact with +a web service defined by a Swagger specification. See below for how to build the +library. + +This module provides an interface to the generated library. All the classes, +objects, and methods (well, not quite *all*, see below) are flattened into this +role. + + package MyApp; + use Moose; + has [qw(username password)] => ( is => 'ro', required => 1, isa => 'Str' ); + with 'WWW::SwaggerClient::Role'; + sub auth_setup_handler {...} + + package main; + + my $api = MyApp->new({username => $username, password => $password}); + + my $pet = $api->get_pet_by_id(pet_id => $pet_id); + +Notice that you need to provide the code to accept the parameters passed in to C +(by setting up attributes via the C keyword). They should be used by +C to configure authentication (see below). + +=head2 Structure of the library + +The library consists of a set of API classes, one for each endpoint. These APIs +implement the method calls available on each endpoint. + +Additionally, there is a set of "object" classes, which represent the objects +returned by and sent to the methods on the endpoints. + +An API factory class is provided, which builds instances of each endpoint API. + +This Moose role flattens all the methods from the endpoint APIs onto the consuming +class. It also provides methods to retrieve the endpoint API objects, and the API +factory object, should you need it. + +For documentation of all these methods, see AUTOMATIC DOCUMENTATION below. + +=head1 METHODS + +=head2 C + +This method is NOT provided - you must write it yourself. Its task is to configure +authentication for each request. + +The method is called on your C<$api> object and passed the following parameters: + +=over 4 + +=item C + +A hashref that will become the request headers. You can insert auth +parameters. + +=item C + +A hashref that will be encoded into the request URL. You can insert auth +parameters. + +=item C + +TODO. + +=item C + +A reference to the C object that is responsible +for communicating with the server. + +=back + +For example: + + sub auth_setup_handler { + my ($self, %p) = @_; + $p{header_params}->{'X-TargetApp-apiKey'} = $api_key; + $p{header_params}->{'X-TargetApp-secretKey'} = $secret_key; + } + +=head2 base_url + +The generated code has the C already set as a default value. This method +returns (and optionally sets) the current value of C. + +=head2 api_factory + +Returns an API factory object. You probably won't need to call this directly. + + $self->api_factory('Pet'); # returns a WWW::SwaggerClient::PetApi instance + + $self->pet_api; # the same + +=head1 MISSING METHODS + +Most of the methods on the API are delegated to individual sub-API objects (e.g. +Pet API, Store API, User API etc). Where different sub-APIs use the same method +name (e.g. C), these methods can't be delegated. So you need to call +C<$api-Epet_api-Enew()>. + +In principle, every API is susceptible to the presence of a few, random, undelegatable +method names. In practice, because of the way method names are constructed, it's +unlikely in general that any methods will be undelegatable, except for: + + new() + class_documentation() + method_documentation() + +To call these methods, you need to get a handle on the relevant object, either +by calling C<$api-Efoo_api> or by retrieving an object, e.g. +C<$api-Eget_pet_by_id(pet_id =E $pet_id)>. + +=head1 BUILDING YOUR LIBRARY + +See the homepage C for full details. +But briefly, clone the git repository, build the codegen codebase, set up your build +config file, then run the API build script. You will need git, Java 7 and Apache +maven 3.0.3 or better already installed. + +The config file should specify the project name for the generated library: + + {"moduleName":"MyProjectName"} + +Your library files will be built under C. + + $ git clone https://github.com/swagger-api/swagger-codegen.git + $ cd swagger-codegen + $ mvn package + $ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \ + -i [URL or file path to JSON swagger API spec] \ + -l perl \ + -c /path/to/config/file.json \ + -o /path/to/output/folder + +Bang, all done. Run the C script in the C directory to see the API +you just built. + +=head1 AUTOMATIC DOCUMENTATION + +You can print out a summary of the generated API by running the included +C script in the C directory of your generated library. + +=head1 DOCUMENTATION FROM THE SWAGGER SPEC + +Additional documentation for each class and method may be provided by the Swagger +spec. If so, this is available via the C and +C methods on each generated API and class: + + my $cdoc = $api->pet_api->class_documentation; + my $cmdoc = $api->pet_api->method_documentation->{$method_name}; + + my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation; + my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name}; + +Each of these calls returns a hashref with various useful pieces of information. + +=cut 1; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm new file mode 100644 index 000000000000..93b45427bbe1 --- /dev/null +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm @@ -0,0 +1,156 @@ +package WWW::SwaggerClient::Role::AutoDoc; +use List::MoreUtils qw(uniq); + +use Moose::Role; + +sub autodoc { + my $self = shift; + + $self->_printisa; + $self->_printmethods; + $self->_printattrs; + print "\n"; +} + +sub _printisa { + my $self = shift; + my $meta = $self->meta; + + my $myclass = ref $self; + + my $super = join ', ', $meta->superclasses; + my @roles = $meta->calculate_all_roles; + shift(@roles); # the first is a composite, the rest are the roles + + my $isa = join ', ', $meta->linearized_isa; + my $sub = join ', ', $meta->subclasses; + my $dsub = join ', ', $meta->direct_subclasses; + + my ($rolepkg, $role_reqs); + + $~ = 'INHERIT'; + write; + + foreach my $role (@roles) { + $rolepkg = $role->{package}; + $role_reqs = join ', ', keys %{$role->{required_methods}}; + $~ = 'ROLES'; + write; + } + +# ----- format specs ----- + format INHERIT = + +@* - +$myclass + ISA: @* + $isa + Direct subclasses: @* + $dsub + All subclasses: @* + $sub +. + format ROLES = + Composes: @* + $rolepkg + requires: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $role_reqs +. +# ----- / format specs ----- +} + +sub _printmethods { + my $self = shift; + $~ = 'METHODHEAD'; + write; + $self->_printmethod($_) for uniq sort $self->meta->get_method_list, $self->meta->get_all_method_names; +} + +sub _printmethod { + my ($self, $methodname) = @_; + return if $methodname =~ /^_/; + return if $self->meta->has_attribute($methodname); + my %internal = map {$_ => 1} qw(BUILD BUILDARGS meta can new DEMOLISHALL DESTROY + DOES isa BUILDALL does VERSION dump + ); + return if $internal{$methodname}; + my $method = $self->meta->get_method($methodname) or return; # symbols imported into namespaces i.e. not known by Moose + + return if $method->original_package_name eq __PACKAGE__; + + my $delegation = ''; + my $delegate_to = ''; + my $via = ''; + my $on = ''; + if ($method->can('associated_attribute')) { + $delegate_to = $method->delegate_to_method; + my $aa = $method->associated_attribute; + $on = $aa->{isa}; + $via = $aa->{name}; + } + + $~ = 'METHOD'; + write; + +# ----- format specs ----- + format METHODHEAD = + +METHODS +------- +Name delegate to on via +=================================================================================================================================== +. + format METHOD = +@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<... +$methodname, $delegate_to, $on, $via +. +# ----- / format specs ----- +} + +sub _printattrs { + my $self = shift; + $~ = 'ATTRHEAD'; + write; + $self->_printattr($_) for sort $self->meta->get_attribute_list; +} + +sub _printattr { + my ($self, $attrname) = @_; + return if $attrname =~ /^_/; + my $attr = $self->meta->get_attribute($attrname) or die "No attr for $attrname"; + + my $is; + $is = 'rw' if $attr->get_read_method && $attr->get_write_method; + $is = 'ro' if $attr->get_read_method && ! $attr->get_write_method; + $is = 'wo' if $attr->get_write_method && ! $attr->get_read_method; + $is = '--' if ! $attr->get_write_method && ! $attr->get_read_method; + $is or die "No \$is for $attrname"; + + my $tc = $attr->type_constraint || ''; + my $from = $attr->associated_class->name || ''; + my $reqd = $attr->is_required ? 'reqd' : 'opt'; + my $lazy = $attr->is_lazy ? 'lazy' : ''; + my $doc = $attr->has_documentation ? 'yes' : ''; + my $handles = join ', ', sort @{$attr->handles || []}; + + $~ = 'ATTR'; + write; + +# ----- format specs ----- + format ATTRHEAD = + +ATTRIBUTES +---------- +Name is isa reqd lazy doc handles +============================================================================================================== +. + format ATTR = +@<<<<<<<<<<<<<<<<< @< @<<<<<<<<<<<<<<<<<<<<<<<< @<<< @<<< @<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +$attrname, $is, $tc, $reqd, $lazy, $doc, $handles + ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $handles +. +# ----- / format specs ----- +} + +1; \ No newline at end of file diff --git a/samples/client/petstore/perl/t/04_role.t b/samples/client/petstore/perl/t/04_role.t index 6fd37afabda2..9592ec3f822d 100644 --- a/samples/client/petstore/perl/t/04_role.t +++ b/samples/client/petstore/perl/t/04_role.t @@ -7,10 +7,6 @@ use lib 'lib'; use strict; use warnings; -use MooseX::amine; -use Class::Inspector; -use Data::Dumper; - SKIP: { eval " package MyApp; From 521b73b3ef33b74b2db9efca89ec9f159f66910b Mon Sep 17 00:00:00 2001 From: Dave Baird Date: Tue, 10 Nov 2015 09:47:58 +0100 Subject: [PATCH 05/14] Apply the singleton pattern to ApiClient - make the api_client a singleton - remove it from the configuration namespace --- .../src/main/resources/perl/ApiClient.mustache | 4 +++- .../src/main/resources/perl/ApiFactory.mustache | 2 +- .../src/main/resources/perl/Configuration.mustache | 1 - .../src/main/resources/perl/api.mustache | 3 +-- samples/client/petstore/perl/README.md | 2 +- .../petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm | 4 +++- .../petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm | 2 +- .../perl/lib/WWW/SwaggerClient/Configuration.pm | 1 - .../petstore/perl/lib/WWW/SwaggerClient/PetApi.pm | 3 +-- .../petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm | 3 +-- .../petstore/perl/lib/WWW/SwaggerClient/UserApi.pm | 3 +-- samples/client/petstore/perl/t/01_pet_api.t | 10 ++++++++-- samples/client/petstore/perl/t/02_store_api.t | 2 +- samples/client/petstore/perl/t/03_api_factory.t | 3 +++ 14 files changed, 25 insertions(+), 18 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache index 89e5650759a6..ae8dce3d3515 100644 --- a/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache @@ -20,7 +20,9 @@ use Module::Runtime qw(use_module); use WWW::{{moduleName}}::Configuration; -sub new +use base 'Class::Singleton'; + +sub _new_instance { my $class = shift; my (%args) = ( diff --git a/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache b/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache index 724ad63b048d..cb619091ca30 100644 --- a/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache @@ -65,7 +65,7 @@ my %_apis = map { $_ =~ /^WWW::{{moduleName}}::(.*)$/; $1 => $_ } sub new { my ($class, %p) = (shift, @_); - $p{api_client} = WWW::{{moduleName}}::ApiClient->new(%p); + $p{api_client} = WWW::{{moduleName}}::ApiClient->instance(%p); return bless \%p, $class; } diff --git a/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache b/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache index d0b8b2c0e684..d0cc157647f4 100644 --- a/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache @@ -10,7 +10,6 @@ use Carp; use constant VERSION => '{{moduleVersion}}'; # class/static variables -our $api_client; our $http_timeout = 180; our $http_user_agent = 'Perl-Swagger'; diff --git a/modules/swagger-codegen/src/main/resources/perl/api.mustache b/modules/swagger-codegen/src/main/resources/perl/api.mustache index a93cbc2b4a4c..e31f2f32d6c4 100644 --- a/modules/swagger-codegen/src/main/resources/perl/api.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/api.mustache @@ -38,9 +38,8 @@ __PACKAGE__->mk_classdata('class_documentation' => {}); # TODO sub new { my $class = shift; - my $default_api_client = $WWW::{{moduleName}}::Configuration::api_client ? $WWW::{{moduleName}}::Configuration::api_client : WWW::{{moduleName}}::ApiClient->new; my (%self) = ( - 'api_client' => $default_api_client, + 'api_client' => WWW::{{moduleName}}::ApiClient->instance, @_ ); diff --git a/samples/client/petstore/perl/README.md b/samples/client/petstore/perl/README.md index 54c8b861eda8..a04d5a0aad6f 100644 --- a/samples/client/petstore/perl/README.md +++ b/samples/client/petstore/perl/README.md @@ -10,7 +10,7 @@ WWW::SwaggerClient::ApiFactory for non-Moosey usage. # SYNOPSIS The Perl Swagger Codegen project builds a library of Perl modules to interact with -a web service defined by a Swagger specification. See below for how to built the +a web service defined by a Swagger specification. See below for how to build the library. This module provides an interface to the generated library. All the classes, diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm index 8b51bd3c97bd..d3568c812e4e 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm @@ -20,7 +20,9 @@ use Module::Runtime qw(use_module); use WWW::SwaggerClient::Configuration; -sub new +use base 'Class::Singleton'; + +sub _new_instance { my $class = shift; my (%args) = ( diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm index bf3617d86f1f..77c23fdb2b36 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm @@ -65,7 +65,7 @@ my %_apis = map { $_ =~ /^WWW::SwaggerClient::(.*)$/; $1 => $_ } sub new { my ($class, %p) = (shift, @_); - $p{api_client} = WWW::SwaggerClient::ApiClient->new(%p); + $p{api_client} = WWW::SwaggerClient::ApiClient->instance(%p); return bless \%p, $class; } diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Configuration.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Configuration.pm index 6a4afe254e0b..916700035182 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Configuration.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Configuration.pm @@ -10,7 +10,6 @@ use Carp; use constant VERSION => '1.0.0'; # class/static variables -our $api_client; our $http_timeout = 180; our $http_user_agent = 'Perl-Swagger'; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm index 0404c9c74bed..813e73468a25 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm @@ -38,9 +38,8 @@ __PACKAGE__->mk_classdata('class_documentation' => {}); # TODO sub new { my $class = shift; - my $default_api_client = $WWW::SwaggerClient::Configuration::api_client ? $WWW::SwaggerClient::Configuration::api_client : WWW::SwaggerClient::ApiClient->new; my (%self) = ( - 'api_client' => $default_api_client, + 'api_client' => WWW::SwaggerClient::ApiClient->instance, @_ ); diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm index d8cd0cbff7dd..533c2e77a267 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm @@ -38,9 +38,8 @@ __PACKAGE__->mk_classdata('class_documentation' => {}); # TODO sub new { my $class = shift; - my $default_api_client = $WWW::SwaggerClient::Configuration::api_client ? $WWW::SwaggerClient::Configuration::api_client : WWW::SwaggerClient::ApiClient->new; my (%self) = ( - 'api_client' => $default_api_client, + 'api_client' => WWW::SwaggerClient::ApiClient->instance, @_ ); diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm index 18d69ed5883d..5d1f7f33f1b6 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm @@ -38,9 +38,8 @@ __PACKAGE__->mk_classdata('class_documentation' => {}); # TODO sub new { my $class = shift; - my $default_api_client = $WWW::SwaggerClient::Configuration::api_client ? $WWW::SwaggerClient::Configuration::api_client : WWW::SwaggerClient::ApiClient->new; my (%self) = ( - 'api_client' => $default_api_client, + 'api_client' => WWW::SwaggerClient::ApiClient->instance, @_ ); diff --git a/samples/client/petstore/perl/t/01_pet_api.t b/samples/client/petstore/perl/t/01_pet_api.t index 5460c3282b26..c7bcdf98a0aa 100644 --- a/samples/client/petstore/perl/t/01_pet_api.t +++ b/samples/client/petstore/perl/t/01_pet_api.t @@ -1,4 +1,4 @@ -use Test::More tests => 37; +use Test::More tests => 38; use Test::Exception; use lib 'lib'; @@ -11,12 +11,18 @@ use_ok('WWW::SwaggerClient::Object::Pet'); use_ok('WWW::SwaggerClient::Object::Tag'); use_ok('WWW::SwaggerClient::Object::Category'); -my $api_client = WWW::SwaggerClient::ApiClient->new('base_url' => 'http://testing'); +my $api_client = WWW::SwaggerClient::ApiClient->instance('base_url' => 'http://testing'); my $pet_api = WWW::SwaggerClient::PetApi->new('api_client' => $api_client); is $pet_api->{api_client}->{base_url}, 'http://testing', 'get the proper base URL from api client'; my $api = WWW::SwaggerClient::PetApi->new(); +is $api->{api_client}->{base_url}, 'http://testing', 'we still get the original base URL from api client, because it\'s a singleton'; + +# reset the base_url - no direct access because an application shouldn't be changing +# its base URL halfway through +$api->{api_client}->{base_url} = 'http://petstore.swagger.io/v2'; + is $api->{api_client}->{base_url}, 'http://petstore.swagger.io/v2', 'get the default base URL from api client'; # test select_header_content_type diff --git a/samples/client/petstore/perl/t/02_store_api.t b/samples/client/petstore/perl/t/02_store_api.t index dfee5c468398..39b18381b0e7 100644 --- a/samples/client/petstore/perl/t/02_store_api.t +++ b/samples/client/petstore/perl/t/02_store_api.t @@ -15,7 +15,7 @@ use_ok('WWW::SwaggerClient::Object::Category'); use_ok('WWW::SwaggerClient::Object::User'); -my $api_client = WWW::SwaggerClient::ApiClient->new(); +my $api_client = WWW::SwaggerClient::ApiClient->instance(); my $store_api = WWW::SwaggerClient::StoreApi->new('api_client' => $api_client); is $store_api->{api_client}->{base_url}, 'http://petstore.swagger.io/v2', 'get the default base URL from api client'; diff --git a/samples/client/petstore/perl/t/03_api_factory.t b/samples/client/petstore/perl/t/03_api_factory.t index 2e6ee6317f92..a06805e2bcfe 100644 --- a/samples/client/petstore/perl/t/03_api_factory.t +++ b/samples/client/petstore/perl/t/03_api_factory.t @@ -15,6 +15,9 @@ is $pet_api->{api_client}->{base_url}, 'http://testing', 'get the proper base UR $api_factory = WWW::SwaggerClient::ApiFactory->new; $pet_api = $api_factory->get_api('Pet'); +# reset the base_url - no direct access because an application shouldn't be changing +# its base URL halfway through +$pet_api->{api_client}->{base_url} = 'http://petstore.swagger.io/v2'; is $pet_api->{api_client}->{base_url}, 'http://petstore.swagger.io/v2', 'get the default base URL from api client'; # test accessor methods From 77b9f51927c86cc6f97d17ea5ec266e6901cf584 Mon Sep 17 00:00:00 2001 From: Dave Baird Date: Tue, 10 Nov 2015 14:22:32 +0100 Subject: [PATCH 06/14] More documentation, and clean up a couple of ragged edges - added documentation for configuring authentication - made auth_setup_handler() optional - get_api_key_with_prefix() is more self-documenting --- .../main/resources/perl/ApiClient.mustache | 18 ++-- .../main/resources/perl/ApiFactory.mustache | 3 + .../src/main/resources/perl/README.md | 89 +++++++++++++---- .../src/main/resources/perl/Role.mustache | 99 ++++++++++++++----- samples/client/petstore/perl/README.md | 89 +++++++++++++---- .../perl/lib/WWW/SwaggerClient/ApiClient.pm | 18 ++-- .../perl/lib/WWW/SwaggerClient/ApiFactory.pm | 3 + .../perl/lib/WWW/SwaggerClient/Role.pm | 99 ++++++++++++++----- 8 files changed, 312 insertions(+), 106 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache index ae8dce3d3515..6e88d7967c24 100644 --- a/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache @@ -290,13 +290,15 @@ sub select_header_content_type # @return string API key with the prefix sub get_api_key_with_prefix { - my ($self, $api_key) = @_; - if ($WWW::{{moduleName}}::Configuration::api_key_prefix->{$api_key}) { - return $WWW::{{moduleName}}::Configuration::api_key_prefix->{$api_key}." ".$WWW::{{moduleName}}::Configuration::api_key->{$api_key}; - } else { - return $WWW::{{moduleName}}::Configuration::api_key->{$api_key}; - } -} + my ($self, $key_name) = @_; + + my $api_key = $WWW::{{moduleName}}::Configuration::api_key->{$key_name}; + + return unless $api_key; + + my $prefix = $WWW::{{moduleName}}::Configuration::api_key_prefix->{$key_name}; + return $prefix ? "$prefix $api_key" : $api_key; +} # update header and query param based on authentication setting # @@ -306,7 +308,7 @@ sub get_api_key_with_prefix sub update_params_for_auth { my ($self, $header_params, $query_params, $auth_settings) = @_; - # we can defer to the application + # we can defer to the application if the spec doesn't describe authentication if ($self->{auth_setup_handler_object}) { $self->{auth_setup_handler_object}->auth_setup_handler( api_client => $self, diff --git a/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache b/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache index cb619091ca30..c38028fb37a6 100644 --- a/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache @@ -61,6 +61,9 @@ my %_apis = map { $_ =~ /^WWW::{{moduleName}}::(.*)$/; $1 => $_ } The method should implement the required auth policy, for example, by setting secret keys in the header, or username and password in the URL, etc. + This is only necessary when the API specification itself does not describe + authentication. + =cut sub new { diff --git a/modules/swagger-codegen/src/main/resources/perl/README.md b/modules/swagger-codegen/src/main/resources/perl/README.md index 3cc2fda6528f..16df3de62178 100644 --- a/modules/swagger-codegen/src/main/resources/perl/README.md +++ b/modules/swagger-codegen/src/main/resources/perl/README.md @@ -19,21 +19,15 @@ role. package MyApp; use Moose; - has [qw(username password)] => ( is => 'ro', required => 1, isa => 'Str' ); with 'WWW::{{moduleName}}::Role'; - sub auth_setup_handler {...} package main; - my $api = MyApp->new({username => $username, password => $password}); + my $api = MyApp->new; my $pet = $api->get_pet_by_id(pet_id => $pet_id); -Notice that you need to provide the code to accept the parameters passed in to `new()` -(by setting up attributes via the `has` keyword). They should be used by -`auth_setup_handler()` to configure authentication (see below). - ## Structure of the library The library consists of a set of API classes, one for each endpoint. These APIs @@ -50,14 +44,74 @@ factory object, should you need it. For documentation of all these methods, see AUTOMATIC DOCUMENTATION below. +## Configuring authentication + +If your Swagger spec does not describe authentication, you can write an +`auth_setup_handler()` method in your base class to handle it (see below). + +In the normal case, the Swagger spec will describe what parameters are required +and where to put them. You just need to supply the authorization tokens. + +These should go in the `WWW::{{moduleName}}::Configuration` namespace as follows. +Note these are all optional, and depend on the API you are accessing. + +- `$WWW::{{moduleName}}::Configuration::username` + + String. The username for basic auth. + +- `$WWW::{{moduleName}}::Configuration::password` + + String. The password for basic auth. + +- `$WWW::{{moduleName}}::Configuration::api_key` + + Hashref. Keyed on the name of each key (there can be multiple tokens). + + $WWW::{{moduleName}}::Configuration::api_key = { + secretKey => 'aaaabbbbccccdddd', + anotherKey => '1111222233334444', + }; + +- `$WWW::{{moduleName}}::Configuration::api_key_prefix` + + Hashref. Keyed on the name of each key (there can be multiple tokens). Note not + all api keys require a prefix. + + $WWW::{{moduleName}}::Configuration::api_key_prefix = { + secretKey => 'string', + anotherKey => 'same or some other string', + }; + +- `$WWW::{{moduleName}}::Configuration::access_token` + + String. The OAuth access token. + # METHODS ## `auth_setup_handler()` -This method is NOT provided - you must write it yourself. Its task is to configure -authentication for each request. +This method does not exist! But if you add it to the class that consumes this +role, it will be called to set up authentication. -The method is called on your `$api` object and passed the following parameters: + package MyApp; + use Moose; + + with 'WWW::{{moduleName}}::Role'; + + sub auth_setup_handler { + my ($self, %p) = @_; + $p{header_params}->{'X-TargetApp-apiKey'} = $api_key; + $p{header_params}->{'X-TargetApp-secretKey'} = $secret_key; + } + + # somewhere else... + + my $api = MyApp->new; + + my $pet = $api->get_pet_by_id(pet_id => $pet_id); + +So, `auth_setup_handler()` will be called on your `$api` object and passed the +following parameters: - `header_params` @@ -71,25 +125,18 @@ The method is called on your `$api` object and passed the following parameters: - `auth_settings` - TODO. + TODO. Probably not necessary? - `api_client` A reference to the `WWW::{{moduleName}}::ApiClient` object that is responsible - for communicating with the server. - -For example: - - sub auth_setup_handler { - my ($self, %p) = @_; - $p{header_params}->{'X-TargetApp-apiKey'} = $api_key; - $p{header_params}->{'X-TargetApp-secretKey'} = $secret_key; - } + for communicating with the server. Just in case that's useful. ## base\_url The generated code has the `base_url` already set as a default value. This method -returns (and optionally sets) the current value of `base_url`. +returns (and optionally sets, but only if the API client has not been +created yet) the current value of `base_url`. ## api\_factory diff --git a/modules/swagger-codegen/src/main/resources/perl/Role.mustache b/modules/swagger-codegen/src/main/resources/perl/Role.mustache index 951f05bab745..4ece1bd092ea 100644 --- a/modules/swagger-codegen/src/main/resources/perl/Role.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/Role.mustache @@ -7,8 +7,6 @@ use Class::Inspector; use Log::Any qw($log); use WWW::{{moduleName}}::ApiFactory; -requires 'auth_setup_handler'; - has base_url => ( is => 'ro', required => 0, isa => 'Str', @@ -64,7 +62,8 @@ sub BUILD { sub _build_af { my $self = shift; - my %args = ( auth_setup_handler_object => $self ); + my %args; + $args{auth_setup_handler_object} = $self if $self->can('auth_setup_handler'); $args{base_url} = $self->base_url if $self->base_url; return WWW::{{moduleName}}::ApiFactory->new(%args); } @@ -90,20 +89,14 @@ role. package MyApp; use Moose; - has [qw(username password)] => ( is => 'ro', required => 1, isa => 'Str' ); with 'WWW::{{moduleName}}::Role'; - sub auth_setup_handler {...} package main; - my $api = MyApp->new({username => $username, password => $password}); + my $api = MyApp->new; my $pet = $api->get_pet_by_id(pet_id => $pet_id); -Notice that you need to provide the code to accept the parameters passed in to C -(by setting up attributes via the C keyword). They should be used by -C to configure authentication (see below). - =head2 Structure of the library The library consists of a set of API classes, one for each endpoint. These APIs @@ -120,14 +113,79 @@ factory object, should you need it. For documentation of all these methods, see AUTOMATIC DOCUMENTATION below. +=head2 Configuring authentication + +If your Swagger spec does not describe authentication, you can write an +C method in your base class to handle it (see below). + +In the normal case, the Swagger spec will describe what parameters are required +and where to put them. You just need to supply the authorization tokens. + +These should go in the C namespace as follows. +Note these are all optional, and depend on the API you are accessing. + +=over 4 + +=item C<$WWW::{{moduleName}}::Configuration::username> + +String. The username for basic auth. + +=item C<$WWW::{{moduleName}}::Configuration::password> + +String. The password for basic auth. + +=item C<$WWW::{{moduleName}}::Configuration::api_key> + +Hashref. Keyed on the name of each key (there can be multiple tokens). + + $WWW::{{moduleName}}::Configuration::api_key = { + secretKey => 'aaaabbbbccccdddd', + anotherKey => '1111222233334444', + }; + +=item C<$WWW::{{moduleName}}::Configuration::api_key_prefix> + +Hashref. Keyed on the name of each key (there can be multiple tokens). Note not +all api keys require a prefix. + + $WWW::{{moduleName}}::Configuration::api_key_prefix = { + secretKey => 'string', + anotherKey => 'same or some other string', + }; + +=item C<$WWW::{{moduleName}}::Configuration::access_token> + +String. The OAuth access token. + +=back + =head1 METHODS =head2 C -This method is NOT provided - you must write it yourself. Its task is to configure -authentication for each request. +This method does not exist! But if you add it to the class that consumes this +role, it will be called to set up authentication. -The method is called on your C<$api> object and passed the following parameters: + package MyApp; + use Moose; + + with 'WWW::{{moduleName}}::Role'; + + sub auth_setup_handler { + my ($self, %p) = @_; + $p{header_params}->{'X-TargetApp-apiKey'} = $api_key; + $p{header_params}->{'X-TargetApp-secretKey'} = $secret_key; + } + + # somewhere else... + + my $api = MyApp->new; + + my $pet = $api->get_pet_by_id(pet_id => $pet_id); + + +So, C will be called on your C<$api> object and passed the +following parameters: =over 4 @@ -143,27 +201,20 @@ parameters. =item C -TODO. +TODO. Probably not necessary? =item C A reference to the C object that is responsible -for communicating with the server. +for communicating with the server. Just in case that's useful. =back -For example: - - sub auth_setup_handler { - my ($self, %p) = @_; - $p{header_params}->{'X-TargetApp-apiKey'} = $api_key; - $p{header_params}->{'X-TargetApp-secretKey'} = $secret_key; - } - =head2 base_url The generated code has the C already set as a default value. This method -returns (and optionally sets) the current value of C. +returns (and optionally sets, but only if the API client has not been +created yet) the current value of C. =head2 api_factory diff --git a/samples/client/petstore/perl/README.md b/samples/client/petstore/perl/README.md index a04d5a0aad6f..1e0091fcc6bf 100644 --- a/samples/client/petstore/perl/README.md +++ b/samples/client/petstore/perl/README.md @@ -19,21 +19,15 @@ role. package MyApp; use Moose; - has [qw(username password)] => ( is => 'ro', required => 1, isa => 'Str' ); with 'WWW::SwaggerClient::Role'; - sub auth_setup_handler {...} package main; - my $api = MyApp->new({username => $username, password => $password}); + my $api = MyApp->new; my $pet = $api->get_pet_by_id(pet_id => $pet_id); -Notice that you need to provide the code to accept the parameters passed in to `new()` -(by setting up attributes via the `has` keyword). They should be used by -`auth_setup_handler()` to configure authentication (see below). - ## Structure of the library The library consists of a set of API classes, one for each endpoint. These APIs @@ -50,14 +44,74 @@ factory object, should you need it. For documentation of all these methods, see AUTOMATIC DOCUMENTATION below. +## Configuring authentication + +If your Swagger spec does not describe authentication, you can write an +`auth_setup_handler()` method in your base class to handle it (see below). + +In the normal case, the Swagger spec will describe what parameters are required +and where to put them. You just need to supply the authorization tokens. + +These should go in the `WWW::SwaggerClient::Configuration` namespace as follows. +Note these are all optional, and depend on the API you are accessing. + +- `$WWW::SwaggerClient::Configuration::username` + + String. The username for basic auth. + +- `$WWW::SwaggerClient::Configuration::password` + + String. The password for basic auth. + +- `$WWW::SwaggerClient::Configuration::api_key` + + Hashref. Keyed on the name of each key (there can be multiple tokens). + + $WWW::SwaggerClient::Configuration::api_key = { + secretKey => 'aaaabbbbccccdddd', + anotherKey => '1111222233334444', + }; + +- `$WWW::SwaggerClient::Configuration::api_key_prefix` + + Hashref. Keyed on the name of each key (there can be multiple tokens). Note not + all api keys require a prefix. + + $WWW::SwaggerClient::Configuration::api_key_prefix = { + secretKey => 'string', + anotherKey => 'same or some other string', + }; + +- `$WWW::SwaggerClient::Configuration::access_token` + + String. The OAuth access token. + # METHODS ## `auth_setup_handler()` -This method is NOT provided - you must write it yourself. Its task is to configure -authentication for each request. +This method does not exist! But if you add it to the class that consumes this +role, it will be called to set up authentication. -The method is called on your `$api` object and passed the following parameters: + package MyApp; + use Moose; + + with 'WWW::SwaggerClient::Role'; + + sub auth_setup_handler { + my ($self, %p) = @_; + $p{header_params}->{'X-TargetApp-apiKey'} = $api_key; + $p{header_params}->{'X-TargetApp-secretKey'} = $secret_key; + } + + # somewhere else... + + my $api = MyApp->new; + + my $pet = $api->get_pet_by_id(pet_id => $pet_id); + +So, `auth_setup_handler()` will be called on your `$api` object and passed the +following parameters: - `header_params` @@ -71,25 +125,18 @@ The method is called on your `$api` object and passed the following parameters: - `auth_settings` - TODO. + TODO. Probably not necessary? - `api_client` A reference to the `WWW::SwaggerClient::ApiClient` object that is responsible - for communicating with the server. - -For example: - - sub auth_setup_handler { - my ($self, %p) = @_; - $p{header_params}->{'X-TargetApp-apiKey'} = $api_key; - $p{header_params}->{'X-TargetApp-secretKey'} = $secret_key; - } + for communicating with the server. Just in case that's useful. ## base\_url The generated code has the `base_url` already set as a default value. This method -returns (and optionally sets) the current value of `base_url`. +returns (and optionally sets, but only if the API client has not been +created yet) the current value of `base_url`. ## api\_factory diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm index d3568c812e4e..e34fffe78481 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm @@ -290,13 +290,15 @@ sub select_header_content_type # @return string API key with the prefix sub get_api_key_with_prefix { - my ($self, $api_key) = @_; - if ($WWW::SwaggerClient::Configuration::api_key_prefix->{$api_key}) { - return $WWW::SwaggerClient::Configuration::api_key_prefix->{$api_key}." ".$WWW::SwaggerClient::Configuration::api_key->{$api_key}; - } else { - return $WWW::SwaggerClient::Configuration::api_key->{$api_key}; - } -} + my ($self, $key_name) = @_; + + my $api_key = $WWW::SwaggerClient::Configuration::api_key->{$key_name}; + + return unless $api_key; + + my $prefix = $WWW::SwaggerClient::Configuration::api_key_prefix->{$key_name}; + return $prefix ? "$prefix $api_key" : $api_key; +} # update header and query param based on authentication setting # @@ -306,7 +308,7 @@ sub get_api_key_with_prefix sub update_params_for_auth { my ($self, $header_params, $query_params, $auth_settings) = @_; - # we can defer to the application + # we can defer to the application if the spec doesn't describe authentication if ($self->{auth_setup_handler_object}) { $self->{auth_setup_handler_object}->auth_setup_handler( api_client => $self, diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm index 77c23fdb2b36..b428e503b9ec 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm @@ -61,6 +61,9 @@ my %_apis = map { $_ =~ /^WWW::SwaggerClient::(.*)$/; $1 => $_ } The method should implement the required auth policy, for example, by setting secret keys in the header, or username and password in the URL, etc. + This is only necessary when the API specification itself does not describe + authentication. + =cut sub new { diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm index 2b8969b3e3f3..b66a6bd2e273 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm @@ -7,8 +7,6 @@ use Class::Inspector; use Log::Any qw($log); use WWW::SwaggerClient::ApiFactory; -requires 'auth_setup_handler'; - has base_url => ( is => 'ro', required => 0, isa => 'Str', @@ -64,7 +62,8 @@ sub BUILD { sub _build_af { my $self = shift; - my %args = ( auth_setup_handler_object => $self ); + my %args; + $args{auth_setup_handler_object} = $self if $self->can('auth_setup_handler'); $args{base_url} = $self->base_url if $self->base_url; return WWW::SwaggerClient::ApiFactory->new(%args); } @@ -90,20 +89,14 @@ role. package MyApp; use Moose; - has [qw(username password)] => ( is => 'ro', required => 1, isa => 'Str' ); with 'WWW::SwaggerClient::Role'; - sub auth_setup_handler {...} package main; - my $api = MyApp->new({username => $username, password => $password}); + my $api = MyApp->new; my $pet = $api->get_pet_by_id(pet_id => $pet_id); -Notice that you need to provide the code to accept the parameters passed in to C -(by setting up attributes via the C keyword). They should be used by -C to configure authentication (see below). - =head2 Structure of the library The library consists of a set of API classes, one for each endpoint. These APIs @@ -120,14 +113,79 @@ factory object, should you need it. For documentation of all these methods, see AUTOMATIC DOCUMENTATION below. +=head2 Configuring authentication + +If your Swagger spec does not describe authentication, you can write an +C method in your base class to handle it (see below). + +In the normal case, the Swagger spec will describe what parameters are required +and where to put them. You just need to supply the authorization tokens. + +These should go in the C namespace as follows. +Note these are all optional, and depend on the API you are accessing. + +=over 4 + +=item C<$WWW::SwaggerClient::Configuration::username> + +String. The username for basic auth. + +=item C<$WWW::SwaggerClient::Configuration::password> + +String. The password for basic auth. + +=item C<$WWW::SwaggerClient::Configuration::api_key> + +Hashref. Keyed on the name of each key (there can be multiple tokens). + + $WWW::SwaggerClient::Configuration::api_key = { + secretKey => 'aaaabbbbccccdddd', + anotherKey => '1111222233334444', + }; + +=item C<$WWW::SwaggerClient::Configuration::api_key_prefix> + +Hashref. Keyed on the name of each key (there can be multiple tokens). Note not +all api keys require a prefix. + + $WWW::SwaggerClient::Configuration::api_key_prefix = { + secretKey => 'string', + anotherKey => 'same or some other string', + }; + +=item C<$WWW::SwaggerClient::Configuration::access_token> + +String. The OAuth access token. + +=back + =head1 METHODS =head2 C -This method is NOT provided - you must write it yourself. Its task is to configure -authentication for each request. +This method does not exist! But if you add it to the class that consumes this +role, it will be called to set up authentication. -The method is called on your C<$api> object and passed the following parameters: + package MyApp; + use Moose; + + with 'WWW::SwaggerClient::Role'; + + sub auth_setup_handler { + my ($self, %p) = @_; + $p{header_params}->{'X-TargetApp-apiKey'} = $api_key; + $p{header_params}->{'X-TargetApp-secretKey'} = $secret_key; + } + + # somewhere else... + + my $api = MyApp->new; + + my $pet = $api->get_pet_by_id(pet_id => $pet_id); + + +So, C will be called on your C<$api> object and passed the +following parameters: =over 4 @@ -143,27 +201,20 @@ parameters. =item C -TODO. +TODO. Probably not necessary? =item C A reference to the C object that is responsible -for communicating with the server. +for communicating with the server. Just in case that's useful. =back -For example: - - sub auth_setup_handler { - my ($self, %p) = @_; - $p{header_params}->{'X-TargetApp-apiKey'} = $api_key; - $p{header_params}->{'X-TargetApp-secretKey'} = $secret_key; - } - =head2 base_url The generated code has the C already set as a default value. This method -returns (and optionally sets) the current value of C. +returns (and optionally sets, but only if the API client has not been +created yet) the current value of C. =head2 api_factory From 06db67210cd527612d4b80c2ccde92e05e9ac09d Mon Sep 17 00:00:00 2001 From: Dave Baird Date: Tue, 10 Nov 2015 14:50:22 +0100 Subject: [PATCH 07/14] Tiny doc tweak --- .../src/main/resources/perl/README.md | 15 ++++++++------- .../src/main/resources/perl/Role.mustache | 15 ++++++++------- samples/client/petstore/perl/README.md | 15 ++++++++------- .../petstore/perl/lib/WWW/SwaggerClient/Role.pm | 15 ++++++++------- 4 files changed, 32 insertions(+), 28 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/perl/README.md b/modules/swagger-codegen/src/main/resources/perl/README.md index 16df3de62178..7603c39f07af 100644 --- a/modules/swagger-codegen/src/main/resources/perl/README.md +++ b/modules/swagger-codegen/src/main/resources/perl/README.md @@ -148,10 +148,10 @@ Returns an API factory object. You probably won't need to call this directly. # MISSING METHODS -Most of the methods on the API are delegated to individual sub-API objects (e.g. -Pet API, Store API, User API etc). Where different sub-APIs use the same method -name (e.g. `new()`), these methods can't be delegated. So you need to call -`$api->pet_api->new()`. +Most of the methods on the API are delegated to individual endpoint API objects +(e.g. Pet API, Store API, User API etc). Where different endpoint APIs use the +same method name (e.g. `new()`), these methods can't be delegated. So you need +to call `$api->pet_api->new()`. In principle, every API is susceptible to the presence of a few, random, undelegatable method names. In practice, because of the way method names are constructed, it's @@ -161,9 +161,10 @@ unlikely in general that any methods will be undelegatable, except for: class_documentation() method_documentation() -To call these methods, you need to get a handle on the relevant object, either -by calling `$api->foo_api` or by retrieving an object, e.g. -`$api->get_pet_by_id(pet_id => $pet_id)`. +To call these methods, you need to get a handle on the relevant object, either +by calling `$api->foo_api` or by retrieving an object, e.g. +`$api->get_pet_by_id(pet_id => $pet_id)`. They are class methods, so +you could also call them on class names. # BUILDING YOUR LIBRARY diff --git a/modules/swagger-codegen/src/main/resources/perl/Role.mustache b/modules/swagger-codegen/src/main/resources/perl/Role.mustache index 4ece1bd092ea..41a6de7ff369 100644 --- a/modules/swagger-codegen/src/main/resources/perl/Role.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/Role.mustache @@ -226,10 +226,10 @@ Returns an API factory object. You probably won't need to call this directly. =head1 MISSING METHODS -Most of the methods on the API are delegated to individual sub-API objects (e.g. -Pet API, Store API, User API etc). Where different sub-APIs use the same method -name (e.g. C), these methods can't be delegated. So you need to call -C<$api-Epet_api-Enew()>. +Most of the methods on the API are delegated to individual endpoint API objects +(e.g. Pet API, Store API, User API etc). Where different endpoint APIs use the +same method name (e.g. C), these methods can't be delegated. So you need +to call C<$api-Epet_api-Enew()>. In principle, every API is susceptible to the presence of a few, random, undelegatable method names. In practice, because of the way method names are constructed, it's @@ -239,9 +239,10 @@ unlikely in general that any methods will be undelegatable, except for: class_documentation() method_documentation() -To call these methods, you need to get a handle on the relevant object, either -by calling C<$api-Efoo_api> or by retrieving an object, e.g. -C<$api-Eget_pet_by_id(pet_id =E $pet_id)>. +To call these methods, you need to get a handle on the relevant object, either +by calling C<$api-Efoo_api> or by retrieving an object, e.g. +C<$api-Eget_pet_by_id(pet_id =E $pet_id)>. They are class methods, so +you could also call them on class names. =head1 BUILDING YOUR LIBRARY diff --git a/samples/client/petstore/perl/README.md b/samples/client/petstore/perl/README.md index 1e0091fcc6bf..d436e81c292d 100644 --- a/samples/client/petstore/perl/README.md +++ b/samples/client/petstore/perl/README.md @@ -148,10 +148,10 @@ Returns an API factory object. You probably won't need to call this directly. # MISSING METHODS -Most of the methods on the API are delegated to individual sub-API objects (e.g. -Pet API, Store API, User API etc). Where different sub-APIs use the same method -name (e.g. `new()`), these methods can't be delegated. So you need to call -`$api->pet_api->new()`. +Most of the methods on the API are delegated to individual endpoint API objects +(e.g. Pet API, Store API, User API etc). Where different endpoint APIs use the +same method name (e.g. `new()`), these methods can't be delegated. So you need +to call `$api->pet_api->new()`. In principle, every API is susceptible to the presence of a few, random, undelegatable method names. In practice, because of the way method names are constructed, it's @@ -161,9 +161,10 @@ unlikely in general that any methods will be undelegatable, except for: class_documentation() method_documentation() -To call these methods, you need to get a handle on the relevant object, either -by calling `$api->foo_api` or by retrieving an object, e.g. -`$api->get_pet_by_id(pet_id => $pet_id)`. +To call these methods, you need to get a handle on the relevant object, either +by calling `$api->foo_api` or by retrieving an object, e.g. +`$api->get_pet_by_id(pet_id => $pet_id)`. They are class methods, so +you could also call them on class names. # BUILDING YOUR LIBRARY diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm index b66a6bd2e273..51d477f9954d 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm @@ -226,10 +226,10 @@ Returns an API factory object. You probably won't need to call this directly. =head1 MISSING METHODS -Most of the methods on the API are delegated to individual sub-API objects (e.g. -Pet API, Store API, User API etc). Where different sub-APIs use the same method -name (e.g. C), these methods can't be delegated. So you need to call -C<$api-Epet_api-Enew()>. +Most of the methods on the API are delegated to individual endpoint API objects +(e.g. Pet API, Store API, User API etc). Where different endpoint APIs use the +same method name (e.g. C), these methods can't be delegated. So you need +to call C<$api-Epet_api-Enew()>. In principle, every API is susceptible to the presence of a few, random, undelegatable method names. In practice, because of the way method names are constructed, it's @@ -239,9 +239,10 @@ unlikely in general that any methods will be undelegatable, except for: class_documentation() method_documentation() -To call these methods, you need to get a handle on the relevant object, either -by calling C<$api-Efoo_api> or by retrieving an object, e.g. -C<$api-Eget_pet_by_id(pet_id =E $pet_id)>. +To call these methods, you need to get a handle on the relevant object, either +by calling C<$api-Efoo_api> or by retrieving an object, e.g. +C<$api-Eget_pet_by_id(pet_id =E $pet_id)>. They are class methods, so +you could also call them on class names. =head1 BUILDING YOUR LIBRARY From 2144cf5d3119b1f0a94903b4f0c6808ab7de1f0e Mon Sep 17 00:00:00 2001 From: Dave Baird Date: Wed, 11 Nov 2015 13:43:40 +0100 Subject: [PATCH 08/14] Handle missing security spec more elegantly - remove the optional auth_setup_handler() callback mechanism - add _global_auth_setup() method on ApiClient to analyse config when security spec not provided - add methods on the Configuration class to abstract getting and setting tokens --- .../main/resources/perl/ApiClient.mustache | 55 ++++++-- .../resources/perl/Configuration.mustache | 53 ++++++++ .../src/main/resources/perl/README.md | 96 ++++++-------- .../src/main/resources/perl/Role.mustache | 120 ++++++++---------- .../src/main/resources/perl/api.mustache | 2 +- samples/client/petstore/perl/README.md | 96 ++++++-------- .../perl/lib/WWW/SwaggerClient/ApiClient.pm | 55 ++++++-- .../lib/WWW/SwaggerClient/Configuration.pm | 53 ++++++++ .../perl/lib/WWW/SwaggerClient/PetApi.pm | 16 +-- .../perl/lib/WWW/SwaggerClient/Role.pm | 120 ++++++++---------- .../perl/lib/WWW/SwaggerClient/StoreApi.pm | 8 +- .../perl/lib/WWW/SwaggerClient/UserApi.pm | 16 +-- samples/client/petstore/perl/t/04_role.t | 64 +++++++++- 13 files changed, 461 insertions(+), 293 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache index 6e88d7967c24..bf1220912d20 100644 --- a/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/ApiClient.mustache @@ -34,6 +34,8 @@ sub _new_instance return bless \%args, $class; } +sub _cfg {'WWW::{{moduleName}}::Configuration'} + # Set the user agent of the API client # # @param string $user_agent The user agent of the API client @@ -308,18 +310,8 @@ sub get_api_key_with_prefix sub update_params_for_auth { my ($self, $header_params, $query_params, $auth_settings) = @_; - # we can defer to the application if the spec doesn't describe authentication - if ($self->{auth_setup_handler_object}) { - $self->{auth_setup_handler_object}->auth_setup_handler( - api_client => $self, - header_params => $header_params, - query_params => $query_params, - auth_settings => $auth_settings, # presumably this won't be defined if we're doing it this way - ); - return; - } - - return if (!defined($auth_settings) || scalar(@$auth_settings) == 0); + return $self->_global_auth_setup($header_params, $query_params) + unless $auth_settings && @$auth_settings; # one endpoint can have more than 1 auth settings foreach my $auth (@$auth_settings) { @@ -332,10 +324,47 @@ sub update_params_for_auth { } {{/authMethods}} else { - # TODO show warning about security definition not found + # TODO show warning about security definition not found } } } +# The endpoint API class has not found any settings for auth. This may be deliberate, +# in which case update_params_for_auth() will be a no-op. But it may also be that the +# swagger spec does not describe the intended authorization. So we check in the config for any +# auth tokens and if we find any, we use them for all endpoints; +sub _global_auth_setup { + my ($self, $header_params, $query_params) = @_; + + my $tokens = $self->_cfg->get_tokens; + return unless keys %$tokens; + + # basic + if (my $uname = delete $tokens->{username}) { + my $pword = delete $tokens->{password}; + $header_params->{'Authorization'} = 'Basic '.encode_base64($uname.":".$pword); + } + + # oauth + if (my $access_token = delete $tokens->{access_token}) { + $header_params->{'Authorization'} = 'Bearer ' . $access_token; + } + + # other keys + foreach my $token_name (keys %$tokens) { + my $in = $tokens->{$token_name}->{in}; + my $token = $self->get_api_key_with_prefix($token_name); + if ($in eq 'head') { + $header_params->{$token_name} = $token; + } + elsif ($in eq 'query') { + $query_params->{$token_name} = $token; + } + else { + die "Don't know where to put token '$token_name' ('$in' is not 'head' or 'query')"; + } + } +} + 1; diff --git a/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache b/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache index d0cc157647f4..75a1ba7f61a6 100644 --- a/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache @@ -16,6 +16,7 @@ our $http_user_agent = 'Perl-Swagger'; # authenticaiton setting our $api_key = {}; our $api_key_prefix = {}; +our $api_key_in = {}; # username and password for HTTP basic authentication our $username = ''; @@ -24,4 +25,56 @@ our $password = ''; # access token for OAuth our $access_token = ''; +sub get_tokens { + my $class = shift; + + my $tokens = {}; + $tokens->{username} = $username if $username; + $tokens->{password} = $password if $password; + $tokens->{access_token} = $access_token if $access_token; + + foreach my $token_name (keys %{ $api_key }) { + $tokens->{$token_name}->{token} = $api_key->{$token_name}; + $tokens->{$token_name}->{prefix} = $api_key_prefix->{$token_name}; + $tokens->{$token_name}->{in} = $api_key_in->{$token_name}; + } + + return $tokens; +} + +sub clear_tokens { + my $class = shift; + my %tokens = %{$class->get_tokens}; # copy + + $username = undef; + $password = undef; + $access_token = undef; + + $api_key = {}; + $api_key_prefix = {}; + $api_key_in = {}; + + return \%tokens; +} + +sub accept_tokens { + my ($class, $tokens) = @_; + + foreach my $known_name (qw(username password access_token)) { + next unless $tokens->{$known_name}; + eval "\$$known_name = delete \$tokens->{\$known_name}"; + die $@ if $@; + } + + foreach my $token_name (keys %$tokens) { + $api_key->{$token_name} = $tokens->{$token_name}->{token}; + if ($tokens->{$token_name}->{prefix}) { + $api_key_prefix->{$token_name} = $tokens->{$token_name}->{prefix}; + } + my $in = $tokens->{$token_name}->{in} || 'head'; + croak "Tokens can only go in 'head' or 'query' (not in '$in')" unless $in =~ /^(?:head|query)$/; + $api_key_in->{$token_name} = $in; + } +} + 1; diff --git a/modules/swagger-codegen/src/main/resources/perl/README.md b/modules/swagger-codegen/src/main/resources/perl/README.md index 7603c39f07af..491892b2f166 100644 --- a/modules/swagger-codegen/src/main/resources/perl/README.md +++ b/modules/swagger-codegen/src/main/resources/perl/README.md @@ -23,7 +23,7 @@ role. package main; - my $api = MyApp->new; + my $api = MyApp->new({ tokens => $tokens }); my $pet = $api->get_pet_by_id(pet_id => $pet_id); @@ -46,14 +46,40 @@ For documentation of all these methods, see AUTOMATIC DOCUMENTATION below. ## Configuring authentication -If your Swagger spec does not describe authentication, you can write an -`auth_setup_handler()` method in your base class to handle it (see below). +In the normal case, the Swagger spec will describe what parameters are +required and where to put them. You just need to supply the tokens. -In the normal case, the Swagger spec will describe what parameters are required -and where to put them. You just need to supply the authorization tokens. + my $tokens = { + # basic + username => $username, + password => $password, + + # oauth + access_token => $oauth_token, + + # keys + $some_key => { token => $token, + prefix => $prefix, + in => $in, # 'head||query', + }, + + $another => { token => $token, + prefix => $prefix, + in => $in, # 'head||query', + }, + ..., + + }; + + my $api = MyApp->new({ tokens => $tokens }); -These should go in the `WWW::{{moduleName}}::Configuration` namespace as follows. -Note these are all optional, and depend on the API you are accessing. +Note these are all optional, as are `prefix` and `in`, and depend on the API +you are accessing. Usually `prefix` and `in` will be determined by the code generator from +the spec and you will not need to set them at run time. If not, `in` will +default to 'head' and `prefix` to the empty string. + +The tokens will be placed in the `WWW::{{moduleName}}::Configuration` namespace +as follows, but you don't need to know about this. - `$WWW::{{moduleName}}::Configuration::username` @@ -88,63 +114,19 @@ Note these are all optional, and depend on the API you are accessing. # METHODS -## `auth_setup_handler()` - -This method does not exist! But if you add it to the class that consumes this -role, it will be called to set up authentication. - - package MyApp; - use Moose; - - with 'WWW::{{moduleName}}::Role'; - - sub auth_setup_handler { - my ($self, %p) = @_; - $p{header_params}->{'X-TargetApp-apiKey'} = $api_key; - $p{header_params}->{'X-TargetApp-secretKey'} = $secret_key; - } - - # somewhere else... - - my $api = MyApp->new; - - my $pet = $api->get_pet_by_id(pet_id => $pet_id); - -So, `auth_setup_handler()` will be called on your `$api` object and passed the -following parameters: - -- `header_params` - - A hashref that will become the request headers. You can insert auth - parameters. - -- `query_params` - - A hashref that will be encoded into the request URL. You can insert auth - parameters. - -- `auth_settings` - - TODO. Probably not necessary? - -- `api_client` - - A reference to the `WWW::{{moduleName}}::ApiClient` object that is responsible - for communicating with the server. Just in case that's useful. - -## base\_url +## `base_url` The generated code has the `base_url` already set as a default value. This method returns (and optionally sets, but only if the API client has not been created yet) the current value of `base_url`. -## api\_factory +## `api_factory` Returns an API factory object. You probably won't need to call this directly. $self->api_factory('Pet'); # returns a WWW::{{moduleName}}::PetApi instance - $self->pet_api; # the same + $self->pet_api; # the same # MISSING METHODS @@ -202,11 +184,11 @@ Additional documentation for each class and method may be provided by the Swagge spec. If so, this is available via the `class_documentation()` and `method_documentation()` methods on each generated API and class: - my $cdoc = $api->pet_api->class_documentation; + my $cdoc = $api->pet_api->class_documentation; my $cmdoc = $api->pet_api->method_documentation->{$method_name}; - my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation; + my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation; my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name}; -Each of these calls returns a hashref with various useful pieces of information. +Each of these calls returns a hashref with various useful pieces of information. diff --git a/modules/swagger-codegen/src/main/resources/perl/Role.mustache b/modules/swagger-codegen/src/main/resources/perl/Role.mustache index 41a6de7ff369..c0891ead4244 100644 --- a/modules/swagger-codegen/src/main/resources/perl/Role.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/Role.mustache @@ -8,19 +8,32 @@ use Log::Any qw($log); use WWW::{{moduleName}}::ApiFactory; has base_url => ( is => 'ro', - required => 0, - isa => 'Str', - ); + required => 0, + isa => 'Str', + ); has api_factory => ( is => 'ro', isa => 'WWW::{{moduleName}}::ApiFactory', builder => '_build_af', lazy => 1, ); + +has tokens => ( is => 'ro', + isa => 'HashRef', + required => 0, + default => sub {{=<% %>=}}{{}}<%={{ }}=%>, # ! + ); + +has _cfg => ( is => 'ro', + isa => 'Str', + default => 'WWW::{{moduleName}}::Configuration', + ); sub BUILD { my $self = shift; + $self->_cfg->accept_tokens( $self->tokens ) if keys %{$self->tokens}; + # ignore these symbols imported into API namespaces my %outsiders = map {$_ => 1} qw( croak ); @@ -93,7 +106,7 @@ role. package main; - my $api = MyApp->new; + my $api = MyApp->new({ tokens => $tokens }); my $pet = $api->get_pet_by_id(pet_id => $pet_id); @@ -115,14 +128,40 @@ For documentation of all these methods, see AUTOMATIC DOCUMENTATION below. =head2 Configuring authentication -If your Swagger spec does not describe authentication, you can write an -C method in your base class to handle it (see below). +In the normal case, the Swagger spec will describe what parameters are +required and where to put them. You just need to supply the tokens. -In the normal case, the Swagger spec will describe what parameters are required -and where to put them. You just need to supply the authorization tokens. + my $tokens = { + # basic + username => $username, + password => $password, + + # oauth + access_token => $oauth_token, + + # keys + $some_key => { token => $token, + prefix => $prefix, + in => $in, # 'head||query', + }, + + $another => { token => $token, + prefix => $prefix, + in => $in, # 'head||query', + }, + ..., + + }; + + my $api = MyApp->new({ tokens => $tokens }); -These should go in the C namespace as follows. -Note these are all optional, and depend on the API you are accessing. +Note these are all optional, as are C and C, and depend on the API +you are accessing. Usually C and C will be determined by the code generator from +the spec and you will not need to set them at run time. If not, C will +default to 'head' and C to the empty string. + +The tokens will be placed in the C namespace +as follows, but you don't need to know about this. =over 4 @@ -161,68 +200,19 @@ String. The OAuth access token. =head1 METHODS -=head2 C - -This method does not exist! But if you add it to the class that consumes this -role, it will be called to set up authentication. - - package MyApp; - use Moose; - - with 'WWW::{{moduleName}}::Role'; - - sub auth_setup_handler { - my ($self, %p) = @_; - $p{header_params}->{'X-TargetApp-apiKey'} = $api_key; - $p{header_params}->{'X-TargetApp-secretKey'} = $secret_key; - } - - # somewhere else... - - my $api = MyApp->new; - - my $pet = $api->get_pet_by_id(pet_id => $pet_id); - - -So, C will be called on your C<$api> object and passed the -following parameters: - -=over 4 - -=item C - -A hashref that will become the request headers. You can insert auth -parameters. - -=item C - -A hashref that will be encoded into the request URL. You can insert auth -parameters. - -=item C - -TODO. Probably not necessary? - -=item C - -A reference to the C object that is responsible -for communicating with the server. Just in case that's useful. - -=back - -=head2 base_url +=head2 C The generated code has the C already set as a default value. This method returns (and optionally sets, but only if the API client has not been created yet) the current value of C. -=head2 api_factory +=head2 C Returns an API factory object. You probably won't need to call this directly. $self->api_factory('Pet'); # returns a WWW::{{moduleName}}::PetApi instance - $self->pet_api; # the same + $self->pet_api; # the same =head1 MISSING METHODS @@ -280,13 +270,13 @@ Additional documentation for each class and method may be provided by the Swagge spec. If so, this is available via the C and C methods on each generated API and class: - my $cdoc = $api->pet_api->class_documentation; + my $cdoc = $api->pet_api->class_documentation; my $cmdoc = $api->pet_api->method_documentation->{$method_name}; - my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation; + my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation; my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name}; -Each of these calls returns a hashref with various useful pieces of information. +Each of these calls returns a hashref with various useful pieces of information. =cut diff --git a/modules/swagger-codegen/src/main/resources/perl/api.mustache b/modules/swagger-codegen/src/main/resources/perl/api.mustache index e31f2f32d6c4..4a48cf2211c0 100644 --- a/modules/swagger-codegen/src/main/resources/perl/api.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/api.mustache @@ -134,7 +134,7 @@ sub {{nickname}} { }{{/bodyParams}} # authentication setting, if any - my $auth_settings = [{{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}]; + my $auth_settings = [qw({{#authMethods}}{{name}} {{/authMethods}})]; # make the API Call {{#returnType}}my $response = $self->{api_client}->call_api($_resource_path, $_method, diff --git a/samples/client/petstore/perl/README.md b/samples/client/petstore/perl/README.md index d436e81c292d..36e3521958ef 100644 --- a/samples/client/petstore/perl/README.md +++ b/samples/client/petstore/perl/README.md @@ -23,7 +23,7 @@ role. package main; - my $api = MyApp->new; + my $api = MyApp->new({ tokens => $tokens }); my $pet = $api->get_pet_by_id(pet_id => $pet_id); @@ -46,14 +46,40 @@ For documentation of all these methods, see AUTOMATIC DOCUMENTATION below. ## Configuring authentication -If your Swagger spec does not describe authentication, you can write an -`auth_setup_handler()` method in your base class to handle it (see below). +In the normal case, the Swagger spec will describe what parameters are +required and where to put them. You just need to supply the tokens. -In the normal case, the Swagger spec will describe what parameters are required -and where to put them. You just need to supply the authorization tokens. + my $tokens = { + # basic + username => $username, + password => $password, + + # oauth + access_token => $oauth_token, + + # keys + $some_key => { token => $token, + prefix => $prefix, + in => $in, # 'head||query', + }, + + $another => { token => $token, + prefix => $prefix, + in => $in, # 'head||query', + }, + ..., + + }; + + my $api = MyApp->new({ tokens => $tokens }); -These should go in the `WWW::SwaggerClient::Configuration` namespace as follows. -Note these are all optional, and depend on the API you are accessing. +Note these are all optional, as are `prefix` and `in`, and depend on the API +you are accessing. Usually `prefix` and `in` will be determined by the code generator from +the spec and you will not need to set them at run time. If not, `in` will +default to 'head' and `prefix` to the empty string. + +The tokens will be placed in the `WWW::SwaggerClient::Configuration` namespace +as follows, but you don't need to know about this. - `$WWW::SwaggerClient::Configuration::username` @@ -88,63 +114,19 @@ Note these are all optional, and depend on the API you are accessing. # METHODS -## `auth_setup_handler()` - -This method does not exist! But if you add it to the class that consumes this -role, it will be called to set up authentication. - - package MyApp; - use Moose; - - with 'WWW::SwaggerClient::Role'; - - sub auth_setup_handler { - my ($self, %p) = @_; - $p{header_params}->{'X-TargetApp-apiKey'} = $api_key; - $p{header_params}->{'X-TargetApp-secretKey'} = $secret_key; - } - - # somewhere else... - - my $api = MyApp->new; - - my $pet = $api->get_pet_by_id(pet_id => $pet_id); - -So, `auth_setup_handler()` will be called on your `$api` object and passed the -following parameters: - -- `header_params` - - A hashref that will become the request headers. You can insert auth - parameters. - -- `query_params` - - A hashref that will be encoded into the request URL. You can insert auth - parameters. - -- `auth_settings` - - TODO. Probably not necessary? - -- `api_client` - - A reference to the `WWW::SwaggerClient::ApiClient` object that is responsible - for communicating with the server. Just in case that's useful. - -## base\_url +## `base_url` The generated code has the `base_url` already set as a default value. This method returns (and optionally sets, but only if the API client has not been created yet) the current value of `base_url`. -## api\_factory +## `api_factory` Returns an API factory object. You probably won't need to call this directly. $self->api_factory('Pet'); # returns a WWW::SwaggerClient::PetApi instance - $self->pet_api; # the same + $self->pet_api; # the same # MISSING METHODS @@ -202,11 +184,11 @@ Additional documentation for each class and method may be provided by the Swagge spec. If so, this is available via the `class_documentation()` and `method_documentation()` methods on each generated API and class: - my $cdoc = $api->pet_api->class_documentation; + my $cdoc = $api->pet_api->class_documentation; my $cmdoc = $api->pet_api->method_documentation->{$method_name}; - my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation; + my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation; my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name}; -Each of these calls returns a hashref with various useful pieces of information. +Each of these calls returns a hashref with various useful pieces of information. diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm index e34fffe78481..dbd822cc1d4a 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiClient.pm @@ -34,6 +34,8 @@ sub _new_instance return bless \%args, $class; } +sub _cfg {'WWW::SwaggerClient::Configuration'} + # Set the user agent of the API client # # @param string $user_agent The user agent of the API client @@ -308,18 +310,8 @@ sub get_api_key_with_prefix sub update_params_for_auth { my ($self, $header_params, $query_params, $auth_settings) = @_; - # we can defer to the application if the spec doesn't describe authentication - if ($self->{auth_setup_handler_object}) { - $self->{auth_setup_handler_object}->auth_setup_handler( - api_client => $self, - header_params => $header_params, - query_params => $query_params, - auth_settings => $auth_settings, # presumably this won't be defined if we're doing it this way - ); - return; - } - - return if (!defined($auth_settings) || scalar(@$auth_settings) == 0); + return $self->_global_auth_setup($header_params, $query_params) + unless $auth_settings && @$auth_settings; # one endpoint can have more than 1 auth settings foreach my $auth (@$auth_settings) { @@ -336,10 +328,47 @@ sub update_params_for_auth { } else { - # TODO show warning about security definition not found + # TODO show warning about security definition not found } } } +# The endpoint API class has not found any settings for auth. This may be deliberate, +# in which case update_params_for_auth() will be a no-op. But it may also be that the +# swagger spec does not describe the intended authorization. So we check in the config for any +# auth tokens and if we find any, we use them for all endpoints; +sub _global_auth_setup { + my ($self, $header_params, $query_params) = @_; + + my $tokens = $self->_cfg->get_tokens; + return unless keys %$tokens; + + # basic + if (my $uname = delete $tokens->{username}) { + my $pword = delete $tokens->{password}; + $header_params->{'Authorization'} = 'Basic '.encode_base64($uname.":".$pword); + } + + # oauth + if (my $access_token = delete $tokens->{access_token}) { + $header_params->{'Authorization'} = 'Bearer ' . $access_token; + } + + # other keys + foreach my $token_name (keys %$tokens) { + my $in = $tokens->{$token_name}->{in}; + my $token = $self->get_api_key_with_prefix($token_name); + if ($in eq 'head') { + $header_params->{$token_name} = $token; + } + elsif ($in eq 'query') { + $query_params->{$token_name} = $token; + } + else { + die "Don't know where to put token '$token_name' ('$in' is not 'head' or 'query')"; + } + } +} + 1; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Configuration.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Configuration.pm index 916700035182..150db4cfac2e 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Configuration.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Configuration.pm @@ -16,6 +16,7 @@ our $http_user_agent = 'Perl-Swagger'; # authenticaiton setting our $api_key = {}; our $api_key_prefix = {}; +our $api_key_in = {}; # username and password for HTTP basic authentication our $username = ''; @@ -24,4 +25,56 @@ our $password = ''; # access token for OAuth our $access_token = ''; +sub get_tokens { + my $class = shift; + + my $tokens = {}; + $tokens->{username} = $username if $username; + $tokens->{password} = $password if $password; + $tokens->{access_token} = $access_token if $access_token; + + foreach my $token_name (keys %{ $api_key }) { + $tokens->{$token_name}->{token} = $api_key->{$token_name}; + $tokens->{$token_name}->{prefix} = $api_key_prefix->{$token_name}; + $tokens->{$token_name}->{in} = $api_key_in->{$token_name}; + } + + return $tokens; +} + +sub clear_tokens { + my $class = shift; + my %tokens = %{$class->get_tokens}; # copy + + $username = undef; + $password = undef; + $access_token = undef; + + $api_key = {}; + $api_key_prefix = {}; + $api_key_in = {}; + + return \%tokens; +} + +sub accept_tokens { + my ($class, $tokens) = @_; + + foreach my $known_name (qw(username password access_token)) { + next unless $tokens->{$known_name}; + eval "\$$known_name = delete \$tokens->{\$known_name}"; + die $@ if $@; + } + + foreach my $token_name (keys %$tokens) { + $api_key->{$token_name} = $tokens->{$token_name}->{token}; + if ($tokens->{$token_name}->{prefix}) { + $api_key_prefix->{$token_name} = $tokens->{$token_name}->{prefix}; + } + my $in = $tokens->{$token_name}->{in} || 'head'; + croak "Tokens can only go in 'head' or 'query' (not in '$in')" unless $in =~ /^(?:head|query)$/; + $api_key_in->{$token_name} = $in; + } +} + 1; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm index 813e73468a25..cbd65a7c003f 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm @@ -106,7 +106,7 @@ sub update_pet { } # authentication setting, if any - my $auth_settings = ['petstore_auth']; + my $auth_settings = [qw(petstore_auth )]; # make the API Call @@ -170,7 +170,7 @@ sub add_pet { } # authentication setting, if any - my $auth_settings = ['petstore_auth']; + my $auth_settings = [qw(petstore_auth )]; # make the API Call @@ -234,7 +234,7 @@ sub find_pets_by_status { # authentication setting, if any - my $auth_settings = ['petstore_auth']; + my $auth_settings = [qw(petstore_auth )]; # make the API Call my $response = $self->{api_client}->call_api($_resource_path, $_method, @@ -301,7 +301,7 @@ sub find_pets_by_tags { # authentication setting, if any - my $auth_settings = ['petstore_auth']; + my $auth_settings = [qw(petstore_auth )]; # make the API Call my $response = $self->{api_client}->call_api($_resource_path, $_method, @@ -375,7 +375,7 @@ sub get_pet_by_id { # authentication setting, if any - my $auth_settings = ['api_key']; + my $auth_settings = [qw(api_key )]; # make the API Call my $response = $self->{api_client}->call_api($_resource_path, $_method, @@ -471,7 +471,7 @@ sub update_pet_with_form { # authentication setting, if any - my $auth_settings = ['petstore_auth']; + my $auth_settings = [qw(petstore_auth )]; # make the API Call @@ -551,7 +551,7 @@ sub delete_pet { # authentication setting, if any - my $auth_settings = ['petstore_auth']; + my $auth_settings = [qw(petstore_auth )]; # make the API Call @@ -645,7 +645,7 @@ sub upload_file { # authentication setting, if any - my $auth_settings = ['petstore_auth']; + my $auth_settings = [qw(petstore_auth )]; # make the API Call diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm index 51d477f9954d..0983f219fdf5 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm @@ -8,19 +8,32 @@ use Log::Any qw($log); use WWW::SwaggerClient::ApiFactory; has base_url => ( is => 'ro', - required => 0, - isa => 'Str', - ); + required => 0, + isa => 'Str', + ); has api_factory => ( is => 'ro', isa => 'WWW::SwaggerClient::ApiFactory', builder => '_build_af', lazy => 1, ); + +has tokens => ( is => 'ro', + isa => 'HashRef', + required => 0, + default => sub {{}}, # ! + ); + +has _cfg => ( is => 'ro', + isa => 'Str', + default => 'WWW::SwaggerClient::Configuration', + ); sub BUILD { my $self = shift; + $self->_cfg->accept_tokens( $self->tokens ) if keys %{$self->tokens}; + # ignore these symbols imported into API namespaces my %outsiders = map {$_ => 1} qw( croak ); @@ -93,7 +106,7 @@ role. package main; - my $api = MyApp->new; + my $api = MyApp->new({ tokens => $tokens }); my $pet = $api->get_pet_by_id(pet_id => $pet_id); @@ -115,14 +128,40 @@ For documentation of all these methods, see AUTOMATIC DOCUMENTATION below. =head2 Configuring authentication -If your Swagger spec does not describe authentication, you can write an -C method in your base class to handle it (see below). +In the normal case, the Swagger spec will describe what parameters are +required and where to put them. You just need to supply the tokens. -In the normal case, the Swagger spec will describe what parameters are required -and where to put them. You just need to supply the authorization tokens. + my $tokens = { + # basic + username => $username, + password => $password, + + # oauth + access_token => $oauth_token, + + # keys + $some_key => { token => $token, + prefix => $prefix, + in => $in, # 'head||query', + }, + + $another => { token => $token, + prefix => $prefix, + in => $in, # 'head||query', + }, + ..., + + }; + + my $api = MyApp->new({ tokens => $tokens }); -These should go in the C namespace as follows. -Note these are all optional, and depend on the API you are accessing. +Note these are all optional, as are C and C, and depend on the API +you are accessing. Usually C and C will be determined by the code generator from +the spec and you will not need to set them at run time. If not, C will +default to 'head' and C to the empty string. + +The tokens will be placed in the C namespace +as follows, but you don't need to know about this. =over 4 @@ -161,68 +200,19 @@ String. The OAuth access token. =head1 METHODS -=head2 C - -This method does not exist! But if you add it to the class that consumes this -role, it will be called to set up authentication. - - package MyApp; - use Moose; - - with 'WWW::SwaggerClient::Role'; - - sub auth_setup_handler { - my ($self, %p) = @_; - $p{header_params}->{'X-TargetApp-apiKey'} = $api_key; - $p{header_params}->{'X-TargetApp-secretKey'} = $secret_key; - } - - # somewhere else... - - my $api = MyApp->new; - - my $pet = $api->get_pet_by_id(pet_id => $pet_id); - - -So, C will be called on your C<$api> object and passed the -following parameters: - -=over 4 - -=item C - -A hashref that will become the request headers. You can insert auth -parameters. - -=item C - -A hashref that will be encoded into the request URL. You can insert auth -parameters. - -=item C - -TODO. Probably not necessary? - -=item C - -A reference to the C object that is responsible -for communicating with the server. Just in case that's useful. - -=back - -=head2 base_url +=head2 C The generated code has the C already set as a default value. This method returns (and optionally sets, but only if the API client has not been created yet) the current value of C. -=head2 api_factory +=head2 C Returns an API factory object. You probably won't need to call this directly. $self->api_factory('Pet'); # returns a WWW::SwaggerClient::PetApi instance - $self->pet_api; # the same + $self->pet_api; # the same =head1 MISSING METHODS @@ -280,13 +270,13 @@ Additional documentation for each class and method may be provided by the Swagge spec. If so, this is available via the C and C methods on each generated API and class: - my $cdoc = $api->pet_api->class_documentation; + my $cdoc = $api->pet_api->class_documentation; my $cmdoc = $api->pet_api->method_documentation->{$method_name}; - my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation; + my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation; my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name}; -Each of these calls returns a hashref with various useful pieces of information. +Each of these calls returns a hashref with various useful pieces of information. =cut diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm index 533c2e77a267..8a1f41036bbb 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm @@ -97,7 +97,7 @@ sub get_inventory { # authentication setting, if any - my $auth_settings = ['api_key']; + my $auth_settings = [qw(api_key )]; # make the API Call my $response = $self->{api_client}->call_api($_resource_path, $_method, @@ -164,7 +164,7 @@ sub place_order { } # authentication setting, if any - my $auth_settings = []; + my $auth_settings = [qw()]; # make the API Call my $response = $self->{api_client}->call_api($_resource_path, $_method, @@ -238,7 +238,7 @@ sub get_order_by_id { # authentication setting, if any - my $auth_settings = []; + my $auth_settings = [qw()]; # make the API Call my $response = $self->{api_client}->call_api($_resource_path, $_method, @@ -312,7 +312,7 @@ sub delete_order { # authentication setting, if any - my $auth_settings = []; + my $auth_settings = [qw()]; # make the API Call diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm index 5d1f7f33f1b6..d8e2c9ae2154 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm @@ -106,7 +106,7 @@ sub create_user { } # authentication setting, if any - my $auth_settings = []; + my $auth_settings = [qw()]; # make the API Call @@ -170,7 +170,7 @@ sub create_users_with_array_input { } # authentication setting, if any - my $auth_settings = []; + my $auth_settings = [qw()]; # make the API Call @@ -234,7 +234,7 @@ sub create_users_with_list_input { } # authentication setting, if any - my $auth_settings = []; + my $auth_settings = [qw()]; # make the API Call @@ -307,7 +307,7 @@ sub login_user { # authentication setting, if any - my $auth_settings = []; + my $auth_settings = [qw()]; # make the API Call my $response = $self->{api_client}->call_api($_resource_path, $_method, @@ -365,7 +365,7 @@ sub logout_user { # authentication setting, if any - my $auth_settings = []; + my $auth_settings = [qw()]; # make the API Call @@ -436,7 +436,7 @@ sub get_user_by_name { # authentication setting, if any - my $auth_settings = []; + my $auth_settings = [qw()]; # make the API Call my $response = $self->{api_client}->call_api($_resource_path, $_method, @@ -519,7 +519,7 @@ sub update_user { } # authentication setting, if any - my $auth_settings = []; + my $auth_settings = [qw()]; # make the API Call @@ -590,7 +590,7 @@ sub delete_user { # authentication setting, if any - my $auth_settings = []; + my $auth_settings = [qw()]; # make the API Call diff --git a/samples/client/petstore/perl/t/04_role.t b/samples/client/petstore/perl/t/04_role.t index 9592ec3f822d..c7104674dbb0 100644 --- a/samples/client/petstore/perl/t/04_role.t +++ b/samples/client/petstore/perl/t/04_role.t @@ -1,4 +1,4 @@ -use Test::More tests => 21; +use Test::More tests => 29; use Test::Exception; use Test::Warnings 'warnings'; use Test::Deep; @@ -15,7 +15,7 @@ SKIP: { sub auth_setup_handler {} "; - skip 'Moose not installed', 21 if $@; + skip 'Moose not installed', 29 if $@; my $api; @@ -76,5 +76,65 @@ my $pet_class_doco = { 'description' => '' }; is_deeply($get_pet->class_documentation, $pet_class_doco, 'Pet object class_documentation is available'); # / documentation tests +my $tokens = { + username => 'UserName', + password => 'PassWord', + access_token => 'OAuth_token', + + someKey => { token => 'some_key_token', + prefix => 'some_key_prefix', + in => 'query', + }, + + anotherKey => { token => 'another_key_token', + }, + }; + +$api->_cfg->accept_tokens({%$tokens}); # pass a copy +no warnings 'once'; +is $WWW::SwaggerClient::Configuration::username, 'UserName', 'accept_tokens() correctly set the username'; +is $WWW::SwaggerClient::Configuration::password, 'PassWord', 'accept_tokens() correctly set the password'; +is $WWW::SwaggerClient::Configuration::access_token, 'OAuth_token', 'accept_tokens() correctly set the oauth'; + +my $api_key_href = { + 'anotherKey' => 'another_key_token', + 'someKey' => 'some_key_token' + }; +cmp_deeply( $WWW::SwaggerClient::Configuration::api_key, $api_key_href, 'accept_tokens() correctly set api_key' ); + +my $api_key_prefix_href = { + 'someKey' => 'some_key_prefix' + }; +cmp_deeply( $WWW::SwaggerClient::Configuration::api_key_prefix, $api_key_prefix_href, 'accept_tokens() correctly set api_key_prefix' ); + +my $api_key_in = { + 'someKey' => 'query', + 'anotherKey' => 'head' + }; +cmp_deeply( $WWW::SwaggerClient::Configuration::api_key_in, $api_key_in, 'accept_tokens() correctly set api_key_in' ); + +use warnings 'once'; + +my $cleared_tokens_cmp = { + 'anotherKey' => { + 'in' => 'head', + 'token' => 'another_key_token', + 'prefix' => undef + }, + 'access_token' => 'OAuth_token', + 'someKey' => { + 'token' => 'some_key_token', + 'in' => 'query', + 'prefix' => 'some_key_prefix' + }, + 'username' => 'UserName', + 'password' => 'PassWord' + }; +cmp_deeply( $api->_cfg->clear_tokens, $cleared_tokens_cmp, 'clear_tokens() returns the correct data structure' ); + +my $bad_token = { bad_token_name => 'bad token value' }; # value should should be hashref +dies_ok { $api->_cfg->accept_tokens($bad_token) } "bad token causes exception"; + + } # / SKIP From 389ce144ef890b12a0138e073c4b63428982c815 Mon Sep 17 00:00:00 2001 From: Dave Baird Date: Thu, 12 Nov 2015 00:36:30 +0100 Subject: [PATCH 09/14] Improved documentation methods - API classes have rudimentary class doc info and useful method doc info - object classes have more detailed method and class info - added more tests for doc methods --- .../src/main/resources/perl/api.mustache | 5 +- .../src/main/resources/perl/object.mustache | 16 ++++- .../lib/WWW/SwaggerClient/Object/Category.pm | 23 ++++++- .../lib/WWW/SwaggerClient/Object/Order.pm | 51 ++++++++++++++- .../perl/lib/WWW/SwaggerClient/Object/Pet.pm | 51 ++++++++++++++- .../perl/lib/WWW/SwaggerClient/Object/Tag.pm | 23 ++++++- .../perl/lib/WWW/SwaggerClient/Object/User.pm | 65 ++++++++++++++++++- .../perl/lib/WWW/SwaggerClient/PetApi.pm | 5 +- .../perl/lib/WWW/SwaggerClient/StoreApi.pm | 5 +- .../perl/lib/WWW/SwaggerClient/UserApi.pm | 5 +- samples/client/petstore/perl/t/04_role.t | 37 ++++++++--- 11 files changed, 268 insertions(+), 18 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/perl/api.mustache b/modules/swagger-codegen/src/main/resources/perl/api.mustache index 4a48cf2211c0..f9312b994b39 100644 --- a/modules/swagger-codegen/src/main/resources/perl/api.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/api.mustache @@ -33,8 +33,11 @@ use WWW::{{moduleName}}::Configuration; use base "Class::Data::Inheritable"; __PACKAGE__->mk_classdata('method_documentation' => {}); -__PACKAGE__->mk_classdata('class_documentation' => {}); # TODO +__PACKAGE__->mk_classdata('class_documentation' => {}); +__PACKAGE__->class_documentation({description => '', # TODO + class => '{{classname}}', +} ); sub new { my $class = shift; diff --git a/modules/swagger-codegen/src/main/resources/perl/object.mustache b/modules/swagger-codegen/src/main/resources/perl/object.mustache index c397569c3962..00c572453c1e 100644 --- a/modules/swagger-codegen/src/main/resources/perl/object.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/object.mustache @@ -21,7 +21,21 @@ use base "WWW::{{moduleName}}::Object::BaseObject"; #NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. # -__PACKAGE__->class_documentation({description => '{{description}}'}); +__PACKAGE__->class_documentation({description => '{{description}}', + class => '{{classname}}', + required => [], # TODO +} ); + +__PACKAGE__->method_documentation({ + {{#vars}}'{{name}}' => { + datatype => '{{datatype}}', + base_name => '{{baseName}}', + description => '{{description}}', + format => '{{format}}', + read_only => '{{readOnly}}', + }, + {{/vars}} +}); __PACKAGE__->swagger_types( { {{#vars}}'{{name}}' => '{{{datatype}}}'{{#hasMore}}, diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Category.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Category.pm index a08ae19ac433..43c12b040c73 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Category.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Category.pm @@ -19,7 +19,28 @@ use base "WWW::SwaggerClient::Object::BaseObject"; #NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. # -__PACKAGE__->class_documentation({description => ''}); +__PACKAGE__->class_documentation({description => '', + class => 'Category', + required => [], # TODO +} ); + +__PACKAGE__->method_documentation({ + 'id' => { + datatype => 'int', + base_name => 'id', + description => '', + format => '', + read_only => '', + }, + 'name' => { + datatype => 'string', + base_name => 'name', + description => '', + format => '', + read_only => '', + }, + +}); __PACKAGE__->swagger_types( { 'id' => 'int', diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Order.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Order.pm index fa411b8e2540..ea5f6160ee5f 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Order.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Order.pm @@ -19,7 +19,56 @@ use base "WWW::SwaggerClient::Object::BaseObject"; #NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. # -__PACKAGE__->class_documentation({description => ''}); +__PACKAGE__->class_documentation({description => '', + class => 'Order', + required => [], # TODO +} ); + +__PACKAGE__->method_documentation({ + 'id' => { + datatype => 'int', + base_name => 'id', + description => '', + format => '', + read_only => '', + }, + 'pet_id' => { + datatype => 'int', + base_name => 'petId', + description => '', + format => '', + read_only => '', + }, + 'quantity' => { + datatype => 'int', + base_name => 'quantity', + description => '', + format => '', + read_only => '', + }, + 'ship_date' => { + datatype => 'DateTime', + base_name => 'shipDate', + description => '', + format => '', + read_only => '', + }, + 'status' => { + datatype => 'string', + base_name => 'status', + description => 'Order Status', + format => '', + read_only => '', + }, + 'complete' => { + datatype => 'boolean', + base_name => 'complete', + description => '', + format => '', + read_only => '', + }, + +}); __PACKAGE__->swagger_types( { 'id' => 'int', diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Pet.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Pet.pm index 58fc85d3f17e..a1aeb1341784 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Pet.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Pet.pm @@ -19,7 +19,56 @@ use base "WWW::SwaggerClient::Object::BaseObject"; #NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. # -__PACKAGE__->class_documentation({description => ''}); +__PACKAGE__->class_documentation({description => '', + class => 'Pet', + required => [], # TODO +} ); + +__PACKAGE__->method_documentation({ + 'id' => { + datatype => 'int', + base_name => 'id', + description => '', + format => '', + read_only => '', + }, + 'category' => { + datatype => 'Category', + base_name => 'category', + description => '', + format => '', + read_only => '', + }, + 'name' => { + datatype => 'string', + base_name => 'name', + description => '', + format => '', + read_only => '', + }, + 'photo_urls' => { + datatype => 'ARRAY[string]', + base_name => 'photoUrls', + description => '', + format => '', + read_only => '', + }, + 'tags' => { + datatype => 'ARRAY[Tag]', + base_name => 'tags', + description => '', + format => '', + read_only => '', + }, + 'status' => { + datatype => 'string', + base_name => 'status', + description => 'pet status in the store', + format => '', + read_only => '', + }, + +}); __PACKAGE__->swagger_types( { 'id' => 'int', diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Tag.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Tag.pm index c3e6ca993bad..a50eded7cde0 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Tag.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/Tag.pm @@ -19,7 +19,28 @@ use base "WWW::SwaggerClient::Object::BaseObject"; #NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. # -__PACKAGE__->class_documentation({description => ''}); +__PACKAGE__->class_documentation({description => '', + class => 'Tag', + required => [], # TODO +} ); + +__PACKAGE__->method_documentation({ + 'id' => { + datatype => 'int', + base_name => 'id', + description => '', + format => '', + read_only => '', + }, + 'name' => { + datatype => 'string', + base_name => 'name', + description => '', + format => '', + read_only => '', + }, + +}); __PACKAGE__->swagger_types( { 'id' => 'int', diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/User.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/User.pm index 1da22e6431bd..cb431b1e059f 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/User.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/User.pm @@ -19,7 +19,70 @@ use base "WWW::SwaggerClient::Object::BaseObject"; #NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. # -__PACKAGE__->class_documentation({description => ''}); +__PACKAGE__->class_documentation({description => '', + class => 'User', + required => [], # TODO +} ); + +__PACKAGE__->method_documentation({ + 'id' => { + datatype => 'int', + base_name => 'id', + description => '', + format => '', + read_only => '', + }, + 'username' => { + datatype => 'string', + base_name => 'username', + description => '', + format => '', + read_only => '', + }, + 'first_name' => { + datatype => 'string', + base_name => 'firstName', + description => '', + format => '', + read_only => '', + }, + 'last_name' => { + datatype => 'string', + base_name => 'lastName', + description => '', + format => '', + read_only => '', + }, + 'email' => { + datatype => 'string', + base_name => 'email', + description => '', + format => '', + read_only => '', + }, + 'password' => { + datatype => 'string', + base_name => 'password', + description => '', + format => '', + read_only => '', + }, + 'phone' => { + datatype => 'string', + base_name => 'phone', + description => '', + format => '', + read_only => '', + }, + 'user_status' => { + datatype => 'int', + base_name => 'userStatus', + description => 'User Status', + format => '', + read_only => '', + }, + +}); __PACKAGE__->swagger_types( { 'id' => 'int', diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm index cbd65a7c003f..7c632f44504a 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm @@ -33,8 +33,11 @@ use WWW::SwaggerClient::Configuration; use base "Class::Data::Inheritable"; __PACKAGE__->mk_classdata('method_documentation' => {}); -__PACKAGE__->mk_classdata('class_documentation' => {}); # TODO +__PACKAGE__->mk_classdata('class_documentation' => {}); +__PACKAGE__->class_documentation({description => '', # TODO + class => 'PetApi', +} ); sub new { my $class = shift; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm index 8a1f41036bbb..70fd83317cb1 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm @@ -33,8 +33,11 @@ use WWW::SwaggerClient::Configuration; use base "Class::Data::Inheritable"; __PACKAGE__->mk_classdata('method_documentation' => {}); -__PACKAGE__->mk_classdata('class_documentation' => {}); # TODO +__PACKAGE__->mk_classdata('class_documentation' => {}); +__PACKAGE__->class_documentation({description => '', # TODO + class => 'StoreApi', +} ); sub new { my $class = shift; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm index d8e2c9ae2154..78a09f061383 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm @@ -33,8 +33,11 @@ use WWW::SwaggerClient::Configuration; use base "Class::Data::Inheritable"; __PACKAGE__->mk_classdata('method_documentation' => {}); -__PACKAGE__->mk_classdata('class_documentation' => {}); # TODO +__PACKAGE__->mk_classdata('class_documentation' => {}); +__PACKAGE__->class_documentation({description => '', # TODO + class => 'UserApi', +} ); sub new { my $class = shift; diff --git a/samples/client/petstore/perl/t/04_role.t b/samples/client/petstore/perl/t/04_role.t index c7104674dbb0..f58e096032a7 100644 --- a/samples/client/petstore/perl/t/04_role.t +++ b/samples/client/petstore/perl/t/04_role.t @@ -1,4 +1,4 @@ -use Test::More tests => 29; +use Test::More tests => 39; use Test::Exception; use Test::Warnings 'warnings'; use Test::Deep; @@ -15,7 +15,7 @@ SKIP: { sub auth_setup_handler {} "; - skip 'Moose not installed', 29 if $@; + skip 'Moose not installed', 39 if $@; my $api; @@ -62,18 +62,39 @@ is $get_pet->tags->[0]->name, 'just kidding', 'stored and retrieved: got the pro is $get_pet->tags->[0]->id, '11', 'stored and retrieved: got the proper tag id'; # documentation tests -TODO: { - local $TODO = "Swagger spec doesn't populate all the description fields"; - is $api->pet_api->class_documentation->{description}, 'Pet API description', 'got corrrect Pet API description'; - is $get_pet->method_documentation->{name}, 'Description of the Pet object name() method', 'Pet object method_documentation is available'; -} +# API class docs +is $api->pet_api->class_documentation->{description}, '', 'got correct Pet API description'; # right now it's blank + +# API method docs is_deeply( [sort keys %{$api->pet_api->method_documentation}], [ 'add_pet', 'delete_pet', 'find_pets_by_status', 'find_pets_by_tags', 'get_pet_by_id', 'update_pet', 'update_pet_with_form', 'upload_file'], "Pet API method_documentation has the correct keys"); +is $api->pet_api->method_documentation->{get_pet_by_id}->{params}->{pet_id}->{description}, + 'ID of pet that needs to be fetched', 'get_pet_by_id parameter pet_id description is correct'; +is $api->pet_api->method_documentation->{get_pet_by_id}->{params}->{pet_id}->{required}, + 1, 'get_pet_by_id parameter pet_id is required'; +is $api->pet_api->method_documentation->{get_pet_by_id}->{params}->{pet_id}->{data_type}, + 'int', 'get_pet_by_id parameter pet_id is an int'; +is $api->pet_api->method_documentation->{get_pet_by_id}->{returns}, + 'Pet', 'get_pet_by_id returns a Pet'; +is $api->pet_api->method_documentation->{get_pet_by_id}->{summary}, + 'Find pet by ID', 'get_pet_by_id summary is correct'; -my $pet_class_doco = { 'description' => '' }; +# object class docs +my $pet_class_doco = { 'description' => '', required => [], class => 'Pet' }; is_deeply($get_pet->class_documentation, $pet_class_doco, 'Pet object class_documentation is available'); +is $get_pet->class_documentation->{description}, '', 'Pet object class_documentation is correct'; # right now it's blank +is $get_pet->class_documentation->{class}, 'Pet', 'Pet object class_documentation returns correct class name'; + +# object method docs +is $get_pet->method_documentation->{status}->{description}, 'pet status in the store', 'Pet object method_documentation for status() - description is correct'; +is $get_pet->method_documentation->{status}->{format}, '', 'Pet object method_documentation for status() - format is correct'; +is $get_pet->method_documentation->{status}->{base_name}, 'status', 'Pet object method_documentation for status() - base_name is correct'; +is $get_pet->method_documentation->{status}->{datatype}, 'string', 'Pet object method_documentation for status() - datatype is correct'; + + + # / documentation tests my $tokens = { From c097696276f83c326e0d67f9a28895d74f598872 Mon Sep 17 00:00:00 2001 From: Dave Baird Date: Thu, 12 Nov 2015 13:03:04 +0100 Subject: [PATCH 10/14] Added more formats to autodoc output - narrow - wide - POD - HTML --- .../src/main/resources/perl/AutoDoc.mustache | 301 ++++++++++++++++-- .../src/main/resources/perl/README.md | 15 +- .../src/main/resources/perl/Role.mustache | 17 +- .../resources/perl/autodoc.script.mustache | 49 ++- samples/client/petstore/perl/README.md | 15 +- samples/client/petstore/perl/bin/autodoc | 49 ++- .../perl/lib/WWW/SwaggerClient/Role.pm | 17 +- .../lib/WWW/SwaggerClient/Role/AutoDoc.pm | 301 ++++++++++++++++-- samples/client/petstore/perl/t/04_role.t | 21 +- 9 files changed, 669 insertions(+), 116 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache b/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache index c756915f80f0..b702c4a45f73 100644 --- a/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache @@ -1,19 +1,21 @@ -package WWW::{{moduleName}}::Role::AutoDoc; +package WWW::BookeoClient::Role::AutoDoc; use List::MoreUtils qw(uniq); use Moose::Role; sub autodoc { - my $self = shift; + my ($self, $how) = @_; - $self->_printisa; - $self->_printmethods; - $self->_printattrs; + die "Unknown format '$how'" unless $how =~ /^(pod|wide|narrow)$/; + + $self->_printisa($how); + $self->_printmethods($how); + $self->_printattrs($how); print "\n"; } sub _printisa { - my $self = shift; + my ($self, $how) = @_; my $meta = $self->meta; my $myclass = ref $self; @@ -22,19 +24,26 @@ sub _printisa { my @roles = $meta->calculate_all_roles; shift(@roles); # the first is a composite, the rest are the roles - my $isa = join ', ', $meta->linearized_isa; + my $isa = join ', ', grep {$_ ne $myclass} $meta->linearized_isa; my $sub = join ', ', $meta->subclasses; my $dsub = join ', ', $meta->direct_subclasses; my ($rolepkg, $role_reqs); - $~ = 'INHERIT'; + $~ = $how eq 'pod' ? 'INHERIT_POD' : 'INHERIT'; write; foreach my $role (@roles) { $rolepkg = $role->{package}; + next if $rolepkg eq 'WWW::BookeoClient::Role::AutoDoc'; $role_reqs = join ', ', keys %{$role->{required_methods}}; - $~ = 'ROLES'; + $role_reqs ||= ''; + $~ = $how eq 'pod' ? 'ROLES_POD' : 'ROLES'; + write; + } + + if ($how eq 'pod') { + $~ = 'ROLES_POD_CLOSE'; write; } @@ -51,23 +60,94 @@ $myclass $sub . format ROLES = - Composes: @* - $rolepkg - requires: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ - $role_reqs + Composes: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $rolepkg + requires: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~ + $role_reqs + ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $role_reqs +. + + format INHERIT_POD = +=head1 NAME + +@* +$myclass + +=head1 INHERITANCE + +=head2 Base class(es) + +@* +$isa + +=head2 Direct subclasses + +@* +$dsub + +=head2 All subclasses + +@* +$sub + +=head1 COMPOSITION + +@* composes the following roles: +$myclass + + +. + format ROLES_POD = +=head2 C<@*> + $rolepkg + +Requires: + +@* +$role_reqs + +. + format ROLES_POD_CLOSE = + + . # ----- / format specs ----- } sub _printmethods { - my $self = shift; - $~ = 'METHODHEAD'; - write; - $self->_printmethod($_) for uniq sort $self->meta->get_method_list, $self->meta->get_all_method_names; + my ($self, $how) = @_; + + if ($how eq 'narrow') { + print <_printmethod($_, $how) for uniq sort $self->meta->get_all_method_names; #$self->meta->get_method_list, + + if ($how eq 'pod') { + $~ = 'METHOD_POD_CLOSE'; + write; + } + + } sub _printmethod { - my ($self, $methodname) = @_; + my ($self, $methodname, $how) = @_; return if $methodname =~ /^_/; return if $self->meta->has_attribute($methodname); my %internal = map {$_ => 1} qw(BUILD BUILDARGS meta can new DEMOLISHALL DESTROY @@ -78,44 +158,134 @@ sub _printmethod { return if $method->original_package_name eq __PACKAGE__; - my $delegation = ''; my $delegate_to = ''; my $via = ''; my $on = ''; + my $original_pkg = $method->original_package_name; if ($method->can('associated_attribute')) { $delegate_to = $method->delegate_to_method; my $aa = $method->associated_attribute; $on = $aa->{isa}; $via = $aa->{name}; + $original_pkg = "(flattened into $original_pkg from ???)"; # TODO - need to get hold of the role pkg, not the pkg it's flattened onto + use Data::Dumper; + #print Dumper($aa); + } + + if ($how eq 'narrow') { + $~ = 'METHOD_NARROW'; + write; + } + elsif ($how eq 'pod' and $delegate_to) { + $~ = 'METHOD_POD_DELEGATED'; + write; + } + elsif ($how eq 'pod') { + $~ = 'METHOD_POD'; + write; + } + else { + $~ = 'METHOD'; + write; } - $~ = 'METHOD'; - write; - # ----- format specs ----- format METHODHEAD = METHODS ------- -Name delegate to on via -=================================================================================================================================== +Name delegates to on via +=========================================================================================================================================================================== . format METHOD = -@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<... -$methodname, $delegate_to, $on, $via +@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<... +$methodname, $delegate_to, $on, $via +. + + format METHOD_NARROW = +@* +$methodname + original pkg: @* + $original_pkg + delegates to: @* + $delegate_to + on: @* + $on + via: @* + $via + +. + + format METHODHEAD_POD = + +=head1 METHODS + +. + + format METHOD_POD = + +=head2 C<@*()> + $methodname + + Defined in: @* + $original_pkg + + +. + format METHOD_POD_DELEGATED = + +=head2 C<@*()> + $methodname + + Defined in: @* + $original_pkg + Delegates to: @*() + $delegate_to + On: @* + $on + Via: @*() + $via + Same as: $self->@*->@*() + $via, $delegate_to + +. + format METHOD_POD_CLOSE = + . # ----- / format specs ----- } sub _printattrs { - my $self = shift; - $~ = 'ATTRHEAD'; - write; - $self->_printattr($_) for sort $self->meta->get_attribute_list; + my ($self, $how) = @_; + + if ($how eq 'narrow') { + print <_printattr($_, $how) for sort $self->meta->get_attribute_list; + + if ($how eq 'pod') { + $~ = 'ATTR_POD_CLOSE'; + write; + } } sub _printattr { - my ($self, $attrname) = @_; + my ($self, $attrname, $how) = @_; return if $attrname =~ /^_/; my $attr = $self->meta->get_attribute($attrname) or die "No attr for $attrname"; @@ -128,12 +298,22 @@ sub _printattr { my $tc = $attr->type_constraint || ''; my $from = $attr->associated_class->name || ''; - my $reqd = $attr->is_required ? 'reqd' : 'opt'; - my $lazy = $attr->is_lazy ? 'lazy' : ''; - my $doc = $attr->has_documentation ? 'yes' : ''; + my $reqd = $attr->is_required ? 'yes' : 'no'; + my $lazy = $attr->is_lazy ? 'yes' : 'no'; + my $doc = $attr->has_documentation ? 'yes' : 'no'; my $handles = join ', ', sort @{$attr->handles || []}; + $handles ||= ''; - $~ = 'ATTR'; + if ($how eq 'narrow') { + $~ = 'ATTR_NARROW'; + } + elsif ($how eq 'pod') { + $~ = 'ATTR_POD'; + } + else { + $~ = 'ATTR'; + } + write; # ----- format specs ----- @@ -149,8 +329,59 @@ Name is isa reqd lazy doc handles $attrname, $is, $tc, $reqd, $lazy, $doc, $handles ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ $handles +. + + format ATTR_NARROW = +@* +$attrname + is: @* + $is + isa: @* + $tc + reqd: @* + $reqd + lazy: @* + $lazy + doc: @* + $doc + handles: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + $handles + ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $handles + +. + format ATTRHEAD_POD = +=head1 ATTRIBUTES + +. + format ATTR_POD = + +=head2 C<@*> + $attrname + + is: @* + $is + isa: @* + $tc + reqd: @* + $reqd + lazy: @* + $lazy + doc: @* + $doc + handles: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + $handles + ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $handles + +. + format ATTR_POD_CLOSE = + + . # ----- / format specs ----- } + + 1; \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/perl/README.md b/modules/swagger-codegen/src/main/resources/perl/README.md index 491892b2f166..e3690f6f10b1 100644 --- a/modules/swagger-codegen/src/main/resources/perl/README.md +++ b/modules/swagger-codegen/src/main/resources/perl/README.md @@ -175,8 +175,19 @@ you just built. # AUTOMATIC DOCUMENTATION -You can print out a summary of the generated API by running the included -`autodoc` script in the `bin` directory of your generated library. +You can print out a summary of the generated API by running the included +`autodoc` script in the `bin` directory of your generated library. A few +output formats are supported: + + Usage: autodoc [OPTION] + + -w wide format (default) + -n narrow format + -p POD format + -H HTML format + -h print this help message + + # DOCUMENTATION FROM THE SWAGGER SPEC diff --git a/modules/swagger-codegen/src/main/resources/perl/Role.mustache b/modules/swagger-codegen/src/main/resources/perl/Role.mustache index c0891ead4244..4f78850ae73c 100644 --- a/modules/swagger-codegen/src/main/resources/perl/Role.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/Role.mustache @@ -51,9 +51,6 @@ sub BUILD { foreach my $method (keys %delegates) { if ( @{$delegates{$method}} > 1 ) { my ($apis) = delete $delegates{$method}; - foreach my $api (@$apis) { - warn sprintf "Cannot delegate %s (use \$self->%s_api->%s instead)\n", $method, lc($api->{api_name}), $method; - } } } @@ -261,8 +258,18 @@ you just built. =head1 AUTOMATIC DOCUMENTATION -You can print out a summary of the generated API by running the included -C script in the C directory of your generated library. +You can print out a summary of the generated API by running the included +C script in the C directory of your generated library. A few +output formats are supported: + + Usage: autodoc [OPTION] + + -w wide format (default) + -n narrow format + -p POD format + -H HTML format + -h print this help message + =head1 DOCUMENTATION FROM THE SWAGGER SPEC diff --git a/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache b/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache index b39bd8986471..547aad21d9d4 100644 --- a/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache @@ -1,19 +1,54 @@ #!/usr/bin/perl -package MyAutodoc; use FindBin; use File::Spec; use lib File::Spec->catdir($FindBin::Bin, '..', 'lib'); +use Getopt::Std; + +my %options=(); +getopts("wnphH", \%options); + +die "Too many options: there can be only one" if keys %options > 1; + +$options{w}++ unless keys %options; + +if ($options{h}) { + print <new; +my $opt; +$opt = 'pod' if $options{p}; +$opt = 'wide' if $options{w}; +$opt = 'narrow' if $options{n}; +$opt = 'pod' if $options{H}; -print $api->autodoc; +my $api = My::App->new; + +if ($options{H}) { + my $pod2html = "pod2html --backlink --css http://st.pimg.net/tucs/style.css?3"; + open STDOUT, "| $pod2html" or die "Can't fork: $!"; + $api->autodoc($opt); + close STDOUT or die "Can't close: $!"; +} +else { + $api->autodoc($opt); +} exit(0); diff --git a/samples/client/petstore/perl/README.md b/samples/client/petstore/perl/README.md index 36e3521958ef..4f668b939295 100644 --- a/samples/client/petstore/perl/README.md +++ b/samples/client/petstore/perl/README.md @@ -175,8 +175,19 @@ you just built. # AUTOMATIC DOCUMENTATION -You can print out a summary of the generated API by running the included -`autodoc` script in the `bin` directory of your generated library. +You can print out a summary of the generated API by running the included +`autodoc` script in the `bin` directory of your generated library. A few +output formats are supported: + + Usage: autodoc [OPTION] + + -w wide format (default) + -n narrow format + -p POD format + -H HTML format + -h print this help message + + # DOCUMENTATION FROM THE SWAGGER SPEC diff --git a/samples/client/petstore/perl/bin/autodoc b/samples/client/petstore/perl/bin/autodoc index 0e9f893e642d..547aad21d9d4 100644 --- a/samples/client/petstore/perl/bin/autodoc +++ b/samples/client/petstore/perl/bin/autodoc @@ -1,19 +1,54 @@ #!/usr/bin/perl -package MyAutodoc; use FindBin; use File::Spec; use lib File::Spec->catdir($FindBin::Bin, '..', 'lib'); +use Getopt::Std; + +my %options=(); +getopts("wnphH", \%options); + +die "Too many options: there can be only one" if keys %options > 1; + +$options{w}++ unless keys %options; + +if ($options{h}) { + print <new; +my $opt; +$opt = 'pod' if $options{p}; +$opt = 'wide' if $options{w}; +$opt = 'narrow' if $options{n}; +$opt = 'pod' if $options{H}; -print $api->autodoc; +my $api = My::App->new; + +if ($options{H}) { + my $pod2html = "pod2html --backlink --css http://st.pimg.net/tucs/style.css?3"; + open STDOUT, "| $pod2html" or die "Can't fork: $!"; + $api->autodoc($opt); + close STDOUT or die "Can't close: $!"; +} +else { + $api->autodoc($opt); +} exit(0); diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm index 0983f219fdf5..83bfb1b5da07 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm @@ -51,9 +51,6 @@ sub BUILD { foreach my $method (keys %delegates) { if ( @{$delegates{$method}} > 1 ) { my ($apis) = delete $delegates{$method}; - foreach my $api (@$apis) { - warn sprintf "Cannot delegate %s (use \$self->%s_api->%s instead)\n", $method, lc($api->{api_name}), $method; - } } } @@ -261,8 +258,18 @@ you just built. =head1 AUTOMATIC DOCUMENTATION -You can print out a summary of the generated API by running the included -C script in the C directory of your generated library. +You can print out a summary of the generated API by running the included +C script in the C directory of your generated library. A few +output formats are supported: + + Usage: autodoc [OPTION] + + -w wide format (default) + -n narrow format + -p POD format + -H HTML format + -h print this help message + =head1 DOCUMENTATION FROM THE SWAGGER SPEC diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm index 93b45427bbe1..b702c4a45f73 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm @@ -1,19 +1,21 @@ -package WWW::SwaggerClient::Role::AutoDoc; +package WWW::BookeoClient::Role::AutoDoc; use List::MoreUtils qw(uniq); use Moose::Role; sub autodoc { - my $self = shift; + my ($self, $how) = @_; - $self->_printisa; - $self->_printmethods; - $self->_printattrs; + die "Unknown format '$how'" unless $how =~ /^(pod|wide|narrow)$/; + + $self->_printisa($how); + $self->_printmethods($how); + $self->_printattrs($how); print "\n"; } sub _printisa { - my $self = shift; + my ($self, $how) = @_; my $meta = $self->meta; my $myclass = ref $self; @@ -22,19 +24,26 @@ sub _printisa { my @roles = $meta->calculate_all_roles; shift(@roles); # the first is a composite, the rest are the roles - my $isa = join ', ', $meta->linearized_isa; + my $isa = join ', ', grep {$_ ne $myclass} $meta->linearized_isa; my $sub = join ', ', $meta->subclasses; my $dsub = join ', ', $meta->direct_subclasses; my ($rolepkg, $role_reqs); - $~ = 'INHERIT'; + $~ = $how eq 'pod' ? 'INHERIT_POD' : 'INHERIT'; write; foreach my $role (@roles) { $rolepkg = $role->{package}; + next if $rolepkg eq 'WWW::BookeoClient::Role::AutoDoc'; $role_reqs = join ', ', keys %{$role->{required_methods}}; - $~ = 'ROLES'; + $role_reqs ||= ''; + $~ = $how eq 'pod' ? 'ROLES_POD' : 'ROLES'; + write; + } + + if ($how eq 'pod') { + $~ = 'ROLES_POD_CLOSE'; write; } @@ -51,23 +60,94 @@ $myclass $sub . format ROLES = - Composes: @* - $rolepkg - requires: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ - $role_reqs + Composes: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $rolepkg + requires: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~ + $role_reqs + ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $role_reqs +. + + format INHERIT_POD = +=head1 NAME + +@* +$myclass + +=head1 INHERITANCE + +=head2 Base class(es) + +@* +$isa + +=head2 Direct subclasses + +@* +$dsub + +=head2 All subclasses + +@* +$sub + +=head1 COMPOSITION + +@* composes the following roles: +$myclass + + +. + format ROLES_POD = +=head2 C<@*> + $rolepkg + +Requires: + +@* +$role_reqs + +. + format ROLES_POD_CLOSE = + + . # ----- / format specs ----- } sub _printmethods { - my $self = shift; - $~ = 'METHODHEAD'; - write; - $self->_printmethod($_) for uniq sort $self->meta->get_method_list, $self->meta->get_all_method_names; + my ($self, $how) = @_; + + if ($how eq 'narrow') { + print <_printmethod($_, $how) for uniq sort $self->meta->get_all_method_names; #$self->meta->get_method_list, + + if ($how eq 'pod') { + $~ = 'METHOD_POD_CLOSE'; + write; + } + + } sub _printmethod { - my ($self, $methodname) = @_; + my ($self, $methodname, $how) = @_; return if $methodname =~ /^_/; return if $self->meta->has_attribute($methodname); my %internal = map {$_ => 1} qw(BUILD BUILDARGS meta can new DEMOLISHALL DESTROY @@ -78,44 +158,134 @@ sub _printmethod { return if $method->original_package_name eq __PACKAGE__; - my $delegation = ''; my $delegate_to = ''; my $via = ''; my $on = ''; + my $original_pkg = $method->original_package_name; if ($method->can('associated_attribute')) { $delegate_to = $method->delegate_to_method; my $aa = $method->associated_attribute; $on = $aa->{isa}; $via = $aa->{name}; + $original_pkg = "(flattened into $original_pkg from ???)"; # TODO - need to get hold of the role pkg, not the pkg it's flattened onto + use Data::Dumper; + #print Dumper($aa); + } + + if ($how eq 'narrow') { + $~ = 'METHOD_NARROW'; + write; + } + elsif ($how eq 'pod' and $delegate_to) { + $~ = 'METHOD_POD_DELEGATED'; + write; + } + elsif ($how eq 'pod') { + $~ = 'METHOD_POD'; + write; + } + else { + $~ = 'METHOD'; + write; } - $~ = 'METHOD'; - write; - # ----- format specs ----- format METHODHEAD = METHODS ------- -Name delegate to on via -=================================================================================================================================== +Name delegates to on via +=========================================================================================================================================================================== . format METHOD = -@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<... -$methodname, $delegate_to, $on, $via +@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<... +$methodname, $delegate_to, $on, $via +. + + format METHOD_NARROW = +@* +$methodname + original pkg: @* + $original_pkg + delegates to: @* + $delegate_to + on: @* + $on + via: @* + $via + +. + + format METHODHEAD_POD = + +=head1 METHODS + +. + + format METHOD_POD = + +=head2 C<@*()> + $methodname + + Defined in: @* + $original_pkg + + +. + format METHOD_POD_DELEGATED = + +=head2 C<@*()> + $methodname + + Defined in: @* + $original_pkg + Delegates to: @*() + $delegate_to + On: @* + $on + Via: @*() + $via + Same as: $self->@*->@*() + $via, $delegate_to + +. + format METHOD_POD_CLOSE = + . # ----- / format specs ----- } sub _printattrs { - my $self = shift; - $~ = 'ATTRHEAD'; - write; - $self->_printattr($_) for sort $self->meta->get_attribute_list; + my ($self, $how) = @_; + + if ($how eq 'narrow') { + print <_printattr($_, $how) for sort $self->meta->get_attribute_list; + + if ($how eq 'pod') { + $~ = 'ATTR_POD_CLOSE'; + write; + } } sub _printattr { - my ($self, $attrname) = @_; + my ($self, $attrname, $how) = @_; return if $attrname =~ /^_/; my $attr = $self->meta->get_attribute($attrname) or die "No attr for $attrname"; @@ -128,12 +298,22 @@ sub _printattr { my $tc = $attr->type_constraint || ''; my $from = $attr->associated_class->name || ''; - my $reqd = $attr->is_required ? 'reqd' : 'opt'; - my $lazy = $attr->is_lazy ? 'lazy' : ''; - my $doc = $attr->has_documentation ? 'yes' : ''; + my $reqd = $attr->is_required ? 'yes' : 'no'; + my $lazy = $attr->is_lazy ? 'yes' : 'no'; + my $doc = $attr->has_documentation ? 'yes' : 'no'; my $handles = join ', ', sort @{$attr->handles || []}; + $handles ||= ''; - $~ = 'ATTR'; + if ($how eq 'narrow') { + $~ = 'ATTR_NARROW'; + } + elsif ($how eq 'pod') { + $~ = 'ATTR_POD'; + } + else { + $~ = 'ATTR'; + } + write; # ----- format specs ----- @@ -149,8 +329,59 @@ Name is isa reqd lazy doc handles $attrname, $is, $tc, $reqd, $lazy, $doc, $handles ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ $handles +. + + format ATTR_NARROW = +@* +$attrname + is: @* + $is + isa: @* + $tc + reqd: @* + $reqd + lazy: @* + $lazy + doc: @* + $doc + handles: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + $handles + ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $handles + +. + format ATTRHEAD_POD = +=head1 ATTRIBUTES + +. + format ATTR_POD = + +=head2 C<@*> + $attrname + + is: @* + $is + isa: @* + $tc + reqd: @* + $reqd + lazy: @* + $lazy + doc: @* + $doc + handles: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + $handles + ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $handles + +. + format ATTR_POD_CLOSE = + + . # ----- / format specs ----- } + + 1; \ No newline at end of file diff --git a/samples/client/petstore/perl/t/04_role.t b/samples/client/petstore/perl/t/04_role.t index f58e096032a7..4a3d6ec13e8b 100644 --- a/samples/client/petstore/perl/t/04_role.t +++ b/samples/client/petstore/perl/t/04_role.t @@ -1,4 +1,4 @@ -use Test::More tests => 39; +use Test::More tests => 38; use Test::Exception; use Test::Warnings 'warnings'; use Test::Deep; @@ -15,25 +15,10 @@ SKIP: { sub auth_setup_handler {} "; - skip 'Moose not installed', 39 if $@; + skip 'Moose not installed', 38 if $@; -my $api; -cmp_deeply( - [ warnings { $api = MyApp->new } ], - bag( - "Cannot delegate new (use \$self->pet_api->new instead)\n", - "Cannot delegate new (use \$self->store_api->new instead)\n", - "Cannot delegate new (use \$self->user_api->new instead)\n", - "Cannot delegate class_documentation (use \$self->pet_api->class_documentation instead)\n", - "Cannot delegate class_documentation (use \$self->store_api->class_documentation instead)\n", - "Cannot delegate class_documentation (use \$self->user_api->class_documentation instead)\n", - "Cannot delegate method_documentation (use \$self->pet_api->method_documentation instead)\n", - "Cannot delegate method_documentation (use \$self->store_api->method_documentation instead)\n", - "Cannot delegate method_documentation (use \$self->user_api->method_documentation instead)\n", - ), - 'got expected warnings about non-delegatable methods', - ); +my $api = MyApp->new; my $pet_id = 10008; # note - we don't need to 'use' these modules because they've already been loaded by ApiFactory From 25c19135ffb873b42efdce4926b17a6aede343ca Mon Sep 17 00:00:00 2001 From: Dave Baird Date: Thu, 12 Nov 2015 14:55:48 +0100 Subject: [PATCH 11/14] autodoc can analyse arbitrary classes - added -c option to load and analyse any class --- .../src/main/resources/perl/AutoDoc.mustache | 10 ++-- .../src/main/resources/perl/README.md | 5 +- .../src/main/resources/perl/Role.mustache | 5 +- .../resources/perl/autodoc.script.mustache | 57 ++++++++++++------- samples/client/petstore/perl/README.md | 5 +- samples/client/petstore/perl/bin/autodoc | 57 ++++++++++++------- .../perl/lib/WWW/SwaggerClient/Role.pm | 5 +- .../lib/WWW/SwaggerClient/Role/AutoDoc.pm | 10 ++-- 8 files changed, 96 insertions(+), 58 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache b/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache index b702c4a45f73..3817deb89114 100644 --- a/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache @@ -1,4 +1,4 @@ -package WWW::BookeoClient::Role::AutoDoc; +package WWW::{{moduleName}}::Role::AutoDoc; use List::MoreUtils qw(uniq); use Moose::Role; @@ -22,7 +22,7 @@ sub _printisa { my $super = join ', ', $meta->superclasses; my @roles = $meta->calculate_all_roles; - shift(@roles); # the first is a composite, the rest are the roles + #shift(@roles) if @roles > 1; # if > 1, the first is a composite, the rest are the roles my $isa = join ', ', grep {$_ ne $myclass} $meta->linearized_isa; my $sub = join ', ', $meta->subclasses; @@ -34,8 +34,8 @@ sub _printisa { write; foreach my $role (@roles) { - $rolepkg = $role->{package}; - next if $rolepkg eq 'WWW::BookeoClient::Role::AutoDoc'; + $rolepkg = $role->{package} || next; # some are anonymous, or something + next if $rolepkg eq 'WWW::{{moduleName}}::Role::AutoDoc'; $role_reqs = join ', ', keys %{$role->{required_methods}}; $role_reqs ||= ''; $~ = $how eq 'pod' ? 'ROLES_POD' : 'ROLES'; @@ -60,7 +60,7 @@ $myclass $sub . format ROLES = - Composes: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + Composes: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~ $rolepkg requires: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~ $role_reqs diff --git a/modules/swagger-codegen/src/main/resources/perl/README.md b/modules/swagger-codegen/src/main/resources/perl/README.md index e3690f6f10b1..7d0f62dca4b3 100644 --- a/modules/swagger-codegen/src/main/resources/perl/README.md +++ b/modules/swagger-codegen/src/main/resources/perl/README.md @@ -186,8 +186,11 @@ output formats are supported: -p POD format -H HTML format -h print this help message + -c your application class + - +The `-c` option allows you to load and inspect your own application. A dummy +namespace is used if you don't supply your own class. # DOCUMENTATION FROM THE SWAGGER SPEC diff --git a/modules/swagger-codegen/src/main/resources/perl/Role.mustache b/modules/swagger-codegen/src/main/resources/perl/Role.mustache index 4f78850ae73c..72c4b47390f2 100644 --- a/modules/swagger-codegen/src/main/resources/perl/Role.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/Role.mustache @@ -269,7 +269,10 @@ output formats are supported: -p POD format -H HTML format -h print this help message - + -c your application class + +The C<-c> option allows you to load and inspect your own application. A dummy +namespace is used if you don't supply your own class. =head1 DOCUMENTATION FROM THE SWAGGER SPEC diff --git a/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache b/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache index 547aad21d9d4..d669119c28bd 100644 --- a/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache @@ -3,33 +3,27 @@ use FindBin; use File::Spec; use lib File::Spec->catdir($FindBin::Bin, '..', 'lib'); +use Moose::Util qw(apply_all_roles); use Getopt::Std; my %options=(); -getopts("wnphH", \%options); +getopts("wnphHc:", \%options); +help if $options{h}; -die "Too many options: there can be only one" if keys %options > 1; +my $my_app = $options{c} || 'My::App'; -$options{w}++ unless keys %options; - -if ($options{h}) { - print <new; +my $api = $my_app->new; if ($options{H}) { my $pod2html = "pod2html --backlink --css http://st.pimg.net/tucs/style.css?3"; @@ -52,3 +47,21 @@ else { } exit(0); + +# -------------------- +sub help { + print <catdir($FindBin::Bin, '..', 'lib'); +use Moose::Util qw(apply_all_roles); use Getopt::Std; my %options=(); -getopts("wnphH", \%options); +getopts("wnphHc:", \%options); +help if $options{h}; -die "Too many options: there can be only one" if keys %options > 1; +my $my_app = $options{c} || 'My::App'; -$options{w}++ unless keys %options; - -if ($options{h}) { - print <new; +my $api = $my_app->new; if ($options{H}) { my $pod2html = "pod2html --backlink --css http://st.pimg.net/tucs/style.css?3"; @@ -52,3 +47,21 @@ else { } exit(0); + +# -------------------- +sub help { + print < option allows you to load and inspect your own application. A dummy +namespace is used if you don't supply your own class. =head1 DOCUMENTATION FROM THE SWAGGER SPEC diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm index b702c4a45f73..333f5b4f626b 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm @@ -1,4 +1,4 @@ -package WWW::BookeoClient::Role::AutoDoc; +package WWW::SwaggerClient::Role::AutoDoc; use List::MoreUtils qw(uniq); use Moose::Role; @@ -22,7 +22,7 @@ sub _printisa { my $super = join ', ', $meta->superclasses; my @roles = $meta->calculate_all_roles; - shift(@roles); # the first is a composite, the rest are the roles + #shift(@roles) if @roles > 1; # if > 1, the first is a composite, the rest are the roles my $isa = join ', ', grep {$_ ne $myclass} $meta->linearized_isa; my $sub = join ', ', $meta->subclasses; @@ -34,8 +34,8 @@ sub _printisa { write; foreach my $role (@roles) { - $rolepkg = $role->{package}; - next if $rolepkg eq 'WWW::BookeoClient::Role::AutoDoc'; + $rolepkg = $role->{package} || next; # some are anonymous, or something + next if $rolepkg eq 'WWW::SwaggerClient::Role::AutoDoc'; $role_reqs = join ', ', keys %{$role->{required_methods}}; $role_reqs ||= ''; $~ = $how eq 'pod' ? 'ROLES_POD' : 'ROLES'; @@ -60,7 +60,7 @@ $myclass $sub . format ROLES = - Composes: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + Composes: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~ $rolepkg requires: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~ $role_reqs From 970c94a4d99ca62543def3ae71d5ea5413997a8f Mon Sep 17 00:00:00 2001 From: Dave Baird Date: Thu, 12 Nov 2015 16:55:20 +0100 Subject: [PATCH 12/14] autodoc retrieves descriptions for delegated methods --- .../src/main/resources/perl/AutoDoc.mustache | 13 ++++++++----- .../src/main/resources/perl/Role.mustache | 4 ++-- .../petstore/perl/lib/WWW/SwaggerClient/Role.pm | 4 ++-- .../perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm | 13 ++++++++----- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache b/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache index 3817deb89114..ba0edd840fff 100644 --- a/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache @@ -161,15 +161,15 @@ sub _printmethod { my $delegate_to = ''; my $via = ''; my $on = ''; + my $doc = ''; my $original_pkg = $method->original_package_name; if ($method->can('associated_attribute')) { $delegate_to = $method->delegate_to_method; my $aa = $method->associated_attribute; $on = $aa->{isa}; $via = $aa->{name}; - $original_pkg = "(flattened into $original_pkg from ???)"; # TODO - need to get hold of the role pkg, not the pkg it's flattened onto - use Data::Dumper; - #print Dumper($aa); + $original_pkg = $on; + $doc = $original_pkg->method_documentation->{$delegate_to}->{summary}; } if ($how eq 'narrow') { @@ -245,6 +245,8 @@ $methodname $on Via: @*() $via + Doc: @* + $doc Same as: $self->@*->@*() $via, $delegate_to @@ -300,7 +302,8 @@ sub _printattr { my $from = $attr->associated_class->name || ''; my $reqd = $attr->is_required ? 'yes' : 'no'; my $lazy = $attr->is_lazy ? 'yes' : 'no'; - my $doc = $attr->has_documentation ? 'yes' : 'no'; + my $has_doc = $attr->has_documentation ? 'yes' : 'no'; + my $doc = $attr->documentation || ''; my $handles = join ', ', sort @{$attr->handles || []}; $handles ||= ''; @@ -326,7 +329,7 @@ Name is isa reqd lazy doc handles . format ATTR = @<<<<<<<<<<<<<<<<< @< @<<<<<<<<<<<<<<<<<<<<<<<< @<<< @<<< @<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -$attrname, $is, $tc, $reqd, $lazy, $doc, $handles +$attrname, $is, $tc, $reqd, $lazy, $has_doc, $handles ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ $handles . diff --git a/modules/swagger-codegen/src/main/resources/perl/Role.mustache b/modules/swagger-codegen/src/main/resources/perl/Role.mustache index 72c4b47390f2..0ad2573016ee 100644 --- a/modules/swagger-codegen/src/main/resources/perl/Role.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/Role.mustache @@ -42,7 +42,7 @@ sub BUILD { # collect the methods callable on each API foreach my $api_name ($self->api_factory->apis_available) { my $api_class = $self->api_factory->classname_for($api_name); - my $methods = Class::Inspector->methods($api_class, 'expanded'); + my $methods = Class::Inspector->methods($api_class, 'expanded'); # not Moose, so use CI instead my @local_methods = grep {! /^_/} grep {! $outsiders{$_}} map {$_->[2]} grep {$_->[1] eq $api_class} @$methods; push( @{$delegates{$_}}, {api_name => $api_name, api_class => $api_class} ) for @local_methods; } @@ -66,6 +66,7 @@ sub BUILD { default => sub {$self->api_factory->get_api($api_name)}, lazy => 1, handles => \@delegated, + documentation => $api_class->class_documentation->{description}, # not populated yet ) ); } } @@ -73,7 +74,6 @@ sub BUILD { sub _build_af { my $self = shift; my %args; - $args{auth_setup_handler_object} = $self if $self->can('auth_setup_handler'); $args{base_url} = $self->base_url if $self->base_url; return WWW::{{moduleName}}::ApiFactory->new(%args); } diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm index 0199f6ee64e7..e2797bf8b8f1 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm @@ -42,7 +42,7 @@ sub BUILD { # collect the methods callable on each API foreach my $api_name ($self->api_factory->apis_available) { my $api_class = $self->api_factory->classname_for($api_name); - my $methods = Class::Inspector->methods($api_class, 'expanded'); + my $methods = Class::Inspector->methods($api_class, 'expanded'); # not Moose, so use CI instead my @local_methods = grep {! /^_/} grep {! $outsiders{$_}} map {$_->[2]} grep {$_->[1] eq $api_class} @$methods; push( @{$delegates{$_}}, {api_name => $api_name, api_class => $api_class} ) for @local_methods; } @@ -66,6 +66,7 @@ sub BUILD { default => sub {$self->api_factory->get_api($api_name)}, lazy => 1, handles => \@delegated, + documentation => $api_class->class_documentation->{description}, # not populated yet ) ); } } @@ -73,7 +74,6 @@ sub BUILD { sub _build_af { my $self = shift; my %args; - $args{auth_setup_handler_object} = $self if $self->can('auth_setup_handler'); $args{base_url} = $self->base_url if $self->base_url; return WWW::SwaggerClient::ApiFactory->new(%args); } diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm index 333f5b4f626b..1b9886e1744f 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm @@ -161,15 +161,15 @@ sub _printmethod { my $delegate_to = ''; my $via = ''; my $on = ''; + my $doc = ''; my $original_pkg = $method->original_package_name; if ($method->can('associated_attribute')) { $delegate_to = $method->delegate_to_method; my $aa = $method->associated_attribute; $on = $aa->{isa}; $via = $aa->{name}; - $original_pkg = "(flattened into $original_pkg from ???)"; # TODO - need to get hold of the role pkg, not the pkg it's flattened onto - use Data::Dumper; - #print Dumper($aa); + $original_pkg = $on; + $doc = $original_pkg->method_documentation->{$delegate_to}->{summary}; } if ($how eq 'narrow') { @@ -245,6 +245,8 @@ $methodname $on Via: @*() $via + Doc: @* + $doc Same as: $self->@*->@*() $via, $delegate_to @@ -300,7 +302,8 @@ sub _printattr { my $from = $attr->associated_class->name || ''; my $reqd = $attr->is_required ? 'yes' : 'no'; my $lazy = $attr->is_lazy ? 'yes' : 'no'; - my $doc = $attr->has_documentation ? 'yes' : 'no'; + my $has_doc = $attr->has_documentation ? 'yes' : 'no'; + my $doc = $attr->documentation || ''; my $handles = join ', ', sort @{$attr->handles || []}; $handles ||= ''; @@ -326,7 +329,7 @@ Name is isa reqd lazy doc handles . format ATTR = @<<<<<<<<<<<<<<<<< @< @<<<<<<<<<<<<<<<<<<<<<<<< @<<< @<<< @<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -$attrname, $is, $tc, $reqd, $lazy, $doc, $handles +$attrname, $is, $tc, $reqd, $lazy, $has_doc, $handles ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ $handles . From 995a1f547f44b0d88a8030a1747ba4f681c47793 Mon Sep 17 00:00:00 2001 From: Dave Baird Date: Fri, 13 Nov 2015 19:30:47 +0100 Subject: [PATCH 13/14] Removed endpoint API class documentation code - there is no standard way for a swagger spec to define descriptive information for an endpoint API - added markdown as a format to the autodoc script - added some version information to autogenerated docs --- .../src/main/resources/perl/AutoDoc.mustache | 45 +- .../src/main/resources/perl/README.md | 13 +- .../src/main/resources/perl/Role.mustache | 40 +- .../src/main/resources/perl/api.mustache | 5 - .../resources/perl/autodoc.script.mustache | 14 +- samples/client/petstore/perl/README.md | 421 ++++++++++-------- samples/client/petstore/perl/bin/autodoc | 14 +- .../perl/lib/WWW/SwaggerClient/PetApi.pm | 5 - .../perl/lib/WWW/SwaggerClient/Role.pm | 40 +- .../lib/WWW/SwaggerClient/Role/AutoDoc.pm | 45 +- .../perl/lib/WWW/SwaggerClient/StoreApi.pm | 5 - .../perl/lib/WWW/SwaggerClient/UserApi.pm | 5 - samples/client/petstore/perl/t/04_role.t | 9 +- 13 files changed, 438 insertions(+), 223 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache b/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache index ba0edd840fff..76da048b0693 100644 --- a/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache @@ -28,11 +28,16 @@ sub _printisa { my $sub = join ', ', $meta->subclasses; my $dsub = join ', ', $meta->direct_subclasses; + my $app_name = $self->version_info->{app_name}; + my $app_version = $self->version_info->{app_version}; + my $generated_date = $self->version_info->{generated_date}; + my $generator_class = $self->version_info->{generator_class}; + + $~ = $how eq 'pod' ? 'INHERIT_POD' : 'INHERIT'; + write; + my ($rolepkg, $role_reqs); - $~ = $how eq 'pod' ? 'INHERIT_POD' : 'INHERIT'; - write; - foreach my $role (@roles) { $rolepkg = $role->{package} || next; # some are anonymous, or something next if $rolepkg eq 'WWW::{{moduleName}}::Role::AutoDoc'; @@ -58,6 +63,14 @@ $myclass $dsub All subclasses: @* $sub + + Target API: @* @* + $app_name, $app_version + Generated on: @* + $generated_date + Generator class: @* + $generator_class + . format ROLES = Composes: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~ @@ -74,6 +87,26 @@ $myclass @* $myclass +=head1 VERSION + +=head2 @* version: @* + $app_name, $app_version + +Automatically generated by the Perl Swagger Codegen project: + +=over 4 + +=item Build date: @* + $generated_date + +=item Build package: @* + $generator_class + +=item Codegen version: + + +=back + =head1 INHERITANCE =head2 Base class(es) @@ -90,6 +123,7 @@ $dsub @* $sub + =head1 COMPOSITION @@ -171,6 +205,9 @@ sub _printmethod { $original_pkg = $on; $doc = $original_pkg->method_documentation->{$delegate_to}->{summary}; } + else { + $doc = $method->documentation; + } if ($how eq 'narrow') { $~ = 'METHOD_NARROW'; @@ -302,7 +339,7 @@ sub _printattr { my $from = $attr->associated_class->name || ''; my $reqd = $attr->is_required ? 'yes' : 'no'; my $lazy = $attr->is_lazy ? 'yes' : 'no'; - my $has_doc = $attr->has_documentation ? 'yes' : 'no'; + my $has_doc = $attr->has_documentation ? 'yes' : 'no'; # *_api attributes will never have doc, but other attributes might have my $doc = $attr->documentation || ''; my $handles = join ', ', sort @{$attr->handles || []}; $handles ||= ''; diff --git a/modules/swagger-codegen/src/main/resources/perl/README.md b/modules/swagger-codegen/src/main/resources/perl/README.md index 7d0f62dca4b3..2e7e57a2c574 100644 --- a/modules/swagger-codegen/src/main/resources/perl/README.md +++ b/modules/swagger-codegen/src/main/resources/perl/README.md @@ -1,6 +1,16 @@ # NAME -WWW::{{moduleName}}::Role - a Moose role for the Perl Swagger Codegen project +WWW::{{moduleName}}::Role - a Moose role for the {{appName}} + +## {{appName}} version: {{appVersion}} + +# VERSION + +Automatically generated by the Perl Swagger Codegen project: + +- Build date: {{generatedDate}} +- Build package: {{generatorClass}} +- Codegen version: ## A note on Moose @@ -185,6 +195,7 @@ output formats are supported: -n narrow format -p POD format -H HTML format + -m Markdown format -h print this help message -c your application class diff --git a/modules/swagger-codegen/src/main/resources/perl/Role.mustache b/modules/swagger-codegen/src/main/resources/perl/Role.mustache index 0ad2573016ee..06c230955d8c 100644 --- a/modules/swagger-codegen/src/main/resources/perl/Role.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/Role.mustache @@ -10,25 +10,39 @@ use WWW::{{moduleName}}::ApiFactory; has base_url => ( is => 'ro', required => 0, isa => 'Str', + documentation => 'Root of the server that requests are sent to', ); has api_factory => ( is => 'ro', isa => 'WWW::{{moduleName}}::ApiFactory', builder => '_build_af', lazy => 1, + documentation => 'Builds an instance of the endpoint API class', ); has tokens => ( is => 'ro', isa => 'HashRef', required => 0, - default => sub {{=<% %>=}}{{}}<%={{ }}=%>, # ! + default => sub { {} }, + documentation => 'The auth tokens required by the application - basic, OAuth and/or API key(s)', ); has _cfg => ( is => 'ro', isa => 'Str', default => 'WWW::{{moduleName}}::Configuration', ); - + +has version_info => ( is => 'ro', + isa => 'HashRef', + default => sub { { + app_name => '{{appName}}', + app_version => '{{appVersion}}', + generated_date => '{{generatedDate}}', + generator_class => '{{generatorClass}}', + } }, + documentation => 'Information about the application version and the codegen codebase version' + ); + sub BUILD { my $self = shift; @@ -66,7 +80,6 @@ sub BUILD { default => sub {$self->api_factory->get_api($api_name)}, lazy => 1, handles => \@delegated, - documentation => $api_class->class_documentation->{description}, # not populated yet ) ); } } @@ -80,7 +93,23 @@ sub _build_af { =head1 NAME -WWW::{{moduleName}}::Role - a Moose role for the Perl Swagger Codegen project +WWW::{{moduleName}}::Role - a Moose role for the {{appName}} + +=head2 {{appName}} version: {{appVersion}} + +=head1 VERSION + +Automatically generated by the Perl Swagger Codegen project: + +=over 4 + +=item Build date: {{generatedDate}} + +=item Build package: {{generatorClass}} + +=item Codegen version: + +=back =head2 A note on Moose @@ -268,12 +297,13 @@ output formats are supported: -n narrow format -p POD format -H HTML format + -m Markdown format -h print this help message -c your application class The C<-c> option allows you to load and inspect your own application. A dummy namespace is used if you don't supply your own class. - + =head1 DOCUMENTATION FROM THE SWAGGER SPEC Additional documentation for each class and method may be provided by the Swagger diff --git a/modules/swagger-codegen/src/main/resources/perl/api.mustache b/modules/swagger-codegen/src/main/resources/perl/api.mustache index f9312b994b39..d6dd9d598e18 100644 --- a/modules/swagger-codegen/src/main/resources/perl/api.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/api.mustache @@ -33,11 +33,6 @@ use WWW::{{moduleName}}::Configuration; use base "Class::Data::Inheritable"; __PACKAGE__->mk_classdata('method_documentation' => {}); -__PACKAGE__->mk_classdata('class_documentation' => {}); - -__PACKAGE__->class_documentation({description => '', # TODO - class => '{{classname}}', -} ); sub new { my $class = shift; diff --git a/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache b/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache index d669119c28bd..240936d9b510 100644 --- a/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/autodoc.script.mustache @@ -7,7 +7,7 @@ use Moose::Util qw(apply_all_roles); use Getopt::Std; my %options=(); -getopts("wnphHc:", \%options); +getopts("wnphmHc:", \%options); help if $options{h}; my $my_app = $options{c} || 'My::App'; @@ -28,10 +28,13 @@ else { package main; my $opt; -$opt = 'pod' if $options{p}; $opt = 'wide' if $options{w}; $opt = 'narrow' if $options{n}; + +$opt = 'pod' if $options{p}; $opt = 'pod' if $options{H}; +$opt = 'pod' if $options{m}; + $opt ||= 'wide'; my $api = $my_app->new; @@ -42,6 +45,12 @@ if ($options{H}) { $api->autodoc($opt); close STDOUT or die "Can't close: $!"; } +elsif ($options{m}) { + my $pod2markdown = "pod2markdown --html-encode-chars 1"; + open STDOUT, "| $pod2markdown" or die "Can't fork: $!"; + $api->autodoc($opt); + close STDOUT or die "Can't close: $!"; +} else { $api->autodoc($opt); } @@ -57,6 +66,7 @@ Usage: autodoc [OPTION] [-c My::App::Class] -n narrow format -p POD format -H HTML format + -m Markdown format -h print this help message -c your application class diff --git a/samples/client/petstore/perl/README.md b/samples/client/petstore/perl/README.md index fd237d92d4c6..289ce4617779 100644 --- a/samples/client/petstore/perl/README.md +++ b/samples/client/petstore/perl/README.md @@ -1,208 +1,281 @@ # NAME -WWW::SwaggerClient::Role - a Moose role for the Perl Swagger Codegen project +My::App -## A note on Moose +# VERSION -This role is the only component of the library that uses Moose. See -WWW::SwaggerClient::ApiFactory for non-Moosey usage. +## Swagger Petstore version: 1.0.0 -# SYNOPSIS +Automatically generated by the Perl Swagger Codegen project: -The Perl Swagger Codegen project builds a library of Perl modules to interact with -a web service defined by a Swagger specification. See below for how to build the -library. +- Build date: 2015-11-13T18:23:57.025Z +- Build package: class io.swagger.codegen.languages.PerlClientCodegen +- Codegen version: -This module provides an interface to the generated library. All the classes, -objects, and methods (well, not quite \*all\*, see below) are flattened into this -role. +# INHERITANCE - package MyApp; - use Moose; - with 'WWW::SwaggerClient::Role'; - - package main; - - my $api = MyApp->new({ tokens => $tokens }); - - my $pet = $api->get_pet_by_id(pet_id => $pet_id); - +## Base class(es) -## Structure of the library +Moose::Object -The library consists of a set of API classes, one for each endpoint. These APIs -implement the method calls available on each endpoint. +## Direct subclasses -Additionally, there is a set of "object" classes, which represent the objects -returned by and sent to the methods on the endpoints. +## All subclasses -An API factory class is provided, which builds instances of each endpoint API. +# COMPOSITION -This Moose role flattens all the methods from the endpoint APIs onto the consuming -class. It also provides methods to retrieve the endpoint API objects, and the API -factory object, should you need it. +My::App composes the following roles: -For documentation of all these methods, see AUTOMATIC DOCUMENTATION below. +## `WWW::SwaggerClient::Role` -## Configuring authentication - -In the normal case, the Swagger spec will describe what parameters are -required and where to put them. You just need to supply the tokens. - - my $tokens = { - # basic - username => $username, - password => $password, - - # oauth - access_token => $oauth_token, - - # keys - $some_key => { token => $token, - prefix => $prefix, - in => $in, # 'head||query', - }, - - $another => { token => $token, - prefix => $prefix, - in => $in, # 'head||query', - }, - ..., - - }; - - my $api = MyApp->new({ tokens => $tokens }); - -Note these are all optional, as are `prefix` and `in`, and depend on the API -you are accessing. Usually `prefix` and `in` will be determined by the code generator from -the spec and you will not need to set them at run time. If not, `in` will -default to 'head' and `prefix` to the empty string. - -The tokens will be placed in the `WWW::SwaggerClient::Configuration` namespace -as follows, but you don't need to know about this. - -- `$WWW::SwaggerClient::Configuration::username` - - String. The username for basic auth. - -- `$WWW::SwaggerClient::Configuration::password` - - String. The password for basic auth. - -- `$WWW::SwaggerClient::Configuration::api_key` - - Hashref. Keyed on the name of each key (there can be multiple tokens). - - $WWW::SwaggerClient::Configuration::api_key = { - secretKey => 'aaaabbbbccccdddd', - anotherKey => '1111222233334444', - }; - -- `$WWW::SwaggerClient::Configuration::api_key_prefix` - - Hashref. Keyed on the name of each key (there can be multiple tokens). Note not - all api keys require a prefix. - - $WWW::SwaggerClient::Configuration::api_key_prefix = { - secretKey => 'string', - anotherKey => 'same or some other string', - }; - -- `$WWW::SwaggerClient::Configuration::access_token` - - String. The OAuth access token. +Requires: # METHODS -## `base_url` +## `add_pet()` -The generated code has the `base_url` already set as a default value. This method -returns (and optionally sets, but only if the API client has not been -created yet) the current value of `base_url`. + Defined in: WWW::SwaggerClient::PetApi + Delegates to: add_pet() + On: WWW::SwaggerClient::PetApi + Via: pet_api() + Doc: Add a new pet to the store + Same as: $self->pet_api->add_pet() + +## `create_user()` + + Defined in: WWW::SwaggerClient::UserApi + Delegates to: create_user() + On: WWW::SwaggerClient::UserApi + Via: user_api() + Doc: Create user + Same as: $self->user_api->create_user() + +## `create_users_with_array_input()` + + Defined in: WWW::SwaggerClient::UserApi + Delegates to: create_users_with_array_input() + On: WWW::SwaggerClient::UserApi + Via: user_api() + Doc: Creates list of users with given input array + Same as: $self->user_api->create_users_with_array_input() + +## `create_users_with_list_input()` + + Defined in: WWW::SwaggerClient::UserApi + Delegates to: create_users_with_list_input() + On: WWW::SwaggerClient::UserApi + Via: user_api() + Doc: Creates list of users with given input array + Same as: $self->user_api->create_users_with_list_input() + +## `delete_order()` + + Defined in: WWW::SwaggerClient::StoreApi + Delegates to: delete_order() + On: WWW::SwaggerClient::StoreApi + Via: store_api() + Doc: Delete purchase order by ID + Same as: $self->store_api->delete_order() + +## `delete_pet()` + + Defined in: WWW::SwaggerClient::PetApi + Delegates to: delete_pet() + On: WWW::SwaggerClient::PetApi + Via: pet_api() + Doc: Deletes a pet + Same as: $self->pet_api->delete_pet() + +## `delete_user()` + + Defined in: WWW::SwaggerClient::UserApi + Delegates to: delete_user() + On: WWW::SwaggerClient::UserApi + Via: user_api() + Doc: Delete user + Same as: $self->user_api->delete_user() + +## `find_pets_by_status()` + + Defined in: WWW::SwaggerClient::PetApi + Delegates to: find_pets_by_status() + On: WWW::SwaggerClient::PetApi + Via: pet_api() + Doc: Finds Pets by status + Same as: $self->pet_api->find_pets_by_status() + +## `find_pets_by_tags()` + + Defined in: WWW::SwaggerClient::PetApi + Delegates to: find_pets_by_tags() + On: WWW::SwaggerClient::PetApi + Via: pet_api() + Doc: Finds Pets by tags + Same as: $self->pet_api->find_pets_by_tags() + +## `get_inventory()` + + Defined in: WWW::SwaggerClient::StoreApi + Delegates to: get_inventory() + On: WWW::SwaggerClient::StoreApi + Via: store_api() + Doc: Returns pet inventories by status + Same as: $self->store_api->get_inventory() + +## `get_order_by_id()` + + Defined in: WWW::SwaggerClient::StoreApi + Delegates to: get_order_by_id() + On: WWW::SwaggerClient::StoreApi + Via: store_api() + Doc: Find purchase order by ID + Same as: $self->store_api->get_order_by_id() + +## `get_pet_by_id()` + + Defined in: WWW::SwaggerClient::PetApi + Delegates to: get_pet_by_id() + On: WWW::SwaggerClient::PetApi + Via: pet_api() + Doc: Find pet by ID + Same as: $self->pet_api->get_pet_by_id() + +## `get_user_by_name()` + + Defined in: WWW::SwaggerClient::UserApi + Delegates to: get_user_by_name() + On: WWW::SwaggerClient::UserApi + Via: user_api() + Doc: Get user by user name + Same as: $self->user_api->get_user_by_name() + +## `login_user()` + + Defined in: WWW::SwaggerClient::UserApi + Delegates to: login_user() + On: WWW::SwaggerClient::UserApi + Via: user_api() + Doc: Logs user into the system + Same as: $self->user_api->login_user() + +## `logout_user()` + + Defined in: WWW::SwaggerClient::UserApi + Delegates to: logout_user() + On: WWW::SwaggerClient::UserApi + Via: user_api() + Doc: Logs out current logged in user session + Same as: $self->user_api->logout_user() + +## `place_order()` + + Defined in: WWW::SwaggerClient::StoreApi + Delegates to: place_order() + On: WWW::SwaggerClient::StoreApi + Via: store_api() + Doc: Place an order for a pet + Same as: $self->store_api->place_order() + +## `update_pet()` + + Defined in: WWW::SwaggerClient::PetApi + Delegates to: update_pet() + On: WWW::SwaggerClient::PetApi + Via: pet_api() + Doc: Update an existing pet + Same as: $self->pet_api->update_pet() + +## `update_pet_with_form()` + + Defined in: WWW::SwaggerClient::PetApi + Delegates to: update_pet_with_form() + On: WWW::SwaggerClient::PetApi + Via: pet_api() + Doc: Updates a pet in the store with form data + Same as: $self->pet_api->update_pet_with_form() + +## `update_user()` + + Defined in: WWW::SwaggerClient::UserApi + Delegates to: update_user() + On: WWW::SwaggerClient::UserApi + Via: user_api() + Doc: Updated user + Same as: $self->user_api->update_user() + +## `upload_file()` + + Defined in: WWW::SwaggerClient::PetApi + Delegates to: upload_file() + On: WWW::SwaggerClient::PetApi + Via: pet_api() + Doc: uploads an image + Same as: $self->pet_api->upload_file() + +# ATTRIBUTES ## `api_factory` -Returns an API factory object. You probably won't need to call this directly. + is: ro + isa: WWW::SwaggerClient::ApiFactory + reqd: no + lazy: yes + doc: Builds an instance of the endpoint API class + handles: - $self->api_factory('Pet'); # returns a WWW::SwaggerClient::PetApi instance - - $self->pet_api; # the same +## `base_url` -# MISSING METHODS + is: ro + isa: Str + reqd: no + lazy: no + doc: Root of the server that requests are sent to + handles: -Most of the methods on the API are delegated to individual endpoint API objects -(e.g. Pet API, Store API, User API etc). Where different endpoint APIs use the -same method name (e.g. `new()`), these methods can't be delegated. So you need -to call `$api->pet_api->new()`. +## `pet_api` -In principle, every API is susceptible to the presence of a few, random, undelegatable -method names. In practice, because of the way method names are constructed, it's -unlikely in general that any methods will be undelegatable, except for: + is: ro + isa: WWW::SwaggerClient::PetApi + reqd: no + lazy: yes + doc: + handles: add_pet, delete_pet, find_pets_by_status, find_pets_by_tags, + get_pet_by_id, update_pet, update_pet_with_form, upload_file - new() - class_documentation() - method_documentation() +## `store_api` -To call these methods, you need to get a handle on the relevant object, either -by calling `$api->foo_api` or by retrieving an object, e.g. -`$api->get_pet_by_id(pet_id => $pet_id)`. They are class methods, so -you could also call them on class names. + is: ro + isa: WWW::SwaggerClient::StoreApi + reqd: no + lazy: yes + doc: + handles: delete_order, get_inventory, get_order_by_id, place_order -# BUILDING YOUR LIBRARY +## `tokens` -See the homepage `https://github.com/swagger-api/swagger-codegen` for full details. -But briefly, clone the git repository, build the codegen codebase, set up your build -config file, then run the API build script. You will need git, Java 7 and Apache -maven 3.0.3 or better already installed. + is: ro + isa: HashRef + reqd: no + lazy: no + doc: The auth tokens required by the application - basic, OAuth and/or API key(s) + handles: -The config file should specify the project name for the generated library: +## `user_api` - {"moduleName":"MyProjectName"} + is: ro + isa: WWW::SwaggerClient::UserApi + reqd: no + lazy: yes + doc: + handles: create_user, create_users_with_array_input, + create_users_with_list_input, delete_user, get_user_by_name, + login_user, logout_user, update_user -Your library files will be built under `WWW::MyProjectName`. +## `version_info` - $ git clone https://github.com/swagger-api/swagger-codegen.git - $ cd swagger-codegen - $ mvn package - $ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \ - -i [URL or file path to JSON swagger API spec] \ - -l perl \ - -c /path/to/config/file.json \ - -o /path/to/output/folder - -Bang, all done. Run the `autodoc` script in the `bin` directory to see the API -you just built. - -# AUTOMATIC DOCUMENTATION - -You can print out a summary of the generated API by running the included -`autodoc` script in the `bin` directory of your generated library. A few -output formats are supported: - - Usage: autodoc [OPTION] - - -w wide format (default) - -n narrow format - -p POD format - -H HTML format - -h print this help message - -c your application class - - -The `-c` option allows you to load and inspect your own application. A dummy -namespace is used if you don't supply your own class. - -# DOCUMENTATION FROM THE SWAGGER SPEC - -Additional documentation for each class and method may be provided by the Swagger -spec. If so, this is available via the `class_documentation()` and -`method_documentation()` methods on each generated API and class: - - my $cdoc = $api->pet_api->class_documentation; - my $cmdoc = $api->pet_api->method_documentation->{$method_name}; - - my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation; - my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name}; - - -Each of these calls returns a hashref with various useful pieces of information. + is: ro + isa: HashRef + reqd: no + lazy: no + doc: Information about the application version and the codegen codebase version + handles: diff --git a/samples/client/petstore/perl/bin/autodoc b/samples/client/petstore/perl/bin/autodoc index 9c167d7a41b6..049fcf7fecf2 100644 --- a/samples/client/petstore/perl/bin/autodoc +++ b/samples/client/petstore/perl/bin/autodoc @@ -7,7 +7,7 @@ use Moose::Util qw(apply_all_roles); use Getopt::Std; my %options=(); -getopts("wnphHc:", \%options); +getopts("wnphmHc:", \%options); help if $options{h}; my $my_app = $options{c} || 'My::App'; @@ -28,10 +28,13 @@ else { package main; my $opt; -$opt = 'pod' if $options{p}; $opt = 'wide' if $options{w}; $opt = 'narrow' if $options{n}; + +$opt = 'pod' if $options{p}; $opt = 'pod' if $options{H}; +$opt = 'pod' if $options{m}; + $opt ||= 'wide'; my $api = $my_app->new; @@ -42,6 +45,12 @@ if ($options{H}) { $api->autodoc($opt); close STDOUT or die "Can't close: $!"; } +elsif ($options{m}) { + my $pod2markdown = "pod2markdown --html-encode-chars 1"; + open STDOUT, "| $pod2markdown" or die "Can't fork: $!"; + $api->autodoc($opt); + close STDOUT or die "Can't close: $!"; +} else { $api->autodoc($opt); } @@ -57,6 +66,7 @@ Usage: autodoc [OPTION] [-c My::App::Class] -n narrow format -p POD format -H HTML format + -m Markdown format -h print this help message -c your application class diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm index 7c632f44504a..6c415d8e846a 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm @@ -33,11 +33,6 @@ use WWW::SwaggerClient::Configuration; use base "Class::Data::Inheritable"; __PACKAGE__->mk_classdata('method_documentation' => {}); -__PACKAGE__->mk_classdata('class_documentation' => {}); - -__PACKAGE__->class_documentation({description => '', # TODO - class => 'PetApi', -} ); sub new { my $class = shift; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm index e2797bf8b8f1..9e719c7d574a 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm @@ -10,25 +10,39 @@ use WWW::SwaggerClient::ApiFactory; has base_url => ( is => 'ro', required => 0, isa => 'Str', + documentation => 'Root of the server that requests are sent to', ); has api_factory => ( is => 'ro', isa => 'WWW::SwaggerClient::ApiFactory', builder => '_build_af', lazy => 1, + documentation => 'Builds an instance of the endpoint API class', ); has tokens => ( is => 'ro', isa => 'HashRef', required => 0, - default => sub {{}}, # ! + default => sub { {} }, + documentation => 'The auth tokens required by the application - basic, OAuth and/or API key(s)', ); has _cfg => ( is => 'ro', isa => 'Str', default => 'WWW::SwaggerClient::Configuration', ); - + +has version_info => ( is => 'ro', + isa => 'HashRef', + default => sub { { + app_name => 'Swagger Petstore', + app_version => '1.0.0', + generated_date => '2015-11-13T18:23:57.025Z', + generator_class => 'class io.swagger.codegen.languages.PerlClientCodegen', + } }, + documentation => 'Information about the application version and the codegen codebase version' + ); + sub BUILD { my $self = shift; @@ -66,7 +80,6 @@ sub BUILD { default => sub {$self->api_factory->get_api($api_name)}, lazy => 1, handles => \@delegated, - documentation => $api_class->class_documentation->{description}, # not populated yet ) ); } } @@ -80,7 +93,23 @@ sub _build_af { =head1 NAME -WWW::SwaggerClient::Role - a Moose role for the Perl Swagger Codegen project +WWW::SwaggerClient::Role - a Moose role for the Swagger Petstore + +=head2 Swagger Petstore version: 1.0.0 + +=head1 VERSION + +Automatically generated by the Perl Swagger Codegen project: + +=over 4 + +=item Build date: 2015-11-13T18:23:57.025Z + +=item Build package: class io.swagger.codegen.languages.PerlClientCodegen + +=item Codegen version: + +=back =head2 A note on Moose @@ -268,12 +297,13 @@ output formats are supported: -n narrow format -p POD format -H HTML format + -m Markdown format -h print this help message -c your application class The C<-c> option allows you to load and inspect your own application. A dummy namespace is used if you don't supply your own class. - + =head1 DOCUMENTATION FROM THE SWAGGER SPEC Additional documentation for each class and method may be provided by the Swagger diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm index 1b9886e1744f..0dc30dbfb902 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role/AutoDoc.pm @@ -28,11 +28,16 @@ sub _printisa { my $sub = join ', ', $meta->subclasses; my $dsub = join ', ', $meta->direct_subclasses; + my $app_name = $self->version_info->{app_name}; + my $app_version = $self->version_info->{app_version}; + my $generated_date = $self->version_info->{generated_date}; + my $generator_class = $self->version_info->{generator_class}; + + $~ = $how eq 'pod' ? 'INHERIT_POD' : 'INHERIT'; + write; + my ($rolepkg, $role_reqs); - $~ = $how eq 'pod' ? 'INHERIT_POD' : 'INHERIT'; - write; - foreach my $role (@roles) { $rolepkg = $role->{package} || next; # some are anonymous, or something next if $rolepkg eq 'WWW::SwaggerClient::Role::AutoDoc'; @@ -58,6 +63,14 @@ $myclass $dsub All subclasses: @* $sub + + Target API: @* @* + $app_name, $app_version + Generated on: @* + $generated_date + Generator class: @* + $generator_class + . format ROLES = Composes: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~ @@ -74,6 +87,26 @@ $myclass @* $myclass +=head1 VERSION + +=head2 @* version: @* + $app_name, $app_version + +Automatically generated by the Perl Swagger Codegen project: + +=over 4 + +=item Build date: @* + $generated_date + +=item Build package: @* + $generator_class + +=item Codegen version: + + +=back + =head1 INHERITANCE =head2 Base class(es) @@ -90,6 +123,7 @@ $dsub @* $sub + =head1 COMPOSITION @@ -171,6 +205,9 @@ sub _printmethod { $original_pkg = $on; $doc = $original_pkg->method_documentation->{$delegate_to}->{summary}; } + else { + $doc = $method->documentation; + } if ($how eq 'narrow') { $~ = 'METHOD_NARROW'; @@ -302,7 +339,7 @@ sub _printattr { my $from = $attr->associated_class->name || ''; my $reqd = $attr->is_required ? 'yes' : 'no'; my $lazy = $attr->is_lazy ? 'yes' : 'no'; - my $has_doc = $attr->has_documentation ? 'yes' : 'no'; + my $has_doc = $attr->has_documentation ? 'yes' : 'no'; # *_api attributes will never have doc, but other attributes might have my $doc = $attr->documentation || ''; my $handles = join ', ', sort @{$attr->handles || []}; $handles ||= ''; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm index 70fd83317cb1..21f9433fa32c 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm @@ -33,11 +33,6 @@ use WWW::SwaggerClient::Configuration; use base "Class::Data::Inheritable"; __PACKAGE__->mk_classdata('method_documentation' => {}); -__PACKAGE__->mk_classdata('class_documentation' => {}); - -__PACKAGE__->class_documentation({description => '', # TODO - class => 'StoreApi', -} ); sub new { my $class = shift; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm index 78a09f061383..a3cd164f3bc3 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm @@ -33,11 +33,6 @@ use WWW::SwaggerClient::Configuration; use base "Class::Data::Inheritable"; __PACKAGE__->mk_classdata('method_documentation' => {}); -__PACKAGE__->mk_classdata('class_documentation' => {}); - -__PACKAGE__->class_documentation({description => '', # TODO - class => 'UserApi', -} ); sub new { my $class = shift; diff --git a/samples/client/petstore/perl/t/04_role.t b/samples/client/petstore/perl/t/04_role.t index 4a3d6ec13e8b..73328fa6e629 100644 --- a/samples/client/petstore/perl/t/04_role.t +++ b/samples/client/petstore/perl/t/04_role.t @@ -1,4 +1,4 @@ -use Test::More tests => 38; +use Test::More tests => 37; use Test::Exception; use Test::Warnings 'warnings'; use Test::Deep; @@ -15,8 +15,8 @@ SKIP: { sub auth_setup_handler {} "; - skip 'Moose not installed', 38 if $@; - +# die $@ if $@; + skip 'Moose not installed', 37 if $@; my $api = MyApp->new; @@ -48,9 +48,6 @@ is $get_pet->tags->[0]->id, '11', 'stored and retrieved: got the proper tag id'; # documentation tests -# API class docs -is $api->pet_api->class_documentation->{description}, '', 'got correct Pet API description'; # right now it's blank - # API method docs is_deeply( [sort keys %{$api->pet_api->method_documentation}], [ 'add_pet', 'delete_pet', 'find_pets_by_status', 'find_pets_by_tags', 'get_pet_by_id', 'update_pet', 'update_pet_with_form', 'upload_file'], From 40f8012cbc08a89bb3acd998347625cd8b61ddd7 Mon Sep 17 00:00:00 2001 From: Dave Baird Date: Fri, 13 Nov 2015 21:52:44 +0100 Subject: [PATCH 14/14] Minor cleanup --- .../main/resources/perl/ApiFactory.mustache | 18 +- .../main/resources/perl/BaseObject.mustache | 2 +- .../src/main/resources/perl/README.md | 6 +- .../src/main/resources/perl/Role.mustache | 90 +++---- .../src/main/resources/perl/api.mustache | 23 +- samples/client/petstore/perl/README.md | 2 +- .../perl/lib/WWW/SwaggerClient/ApiFactory.pm | 18 +- .../WWW/SwaggerClient/Object/BaseObject.pm | 2 +- .../perl/lib/WWW/SwaggerClient/PetApi.pm | 234 +++++++++--------- .../perl/lib/WWW/SwaggerClient/Role.pm | 92 +++---- .../perl/lib/WWW/SwaggerClient/StoreApi.pm | 82 +++--- .../perl/lib/WWW/SwaggerClient/UserApi.pm | 194 ++++++++------- 12 files changed, 378 insertions(+), 385 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache b/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache index c38028fb37a6..fc119f7a9026 100644 --- a/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/ApiFactory.mustache @@ -21,9 +21,7 @@ use WWW::{{moduleName}}::ApiClient; use WWW::{{moduleName}}::ApiFactory; - my $api_factory = WWW::{{moduleName}}::ApiFactory->new( base_url => 'http://petstore.swagger.io/v2', - ..., # other args for ApiClient constructor - ); + my $api_factory = WWW::{{moduleName}}::ApiFactory->new( ... ); # any args for ApiClient constructor # later... my $pet_api = $api_factory->get_api('Pet'); @@ -47,23 +45,11 @@ my %_apis = map { $_ =~ /^WWW::{{moduleName}}::(.*)$/; $1 => $_ } =head1 new() - All parameters are optional, and are passed to and stored on the api_client object. + Any parameters are optional, and are passed to and stored on the api_client object. base_url: (optional) supply this to change the default base URL taken from the Swagger definition. - auth_setup_handler_object: (optional) - An object (or class name) that implements an auth_setup_handler() method. - - If set, the auth_setup_handler() method will be called on the object, and - passed a hashref with keys: api_client, query_params, header_params, auth_settings. - - The method should implement the required auth policy, for example, by setting - secret keys in the header, or username and password in the URL, etc. - - This is only necessary when the API specification itself does not describe - authentication. - =cut sub new { diff --git a/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache b/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache index 2bc48770632d..a41931940bae 100644 --- a/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/BaseObject.mustache @@ -22,7 +22,7 @@ use base ("Class::Accessor", "Class::Data::Inheritable"); __PACKAGE__->mk_classdata('attribute_map' => {}); __PACKAGE__->mk_classdata('swagger_types' => {}); -__PACKAGE__->mk_classdata('method_documentation' => {}); # TODO +__PACKAGE__->mk_classdata('method_documentation' => {}); __PACKAGE__->mk_classdata('class_documentation' => {}); # new object diff --git a/modules/swagger-codegen/src/main/resources/perl/README.md b/modules/swagger-codegen/src/main/resources/perl/README.md index 2e7e57a2c574..8d0b7695c153 100644 --- a/modules/swagger-codegen/src/main/resources/perl/README.md +++ b/modules/swagger-codegen/src/main/resources/perl/README.md @@ -136,7 +136,7 @@ Returns an API factory object. You probably won't need to call this directly. $self->api_factory('Pet'); # returns a WWW::{{moduleName}}::PetApi instance - $self->pet_api; # the same + $self->pet_api; # the same # MISSING METHODS @@ -207,9 +207,9 @@ namespace is used if you don't supply your own class. Additional documentation for each class and method may be provided by the Swagger spec. If so, this is available via the `class_documentation()` and -`method_documentation()` methods on each generated API and class: +`method_documentation()` methods on each generated object class, and the +`method_documentation()` method on the endpoint API classes: - my $cdoc = $api->pet_api->class_documentation; my $cmdoc = $api->pet_api->method_documentation->{$method_name}; my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation; diff --git a/modules/swagger-codegen/src/main/resources/perl/Role.mustache b/modules/swagger-codegen/src/main/resources/perl/Role.mustache index 06c230955d8c..7bca8cca78d7 100644 --- a/modules/swagger-codegen/src/main/resources/perl/Role.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/Role.mustache @@ -8,40 +8,40 @@ use Log::Any qw($log); use WWW::{{moduleName}}::ApiFactory; has base_url => ( is => 'ro', - required => 0, - isa => 'Str', - documentation => 'Root of the server that requests are sent to', - ); + required => 0, + isa => 'Str', + documentation => 'Root of the server that requests are sent to', + ); has api_factory => ( is => 'ro', - isa => 'WWW::{{moduleName}}::ApiFactory', - builder => '_build_af', - lazy => 1, - documentation => 'Builds an instance of the endpoint API class', - ); + isa => 'WWW::{{moduleName}}::ApiFactory', + builder => '_build_af', + lazy => 1, + documentation => 'Builds an instance of the endpoint API class', + ); has tokens => ( is => 'ro', - isa => 'HashRef', - required => 0, - default => sub { {} }, - documentation => 'The auth tokens required by the application - basic, OAuth and/or API key(s)', - ); + isa => 'HashRef', + required => 0, + default => sub { {} }, + documentation => 'The auth tokens required by the application - basic, OAuth and/or API key(s)', + ); has _cfg => ( is => 'ro', - isa => 'Str', - default => 'WWW::{{moduleName}}::Configuration', - ); + isa => 'Str', + default => 'WWW::{{moduleName}}::Configuration', + ); has version_info => ( is => 'ro', - isa => 'HashRef', - default => sub { { - app_name => '{{appName}}', - app_version => '{{appVersion}}', - generated_date => '{{generatedDate}}', - generator_class => '{{generatorClass}}', - } }, - documentation => 'Information about the application version and the codegen codebase version' - ); + isa => 'HashRef', + default => sub { { + app_name => '{{appName}}', + app_version => '{{appVersion}}', + generated_date => '{{generatedDate}}', + generator_class => '{{generatorClass}}', + } }, + documentation => 'Information about the application version and the codegen codebase version' + ); sub BUILD { my $self = shift; @@ -68,20 +68,20 @@ sub BUILD { } } - # build the flattened API - foreach my $api_name ($self->api_factory->apis_available) { - my $att_name = sprintf "%s_api", lc($api_name); - my $api_class = $self->api_factory->classname_for($api_name); - my @delegated = grep { $delegates{$_}->[0]->{api_name} eq $api_name } keys %delegates; - $log->debugf("Adding API: '%s' handles %s", $att_name, join ', ', @delegated); - $self->meta->add_attribute( $att_name => ( - is => 'ro', - isa => $api_class, - default => sub {$self->api_factory->get_api($api_name)}, - lazy => 1, - handles => \@delegated, - ) ); - } + # build the flattened API + foreach my $api_name ($self->api_factory->apis_available) { + my $att_name = sprintf "%s_api", lc($api_name); + my $api_class = $self->api_factory->classname_for($api_name); + my @delegated = grep { $delegates{$_}->[0]->{api_name} eq $api_name } keys %delegates; + $log->debugf("Adding API: '%s' handles %s", $att_name, join ', ', @delegated); + $self->meta->add_attribute( $att_name => ( + is => 'ro', + isa => $api_class, + default => sub {$self->api_factory->get_api($api_name)}, + lazy => 1, + handles => \@delegated, + ) ); + } } sub _build_af { @@ -235,10 +235,10 @@ created yet) the current value of C. =head2 C Returns an API factory object. You probably won't need to call this directly. - - $self->api_factory('Pet'); # returns a WWW::{{moduleName}}::PetApi instance - $self->pet_api; # the same + $self->api_factory('Pet'); # returns a WWW::{{moduleName}}::PetApi instance + + $self->pet_api; # the same =head1 MISSING METHODS @@ -308,9 +308,9 @@ namespace is used if you don't supply your own class. Additional documentation for each class and method may be provided by the Swagger spec. If so, this is available via the C and -C methods on each generated API and class: +C methods on each generated object class, and the +C method on the endpoint API classes: - my $cdoc = $api->pet_api->class_documentation; my $cmdoc = $api->pet_api->method_documentation->{$method_name}; my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation; diff --git a/modules/swagger-codegen/src/main/resources/perl/api.mustache b/modules/swagger-codegen/src/main/resources/perl/api.mustache index d6dd9d598e18..f25c63a528cc 100644 --- a/modules/swagger-codegen/src/main/resources/perl/api.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/api.mustache @@ -61,19 +61,20 @@ sub new { {{#allParams}}# @param {{dataType}} ${{paramName}} {{description}} {{#required}}(required){{/required}}{{^required}}(optional){{/required}} {{/allParams}} { - my $params = { + my $params = { {{#allParams}} - '{{paramName}}' => { - data_type => '{{dataType}}', - description => '{{description}}', - required => {{#required}}'1'{{/required}}{{^required}}'0'{{/required}}, - }, + '{{paramName}}' => { + data_type => '{{dataType}}', + description => '{{description}}', + required => {{#required}}'1'{{/required}}{{^required}}'0'{{/required}}, + }, {{/allParams}} - }; - __PACKAGE__->method_documentation->{ {{nickname}} } = { summary => '{{summary}}', - params => $params, - returns => {{#returnType}}'{{{returnType}}}'{{/returnType}}{{^returnType}}undef{{/returnType}}, - }; + }; + __PACKAGE__->method_documentation->{ {{nickname}} } = { + summary => '{{summary}}', + params => $params, + returns => {{#returnType}}'{{{returnType}}}'{{/returnType}}{{^returnType}}undef{{/returnType}}, + }; } # @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} # diff --git a/samples/client/petstore/perl/README.md b/samples/client/petstore/perl/README.md index 289ce4617779..adfe2455d658 100644 --- a/samples/client/petstore/perl/README.md +++ b/samples/client/petstore/perl/README.md @@ -8,7 +8,7 @@ My::App Automatically generated by the Perl Swagger Codegen project: -- Build date: 2015-11-13T18:23:57.025Z +- Build date: 2015-11-13T20:46:43.271Z - Build package: class io.swagger.codegen.languages.PerlClientCodegen - Codegen version: diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm index b428e503b9ec..f0846a9b5944 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/ApiFactory.pm @@ -21,9 +21,7 @@ use WWW::SwaggerClient::ApiClient; use WWW::SwaggerClient::ApiFactory; - my $api_factory = WWW::SwaggerClient::ApiFactory->new( base_url => 'http://petstore.swagger.io/v2', - ..., # other args for ApiClient constructor - ); + my $api_factory = WWW::SwaggerClient::ApiFactory->new( ... ); # any args for ApiClient constructor # later... my $pet_api = $api_factory->get_api('Pet'); @@ -47,23 +45,11 @@ my %_apis = map { $_ =~ /^WWW::SwaggerClient::(.*)$/; $1 => $_ } =head1 new() - All parameters are optional, and are passed to and stored on the api_client object. + Any parameters are optional, and are passed to and stored on the api_client object. base_url: (optional) supply this to change the default base URL taken from the Swagger definition. - auth_setup_handler_object: (optional) - An object (or class name) that implements an auth_setup_handler() method. - - If set, the auth_setup_handler() method will be called on the object, and - passed a hashref with keys: api_client, query_params, header_params, auth_settings. - - The method should implement the required auth policy, for example, by setting - secret keys in the header, or username and password in the URL, etc. - - This is only necessary when the API specification itself does not describe - authentication. - =cut sub new { diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/BaseObject.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/BaseObject.pm index d85ecf8a749b..f99b7715ae8d 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/BaseObject.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Object/BaseObject.pm @@ -22,7 +22,7 @@ use base ("Class::Accessor", "Class::Data::Inheritable"); __PACKAGE__->mk_classdata('attribute_map' => {}); __PACKAGE__->mk_classdata('swagger_types' => {}); -__PACKAGE__->mk_classdata('method_documentation' => {}); # TODO +__PACKAGE__->mk_classdata('method_documentation' => {}); __PACKAGE__->mk_classdata('class_documentation' => {}); # new object diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm index 6c415d8e846a..06ccfca98e80 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm @@ -58,17 +58,18 @@ sub new { # # @param Pet $body Pet object that needs to be added to the store (optional) { - my $params = { - 'body' => { - data_type => 'Pet', - description => 'Pet object that needs to be added to the store', - required => '0', - }, - }; - __PACKAGE__->method_documentation->{ update_pet } = { summary => 'Update an existing pet', - params => $params, - returns => undef, - }; + my $params = { + 'body' => { + data_type => 'Pet', + description => 'Pet object that needs to be added to the store', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ update_pet } = { + summary => 'Update an existing pet', + params => $params, + returns => undef, + }; } # @return void # @@ -122,17 +123,18 @@ sub update_pet { # # @param Pet $body Pet object that needs to be added to the store (optional) { - my $params = { - 'body' => { - data_type => 'Pet', - description => 'Pet object that needs to be added to the store', - required => '0', - }, - }; - __PACKAGE__->method_documentation->{ add_pet } = { summary => 'Add a new pet to the store', - params => $params, - returns => undef, - }; + my $params = { + 'body' => { + data_type => 'Pet', + description => 'Pet object that needs to be added to the store', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ add_pet } = { + summary => 'Add a new pet to the store', + params => $params, + returns => undef, + }; } # @return void # @@ -186,17 +188,18 @@ sub add_pet { # # @param ARRAY[string] $status Status values that need to be considered for filter (optional) { - my $params = { - 'status' => { - data_type => 'ARRAY[string]', - description => 'Status values that need to be considered for filter', - required => '0', - }, - }; - __PACKAGE__->method_documentation->{ find_pets_by_status } = { summary => 'Finds Pets by status', - params => $params, - returns => 'ARRAY[Pet]', - }; + my $params = { + 'status' => { + data_type => 'ARRAY[string]', + description => 'Status values that need to be considered for filter', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ find_pets_by_status } = { + summary => 'Finds Pets by status', + params => $params, + returns => 'ARRAY[Pet]', + }; } # @return ARRAY[Pet] # @@ -253,17 +256,18 @@ sub find_pets_by_status { # # @param ARRAY[string] $tags Tags to filter by (optional) { - my $params = { - 'tags' => { - data_type => 'ARRAY[string]', - description => 'Tags to filter by', - required => '0', - }, - }; - __PACKAGE__->method_documentation->{ find_pets_by_tags } = { summary => 'Finds Pets by tags', - params => $params, - returns => 'ARRAY[Pet]', - }; + my $params = { + 'tags' => { + data_type => 'ARRAY[string]', + description => 'Tags to filter by', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ find_pets_by_tags } = { + summary => 'Finds Pets by tags', + params => $params, + returns => 'ARRAY[Pet]', + }; } # @return ARRAY[Pet] # @@ -320,17 +324,18 @@ sub find_pets_by_tags { # # @param int $pet_id ID of pet that needs to be fetched (required) { - my $params = { - 'pet_id' => { - data_type => 'int', - description => 'ID of pet that needs to be fetched', - required => '1', - }, - }; - __PACKAGE__->method_documentation->{ get_pet_by_id } = { summary => 'Find pet by ID', - params => $params, - returns => 'Pet', - }; + my $params = { + 'pet_id' => { + data_type => 'int', + description => 'ID of pet that needs to be fetched', + required => '1', + }, + }; + __PACKAGE__->method_documentation->{ get_pet_by_id } = { + summary => 'Find pet by ID', + params => $params, + returns => 'Pet', + }; } # @return Pet # @@ -396,27 +401,28 @@ sub get_pet_by_id { # @param string $name Updated name of the pet (optional) # @param string $status Updated status of the pet (optional) { - my $params = { - 'pet_id' => { - data_type => 'string', - description => 'ID of pet that needs to be updated', - required => '1', - }, - 'name' => { - data_type => 'string', - description => 'Updated name of the pet', - required => '0', - }, - 'status' => { - data_type => 'string', - description => 'Updated status of the pet', - required => '0', - }, - }; - __PACKAGE__->method_documentation->{ update_pet_with_form } = { summary => 'Updates a pet in the store with form data', - params => $params, - returns => undef, - }; + my $params = { + 'pet_id' => { + data_type => 'string', + description => 'ID of pet that needs to be updated', + required => '1', + }, + 'name' => { + data_type => 'string', + description => 'Updated name of the pet', + required => '0', + }, + 'status' => { + data_type => 'string', + description => 'Updated status of the pet', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ update_pet_with_form } = { + summary => 'Updates a pet in the store with form data', + params => $params, + returns => undef, + }; } # @return void # @@ -488,22 +494,23 @@ sub update_pet_with_form { # @param int $pet_id Pet id to delete (required) # @param string $api_key (optional) { - my $params = { - 'pet_id' => { - data_type => 'int', - description => 'Pet id to delete', - required => '1', - }, - 'api_key' => { - data_type => 'string', - description => '', - required => '0', - }, - }; - __PACKAGE__->method_documentation->{ delete_pet } = { summary => 'Deletes a pet', - params => $params, - returns => undef, - }; + my $params = { + 'pet_id' => { + data_type => 'int', + description => 'Pet id to delete', + required => '1', + }, + 'api_key' => { + data_type => 'string', + description => '', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ delete_pet } = { + summary => 'Deletes a pet', + params => $params, + returns => undef, + }; } # @return void # @@ -569,27 +576,28 @@ sub delete_pet { # @param string $additional_metadata Additional data to pass to server (optional) # @param file $file file to upload (optional) { - my $params = { - 'pet_id' => { - data_type => 'int', - description => 'ID of pet to update', - required => '1', - }, - 'additional_metadata' => { - data_type => 'string', - description => 'Additional data to pass to server', - required => '0', - }, - 'file' => { - data_type => 'file', - description => 'file to upload', - required => '0', - }, - }; - __PACKAGE__->method_documentation->{ upload_file } = { summary => 'uploads an image', - params => $params, - returns => undef, - }; + my $params = { + 'pet_id' => { + data_type => 'int', + description => 'ID of pet to update', + required => '1', + }, + 'additional_metadata' => { + data_type => 'string', + description => 'Additional data to pass to server', + required => '0', + }, + 'file' => { + data_type => 'file', + description => 'file to upload', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ upload_file } = { + summary => 'uploads an image', + params => $params, + returns => undef, + }; } # @return void # diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm index 9e719c7d574a..feb5228cb615 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Role.pm @@ -8,40 +8,40 @@ use Log::Any qw($log); use WWW::SwaggerClient::ApiFactory; has base_url => ( is => 'ro', - required => 0, - isa => 'Str', - documentation => 'Root of the server that requests are sent to', - ); + required => 0, + isa => 'Str', + documentation => 'Root of the server that requests are sent to', + ); has api_factory => ( is => 'ro', - isa => 'WWW::SwaggerClient::ApiFactory', - builder => '_build_af', - lazy => 1, - documentation => 'Builds an instance of the endpoint API class', - ); + isa => 'WWW::SwaggerClient::ApiFactory', + builder => '_build_af', + lazy => 1, + documentation => 'Builds an instance of the endpoint API class', + ); has tokens => ( is => 'ro', - isa => 'HashRef', - required => 0, - default => sub { {} }, - documentation => 'The auth tokens required by the application - basic, OAuth and/or API key(s)', - ); + isa => 'HashRef', + required => 0, + default => sub { {} }, + documentation => 'The auth tokens required by the application - basic, OAuth and/or API key(s)', + ); has _cfg => ( is => 'ro', - isa => 'Str', - default => 'WWW::SwaggerClient::Configuration', - ); + isa => 'Str', + default => 'WWW::SwaggerClient::Configuration', + ); has version_info => ( is => 'ro', - isa => 'HashRef', - default => sub { { - app_name => 'Swagger Petstore', - app_version => '1.0.0', - generated_date => '2015-11-13T18:23:57.025Z', - generator_class => 'class io.swagger.codegen.languages.PerlClientCodegen', - } }, - documentation => 'Information about the application version and the codegen codebase version' - ); + isa => 'HashRef', + default => sub { { + app_name => 'Swagger Petstore', + app_version => '1.0.0', + generated_date => '2015-11-13T20:46:43.271Z', + generator_class => 'class io.swagger.codegen.languages.PerlClientCodegen', + } }, + documentation => 'Information about the application version and the codegen codebase version' + ); sub BUILD { my $self = shift; @@ -68,20 +68,20 @@ sub BUILD { } } - # build the flattened API - foreach my $api_name ($self->api_factory->apis_available) { - my $att_name = sprintf "%s_api", lc($api_name); - my $api_class = $self->api_factory->classname_for($api_name); - my @delegated = grep { $delegates{$_}->[0]->{api_name} eq $api_name } keys %delegates; - $log->debugf("Adding API: '%s' handles %s", $att_name, join ', ', @delegated); - $self->meta->add_attribute( $att_name => ( - is => 'ro', - isa => $api_class, - default => sub {$self->api_factory->get_api($api_name)}, - lazy => 1, - handles => \@delegated, - ) ); - } + # build the flattened API + foreach my $api_name ($self->api_factory->apis_available) { + my $att_name = sprintf "%s_api", lc($api_name); + my $api_class = $self->api_factory->classname_for($api_name); + my @delegated = grep { $delegates{$_}->[0]->{api_name} eq $api_name } keys %delegates; + $log->debugf("Adding API: '%s' handles %s", $att_name, join ', ', @delegated); + $self->meta->add_attribute( $att_name => ( + is => 'ro', + isa => $api_class, + default => sub {$self->api_factory->get_api($api_name)}, + lazy => 1, + handles => \@delegated, + ) ); + } } sub _build_af { @@ -103,7 +103,7 @@ Automatically generated by the Perl Swagger Codegen project: =over 4 -=item Build date: 2015-11-13T18:23:57.025Z +=item Build date: 2015-11-13T20:46:43.271Z =item Build package: class io.swagger.codegen.languages.PerlClientCodegen @@ -235,10 +235,10 @@ created yet) the current value of C. =head2 C Returns an API factory object. You probably won't need to call this directly. - - $self->api_factory('Pet'); # returns a WWW::SwaggerClient::PetApi instance - $self->pet_api; # the same + $self->api_factory('Pet'); # returns a WWW::SwaggerClient::PetApi instance + + $self->pet_api; # the same =head1 MISSING METHODS @@ -308,9 +308,9 @@ namespace is used if you don't supply your own class. Additional documentation for each class and method may be provided by the Swagger spec. If so, this is available via the C and -C methods on each generated API and class: +C methods on each generated object class, and the +C method on the endpoint API classes: - my $cdoc = $api->pet_api->class_documentation; my $cmdoc = $api->pet_api->method_documentation->{$method_name}; my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm index 21f9433fa32c..abe936573e7c 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm @@ -57,12 +57,13 @@ sub new { # Returns pet inventories by status # { - my $params = { - }; - __PACKAGE__->method_documentation->{ get_inventory } = { summary => 'Returns pet inventories by status', - params => $params, - returns => 'HASH[string,int]', - }; + my $params = { + }; + __PACKAGE__->method_documentation->{ get_inventory } = { + summary => 'Returns pet inventories by status', + params => $params, + returns => 'HASH[string,int]', + }; } # @return HASH[string,int] # @@ -116,17 +117,18 @@ sub get_inventory { # # @param Order $body order placed for purchasing the pet (optional) { - my $params = { - 'body' => { - data_type => 'Order', - description => 'order placed for purchasing the pet', - required => '0', - }, - }; - __PACKAGE__->method_documentation->{ place_order } = { summary => 'Place an order for a pet', - params => $params, - returns => 'Order', - }; + my $params = { + 'body' => { + data_type => 'Order', + description => 'order placed for purchasing the pet', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ place_order } = { + summary => 'Place an order for a pet', + params => $params, + returns => 'Order', + }; } # @return Order # @@ -183,17 +185,18 @@ sub place_order { # # @param string $order_id ID of pet that needs to be fetched (required) { - my $params = { - 'order_id' => { - data_type => 'string', - description => 'ID of pet that needs to be fetched', - required => '1', - }, - }; - __PACKAGE__->method_documentation->{ get_order_by_id } = { summary => 'Find purchase order by ID', - params => $params, - returns => 'Order', - }; + my $params = { + 'order_id' => { + data_type => 'string', + description => 'ID of pet that needs to be fetched', + required => '1', + }, + }; + __PACKAGE__->method_documentation->{ get_order_by_id } = { + summary => 'Find purchase order by ID', + params => $params, + returns => 'Order', + }; } # @return Order # @@ -257,17 +260,18 @@ sub get_order_by_id { # # @param string $order_id ID of the order that needs to be deleted (required) { - my $params = { - 'order_id' => { - data_type => 'string', - description => 'ID of the order that needs to be deleted', - required => '1', - }, - }; - __PACKAGE__->method_documentation->{ delete_order } = { summary => 'Delete purchase order by ID', - params => $params, - returns => undef, - }; + my $params = { + 'order_id' => { + data_type => 'string', + description => 'ID of the order that needs to be deleted', + required => '1', + }, + }; + __PACKAGE__->method_documentation->{ delete_order } = { + summary => 'Delete purchase order by ID', + params => $params, + returns => undef, + }; } # @return void # diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm index a3cd164f3bc3..9ba45815c8ce 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm @@ -58,17 +58,18 @@ sub new { # # @param User $body Created user object (optional) { - my $params = { - 'body' => { - data_type => 'User', - description => 'Created user object', - required => '0', - }, - }; - __PACKAGE__->method_documentation->{ create_user } = { summary => 'Create user', - params => $params, - returns => undef, - }; + my $params = { + 'body' => { + data_type => 'User', + description => 'Created user object', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ create_user } = { + summary => 'Create user', + params => $params, + returns => undef, + }; } # @return void # @@ -122,17 +123,18 @@ sub create_user { # # @param ARRAY[User] $body List of user object (optional) { - my $params = { - 'body' => { - data_type => 'ARRAY[User]', - description => 'List of user object', - required => '0', - }, - }; - __PACKAGE__->method_documentation->{ create_users_with_array_input } = { summary => 'Creates list of users with given input array', - params => $params, - returns => undef, - }; + my $params = { + 'body' => { + data_type => 'ARRAY[User]', + description => 'List of user object', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ create_users_with_array_input } = { + summary => 'Creates list of users with given input array', + params => $params, + returns => undef, + }; } # @return void # @@ -186,17 +188,18 @@ sub create_users_with_array_input { # # @param ARRAY[User] $body List of user object (optional) { - my $params = { - 'body' => { - data_type => 'ARRAY[User]', - description => 'List of user object', - required => '0', - }, - }; - __PACKAGE__->method_documentation->{ create_users_with_list_input } = { summary => 'Creates list of users with given input array', - params => $params, - returns => undef, - }; + my $params = { + 'body' => { + data_type => 'ARRAY[User]', + description => 'List of user object', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ create_users_with_list_input } = { + summary => 'Creates list of users with given input array', + params => $params, + returns => undef, + }; } # @return void # @@ -251,22 +254,23 @@ sub create_users_with_list_input { # @param string $username The user name for login (optional) # @param string $password The password for login in clear text (optional) { - my $params = { - 'username' => { - data_type => 'string', - description => 'The user name for login', - required => '0', - }, - 'password' => { - data_type => 'string', - description => 'The password for login in clear text', - required => '0', - }, - }; - __PACKAGE__->method_documentation->{ login_user } = { summary => 'Logs user into the system', - params => $params, - returns => 'string', - }; + my $params = { + 'username' => { + data_type => 'string', + description => 'The user name for login', + required => '0', + }, + 'password' => { + data_type => 'string', + description => 'The password for login in clear text', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ login_user } = { + summary => 'Logs user into the system', + params => $params, + returns => 'string', + }; } # @return string # @@ -325,12 +329,13 @@ sub login_user { # Logs out current logged in user session # { - my $params = { - }; - __PACKAGE__->method_documentation->{ logout_user } = { summary => 'Logs out current logged in user session', - params => $params, - returns => undef, - }; + my $params = { + }; + __PACKAGE__->method_documentation->{ logout_user } = { + summary => 'Logs out current logged in user session', + params => $params, + returns => undef, + }; } # @return void # @@ -381,17 +386,18 @@ sub logout_user { # # @param string $username The name that needs to be fetched. Use user1 for testing. (required) { - my $params = { - 'username' => { - data_type => 'string', - description => 'The name that needs to be fetched. Use user1 for testing.', - required => '1', - }, - }; - __PACKAGE__->method_documentation->{ get_user_by_name } = { summary => 'Get user by user name', - params => $params, - returns => 'User', - }; + my $params = { + 'username' => { + data_type => 'string', + description => 'The name that needs to be fetched. Use user1 for testing.', + required => '1', + }, + }; + __PACKAGE__->method_documentation->{ get_user_by_name } = { + summary => 'Get user by user name', + params => $params, + returns => 'User', + }; } # @return User # @@ -456,22 +462,23 @@ sub get_user_by_name { # @param string $username name that need to be deleted (required) # @param User $body Updated user object (optional) { - my $params = { - 'username' => { - data_type => 'string', - description => 'name that need to be deleted', - required => '1', - }, - 'body' => { - data_type => 'User', - description => 'Updated user object', - required => '0', - }, - }; - __PACKAGE__->method_documentation->{ update_user } = { summary => 'Updated user', - params => $params, - returns => undef, - }; + my $params = { + 'username' => { + data_type => 'string', + description => 'name that need to be deleted', + required => '1', + }, + 'body' => { + data_type => 'User', + description => 'Updated user object', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ update_user } = { + summary => 'Updated user', + params => $params, + returns => undef, + }; } # @return void # @@ -535,17 +542,18 @@ sub update_user { # # @param string $username The name that needs to be deleted (required) { - my $params = { - 'username' => { - data_type => 'string', - description => 'The name that needs to be deleted', - required => '1', - }, - }; - __PACKAGE__->method_documentation->{ delete_user } = { summary => 'Delete user', - params => $params, - returns => undef, - }; + my $params = { + 'username' => { + data_type => 'string', + description => 'The name that needs to be deleted', + required => '1', + }, + }; + __PACKAGE__->method_documentation->{ delete_user } = { + summary => 'Delete user', + params => $params, + returns => undef, + }; } # @return void #