This document provides step-by-step
guidance for porting Document Storage System’s open-source vxVistA from Caché to GT.M. This document will refer to other published instructions
for steps that are described in detail elsewhere.
The
process of porting vxVistA from Caché to GT.M will consist of four main parts:
1) Download and install vxVistA to a Caché environment, 2) Export vxVistA
routines and globals from Caché in a format suitable for import to GT.M, 3)
Import vxVistA routines and globals to a GT.M database, and 4) make necessary
configuration changes within vxVistA to enable it to function in the GT.M
environment.
1. Download vxVistA from vxVistA.org to a convenient
location on your computer.
2. Extract files from the downloaded zip, and …
3. Follow the instructions in the document,
“simple_vxVistA 2010.1 Open Source Setup and Installation Guide.pdf” to copy
the vxVistA cache.dat database file, and install it in Caché.
4. In order to export routines and globals from
the vxVistA Caché database, you will need to create a folder to receive the
exported routines and globals. A good
idea is to create a parent folder, say “vxVistA-2010.1” and within that folder
create subfolders named ‘r’ for routines and ‘g’ for globals, for example:
5. Next you will access the VOS namespace,
created in the step 3, at the “programmer prompt.” To do this, right click the Caché cube icon
in the Windows system tray, and choose Terminal:
This
will open a telnet-like Window in the Caché USER namespace. Change to the VOS namespace by entering ZN
“VOS”:
6. You are now ready to export routines
(programs) and almost ready to export globals (vxVistA data files). First, routines. The Caché routine output utility ^%RO is
compatible with GT.M’s routine import utility ^%RI, so this step is
simple. From the VOS> programmer
prompt run the routine output utility and select all routines, using the ‘*’
wildcard, as illustrated below. Be
patient, after pressing <Enter> at the second “Routine(s)” prompt. Assembling the list of routines to export may
take some time.
After
you accept the “No” default at the “Printer Format?” prompt, Caché will display
routine names, as they are exported.
7. Verify that the file was written to the ‘r’ sub-folder
(or whatever name you selected for this folder). The file size is approximately 95 MB. We will convert the file to Unix/Linux format
in a subsequent step.
8. To export globals we will use a custom
convenience routine that includes within it a list of vxVistA global
names. This routine generates a separate
file for each global, in a format compatible for import to GT.M. However, this utility routine is not part of
vxVistA and must first be downloaded and then imported to the VOS
namespace. Just as you downloaded
vxVistA in step 1, download SISZWR-vxVistA.RO
to a convenient location on your computer.
9. From the VOS programmer prompt, use the Caché
routine import utility ^%RI to load the routine from the location where you
saved it. Note that the path on your
computer may differ from the one in the illustration:
10. This step uses the SISZWR routine to export globals
to the ‘g’ sub-folder, or an appropriate location. From the programmer prompt, carefully enter
the following command, substituting the path on your computer where you want
the exported globals to be stored.
Proofread
this line before pressing <Enter>.
Note that no feedback will be displayed for this command in the VOS
Terminal window. However, if you open
the ‘g’ sub-folder you will see many files being created, one for each
global. Some files are large, and the
globals containing them take a significant time to export, for example the
Lexicon EXPRESSIONS file in the ^LEX global.
Be patient. When all globals have
been written, the VOS> prompt will redisplay. At this point, the ‘g’ sub-folder should
contain 397 files (items).
11. This completes the Caché export steps. You may close the Caché Terminal window by
typing ‘H’ for HALT, followed by <Enter> at the programmer prompt:
12. If you have not yet installed GT.M, download
and install the latest version from http://sourceforge.net/projects/fis-gtm/.
13. Create a Linux user for vxVistA. Use all lowercase characters for the
username. We will create folders under
this user’s login folder, to contain the GT.M database, and vxVistA files.
14. Login as the vxVistA user. In the user’s login folder, make a directory
to contain the database, etc. Choose a
meaningful name, for example, the vxVistA version ID.
15. Use FTP or SCP or some other means to copy the
‘g’ and ‘r’ folders containing the exported globals and routines from the
computer where Caché is installed to the vxVistA user’s database directory,
i.e., the directory that was created in the preceding step.
This
copy may take a little while, depending on the speed of your network. When finished you may check the contents of
the g and r target folders to be sure that the transferred files are there.
16. The global *.zwr files are text files, where
each record terminates with ASCII 10 (linefeed) only. In other words, they are in Linux text
format. However, the large routine
output file, containing all vxVistA routines, is in Windows text format. There are many ways to convert this file to
Linux text format. The following
illustration uses Perl. Change to the r
directory and enter the following:
17. In this step we create a backup of work
completed in the preceding steps. In the
event that something goes awry in a subsequent step it will not be necessary to
repeat all of the work. Begin by
changing the directory to the vxVistA user’s login directory (parent of the
2010.1 folder). Then create a tar
archive of the 2010.1 folder, its subfolders and their contents. When complete, compress the archive using
gzip.
The
backup file vxVistA.tar.gz (or a substitute name
of your choice) should be approximately 295 MB in size.
It
would be prudent to copy this file to a USB key or network drive for
safekeeping.
18. The next few steps will create a GT.M database
and import the vxVistA globals to that database. First, set a few environment variables
manually. (Anticipate being logged-in to
the vxVistA user account for some time.)
If
you logout from the vxVistA user account before completing the steps in this
section, be sure to reset the environment variables, after login. In other words, repeat this step after a
logout-login sequence.
19. Create a global directory file, using the GT.M
utility GDE.
You
may wish to verify that the directory file exists in the 2010.1 folder.
20. Next create the database itself, and adjust
parameters, using the GT.M mupip utility.
The
2010.1 folder should now contain two files named database.dat and database.gld,
in addition to the ‘g’ and ‘r’ sub-folders.
21. Navigate to the ‘g’ sub-folder and create a
sub-folder within ‘g’ named ‘q’ (for quarantine). Move the YTT.zwr file to sub-folder ‘q’. Global ^YTT includes subscripts (keys) whose
lengths exceed the maximum length allowed by the MUMPS standard. If imported to the GT.M database, these keys
could cause a database integrity issue.
While
still in the ‘g’ sub-folder, proceed to the next step.
22. This step will import vxVistA globals from
*.zwr files to the newly created GT.M database.
Each file corresponds to a different global.
After
you have entered the command line shown in the above illustration, mupip will
echo information about each global, as it is imported to the database. As previously noted for the export step, some
globals are large and require time to load.
Do not be alarmed by long pauses.
The last global to load is %Z.
23. This step will import vxVistA routines from
the allRoutines.RO file. However,
routines are not themselves loaded into the database file, but are extracted as
<routine name>.m files to the $gtmroutines directory. This step has several sub-parts. First, change the directory back to the login
folder (parent of 2010.1). Next, invoke
GT.M in direct mode (second line in the illustration below). Then invoke the GT.M import utility routine
^%RI. Answer the prompts, as illustrated
below. When specifying the output
directory, be sure to include the final “/” character. Omitting this character will cause the import
to fail. GT.M will display routine names
as they are being extracted. When
finished enter the H (halt) command to exit direct mode.
24. At this point the ‘r’ directory contains more
than 25,000 source routines, stored as individual files, each with the .m
extension. GT.M compiles these source
routines to an object code form, for efficiency of execution. The object routines will have the .o
extension. For convenience, and to avoid
unpleasant compile errors when routines are first referenced for execution by
GT.M, in this step we will pre-compile the 25,000+ routines that were extracted
in the preceding step.
First change directory to the 2010.1/r
folder. Then enter the command line
shown in the following illustration.
Anticipate the display of many compile errors. This is normal.
25. This section, which created a GT.M database
for vxVistA, and imported routines and globals, is complete. In the next section, vxVistA will be
configured and adapted for the GT.M environment. At this point you may wish to make a
convenience backup, to include the GT.M database and routine files. This step is optional.
26. Before beginning the configuration it is
necessary to address a minor “catch 22” or “chicken and egg” problem. The VistA Kernel setup program relies upon
another program, which happens to be one of the ones that it sets up. Thus, it cannot create the program, or any of
the others that it creates, unless the program in question is available for use
by the setup program. If this does not
make sense, don’t ask why, just perform the following steps. First navigate to the ‘r’ directory, if not
already there; then copy routine ZOSVGUX.m to _ZOSV.m and compile the latter,
as illustrated below.
27. This step may be regarded as an interpolation
for convenience. In the vxVistA login
directory, create a script that defines environment variables and another
script that connects to GT.M in direct mode, referencing the vxVistA
environment variables. This will
eliminate the need to reestablish environment variables on each login, although
this could also be done in the vxVistA user’s login profile. Use an editor to create a file named
vos-env. The file’s contents will be as
listed in the illustration below. After
creating the file, make it executable (chmod command). Similarly create the vos file (stands for
vxVistA open-source), with the contents shown below. Make it executable also.
Test
the vos script as follows:
28. Now to the first “real” vxVistA configuration
step. Connect to GT.M using the
convenience script ./vos and run the Kernel setup
routine ^ZTMGRSET, as illustrated below.
Some key responses are highlighted.
Enter the two-part value VOS,VOS for the
MANAGER’S and PRODUCTION UCI,VOLUME SET prompts. In other words, do not accept the single part
VOS default answer at these prompts.
Note
highlighted responses. System defaults
to ‘3’ (the export environment). Change
this value to ‘8’. Near the end, answer
YES to the “Want to rename the FileMan routines” prompt. When finished type ‘H’ to halt from MUMPS.
29. The %Z* routines created in the preceding
step, as well as %XUCI, have not been compiled.
Therefore, this step will compile them.
Navigate to the 2010.1/r sub-directory, and enter the commands shown
below. Once again, do not be alarmed to
see more than a few compile errors.
These routines contain platform-specific code. However, code for platforms other than GT.M
will not ordinarily be reached during execution in the GT.M context.
30. At this point, it is fair to test a couple of
things, to confirm that the steps performed thus far have accomplished
something. We will run the main Kernel
option driver, and then Fileman.
However, we will not make any substantial changes to the database in
this step. To run the option driver, SET
DUZ=1 (user=1), then DO ^XUP. To run
Fileman, DO Q^DI and then enter ‘?’ to display Fileman’s main options.
31. It may go without saying that if your test
results do not correspond to those shown above, it is necessary to stop at this
point, and troubleshoot the problem.
Unfortunately, such troubleshooting is beyond the scope of this “How to”
document. In the worst case, you can go
back to the step where you last backed-up your work, e.g., step 17 or step 24,
and redo steps from that point forward.
32. This step is a little tricky, in that the
value you will enter depends on your computer name. It will not be the same value as shown in the
illustration below. First, at the
GTM> prompt, enter the command shown in the first line of the illustration
below.
The
actual value displayed for variable Y will differ on your system. We are interested in the fourth “^”-piece of
this value, which in the above example is VOS:MP2800-U. On your system, this piece will be VOS:<name of your computer>. Whatever it is, use that value in place of
MP2800-U when editing the BOX-VOLUME PAIR, as demonstrated below. Include the VOS and colon, but substitute
your computer name for the MP2800-U name.
Fileman
(Q^DI) requires a user context. If you
have just started GT.M and have not yet established a user context, SET DUZ=1
before entering the DO Q^DI command.
33. Soon we will start the vxVistA Task Manager to
verify the preceding step. However,
before attempting to start Taskman, in the present step we modify two DEVICE
definitions, substituting Linux / GT.M attributes, where appropriate, for
Windows or Caché values. First, the NULL
device (bit bucket)… The NULL device, as exported from the Windows Caché
implementation refers to the DOS / Windows device //./nul. We will rename this device as WINDOWS NULL,
and then rename the GTM-LINUX-NULL device to NULL. This facilitates unambiguous lookup of the
NULL device.
Next we address the HFS device. HFS stands for “Host File System.” This device is used by vxVistA to read or
write to files on the host operating system.
Edit the HFS entry as illustrated below.
In the above example, press <Enter> when
accepting the default value for a field.
At the QUEUING prompt, enter ^OPEN PARAMETERS to branch to the OPEN
PARAMETERS field, skipping many irrelevant fields. After entering the replacement value for this
field, type ‘^’ to exit.
34. When Taskman is started, it will automatically
start several sub-tasks. Two of these
relate to starting TCP/IP listeners for vxCPRS and VistALink. We do not want Taskman to attempt to start
these listeners in GT.M. Instead we will
define an OS service listener for vxCPRS in a subsequent step. Thus, at this point, the special queuing of
these options will be removed. While
normally this would be done using a Taskman screen option, for expediency we
use Fileman to remove special queuing of these options, as illustrated below.
35. This step will attempt to start Taskman, and
then check to verify that Taskman is running.
First, to start Taskman, use option XUTM RESTART, as shown below.
The above illustration assumes that the user
context already exists. If you have
exited and re-entered GT.M before this step, type SET DUZ=1 DO ^XUP, as the
first line.
Wait about 15 seconds before checking to see
if Taskman has started. DO ^XUP again,
and Select OPTION NAME: XUTM ZTMON to examine the Taskman status. This option displays a status screen that
updates automatically. To exit the
monitor, type “^” and <Enter> at the UPDATE prompt.
The display shown above is normal. Taskman is “current.” The status of the node
we defined a few steps before this one VOS:MP2800-U
(substitute your computer name) is RUN, and that node has an available
sub-manager (last line).
36. At this point it would be tempting to try a
vxVistA user login. However, that
attempt would be certain to fail. The
reason is that vxVistA hashes login codes (access and verify codes), as well as
electronic signature codes, using the VA VistA Kernel’s MD5 routines, which
unfortunately rely upon one or more Caché Object Script functions that are not
in standard MUMPS, and are not supported in GT.M. It would be possible to disable this hash, or
replace it with a different hash, but either of these options would require
re-entering access and verify codes, and electronic signatures, for documented
vxVistA users. Much better is to compute
the same hash, albeit in a different way.
vxVistA includes an “override” mechanism, by which
one can substitute another computation in place of the default VA Kernel MD5
routines. This mechanism is the file VFD
IMPLEMENTATION-SPECIFIC API. In this
step, we will add an entry to this file, in order to hash access and verify
codes (and electronic signatures), producing the same result as the vxVistA
default hash.
Three sub-steps are required. The first is trivially simple, the second
nearly so, and the third will require care.
First, create a sub-directory of /tmp named xush (all lowercase).
Sub-step 2. Use an editor to create a script
in the vxVistA user’s login directory /home/vxvista named xush (all lower
case). The script will have only two
lines of text, as shown in the listing below.
When finished, be sure to make the script executable (chmod command).
The following example may be used to verify
the above script:
Sub-step 3.
In this step we will create an entry in the VFD IMPLEMENTATION-SPECIFIC
API file named ONE-WAY HASH. The name is
important because the entry is a pointer to the VFD SUPPORTED API file. In the entry’s XECUTE field we will paste the
long line of code below. It would be
possible to type in this line of code, but every quotation mark matters, making
for a significant likelihood of error.
Therefore, it is recommended to copy the single line below, from the
first to last character, and paste the line as the value of the XECUTE
field. Copy and paste the following:
N %,%0,F,Z S
F="/tmp/xush/"_$J,%="zsystem ""echo "_X_" |
/home/vxvista/xush > "_F_"""",%0="zsystem
""rm ""_F",Z="O F:READONLY:2 I U F R X:2 C F" X %,Z,%0
The NOTES field is optional. However if you do enter a note, use F1-E to
exit and save the note (or F1-Q to exit without saving). Press the F1 key and then the E key (or Q)
successively. Here is the full
illustration.
Press F1, then E, to exit the NOTES
editor. Skip the final SITE ID
prompt. This step is complete.
37. Page 2 of the document, “simple_vxVistA 2010.1
Open Source Setup and Installation Guide.pdf” (see Step 3 above) states that
the vxVistA administrator login codes are Access: ADMIN123 and Verify:
123Admin! (where the latter is case-sensitive).
Use these codes to test the preceding step. Login can only succeed if the codes are
hashed identically to the stored hash in vxVistA. For this test we will use the ^XUS routine
and will simply halt at the first menu prompt, if successful.
The successful login illustrated above proves
that the hash computed by the Linux md5sum, suitably wrapped, is the same as
the stored vxVistA hash for the ADMIN user.
If you are an expert Linux / GT.M user, you may wish to improve or
simplify the rather complex step 36. For
example, a pipe might be substituted in place of the scratch file
/tmp/xush. Keep in mind, however, that
the XECUTE field code must satisfy Fileman’s ^DIM syntax checker.
38. Why did step 37 use ^XUS, rather than ^ZU to
test the first logon? One answer is that
routine ^ZTMGRSET does not file the platform-specific ^ZU routine. Where is routine ^ZUGUX? The answer to this question is that there is
no ^ZUGUX. Instead, routine ^ZUGTM
supports the GT.M platform, whether under VMS or Unix
/ Linux. In this step we copy routine
^ZUGTM to ^ZU and compile it.
39. Before testing a login to vxVistA through ^ZU,
we will create a script, to illustrate how user login might be tied to
^ZU. Use an editor, and create a
three-line script, with the contents shown below. Once again, do not forget to make the script
executable.
Now test login to vxVistA via the zu script. Reminder:
The access code is ADMIN123 and the verify code is 123Admin! (case-sensitive).
To exit from vxVistA type halt at the menu
prompt.
40. Similar to the way in which vxVistA computes a
hash of access / verify codes etc., when a (TIU) document is signed, vxVistA
stores an encrypted string that encodes a combination of the signature block
and a checksum of the document itself.
Unlike the login codes hash, this encrypted string can be decrypted, and
is decrypted whenever a document
signature is displayed.
The algorithm used by vxVistA for document
signature block encryption also relies upon non-standard language features that
are not supported in GT.M. However,
because vxVistA (open-source) does not include any signed (TIU) documents, it
is not necessary to implement the same
encryption algorithm as vxVistA uses by default. Thus, the problem of implementing an
alternative invertible encryption for document signature blocks can be
deferred.
For the present, we will override the default
vxVistA document encryption, in order to avoid an error on signing a test
document. In this case, the override
will be simply no encryption. Instead of a long line of code, the XECUTE
field for ENCRYPT STRING and DECRYPT STRING entries will have the value ‘Q’ for
quit. Create these entries in the VFD IMPLEMENTATION-SPECIFIC
API file, using Fileman, as illustrated below.
41. In the first few steps of part 3 of this
document, we defined a directory structure to contain the vxVistA GT.M database
and routines. This structure is similar
to VistA / GT.M community practice, but other structures are also possible, and
in common use. One such alternative stores object routines (.o files) in a separate directory
from source routines (.m files).
In order to work independently of the
platform, [vx]VistA uses various methods of invoking
platform-specific code when needed.
Previous steps have addressed platform-specific VistA library (%Z*)
routines, for example. In this step we will
modify another structure that implements platform-specific code for saving
routines.
This code is located in the ZSAVE field of the
GT.M(UNIX) entry of the MUMPS OPERATING SYSTEM file.
Before modification, the code assumes that object routines are stored in a
separate directory from source routines.
It will be necessary to modify this code for the simpler directory
structure that we have created for vxVistA.
This will be the first use of Fileman’s ‘Replace-With’ editor. Although the line of code to be edited is
long, we will be changing only a short part of it, the following:
Replace $P($P($ZRO,")"),"(",2) With $P($ZRO," ")
The following example illustrates the entire
Fileman editing session, including the critical ‘Replace-With’ part:
Note
added in revision: If Fileman is
re-initialized after modifying the ZSAVE code as described in the present step,
the initialization process will replace modified ZSAVE code with the
original. In Fileman version 22.0 (ca.
2012), the original (default) code may be found in routine ^DINIT21.
42. vxCPRS – At last!
As noted in a previous step, we will configure an OS service to accept
vxCPRS connections. Details may vary
between different Linux flavors.
However, concepts are generally equivalent. For an introduction to Linux sockets, with
examples, a useful tutorial may be found at http://www.troubleshooters.com/codecorn/sockets/.
First, create yet another script in the
vxVistA user’s login directory. The name
doesn’t much matter. However, call it
rpcb-9201 for “remote procedure call broker – port 9201.” Use the editor of your choice and enter the
script shown in the listing below. Do
not forget to make it executable.
It is possible to test this script,
independently of the service that will run it.
To do so, execute the script, then press CTRL-C to reach the GTM>
prompt. At this point, enter the
‘zwrite’ command to examine the symbol table.
Then enter ‘h’ halt. The
following illustration includes only the first few lines of the symbol table.
43. As previously noted, there are several
different ways to define and start a service.
This step will illustrate one method, using the xinetd
super-server. You will probably not be
able to perform this step from the vxVistA login context, as it requires
super-user privileges. Login as a user that can ‘sudo’ for this part. For example –
If your Linux OS does not use xinetd, then
identify an alternative way of establishing the vxVistA RPC Broker listening
service. In this example, we edit the
xinetd.conf file to add the desired service.
The same might be accomplished by creating a separate script for the
service in the /etc/xinetd.d directory.
In any case, the following illustrates the lines to be added to
xinetd.conf (or as a separate script).
Finally, edit the /etc/services file, adding the
following line:
44. If you are using xinetd, as illustrated in the
preceding step, restart the super-server.
After restarting, verify that the service is
running. For example, ‘netstat –l’
should include a line similar to the following in its display:
45. If you have not already created a shortcut to
the vxCPRS executable, as described in the “simple_vxVistA 2010.1 Open Source
Setup and Installation Guide.pdf” document, do so at this time. Edit the properties to specify the IP address
(or host name) of your GT.M / vxVistA installation, port 9201. In other words, replace the word LOCALHOST in
the illustration on page 42 of the aforementioned document with the IP address
or host name of your vxVistA server.
Apply or save this change.
Open the vxCPRS shortcut. After a few seconds you should see the vxCPRS
login form:
Enter the same codes that were used previously
to test an interactive terminal login, ADMIN123 and 123Admin! (case-sensitive verify code).
If successful, the patient selection form will display on top of the
vxCPRS cover sheet.
Select a patient, and click OK. In the example below, Zztestpatient,One M was selected.
If you have left Taskman running (from the
step that tested Taskman startup) the cover sheet display should look the same
as the illustration above.
The following steps will be described in less
detail than previous steps, under the assumption that experience gained from
exercising configuration steps up to the successful launch of vxCPRS makes
greater detail unnecessary.
46. Step number 40 explained that when a (TIU)
document is signed, vxVistA stores an encrypted string that encodes a
combination of the signature block and a checksum of the document itself, and
that the encryption algorithm used by vxVistA relies upon one or more
non-standard language features that are not implemented in GT.M. The present step suggests how to substitute a
different invertible encryption algorithm, one that uses only standard MUMPS
and works the same in GT.M and Caché.
Note: This step has been temporarily removed,
due to a conceptual flaw in the original suggestion. An alternative suggestion may be substituted
in the future. Meanwhile, skip this step
and continue with step 47.
47. In this step we will address another usage of
a non-standard language feature.
However, this is not a vxVistA-specific usage, but one that is found in
the FOIA release of VistA itself. A few
VistA routines rely upon the two-parameter form of the MUMPS $QUERY
function. This form is supported in
Caché but is not part of standard MUMPS and is not included in GT.M. As a workaround, we will use an extrinsic
function to simulate the two-parameter form of $QUERY. If you are a MUMPS programmer you may wish to
create your own substitute function for $QUERY.
The one given here uses $QSUBSCRIPT, and requires GT.M version 5.4-002B
or greater.
Download the routine SISQSIM in either Caché routine save format or in GT.M
source routine format. Use the GT.M
utility ^%RI, as described in previous step number 23, to import routine
SISQSIM from the SISQSIM.RO file.
Alternatively, simply copy the GT.M source format routine to the
routines directory …2010.1/r/. After
importing or copying the routine, compile it.
Compiling the routine will display an error in a part of the code that
is not reached in the GT.M context.
After compiling the routine, run the following
test –
As indicated by the comment, this test takes a
few minutes and, if successful, produces no output. The test simulates reverse $QUERY through all
nodes in the Fileman data dictionary global ^DD.
48. This step will show how to identify VistA code
that uses the two-parameter form of the $QUERY function, and will give an
example of substituting the $$Q^SISQSIM extrinsic function that was loaded and
tested in the preceding step.
First, an example… The line of code reproduced
below includes a use of the two parameter form of the $QUERY function. The context is an API related to Military
Sexual Trauma (MST) information. While
GETSTAT^DGMSTAPI may not be needed or used in a non-VA implementation of VistA,
this example serves to illustrate the $QUERY problem.
We will modify this reference to use the $$Q
simulation in place of the intrinsic $QUERY function. While the intrinsic function expects a local
or global variable as the first parameter, the simulation needs instead the name of the variable. Use any editor, vi for example, to edit the
routine. The illustration below shows
the edit in VPE’s ..e editor.
The replacement code shown in line 47 above
calls $$Q^SISQSIM instead of $Q and wraps the global variable using the $NA
(name) function. This is the same
process as will be used for replacing other usages of the two-parameter $QUERY.
It is important to keep track of VistA
routines that have been modified, as these routines may be included in a future
VistA patch. If they are, then the
modification must be revisited after installing the patch. Therefore it is recommended to maintain a
file of modified routines for possible future reference.
The obvious question that occurs is how to
find such usages of the two-parameter $QUERY in VistA, in order to anticipate
problems before they occur, i.e., before they result in application-level MUMPS
errors. To aid in this endeavor, we will
import yet another utility routine.
Again the routine is provided in both Caché
routine save and GT.M source formats. Download, install and compile this routine,
in the same way as the SISQSIM routine was installed above. No compile errors are expected.
The next illustration shows how to use this
utility to search a group of routines for a MUMPS pattern. In this example we will search the BCMA
routines (PSB*) for a pattern that could indicate a two-parameter $Q reference.
The illustration above omits the search
output. The output lists three routines,
one of which is a false positive. In other words, one of the routines includes
code that matches the MUMPS pattern but is not
a usage of the two-parameter $QUERY. The
two routines that do use the two-parameter form of $QUERY and the references
themselves are shown below.
A few additional remarks may be warranted, in
regard to the task of modifying these routines.
First, note that the variable PSBQRY is indirected in $QUERY parameter
references. This means that variable
PSBQRY contains the name of the $Q
parameter variable. In other words, when
substituting $$Q^SISQSIM, you would refer to variable PSBQRY itself, to pass
the name, that is, $$Q^SISQSIM(PSBQRY,-1). Second, note that not all references to
variable PSBQRY in the above lines involve a $Q call. For example, the reference to $E($P(PSBQRY,U,1),1,12) does not involve $QUERY, and
therefore does not require modification.
Third, note that where more than one reference to the two-parameter form
of $Q exists in the line of code (+128^PSBOMH1 and +79^PSBRPC2), one may wish
to split the line for clarity. However,
substantial care is required, because lines with more than one $Q(…,-1) reference are within the scope of IF commands (the
first commands in each line). This scope
must be preserved over any additional lines that are created to replace these
lines.
Proceed to modify the PSB* routines identified
above in the same way as was illustrated for routine DGMSTAPI at the beginning
of this step. Remember to record the
modified routines for future reference.
Also, when this part of the configuration work is complete, it may be
prudent to search for possible additional uses of the two-parameter $QUERY in
other VistA applications.
49. Next, anticipating a possible problem, we will
define a couple of additional directories.
Step 36 created sub-directory xush in the /tmp folder. By the way, if your flavor of Linux clears
the /tmp folder on system boot, this feature should be disabled. Configure startup to retain sub-directories of
the /tmp directory on reboot.
Alternatively, create these temporary directories in a different path,
one that is not cleared on reboot.
Make two new sub-directories, for example,
named /tmp/hfs and /tmp/psb. Then use
Fileman to name /tmp/hfs as the PRIMARY HFS DIRECTORY in the KERNEL SYSTEM
PARAMETERS file.
Similarly use ^XPAREDIT to name /tmp/psb as
the PSB HFS SCRATCH directory.
50. We are now ready to test vxBCMA. Locate the vxBCMA executable from the
vxVistA.org download and create a Windows shortcut to the program. Configure the shortcut for the RPC Broker server
and port in the same way as was described for vxCPRS in step 45. Open the shortcut. A vxBCMA splash screen will be displayed,
followed by the standard VISTA Sign-on form.
Use the same logon codes as were used in previous steps, including the
vxCPRS test step (45).
You
may also receive a warning about a clock time discrepancy between the Windows
client and Linux server. Of course, the
clocks should be synchronized. However,
for the purpose of this test, the warning may be ignored. Next the Patient Lookup dialog appears. In normal usage, vxBCMA expects the patient’s
wristband to be scanned. However, it is
the same to type the patient ID in the text box, as shown.
Upon
responding affirmatively to the patient confirmation (below),
…
the
vxBCMA main form will be displayed. Note
that patient ABC001 is the only inpatient in the vxVistA.org 2010.1 database, as
distributed. If you have admitted other
test patients, of course they may also be selected.
Display
of the main vxBCMA form proves only that the application is runnable. Changing to the Cover Sheet tab shows that
this patient has no orders for display.
Therefore, it is not possible to demonstrate anything meaningful with
vxBCMA until some current or recent inpatient medications orders have been
processed for the patient.
51. In step 48 we mentioned the possible use of
VPE for editing a routine in vxVistA.
VPE is a popular programming shell for VistA that includes useful
utilities for displaying and editing routines and globals, and for displaying
the Fileman data dictionary. The latest
version may be downloaded from http://www.hardhats.org/tools/vpe/vpe_db.html.
While
VPE was pre-installed in the vxVistA environment, VPE %-routines and globals
were not transported in this port of vxVistA to GT.M (steps 6 – 10). Therefore, it is necessary to do a clean
install of VPE to the VOS (GT.M) environment.
Download VPE MGR and PRD routine save sets from the above link. The MSM version of these routine saves can be
imported using the GT.M ^%RI utility.
After downloading the .MGR and .PRD files, convert them to Linux format,
as was illustrated in configuration step 16.
Then import and compile them, as previously illustrated for other routine
sets. Follow the instructions given in
‘VPE_12_Read Me.txt’ to initialize VPE (DO ^ZVEMBLD and DO ^VEEMINIT). Note that both initializations should be
performed in the VOS account—there is no separate MGR account.
Step
41 explained how to modify ZSAVE code in the MUMPS OPERATING SYSTEM file for
the GT.M(UNIX) entry.
The specific modification required depends upon the scheme used for
storing vxVistA source and object routines.
If both source and object routines were stored in the same directory (../2010.1/r/), the modification given in step 41 will also
work for VPE’s routine editor.
52. We have reached the point where additional
configuration of vxVistA under GT.M requires more detailed knowledge of vxVistA
(or VistA) applications. However, the
methods illustrated in this preliminary configuration document should apply
also to configuring other applications, such as VistA HL7. For example, the rpcb-9201 script that was
created in step 42 can serve as a pattern for making a similar HL7-in script.
vxVistA and FOIA VistA come pre-defined with one
multi-listener logical link named LISTENER on port number 5340.
The convention for HL7 VistA listening ports
is to use port 5000 for production and port 5025 for test. However, to minimize the setup required, we
will use 5340 as the HL7 listening port in this example. Begin by creating a script.
Note the obvious similarity to the rpcb-9201
script. Be sure to make the script
executable. After creating the script,
create the corresponding service and add it to the services file. These steps are analogous to what was done
for the RPC Broker listener in step 43.
If you are using xinetd for these steps, then restart the super-server,
when finished.
One last step for HL7… The LISTENER logical
link, as distributed in FOIA and vxVistA refers to an address on the VA’s
private network. Use either HL7
Interface Developer Options … EL, or Fileman, to remove this address.
At this point vxVistA should be set to receive
inbound HL7 messages via port 5340.
Configuring HL7 to process received messages is a non-trivial task, and
falls beyond the scope of this ‘How to’ document. However, you can verify that the
infrastructure created in this step works properly, without setting up an
application to process the received HL7 message.
If you are able to send an HL7 test message in
to port 5340 using Mirth (or any message sending application) it will be
possible to verify that the message was received and handed to vxVistA
HL7. Use Fileman to inquire to the HL7
MESSAGE ADMINISTRATION file (File 773).
Note that the ‘0 Entries’ warning is spurious. VistA HL7 does not maintain the header of
this file. After sending the message,
inquire for any message received TODAY.
Here is an example.
The second message in the above ‘choose’ list
is the VistA-generated ACK. Here are the
details of the received message.
STATUS: ERROR was expected, as no application
has been defined to process the received message. However, the existence of this entry in the
HL7 MESSAGE ADMINISTRATION file proves that the message was received in
vxVistA. Consult the relevant VistA
documentation for additional information about HL7.
53. The GT.M environment does not include certain
built-in utilities that are familiar to Caché users, such as a System Status
display. Instead, the GT.M model relies
on the underlying operating system, augmented by open source tools, for system
administration, software development, and so forth.
A simple System Status utility that includes
“Job Examine” and “Kill Job” functions is described in detail and available for
download here. This utility has been tested with the
specific implementation of vxVistA under GT.M described in the present
document. See illustration below.
This completes the basic port of vxVistA to
GT.M. Additional work will be needed to
set up other applications, such as VistALink, or to configure vxVistA for use
as a working EMR in a real Health Care setting.
Note that Document Storage Systems, Inc. does
not presently support vxVistA under the GT.M platform (July 2011). Therefore, additional support can be expected
only on a voluntary basis from the community of users.
The author makes no claim as to the accuracy
or completeness of the information contained in this document. In no event will the author be liable for any
damages, lost effort, inability to deploy the application, or anything else
relating to a decision to use the information in this document.
A massively
patched and updated version of vxVistA (open-source) was released in February
2014—see vxVistA.org.
This release includes vxGroupNotes, vxPatientPicture, and vxVitals, as well as
vxBCMA and vxCPRS.
The procedure for
porting vxVistA 2013.0 to the GT.M environment is analogous to porting the
2010.1 version, as was described in the preceding 50+ steps. Of course, one
should choose version-appropriate names for the database directory, and script
files, replacing 2010.1 with 2013.0, and VOS with V13, and so forth.
In step 17 of the
2010.1 port we saved a backup of work. A similar archive of the 2013.0 port may
be downloaded from here. This
archive includes the vxVistA 2013.0 routines in GT.M %RO format (Restore using
^%RI). The archive also includes the 2013.0 globals as one large mupip extract,
and separately the ^YTT global in zwr format (Restore using mupip). The latter
global has unusually large keys. However, recent versions of GT.M will
accommodate key lengths of up to 1019 characters (K. S. Bhaskar, private
communication).
The vxVistA
2013.0 download (from vxVistA.org)
includes complete documentation for installation and configuration of the
database and associated GUI applications.
The following notes suggest ways of avoiding possible points of failure,
when implementing vxVistA 2013.0 under GT.M.
1. The patched version of Taskman that is
distributed with vxVistA 2013.0 contains a non-standard construct that is not
allowed by GT.M (but allowed by Caché, and thus not noticed in the Caché
environment). A lock that was acquired prior to the start of a transaction is
released after the start of the transaction and before it has been committed.
The offending code is found in routine ^%ZTLOAD1. To correct this, the order of
committing the transaction and releasing the lock must be inverted.
2. The second suggested change also involves
Taskman. However, in this case it is a vxVistA-specific patch that requires
changing. Under some circumstances, a null-subscript error can occur. This is
prevented by testing ZTIO and quitting if the variable is empty, in effect
reinstating the original version of this test.
3. The vxVistA 2013.0 database includes three
test patients with data. These test
patients have “alternate IDs” for an INSTITUTION different than the one
configured. It is recommended to duplicate these alternate IDs for the
vxVistA.org INSTITUTION entry, and to mark the added entries as DEFAULT
alternate IDs.
The same disclaimer applies to these
2013.0 notes as for the 2010.1 steps (see note following step 53 above).
This section presents questions that might have been asked, had this project generated sufficient interest.
1. Step 28 describes how to run the Kernel setup routine ^ZTMGRSET. Is it necessary to initialize Fileman also?
Yes, Fileman should be initialized (DO ^DINIT). Specify the type of MUMPS as GT.M(UNIX):
Specifying
GT.M(UNIX) as the type of MUMPS system causes Fileman to set the ^DD(“OS”) node
to the internal entry number of the GT.M(UNIX) entry in the MUMPS OPERATING
SYSTEM file (IEN=19). Fileman needs the
correct MUMPS type value when saving compiled templates.
See
also the note at the end of step 41 of this document, explaining that
initializing Fileman replaces the contents of MUMPS OPERATING SYSTEM file
entries, including the ZSAVE code, which may have been modified.
2.
vxVistA includes
a few routines that have names greater than the SACC standard 8 characters in
length. How can one view or edit these
routines in VPE?
VPE includes checks for both routine name
length and line tag length. To view or
edit a routine that has a long name, it is necessary first to modify VPE,
changing the maximum length allowed from 8 to 16 characters. Edit, save, and compile the following five
VPE routines, as illustrated.
%ZVEMKU
%ZVEMOS
%ZVEMRLX
%ZVEMRS
%ZVEMRV