razorrisk-razor-connectivity 0.14.10
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 +7 -0
- data/Rakefile +89 -0
- data/lib/razor_risk/razor/connectivity/clarite_2/config_maker.rb +162 -0
- data/lib/razor_risk/razor/connectivity/exceptions.rb +101 -0
- data/lib/razor_risk/razor/connectivity/razor_3/body_maker.rb +126 -0
- data/lib/razor_risk/razor/connectivity/razor_3/header_maker.rb +273 -0
- data/lib/razor_risk/razor/connectivity/razor_3/message_map.rb +156 -0
- data/lib/razor_risk/razor/connectivity/razor_3/razor_requester.rb +559 -0
- data/lib/razor_risk/razor/connectivity/razor_3/response.rb +224 -0
- data/lib/razor_risk/razor/connectivity/razor_3.rb +5 -0
- data/lib/razor_risk/razor/connectivity/version.rb +40 -0
- data/test/bin/razor_request_exe_empty_response.rb +28 -0
- data/test/unit/connectivity/clarite_2/tc_config_maker.rb +399 -0
- data/test/unit/connectivity/razor_3/tc_body_maker.rb +164 -0
- data/test/unit/connectivity/razor_3/tc_header_maker.rb +652 -0
- data/test/unit/connectivity/razor_3/tc_message_map.rb +125 -0
- data/test/unit/connectivity/razor_3/tc_razor_requester.rb +244 -0
- data/test/unit/connectivity/razor_3/tc_razor_requester_executable.rb +176 -0
- data/test/unit/connectivity/razor_3/tc_response.rb +239 -0
- metadata +158 -0
@@ -0,0 +1,559 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# ######################################################################## #
|
4
|
+
#
|
5
|
+
# Class for connecting to the Razor application via the RazorRequest
|
6
|
+
# executable.
|
7
|
+
#
|
8
|
+
# Copyright (c) 2017 Razor Risk Technologies Pty Limited. All rights reserved.
|
9
|
+
#
|
10
|
+
# ######################################################################## #
|
11
|
+
|
12
|
+
|
13
|
+
# ######################################################################## #
|
14
|
+
# requires
|
15
|
+
|
16
|
+
require 'razor_risk/razor/connectivity/razor_3/response'
|
17
|
+
require 'razor_risk/razor/connectivity/exceptions'
|
18
|
+
|
19
|
+
require 'razor_risk/core/system/system_traits'
|
20
|
+
|
21
|
+
require 'razor_risk/core/diagnostics/logger'
|
22
|
+
|
23
|
+
require 'nokogiri'
|
24
|
+
require 'pantheios'
|
25
|
+
require 'recls'
|
26
|
+
require 'xqsr3/quality/parameter_checking'
|
27
|
+
require 'xqsr3/extensions/string/quote_if'
|
28
|
+
|
29
|
+
require 'open3'
|
30
|
+
require 'tempfile'
|
31
|
+
|
32
|
+
# ######################################################################## #
|
33
|
+
# modules
|
34
|
+
|
35
|
+
module RazorRisk
|
36
|
+
module Razor
|
37
|
+
module Connectivity
|
38
|
+
module Razor3
|
39
|
+
|
40
|
+
# ######################################################################## #
|
41
|
+
# classes
|
42
|
+
|
43
|
+
# Class that provides easy call interface to Razor, following along with the
|
44
|
+
# "traditional" behaviour of the RazorRequest tool
|
45
|
+
#
|
46
|
+
# It is used by creating an instance, which requires the ClarITe config
|
47
|
+
# (path) and the Razor Environment name, as in:
|
48
|
+
#
|
49
|
+
# +rr = RazorRequester.new cc_path, env_name
|
50
|
+
#
|
51
|
+
# and then requests are dispatched to the relevant Razor installation (as
|
52
|
+
# named by the environment) via the +send_request+ method, as in:
|
53
|
+
#
|
54
|
+
# +rr.send_request request
|
55
|
+
#
|
56
|
+
# where +request+ is a Razor request document.
|
57
|
+
#
|
58
|
+
# Both initialiser and +send_request+ methods take options, as detailed in
|
59
|
+
# their respective documentation sections. The initialiser's +:executable+
|
60
|
+
# option is required when the class method +requires_executable?+ returns
|
61
|
+
# +true+, and should point to the full path of the underlying RazorRequest
|
62
|
+
# program to be used for connectivity with the Razor system
|
63
|
+
class RazorRequester
|
64
|
+
|
65
|
+
include ::Pantheios
|
66
|
+
include ::Xqsr3::Quality::ParameterChecking
|
67
|
+
include ::RazorRisk::Core::Diagnostics::Logger
|
68
|
+
private
|
69
|
+
def nil_if_empty v
|
70
|
+
|
71
|
+
return nil if v.respond_to?(:empty?) && v.empty?
|
72
|
+
v
|
73
|
+
end
|
74
|
+
def to_nil *args; end
|
75
|
+
def self.to_nil *args; end
|
76
|
+
public
|
77
|
+
|
78
|
+
# FIXME: THIS MUST BE FIXED.
|
79
|
+
#
|
80
|
+
# Validate that all characters in the string are alphanumerics, spaces,
|
81
|
+
# or underscores.
|
82
|
+
#
|
83
|
+
# This check is temporary and does not grantee SQL safety. This
|
84
|
+
# must be addressed as a larger issue around sanitization of user
|
85
|
+
# inputs to Razor.
|
86
|
+
#
|
87
|
+
# @param str [String] The string to be validated.
|
88
|
+
#
|
89
|
+
# @yield Executes the block if the string is not safe.
|
90
|
+
#
|
91
|
+
# @raise [ArgumentError] If the argument is not a string.
|
92
|
+
# @raise [ArgumentError] If the argument is not a string.
|
93
|
+
#
|
94
|
+
# @example Raise an exception if unsafe.
|
95
|
+
# stopgap_sql_string_validator_fix_me '.!?' { raise ArgumentError }
|
96
|
+
def self.stopgap_sql_string_validator_fix_me str, &block
|
97
|
+
|
98
|
+
raise ArgumentError.new 'No block was given' unless block_given?
|
99
|
+
|
100
|
+
check_parameter str, 'str', type: ::String
|
101
|
+
|
102
|
+
unless /^[A-Za-z0-9_ ]+$/ =~ str
|
103
|
+
yield
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# see #stopgap_sql_string_validator_fix_me
|
108
|
+
def stopgap_sql_string_validator_fix_me *args, &block
|
109
|
+
self.class.stopgap_sql_string_validator_fix_me(*args, &block)
|
110
|
+
end
|
111
|
+
|
112
|
+
# ##########################################################
|
113
|
+
# types
|
114
|
+
|
115
|
+
# Root exception for failures of RazorRequester
|
116
|
+
class Exception < ::RazorRisk::Razor::Connectivity::Exceptions::ConnectivityException
|
117
|
+
end
|
118
|
+
|
119
|
+
# Exception thrown when request fails
|
120
|
+
class RequestFailedException < Exception
|
121
|
+
|
122
|
+
def initialize message, exit_status, razor_code, contingent_report, **options
|
123
|
+
|
124
|
+
trace ParamNames[ :message, :exit_status, :razor_code, :contingent_report, :options ], message, exit_status, razor_code, contingent_report, options
|
125
|
+
|
126
|
+
if (message || '').empty?
|
127
|
+
|
128
|
+
message = contingent_report
|
129
|
+
else
|
130
|
+
|
131
|
+
if (contingent_report || '').empty?
|
132
|
+
|
133
|
+
;
|
134
|
+
else
|
135
|
+
|
136
|
+
message = "#{message}: #{contingent_report}"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
super message, options
|
141
|
+
|
142
|
+
@exit_status = exit_status
|
143
|
+
@razor_code = razor_code
|
144
|
+
@contingent_report = contingent_report
|
145
|
+
end
|
146
|
+
|
147
|
+
attr_reader :exit_status
|
148
|
+
attr_reader :razor_code
|
149
|
+
attr_reader :contingent_report
|
150
|
+
|
151
|
+
def inspect
|
152
|
+
|
153
|
+
"#<#{self.class}:0x00#{object_id << 1}: exit_status=#{exit_status}; razor_code=#{razor_code}; contingent_report=#{contingent_report}>"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# Raised when the response from the +:razor_executable+ is not
|
158
|
+
# recognised (which might mean an invalid executable has been specified)
|
159
|
+
class InvalidResponseException < Exception; end
|
160
|
+
|
161
|
+
# Raised when the credentials given are invalid
|
162
|
+
class InvalidCredentialsException < RequestFailedException; end
|
163
|
+
|
164
|
+
# Represents the executable
|
165
|
+
class Executable
|
166
|
+
|
167
|
+
include RazorRisk::Core::System::SystemTraits
|
168
|
+
|
169
|
+
include ::Xqsr3::Quality::ParameterChecking
|
170
|
+
include ::Xqsr3::Quality::ParameterChecking
|
171
|
+
|
172
|
+
module Constants
|
173
|
+
|
174
|
+
RRParameters = {
|
175
|
+
username: '/usr',
|
176
|
+
password: '/pwd',
|
177
|
+
domain: '/domain',
|
178
|
+
impersonatee: '/impersonate',
|
179
|
+
razor_space: '/space',
|
180
|
+
razor_environment: '/env',
|
181
|
+
razor_alias: '/alias',
|
182
|
+
session_id: '/sessionId',
|
183
|
+
}
|
184
|
+
|
185
|
+
RROptions = {
|
186
|
+
debug: '/debug',
|
187
|
+
logStderr: '/logStderr',
|
188
|
+
session: '/session',
|
189
|
+
open_session: '/openSession',
|
190
|
+
}
|
191
|
+
end
|
192
|
+
|
193
|
+
# Initialises the instance
|
194
|
+
#
|
195
|
+
# @param executable [::String, Array<::String>] As string with 1 or
|
196
|
+
# more elements separated by '|' (or by the platform's separator -
|
197
|
+
# ';' on Windows; ':' otherwise)
|
198
|
+
#
|
199
|
+
def initialize executable
|
200
|
+
|
201
|
+
check_parameter executable, 'executable', types: [ ::String, [ ::String ] ]
|
202
|
+
|
203
|
+
exec_parts = executable.split(windows? ? /[|;]/ : /[|:]/) if ::String === executable
|
204
|
+
exec_parts = exec_parts.flatten
|
205
|
+
exec_parts = exec_parts.reject { |xp| xp.strip.empty? }
|
206
|
+
|
207
|
+
raise ::ArgumentError, "the given executable '#{executable}' resolves to nothing" if exec_parts.empty?
|
208
|
+
|
209
|
+
arg0 = exec_parts.shift
|
210
|
+
|
211
|
+
@arg0 = Recls.stat(arg0) or raise ArgumentError, "given executable '#{arg0}' does not exist"
|
212
|
+
@argv = exec_parts
|
213
|
+
end
|
214
|
+
|
215
|
+
# Forms the full command to be executed, based on the given
|
216
|
+
# parameters, options, and also on the nature of the executable
|
217
|
+
# specified in the initialiser
|
218
|
+
#
|
219
|
+
# @param config_path [::String] The ClarITe configuration
|
220
|
+
# @param request_path [::String] The path of the request document.
|
221
|
+
# @param options [::Hash] Options hash
|
222
|
+
#
|
223
|
+
# @option options [::String] :username The user to use fro the
|
224
|
+
# credentials.
|
225
|
+
# @option options [::String] :password The password to use for
|
226
|
+
# credentials.
|
227
|
+
# @option options [::String] :domain The domain to use for
|
228
|
+
# credentials.
|
229
|
+
# @option options [::String] :impersonatee The user to impersonate.
|
230
|
+
# @option options [::String] :razor_environment The Razor environment.
|
231
|
+
# @option options [Boolean] :session Uses a Razor session for the
|
232
|
+
# request.
|
233
|
+
# @option options [Boolean] :debug Turns on debug.
|
234
|
+
# @option options [Boolean] :log_to_stderr Turns on logging.
|
235
|
+
#
|
236
|
+
# @return [::String] The command to execute.
|
237
|
+
def form_command config_path, request_path, **options
|
238
|
+
|
239
|
+
cmd = []
|
240
|
+
cmd << program_path.to_s.quote_if
|
241
|
+
|
242
|
+
unless program_arguments.empty?
|
243
|
+
|
244
|
+
program_arguments.each do |arg|
|
245
|
+
|
246
|
+
cmd << arg.quote_if
|
247
|
+
end
|
248
|
+
else
|
249
|
+
|
250
|
+
cmd << '/config' << config_path.quote_if
|
251
|
+
cmd << '/request' << request_path.quote_if unless request_path.nil?
|
252
|
+
|
253
|
+
Constants::RRParameters.each do |key,value|
|
254
|
+
cmd << value << options[key].quote_if if options[key]
|
255
|
+
end
|
256
|
+
|
257
|
+
Constants::RROptions.each do |key,value|
|
258
|
+
cmd << value if options[key]
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
cmd * ' '
|
263
|
+
end
|
264
|
+
|
265
|
+
def program_path; @arg0; end
|
266
|
+
def program_arguments; @argv; end
|
267
|
+
end
|
268
|
+
|
269
|
+
# Indicates whether the instance requires an executable
|
270
|
+
def self.requires_executable?
|
271
|
+
|
272
|
+
true
|
273
|
+
end
|
274
|
+
|
275
|
+
# Initialises an instance with configuration and set-up options
|
276
|
+
#
|
277
|
+
# @param config [::String, nil] The ClarITe configuration. By default
|
278
|
+
# this is interpreted as a file path, unless the option
|
279
|
+
# +:config_as_string+ is given. If +nil+ it will be obtained from
|
280
|
+
# option +:config+. One or the other must be supplied.
|
281
|
+
# @param options [::Hash] The options hash.
|
282
|
+
#
|
283
|
+
# @option options [::String] :config The ClarITe configuration. By
|
284
|
+
# default this is interpreted as a file path, unless the option
|
285
|
+
# +:config_as_string+ is given. Ignored if the parameter +config+ is
|
286
|
+
# not +nil+.
|
287
|
+
# @option options [::String] :razor_environment Specifies the Razor
|
288
|
+
# environment. May not be combinbed with +:razor_alias+.
|
289
|
+
# @option options [::String] :razor_space Specifies the ClarITe
|
290
|
+
# space. May not be combinbed with +:razor_alias+.
|
291
|
+
# @option options [::String] :razor_alias Specifies the Razor alias. May
|
292
|
+
# not be combinbed with +:razor_environment+ or +:razor_space+.
|
293
|
+
# @option options [Boolean] :config_as_string The +config+ parameter
|
294
|
+
# [or +:config+ option] is treated as a string containing the
|
295
|
+
# configuration, rather than the path to a configuration file.
|
296
|
+
# @option options [::String] :executable Specifies the executable for
|
297
|
+
# RazorRequest. Required if the class method +requires_executable?+ is
|
298
|
+
# +true+. May contain program arguments, separated using the
|
299
|
+
# platform-independent path separator '|' [or the platform-specific
|
300
|
+
# path separator - ';' for Windows; ':' otherwise].
|
301
|
+
# @option options :aborter DEPRECATED
|
302
|
+
#
|
303
|
+
def initialize config, **options
|
304
|
+
|
305
|
+
trace ParamNames[ :config, :options ], config, options
|
306
|
+
|
307
|
+
check_parameter config, 'config', type: ::String, allow_nil: true
|
308
|
+
|
309
|
+
warn ':aborter option is not longer recognised' if options[:aborter]
|
310
|
+
|
311
|
+
# NOTE: This (ctor) method concerns itself only with specifying (and
|
312
|
+
# validating) the executable and the configuration
|
313
|
+
|
314
|
+
config = nil_if_empty(config) || nil_if_empty(options[:config]) or raise ArgumentError, 'config not specified'
|
315
|
+
|
316
|
+
unless options[:config_as_string]
|
317
|
+
raise ArgumentError, "given config file '#{config}' does not exist, or is not a file" unless File.file? config
|
318
|
+
end
|
319
|
+
|
320
|
+
unless options[:razor_environment] or options[:razor_alias]
|
321
|
+
raise ArgumentError, 'either :razor_environment or :razor_alias options must be specified'
|
322
|
+
end
|
323
|
+
|
324
|
+
if self.class.requires_executable?
|
325
|
+
|
326
|
+
executable = options[:executable] or raise ArgumentError, ':executable option is required'
|
327
|
+
|
328
|
+
@executable = Executable.new executable
|
329
|
+
end
|
330
|
+
|
331
|
+
@config = config
|
332
|
+
@options = options
|
333
|
+
end
|
334
|
+
|
335
|
+
attr_reader :config
|
336
|
+
attr_reader :options
|
337
|
+
|
338
|
+
def executable
|
339
|
+
@executable.program_path
|
340
|
+
end
|
341
|
+
|
342
|
+
def environment
|
343
|
+
@options[:razor_environment] || @options[:razor_alias]
|
344
|
+
end
|
345
|
+
|
346
|
+
# Sends the given request.
|
347
|
+
#
|
348
|
+
# @param request [#to_s] The string form of this object is used as the
|
349
|
+
# request.
|
350
|
+
# @param options [::Hash] The options hash.
|
351
|
+
#
|
352
|
+
# @option options [::String] :username The username part of the
|
353
|
+
# credentials.
|
354
|
+
# @option options [::String] :password The password to be specified as
|
355
|
+
# part of the credentials. Ignored unless +options[:username]+ is
|
356
|
+
# specified.
|
357
|
+
# @option options [::String] :domain The domain to be specified as part
|
358
|
+
# of the credentials. Ignored unless options +:username]+ is specified.
|
359
|
+
# @option options [::String] :impersonatee The name of the account that
|
360
|
+
# will be impersonated for the purposes of the request.
|
361
|
+
# @option options [Boolean] :session Causes a Razor session to be used
|
362
|
+
# for the request.
|
363
|
+
# @option options [Boolean] :request_as_path The +request+ parameter is
|
364
|
+
# treated as a path to a file containing the request contents, rather
|
365
|
+
# than the request contents.
|
366
|
+
# @option options [Boolean] :debug Causes certain debugging actions,
|
367
|
+
# including not removing temporary files.
|
368
|
+
# @option options [Boolean] :log_to_stderr Causes the RazorRequest CLI
|
369
|
+
# flag '/logStderr' to be included in the command-line.
|
370
|
+
# @option options :request_as_string DEPRECATED
|
371
|
+
#
|
372
|
+
def send_request request, **options
|
373
|
+
|
374
|
+
trace ParamNames[ :request, :options ], request, options
|
375
|
+
|
376
|
+
options.reject! { |k,v| v.empty? if v.respond_to? :empty? }
|
377
|
+
|
378
|
+
unless (options[:username] && options[:password]) ||
|
379
|
+
options[:single_sign_on] ||
|
380
|
+
options[:impersonatee] ||
|
381
|
+
options[:session_id]
|
382
|
+
raise ArgumentError, 'Some form of credentials must be provided.'
|
383
|
+
end
|
384
|
+
|
385
|
+
# Disable session option if session already provided
|
386
|
+
options[:session] = false if options[:session_id]
|
387
|
+
|
388
|
+
options = @options.merge options.reject { |k| [ :config_as_string, :config ].include? k }
|
389
|
+
|
390
|
+
raise ArgumentError, ':request_as_string option no longer supported' if options[:request_as_string]
|
391
|
+
|
392
|
+
if (options[:razor_environment] or options[:razor_space]) and options[:razor_alias]
|
393
|
+
raise ArgumentError, 'option :razor_alias may not be combined with :razor_environment or :razor_space'
|
394
|
+
end
|
395
|
+
|
396
|
+
warn ':domain option will be ignored as no username was specified' if options[:domain] and not options[:username]
|
397
|
+
warn ':password option will be ignored as no username was specified' if options[:password] and not options[:username]
|
398
|
+
|
399
|
+
if options[:config_as_string]
|
400
|
+
|
401
|
+
tf = Tempfile.new('clarite_config')
|
402
|
+
|
403
|
+
begin
|
404
|
+
|
405
|
+
cc_path = tf.path
|
406
|
+
|
407
|
+
tf.close
|
408
|
+
|
409
|
+
File.open(cc_path, 'w') do |f|
|
410
|
+
|
411
|
+
f.write @config
|
412
|
+
f.write "\n"
|
413
|
+
end
|
414
|
+
|
415
|
+
do_send_request_ cc_path, request, options.reject { |k| k == :config_as_string }
|
416
|
+
ensure
|
417
|
+
|
418
|
+
File.unlink(cc_path)
|
419
|
+
end
|
420
|
+
else
|
421
|
+
|
422
|
+
do_send_request_ @config, request, options
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
private
|
427
|
+
def do_send_request_ config_path, request, options
|
428
|
+
|
429
|
+
trace ParamNames[ :config_path, :request, :options ], config_path, request, options
|
430
|
+
|
431
|
+
unless options[:request_as_path] || request.nil?
|
432
|
+
|
433
|
+
rq_file = Tempfile.new('request_document')
|
434
|
+
|
435
|
+
begin
|
436
|
+
|
437
|
+
rq_file.write request
|
438
|
+
rq_file.write "\n"
|
439
|
+
rq_file.flush
|
440
|
+
rq_file.rewind
|
441
|
+
|
442
|
+
return do_send_request_ config_path, rq_file.path, options.merge({ :request_as_path => true })
|
443
|
+
ensure
|
444
|
+
|
445
|
+
rq_file.close
|
446
|
+
rq_file.unlink unless options[:debug]
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
options[:log_to_stderr] = options[:log_to_stderr] || options[:debug]
|
451
|
+
|
452
|
+
cmd = @executable.form_command config_path, request, **options
|
453
|
+
|
454
|
+
log :debug0, 'cmd: \'', cmd, '\''
|
455
|
+
|
456
|
+
t_before = Time.now
|
457
|
+
|
458
|
+
stdout_str, stderr_str, status = Open3.capture3 cmd
|
459
|
+
|
460
|
+
t_after = Time.now
|
461
|
+
|
462
|
+
if severity_logged? :debug1
|
463
|
+
|
464
|
+
log :debug1, 'stderr: \'', stderr_str.chomp, '\''
|
465
|
+
log :debug1, 'stdout: \'', stdout_str.chomp, '\''
|
466
|
+
log :debug1, 'status: \'', status, '\''
|
467
|
+
end
|
468
|
+
|
469
|
+
log :benchmark, "execution of RazorRequest(.exe) (in #{self.class}##{__method__}): dt=#{(t_after - t_before) * 1000}ms" if severity_logged?(:benchmark)
|
470
|
+
|
471
|
+
exit_status = status.exitstatus
|
472
|
+
|
473
|
+
if 0 != exit_status
|
474
|
+
|
475
|
+
# Current version of RazorRequest writes its contingent report to
|
476
|
+
# stdout - I know! - when it fails (with non-0 exit code), so we
|
477
|
+
# must parse that
|
478
|
+
|
479
|
+
cr_str = options[:log_to_stderr] ? stderr_str : stdout_str
|
480
|
+
|
481
|
+
cr_lines = cr_str.split(/[\r\n]/)
|
482
|
+
contingent_report = cr_lines[-1]
|
483
|
+
|
484
|
+
# now parse the CR to extract the Razor code
|
485
|
+
|
486
|
+
rzc = nil
|
487
|
+
|
488
|
+
cr_lines.each_with_index do |line0, index0|
|
489
|
+
|
490
|
+
line = line0.chomp
|
491
|
+
index = 1 + index0
|
492
|
+
|
493
|
+
unless rzc
|
494
|
+
|
495
|
+
rzc = $1 if line =~ /^(RZC\d+)\s+(.*)$/
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
log :debug2, "contingent report lines:\n\t#{cr_lines.join(%Q<\n\t>)}" if options[:debug] && severity_logged?(:debug2)
|
500
|
+
|
501
|
+
x_class = RequestFailedException
|
502
|
+
|
503
|
+
if 15 == exit_status || cr_lines.any? { |line| line =~ /RAZOR log[io]n failed/i }
|
504
|
+
|
505
|
+
x_class = InvalidCredentialsException
|
506
|
+
end
|
507
|
+
|
508
|
+
raise x_class.new "request failed", exit_status, rzc, contingent_report, contingent_report_lines: cr_lines
|
509
|
+
else
|
510
|
+
|
511
|
+
# record stderr
|
512
|
+
|
513
|
+
contingent_report = stderr_str.split(/[\r\n]/)
|
514
|
+
|
515
|
+
log :debug2, "contingent report lines:\n\t#{contingent_report.join(%Q<\n\t>)}" if options[:debug] && severity_logged?(:debug2)
|
516
|
+
end
|
517
|
+
|
518
|
+
if stdout_str.split(/[\r\n]/) == ["<ack>queued</ack>"]
|
519
|
+
response = ::Nokogiri.XML(stdout_str)
|
520
|
+
else
|
521
|
+
xml_doc = begin
|
522
|
+
|
523
|
+
::Nokogiri.XML(stdout_str) { |config| config.strict }
|
524
|
+
rescue ::Nokogiri::XML::SyntaxError => x
|
525
|
+
|
526
|
+
raise InvalidResponseException.new 'invalid response', cause: x
|
527
|
+
end
|
528
|
+
|
529
|
+
log(:debug4) { "xml_doc: #{xml_doc.to_xml}" }
|
530
|
+
|
531
|
+
begin
|
532
|
+
|
533
|
+
response = Response.new xml_doc
|
534
|
+
rescue ArgumentError => x
|
535
|
+
|
536
|
+
raise InvalidResponseException.new 'invalid response', cause: x
|
537
|
+
end
|
538
|
+
|
539
|
+
log :debug3, 'response: ', response
|
540
|
+
end
|
541
|
+
|
542
|
+
log :debug3, 'response: ', response
|
543
|
+
response
|
544
|
+
end
|
545
|
+
public
|
546
|
+
|
547
|
+
end
|
548
|
+
|
549
|
+
# ######################################################################## #
|
550
|
+
# modules
|
551
|
+
|
552
|
+
end # module Razor3
|
553
|
+
end # module Connectivity
|
554
|
+
end # module Razor
|
555
|
+
end # module RazorRisk
|
556
|
+
|
557
|
+
# ############################## end of file ############################# #
|
558
|
+
|
559
|
+
|