qbwc 0.0.5 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -1
- data/.travis.yml +6 -0
- data/README.md +152 -144
- data/Rakefile +7 -1
- data/lib/generators/qbwc/install/install_generator.rb +20 -4
- data/lib/generators/qbwc/install/templates/config/qbwc.rb +42 -26
- data/lib/generators/qbwc/install/templates/controllers/qbwc_controller.rb +2 -38
- data/lib/generators/qbwc/install/templates/db/migrate/create_qbwc_jobs.rb +15 -0
- data/lib/generators/qbwc/install/templates/db/migrate/create_qbwc_sessions.rb +16 -0
- data/lib/qbwc.rb +107 -71
- data/lib/qbwc/active_record.rb +6 -0
- data/lib/qbwc/active_record/job.rb +111 -0
- data/lib/qbwc/active_record/session.rb +52 -0
- data/lib/qbwc/controller.rb +176 -0
- data/lib/qbwc/job.rb +81 -18
- data/lib/qbwc/railtie.rb +8 -0
- data/lib/qbwc/request.rb +14 -23
- data/lib/qbwc/session.rb +100 -72
- data/lib/qbwc/version.rb +1 -1
- data/lib/qbwc/worker.rb +16 -0
- data/qbwc.gemspec +11 -5
- data/test/qbwc/controllers/controller_test.rb +157 -0
- data/test/qbwc/integration/job_management_test.rb +86 -0
- data/test/qbwc/integration/request_generation_test.rb +340 -0
- data/test/qbwc/integration/response_test.rb +303 -0
- data/test/qbwc/integration/routes_test.rb +38 -0
- data/test/qbwc/integration/session_test.rb +94 -0
- data/test/test_helper.rb +248 -0
- data/test/wash_out_helper.rb +76 -0
- metadata +133 -55
- data/Gemfile.lock +0 -72
- data/lib/qbwc/soap_wrapper.rb +0 -35
- data/lib/qbwc/soap_wrapper/QBWebConnectorSvc.rb +0 -69
- data/lib/qbwc/soap_wrapper/QBWebConnectorSvc.wsdl +0 -312
- data/lib/qbwc/soap_wrapper/default.rb +0 -198
- data/lib/qbwc/soap_wrapper/defaultMappingRegistry.rb +0 -163
- data/lib/qbwc/soap_wrapper/defaultServant.rb +0 -133
- data/spec/spec_helper.rb +0 -17
@@ -0,0 +1,176 @@
|
|
1
|
+
require 'wash_out/version'
|
2
|
+
include WashOut
|
3
|
+
|
4
|
+
module QBWC
|
5
|
+
module Controller
|
6
|
+
|
7
|
+
AUTHENTICATE_NOT_VALID_USER = 'nvu'
|
8
|
+
AUTHENTICATE_NO_WORK = 'none'
|
9
|
+
|
10
|
+
def self.included(base)
|
11
|
+
base.class_eval do
|
12
|
+
include WashOut::SOAP
|
13
|
+
skip_before_filter :_parse_soap_parameters, :_authenticate_wsse, :_map_soap_parameters, :only => :qwc
|
14
|
+
before_filter :get_session, :except => [:qwc, :authenticate, :_generate_wsdl]
|
15
|
+
after_filter :save_session, :except => [:qwc, :authenticate, :_generate_wsdl, :close_connection, :connection_error]
|
16
|
+
|
17
|
+
# wash_out changed the format of app/views/wash_with_soap/rpc/response.builder in commit
|
18
|
+
# https://github.com/inossidabile/wash_out/commit/24a77f4a3d874562732c6e8c3a30e8defafea7cb
|
19
|
+
wash_out_xml_namespace = (Gem::Version.new(WashOut::VERSION) < Gem::Version.new('0.9.1') ? 'tns:' : '')
|
20
|
+
|
21
|
+
soap_action 'serverVersion', :to => :server_version,
|
22
|
+
:return => {'tns:serverVersionResult' => :string},
|
23
|
+
:response_tag => "#{wash_out_xml_namespace}serverVersionResponse"
|
24
|
+
|
25
|
+
soap_action 'clientVersion', :to => :client_version,
|
26
|
+
:args => {:strVersion => :string},
|
27
|
+
:return => {'tns:clientVersionResult' => :string},
|
28
|
+
:response_tag => "#{wash_out_xml_namespace}clientVersionResponse"
|
29
|
+
|
30
|
+
soap_action 'authenticate',
|
31
|
+
:args => {:strUserName => :string, :strPassword => :string},
|
32
|
+
:return => {'tns:authenticateResult' => StringArray},
|
33
|
+
:response_tag => "#{wash_out_xml_namespace}authenticateResponse"
|
34
|
+
|
35
|
+
soap_action 'sendRequestXML', :to => :send_request,
|
36
|
+
:args => {:ticket => :string, :strHCPResponse => :string, :strCompanyFilename => :string, :qbXMLCountry => :string, :qbXMLMajorVers => :string, :qbXMLMinorVers => :string},
|
37
|
+
:return => {'tns:sendRequestXMLResult' => :string},
|
38
|
+
:response_tag => "#{wash_out_xml_namespace}sendRequestXMLResponse"
|
39
|
+
|
40
|
+
soap_action 'receiveResponseXML', :to => :receive_response,
|
41
|
+
:args => {:ticket => :string, :response => :string, :hresult => :string, :message => :string},
|
42
|
+
:return => {'tns:receiveResponseXMLResult' => :integer},
|
43
|
+
:response_tag => "#{wash_out_xml_namespace}receiveResponseXMLResponse"
|
44
|
+
|
45
|
+
soap_action 'closeConnection', :to => :close_connection,
|
46
|
+
:args => {:ticket => :string},
|
47
|
+
:return => {'tns:closeConnectionResult' => :string},
|
48
|
+
:response_tag => "#{wash_out_xml_namespace}closeConnectionResponse"
|
49
|
+
|
50
|
+
soap_action 'connectionError', :to => :connection_error,
|
51
|
+
:args => {:ticket => :string, :hresult => :string, :message => :string},
|
52
|
+
:return => {'tns:connectionErrorResult' => :string},
|
53
|
+
:response_tag => "#{wash_out_xml_namespace}connectionErrorResponse"
|
54
|
+
|
55
|
+
soap_action 'getLastError', :to => :get_last_error,
|
56
|
+
:args => {:ticket => :string},
|
57
|
+
:return => {'tns:getLastErrorResult' => :string},
|
58
|
+
:response_tag => "#{wash_out_xml_namespace}getLastErrorResponse"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def qwc
|
63
|
+
# Optional tag
|
64
|
+
scheduler_block = ''
|
65
|
+
if !QBWC.minutes_to_run.nil?
|
66
|
+
scheduler_block = <<SB
|
67
|
+
<Scheduler>
|
68
|
+
<RunEveryNMinutes>#{QBWC.minutes_to_run}</RunEveryNMinutes>
|
69
|
+
</Scheduler>
|
70
|
+
SB
|
71
|
+
end
|
72
|
+
|
73
|
+
qwc = <<QWC
|
74
|
+
<QBWCXML>
|
75
|
+
<AppName>#{Rails.application.class.parent_name} #{Rails.env} #{@app_name_suffix}</AppName>
|
76
|
+
<AppID></AppID>
|
77
|
+
<AppURL>#{qbwc_action_url(:only_path => false)}</AppURL>
|
78
|
+
<AppDescription>Quickbooks integration</AppDescription>
|
79
|
+
<AppSupport>#{QBWC.support_site_url || root_url(:protocol => 'https://')}</AppSupport>
|
80
|
+
<UserName>#{@username || QBWC.username}</UserName>
|
81
|
+
<OwnerID>#{QBWC.owner_id}</OwnerID>
|
82
|
+
<FileID>{90A44FB5-33D9-4815-AC85-BC87A7E7D1EB}</FileID>
|
83
|
+
<QBType>QBFS</QBType>
|
84
|
+
<Style>Document</Style>
|
85
|
+
#{scheduler_block}
|
86
|
+
</QBWCXML>
|
87
|
+
QWC
|
88
|
+
send_data qwc, :filename => "#{@filename || Rails.application.class.parent_name}.qwc", :content_type => 'application/x-qwc'
|
89
|
+
end
|
90
|
+
|
91
|
+
class StringArray < WashOut::Type
|
92
|
+
map "tns:string" => [:string]
|
93
|
+
end
|
94
|
+
|
95
|
+
def server_version
|
96
|
+
render :soap => {"tns:serverVersionResult" => server_version_response}
|
97
|
+
end
|
98
|
+
|
99
|
+
def client_version
|
100
|
+
render :soap => {"tns:clientVersionResult" => check_client_version}
|
101
|
+
end
|
102
|
+
|
103
|
+
def authenticate
|
104
|
+
username = params[:strUserName]
|
105
|
+
password = params[:strPassword]
|
106
|
+
if !QBWC.authenticator.nil?
|
107
|
+
company_file_path = QBWC.authenticator.call(username, password)
|
108
|
+
elsif username == QBWC.username && password == QBWC.password
|
109
|
+
company_file_path = QBWC.company_file_path
|
110
|
+
else
|
111
|
+
company_file_path = nil
|
112
|
+
end
|
113
|
+
|
114
|
+
ticket = nil
|
115
|
+
if company_file_path.nil?
|
116
|
+
QBWC.logger.info "Authentication of user '#{username}' failed."
|
117
|
+
company_file_path = AUTHENTICATE_NOT_VALID_USER
|
118
|
+
elsif !QBWC.pending_jobs(company_file_path).present?
|
119
|
+
QBWC.logger.info "Authentication of user '#{username}' succeeded, but no jobs pending for '#{company_file_path}'."
|
120
|
+
company_file_path = AUTHENTICATE_NO_WORK
|
121
|
+
else
|
122
|
+
QBWC.logger.info "Authentication of user '#{username}' succeeded, jobs are pending for '#{company_file_path}'."
|
123
|
+
ticket = QBWC.storage_module::Session.new(username, company_file_path).ticket
|
124
|
+
QBWC.session_initializer.call(get_session(ticket)) unless QBWC.session_initializer.nil?
|
125
|
+
end
|
126
|
+
render :soap => {"tns:authenticateResult" => {"tns:string" => [ticket || '', company_file_path]}}
|
127
|
+
end
|
128
|
+
|
129
|
+
def send_request
|
130
|
+
request = @session.request_to_send
|
131
|
+
render :soap => {'tns:sendRequestXMLResult' => request}
|
132
|
+
end
|
133
|
+
|
134
|
+
def receive_response
|
135
|
+
if params[:hresult]
|
136
|
+
QBWC.logger.warn "#{params[:hresult]}: #{params[:message]}"
|
137
|
+
@session.error = params[:message]
|
138
|
+
@session.status_code = params[:hresult]
|
139
|
+
@session.status_severity = 'Error'
|
140
|
+
end
|
141
|
+
@session.response = params[:response]
|
142
|
+
render :soap => {'tns:receiveResponseXMLResult' => (QBWC::on_error == 'continueOnError' || @session.error.nil?) ? @session.progress : -1}
|
143
|
+
end
|
144
|
+
|
145
|
+
def close_connection
|
146
|
+
@session.destroy
|
147
|
+
render :soap => {'tns:closeConnectionResult' => 'OK'}
|
148
|
+
end
|
149
|
+
|
150
|
+
def connection_error
|
151
|
+
@session.destroy
|
152
|
+
logger.warn "#{params[:hresult]}: #{params[:message]}"
|
153
|
+
render :soap => {'tns:connectionErrorResult' => 'done'}
|
154
|
+
end
|
155
|
+
|
156
|
+
def get_last_error
|
157
|
+
render :soap => {'tns:getLastErrorResult' => @session.error || ''}
|
158
|
+
end
|
159
|
+
|
160
|
+
protected
|
161
|
+
|
162
|
+
def get_session(ticket = params[:ticket])
|
163
|
+
@session = QBWC.storage_module::Session.get(ticket)
|
164
|
+
end
|
165
|
+
|
166
|
+
def save_session
|
167
|
+
@session.save if @session
|
168
|
+
end
|
169
|
+
|
170
|
+
def server_version_response
|
171
|
+
end
|
172
|
+
|
173
|
+
def check_client_version
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
data/lib/qbwc/job.rb
CHANGED
@@ -1,47 +1,110 @@
|
|
1
1
|
class QBWC::Job
|
2
2
|
|
3
|
-
attr_reader :name, :
|
3
|
+
attr_reader :name, :company, :worker_class
|
4
4
|
|
5
|
-
def initialize(name,
|
5
|
+
def initialize(name, enabled, company, worker_class, requests = [], data = nil)
|
6
6
|
@name = name
|
7
|
-
@enabled =
|
8
|
-
@
|
7
|
+
@enabled = enabled
|
8
|
+
@company = company || QBWC.company_file_path
|
9
|
+
@worker_class = worker_class
|
10
|
+
@requests = requests
|
11
|
+
@data = data
|
12
|
+
@request_index = 0
|
13
|
+
end
|
14
|
+
|
15
|
+
def worker
|
16
|
+
worker_class.constantize.new
|
17
|
+
end
|
9
18
|
|
10
|
-
|
19
|
+
def process_response(qbxml_response, response, session, advance)
|
20
|
+
QBWC.logger.info "Processing response."
|
21
|
+
completed_request = requests[request_index]
|
22
|
+
advance_next_request if advance
|
23
|
+
QBWC.logger.info "Job '#{name}' received response: '#{qbxml_response}'." if QBWC.log_requests_and_responses
|
24
|
+
worker.handle_response(response, session, self, completed_request, data)
|
11
25
|
end
|
12
26
|
|
13
|
-
def
|
14
|
-
|
27
|
+
def advance_next_request
|
28
|
+
new_index = request_index + 1
|
29
|
+
QBWC.logger.info "Job '#{name}' advancing to request #'#{new_index}'."
|
30
|
+
self.request_index = new_index
|
15
31
|
end
|
16
32
|
|
17
33
|
def enable
|
18
|
-
|
34
|
+
self.enabled = true
|
19
35
|
end
|
20
36
|
|
21
37
|
def disable
|
22
|
-
|
38
|
+
self.enabled = false
|
39
|
+
end
|
40
|
+
|
41
|
+
def pending?
|
42
|
+
if !enabled?
|
43
|
+
QBWC.logger.info "Job '#{name}' not enabled."
|
44
|
+
return false
|
45
|
+
end
|
46
|
+
sr = worker.should_run?(self)
|
47
|
+
QBWC.logger.info "Job '#{name}' should_run?: #{sr}."
|
48
|
+
return sr
|
23
49
|
end
|
24
50
|
|
25
51
|
def enabled?
|
26
52
|
@enabled
|
27
53
|
end
|
28
54
|
|
29
|
-
def
|
30
|
-
@
|
55
|
+
def requests
|
56
|
+
@requests
|
31
57
|
end
|
32
58
|
|
33
|
-
def
|
34
|
-
@
|
59
|
+
def requests=(r)
|
60
|
+
@requests = r
|
35
61
|
end
|
36
62
|
|
37
|
-
|
63
|
+
def data
|
64
|
+
@data
|
65
|
+
end
|
38
66
|
|
39
|
-
def
|
40
|
-
|
67
|
+
def data=(d)
|
68
|
+
@data = d
|
41
69
|
end
|
42
70
|
|
43
|
-
def
|
44
|
-
|
71
|
+
def request_index
|
72
|
+
@request_index
|
73
|
+
end
|
74
|
+
|
75
|
+
def request_index=(ri)
|
76
|
+
@request_index = ri
|
77
|
+
end
|
78
|
+
|
79
|
+
def requests_provided_when_job_added
|
80
|
+
@requests_provided_when_job_added
|
81
|
+
end
|
82
|
+
|
83
|
+
def requests_provided_when_job_added=(value)
|
84
|
+
@requests_provided_when_job_added = value
|
85
|
+
end
|
86
|
+
|
87
|
+
def next_request
|
88
|
+
# Generate and save the requests to run when starting the job.
|
89
|
+
if (requests.nil? || requests.empty?) && ! self.requests_provided_when_job_added
|
90
|
+
r = worker.requests(self)
|
91
|
+
r = [r] unless r.nil? || r.is_a?(Array)
|
92
|
+
self.requests = r
|
93
|
+
end
|
94
|
+
|
95
|
+
QBWC.logger.info("Requests available are '#{requests}'.") if QBWC.log_requests_and_responses
|
96
|
+
ri = request_index
|
97
|
+
QBWC.logger.info("Request index is '#{ri}'.")
|
98
|
+
return nil if ri.nil? || requests.nil? || ri >= requests.length
|
99
|
+
nr = requests[ri]
|
100
|
+
QBWC.logger.info("Next request is '#{nr}'.") if QBWC.log_requests_and_responses
|
101
|
+
return QBWC::Request.new(nr)
|
102
|
+
end
|
103
|
+
alias :next :next_request # Deprecated method name 'next'
|
104
|
+
|
105
|
+
def reset
|
106
|
+
self.request_index = 0
|
107
|
+
self.requests = [] unless self.requests_provided_when_job_added
|
45
108
|
end
|
46
109
|
|
47
110
|
end
|
data/lib/qbwc/railtie.rb
ADDED
data/lib/qbwc/request.rb
CHANGED
@@ -1,46 +1,37 @@
|
|
1
1
|
class QBWC::Request
|
2
2
|
|
3
3
|
attr_reader :request, :response_proc
|
4
|
-
attr_accessor :response, :error
|
5
4
|
|
6
|
-
def initialize(request
|
5
|
+
def initialize(request)
|
7
6
|
#Handle Cases for a request passed in as a Hash or String
|
8
7
|
#If it's a hash verify that it is properly wrapped with qbxml_msg_rq and xml_attributes for on_error events
|
9
8
|
#Allow strings of QBXML to be passed in directly.
|
10
9
|
case
|
11
10
|
when request.is_a?(Hash)
|
12
|
-
|
13
|
-
|
14
|
-
wrapped_request = { :qbxml_msgs_rq => {:xml_attributes => {"onError"=> QBWC::on_error } } }
|
15
|
-
wrapped_request[:qbxml_msgs_rq] = wrapped_request[:qbxml_msgs_rq].merge(request)
|
16
|
-
request = wrapped_request
|
17
|
-
end
|
18
|
-
|
19
|
-
@request = QBWC.parser.hash_to_qbxml(request)
|
11
|
+
request = self.class.wrap_request(request)
|
12
|
+
@request = QBWC.parser.to_qbxml(request, {:validate => true})
|
20
13
|
when request.is_a?(String)
|
21
14
|
@request = request
|
15
|
+
else
|
16
|
+
raise "Request '#{request}' must be a Hash or a String."
|
22
17
|
end
|
23
|
-
@response_proc = response_proc
|
24
|
-
end
|
25
|
-
|
26
|
-
def process_response
|
27
|
-
@response_proc && @response && @response_proc.call(response)
|
28
18
|
end
|
29
19
|
|
30
20
|
def to_qbxml
|
31
|
-
QBWC.parser.
|
21
|
+
QBWC.parser.to_qbxml(request)
|
32
22
|
end
|
33
23
|
|
34
24
|
def to_hash
|
35
|
-
QBWC.parser.
|
25
|
+
hash = QBWC.parser.from_qbxml(@request.to_s)["qbxml"]["qbxml_msgs_rq"]
|
26
|
+
hash.except('xml_attributes')
|
36
27
|
end
|
37
28
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
29
|
+
# Wrap a Hash request with qbxml_msgs_rq, if it's not already.
|
30
|
+
def self.wrap_request(request)
|
31
|
+
return request if request.keys.include?(:qbxml_msgs_rq)
|
32
|
+
wrapped_request = { :qbxml_msgs_rq => {:xml_attributes => {"onError"=> QBWC::on_error } } }
|
33
|
+
wrapped_request[:qbxml_msgs_rq] = wrapped_request[:qbxml_msgs_rq].merge(request)
|
34
|
+
return wrapped_request
|
44
35
|
end
|
45
36
|
|
46
37
|
end
|
data/lib/qbwc/session.rb
CHANGED
@@ -1,115 +1,143 @@
|
|
1
1
|
class QBWC::Session
|
2
|
-
include Enumerable
|
3
2
|
|
4
|
-
attr_reader :
|
5
|
-
|
3
|
+
attr_reader :user, :company, :ticket, :progress
|
4
|
+
attr_accessor :error, :status_code, :status_severity
|
6
5
|
|
7
6
|
@@session = nil
|
8
7
|
|
9
|
-
|
8
|
+
def self.get(ticket)
|
9
|
+
@@session
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(user = nil, company = nil, ticket = nil)
|
13
|
+
@user = user
|
14
|
+
@company = company
|
10
15
|
@current_job = nil
|
11
|
-
@
|
12
|
-
@
|
16
|
+
@error = nil
|
17
|
+
@progress = 0
|
18
|
+
@iterator_id = nil
|
19
|
+
@initial_job_count = pending_jobs.length
|
13
20
|
|
14
|
-
@
|
15
|
-
@qbwc_iterating = false
|
21
|
+
@ticket = ticket || Digest::SHA1.hexdigest("#{Rails.application.config.secret_token}#{Time.now.to_i}")
|
16
22
|
|
17
23
|
@@session = self
|
18
|
-
reset
|
24
|
+
reset(ticket.nil?)
|
25
|
+
end
|
26
|
+
|
27
|
+
def response_is_error?
|
28
|
+
self.error && self.status_severity == 'Error'
|
19
29
|
end
|
20
30
|
|
21
|
-
def
|
22
|
-
|
23
|
-
enabled_jobs.map { |j| j.reset }
|
24
|
-
@requests = build_request_generator(enabled_jobs)
|
31
|
+
def error_and_stop_requested?
|
32
|
+
response_is_error? && QBWC::on_error == 'stopOnError'
|
25
33
|
end
|
26
34
|
|
27
35
|
def finished?
|
28
|
-
|
36
|
+
self.progress == 100
|
37
|
+
end
|
38
|
+
|
39
|
+
def next_request
|
40
|
+
if current_job.nil? || error_and_stop_requested?
|
41
|
+
self.progress = 100
|
42
|
+
return nil
|
43
|
+
end
|
44
|
+
until (request = current_job.next_request) do
|
45
|
+
pending_jobs.shift
|
46
|
+
reset(true) or break
|
47
|
+
end
|
48
|
+
jobs_completed = @initial_job_count - pending_jobs.length
|
49
|
+
self.progress = ((jobs_completed.to_f / @initial_job_count.to_f ) * 100).to_i
|
50
|
+
request
|
29
51
|
end
|
52
|
+
alias :next :next_request # Deprecated method name 'next'
|
53
|
+
|
54
|
+
def current_request
|
55
|
+
request = self.next_request
|
56
|
+
if request && self.iterator_id.present?
|
57
|
+
request = request.to_hash
|
58
|
+
request.delete('xml_attributes')
|
59
|
+
request.values.first['xml_attributes'] = {'iterator' => 'Continue', 'iteratorID' => self.iterator_id}
|
60
|
+
request = QBWC::Request.new(request)
|
61
|
+
end
|
62
|
+
request
|
63
|
+
end
|
64
|
+
|
65
|
+
def request_to_send
|
66
|
+
current_job_name = current_job.name
|
67
|
+
request = current_request.try(:request) || ''
|
68
|
+
QBWC.logger.info("Sending request from job #{current_job_name}")
|
69
|
+
QBWC.logger.info(request) if QBWC.log_requests_and_responses
|
30
70
|
|
31
|
-
|
32
|
-
@requests.alive? ? @requests.resume : nil
|
71
|
+
request
|
33
72
|
end
|
34
73
|
|
35
74
|
def response=(qbxml_response)
|
36
75
|
begin
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
else
|
43
|
-
@current_request.process_response
|
76
|
+
QBWC.logger.info 'Parsing response.'
|
77
|
+
unless qbxml_response.nil?
|
78
|
+
response = QBWC.parser.from_qbxml(qbxml_response)["qbxml"]["qbxml_msgs_rs"].except("xml_attributes")
|
79
|
+
response = response[response.keys.first]
|
80
|
+
parse_response_header(response)
|
44
81
|
end
|
82
|
+
self.current_job.process_response(qbxml_response, response, self, iterator_id.blank?) unless self.current_job.nil?
|
83
|
+
self.next_request # search next request
|
84
|
+
|
45
85
|
rescue => e
|
46
|
-
|
47
|
-
|
48
|
-
|
86
|
+
self.error = e.message
|
87
|
+
QBWC.logger.warn "An error occured in QBWC::Session: #{e.message}"
|
88
|
+
QBWC.logger.warn e.backtrace.join("\n")
|
49
89
|
end
|
90
|
+
end
|
50
91
|
|
92
|
+
def save
|
51
93
|
end
|
52
94
|
|
53
|
-
def
|
54
|
-
|
95
|
+
def destroy
|
96
|
+
self.freeze
|
97
|
+
@@session = nil
|
55
98
|
end
|
56
99
|
|
57
|
-
|
100
|
+
protected
|
58
101
|
|
59
|
-
|
60
|
-
|
61
|
-
end
|
102
|
+
attr_accessor :current_job, :iterator_id
|
103
|
+
attr_writer :progress
|
62
104
|
|
63
|
-
|
64
|
-
Fiber.new do
|
65
|
-
jobs.each do |j|
|
66
|
-
@current_job = j
|
67
|
-
while (r = next_request)
|
68
|
-
@current_request = r
|
69
|
-
Fiber.yield r
|
70
|
-
end
|
71
|
-
end
|
105
|
+
private
|
72
106
|
|
73
|
-
|
74
|
-
|
75
|
-
|
107
|
+
def reset(reset_job = false)
|
108
|
+
self.current_job = pending_jobs.first
|
109
|
+
self.current_job.reset if reset_job && self.current_job
|
110
|
+
return self.current_job
|
76
111
|
end
|
77
112
|
|
78
|
-
def
|
79
|
-
|
113
|
+
def pending_jobs
|
114
|
+
@pending_jobs ||= QBWC.pending_jobs(@company)
|
80
115
|
end
|
81
116
|
|
82
117
|
def parse_response_header(response)
|
83
|
-
|
118
|
+
QBWC.logger.info 'Parsing headers.'
|
84
119
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
if iterator_remaining_count.to_i > 0
|
93
|
-
@qbwc_iterating = true
|
94
|
-
new_request = @current_request.to_hash
|
95
|
-
new_request.delete('xml_attributes')
|
96
|
-
new_request.values.first['xml_attributes'] = {'iterator' => 'Continue', 'iteratorID' => iterator_id}
|
97
|
-
@qbwc_iterator_queue << QBWC::Request.new(new_request, @current_request.response_proc)
|
98
|
-
else
|
99
|
-
@qbwc_iterating = false
|
100
|
-
end
|
120
|
+
self.iterator_id = nil
|
121
|
+
self.error = nil
|
122
|
+
self.status_code = nil
|
123
|
+
self.status_severity = nil
|
124
|
+
|
125
|
+
if response.is_a? Array
|
126
|
+
response = response.find {|r| r.is_a?(Hash) && r['xml_attributes'] && r['xml_attributes']['statusCode'].to_i > 1} || response.first
|
101
127
|
end
|
102
|
-
|
128
|
+
return unless response.is_a?(Hash) && response['xml_attributes']
|
103
129
|
|
104
|
-
|
130
|
+
@status_code, @status_severity, status_message, iterator_remaining_count, iterator_id = \
|
131
|
+
response['xml_attributes'].values_at('statusCode', 'statusSeverity', 'statusMessage',
|
132
|
+
'iteratorRemainingCount', 'iteratorID')
|
133
|
+
QBWC.logger.info "Parsed headers. statusSeverity: '#{status_severity}'. statusCode: '#{@status_code}'"
|
105
134
|
|
106
|
-
|
107
|
-
|
108
|
-
|
135
|
+
if @status_severity == 'Error' || @status_severity == 'Warn'
|
136
|
+
self.error = "QBWC #{@status_severity.upcase}: #{@status_code} - #{status_message}"
|
137
|
+
@status_severity == 'Error' ? QBWC.logger.error(self.error) : QBWC.logger.warn(self.error)
|
138
|
+
end
|
109
139
|
|
110
|
-
|
140
|
+
self.iterator_id = iterator_id if iterator_remaining_count.to_i > 0 && @status_severity != 'Error'
|
111
141
|
|
112
|
-
|
113
|
-
@@session
|
114
|
-
end
|
142
|
+
end
|
115
143
|
end
|