From cddbd8c2d516e8eed33df6b5502a2e07a7a3b07b Mon Sep 17 00:00:00 2001 From: Lari Taskula Date: Mon, 20 Jun 2016 13:08:46 +0300 Subject: [PATCH] Bug 16212: Automatically minify swagger.json This patch adds automatic minification of swagger.json. Since startup subroutine is executed on each call to REST API, we need to be careful to not do useless computation by minificating swagger.json when not required. Therefore, we need some algorithm to determine whether minification is needed. In this patch, minification is executed in two cases: 1. swagger.min.json does not exist 2. swagger.json is modified more recently than swagger.min.json Includes tests. --- Koha/REST/V1.pm | 26 ++++++++++++ t/api/v1/minifier.t | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 t/api/v1/minifier.t diff --git a/Koha/REST/V1.pm b/Koha/REST/V1.pm index 1bfda46..b1b4954 100644 --- a/Koha/REST/V1.pm +++ b/Koha/REST/V1.pm @@ -43,6 +43,8 @@ sub startup { # Force charset=utf8 in Content-Type header for JSON responses $self->types->type(json => 'application/json; charset=utf8'); + $self->minifySwagger(); + my $secret_passphrase = C4::Context->config('api_secret_passphrase'); if ($secret_passphrase) { $self->secrets([$secret_passphrase]); @@ -54,4 +56,28 @@ sub startup { }); } +sub minifySwagger { + my ($self, $swaggerPath) = @_; + + $swaggerPath = C4::Context->config("intranetdir").'/api/v1/' unless $swaggerPath; + my $pathToMinifier = $swaggerPath.'minifySwagger.pl'; + my $pathToSwaggerJson = $swaggerPath.'swagger.json'; + my $pathToSwaggerMinJson = $swaggerPath.'swagger.min.json'; + + if (_isMinificationRequired($pathToSwaggerJson, $pathToSwaggerMinJson)) { + my $output = `perl $pathToMinifier -s $pathToSwaggerJson -d $pathToSwaggerMinJson`; + if ($output) { + die $output; + } + } +} + +sub _isMinificationRequired { + my ($pathToSwaggerJson, $pathToSwaggerMinJson) = @_; + + return 1 unless -e $pathToSwaggerJson; # swagger.json exists? + return 1 unless -e $pathToSwaggerMinJson; # swagger.min.json exists? + return 1 if -C $pathToSwaggerJson < -C $pathToSwaggerMinJson; # compare modification time +} + 1; diff --git a/t/api/v1/minifier.t b/t/api/v1/minifier.t new file mode 100644 index 0000000..8992a72 --- /dev/null +++ b/t/api/v1/minifier.t @@ -0,0 +1,119 @@ +#!/usr/bin/env perl + +# Copyright (C) 2016 KohaSuomi +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use File::Copy qw/copy/; +use File::Temp; +use File::Path qw/make_path rmtree/; + +use Test::More tests => 9; + +use C4::Context; +use Koha::REST::V1; + +my $oldSwagger_title = "Swagger Sample App"; +my $newSwagger_title = "Koha REST API"; + +# Construct an example swagger.json +my $swaggerJsonTest = +qq ({ + "swagger": "2.0", + "info": { + "title": "$oldSwagger_title", + "version": "1" + }, + "paths": {}, + "definitions": {}, + "parameters": {} +}); + +my $swaggerJsonTestModified = +qq ({ + "swagger": "2.0", + "info": { + "title": "$newSwagger_title", + "version": "1" + }, + "paths": {}, + "definitions": {}, + "parameters": {} +}); + +# Path containing actual swagger specification files +my $real_swaggerPath = C4::Context->config("intranetdir").'/api/v1/'; + +# Create a tmp directory where we can modify swagger.json +my $swaggerPath = File::Temp->newdir()."/"; +make_path($swaggerPath); + +# Copy minifySwagger.pl to this location +copy($real_swaggerPath.'minifySwagger.pl', $swaggerPath); + +my $pathToMinifier = $swaggerPath.'minifySwagger.pl'; +my $pathToSwaggerJson = $swaggerPath.'swagger.json'; +my $pathToSwaggerMinJson = $swaggerPath.'swagger.min.json'; + +is(-e $pathToSwaggerJson, undef, "swagger.json does not yet exist"); +is(-e $pathToSwaggerMinJson, undef, "swagger.min.json does not yet exist"); + +my $exists = -e $pathToSwaggerJson; +# Create swagger.json test file +open my $fh, '>', $pathToSwaggerJson; +print $fh $swaggerJsonTest; +close $fh; + +ok(-e $pathToSwaggerJson, "swagger.json created!"); + +Koha::REST::V1::minifySwagger(undef, $swaggerPath); +ok(-e $pathToSwaggerMinJson, "swagger.min.json created!"); +my $lastmodified = -C $pathToSwaggerMinJson; + +# Read swagger.min.json +require Swagger2; +my $swaggerMin = Swagger2->new($pathToSwaggerMinJson); +$swaggerMin = $swaggerMin->expand; +my $oldSwaggerTitle = $swaggerMin->{'api_spec'}->{'data'}->{'info'}->{'title'}; +is($oldSwaggerTitle, $oldSwagger_title, "old title found"); + +# Modify swagger.json +sleep(1); # make sure modification time differs from swagger.min.json +open $fh, '>', $pathToSwaggerJson; +print $fh $swaggerJsonTestModified; +close $fh; + +Koha::REST::V1::minifySwagger(undef, $swaggerPath); + +ok($lastmodified > -C $pathToSwaggerMinJson, + "swagger.min.json modified after editing swagger.json"); +$lastmodified = -C $pathToSwaggerMinJson; + +# Re-read swagger.min.json +$swaggerMin = Swagger2->new($pathToSwaggerMinJson); +$swaggerMin = $swaggerMin->expand; +my $newSwaggerTitle = $swaggerMin->{'api_spec'}->{'data'}->{'info'}->{'title'}; +is($newSwaggerTitle, $newSwagger_title, "new title found"); # was minified + +Koha::REST::V1::minifySwagger(undef, $swaggerPath); +ok($lastmodified == -C $pathToSwaggerMinJson, + "swagger.min.json not modified because no modifications to swagger.json"); + +# Cleanup +rmtree($swaggerPath) if $swaggerPath ne $real_swaggerPath; +is(-e $swaggerPath, undef, "tmp files deleted"); -- 1.9.1