rbc 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5a3731beac6830ccaeb731bea39085387a18fa60
4
+ data.tar.gz: fefacafc5c889919dfd74a1980ef2db4a7a20662
5
+ SHA512:
6
+ metadata.gz: 3f58393a6e1ad1752f7ea19b773fee346df289bc807547ad16a5182cc86e268d8107ad6e9396e30336ff02f02efa765f770fadcc21f1eb8bec1ffb3abbcce561
7
+ data.tar.gz: 24c0edf06d10c7d91b6eb2995ad369c70102be9424d76ee28c860f9e55e720944c43dd771e9cda3f7cdda491cb2330ce894d41028c53ca57890a834db471a892
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ *.swp
4
+ .bundle
5
+ .config
6
+ coverage
7
+ InstalledFiles
8
+ lib/bundler/man
9
+ pkg
10
+ rdoc
11
+ spec/reports
12
+ test/tmp
13
+ test/key.yaml
14
+ test/version_tmp
15
+ tmp
16
+
17
+ # YARD artifacts
18
+ .yardoc
19
+ _yardoc
20
+ doc/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ ruby '2.1.2'
2
+ source 'https://rubygems.org'
3
+ gemspec
4
+ gem 'curb'
@@ -0,0 +1,112 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rbc (0.2.8)
5
+ httparty (~> 0.9, >= 0.9.0)
6
+ nokogiri (>= 1.5.5)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ celluloid (0.15.2)
12
+ timers (~> 1.1.0)
13
+ coderay (1.1.0)
14
+ coveralls (0.7.0)
15
+ multi_json (~> 1.3)
16
+ rest-client
17
+ simplecov (>= 0.7)
18
+ term-ansicolor
19
+ thor
20
+ curb (0.8.5)
21
+ diff-lcs (1.2.5)
22
+ docile (1.1.5)
23
+ ffi (1.9.3)
24
+ formatador (0.2.5)
25
+ guard (2.6.1)
26
+ formatador (>= 0.2.4)
27
+ listen (~> 2.7)
28
+ lumberjack (~> 1.0)
29
+ pry (>= 0.9.12)
30
+ thor (>= 0.18.1)
31
+ guard-rspec (4.3.1)
32
+ guard (~> 2.1)
33
+ rspec (>= 2.14, < 4.0)
34
+ httparty (0.13.1)
35
+ json (~> 1.8)
36
+ multi_xml (>= 0.5.2)
37
+ json (1.8.1)
38
+ listen (2.7.9)
39
+ celluloid (>= 0.15.2)
40
+ rb-fsevent (>= 0.9.3)
41
+ rb-inotify (>= 0.9)
42
+ lumberjack (1.0.9)
43
+ method_source (0.8.2)
44
+ mime-types (2.3)
45
+ mini_portile (0.6.0)
46
+ multi_json (1.10.1)
47
+ multi_xml (0.5.5)
48
+ netrc (0.7.7)
49
+ nokogiri (1.6.3.1)
50
+ mini_portile (= 0.6.0)
51
+ pry (0.10.0)
52
+ coderay (~> 1.1.0)
53
+ method_source (~> 0.8.1)
54
+ slop (~> 3.4)
55
+ pry-nav (0.2.4)
56
+ pry (>= 0.9.10, < 0.11.0)
57
+ pry-remote (0.1.8)
58
+ pry (~> 0.9)
59
+ slop (~> 3.0)
60
+ rake (10.3.2)
61
+ rb-fsevent (0.9.4)
62
+ rb-inotify (0.9.5)
63
+ ffi (>= 0.5.0)
64
+ rest-client (1.7.2)
65
+ mime-types (>= 1.16, < 3.0)
66
+ netrc (~> 0.7)
67
+ rspec (3.0.0)
68
+ rspec-core (~> 3.0.0)
69
+ rspec-expectations (~> 3.0.0)
70
+ rspec-mocks (~> 3.0.0)
71
+ rspec-core (3.0.3)
72
+ rspec-support (~> 3.0.0)
73
+ rspec-expectations (3.0.3)
74
+ diff-lcs (>= 1.2.0, < 2.0)
75
+ rspec-support (~> 3.0.0)
76
+ rspec-mocks (3.0.3)
77
+ rspec-support (~> 3.0.0)
78
+ rspec-nc (0.1.1)
79
+ rspec (>= 2.9)
80
+ terminal-notifier (>= 1.4)
81
+ rspec-support (3.0.3)
82
+ simplecov (0.9.0)
83
+ docile (~> 1.1.0)
84
+ multi_json
85
+ simplecov-html (~> 0.8.0)
86
+ simplecov-html (0.8.0)
87
+ slop (3.6.0)
88
+ term-ansicolor (1.3.0)
89
+ tins (~> 1.0)
90
+ terminal-notifier (1.6.1)
91
+ terminal-notifier-guard (1.5.3)
92
+ thor (0.19.1)
93
+ timers (1.1.0)
94
+ tins (1.3.0)
95
+
96
+ PLATFORMS
97
+ ruby
98
+
99
+ DEPENDENCIES
100
+ bundler (~> 1.6)
101
+ coveralls
102
+ curb
103
+ guard
104
+ guard-rspec
105
+ pry
106
+ pry-nav
107
+ pry-remote
108
+ rake
109
+ rbc!
110
+ rspec
111
+ rspec-nc
112
+ terminal-notifier-guard
@@ -0,0 +1,11 @@
1
+ guard :rspec, cmd: 'bundle exec rspec' do
2
+ # watch /lib/ files
3
+ watch(%r{^lib/(.+).rb$}) do |m|
4
+ "spec/#{m[1]}_spec.rb"
5
+ end
6
+
7
+ # watch /spec/ files
8
+ watch(%r{^spec/(.+).rb$}) do |m|
9
+ "spec/#{m[1]}.rb"
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ rbc
2
+ ===
3
+
4
+ A ruby client for interacting with the IMS BioSpecimen Inventory system
@@ -0,0 +1,44 @@
1
+ require 'rspec/core/rake_task'
2
+ require 'bundler/gem_tasks'
3
+ require 'nokogiri'
4
+ require 'curb'
5
+ require 'yaml'
6
+
7
+ namespace :fetch do
8
+ desc "Fetch list of service endpoints and methods and store to file"
9
+ task "services" do
10
+ hosts = {
11
+ :dev => 'http://www506.imsweb.com/wsapi-dev/bsi/webservices/service/',
12
+ :prod => 'http://www506.imsweb.com/wsapi-prod/bsi/webservices/service/'
13
+ }
14
+
15
+ root = 'package-frame.html'
16
+
17
+ host = hosts[:dev]
18
+ page = `http #{hosts[:dev]+root}`
19
+ doc = Nokogiri::HTML.parse(page)
20
+
21
+ services = {}
22
+ doc.xpath('//a')[1..-1].each do |link|
23
+ service = link.content.gsub(/(^(?<s>[a-zA-Z]+)Service)/, '\k<s>').downcase.to_sym
24
+ services[service] = {
25
+ :doc_link => host + link.attributes['href'].value,
26
+ :methods => []
27
+ }
28
+ end
29
+
30
+ services.values.each do |service|
31
+ page = `http #{service[:doc_link]}`
32
+ doc = Nokogiri::HTML.parse(page)
33
+ methods = doc.xpath('//code/b/a').map{|node| node.content}
34
+ service[:methods] = methods.grep(/^[a-z]+/)
35
+ end
36
+
37
+ File.open('./lib/service_spec.yaml', 'wb') do |f|
38
+ f.write(services.to_yaml)
39
+ end
40
+
41
+ end
42
+ end
43
+
44
+ task :default => :spec
@@ -0,0 +1,64 @@
1
+ require 'yaml'
2
+ require 'rbc/version'
3
+ require 'rbc/bsi'
4
+
5
+ class RBC
6
+ include RBCVersion
7
+ include BSIServices
8
+ BSI_INSTANCES = {
9
+ :mirror => 'https://websvc-mirror.bsisystems.com:2271/bsi/xmlrpc',
10
+ :staging => 'https://websvc-mirror.bsisystems.com:2271/bsi/xmlrpc',
11
+ :production => 'https://websvc.bsisystems.com:2262/bsi/xmlrpc'
12
+ }
13
+
14
+ attr_accessor :session_id, :url_target, :creds, :test, :common
15
+
16
+ services = YAML::load(File.open(File.join(File.dirname(__FILE__), 'service_spec.yaml')))
17
+ (services.keys-[:test, :common]).each do |s|
18
+ klass = Class.new(BSIModule)
19
+ attr_accessor s
20
+ self.const_set(s.to_s.capitalize, klass)
21
+ end
22
+
23
+ # Initialize connection based on provided credentials
24
+ def initialize(creds, options={:debug=>false, :stealth=>false, :instance=>:mirror})
25
+ raise ArgumentError, """
26
+ No credentials hash provided, expected a hash in the form of:
27
+ {
28
+ :user => 'username',
29
+ :pass => 'password',
30
+ :server => 'MYBSIDATABASE',
31
+ }
32
+ """ if creds.class != Hash || creds[:user].nil? || creds[:pass].nil? || creds[:server].nil?
33
+ raise ArgumentError, 'Please provide either a valid instance or specify a custom url using option key :url => \'https://...\'' if BSI_INSTANCES[options[:instance]].nil? && options[:url].nil? && options[:stealth]==false
34
+ options[:url] = BSI_INSTANCES[options[:instance]] unless options[:url]
35
+ self.url_target = options[:url]
36
+
37
+ raise RuntimError, "Invalid url" unless url_target.match(/^https?:\/\/(.+):\d{4}\/bsi\/xmlrpc$/)
38
+
39
+ self.session_id = creds[:session_id] if creds[:session_id]
40
+ services = YAML::load(File.open(File.join(File.dirname(__FILE__), 'service_spec.yaml')))
41
+ (services.keys).each do |k|
42
+ instance_eval(
43
+ "self.#{k} = #{k.to_s.capitalize}.new(creds, options.merge( { :methods => services[k][:methods] } ) )"
44
+ )
45
+ end
46
+
47
+ @test = Test.new(creds, options)
48
+ @common = Common.new(creds, options)
49
+ =begin
50
+ # Initialize BSI service connection adaptors
51
+ @attachment = Attachment.new(creds, options.merge({:methods => %w(download) } ) )
52
+ @batch = Batch.new(creds, options.merge( { :methods => %w(addVials commit create delete get getBatchProperties getHeaders getVialProperties performL1Checks performL2Checks removeVials update updateVials reserveAvailableBsiIds)}) )
53
+ @database = Database.new(creds, options.merge( { :methods => %w(getFields getTables normalizeValues)}) )
54
+ @shipment = Shipment.new(creds, options.merge( { :methods => %w(getProperties getShipment submit update uploadManifest updateDiscrepancyResolutionSuggestions)}) )
55
+ @requisition= Requisition.new(creds, options.merge( { :methods => %w(addVials getAttachments getProperties getReqDiscrepancies removeVials save submit submitSavedRequisitions update updateDiscrepancyResolutions updatePriorities uploadAttachment uploadManifest)}) )
56
+ @reults = Report.new(creds, options.merge( { :methods => %w(createResultsBatch)}) )
57
+ @report = Report.new(creds, options.merge( { :methods => %w(count execute)}) )
58
+ @study = Study.new(creds, options.merge( { :methods => %w(getAttachments)}) )
59
+ @user = User.new(creds, options.merge( { :methods => %w(authorize create getInfo update)}) )
60
+ @subject = Subject.new(creds, options.merge( { :methods => %w(deleteSubject getAttachments getSubject getSubjectProperties performL1Checks performL2Checks saveNewSubject saveSubject)}) )
61
+ =end
62
+ @common.logon if @session_id.nil?
63
+ end
64
+ end
@@ -0,0 +1,325 @@
1
+ module Marshaling
2
+ require 'Nokogiri'
3
+ require 'httparty'
4
+ require 'base64'
5
+ ####################################
6
+ # Exceptions #
7
+ ####################################
8
+
9
+ # General exception
10
+ class Error < StandardError
11
+
12
+ attr_reader :message, :code
13
+ attr_accessor :action
14
+ def initialize(code=nil, message=nil, action=nil)
15
+ @message = message
16
+ @code = code
17
+ @action = action
18
+ end
19
+
20
+ def to_s
21
+ "#{@code}: #{@message}"
22
+ end
23
+
24
+ end
25
+
26
+ class IncorrectMethodSignature < Error; end
27
+ class IncorrectMethodSignature < Error; end
28
+
29
+ # Exception dispatcher based on error logged by BSI
30
+
31
+ class Marshaler
32
+
33
+ SSL_RETRY_LIMIT = 5
34
+
35
+ def generate_exception(code, message)
36
+ case code
37
+ when 9000
38
+ # 9000 level
39
+ case message
40
+ when 'Logon failed: Broken pipe'
41
+ raise Error.new(code, message, 'retry')
42
+ end
43
+ else
44
+ raise Error.new(code, message)
45
+ end
46
+ end
47
+
48
+ def initialize(url, options={:verify=>true})
49
+ @target_url = url
50
+ @debug = options[:debug]
51
+ @stealth = options[:stealth]
52
+ @verify_ssl = options[:verify]
53
+ end
54
+
55
+ # Build xml for submission
56
+ def build_call(method_name, *arguments)
57
+
58
+ builder = Nokogiri::XML::Builder.new do |xml|
59
+ xml.methodCall{
60
+ xml.methodName_ method_name.gsub(/_/, '.')
61
+ xml.params{
62
+ arguments.each do |a|
63
+ xml.param{
64
+ unless a.nil?
65
+ type = a.class.to_s.downcase
66
+ send("#{type}_to_xml", xml, a)
67
+ else
68
+ raise "Nil is not an acceptable argument for method: #{method_name}#{arguments.to_s.gsub(/\]/, ')').gsub(/\[/, '(')}"
69
+ end
70
+ }
71
+ end
72
+ }
73
+ }
74
+ end
75
+
76
+ # Submit xml to them
77
+ send_xml( builder.to_xml )
78
+ end
79
+
80
+ def parse(xml)
81
+
82
+ # Handle Errors appropriately
83
+ unless xml['methodResponse'].keys.include?('fault')
84
+ type = xml['methodResponse']['params']['param']['value'].keys.pop
85
+ # Handle happy path, no errors
86
+ send("convert_#{type}".to_sym, xml['methodResponse']['params']['param']['value'][type])
87
+ else
88
+ # Error occurred, extract it, notify
89
+ code = xml['methodResponse']['fault']['value']['struct']['member'][0]['value']['int'].to_i
90
+ message = xml['methodResponse']['fault']['value']['struct']['member'][1]['value']['string']
91
+ # How we should generate exceptions
92
+ generate_exception(code, message)
93
+ end
94
+ end
95
+
96
+ def send_xml( xml)
97
+
98
+ options = {:body => xml}
99
+ if @target_url.match(/https/)
100
+ options.merge!(:ssl_version=>:SSLv3)
101
+ options.merge!(:verify => @verify_ssl)
102
+ end
103
+ if @debug
104
+ puts "Sending:"
105
+ puts xml
106
+ puts ""
107
+ end
108
+
109
+ try_num = 0
110
+ unless @stealth
111
+ begin
112
+ response = HTTParty.post(@target_url, options)
113
+ rescue OpenSSL::SSL::SSLError => e
114
+ if try_num < SSL_RETRY_LIMIT
115
+ try_num = try_num + 1
116
+ puts "SSL error. Retry #{try_num}"
117
+ retry
118
+ else
119
+ raise e
120
+ end
121
+ rescue Error => e
122
+ puts 'Broken Pipe error, retrying'
123
+ retry if e.action == 'retry'
124
+ end
125
+ end
126
+
127
+ unless @stealth
128
+ if @debug
129
+ puts "Recieved:"
130
+ puts Nokogiri::XML(response.body, &:noblanks)
131
+ end
132
+
133
+ parse(response)
134
+ end
135
+
136
+ end
137
+
138
+ def test_send_xml(xml)
139
+ puts xml
140
+ end
141
+
142
+
143
+ # Methods to convert ruby structures into XML in the format BSI expects
144
+ def float_to_xml(noko, float)
145
+ noko.value{
146
+ noko.float_ float
147
+ }
148
+ end
149
+
150
+ def enumerator_to_xml(noko, enumerator)
151
+ # this should only be exercised when trying to pass a byte array
152
+ # this should be sent enclosed in <base64> and encoded as such
153
+
154
+ noko.value{
155
+ noko.base64_ Base64.encode64(enumerator.to_a.pack('c*'))
156
+ }
157
+
158
+ end
159
+
160
+ def array_to_xml(noko, array)
161
+ noko.value{
162
+ noko.array{
163
+ noko.data{
164
+ array.each do |e|
165
+ send("#{e.class.to_s.downcase}_to_xml".to_sym, noko, e)
166
+ end
167
+ }
168
+ }
169
+ }
170
+ end
171
+
172
+ def hash_to_xml(noko, hash)
173
+ noko.value{
174
+ noko.struct{
175
+ hash.each do |k,v|
176
+ noko.member{
177
+ noko.name_ k.to_s
178
+ send("#{v.class.to_s.downcase}_to_xml".to_sym, noko, v) unless v.nil?
179
+ }
180
+ end
181
+ }
182
+ }
183
+ end
184
+
185
+ def string_to_xml(noko, string)
186
+ noko.value{
187
+ noko.string_ string
188
+ }
189
+ end
190
+
191
+ def fixnum_to_xml(noko, int)
192
+ noko.value{
193
+ noko.int_ int
194
+ }
195
+ end
196
+
197
+ def convert_struct(xml)
198
+ hash = Hash.new
199
+ xml['member'].each do |e|
200
+ member_name = e['name']
201
+ member_value_type = e['value'].keys.first
202
+ member_value = send("convert_#{ member_value_type.gsub(/\./, '_') }".to_sym, e['value'][member_value_type] )
203
+ hash.store( member_name, member_value )
204
+ end
205
+ hash
206
+ end
207
+
208
+ def convert_array(xml)
209
+ array = Array.new
210
+ unless xml['data'].nil?
211
+ case xml['data']['value'].class.to_s.downcase
212
+ when 'array'
213
+ xml['data']['value'].each do |e|
214
+ member_type = e.keys.first
215
+ member_value = e[member_type]
216
+ array << send( "convert_#{member_type}".to_sym, member_value )
217
+ end
218
+ when 'hash'
219
+ member_type = xml['data']['value'].keys.first
220
+ member_value = xml['data']['value'][member_type]
221
+ array << send( "convert_#{member_type.gsub(/\./, '_')}".to_sym, member_value )
222
+ end
223
+ else
224
+ array = nil
225
+ end
226
+ array
227
+ end
228
+
229
+ # Methods to convert XML BSI sends back to us into ruby
230
+ def convert_int(xml)
231
+ xml.to_i
232
+ end
233
+
234
+ def convert_boolean(xml)
235
+ xml
236
+ end
237
+
238
+ def convert_nil(xml)
239
+ nil
240
+ end
241
+
242
+ def convert_string(xml)
243
+ xml
244
+ end
245
+
246
+ def convert_dateTime_iso8601(xml)
247
+ DateTime.parse(xml)
248
+ end
249
+ end
250
+ end
251
+
252
+ module BSIServices
253
+ #
254
+ # Parent class of a standard BSIService
255
+ #
256
+ class BSIModule
257
+ include Marshaling
258
+ @@target_url = nil
259
+ @@session_id = nil
260
+ @@debug = false
261
+
262
+ def initialize(creds, options={})
263
+ methods = []
264
+ methods = options[:methods] if options[:methods]
265
+ @@debug = options[:debug]
266
+ @@stealth = options[:stealth]
267
+ @@session_id = creds[:session_id] if creds[:session_id]
268
+ @@target_url = options[:url]
269
+ @@marshal = Marshaler.new(@@target_url, options)
270
+ add_methods(methods)
271
+ end
272
+
273
+ def add_methods(methods)
274
+ methods.each do |meth|
275
+ define_singleton_method meth, ->(*arguments) { @@marshal.build_call( "#{self.class.to_s.split('::').last.downcase}.#{__method__}", *arguments.unshift( @@session_id ) ) }
276
+ end
277
+ end
278
+
279
+ end
280
+
281
+ #
282
+ # Special standard services that behave differently than the rest
283
+ #
284
+ class Test < BSIModule
285
+
286
+ def add(*arguments)
287
+ @@marshal.build_call('test.add', *arguments)
288
+ end
289
+
290
+ def echo(string)
291
+ @@marshal.build_call('test.echo', string)
292
+ end
293
+
294
+ end
295
+
296
+ class Common < BSIModule
297
+ # Special class where we don't want to pass SESSION_ID to all of its methods
298
+
299
+ def initialize(creds, options={})
300
+ @creds = creds
301
+ super
302
+ end
303
+
304
+ def logon
305
+ session_id = @@marshal.build_call( 'common.logon', @creds[:user], @creds[:pass], @creds[:server] )
306
+ if @@stealth
307
+ @@session_id = 'DUMMY-SESSION-ID'
308
+ else
309
+ @@session_id = session_id
310
+ end
311
+ end
312
+
313
+ def logoff
314
+ @@marshal.build_call('common.logoff', @@session_id)
315
+ end
316
+
317
+ end
318
+
319
+ class Batch < BSIModule
320
+ def reserveNextBsiId( batch_id, sample_id_template)
321
+ reserveAvailableBsiIds( batch_id, sample_id_template, 1).first
322
+ end
323
+ end
324
+
325
+ end
@@ -0,0 +1,3 @@
1
+ module RBCVersion
2
+ VERSION = "0.2.8"
3
+ end
@@ -0,0 +1,156 @@
1
+ ---
2
+ :attachment:
3
+ :doc_link: http://www506.imsweb.com/wsapi-dev/bsi/webservices/service/AttachmentService.html
4
+ :methods:
5
+ - download
6
+ :batch:
7
+ :doc_link: http://www506.imsweb.com/wsapi-dev/bsi/webservices/service/BatchService.html
8
+ :methods:
9
+ - addVials
10
+ - commit
11
+ - create
12
+ - delete
13
+ - get
14
+ - getBatchProperties
15
+ - getHeaders
16
+ - getVialProperties
17
+ - performL1Checks
18
+ - performL2Checks
19
+ - removeVials
20
+ - reserveAvailableBsiIds
21
+ - update
22
+ - updateVials
23
+ :billing:
24
+ :doc_link: http://www506.imsweb.com/wsapi-dev/bsi/webservices/service/BillingService.html
25
+ :methods:
26
+ - run
27
+ :cabig:
28
+ :doc_link: http://www506.imsweb.com/wsapi-dev/bsi/webservices/service/CABigService.html
29
+ :methods:
30
+ - getAvailableSpecimenCount
31
+ - getSpecimenCount
32
+ - getSpecimenFields
33
+ - getSpecimens
34
+ - logoff
35
+ - logon
36
+ :codelist:
37
+ :doc_link: http://www506.imsweb.com/wsapi-dev/bsi/webservices/service/CodeListService.html
38
+ :methods:
39
+ - synchCodeList
40
+ :common:
41
+ :doc_link: http://www506.imsweb.com/wsapi-dev/bsi/webservices/service/CommonService.html
42
+ :methods:
43
+ - checkPermission
44
+ - logoff
45
+ - logon
46
+ - ping
47
+ - setForgottenPassword
48
+ - webLogon
49
+ :database:
50
+ :doc_link: http://www506.imsweb.com/wsapi-dev/bsi/webservices/service/DatabaseService.html
51
+ :methods:
52
+ - getFields
53
+ - getTables
54
+ - normalizeValues
55
+ :intrak:
56
+ :doc_link: http://www506.imsweb.com/wsapi-dev/bsi/webservices/service/InTrakService.html
57
+ :methods:
58
+ - notifyDataModification
59
+ - notifyEventComplete
60
+ - notifyShipmentReceived
61
+ - notifyShipmentSpecimensReceived
62
+ - notifyShipTaskDataUpdated
63
+ - notifySpecimensAliquotted
64
+ - notifySpecimensDestroyed
65
+ - notifySpecimensRelabeled
66
+ - notifySpecimensReturned
67
+ - notifySpecimensShipped
68
+ :ireport:
69
+ :doc_link: http://www506.imsweb.com/wsapi-dev/bsi/webservices/service/IReportService.html
70
+ :methods:
71
+ - getDisplayTables
72
+ - getReport
73
+ - getReportDirectoryStructure
74
+ - getReportsInFolder
75
+ - saveReport
76
+ :kit:
77
+ :doc_link: http://www506.imsweb.com/wsapi-dev/bsi/webservices/service/KitService.html
78
+ :methods:
79
+ - updateStatus
80
+ :ladds:
81
+ :doc_link: http://www506.imsweb.com/wsapi-dev/bsi/webservices/service/LADDSService.html
82
+ :methods:
83
+ - upload
84
+ :report:
85
+ :doc_link: http://www506.imsweb.com/wsapi-dev/bsi/webservices/service/ReportService.html
86
+ :methods:
87
+ - count
88
+ - count
89
+ - execute
90
+ - execute
91
+ :requisition:
92
+ :doc_link: http://www506.imsweb.com/wsapi-dev/bsi/webservices/service/RequisitionService.html
93
+ :methods:
94
+ - addVials
95
+ - changeRequisitionVialApprovalStatus
96
+ - checkAuthorization
97
+ - getAttachments
98
+ - getBsiIdsRequiringApproval
99
+ - getProperties
100
+ - getReqDiscrepancies
101
+ - removeVials
102
+ - save
103
+ - submit
104
+ - submit
105
+ - submitSavedRequisition
106
+ - update
107
+ - updateDiscrepancyResolutionSuggestions
108
+ - updatePriorities
109
+ - uploadAttachment
110
+ - uploadManifest
111
+ :results:
112
+ :doc_link: http://www506.imsweb.com/wsapi-dev/bsi/webservices/service/ResultsService.html
113
+ :methods:
114
+ - createResultsBatch
115
+ - createResultsBatch
116
+ - getProcedureDescription
117
+ - getResultsRunData
118
+ - saveResultsRunData
119
+ :shipment:
120
+ :doc_link: http://www506.imsweb.com/wsapi-dev/bsi/webservices/service/ShipmentService.html
121
+ :methods:
122
+ - addVials
123
+ - getProperties
124
+ - getShipment
125
+ - submit
126
+ - submit
127
+ - update
128
+ - updateDiscrepancyResolutionSuggestions
129
+ - uploadManifest
130
+ :study:
131
+ :doc_link: http://www506.imsweb.com/wsapi-dev/bsi/webservices/service/StudyService.html
132
+ :methods:
133
+ - getAttachments
134
+ :subject:
135
+ :doc_link: http://www506.imsweb.com/wsapi-dev/bsi/webservices/service/SubjectService.html
136
+ :methods:
137
+ - deleteSubject
138
+ - getAttachments
139
+ - getSubject
140
+ - getSubjectProperties
141
+ - performL1Checks
142
+ - performL2Checks
143
+ - saveNewSubject
144
+ - saveSubject
145
+ :test:
146
+ :doc_link: http://www506.imsweb.com/wsapi-dev/bsi/webservices/service/TestService.html
147
+ :methods:
148
+ - add
149
+ - echo
150
+ :user:
151
+ :doc_link: http://www506.imsweb.com/wsapi-dev/bsi/webservices/service/UserService.html
152
+ :methods:
153
+ - authorize
154
+ - create
155
+ - getInfo
156
+ - update
@@ -0,0 +1,39 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) << File.expand_path('../lib', __FILE__)
4
+ require 'rbc/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ # Metadata
8
+ s.name = 'rbc'
9
+ s.version = RBCVersion::VERSION
10
+ s.authors = ['Elijah Christensen']
11
+ s.email = ['ejd.christensen@gmail.com']
12
+ s.summary = 'A ruby client for managing interactions with the IMS BioSpecimen Inventory system'
13
+ s.platform = Gem::Platform::RUBY
14
+ s.homepage = 'https://github.com/elijahc/rbc'
15
+ s.license = 'MIT'
16
+
17
+ # Manifest
18
+ s.files = `git ls-files`.split(/\n/)
19
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
21
+ s.require_paths = ['lib']
22
+
23
+ # Development Dependencies
24
+ s.add_development_dependency "bundler", "~> 1.6"
25
+ s.add_development_dependency "rake"
26
+ s.add_development_dependency "rspec"
27
+ s.add_development_dependency "rspec-nc"
28
+ s.add_development_dependency "guard"
29
+ s.add_development_dependency "guard-rspec"
30
+ s.add_development_dependency "terminal-notifier-guard"
31
+ s.add_development_dependency "pry"
32
+ s.add_development_dependency "pry-remote"
33
+ s.add_development_dependency "pry-nav"
34
+ s.add_development_dependency "coveralls"
35
+
36
+ # Runtime Dependencies
37
+ s.add_runtime_dependency('nokogiri', ['>= 1.5.5'])
38
+ s.add_runtime_dependency('httparty', '~> 0.9', '>= 0.9.0')
39
+ end
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0"?>
2
+ <methodCall>
3
+ <methodName>examples.getStateName</methodName>
4
+ <params>
5
+ <param>
6
+ <value><i4>41</i4></value>
7
+ </param>
8
+ </params>
9
+ </methodCall>
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe RBC do
4
+
5
+ it 'has a version number' do
6
+ expect(RBC::VERSION).not_to be_nil
7
+ expect(RBC::VERSION).to be_instance_of String
8
+ end
9
+
10
+ describe '#new' do
11
+ it 'expects a Hash' do
12
+ expect{RBC.new}.to raise_error(ArgumentError)
13
+ expect{RBC.new([])}.to raise_error(ArgumentError)
14
+ expect{RBC.new({:user => 'me'})}.to raise_error(ArgumentError)
15
+ expect{RBC.new({:user => 'me', :pass => 'too'})}.to raise_error(ArgumentError)
16
+ end
17
+
18
+ it 'takes an optional instance parameter' do
19
+ @bsi = RBC.new({:user => 'me', :pass => 'pass', :server => 'server'}, {:instance => :mirror})
20
+ expect(@bsi.url_target).to eq(RBC::BSI_INSTANCES[:mirror])
21
+ end
22
+ end
23
+
24
+
25
+ end
@@ -0,0 +1,9 @@
1
+ require 'coveralls'
2
+ Coveralls.wear!
3
+
4
+ require 'pry'
5
+ require 'rbc'
6
+
7
+ RSpec.configure do |config|
8
+ config.expect_with :rspec
9
+ end
@@ -0,0 +1,53 @@
1
+ require 'rbc'
2
+ require 'yaml'
3
+ require 'test/unit'
4
+
5
+ class TestRBC < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @creds = YAML::load(File.open( './test/key.yaml' ))
9
+ @bsi = RBC.new(@creds, {:debug => true, :stealth => true})
10
+ end
11
+
12
+ def teardown
13
+ @bsi.logoff
14
+ end
15
+
16
+ def test_init
17
+
18
+ assert('RBC', @bsi.class)
19
+ end
20
+
21
+ def test_add
22
+ assert_equal( 4, @bsi.test.add(1,3) )
23
+ end
24
+
25
+ def test_echo
26
+ assert_equal( 'You said: Hi there BSI', @bsi.test.echo('Hi there BSI') )
27
+ end
28
+
29
+ def test_batch_create
30
+ batch_props = Hash.new
31
+ batch_props.store('batch.acess_level', "1")
32
+ batch_props.store('batch.description', 'Add Batch example')
33
+ batch_props.store('batch.template_path', '/system/templates/default')
34
+ batch_props.store('batch_req_verification', '0')
35
+
36
+ end
37
+
38
+ def test_report_execute
39
+
40
+ report_spec = [{:field => 'vial.bsi_id', :operator => 'not equals', :value => '@@Missing'}]
41
+ display = ['vial.bsi_id']
42
+ report = @bsi.report_execute(report_spec, display, ['vial.bsi_id'], 0, 1)
43
+
44
+ end
45
+
46
+ def test_report_count
47
+ report_spec = [ {:field => 'vial.bsi_id', :operator => 'not equals', :value => '@@Missing'}
48
+ ]
49
+ display = ['requisition.requisition_id', '+req_repository.req_status']
50
+ count = @bsi.report_count(report_spec, display)
51
+ end
52
+
53
+ end
metadata ADDED
@@ -0,0 +1,251 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rbc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.8
5
+ platform: ruby
6
+ authors:
7
+ - Elijah Christensen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-nc
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: guard-rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: terminal-notifier-guard
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: pry
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: pry-remote
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: pry-nav
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: coveralls
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: nokogiri
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: 1.5.5
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: 1.5.5
181
+ - !ruby/object:Gem::Dependency
182
+ name: httparty
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '0.9'
188
+ - - ">="
189
+ - !ruby/object:Gem::Version
190
+ version: 0.9.0
191
+ type: :runtime
192
+ prerelease: false
193
+ version_requirements: !ruby/object:Gem::Requirement
194
+ requirements:
195
+ - - "~>"
196
+ - !ruby/object:Gem::Version
197
+ version: '0.9'
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ version: 0.9.0
201
+ description:
202
+ email:
203
+ - ejd.christensen@gmail.com
204
+ executables: []
205
+ extensions: []
206
+ extra_rdoc_files: []
207
+ files:
208
+ - ".gitignore"
209
+ - Gemfile
210
+ - Gemfile.lock
211
+ - Guardfile
212
+ - README.md
213
+ - Rakefile
214
+ - lib/rbc.rb
215
+ - lib/rbc/bsi.rb
216
+ - lib/rbc/version.rb
217
+ - lib/service_spec.yaml
218
+ - rbc.gemspec
219
+ - ref/xml_post_example.xml
220
+ - spec/rbc_spec.rb
221
+ - spec/spec_helper.rb
222
+ - test/test_rbc.rb
223
+ homepage: https://github.com/elijahc/rbc
224
+ licenses:
225
+ - MIT
226
+ metadata: {}
227
+ post_install_message:
228
+ rdoc_options: []
229
+ require_paths:
230
+ - lib
231
+ required_ruby_version: !ruby/object:Gem::Requirement
232
+ requirements:
233
+ - - ">="
234
+ - !ruby/object:Gem::Version
235
+ version: '0'
236
+ required_rubygems_version: !ruby/object:Gem::Requirement
237
+ requirements:
238
+ - - ">="
239
+ - !ruby/object:Gem::Version
240
+ version: '0'
241
+ requirements: []
242
+ rubyforge_project:
243
+ rubygems_version: 2.2.2
244
+ signing_key:
245
+ specification_version: 4
246
+ summary: A ruby client for managing interactions with the IMS BioSpecimen Inventory
247
+ system
248
+ test_files:
249
+ - spec/rbc_spec.rb
250
+ - spec/spec_helper.rb
251
+ - test/test_rbc.rb