razorrisk-razor-connectivity 0.14.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|