Module: Angus::Remote::Response::Builder

Defined in:
lib/angus/remote/response/builder.rb

Class Method Summary collapse

Class Method Details

.apply_glossary(name, glossary_terms_hash) ⇒ Object

Searches for a short name in the glossary and returns the corresponding long name

If name is not a short name, returns the name

Parameters:

  • name (String)
  • glossary_terms_hash, (Hash<String, GlossaryTerm>)

    where keys are short names

Returns:

  • long name



162
163
164
165
166
167
168
# File 'lib/angus/remote/response/builder.rb', line 162

def self.apply_glossary(name, glossary_terms_hash)
  if glossary_terms_hash.include?(name)
    name = glossary_terms_hash[name].long_name
  end

  return name
end

.build(status_code, body, service_code_name, service_version, operation_namespace, operation_code_name) ⇒ Object

Builds a Response

The r parameter should contain in the body, encoded as json, the values / objects specified in the operation response metadata

Parameters:

  • status_code (Integer)

    HTTP status_code

  • body (String)

    HTTP body

  • service_code_name (String)

    Name of the service that the response belongs to

  • service_version (String)

    Version of the service that the response belongs to

  • operation_namespace (String)

    Namespace of the operation that the response belongs to

  • operation_name (String)

    Name of the operation that the response belongs to

Returns:

  • A Response object that responds to the methods:

    • status

    • messages

    Also, provides one method for each value / object / array returned



39
40
41
42
43
44
45
46
47
# File 'lib/angus/remote/response/builder.rb', line 39

def self.build(status_code, body, service_code_name, service_version, operation_namespace,
               operation_code_name)
  service_definition = Angus::Remote::ServiceDirectory.service_definition(
    service_code_name, service_version
  )

  self.build_from_definition(status_code, body, service_code_name, service_version,
                             service_definition, operation_namespace, operation_code_name)
end

.build_collection_from_representation(value_array, type, representations, glossary_terms_hash) ⇒ Object

Builds an array of objects that corresponds to the received type



267
268
269
270
271
272
273
274
275
276
277
# File 'lib/angus/remote/response/builder.rb', line 267

def self.build_collection_from_representation(value_array, type, representations,
                                              glossary_terms_hash)
  collection = []

  value_array.each do |raw_value|
    collection << build_from_representation(raw_value, type, representations,
                                            glossary_terms_hash)
  end

  collection
end

.build_from_definition(status_code, body, service_code_name, service_version, service_definition, operation_namespace, operation_code_name) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/angus/remote/response/builder.rb', line 49

def self.build_from_definition(status_code, body, service_code_name, service_version,
                               service_definition, operation_namespace, operation_code_name)
  representations = service_definition.representations
  glossary = service_definition.glossary

  operation_definition = service_definition.operation_definition(operation_namespace,
                                                                 operation_code_name)

  json_response = JSON(body)

  response_class = build_response_class(operation_definition.name)

  response = response_class.new

  # TODO use constants
  response[:status_code] = status_code
  response[:body] = body
  response[:service_code_name] = service_code_name
  response[:service_version] = service_version
  response[:operation_namespace] = operation_namespace
  response[:operation_code_name] = operation_code_name

  response.status = json_response['status']
  response.messages = self.build_messages(json_response['messages'])

  representations_hash = self.representations_hash(representations)
  glossary_terms_hash = glossary.terms_hash

  operation_definition.response_elements.each do |element|
    self.build_response_method(json_response, response_class, response,
                               representations_hash, glossary_terms_hash, element)
  end

  response
end

.build_from_remote_response(remote_response, service_code_name, version, operation_namespace, operation_code_name) ⇒ Object

Builds a Response based on a service’s response

The remote_response parameter should contain in the body, encoded as json, the values / objects specified in the operation response metadata.

Parameters:

  • remote_response (Http)

    HTTP response object, must respond to methods :body and :code

  • service_name (String)

    Name of the invoked service

  • version (String)

    Version of the invoked service

  • operation_namespace (String)

    Namespace of the invoked operation

  • operation_name (String)

    Name of the invoked operation



144
145
146
147
148
149
150
151
152
# File 'lib/angus/remote/response/builder.rb', line 144

def self.build_from_remote_response(remote_response, service_code_name, version,
                                    operation_namespace, operation_code_name)

  status_code = remote_response.code
  body = remote_response.body

  self.build(status_code, body, service_code_name, version, operation_namespace,
             operation_code_name)
end

.build_from_representation(hash_value, type, representations, glossary_terms_hash) ⇒ Object

Receives a hash, a type and an array of representations and build an object that has one method for each attribute of the type.



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/angus/remote/response/builder.rb', line 206

