ovirt-engine-sdk 4.1.5 → 4.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright (c) 2015-2016 Red Hat, Inc.
2
+ Copyright (c) 2015-2017 Red Hat, Inc.
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -17,10 +17,27 @@ limitations under the License.
17
17
  #ifndef __OV_XML_READER_H__
18
18
  #define __OV_XML_READER_H__
19
19
 
20
- // Classes:
20
+ #include <ruby.h>
21
+
22
+ #include <libxml/xmlreader.h>
23
+ #include <stdbool.h>
24
+
25
+ /* Data type and class: */
26
+ extern rb_data_type_t ov_xml_reader_type;
21
27
  extern VALUE ov_xml_reader_class;
22
28
 
23
- // Initialization function:
29
+ /* Content: */
30
+ typedef struct {
31
+ VALUE io;
32
+ xmlTextReaderPtr reader;
33
+ bool closed;
34
+ } ov_xml_reader_object;
35
+
36
+ /* Macro to get the pointer: */
37
+ #define ov_xml_reader_ptr(object, ptr) \
38
+ TypedData_Get_Struct((object), ov_xml_reader_object, &ov_xml_reader_type, (ptr))
39
+
40
+ /* Initialization function: */
24
41
  extern void ov_xml_reader_define(void);
25
42
 
26
43
  #endif
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright (c) 2015-2016 Red Hat, Inc.
2
+ Copyright (c) 2015-2017 Red Hat, Inc.
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@ limitations under the License.
16
16
 
17
17
  #include <ruby.h>
18
18
 
19
- #include <stdbool.h>
20
19
  #include <libxml/xmlwriter.h>
21
20
 
22
21
  #include "ov_module.h"
@@ -31,57 +30,76 @@ static ID STRING_ID;
31
30
  static ID STRING_IO_ID;
32
31
  static ID WRITE_ID;
33
32
 
