Class: TrainPlugins::Rest::Connection

Inherits:
Train::Plugins::Transport::BaseConnection
  • Object
show all
Defined in:
lib/train-rest/connection.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Connection

Returns a new instance of Connection.



13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/train-rest/connection.rb', line 13

def initialize(options)
  super(options)

  # Plugin was called with an URI only
  options[:endpoint] = options[:target].sub("rest://", "https://") unless options[:endpoint]

  # Accept string (CLI) and boolean (API) options
  options[:verify_ssl] = options[:verify_ssl].to_s == "false" ? false : true

  setup_vcr

  connect
end

Instance Attribute Details

#auth_handlerObject

Raises:

  • (NameError)


173
174
175
176
177
178
# File 'lib/train-rest/connection.rb', line 173

def auth_handler
  desired_handler = auth_handler_classes.detect { |handler| handler.name == auth_type.to_s }
  raise NameError.new(format("Authentication handler %s not found", auth_type.to_s)) unless desired_handler

  @auth_handler ||= desired_handler.new(self)
end

#detected_os=(value) ⇒ Object (writeonly)

Allow overwriting to refine the type of REST API



66
67
68
# File 'lib/train-rest/connection.rb', line 66

def detected_os=(value)
  @detected_os = value
end

#optionsObject (readonly)

Returns the value of attribute options.



11
12
13
# File 'lib/train-rest/connection.rb', line 11

def options
  @options
end

#override_headersObject

Allow (programmatically) setting additional headers apart from global transport configuration



90
91
92
# File 'lib/train-rest/connection.rb', line 90

def override_headers
  @override_headers
end

Instance Method Details

#active_auth_handlerSymbol

Return active auth handler.

Returns:

  • (Symbol)


161
162
163
# File 'lib/train-rest/connection.rb', line 161

def active_auth_handler
  options[:auth_type]
end

#auth_parametersObject

Auth Handlers-faced API



169
170
171
# File 'lib/train-rest/connection.rb', line 169

def auth_parameters
  auth_handler.auth_parameters
end

#closeObject



55
56
57
# File 'lib/train-rest/connection.rb', line 55

def close
  logout if auth_handlers.include? auth_type
end

#connectObject



51
52
53
# File 'lib/train-rest/connection.rb', line 51

def connect
   if auth_handlers.include? auth_type
end

#inventoryObject Also known as: os



68
69
70
71
72
73
74
75
76
77
# File 'lib/train-rest/connection.rb', line 68

def inventory
  OpenStruct.new({
    name: @detected_os || "rest",
    release: TrainPlugins::Rest::VERSION,
    family_hierarchy: %w{rest api},
    family: "api",
    platform: "rest",
    platform_version: 0,
  })
end

#platformObject



81
82
83
84
85
# File 'lib/train-rest/connection.rb', line 81

def platform
  Train::Platforms.name("rest").in_family("api")

  force_platform!("rest", { release: TrainPlugins::Rest::VERSION })
end

#request(path, method = :get, request_parameters: {}, data: nil, headers: {}, json_processing: true) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/train-rest/connection.rb', line 98

def request(path, method = :get, request_parameters: {}, data: nil, headers: {}, json_processing: true)
  auth_handler.renew_session if auth_handler.renewal_needed?

  parameters = global_parameters.merge(request_parameters)

  parameters[:method] = method
  parameters[:url] = full_url(path)

  if json_processing
    parameters[:headers]["Accept"]       = "application/json"
    parameters[:headers]["Content-Type"] = "application/json"
    parameters[:payload] = JSON.generate(data) unless data.nil?
  else
    parameters[:payload] = data
  end

  # Merge override headers + request specific headers
  parameters[:headers].merge!(override_headers || {})
  parameters[:headers].merge!(headers)

  # Merge payload based headers (e.g. signature-based auth)
  if auth_handler.signature_based?
    auth_signature = auth_handler.process(
                          payload: data,
                          headers: parameters[:headers],
                          url: parameters[:url],
                          method: method
                        )

    parameters[:headers].merge! auth_signature[:headers]
  else
    parameters[:headers].merge! auth_parameters[:headers]
  end

  parameters.compact!

  logger.info format("[REST] => %s", parameters.to_s) if options[:debug_rest]
  response = RestClient::Request.execute(parameters)

  logger.info format("[REST] <= %s", response.to_s) if options[:debug_rest]
  transform_response(response, json_processing)

rescue RestClient::Exception => error
  auth_handler.process_error(error)
end

#setup_vcrObject



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/train-rest/connection.rb', line 27

def setup_vcr
  return unless options[:vcr_cassette]

  require "vcr" unless defined?(VCR)

  # TODO: Starts from "/" :(
  library = options[:vcr_library]
  match_on = options[:vcr_match_on].split.map(&:to_sym)

  VCR.configure do |config|
    config.cassette_library_dir = library
    config.hook_into options[:vcr_hook_into]
    config.default_cassette_options = {
      record: options[:vcr_record].to_sym,
      match_requests_on: match_on,
    }
  end

  VCR.insert_cassette options[:vcr_cassette]
rescue LoadError
  logger.fatal "Install the vcr gem to use HTTP(S) playback capability"
  raise
end

#switch_auth_handler(new_handler) ⇒ Object

Allow switching generic handlers for an API-specific one.

New handler needs to be loaded prior and be derived from TrainPlugins::REST::AuthHandler.



147
148
149
150
151
152
153
154
155
156
# File 'lib/train-rest/connection.rb', line 147

def switch_auth_handler(new_handler)
  return if active_auth_handler == new_handler

  logout

  options[:auth_type] = new_handler.to_sym
  @auth_handler = nil

  
end

#uriObject



59
60
61
62
63
# File 'lib/train-rest/connection.rb', line 59

def uri
  components = URI(options[:endpoint])
  components.scheme = "rest"
  components.to_s
end