ovirt-engine-sdk 4.1.5 → 4.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES.adoc +37 -0
- data/ext/ovirtsdk4c/ov_http_client.c +531 -353
- data/ext/ovirtsdk4c/ov_http_client.h +39 -2
- data/ext/ovirtsdk4c/ov_http_request.c +130 -102
- data/ext/ovirtsdk4c/ov_http_request.h +10 -2
- data/ext/ovirtsdk4c/ov_http_response.c +63 -50
- data/ext/ovirtsdk4c/ov_http_response.h +9 -2
- data/ext/ovirtsdk4c/ov_http_transfer.c +80 -0
- data/ext/ovirtsdk4c/ov_http_transfer.h +47 -0
- data/ext/ovirtsdk4c/ov_string.c +43 -0
- data/ext/ovirtsdk4c/ov_string.h +25 -0
- data/ext/ovirtsdk4c/ov_xml_reader.c +115 -99
- data/ext/ovirtsdk4c/ov_xml_reader.h +20 -3
- data/ext/ovirtsdk4c/ov_xml_writer.c +95 -77
- data/ext/ovirtsdk4c/ov_xml_writer.h +18 -3
- data/ext/ovirtsdk4c/ovirtsdk4c.c +2 -0
- data/lib/ovirtsdk4.rb +1 -0
- data/lib/ovirtsdk4/connection.rb +176 -26
- data/lib/ovirtsdk4/error.rb +38 -0
- data/lib/ovirtsdk4/probe.rb +4 -7
- data/lib/ovirtsdk4/readers.rb +9 -1
- data/lib/ovirtsdk4/service.rb +267 -36
- data/lib/ovirtsdk4/services.rb +7342 -15734
- data/lib/ovirtsdk4/types.rb +50 -4
- data/lib/ovirtsdk4/version.rb +1 -1
- data/lib/ovirtsdk4/writer.rb +27 -1
- data/lib/ovirtsdk4/writers.rb +3 -1
- metadata +7 -2
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
Copyright (c) 2015-
|
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
|
-
|
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
|
-
|
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-
|
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
|
-
|
35
|
-
|
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(
|
46
|
-
|
47
|
-
|
48
|
-
|
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(
|
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 (
|
55
|
-
xmlTextWriterPtr tmp =
|
56
|
-
|
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(
|
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*
|
79
|
+
ov_xml_writer_object* ptr;
|
66
80
|
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
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 (
|
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(
|
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*
|
103
|
-
xmlOutputBufferPtr buffer
|
120
|
+
ov_xml_writer_object* ptr;
|
121
|
+
xmlOutputBufferPtr buffer;
|
104
122
|
|
105
123
|
/* Get the pointer to the object: */
|
106
|
-
|
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
|
-
|
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
|
-
|
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,
|
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
|
-
|
142
|
-
if (
|
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(
|
150
|
-
xmlTextWriterSetIndentString(
|
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
|
158
|
-
ov_xml_writer_object*
|
175
|
+
int rc;
|
176
|
+
ov_xml_writer_object* ptr;
|
159
177
|
|
160
|
-
|
161
|
-
ov_xml_writer_check_closed(
|
162
|
-
rc = xmlTextWriterFlush(
|
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(
|
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
|
171
|
-
int rc
|
172
|
-
ov_xml_writer_object*
|
188
|
+
char* c_name;
|
189
|
+
int rc;
|
190
|
+
ov_xml_writer_object* ptr;
|
173
191
|
|
174
|
-
|
175
|
-
ov_xml_writer_check_closed(
|
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(
|
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
|
187
|
-
ov_xml_writer_object*
|
204
|
+
int rc;
|
205
|
+
ov_xml_writer_object* ptr;
|
188
206
|
|
189
|
-
|
190
|
-
ov_xml_writer_check_closed(
|
191
|
-
rc = xmlTextWriterEndElement(
|
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
|
200
|
-
char* c_value
|
201
|
-
int rc
|
202
|
-
ov_xml_writer_object*
|
217
|
+
char* c_name;
|
218
|
+
char* c_value;
|
219
|
+
int rc;
|
220
|
+
ov_xml_writer_object* ptr;
|
203
221
|
|
204
|
-
|
205
|
-
ov_xml_writer_check_closed(
|
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(
|
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
|
219
|
-
char* c_value
|
220
|
-
int rc
|
221
|
-
ov_xml_writer_object*
|
236
|
+
char* c_name;
|
237
|
+
char* c_value;
|
238
|
+
int rc;
|
239
|
+
ov_xml_writer_object* ptr;
|
222
240
|
|
223
|
-
|
224
|
-
ov_xml_writer_check_closed(
|
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(
|
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
|
-
|
238
|
-
|
255
|
+
int rc;
|
256
|
+
ov_xml_writer_object* ptr;
|
239
257
|
|
240
|
-
|
241
|
-
ov_xml_writer_check_closed(
|
242
|
-
rc = xmlTextWriterFlush(
|
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*
|
268
|
+
ov_xml_writer_object* ptr;
|
251
269
|
|
252
|
-
|
253
|
-
ov_xml_writer_check_closed(
|
254
|
-
xmlFreeTextWriter(
|
255
|
-
|
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-
|
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
|
-
|
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
|
-
|
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
|
data/ext/ovirtsdk4c/ovirtsdk4c.c
CHANGED
@@ -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
data/lib/ovirtsdk4/connection.rb
CHANGED
@@ -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
|
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
|
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
|
-
#
|
212
|
-
|
220
|
+
# Send the request:
|
221
|
+
@client.send(request)
|
222
|
+
end
|
213
223
|
|
214
|
-
|
215
|
-
|
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
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
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
|
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
|
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
|