Class: TungstenAPI::APICall

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

Overview

This class defines an API call, as needed by the Tungsten Manager API. Up to a ppint, the class is fairly generic, as it defines how to create a URI with three to four segments.

An APICall instance can run a ‘get’ or a ‘post’ call.

Class methods:

  • set_api_root : defines which string is the root of the URI (default: ‘manager’)

  • set_return_on_call_fail: defines how we fail when a call does not succeed. You can set either :hash (default) or :raise. When :hash is defined, get and post always return a hash containing ‘message’ and ‘httpStatus’. If :raise is chosen then all call failures will raise an exception

  • header : used to display the list of API calls

  • dashes : used to draw dashes below the header. (internally used by TungstenDataserviceManager::list)

Public instance methods:

* initialize (name, prefix, command, help, return_structure = :hash, type = :get)
* description (display_mode ={:text|:hash:json} ) shows the API structure
* make_uri (api_server, service) : creates a well formed URI, ready to submit
* get (api_server, service) : returns the result of a 'get' call
* post (api_server, service) : returns the result of a 'post' operation

Direct Known Subclasses

ReplicatorAPICall

Constant Summary collapse

@@return_on_call_fail =

By default, a call using this class will return a hash You can change this behavior by setting the fail type to :raise instead

:hash
@@api_root =
'manager'
@@template =

This template is used to display a quick help about the API call

"%-15s %-4s %-10s %-10s %s"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, prefix, command, help, return_structure = :hash, type = :get, ignore_service = false) ⇒ APICall

Initialize the object.

  • name : how we call the API, even informally. This name is not used operationally

  • prefix: the portion of the call that needs to be inserted before the service name

  • command: what the api call responds to. For some calls, this part can be empty

  • type: either :get or :post

  • return_structure: so far, only :hash is supported

  • help: a brief description of what the API does



85
86
87
88
89
90
91
92
93
94
# File 'lib/tungsten/api.rb', line 85

def initialize(name, prefix, command, help, return_structure = :hash, type = :get, ignore_service=false)
    @name = name    
    @prefix = prefix
    @command = command
    @type = type  # type can be :get, :post, :cmd
    @returns = return_structure
    @help = help
    @ignore_service = ignore_service
    # TODO : add expected structure
end

Instance Attribute Details

#commandObject

Returns the value of attribute command.



56
57
58
# File 'lib/tungsten/api.rb', line 56

def command
  @command
end

#nameObject

Returns the value of attribute name.



56
57
58
# File 'lib/tungsten/api.rb', line 56

def name
  @name
end

#prefixObject

Returns the value of attribute prefix.



56
57
58
# File 'lib/tungsten/api.rb', line 56

def prefix
  @prefix
end

#return_structureObject

Returns the value of attribute return_structure.



56
57
58
# File 'lib/tungsten/api.rb', line 56

def return_structure
  @return_structure
end

#typeObject

Returns the value of attribute type.



56
57
58
# File 'lib/tungsten/api.rb', line 56

def type
  @type
end

Class Method Details

.dashesObject

returns a set of dashes to ptint below the header



144
145
146
# File 'lib/tungsten/api.rb', line 144

def self.dashes ()
    return sprintf(@@template , '----', '----', '------', '-------' , '----')
end

.headerObject

returns a header for the API call fields



137
138
139
# File 'lib/tungsten/api.rb', line 137

def self.header ()
    return sprintf(@@template , 'name', 'type', 'prefix', 'command' , 'help')
end

.set_api_root(api_root) ⇒ Object

Defines the default API root in the URI. Currently it is ‘manager’



130
131
132
# File 'lib/tungsten/api.rb', line 130

def self.set_api_root(api_root)
    @@api_root = api_root
end

.set_return_on_call_fail(return_on_call_fail) ⇒ Object

Class method. Defines how we behave in case of call failure By default, we ALWAYS return a :hash. We can also :raise an exception



122
123
124
# File 'lib/tungsten/api.rb', line 122

def self.set_return_on_call_fail(return_on_call_fail)
    @@return_on_call_fail = return_on_call_fail
end

Instance Method Details

#description(display_mode = :text) ⇒ Object

