Skip to content

Commit

Permalink
Closes #458 - not fully finished yet, due to Catalogues API constraints
Browse files Browse the repository at this point in the history
  • Loading branch information
jbonnet committed Mar 21, 2017
1 parent 54fc3a9 commit 897df52
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 55 deletions.
4 changes: 4 additions & 0 deletions son-gtkapi/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ development: &common_settings
url: http://localhost:5800
model: User
environment: USER_MANAGEMENT_URL
catalogue:
url: http://sp.int3.sonata-nfv.eu:4002/catalogues
model: Catalogue
environment: CATALOGUES_URL
level: debug
default_page_size: 10
default_page_number: 0
Expand Down
42 changes: 42 additions & 0 deletions son-gtkapi/models/catalogue.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
##
## Copyright (c) 2015 SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
## ALL RIGHTS RESERVED.
##
## Licensed under the Apache License, Version 2.0 (the "License");
## you may not use this file except in compliance with the License.
## You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##
## Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
## nor the names of its contributors may be used to endorse or promote
## products derived from this software without specific prior written
## permission.
##
## This work has been performed in the framework of the SONATA project,
## funded by the European Commission under Grant number 671517 through
## the Horizon 2020 and 5G-PPP programmes. The authors would like to
## acknowledge the contributions of their colleagues of the SONATA
## partner consortium (www.sonata-nfv.eu).
# encoding: utf-8
require './models/manager_service.rb'

class Catalogue < ManagerService

#JSON_HEADERS = { 'Accept'=> 'application/json', 'Content-Type'=>'application/json'}
LOG_MESSAGE = 'GtkApi::' + self.name

def self.config(url:)
method = LOG_MESSAGE + "#config(url=#{url})"
raise ArgumentError.new('Catalogue can not be configured with nil url') if url.nil?
raise ArgumentError.new('Catalogue can not be configured with empty url') if url.empty?
@@url = url
GtkApi.logger.debug(method) {'entered'}
end
end
2 changes: 1 addition & 1 deletion son-gtkapi/models/function_manager_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

class FunctionManagerService < ManagerService

JSON_HEADERS = { 'Accept'=> 'application/json', 'Content-Type'=>'application/json'}
#JSON_HEADERS = { 'Accept'=> 'application/json', 'Content-Type'=>'application/json'}
LOG_MESSAGE = 'GtkApi::' + self.name

def self.config(url:)
Expand Down
93 changes: 86 additions & 7 deletions son-gtkapi/models/package_manager_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ def self.url

def self.config(url:)
method = LOG_MESSAGE + "##{__method__}"
GtkApi.logger.debug(method) {'entered'}
raise ArgumentError.new('PackageManagerService can not be configured with nil url') if url.nil?
raise ArgumentError.new('PackageManagerService can not be configured with empty url') if url.empty?
GtkApi.logger.debug(method) {'entered with url='+url}
raise ArgumentError.new('PackageManagerService can not be configured with nil or empty url') if (url.nil? || url.empty?)
@@url = url
GtkApi.logger.debug(method) {'@@url='+url}
@@catalogue_url = ENV[GtkApi.services['catalogue']['environment']] || GtkApi.services['catalogue']['url']
GtkApi.logger.debug(method) {'@@catalogue_url='+@@catalogue_url}
end

def self.create(params)
Expand Down Expand Up @@ -96,11 +96,27 @@ def self.find_by_uuid(uuid)
method = LOG_MESSAGE + "##{__method__}"
GtkApi.logger.debug(method) {'entered'}
headers = { 'Accept'=> '*/*', 'Content-Type'=>'application/json'}
headers[:params] = uuid
begin
response = RestClient.get(@@url+"/packages/#{uuid}", headers)
GtkApi.logger.debug(method) {"response #{response}"}
response
JSON.parse response, symbolize_names: true
rescue => e
e.to_json
end
end

def self.find_package_file_name(uuid)
method = LOG_MESSAGE + "##{__method__}"
GtkApi.logger.debug(method) {'entered with uuid='+uuid}
headers = { 'Accept'=> '*/*', 'Content-Type'=>'application/json'}
begin
response = RestClient.get(@@url+"/son-packages/#{uuid}", headers)
GtkApi.logger.debug(method) {"response #{response}"}
if response.code == 200
JSON.parse(response, symbolize_names: true)[:grid_fs_name]
else
""
end
rescue => e
e.to_json
end
Expand All @@ -114,14 +130,77 @@ def self.find(params)
begin
response = RestClient.get(@@url+'/packages', headers)
GtkApi.logger.debug(method) {"response #{response}"}
response
JSON.parse response, symbolize_names: true
rescue => e
GtkApi.logger.error(method) {"Error during processing: #{$!}"}
GtkApi.logger.error(method) {"Backtrace:\n\t#{e.backtrace.join("\n\t")}"}
nil
end
end

def self.download(uuid)
method = LOG_MESSAGE + "##{__method__}"
raise ArgumentError.new('Package can not be downloaded if uuid is not given') if uuid.nil?

GtkApi.logger.debug(method) {'entered with uuid='+uuid}

#package_file_meta_data = self.find_package_file_meta_data_by_uuid(uuid)
#GtkApi.logger.debug(method) {"package_file_meta_data=#{package_file_meta_data}"}
#raise 'No package file meta-data found with package file uuid='+uuid if package_file_meta_data.empty?

file_name = self.save_package_file(uuid) #package_file_meta_data)
GtkApi.logger.debug(method) {"file_name=#{file_name}"}
raise "Package file with file_name=#{file_name} failled to be saved" if (file_name.nil? || file_name.empty?)
file_name
end

