From c7fbadbf8192585ce6dd2487060183896a625e13 Mon Sep 17 00:00:00 2001 From: Dennis Kliban Date: Mon, 6 Dec 2021 13:43:40 -0500 Subject: [PATCH] Generate ruby client using openapi-generator-cli 5.3.0 closes: #55 --- generate.sh | 2 +- .../ruby/api_client_faraday_partial.mustache | 19 ++- templates/ruby/configuration.mustache | 128 ++++++++++++++++-- 3 files changed, 131 insertions(+), 18 deletions(-) diff --git a/generate.sh b/generate.sh index c913cd4..4401550 100755 --- a/generate.sh +++ b/generate.sh @@ -60,7 +60,7 @@ fi if [ $2 = 'ruby' ] then python3 remove-cookie-auth.py - $container_exec run -u $(id -u) --rm -v ${PWD}:$volume_name openapitools/openapi-generator-cli:v4.3.1 generate \ + $container_exec run -u $(id -u) --rm -v ${PWD}:$volume_name openapitools/openapi-generator-cli:v5.3.0 generate \ -i /local/api.json \ -g ruby \ -o /local/$1-client \ diff --git a/templates/ruby/api_client_faraday_partial.mustache b/templates/ruby/api_client_faraday_partial.mustache index 38bceaf..605cf61 100644 --- a/templates/ruby/api_client_faraday_partial.mustache +++ b/templates/ruby/api_client_faraday_partial.mustache @@ -14,7 +14,8 @@ :params_encoder => @config.params_encoder } connection = Faraday.new(:url => config.base_url, :ssl => ssl_options, :request => request_options) do |conn| - conn.basic_auth(config.username, config.password) + conn.request(:basic_auth, config.username, config.password) + @config.configure_middleware(conn) if opts[:header_params]["Content-Type"] == "multipart/form-data" conn.request :multipart conn.request :url_encoded @@ -65,7 +66,7 @@ # @option opts [Object] :body HTTP body (JSON/XML) # @return [Typhoeus::Request] A Typhoeus Request def build_request(http_method, path, request, opts = {}) - url = build_request_url(path) + url = build_request_url(path, opts) http_method = http_method.to_sym.downcase header_params = @default_headers.merge(opts[:header_params] || {}) @@ -75,9 +76,6 @@ update_params_for_auth! header_params, query_params, opts[:auth_names] req_opts = { - :method => http_method, - :headers => header_params, - :params => query_params, :params_encoding => @config.params_encoding, :timeout => @config.timeout, :verbose => @config.debugging @@ -85,13 +83,13 @@ if [:post, :patch, :put, :delete].include?(http_method) req_body = build_request_body(header_params, form_params, opts[:body]) - req_opts.update :body => req_body if @config.debugging @config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n" end end request.headers = header_params request.body = req_body + request.options = OpenStruct.new(req_opts) request.url url request.params = query_params download_file(request) if opts[:return_type] == 'File' @@ -129,3 +127,12 @@ end data end + + def download_file(request) + @stream = [] + + # handle streaming Responses + request.options.on_data = Proc.new do |chunk, overall_received_bytes| + @stream << chunk + end + end diff --git a/templates/ruby/configuration.mustache b/templates/ruby/configuration.mustache index 1468e2d..d1d5f47 100644 --- a/templates/ruby/configuration.mustache +++ b/templates/ruby/configuration.mustache @@ -13,6 +13,18 @@ module {{moduleName}} # Defines url base path attr_accessor :base_path + # Define server configuration index + attr_accessor :server_index + + # Define server operation configuration index + attr_accessor :server_operation_index + + # Default server variables + attr_accessor :server_variables + + # Default server operation variables + attr_accessor :server_operation_variables + # Defines API keys used with API Key authentications. # # @return [Hash] key: parameter name, value: parameter value (API key) @@ -90,11 +102,14 @@ module {{moduleName}} def initialize @scheme = '{{scheme}}' - @host = '{{host}}' + @host = '{{host}}{{#port}}:{{{.}}}{{/port}}' @base_path = '{{contextPath}}' + @server_index = 0 + @server_operation_index = {} + @server_variables = {} + @server_operation_variables = {} @api_key = {} @api_key_prefix = {} - @timeout = 0 @client_side_validation = true {{#isFaraday}} @ssl_verify = true @@ -103,6 +118,10 @@ module {{moduleName}} @ssl_client_cert = nil @ssl_client_key = nil @params_encoder = nil + @middlewares = [] + @request_middlewares = [] + @response_middlewares = [] + @timeout = 60 {{/isFaraday}} {{^isFaraday}} @verify_ssl = true @@ -110,6 +129,7 @@ module {{moduleName}} @params_encoding = nil @cert_file = nil @key_file = nil + @timeout = 0 {{/isFaraday}} @debugging = false @inject_format = false @@ -144,17 +164,23 @@ module {{moduleName}} @base_path = '' if @base_path == '/' end - def base_url - "#{scheme}://#{[host, base_path].join('/').gsub(/\/+/, '/')}".sub(/\/+\z/, '') + # Returns base URL for specified operation based on server settings + def base_url(operation = nil) + index = server_operation_index.fetch(operation, server_index) + return "#{scheme}://#{[host, base_path].join('/').gsub(/\/+/, '/')}".sub(/\/+\z/, '') if index == nil + + server_url(index, server_operation_variables.fetch(operation, server_variables), operation_server_settings[operation]) end # Gets API key (with prefix if set). # @param [String] param_name the parameter name of API key auth - def api_key_with_prefix(param_name) + def api_key_with_prefix(param_name, param_alias = nil) + key = @api_key[param_name] + key = @api_key.fetch(param_alias, key) unless param_alias.nil? if @api_key_prefix[param_name] - "#{@api_key_prefix[param_name]} #{@api_key[param_name]}" + "#{@api_key_prefix[param_name]} #{key}" else - @api_key[param_name] + key end end @@ -173,7 +199,7 @@ module {{moduleName}} type: 'api_key', in: {{#isKeyInHeader}}'header'{{/isKeyInHeader}}{{#isKeyInQuery}}'query'{{/isKeyInQuery}}, key: '{{keyParamName}}', - value: api_key_with_prefix('{{keyParamName}}') + value: api_key_with_prefix('{{name}}'{{#vendorExtensions.x-auth-id-alias}}, '{{.}}'{{/vendorExtensions.x-auth-id-alias}}) }, {{/isApiKey}} {{#isBasic}} @@ -245,12 +271,58 @@ module {{moduleName}} ] end + def operation_server_settings + { + {{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + {{#servers}} + {{#-first}} + "{{{classname}}}.{{{nickname}}}": [ + {{/-first}} + { + url: "{{{url}}}", + description: "{{{description}}}{{^description}}No description provided{{/description}}", + {{#variables}} + {{#-first}} + variables: { + {{/-first}} + {{{name}}}: { + description: "{{{description}}}{{^description}}No description provided{{/description}}", + default_value: "{{{defaultValue}}}", + {{#enumValues}} + {{#-first}} + enum_values: [ + {{/-first}} + "{{{.}}}"{{^-last}},{{/-last}} + {{#-last}} + ] + {{/-last}} + {{/enumValues}} + }{{^-last}},{{/-last}} + {{#-last}} + } + {{/-last}} + {{/variables}} + }{{^-last}},{{/-last}} + {{#-last}} + ], + {{/-last}} + {{/servers}} + {{/operation}} + {{/operations}} + {{/apis}} + {{/apiInfo}} + } + end + # Returns URL based on server settings # # @param index array index of the server settings # @param variables hash of variable and the corresponding value - def server_url(index, variables = {}) - servers = server_settings + def server_url(index, variables = {}, servers = nil) + servers = server_settings if servers == nil # check array index out of bound if (index < 0 || index >= servers.size) @@ -260,10 +332,12 @@ module {{moduleName}} server = servers[index] url = server[:url] + return url unless server.key? :variables + # go through variable and assign a value server[:variables].each do |name, variable| if variables.key?(name) - if (server[:variables][name][:enum_values].include? variables[name]) + if (!server[:variables][name].key?(:enum_values) || server[:variables][name][:enum_values].include?(variables[name])) url.gsub! "{" + name.to_s + "}", variables[name] else fail ArgumentError, "The variable `#{name}` in the server URL has invalid value #{variables[name]}. Must be #{server[:variables][name][:enum_values]}." @@ -276,5 +350,37 @@ module {{moduleName}} url end + + {{#isFaraday}} + # Adds middleware to the stack + def use(*middleware) + @middlewares << middleware + end + + # Adds request middleware to the stack + def request(*middleware) + @request_middlewares << middleware + end + + # Adds response middleware to the stack + def response(*middleware) + @response_middlewares << middleware + end + + # Set up middleware on the connection + def configure_middleware(connection) + @middlewares.each do |middleware| + connection.use(*middleware) + end + + @request_middlewares.each do |middleware| + connection.request(*middleware) + end + + @response_middlewares.each do |middleware| + connection.response(*middleware) + end + end + {{/isFaraday}} end end