class Bosh::Cpi::Cli
Constants
- INVALID_CALL_ERROR_TYPE
- KNOWN_RPC_METHODS
- RPC_METHOD_TO_RUBY_METHOD
- UNKNOWN_ERROR_TYPE
Public Class Methods
new(cpi, logs_string_io, result_io)
click to toggle source
# File lib/bosh/cpi/cli.rb, line 38 def initialize(cpi, logs_string_io, result_io) @cpi = cpi @logs_string_io = logs_string_io @result_io = result_io @logger = Bosh::Cpi::Logger.new(STDERR) end
Public Instance Methods
run(json)
click to toggle source
# File lib/bosh/cpi/cli.rb, line 45 def run(json) begin request = JSON.load(json) rescue JSON::ParserError => e return error_response(INVALID_CALL_ERROR_TYPE, "Request cannot be deserialized, details: #{e.message}", false, e.backtrace) end method = request['method'] unless method.is_a?(String) return error_response(INVALID_CALL_ERROR_TYPE, "Method must be a String, got: '#{method.inspect}'", false) end unless KNOWN_RPC_METHODS.include?(method) return error_response(Bosh::Clouds::NotImplemented.name, "Method is not known, got: '#{method}'", false) end arguments = request['arguments'] unless arguments.is_a?(Array) return error_response(INVALID_CALL_ERROR_TYPE, "Arguments must be an Array", false) end context = request['context'] unless context.is_a?(Hash) && context['director_uuid'].is_a?(String) return error_response(INVALID_CALL_ERROR_TYPE, "Request should include context with director uuid", false) end req_id = context['request_id'] @logger.set_request_id(req_id) configure_director(context['director_uuid']) ruby_method = RPC_METHOD_TO_RUBY_METHOD[method] || method begin start_time = Time.now.utc @logger.info("Starting #{method}...") cpi = @cpi.call(context) result = cpi.public_send(ruby_method, *arguments) rescue Bosh::Clouds::RetriableCloudError => e return error_response(error_name(e), e.message, e.ok_to_retry, e.backtrace) rescue Bosh::Clouds::CloudError, Bosh::Clouds::CpiError => e return error_response(error_name(e), e.message, false, e.backtrace) rescue ArgumentError => e return error_response(INVALID_CALL_ERROR_TYPE, "Arguments are not correct, details: '#{e.message}'", false, e.backtrace) rescue Exception => e return error_response(UNKNOWN_ERROR_TYPE, e.message, false, e.backtrace) ensure end_time = Time.now.utc @logger.info("Finished #{method} in #{(end_time - start_time).round(2)} seconds") end result_response(result) end
Private Instance Methods
configure_director(director_uuid)
click to toggle source
# File lib/bosh/cpi/cli.rb, line 103 def configure_director(director_uuid) Bosh::Clouds::Config.uuid = director_uuid end
encode_string_as_utf8(src)
click to toggle source
# File lib/bosh/cpi/cli.rb, line 137 def encode_string_as_utf8(src) log = @logs_string_io.string.force_encoding(Encoding::UTF_8) unless log.valid_encoding? # the src encoding hint of Encoding::BINARY is only required for ruby 1.9.3 log = @logs_string_io.string.encode(Encoding::UTF_8, Encoding::BINARY, undef: :replace, invalid: :replace) end log end
error_name(error)
click to toggle source
# File lib/bosh/cpi/cli.rb, line 133 def error_name(error) error.class.name end
error_response(type, message, ok_to_retry, bt=[])
click to toggle source
# File lib/bosh/cpi/cli.rb, line 107 def error_response(type, message, ok_to_retry, bt=[]) if !bt.empty? @logs_string_io.print("Rescued #{type}: #{message}. backtrace: #{bt.join("\n")}") end hash = { result: nil, error: { type: type, message: message, ok_to_retry: ok_to_retry, }, log: encode_string_as_utf8(@logs_string_io.string) } @result_io.print(JSON.dump(hash)); nil end
result_response(result)
click to toggle source
# File lib/bosh/cpi/cli.rb, line 124 def result_response(result) hash = { result: result, error: nil, log: encode_string_as_utf8(@logs_string_io.string) } @result_io.print(JSON.dump(hash)); nil end