def self.find_package_file_meta_data_by_uuid(uuid)
method = LOG_MESSAGE + "##{__method__}"
GtkApi.logger.debug(method) {'entered with uuid='+uuid}
headers = { 'Accept'=> 'application/json', 'Content-Type'=>'application/json'}
begin
response = RestClient.get(@@catalogue_url+"/son-packages/#{uuid}", headers)
GtkApi.logger.debug(method) {"response.code=#{response.code}"}
if response.code == 200
JSON.parse(response, symbolize_names: true)
else
{}
end
rescue => e
e.to_json
end
end

def self.save_package_file(uuid)
method = LOG_MESSAGE + "##{__method__}"
GtkApi.logger.debug(method) {"entered with package_file_meta_data=#{uuid}"}

# Get data
url = URI(@@catalogue_url)
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(@@catalogue_url+"/son-packages/#{uuid}")
# These fields are mandatory
request["content-type"] = 'application/zip'
request["content-disposition"] = 'attachment; filename=<filename.son>'
response = http.request(request)
GtkApi.logger.debug("Catalogue response.code: #{response.code}")
case response.code
when '200'
data = response.read_body

# Save temporary file
tmp_dir = File.join(GtkApi.root, 'tmp')
FileUtils.mkdir(tmp_dir) unless File.exists?(tmp_dir)
package_file_name = uuid+'-'+'filename.son' #package_file_meta_data[:uuid]+'-'+package_file_meta_data[:grid_fs_name]
package_file_path = File.join(tmp_dir, package_file_name)
File.open(package_file_path, 'w') { |file| file.write(data) }
# pass back the name
package_file_path
else
nil
end
end

def self.delete(uuid)
method = LOG_MESSAGE + "##{__method__}"
GtkApi.logger.debug(method) {'entered'}
Expand Down
30 changes: 28 additions & 2 deletions son-gtkapi/routes/package.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,14 @@
## acknowledge the contributions of their colleagues of the SONATA
## partner consortium (www.sonata-nfv.eu).
# encoding: utf-8
require "sinatra/base"
require 'sinatra/namespace'
require "sinatra/streaming"

class GtkApi < Sinatra::Base

register Sinatra::Namespace
helpers Sinatra::Streaming

namespace '/api/v2/packages' do
# POST of packages
Expand Down Expand Up @@ -77,7 +81,7 @@ class GtkApi < Sinatra::Base
package = PackageManagerService.find_by_uuid(params[:uuid])
if package
logger.debug(log_message) {"leaving with package #{package}"}
halt 200, package
halt 200, package.to_json
else
logger.debug(log_message) {"leaving with \"No package with UUID=#{params[:uuid]} was found\""}
json_error 404, "No package with UUID=#{params[:uuid]} was found"
Expand All @@ -87,6 +91,28 @@ class GtkApi < Sinatra::Base
json_error 400, 'No package UUID specified'
end

# GET a specific package's file
get '/:uuid/download/?' do
log_message = 'GtkApi::GET /api/v2/packages/:uuid/download/?'
logger.debug(log_message) {'entered'}
unless params[:uuid].nil?
logger.debug(log_message) {"params[:uuid]=#{params[:uuid]}"}
json_error 400, 'Invalid Package UUID' unless valid? params['uuid']
package = PackageManagerService.find_by_uuid(params[:uuid])
if package
logger.debug(log_message) {"Found package #{package}"}
logger.debug(log_message) {"Looking for the package file name for package file #{package[:son_package_uuid]}..."}
file_name = PackageManagerService.download(package[:son_package_uuid])
send_file file_name
else
logger.debug(log_message) {"leaving with \"No package with UUID=#{params[:uuid]} was found\""}
json_error 404, "No package with UUID=#{params[:uuid]} was found"
end
end
logger.debug(log_message) {"leaving with \"No package UUID specified\""}
json_error 400, 'No package UUID specified'
end

# GET potentially many packages
get '/?' do
log_message = 'GtkApi::GET /api/v2/packages/?'
Expand All @@ -100,7 +126,7 @@ class GtkApi < Sinatra::Base
logger.debug(log_message) { "leaving with #{packages}"}
# TODO: total must be returned from the PackageManagement service
links = build_pagination_headers(url: request_url, limit: @limit.to_i, offset: @offset.to_i, total: packages.size)
[200, {'Link' => links}, packages]
[200, {'Link' => links}, packages.to_json]
else
error_message = 'No packages found' + (query_string.empty? ? '' : ' with parameters '+query_string)
json_error 404, error_message, log_message
Expand Down
19 changes: 19 additions & 0 deletions son-gtkpkg/models/catalogue.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,25 @@ def create_zip(zip)
# Response should return code 201, and ID of the stored son-package
end

def fetch_zip(uuid)
#url = URI("http://api.int.sonata-nfv.eu:4002/catalogues/son-packages")
url = URI(@url)
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(@url+'/'+uuid)
# These fields are mandatory
request["content-type"] = 'application/zip'
request["content-disposition"] = 'attachment; filename=<filename.son>'
response = http.request(request)
@logger.debug("Catalogue response: #{response}")
case response.code
when 200
#length = File.write(zip, response.read_body)
response.read_body
else
nil
end
end

def find_by_uuid(uuid)
@logger.debug CLASS+".find_by_uuid(#{uuid})"
headers = {'Accept'=>'application/json', 'Content-Type'=>'application/json'}
Expand Down
Loading

0 comments on commit 897df52

Please sign in to comment.