def self.build_from_representation(hash_value, type, representations, glossary_terms_hash)
  return nil if hash_value.nil?

  representation_class = Class.new do
    include Angus::Remote::Response::Hash
  end

  representation_object = representation_class.new

  if representations.include?(type)
    representation = representations[type]
    return nil if representation.nil?
    representation.fields.each do |field|
      field_raw_value = hash_value[field.name]
      field_value = nil
      unless field_raw_value.nil? && field.required == false
        if field.type && representations.include?(field.type)
          field_value = self.build_from_representation(field_raw_value, field.type,
                                                       representations,
                                                       glossary_terms_hash)
        elsif field.elements_type
          field_value = self.build_collection_from_representation(field_raw_value,
                                                                  field.elements_type,
                                                                  representations,
                                                                  glossary_terms_hash)
        elsif field.type && field.type.to_sym == :variable
          field_value = self.build_from_variable_fields(field_raw_value)
        elsif field.type
          field_value = Angus::Unmarshalling.unmarshal_scalar(field_raw_value,
                                                                field.type.to_sym)
        end
      end

      # Don't apply the glossary to response elements
      representation_object.elements[field.name] = field_value

      # Instead, apply the glossary to method names
      getter_method_name = self.apply_glossary(field.name, glossary_terms_hash)

      representation_class.send :define_method, field.name.to_sym do
        field_value
      end
    end
  else
    if type.to_sym == :variable
      representation_object = self.build_from_variable_fields(hash_value)
    else
      begin
        representation_object = Angus::Unmarshalling.unmarshal_scalar(hash_value,
                                                                        type.to_sym)
      rescue ArgumentError
        representation_object = nil
      end
    end
  end


  return representation_object
end

.build_from_variable_fields(variable_fields_hash) ⇒ Object

Builds an object from variable fields



280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/angus/remote/response/builder.rb', line 280

def self.build_from_variable_fields(variable_fields_hash)

  return nil if variable_fields_hash.nil?

  representation_class = Class.new do
    include Angus::Remote::Response::Hash
  end

  representation_object = representation_class.new

  variable_fields_hash.each do |key_name, field_value|
    representation_object.elements[key_name] = field_value
    representation_class.send :define_method, key_name.to_sym do
      field_value
    end
  end

  representation_object

end

.build_messages(messages) ⇒ Object

Receives an array of messages and returns an array of Message objects



191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/angus/remote/response/builder.rb', line 191

def self.build_messages(messages)
  messages ||= []

  messages.map do |m|
    message = Angus::Remote::Message.new
    message.description = m['dsc']
    message.key = m['key']
    message.level = m['level']

    message
  end
end

.build_response_class(operation_name) ⇒ Class

Build a response class for the operation

Parameters:

  • operation_name (String)

    the name of the operation

Returns:



175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/angus/remote/response/builder.rb', line 175

def self.build_response_class(operation_name)
  response_class = Class.new(Angus::Remote::RemoteResponse)
  response_class.class_eval <<-END
    def self.name
      "#<Response_#{operation_name.gsub(' ', '_')}>"
    end

    def self.to_s
      name
    end
  END

  response_class
end

.build_response_method(json_response, response_class, response, representations_hash, glossary_terms_hash, element) ⇒ Object

Builds the methods for each value / object / array

The r parameter should contain in the body, encoded as json, the values / objects specified in the operation response metadata



89
90
91
92
93
94
95
96
97
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
# File 'lib/angus/remote/response/builder.rb', line 89

def self.build_response_method(json_response, response_class, response,
                               representations_hash, glossary_terms_hash, element)
  if (json_response.has_key?(element.name))
    hash_value = json_response[element.name]
  elsif (element.required == false)
    hash_value = element.default
  else
    return
  end

  object_value = nil

  if element.type && representations_hash.include?(element.type)
    object_value = self.build_from_representation(hash_value, element.type,
                                                  representations_hash, glossary_terms_hash)
  elsif element.elements_type
    object_value = self.build_collection_from_representation(hash_value,
                                                             element.elements_type,
                                                             representations_hash,
                                                             glossary_terms_hash)
  elsif element.type && element.type.to_sym == :variable
    object_value = self.build_from_variable_fields(hash_value)
  elsif element.type
    begin
      object_value = Angus::Unmarshalling.unmarshal_scalar(hash_value,
                                                             element.type.to_sym)
    rescue ArgumentError
      object_value = nil
    end
  end

  # Don't apply the glossary to response elements
  response.elements[element.name] = object_value

  # Instead, apply the glossary to method names
  getter_method_name = self.apply_glossary(element.name, glossary_terms_hash)

  response_class.send :define_method, getter_method_name do
    object_value
  end
end

.representations_hash(representations) ⇒ Object

Receives an array of representations and returns a hash of representations where the keys are the representation’s names and the values are the representations



303
304
305
306
307
308
309
# File 'lib/angus/remote/response/builder.rb', line 303

def self.representations_hash(representations)
  hash = {}
  representations.each do |representation|
    hash[representation.name] = representation
  end
  hash
end