Returns a description of the API call, according to the display_mode:

  • :text (default) is a single line of text according to @@template

  • :hash is a Ruby hash of the API call contents

  • :json is a JSON representation of the above hash



168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/tungsten/api.rb', line 168

def description (display_mode = :text)
    if display_mode == :text
        return self.to_s
    end
    if display_mode == :json
        return JSON.generate(self.to_hash)
    elsif display_mode == :hash
        return self.to_hash
    else
        raise SyntaxError, "No suitable display mode selected"
    end
end

#evaluate_response(api_server, response) ⇒ Object

Used internally by the calls to get and post to determine if the response was successful



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/tungsten/api.rb', line 184

def evaluate_response (api_server, response)
    if response.body
        hash_from_json = JSON.parse(response.body)
    end
    
    unless hash_from_json
      raise "Unable to parse API response from #{api_server}"
    end
    
    if TU.log_cmd_results?()
      TU.debug("Result: #{JSON.pretty_generate(hash_from_json)}")
    end
    
    if hash_from_json && hash_from_json["returnMessage"] && hash_from_json["returnCode"] && hash_from_json["returnCode"] != '200'
        return_object = {
            "httpStatus"    => hash_from_json["returnCode"],
            "message"       => hash_from_json["returnMessage"]
        } 
        if @@return_on_call_fail == :raise
            raise RuntimeError, "There was an error (#{hash_from_json["returnCode"]}) : #{hash_from_json["returnMessage"]}"
        end
        return return_object
    end
 
    if response.code != '200'
        if @@return_on_call_fail == :raise
            raise RuntimeError, "The request returned code #{response.code}"
        else
            return_object = {
                "httpStatus"    => response.code,
                "message"       => "unidentified error with code #{response.code}"
            } 
            return return_object
        end
    end
    return hash_from_json
end

#from_hash(hash) ⇒ Object



96
97
98
99
100
101
102
103
104
# File 'lib/tungsten/api.rb', line 96

def from_hash (hash)
    @name = hash[name]
    @prefix = hash[prefix]
    @command = hash[command]
    @type = hash[type]  # type can be :get, :post, :cmd
    @returns = hash[return_structure]
    @help = hash[help]
    self 
end

#get(api_server, service) ⇒ Object

Runs a ‘get’ call, using a given api_server and service name



225
226
227
228
229
230
231
# File 'lib/tungsten/api.rb', line 225

def get(api_server, service)
    api_uri = URI(self.make_uri(api_server,service))
    puts  "GET #{api_uri}" if ENV["SHOW_INTERNALS"]
    TU.debug("GET #{api_uri}")
    response = Net::HTTP.get_response(api_uri)
    return evaluate_response(api_server,response)
end

#make_uri(api_server, service) ⇒ Object

Creates a well formed URI, ready to be used



109
110
111
112
113
114
115
# File 'lib/tungsten/api.rb', line 109

def make_uri(api_server, service)
    if (service && ! @ignore_service)
        return "http://#{api_server}/#{@@api_root}/#{@prefix}/#{service}/#{@command}" 
    else
        return "http://#{api_server}/#{@@api_root}/#{@command}" 
    end
end

#post(api_server, service, post_params = {}) ⇒ Object

Runs a ‘post’ call, using a given api_server and service name



236
237
238
239
240
241
242
# File 'lib/tungsten/api.rb', line 236

def post(api_server, service, post_params = {})
    api_uri = URI(self.make_uri(api_server,service))
    puts  "POST #{api_uri}" if ENV["SHOW_INTERNALS"]
    TU.debug("POST #{api_uri}")
    response = Net::HTTP.post_form(api_uri, post_params)
    return evaluate_response(api_server,response)
end

#to_hashObject



152
153
154
155
156
157
158
159
160
# File 'lib/tungsten/api.rb', line 152

def to_hash
    { 
        :name.to_s => @name, 
        :type.to_s => @type, 
        :prefix.to_s => @prefix, 
        :command.to_s => @command, 
        :help.to_s => @help 
    }
end

#to_sObject



148
149
150
# File 'lib/tungsten/api.rb', line 148

def to_s
    return sprintf(@@template , @name, @type, @prefix, @command , @help)
end