Class: ServiceAPI

Inherits:
Object
  • Object
show all
Defined in:
lib/ServiceAPI.rb

Instance Method Summary collapse

Instance Method Details

#add_param(params, param) ⇒ Object


Convenience method to build a string of HTTP query parameters.



65
66
67
68
69
70
71
72
73
# File 'lib/ServiceAPI.rb', line 65

def add_param(params, param)
  if (param == nil || param.length() == 0)
    return params
  end
  if (params == nil || params.length() == 0)
    return "?#{param}"
  end
  return "#{params}&#{param}"
end

#do_request_by_service(req, state, service) ⇒ Object


Utility function to perform HTTP request. This is the method API subclasses should usually invoke when Discovery is available. It will connect to a service of the given type. It will log output and return a Result object.



148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/ServiceAPI.rb', line 148

def do_request_by_service(req, state, service)
  service_list = state.get('service_list')
  if (service_list == nil)
    return Result.fatal_error("service_list not available in state!")
  end

  if (service_list[service] == nil)
    return Result.fatal_error("No service of type #{service} available!")
  end

  url = service_list[service][0]
  return do_request_by_url(req, state, url)
end

#do_request_by_url(req, state, url) ⇒ Object


Utility function to perform HTTP request. API subclasses can invoke this to connect to a specific host/port. It will log output and return a Result object.



167
168
169
170
171
172
173
174
175
176
# File 'lib/ServiceAPI.rb', line 167

def do_request_by_url(req, state, url)
  show_req(req)
  response = get_http_response(req, state, url)
  show_response(response)

  state.set_in_test('http_code', response.code)
  result = Result.new(response)

  return result
end

#get_http_response(req, state, url) ⇒ Object


Utility function to perform raw HTTP request.

If url is not provided, will attempt to use generic ‘server’ and ‘server_port’ values from state.



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
# File 'lib/ServiceAPI.rb', line 110

def get_http_response(req, state, url)

  # TODO: SSL support

  auth = state.get('auth')
  if (auth == "basic")
    user = state.get('auth_user')
    password = state.get('auth_password')
    req.basic_auth(user, password)
  end

  if (url == nil)
    server = state.get('server')
    port = state.get('server_port')
    die("no server specified") if (server == nil)
    die("no server port specified") if (port == nil)
    url = "http://#{server}:#{port}"
  end

  begin
    urlobj = URI.parse(url)
    http = Net::HTTP.new(urlobj.host, urlobj.port)
    out(1, "Connecting to: #{urlobj.to_s}")
    response = http.request(req)

  rescue Exception => e
    return Result.fatal_error("Failure connecting to server #{server}: #{e.to_s}")
  end

  return response
end

#need(symbol, state) ⇒ Object


Returns a string which can be eval’d to set a variable or return an error.

A very common pattern in service module methods is to attempt to get a value from state or return a fatal error Result if it is missing. This convenience method allows reducing the code segment:

xyz = state.get('xyz')
if (xyz == nil)
  return Result.fatal_error("xyz required")
end

to this:

xyz = ""; eval(need :xyz, state)

(If only ruby has LISP macros, this could be so much cleaner…)



29
30
31
32
33
34
35
# File 'lib/ServiceAPI.rb', line 29

def need(symbol, state)
  x = state.get(symbol.to_s)
  if (x == nil)
    return "return Result.fatal_error(\"#{symbol.to_s} required\")"
  end
  return "#{symbol.to_s} = state.get('#{symbol.to_s}')"
end

#show_req(request) ⇒ Object


Show details about request being sent.



78
79
80
81
82
83
84
85
86
87
88
# File 'lib/ServiceAPI.rb', line 78

def show_req(request)
  if ($LOG_LEVEL >= 2)
    puts "---[ Request ]----------------------------------------------------"
    puts "#{request.method} #{request.path}"
    request.each_header { |name,value|
      puts "#{name}: #{value}"
    }
    puts "\n#{request.body}\n"
    puts "------------------------------------------------------------------"
  end
end

#show_response(response) ⇒ Object


Show details about response received.



93
94
95
96
97
98
99
100
101
102
103
# File 'lib/ServiceAPI.rb', line 93

def show_response(response)
  if ($LOG_LEVEL >= 2)
    puts "---[ Response ]---------------------------------------------------"
    puts "#{response.code} #{response.message}"
    response.each_header { |name,value|
      puts "#{name}: #{value}"
    }
    puts "\n#{response.body}\n"
    puts "------------------------------------------------------------------"
  end
end

#uuidObject


Generate a random UUID.

Attempts a few different ways, hopefully one of them work. If all fails, die.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/ServiceAPI.rb', line 42

def uuid
  begin
    require 'securerandom'
    uuid = SecureRandom.uuid()

  rescue Exception => e
    if (File.exist?("/usr/bin/uuidgen")) # Centos e2fsprogs package
      uuid = `/usr/bin/uuidgen`
      return uuid.chomp

    elsif (File.exist?("/usr/bin/uuid")) # Debian uuid package
      uuid = `/usr/bin/uuid`
      return uuid.chomp

    else
      die("Unable to generate UUIDs")
    end
  end
end