I’ve been working with a large hospital chain and working on solving some pretty complex challenges. Recently, we have been working on implementing some McKesson applications within their organization, but we also wanted to implement it with the concept of ‘Roles’ kept in mind.
Let me first start with our application challenges. The two most commonly used McKesson applications are HCI and HPP. For HCI, we found that there is an engine underneath called cloverleaf that uses a standard protocol called HL7 to send messages around. We have three options to explore. The first is a proprietary HL7 driver that will connect to an HL7 listener, and pass it a carefully constructed HL7 message (the message I have to construct in the driver output transform). The second is to use an HL7 emulator that is already in place to consume a text file in the format of that same HL7 message. The third is to use an open API that I found to open a socket using the java api. I can call the java api from ECMAScript and use an XPath expression within my driver to do it. Once I open the socket, I simply pass the same HL7 message used by the other two steps through it. Currently, I’m debugging option three, and we have already done some preliminary testing on option 2. If we can’t get option 3 working, we can fall back on 2.
For HPP, we did something pretty nifty as well. The customer identified an API that could be used to interface with the HPP database. They stood up a web service that I could send calls to in a very specific format to add/modify/disable users from that system. I simply construct a URL with a bunch of arguments on the end and call the URL. The webserver will take the URL, process the transaction and post back a return code instead of a bunch of HTML. Very simple implementation. The key part was to encrypt the arguments so I wouldn’t be sending username and password combinations over the wire in clear text. I did this by implementing an encryption protocol using ECMAScript and XPath within my driver. So now, my URL has a bunch of seemly meaningless characters on the end, but the webserver can decode this into a meaningful set of arguments.
The next challenge for implementing these two applications came up when the customer requested to not have over 200 drivers to do this implementation. There are over 100 locations for this customer and each location has an HCI and HPP implementation. We needed to architect the drivers in such a way that one HCI or HPP driver could service more than one location. Just to add a little more fun and complexity, the customer also wants the “Roles” concept to be built in as well.
I worked with the customer and we kicked ideas back and forth until we came up with what we thought would be a great implementation. We took the idea of a ‘role’ and decided to turn it into an edirectory object. We also decided that we may as well make each ‘facility’ its own object as well. We already have objects for each ‘user’. Here is how they all tie together. For HCI, there will be a ‘role’ for each role in that system (or you can define a role in HCI as a combination of attributes that consists of access to that system). For each facility, we will create a ‘facility’ object. We already have a ‘user’ object for each user in their system. So, now we have a ‘role’ object with a bunch of attributes that define what the “Nurse” role in the HCI system consists. We also have a facility object for Hospital 123, with some attributes telling us information about that location, such as the location of its HCI system, the port number, private key file used for securely coping files over, and such. The only information we need to store on the actual user is what role and what facility (Role – Nurse, Facility – 123).
Due to the fact that a user at this customer could potentially have access to multiple locations at the same time, we had to ensure that the attribute where we store the role and facility for HCI and HPP were multivalued. So, we now have two attributes attached to user (well, attached to an aux class, which is attached to our users). These two attributes are multivalued lists of facilities with roles. We now have what access and where it should be provisioned in a list format attached to each user.
In the actual logic, we keep an eye on this attribute to know when we need to provision/deprovision/modify an account on a respective system. I used a series of loops to go through each value and did ECMAScript functions with XPath calls to actually write out files or call URL’s. This allowed me to service multiple sites with a single driver. I just used a multivalued GCV on the driver to list which facilities are supported by this driver (so I could split the load if required). When the driver determined work needed to be done for a user, I would retrieve the access information from the role object using an XPath call, then retrieve the information on where to provision this information from the facility object, tag all that information with what I need from the user (username, password, etc), then make my call.
We were able to successfully implement complex IDM systems, such as McKesson HCI and HPP, using the out-of-the-box Novell IDM components and some creative architecture. This also gave us the ability to grant roles into the framework and service multiple sites with a single driver for each system. The drivers can be split up if required for load balancing. Also, if a role needs to be modified in the future, we simply need to modify the ‘role’ object in question, without having to touch the potentially thousands of users subscribing to that ‘role’.