34
- typedef struct {
35
- VALUE io;
36
- xmlTextWriterPtr writer;
37
- } ov_xml_writer_object;
38
-
39
- static void ov_xml_writer_check_closed(ov_xml_writer_object* object) {
40
- if (object->writer == NULL) {
33
+ static void ov_xml_writer_check_closed(ov_xml_writer_object* ptr) {
34
+ if (ptr->writer == NULL) {
41
35
  rb_raise(ov_error_class, "The writer is already closed");
42
36
  }
43
37
  }
44
38
 
45
- static void ov_xml_writer_mark(ov_xml_writer_object *object) {
46
- /* Mark the IO object as reachable: */
47
- if (!NIL_P(object->io)) {
48
- rb_gc_mark(object->io);
49
- }
39
+ static void ov_xml_writer_mark(void* vptr) {
40
+ ov_xml_writer_object* ptr;
41
+
42
+ ptr = vptr;
43
+ rb_gc_mark(ptr->io);
50
44
  }
51
45
 
52
- static void ov_xml_writer_free(ov_xml_writer_object *object) {
46
+ static void ov_xml_writer_free(void* vptr) {
47
+ ov_xml_writer_object* ptr;
48
+
49
+ /* Get the pointer: */
50
+ ptr = vptr;
51
+
53
52
  /* Free the libxml writer, the buffer is automatically closed: */
54
- if (object->writer != NULL) {
55
- xmlTextWriterPtr tmp = object->writer;
56
- object->writer = NULL;
53
+ if (ptr->writer != NULL) {
54
+ xmlTextWriterPtr tmp = ptr->writer;
55
+ ptr->writer = NULL;
57
56
  xmlFreeTextWriter(tmp);
58
57
  }
59
58
 
60
59
  /* Free this object: */
61
- xfree(object);
60
+ xfree(ptr);
62
61
  }
63
62
 
63
+ rb_data_type_t ov_xml_writer_type = {
64
+ .wrap_struct_name = "OVXMLWRITER",
65
+ .function = {
66
+ .dmark = ov_xml_writer_mark,
67
+ .dfree = ov_xml_writer_free,
68
+ .dsize = NULL,
69
+ .reserved = { NULL, NULL }
70
+ },
71
+ #ifdef RUBY_TYPED_FREE_IMMEDIATELY
72
+ .parent = NULL,
73
+ .data = NULL,
74
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
75
+ #endif
76
+ };
77
+
64
78
  static VALUE ov_xml_writer_alloc(VALUE klass) {
65
- ov_xml_writer_object* object = NULL;
79
+ ov_xml_writer_object* ptr;
66
80
 
67
- object = ALLOC(ov_xml_writer_object);
68
- memset(object, 0, sizeof(ov_xml_writer_object));
69
- return Data_Wrap_Struct(klass, ov_xml_writer_mark, ov_xml_writer_free, object);
81
+ ptr = ALLOC(ov_xml_writer_object);
82
+ ptr->io = Qnil;
83
+ ptr->writer = NULL;
84
+ return TypedData_Wrap_Struct(klass, &ov_xml_writer_type, ptr);
70
85
  }
71
86
 
72
87
  static int ov_xml_writer_callback(void *context, const char *buffer, int length) {
73
88
  VALUE count;
74
89
  VALUE data;
75
- ov_xml_writer_object *object = (ov_xml_writer_object*) context;
90
+ ov_xml_writer_object* ptr;
91
+
92
+ /* Get the pointer: */
93
+ ptr = context;
76
94
 
77
95
  /* Do nothing if the writer is already closed: */
78
- if (object->writer == NULL) {
96
+ if (ptr->writer == NULL) {
79
97
  return 0;
80
98
  }
81
99
 
82
100
  /* Convert the buffer to a Ruby string and write it to the IO object, using the "write" method: */
83
101
  data = rb_str_new(buffer, length);
84
- count = rb_funcall(object->io, WRITE_ID, 1, data);
102
+ count = rb_funcall(ptr->io, WRITE_ID, 1, data);
85
103
 
86
104
  return NUM2INT(count);
87
105
  }
@@ -99,11 +117,11 @@ static VALUE ov_xml_writer_initialize(int argc, VALUE* argv, VALUE self) {
99
117
  VALUE indent;
100
118
  VALUE io;
101
119
  VALUE io_class;
102
- ov_xml_writer_object* object = NULL;
103
- xmlOutputBufferPtr buffer = NULL;
120
+ ov_xml_writer_object* ptr;
121
+ xmlOutputBufferPtr buffer;
104
122
 
105
123
  /* Get the pointer to the object: */
106
- Data_Get_Struct(self, ov_xml_writer_object, object);
124
+ ov_xml_writer_ptr(self, ptr);
107
125
 
108
126
  /* Get the values of the parameters: */
109
127
  if (argc > 2) {
@@ -115,12 +133,12 @@ static VALUE ov_xml_writer_initialize(int argc, VALUE* argv, VALUE self) {
115
133
  /* The first parameter can be an IO object or nil. If it is nil then we need to create a IO object where we can
116
134
  write the generated XML. */
117
135
  if (NIL_P(io)) {
118
- object->io = ov_xml_writer_create_string_io();
136
+ ptr->io = ov_xml_writer_create_string_io();
119
137
  }
120
138
  else {
121
139
  io_class = rb_class_of(io);
122
140
  if (io_class == rb_cIO) {
123
- object->io = io;
141
+ ptr->io = io;
124
142
  }
125
143
  else {
126
144
  rb_raise(
@@ -132,50 +150,50 @@ static VALUE ov_xml_writer_initialize(int argc, VALUE* argv, VALUE self) {
132
150
  }
133
151
 
134
152
  /* Create the libxml buffer that writes to the IO object: */
135
- buffer = xmlOutputBufferCreateIO(ov_xml_writer_callback, NULL, object, NULL);
153
+ buffer = xmlOutputBufferCreateIO(ov_xml_writer_callback, NULL, ptr, NULL);
136
154
  if (buffer == NULL) {
137
155
  rb_raise(ov_error_class, "Can't create XML buffer");
138
156
  }
139
157
 
140
158
  /* Create the libxml writer: */
141
- object->writer = xmlNewTextWriter(buffer);
142
- if (object->writer == NULL) {
159
+ ptr->writer = xmlNewTextWriter(buffer);
160
+ if (ptr->writer == NULL) {
143
161
  xmlOutputBufferClose(buffer);
144
162
  rb_raise(ov_error_class, "Can't create XML writer");
145
163
  }
146
164
 
147
165
  /* Enable indentation: */
148
166
  if (RTEST(indent)) {
149
- xmlTextWriterSetIndent(object->writer, 1);
150
- xmlTextWriterSetIndentString(object->writer, BAD_CAST " ");
167
+ xmlTextWriterSetIndent(ptr->writer, 1);
168
+ xmlTextWriterSetIndentString(ptr->writer, BAD_CAST " ");
151
169
  }
152
170
 
153
171
  return self;
154
172
  }
155
173
 
156
174
  static VALUE ov_xml_writer_string(VALUE self) {
157
- int rc = 0;
158
- ov_xml_writer_object* object = NULL;
175
+ int rc;
176
+ ov_xml_writer_object* ptr;
159
177
 
160
- Data_Get_Struct(self, ov_xml_writer_object, object);
161
- ov_xml_writer_check_closed(object);
162
- rc = xmlTextWriterFlush(object->writer);
178
+ ov_xml_writer_ptr(self, ptr);
179
+ ov_xml_writer_check_closed(ptr);
180
+ rc = xmlTextWriterFlush(ptr->writer);
163
181
  if (rc < 0) {
164
182
  rb_raise(ov_error_class, "Can't flush XML writer");
165
183
  }
166
- return rb_funcall(object->io, STRING_ID, 0, NULL);
184
+ return rb_funcall(ptr->io, STRING_ID, 0, NULL);
167
185
  }
168
186
 
169
187
  static VALUE ov_xml_writer_write_start(VALUE self, VALUE name) {
170
- char* c_name = NULL;
171
- int rc = 0;
172
- ov_xml_writer_object* object = NULL;
188
+ char* c_name;
189
+ int rc;
190
+ ov_xml_writer_object* ptr;
173
191
 
174
- Data_Get_Struct(self, ov_xml_writer_object, object);
175
- ov_xml_writer_check_closed(object);
192
+ ov_xml_writer_ptr(self, ptr);
193
+ ov_xml_writer_check_closed(ptr);
176
194
  Check_Type(name, T_STRING);
177
195
  c_name = StringValueCStr(name);
178
- rc = xmlTextWriterStartElement(object->writer, BAD_CAST c_name);
196
+ rc = xmlTextWriterStartElement(ptr->writer, BAD_CAST c_name);
179
197
  if (rc < 0) {
180
198
  rb_raise(ov_error_class, "Can't start XML element");
181
199
  }
@@ -183,12 +201,12 @@ static VALUE ov_xml_writer_write_start(VALUE self, VALUE name) {
183
201
  }
184
202
 
185
203
  static VALUE ov_xml_writer_write_end(VALUE self) {
186
- int rc = 0;
187
- ov_xml_writer_object* object = NULL;
204
+ int rc;
205
+ ov_xml_writer_object* ptr;
188
206
 
189
- Data_Get_Struct(self, ov_xml_writer_object, object);
190
- ov_xml_writer_check_closed(object);
191
- rc = xmlTextWriterEndElement(object->writer);
207
+ ov_xml_writer_ptr(self, ptr);
208
+ ov_xml_writer_check_closed(ptr);
209
+ rc = xmlTextWriterEndElement(ptr->writer);
192
210
  if (rc < 0) {
193
211
  rb_raise(ov_error_class, "Can't end XML element");
194
212
  }
@@ -196,18 +214,18 @@ static VALUE ov_xml_writer_write_end(VALUE self) {
196
214
  }
197
215
 
198
216
  static VALUE ov_xml_writer_write_attribute(VALUE self, VALUE name, VALUE value) {
199
- char* c_name = NULL;
200
- char* c_value = NULL;
201
- int rc = 0;
202
- ov_xml_writer_object* object = NULL;
217
+ char* c_name;
218
+ char* c_value;
219
+ int rc;
220
+ ov_xml_writer_object* ptr;
203
221
 
204
- Data_Get_Struct(self, ov_xml_writer_object, object);
205
- ov_xml_writer_check_closed(object);
222
+ ov_xml_writer_ptr(self, ptr);
223
+ ov_xml_writer_check_closed(ptr);
206
224
  Check_Type(name, T_STRING);
207
225
  Check_Type(value, T_STRING);
208
226
  c_name = StringValueCStr(name);
209
227
  c_value = StringValueCStr(value);
210
- rc = xmlTextWriterWriteAttribute(object->writer, BAD_CAST c_name, BAD_CAST c_value);
228
+ rc = xmlTextWriterWriteAttribute(ptr->writer, BAD_CAST c_name, BAD_CAST c_value);
211
229
  if (rc < 0) {
212
230
  rb_raise(ov_error_class, "Can't write attribute with name \"%s\" and value \"%s\"", c_name, c_value);
213
231
  }
@@ -215,18 +233,18 @@ static VALUE ov_xml_writer_write_attribute(VALUE self, VALUE name, VALUE value)
215
233
  }
216
234
 
217
235
  static VALUE ov_xml_writer_write_element(VALUE self, VALUE name, VALUE value) {
218
- char* c_name = NULL;
219
- char* c_value = NULL;
220
- int rc = 0;
221
- ov_xml_writer_object* object = NULL;
236
+ char* c_name;
237
+ char* c_value;
238
+ int rc;
239
+ ov_xml_writer_object* ptr;
222
240
 
223
- Data_Get_Struct(self, ov_xml_writer_object, object);
224
- ov_xml_writer_check_closed(object);
241
+ ov_xml_writer_ptr(self, ptr);
242
+ ov_xml_writer_check_closed(ptr);
225
243
  Check_Type(name, T_STRING);
226
244
  Check_Type(value, T_STRING);
227
245
  c_name = StringValueCStr(name);
228
246
  c_value = StringValueCStr(value);
229
- rc = xmlTextWriterWriteElement(object->writer, BAD_CAST c_name, BAD_CAST c_value);
247
+ rc = xmlTextWriterWriteElement(ptr->writer, BAD_CAST c_name, BAD_CAST c_value);
230
248
  if (rc < 0) {
231
249
  rb_raise(ov_error_class, "Can't write element with name \"%s\" and value \"%s\"", c_name, c_value);
232
250
  }
@@ -234,12 +252,12 @@ static VALUE ov_xml_writer_write_element(VALUE self, VALUE name, VALUE value) {
234
252
  }
235
253
 
236
254
  static VALUE ov_xml_writer_flush(VALUE self) {
237
- ov_xml_writer_object* object = NULL;
238
- int rc = 0;
255
+ int rc;
256
+ ov_xml_writer_object* ptr;
239
257
 
240
- Data_Get_Struct(self, ov_xml_writer_object, object);
241
- ov_xml_writer_check_closed(object);
242
- rc = xmlTextWriterFlush(object->writer);
258
+ ov_xml_writer_ptr(self, ptr);
259
+ ov_xml_writer_check_closed(ptr);
260
+ rc = xmlTextWriterFlush(ptr->writer);
243
261
  if (rc < 0) {
244
262
  rb_raise(ov_error_class, "Can't flush XML writer");
245
263
  }
@@ -247,12 +265,12 @@ static VALUE ov_xml_writer_flush(VALUE self) {
247
265
  }
248
266
 
249
267
  static VALUE ov_xml_writer_close(VALUE self) {
250
- ov_xml_writer_object* object = NULL;
268
+ ov_xml_writer_object* ptr;
251
269
 
252
- Data_Get_Struct(self, ov_xml_writer_object, object);
253
- ov_xml_writer_check_closed(object);
254
- xmlFreeTextWriter(object->writer);
255
- object->writer = NULL;
270
+ ov_xml_writer_ptr(self, ptr);
271
+ ov_xml_writer_check_closed(ptr);
272
+ xmlFreeTextWriter(ptr->writer);
273
+ ptr->writer = NULL;
256
274
  return Qnil;
257
275
  }
258
276
 
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright (c) 2015-2016 Red Hat, Inc.
2
+ Copyright (c) 2015-2017 Red Hat, Inc.
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -17,10 +17,25 @@ limitations under the License.
17
17
  #ifndef __OV_XML_WRITER_H__
18
18
  #define __OV_XML_WRITER_H__
19
19
 
20
- // Classes:
20
+ #include <ruby.h>
21
+
22
+ #include <libxml/xmlwriter.h>
23
+
24
+ /* Data type and class: */
25
+ extern rb_data_type_t ov_xml_writer_type;
21
26
  extern VALUE ov_xml_writer_class;
22
27
 
23
- // Initialization function:
28
+ /* Content: */
29
+ typedef struct {
30
+ VALUE io;
31
+ xmlTextWriterPtr writer;
32
+ } ov_xml_writer_object;
33
+
34
+ /* Macro to get the pointer: */
35
+ #define ov_xml_writer_ptr(object, ptr) \
36
+ TypedData_Get_Struct((object), ov_xml_writer_object, &ov_xml_writer_type, (ptr))
37
+
38
+ /* Initialization function: */
24
39
  extern void ov_xml_writer_define(void);
25
40
 
26
41
  #endif
@@ -21,6 +21,7 @@ limitations under the License.
21
21
  #include "ov_http_client.h"
22
22
  #include "ov_http_request.h"
23
23
  #include "ov_http_response.h"
24
+ #include "ov_http_transfer.h"
24
25
  #include "ov_xml_reader.h"
25
26
  #include "ov_xml_writer.h"
26
27
 
@@ -33,6 +34,7 @@ void Init_ovirtsdk4c(void) {
33
34
  ov_http_client_define();
34
35
  ov_http_request_define();
35
36
  ov_http_response_define();
37
+ ov_http_transfer_define();
36
38
  ov_xml_reader_define();
37
39
  ov_xml_writer_define();
38
40
  }
data/lib/ovirtsdk4.rb CHANGED
@@ -28,6 +28,7 @@ require 'ovirtsdk4c'
28
28
  # Own requirements.
29
29
  #
30
30
  require 'ovirtsdk4/version.rb'
31
+ require 'ovirtsdk4/error.rb'
31
32
  require 'ovirtsdk4/connection.rb'
32
33
  require 'ovirtsdk4/type.rb'
33
34
  require 'ovirtsdk4/types.rb'
@@ -95,7 +95,13 @@ module OvirtSDK4
95
95
  # @option opts [Hash] :headers Custom HTTP headers to send with all requests. The keys of the hash can be
96
96
  # strings of symbols, and they will be used as the names of the headers. The values of the hash will be used
97
97
  # as the names of the headers. If the same header is provided here and in the `headers` parameter of a specific
98
- # method call, then the `headers` parameter of the specific method call will have precendence.
98
+ # method call, then the `headers` parameter of the specific method call will have precedence.
99
+ #
100
+ # @option opts [Integer] :connections (0) The maximum number of connections to open to the host. If the value is
101
+ # `0` (the default) then the number of connections will be unlimited.
102
+ #
103
+ # @option opts [Integer] :pipeline (0) The maximum number of request to put in an HTTP pipeline without waiting for
104
+ # the response. If the value is `0` (the default) then pipelining is disabled.
99
105
  #
100
106
  def initialize(opts = {})
101
107
  # Get the values of the parameters and assign default values:
@@ -115,6 +121,8 @@ module OvirtSDK4
115
121
  @proxy_username = opts[:proxy_username]
116
122
  @proxy_password = opts[:proxy_password]
117
123
  @headers = opts[:headers]
124
+ @connections = opts[:connections] || 0
125
+ @pipeline = opts[:pipeline] || 0
118
126
 
119
127
  # Check that the URL has been provided:
120
128
  raise ArgumentError, "The 'url' option is mandatory" unless @url
@@ -147,7 +155,9 @@ module OvirtSDK4
147
155
  compress: @compress,
148
156
  proxy_url: @proxy_url,
149
157
  proxy_username: @proxy_username,
150
- proxy_password: @proxy_password
158
+ proxy_password: @proxy_password,
159
+ connections: @connections,
160
+ pipeline: @pipeline
151
161
  )
152
162
  end
153
163
 
@@ -174,10 +184,9 @@ module OvirtSDK4
174
184
  end
175
185
 
176
186
  #
177
- # Sends an HTTP request and waits for the response.
187
+ # Sends an HTTP request.
178
188
  #
179
189
  # @param request [HttpRequest] The request object containing the details of the HTTP request to send.
180
- # @return [Response] A request object containing the details of the HTTP response received.
181
190
  #
182
191
  # @api private
183
192
  #
@@ -208,13 +217,31 @@ module OvirtSDK4
208
217
  @token ||= create_access_token
209
218
  request.token = @token
210
219
 
211
- # Create an empty response:
212
- response = HttpResponse.new
220
+ # Send the request:
221
+ @client.send(request)
222
+ end
213
223
 
214
- # Send the request and wait for the response:
215
- @client.send(request, response)
224
+ #
225
+ # Waits for the response to the given request.
226
+ #
227
+ # @param request [HttpRequest] The request object whose corresponding response you want to wait for.
228
+ # @return [Response] A request object containing the details of the HTTP response received.
229
+ #
230
+ def wait(request)
231
+ # Wait for the response:
232
+ response = @client.wait(request)
233
+ raise response if response.is_a?(Exception)
234
+
235
+ # If the request failed because of authentication, and it wasn't a request to the SSO service, then the
236
+ # most likely cause is an expired SSO token. In this case we need to request a new token, and try the original
237
+ # request again, but only once. It if fails again, we just return the failed response.
238
+ if response.code == 401 && request.token
239
+ @token = create_access_token
240
+ request.token = @token
241
+ @client.send(request)
242
+ response = @client.wait(request)
243
+ end
216
244
 
217
- # Return the response:
218
245
  response
219
246
  end
220
247
 
@@ -273,25 +300,26 @@ module OvirtSDK4
273
300
  #
274
301
  def get_sso_response(url, parameters)
275
302
  # Create the request:
276
- request = HttpRequest.new(
277
- method: :POST,
278
- url: url,
279
- headers: {
280
- 'User-Agent' => "RubySDK/#{VERSION}",
281
- 'Content-Type' => 'application/x-www-form-urlencoded',
282
- 'Accept' => 'application/json'
283
- },
284
- body: URI.encode_www_form(parameters)
285
- )
303
+ request = HttpRequest.new
304
+ request.method = :POST
305
+ request.url = url
306
+ request.headers = {
307
+ 'User-Agent' => "RubySDK/#{VERSION}",
308
+ 'Content-Type' => 'application/x-www-form-urlencoded',
309
+ 'Accept' => 'application/json'
310
+ }
311
+ request.body = URI.encode_www_form(parameters)
286
312
 
287
313
  # Add the global headers:
288
314
  request.headers.merge!(@headers) if @headers
289
315
 
290
- # Create an empty response:
291
- response = HttpResponse.new
292
-
293
316
  # Send the request and wait for the response:
294
- @client.send(request, response)
317
+ @client.send(request)
318
+ response = @client.wait(request)
319
+ raise response if response.is_a?(Exception)
320
+
321
+ # Check the returned content type:
322
+ check_json_content_type(response)
295
323
 
296
324
  # Parse and return the JSON response:
297
325
  JSON.parse(response.body)
@@ -361,10 +389,14 @@ module OvirtSDK4
361
389
  # `true`.
362
390
  #
363
391
  # @param raise_exception [Boolean]
392
+ #
393
+ # @param timeout [Integer] (nil) The maximun total time to wait for the test to complete, in seconds. If the value
394
+ # is `nil` (the default) then the timeout set globally for the connection will be used.
395
+ #
364
396
  # @return [Boolean]
365
397
  #
366
- def test(raise_exception = false)
367
- system_service.get
398
+ def test(raise_exception = false, timeout = nil)
399
+ system_service.get(timeout: timeout)
368
400
  true
369
401
  rescue StandardError
370
402
  raise if raise_exception
@@ -412,7 +444,7 @@ module OvirtSDK4
412
444
  # Check that the "href" has a value, as it is needed in order to retrieve the representation of the object:
413
445
  href = object.href
414
446
  if href.nil?
415
- raise Error, "Can't follow link because the 'href' attribute does't have a value"
447
+ raise Error, "Can't follow link because the 'href' attribute doesn't have a value"
416
448
  end
417
449
 
418
450
  # Check that the value of the "href" attribute is compatible with the base URL of the connection:
@@ -446,5 +478,123 @@ module OvirtSDK4
446
478
  # Remove the temporary file that contains the trusted CA certificates:
447
479
  @ca_store.unlink if @ca_store
448
480
  end
481
+
482
+ #
483
+ # Checks that the content type of the given response is JSON. If it is JSON then it does nothing. If it isn't
484
+ # JSON then it raises an exception.
485
+ #
486
+ # @param response [HttpResponse] The HTTP response to check.
487
+ #
488
+ # @api private
489
+ #
490
+ def check_json_content_type(response)
491
+ check_content_type(JSON_CONTENT_TYPE_RE, 'JSON', response)
492
+ end
493
+
494
+ #
495
+ # Checks that the content type of the given response is XML. If it is XML then it does nothing. If it isn't
496
+ # XML then it raises an exception.
497
+ #
498
+ # @param response [HttpResponse] The HTTP response to check.
499
+ #
500
+ # @api private
501
+ #
502
+ def check_xml_content_type(response)
503
+ check_content_type(XML_CONTENT_TYPE_RE, 'XML', response)
504
+ end
505
+
506
+ #
507
+ # Creates and raises an error containing the details of the given HTTP response.
508
+ #
509
+ # @param response [HttpResponse] The HTTP response where the details of the raised error will be taken from.
510
+ # @param detail [String, Fault] (nil) The detail of the error. It can be a string or a `Fault` object.
511
+ #
512
+ # @api private
513
+ #
514
+ def raise_error(response, detail = nil)
515
+ # Check if the detail is a fault:
516
+ fault = detail.is_a?(Fault) ? detail : nil
517
+
518
+ # Build the error message from the response and the fault:
519
+ message = ''
520
+ unless fault.nil?
521
+ unless fault.reason.nil?
522
+ message << ' ' unless message.empty?
523
+ message << "Fault reason is \"#{fault.reason}\"."
524
+ end
525
+ unless fault.detail.nil?
526
+ message << ' ' unless message.empty?
527
+ message << "Fault detail is \"#{fault.detail}\"."
528
+ end
529
+ end
530
+ unless response.nil?
531
+ unless response.code.nil?
532
+ message << ' ' unless message.empty?
533
+ message << "HTTP response code is #{response.code}."
534
+ end
535
+ unless response.message.nil?
536
+ message << ' ' unless message.empty?
537
+ message << "HTTP response message is \"#{response.message}\"."
538
+ end
539
+ end
540
+
541
+ # If the detail is a string, append it to the message:
542
+ if detail.is_a?(String)
543
+ message << ' ' unless message.empty?
544
+ message << detail
545
+ message << '.'
546
+ end
547
+
548
+ # Create and populate the error:
549
+ error = Error.new(message)
550
+ error.code = response.code if response
551
+ error.fault = fault
552
+
553
+ raise error
554
+ end
555
+
556
+ private
557
+
558
+ #
559
+ # Regular expression used to check JSON content type.
560
+ #
561
+ # @api private
562
+ #
563
+ JSON_CONTENT_TYPE_RE = %r{^\s*(application|text)/json\s*(;.*)?$}i
564
+
565
+ #
566
+ # Regular expression used to check XML content type.
567
+ #
568
+ # @api private
569
+ #
570
+ XML_CONTENT_TYPE_RE = %r{^\s*(application|text)/xml\s*(;.*)?$}i
571
+
572
+ #
573
+ # The typical URL path, used just to generate informative error messages.
574
+ #
575
+ # @api private
576
+ #
577
+ TYPICAL_PATH = '/ovirt-engine/api'.freeze
578
+
579
+ #
580
+ # Checks the content type of the given HTTP response and raises an exception if it isn't the expected one.
581
+ #
582
+ # @param expected_re [Regex] The regular expression used to check the expected content type.
583
+ # @param expected_name [String] The name of the expected content type.
584
+ # @param response [HttpResponse] The HTTP response to check.
585
+ #
586
+ # @api private
587
+ #
588
+ def check_content_type(expected_re, expected_name, response)
589
+ content_type = response.headers['content-type']
590
+ return if expected_re =~ content_type
591
+ detail = "The response content type '#{content_type}' isn't #{expected_name}"
592
+ url = URI(@url)
593
+ if url.path != TYPICAL_PATH
594
+ detail << ". Is the path '#{url.path}' included in the 'url' parameter correct?"
595
+ detail << " The typical one is '#{TYPICAL_PATH}'"
596
+ end
597
+ raise_error(response, detail)
598
+ end
449
599
  end
450
600
  end