vistarpc4r 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "shoulda", ">= 0"
10
+ gem "bundler", "~> 1.0.0"
11
+ gem "jeweler", "~> 1.6.0"
12
+ gem "rcov", ">= 0"
13
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,20 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ git (1.2.5)
5
+ jeweler (1.6.0)
6
+ bundler (~> 1.0.0)
7
+ git (>= 1.2.5)
8
+ rake
9
+ rake (0.9.0)
10
+ rcov (0.9.9)
11
+ shoulda (2.11.3)
12
+
13
+ PLATFORMS
14
+ ruby
15
+
16
+ DEPENDENCIES
17
+ bundler (~> 1.0.0)
18
+ jeweler (~> 1.6.0)
19
+ rcov
20
+ shoulda
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Mike Cham
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,19 @@
1
+ = vistarpc4r
2
+
3
+ Description goes here.
4
+
5
+ == Contributing to vistarpc4r
6
+
7
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
8
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
9
+ * Fork the project
10
+ * Start a feature/bugfix branch
11
+ * Commit and push until you are happy with your contribution
12
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2011 Mike Cham. See LICENSE.txt for
18
+ further details.
19
+
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "vistarpc4r"
18
+ gem.homepage = "http://github.com/michaelcham/vistarpc4r"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Provides capability to make rpc calls to VistA EHR systems that have rpcbroker running}
21
+ gem.description = %Q{more}
22
+ gem.email = "mike@blenderhouse.com"
23
+ gem.authors = ["Mike Cham"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+
35
+ require 'rcov/rcovtask'
36
+ Rcov::RcovTask.new do |test|
37
+ test.libs << 'test'
38
+ test.pattern = 'test/**/test_*.rb'
39
+ test.verbose = true
40
+ test.rcov_opts << '--exclude "gems/*"'
41
+ end
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "vistarpc4r #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,62 @@
1
+ require 'rpc_broker_connection'
2
+
3
+ #broker = RPCBrokerConnection.new('192.168.1.20', 9270, 'sys.admin', 'vista!123')
4
+ broker = RPCBrokerConnection.new('openvista.medsphere.org', 9201, 'PU1234', 'PU1234!!', false)
5
+
6
+ broker.connect
7
+ broker.setContext('OR CPRS GUI CHART')
8
+
9
+ dfn = "4" # internal id of the patient, CLINICAL, Male
10
+ provider ="42" #internal id of care provider Physican, User
11
+ # Problem list
12
+ puts "Problem list-------------------------------------"
13
+ vrpc = VistaRPC.new("ORQQPL LIST", RPCResponse::ARRAY)
14
+ vrpc.params[0]=dfn #patient ien
15
+ vrpc.params[1]="A"
16
+ resp = broker.execute(vrpc)
17
+ resp.value.each do |d|
18
+ puts d
19
+ end
20
+
21
+ # Get Basic patient information that is used for problem list modification RPCs
22
+ vrpc = VistaRPC.new("ORQQPL INIT PT", RPCResponse::ARRAY)
23
+ vrpc.params[0]=dfn
24
+ resp = broker.execute(vrpc)
25
+ ptVAMC=resp.value[0] # := copy(Alist[i],1,999);
26
+ ptDead=resp.value[1] # := AList[i];
27
+ ptBID=resp.value[6] # := Alist[i];
28
+ ptname=""
29
+ gmpdfn = dfn + "^" + ptname + "^" + ptBID + "^" + ptDead
30
+ puts gmpdfn
31
+
32
+ # Add a new problem
33
+ vrpc = VistaRPC.new("ORQQPL ADD SAVE", RPCResponse::ARRAY)
34
+ vrpc.params[0]=gmpdfn
35
+ vrpc.params[1]= provider
36
+ vrpc.params[2]= ptVAMC
37
+ vrpc.params[3] = [
38
+ ["1", "GMPFLD(.01)=\"\"\"819.01\"\"\""], # Diagnosis
39
+ ["2", "GMPFLD(.05)=\"\"\"^nietest\"\"\""], # Narrative
40
+ ["3", "GMPFLD(.12)=\"\"\"A\"\"\""], # status A?
41
+ ["4", "GMPFLD(.13)=\"\"\"\"\"\""], # Date of onset
42
+ ["5", "GMPFLD(1.01)=\"\"\"\"\"\""], # Problem
43
+ ["6", "GMPFLD(10,0)=\"\"\"\"\"\""] # Note
44
+ ]
45
+ resp=broker.execute(vrpc)
46
+ puts resp
47
+
48
+ vrpc = VistaRPC.new("ORQQPL LIST", RPCResponse::ARRAY)
49
+ vrpc.params[0]=dfn #patient ien
50
+ vrpc.params[1]="A"
51
+ resp = broker.execute(vrpc)
52
+ resp.value.each do |d|
53
+ puts d
54
+ end
55
+
56
+ #vrpc = VistaRPC.new("ORQQPL DELETE", RPCResponse::SINGLE_VALUE)
57
+ #vrpc.params[0]="34"
58
+ #vrpc.params[1]=provider
59
+ #vrpc.params[2]=ptVAMC
60
+ #vrpc.params[3]="Because"
61
+ #resp=broker.execute(vrpc)
62
+ #puts resp
@@ -0,0 +1,429 @@
1
+ require 'socket'
2
+ #require 'rpc_response'
3
+ #require 'vista_rpc'
4
+
5
+ module VistaRPC4r
6
+ class RPCBrokerConnection
7
+ # Header chunk types
8
+ CHUNK_TYPE_HEADER = "1"
9
+ CHUNK_TYPE_RPC = "2"
10
+ CHUNK_TYPE_SECURITY = "3"
11
+ CHUNK_TYPE_COMMAND = "4"
12
+ CHUNK_TYPE_DATA = "5"
13
+ XWB_HEADER = "[XWB]"
14
+ # Header and protocol info
15
+ VISTA_RPC_VERSION = "1"
16
+ VISTA_RPC_TYPE_CMD = "0"
17
+ VISTA_RPC_TYPE_RPC = "1"
18
+ VISTA_RPC_LENV = 3
19
+ VISTA_RPC_LENV_STR = "3"
20
+ VISTA_RPC_RETURN_DATA = "0"
21
+ VISTA_RPC_NO_RETURN_DATA = "1"
22
+ END_MARKER = 4
23
+ # Parameter types
24
+ PARAM_LITERAL_MARKER = "0"
25
+ PARAM_REFERENCE_MARKER = "1"
26
+ PARAM_LIST_MARKER = "2"
27
+ PARAM_GLOBAL_MARKER = "3"
28
+ PARAM_EMPTY_MARKER = "4"
29
+
30
+ def initialize(host, port, access, verify, debug=FALSE)
31
+ @sentConnect = false
32
+ @signedOn = false
33
+ @host=host
34
+ @port=port
35
+ @access=access
36
+ @verify=verify
37
+ @debug=debug
38
+ @token=nil
39
+ @socket = nil
40
+ @encryptedAV = nil
41
+ @writeBuffer = String.new
42
+ @duz = "0"
43
+ @currentContext = nil
44
+ end
45
+
46
+ def connect
47
+ retVal = true
48
+ if isConnected()
49
+ puts " already connected, closing first"
50
+ close
51
+ end
52
+ @socket = TCPSocket.open(@host, @port) # Connect
53
+ # socket.setTcpNoDelay(true)
54
+ tcpConnect = VistaRPC.new("TCPConnect", RPCResponse::SINGLE_VALUE, true)
55
+ tcpConnect.params[0]= @socket.addr[4] # local IP address
56
+ tcpConnect.params[1]= "0" # callback port ?
57
+ tcpConnect.params[2]= "OVID"
58
+ connectResponse = execute(tcpConnect)
59
+ if (connectResponse == nil || connectResponse.value == nil || connectResponse.value == "reject")
60
+ puts "Handshake error"
61
+ end
62
+ if (connectResponse.error_message != nil)
63
+ puts "RPC Error: " + connectResponse.error_message
64
+ end
65
+ @sentConnect = true
66
+
67
+ signOn()
68
+ retVal = logIn()
69
+ return retVal
70
+ end
71
+
72
+ def signOn()
73
+ signonResponse = execute(VistaRPC.new("XUS SIGNON SETUP", RPCResponse::ARRAY))
74
+ if (signonResponse == nil || signonResponse.error_message != nil)
75
+ puts "XUS SIGNON SETUP failed"
76
+ end
77
+ @signedOn = true
78
+ end
79
+
80
+ def logIn()
81
+ xusAvCode = VistaRPC.new("XUS AV CODE", RPCResponse::ARRAY)
82
+ @duz = "0"
83
+
84
+ if (@encryptedAV == nil)
85
+ if (@token != nil)
86
+ @encryptedAV = @token
87
+ else
88
+ @encryptedAV = xusAvCode.encrypt(@access + ";" + @verify)
89
+ end
90
+
91
+ end
92
+ xusAvCode.params[0]= @encryptedAV
93
+ response = execute(xusAvCode)
94
+ if (response == nil)
95
+ return false
96
+ end
97
+ hasErrors = (response.error_message != nil)
98
+ answer = response.value
99
+ if (!hasErrors)
100
+ if (answer.length == 0)
101
+ hasErrors = true
102
+ else
103
+ hasErrors = answer[0]== "0"
104
+ end
105
+ end
106
+ if (hasErrors)
107
+ brokerInfo = extractBrokerErrorInfo(response)
108
+ puts("Access denied: " + brokerInfo)
109
+ else
110
+ duz = answer[0]
111
+ end
112
+ return true
113
+ end
114
+
115
+
116
+ def extractBrokerErrorInfo(response)
117
+ sb = String.new
118
+ # if (response != nil && response.getArray() != nil)
119
+ # response.getArray.each do |answer|
120
+ # if (answer != nil && answer.length > 0 && !answer.matches("^(\\d+)$"))
121
+ # if (sb.length() != 0) # sb is Stringbuilder
122
+ # sb.append(" : ")
123
+ # sb.append(answer)
124
+ # end
125
+ # end
126
+ # end
127
+ # end
128
+ return sb
129
+ end
130
+
131
+ def close()
132
+ if isConnected()
133
+ if @sentConnect
134
+ @sentConnect = false
135
+ bye = VistaRPC.new("#BYE#", RPCResponse::SINGLE_VALUE, true)
136
+ execute(bye)
137
+ @socket.close()
138
+ @socket = nil
139
+ end
140
+ end
141
+ end
142
+
143
+ def isConnected()
144
+ return @socket != nil
145
+ end
146
+
147
+ # public String buildSubscript(String string) {
148
+ # return /* "\r" + */ string
149
+ # }
150
+
151
+ def executeOnce(rpc)
152
+ retVal = nil
153
+ writeProtocol()
154
+ writeCommand(rpc)
155
+ writeParams(rpc)
156
+ write(END_MARKER)
157
+ if (flush())
158
+ retVal = getResponse(rpc.type)
159
+ if @debug
160
+ puts "<Response> " + retVal.to_s + "</Response>"
161
+ end
162
+ end
163
+ return retVal
164
+ end
165
+
166
+ def write(data)
167
+ @writeBuffer << data
168
+ end
169
+
170
+ def writeProtocol
171
+ write(XWB_HEADER + VISTA_RPC_VERSION + VISTA_RPC_TYPE_RPC + VISTA_RPC_LENV_STR + VISTA_RPC_RETURN_DATA)
172
+ end
173
+
174
+ def writeCommand(rpc)
175
+ if (rpc.isCommand)
176
+ write(CHUNK_TYPE_COMMAND)
177
+ else
178
+ write(CHUNK_TYPE_RPC)
179
+ writeSPack(VISTA_RPC_VERSION)
180
+ end
181
+ writeSPack(rpc.name)
182
+ end
183
+
184
+ def writeSPack(value)
185
+ write(value.length) # integer
186
+ write(value)
187
+ end
188
+
189
+ def writeLPack(string)
190
+ len = sprintf("%03i", string.length) # 0-padded 3 place string of integer
191
+ #Integer.toString(string.length())
192
+ # while (len.length() < VISTA_RPC_LENV) {
193
+ # len = "0" + len
194
+ # }
195
+ write(len) # "003"
196
+ write(string)
197
+ end
198
+
199
+ def writeParams(rpc)
200
+ write(CHUNK_TYPE_DATA)
201
+
202
+ params = rpc.params # Hash integer => object
203
+ if (!params.empty?)
204
+ params.each do |param|
205
+ if param.nil?
206
+ writeEmptyParam()
207
+ elsif param.class == String
208
+ writeStringParam(param)
209
+ elsif param.class == Array
210
+ writeArrayParam(param)
211
+ else
212
+ writeEmptyParam()
213
+ end
214
+ end
215
+ else
216
+ writeEmptyParam()
217
+ end
218
+ #No end marker. Chunk 5 is assumed to be the last.
219
+ end
220
+
221
+ def writeArrayParam(paramarray)
222
+ write(PARAM_LIST_MARKER)
223
+ size = paramarray.size
224
+ index = 0
225
+ paramarray.each do |v|
226
+ writeLPack(v[0])
227
+ writeLPack(v[1])
228
+ index += 1
229
+ if index !=size # looks like don't write a 't' after the last entry
230
+ write("t")
231
+ end
232
+ end
233
+ write("f")
234
+ end
235
+
236
+ def writeStringParam(string)
237
+ write(PARAM_LITERAL_MARKER)
238
+ writeLPack(string)
239
+ write("f")
240
+ end
241
+
242
+ def writeEmptyParam()
243
+ write(PARAM_EMPTY_MARKER)
244
+ write("f")
245
+ end
246
+
247
+ def flush()
248
+ retVal = false
249
+ if (isConnected() || connect())
250
+ if @debug
251
+ puts "<Request>" + @writeBuffer + "</Request>"
252
+ end
253
+ @socket.write(@writeBuffer)
254
+ @socket.flush
255
+ @writeBuffer = String.new
256
+ retVal = true
257
+ end
258
+ return retVal
259
+ end
260
+
261
+ def getResponse(rpcType)
262
+ hadError = Array.new # for passing around boolean by reference
263
+ hadError[0]=false
264
+ securityError = readSPack(hadError)
265
+ #puts "<SecurityError>" + securityError + "</SecurityError>"
266
+ if (hadError[0])
267
+ return nil
268
+ end
269
+ if (securityError.empty?)
270
+ securityError = nil
271
+ end
272
+
273
+ otherError = readSPack(hadError)
274
+ if (hadError[0])
275
+ return nil
276
+ end
277
+ if (otherError.empty?)
278
+ otherError = nil
279
+ end
280
+
281
+ retVal = nil
282
+ if (rpcType == RPCResponse::SINGLE_VALUE or rpcType == RPCResponse::GLOBAL_INSTANCE)
283
+ retVal = RPCResponse.new(readString(nil, hadError))
284
+ if (hadError[0])
285
+ return nil
286
+ end
287
+ elsif (rpcType == RPCResponse::GLOBAL_ARRAY or rpcType == RPCResponse::WORD_PROCESSING or rpcType == RPCResponse::ARRAY)
288
+ retVal = RPCResponse.new(readArray(hadError))
289
+ if (hadError[0])
290
+ return nil
291
+ end
292
+ end
293
+
294
+ if (retVal != nil && (otherError != nil || securityError != nil))
295
+ if (otherError != nil && securityError != nil)
296
+ retVal.error_message = otherError + "^" + securityError
297
+ elsif (otherError != nil)
298
+ retVal.error_message = otherError
299
+ else
300
+ retVal.error_message = securityError
301
+ end
302
+ end
303
+ return retVal
304
+ end
305
+
306
+ # returns array of string
307
+ def readArray(hadError)
308
+ if (hadError != nil)
309
+ hadError[0] = false
310
+ end
311
+ arrayList = Array.new
312
+ endMarker = Array.new
313
+ endMarker[0] = false
314
+ while true
315
+ newString = readString(endMarker, hadError)
316
+ if (newString == nil)
317
+ if (hadError != nil)
318
+ hadError[0] = true
319
+ end
320
+ break
321
+ end
322
+ if (endMarker[0])
323
+ break
324
+ end
325
+ arrayList << newString
326
+ end
327
+ return arrayList
328
+ end
329
+
330
+
331
+ # readString uses array argument so can pass values back
332
+ def readString(endMarker, hadError) # returns...string!
333
+ if (endMarker != nil)
334
+ endMarker[0] = !isConnected()
335
+ end
336
+ if (hadError != nil)
337
+ hadError[0] = !isConnected()
338
+ end
339
+ if (!isConnected())
340
+ return nil
341
+ end
342
+ buffer = String.new
343
+ gotCR = false
344
+ while true
345
+ byte = @socket.readbyte # read one byte
346
+ if (byte == END_MARKER)
347
+ if (endMarker != nil)
348
+ endMarker[0] = true
349
+ end
350
+ break
351
+ end
352
+ if (gotCR && byte == 10) # CR-LF
353
+ break
354
+ end
355
+ if (byte == 13)
356
+ gotCR = true
357
+ else
358
+ if (gotCR)
359
+ buffer << 13 # we got a CR without a LF, so keep it in.
360
+ gotCR = false
361
+ end
362
+ buffer << byte
363
+ end
364
+ end
365
+
366
+ retVal = buffer
367
+ return retVal
368
+ end
369
+
370
+ def readSPack(hadError)
371
+ if (hadError != nil)
372
+ hadError[0] = false
373
+ end
374
+ len = @socket.readbyte # read one byte into a fixnum
375
+ data = String.new
376
+ data = @socket.read(len)
377
+ return data
378
+ end
379
+
380
+ def execute(rpc)
381
+ retVal = executeOnce(rpc)
382
+ if (retVal == nil && @signedOn)
383
+ #reconnect
384
+ if (rpc.name == "#BYE#")
385
+ # We're disconnecting anyway
386
+ return nil
387
+ end
388
+ # attempt to log back on
389
+ if (connect())
390
+ if (@currentContext != nil)
391
+ context = !currentContext
392
+ @currentContext = nil
393
+ setContext(context)
394
+ end
395
+ retVal = executeOnce(rpc)
396
+ end
397
+ end
398
+ if (retVal == nil)
399
+ puts "Lost connection to server"
400
+ end
401
+ return retVal
402
+ end
403
+
404
+ def setContext(context)
405
+ if (context == @currentContext)
406
+ puts "context is already set to " + context + "..."
407
+ return
408
+ end
409
+ if (@currentContext != nil)
410
+ puts "changing context from " + currentContext + " to " + context
411
+ end
412
+
413
+ puts "Setting context to: " + context
414
+ xwbCreateContext = VistaRPC.new("XWB CREATE CONTEXT", RPCResponse::SINGLE_VALUE)
415
+ encryptedContext = xwbCreateContext.encrypt(context)
416
+ xwbCreateContext.params[0] = encryptedContext
417
+ response = execute(xwbCreateContext)
418
+ if (response == nil || response.error_message != nil)
419
+ puts "XWB CREATE CONTEXT failed: " + response.error_message
420
+ end
421
+ @currentContext = context
422
+ end
423
+
424
+ def getDUZ
425
+ return duz
426
+ end
427
+
428
+ end
429
+ end
@@ -0,0 +1,46 @@
1
+ module VistaRPC4r
2
+ class RPCResponse
3
+ attr_accessor :type, :value, :error_message
4
+
5
+ SINGLE_VALUE = 1
6
+ GLOBAL_INSTANCE = 2
7
+ ARRAY = 3
8
+ GLOBAL_ARRAY=4
9
+ WORD_PROCESSING=5
10
+
11
+ def initialize(value=nil, type=nil)
12
+ if value.nil?
13
+ @type = SINGLE_VALUE
14
+ @value = nil
15
+ elsif value.class == String
16
+ @value = value
17
+ @type = SINGLE_VALUE
18
+ elsif value.class == Array
19
+ @value = value
20
+ @type = ARRAY
21
+ elsif !type.nil?
22
+ @value = value
23
+ @type = type
24
+ end
25
+ @error_message = nil
26
+ end
27
+
28
+ def to_s
29
+ sb = String.new
30
+ if !@error_message.nil?
31
+ sb << "ERROR: "
32
+ sb << @error_message
33
+ elsif @value.nil?
34
+ sb << "No value or error"
35
+ elsif @value.class == Array
36
+ sb = "ARRAY:" + value.join("|")
37
+ elsif @value.class == String
38
+ sb = "STRING:" + value.to_s
39
+ else
40
+ sb << "Unknown value type"
41
+ end
42
+ return sb
43
+ end
44
+ end
45
+
46
+ end
@@ -0,0 +1,84 @@
1
+ require 'rpc_broker_connection'
2
+
3
+ #broker = RPCBrokerConnection.new('192.168.1.20', 9270, 'sys.admin', 'vista!123')
4
+ broker = RPCBrokerConnection.new('openvista.medsphere.org', 9201, 'PU1234', 'PU1234!!')
5
+
6
+ broker.connect
7
+ broker.setContext('OR CPRS GUI CHART')
8
+
9
+ wardsrpc = VistaRPC.new("ORQPT WARDS", RPCResponse::ARRAY)
10
+ wardsresponse = broker.execute(wardsrpc)
11
+ wardsresponse.value.each do |ward|
12
+ a = ward.split("^")
13
+ puts "Ward:" + a[1]
14
+ wardrpc = VistaRPC.new("ORQPT WARD PATIENTS", RPCResponse::ARRAY)
15
+ wardrpc.params[0]=a[0] #ward ien
16
+ wardresponse = broker.execute(wardrpc)
17
+ wardresponse.value.each do |patient|
18
+ b = patient.split("^")
19
+ puts b[0] + ":" + b[1]
20
+ end
21
+ end
22
+
23
+ # Problem list
24
+ puts "Problem list-------------------------------------"
25
+ patientrpc = VistaRPC.new("ORQQPL LIST", RPCResponse::ARRAY)
26
+ patientrpc.params[0]="4" #patient ien
27
+ patientrpc.params[1]="A" #patient ien
28
+ patientresponse = broker.execute(patientrpc)
29
+ patientresponse.value.each do |d|
30
+ puts d
31
+ end
32
+
33
+ # Medications
34
+ puts "Medications-------------------------------------"
35
+ patientrpc = VistaRPC.new("ORWPS COVER", RPCResponse::ARRAY)
36
+ patientrpc.params[0]="4" #patient ien
37
+ patientresponse = broker.execute(patientrpc)
38
+ patientresponse.value.each do |d|
39
+ puts d
40
+ end
41
+
42
+ #Labs
43
+ puts "Labs-------------------------------------"
44
+ patientrpc = VistaRPC.new("ORWCV LAB", RPCResponse::ARRAY)
45
+ patientrpc.params[0]="4" #patient ien
46
+ patientresponse = broker.execute(patientrpc)
47
+ patientresponse.value.each do |d|
48
+ puts d
49
+ end
50
+
51
+ # Vitals
52
+ puts "Vitals-------------------------------------"
53
+ patientrpc = VistaRPC.new("ORQQVI VITALS", RPCResponse::ARRAY)
54
+ patientrpc.params[0]="4" #patient ien
55
+ patientresponse = broker.execute(patientrpc)
56
+ patientresponse.value.each do |d|
57
+ puts d
58
+ end
59
+
60
+ # Demo
61
+ puts "Demographics-------------------------------------"
62
+ patientrpc = VistaRPC.new("ORWPT PTINQ", RPCResponse::ARRAY)
63
+ patientrpc.params[0]="4" #patient ien
64
+ patientresponse = broker.execute(patientrpc)
65
+ patientresponse.value.each do |d|
66
+ puts d
67
+ end
68
+
69
+ #visits
70
+ puts "Visits-------------------------------------"
71
+ patientrpc = VistaRPC.new("ORWCV VST", RPCResponse::ARRAY)
72
+ patientrpc.params[0]="4" #patient ien
73
+ patientresponse = broker.execute(patientrpc)
74
+ patientresponse.value.each do |d|
75
+ puts d
76
+ end
77
+
78
+ #providers
79
+ puts "Providers---------------------------------"
80
+ patientrpc = VistaRPC.new("ORQPT PROVIDERS", RPCResponse::ARRAY)
81
+ patientresponse = broker.execute(patientrpc)
82
+ patientresponse.value.each do |d|
83
+ puts d
84
+ end
@@ -0,0 +1,99 @@
1
+ # the 'Request' of the RPC request/response. Stores the command or api call, and arguments
2
+ module VistaRPC4r
3
+ class VistaRPC
4
+ attr_accessor :name, :type, :isCommand, :params
5
+
6
+ def initialize(name, type=RPCResponse::SINGLE_VALUE, isCommand=false)
7
+ @name=name # string
8
+ @type=type # response type
9
+ @params=Array.new # params = new TreeMap<Integer, Object>();
10
+ @isCommand=isCommand # boolean
11
+ @cipher = [
12
+ "wkEo-ZJt!dG)49K{nX1BS$vH<&:Myf*>Ae0jQW=;|#PsO`'%+rmb[gpqN,l6/hFC@DcUa ]z~R}\"V\\iIxu?872.(TYL5_3",
13
+ "rKv`R;M/9BqAF%&tSs#Vh)dO1DZP> *fX'u[.4lY=-mg_ci802N7LTG<]!CWo:3?{+,5Q}(@jaExn$~p\\IyHwzU\"|k6Jeb",
14
+ "\\pV(ZJk\"WQmCn!Y,y@1d+~8s?[lNMxgHEt=uw|X:qSLjAI*}6zoF{T3#;ca)/h5%`P4$r]G'9e2if_>UDKb7<v0&- RBO.",
15
+ "depjt3g4W)qD0V~NJar\\B \"?OYhcu[<Ms%Z`RIL_6:]AX-zG.#}$@vk7/5x&*m;(yb2Fn+l'PwUof1K{9,|EQi>H=CT8S!",
16
+ "NZW:1}K$byP;jk)7'`x90B|cq@iSsEnu,(l-hf.&Y_?J#R]+voQXU8mrV[!p4tg~OMez CAaGFD6H53%L/dT2<*>\"{\\wI=",
17
+ "vCiJ<oZ9|phXVNn)m K`t/SI%]A5qOWe\\&?;jT~M!fz1l>[D_0xR32c*4.P\"G{r7}E8wUgyudF+6-:B=$(sY,LkbHa#'@Q",
18
+ "hvMX,'4Ty;[a8/{6l~F_V\"}qLI\\!@x(D7bRmUH]W15J%N0BYPkrs&9:$)Zj>u|zwQ=ieC-oGA.#?tfdcO3gp`S+En K2*<",
19
+ "jd!W5[];4'<C$/&x|rZ(k{>?ghBzIFN}fAK\"#`p_TqtD*1E37XGVs@0nmSe+Y6Qyo-aUu%i8c=H2vJ\\) R:MLb.9,wlO~P",
20
+ "2ThtjEM+!=xXb)7,ZV{*ci3\"8@_l-HS69L>]\\AUF/Q%:qD?1~m(yvO0e'<#o$p4dnIzKP|`NrkaGg.ufCRB[; sJYwW}5&",
21
+ "vB\\5/zl-9y:Pj|=(R'7QJI *&CTX\"p0]_3.idcuOefVU#omwNZ`$Fs?L+1Sk<,b)hM4A6[Y%aDrg@~KqEW8t>H};n!2xG{",
22
+ "sFz0Bo@_HfnK>LR}qWXV+D6`Y28=4Cm~G/7-5A\\b9!a#rP.l&M$hc3ijQk;),TvUd<[:I\"u1'NZSOw]*gxtE{eJp|y (?%",
23
+ "M@,D}|LJyGO8`$*ZqH .j>c~h<d=fimszv[#-53F!+a;NC'6T91IV?(0x&/{B)w\"]Q\\YUWprk4:ol%g2nE7teRKbAPuS_X",
24
+ ".mjY#_0*H<B=Q+FML6]s;r2:e8R}[ic&KA 1w{)vV5d,$u\"~xD/Pg?IyfthO@CzWp%!`N4Z'3-(o|J9XUE7k\\TlqSb>anG",
25
+ "xVa1']_GU<X`|\\NgM?LS9{\"jT%s$}y[nvtlefB2RKJW~(/cIDCPow4,>#zm+:5b@06O3Ap8=*7ZFY!H-uEQk; .q)i&rhd",
26
+ "I]Jz7AG@QX.\"%3Lq>METUo{Pp_ |a6<0dYVSv8:b)~W9NK`(r'4fs&wim\\kReC2hg=HOj$1B*/nxt,;c#y+![?lFuZ-5D}",
27
+ "Rr(Ge6F Hx>q$m&C%M~Tn,:\"o'tX/*yP.{lZ!YkiVhuw_<KE5a[;}W0gjsz3]@7cI2\\QN?f#4p|vb1OUBD9)=-LJA+d`S8",
28
+ "I~k>y|m};d)-7DZ\"Fe/Y<B:xwojR,Vh]O0Sc[`$sg8GXE!1&Qrzp._W%TNK(=J 3i*2abuHA4C'?Mv\\Pq{n#56LftUl@9+",
29
+ "~A*>9 WidFN,1KsmwQ)GJM{I4:C%}#Ep(?HB/r;t.&U8o|l['Lg\"2hRDyZ5`nbf]qjc0!zS-TkYO<_=76a\\X@$Pe3+xVvu",
30
+ "yYgjf\"5VdHc#uA,W1i+v'6|@pr{n;DJ!8(btPGaQM.LT3oe?NB/&9>Z`-}02*%x<7lsqz4OS ~E$\\R]KI[:UwC_=h)kXmF",
31
+ "5:iar.{YU7mBZR@-K|2 \"+~`M%8sq4JhPo<_X\\Sg3WC;Tuxz,fvEQ1p9=w}FAI&j/keD0c?)LN6OHV]lGy'$*>nd[(tb!#" ]
32
+ end
33
+
34
+ def encrypt(orig_string)
35
+ ra = rand(19)
36
+ rb = rand(19)
37
+ while (rb == ra || rb == 0)
38
+ rb = rand(19)
39
+ end
40
+ ca = @cipher[ra]
41
+ cb = @cipher[rb]
42
+ len = orig_string.length
43
+ pos = 0;
44
+
45
+ buffer = String.new
46
+ buffer << ra+32
47
+ for i in 0..(len-1)
48
+ c = orig_string[i]
49
+ index = ca.index(c)
50
+ if (index.nil?)
51
+ buffer << c
52
+ else
53
+ buffer << cb[index]
54
+ end
55
+ end
56
+ buffer << rb + 32
57
+ return buffer
58
+ end
59
+
60
+ def to_s
61
+ sb = String.new
62
+ sb << @name + ":"
63
+ sb << @params.to_s
64
+ return sb
65
+ end
66
+
67
+ # @Override
68
+ # public boolean equals(Object obj) {
69
+ # if (obj == null) {
70
+ # return false;
71
+ # }
72
+ # if (getClass() != obj.getClass()) {
73
+ # return false;
74
+ # }
75
+ # final VistaRPC other = (VistaRPC) obj;
76
+ # if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
77
+ # return false;
78
+ # }
79
+ # if (this.type != other.type) {
80
+ # return false;
81
+ # }
82
+ # if (this.params != other.params && (this.params == null || !this.params.equals(other.params))) {
83
+ # return false;
84
+ # }
85
+ # return true;
86
+ # }
87
+
88
+ # @Override
89
+ # public int hashCode() {
90
+ # int hash = 3;
91
+ # hash = 29 * hash + (this.name != null ? this.name.hashCode() : 0);
92
+ # hash = 29 * hash + (this.type != null ? this.type.hashCode() : 0);
93
+ # hash = 29 * hash + (this.params != null ? this.params.hashCode() : 0);
94
+ # return hash;
95
+ # }
96
+
97
+
98
+ end
99
+ end
data/lib/vistarpc4r.rb ADDED
@@ -0,0 +1,6 @@
1
+ module VistaRPC4r
2
+ end
3
+
4
+ require 'vistarpc4r/rpc_response'
5
+ require 'vistarpc4r/vista_rpc'
6
+ require 'vistarpc4r/rpc_broker_connection'
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'vistarpc4r'
16
+
17
+ class Test::Unit::TestCase
18
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestVistarpc4r < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
@@ -0,0 +1,64 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{vistarpc4r}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Mike Cham"]
12
+ s.date = %q{2011-05-25}
13
+ s.description = %q{more}
14
+ s.email = %q{mike@blenderhouse.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "LICENSE.txt",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "lib/vistarpc4r.rb",
28
+ "lib/vistarpc4r/add_problems.rb",
29
+ "lib/vistarpc4r/rpc_broker_connection.rb",
30
+ "lib/vistarpc4r/rpc_response.rb",
31
+ "lib/vistarpc4r/test.rb",
32
+ "lib/vistarpc4r/vista_rpc.rb",
33
+ "test/helper.rb",
34
+ "test/test_vistarpc4r.rb",
35
+ "vistarpc4r.gemspec"
36
+ ]
37
+ s.homepage = %q{http://github.com/michaelcham/vistarpc4r}
38
+ s.licenses = ["MIT"]
39
+ s.require_paths = ["lib"]
40
+ s.rubygems_version = %q{1.5.3}
41
+ s.summary = %q{Provides capability to make rpc calls to VistA EHR systems that have rpcbroker running}
42
+
43
+ if s.respond_to? :specification_version then
44
+ s.specification_version = 3
45
+
46
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
47
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
48
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
49
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.0"])
50
+ s.add_development_dependency(%q<rcov>, [">= 0"])
51
+ else
52
+ s.add_dependency(%q<shoulda>, [">= 0"])
53
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
54
+ s.add_dependency(%q<jeweler>, ["~> 1.6.0"])
55
+ s.add_dependency(%q<rcov>, [">= 0"])
56
+ end
57
+ else
58
+ s.add_dependency(%q<shoulda>, [">= 0"])
59
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
60
+ s.add_dependency(%q<jeweler>, ["~> 1.6.0"])
61
+ s.add_dependency(%q<rcov>, [">= 0"])
62
+ end
63
+ end
64
+
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vistarpc4r
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Mike Cham
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-05-25 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ type: :development
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ name: shoulda
33
+ version_requirements: *id001
34
+ prerelease: false
35
+ - !ruby/object:Gem::Dependency
36
+ type: :development
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ~>
41
+ - !ruby/object:Gem::Version
42
+ hash: 23
43
+ segments:
44
+ - 1
45
+ - 0
46
+ - 0
47
+ version: 1.0.0
48
+ name: bundler
49
+ version_requirements: *id002
50
+ prerelease: false
51
+ - !ruby/object:Gem::Dependency
52
+ type: :development
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ~>
57
+ - !ruby/object:Gem::Version
58
+ hash: 15
59
+ segments:
60
+ - 1
61
+ - 6
62
+ - 0
63
+ version: 1.6.0
64
+ name: jeweler
65
+ version_requirements: *id003
66
+ prerelease: false
67
+ - !ruby/object:Gem::Dependency
68
+ type: :development
69
+ requirement: &id004 !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ hash: 3
75
+ segments:
76
+ - 0
77
+ version: "0"
78
+ name: rcov
79
+ version_requirements: *id004
80
+ prerelease: false
81
+ description: more
82
+ email: mike@blenderhouse.com
83
+ executables: []
84
+
85
+ extensions: []
86
+
87
+ extra_rdoc_files:
88
+ - LICENSE.txt
89
+ - README.rdoc
90
+ files:
91
+ - .document
92
+ - Gemfile
93
+ - Gemfile.lock
94
+ - LICENSE.txt
95
+ - README.rdoc
96
+ - Rakefile
97
+ - VERSION
98
+ - lib/vistarpc4r.rb
99
+ - lib/vistarpc4r/add_problems.rb
100
+ - lib/vistarpc4r/rpc_broker_connection.rb
101
+ - lib/vistarpc4r/rpc_response.rb
102
+ - lib/vistarpc4r/test.rb
103
+ - lib/vistarpc4r/vista_rpc.rb
104
+ - test/helper.rb
105
+ - test/test_vistarpc4r.rb
106
+ - vistarpc4r.gemspec
107
+ has_rdoc: true
108
+ homepage: http://github.com/michaelcham/vistarpc4r
109
+ licenses:
110
+ - MIT
111
+ post_install_message:
112
+ rdoc_options: []
113
+
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ hash: 3
122
+ segments:
123
+ - 0
124
+ version: "0"
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
126
+ none: false
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ hash: 3
131
+ segments:
132
+ - 0
133
+ version: "0"
134
+ requirements: []
135
+
136
+ rubyforge_project:
137
+ rubygems_version: 1.5.3
138
+ signing_key:
139
+ specification_version: 3
140
+ summary: Provides capability to make rpc calls to VistA EHR systems that have rpcbroker running
141
+ test_files: []
142
+