Thursday, November 12, 2009

TriZetto Hosted Batch Architecture

TriZetto Hosting has a framework in place for executing batch jobs – and that framework is called the Hosted Batch Architecture or HBA for short. So if you are a TriZetto Hosting customer, and are writing custom code to extend/enhance the core functionality of QNXT or Facets, you will come to a cross roads where you will need a job created to execute this custom code. And this is where the HBA comes into play. You will have to make sure your job is HBA compatible.

Before I get into what it means to be HBA compatible, I’d like to bring up the benefits the HBA provides us. The HBA provides a common look and feel for the execution and supportability of all jobs. This is a very important principle in custom development practice – keeping things consistent and the same. This means that all jobs will be kicked off the same way, they will use the same resources like I/O and database connections, and in the event that an error occurs, errors will be handled in the same manner. This is a very powerful benefit for TriZetto customers in my opinion. This reduces the burden and the cost of troubleshooting problems when they arise.

 The HBA in it of itself is a “black box.” So I can not really tell you what the HBA is. The TriZetto documentation refers to is a framework, so that is what I call it here. From a customer’s point of view, I can share with you that jobs can be configured using XML, and that you can use VB Script to extend the capabilities of the HBA if the need arises.


Creating jobs that are HBA compatible

Note: this section is entirely QNXT specific, and speaks to version 4.51 of the HBA

In a previous post, I discussed customizing QNXT using the Custom Database. Once you have a Custom Database setup, you will need custom code to take various read and write actions against that database. A common approach is to write this custom code into SQL Server Integration Service (SSIS) Packages. SSIS allows you to extract, transform and load data in and out of SQL Server.

Within an SSIS Package you define Connection Managers for any type of resource that will be consumed or published by the SSIS Package. For example, you will need Connection Managers for database connections, file system locations (like an /input or /output folder for example), SMTP and any other resource that will be part of the workflow of the package. A common practice in SSIS development is to place the values of these resources into a configuration file called .dtsConfig, and bind these configurations in at runtime. This way, if you have varying configurations depending on which environment (development, test or production) the package runs in, you don’t have to change code in the package to deploy to these environments.

In order to use a configuration file, you have to define Package Variables within your SSIS package. And use these Package Variables when creating Connection Managers so that resource names are never hard coded into the package. At run time, when the configuration file is bound in, the Package Variables are populated with the appropriate values for that environment, and the Connection Managers are ready to be consumed by and published to.

With the HBA, you employ a similar practice. The key differences are that:

(a) The configuration file is not a .dtsConfig. Instead it is a proprietary TriZetto file called Common System Properties. And if any local configurations are needed, there is a separate configuration file called the HBA Wrapper also referred to as the job XML

(b) The Package Variables must be placed within an HBA namespace

TriZetto provides an HBA Development Guide which details all of the particulars of how to build HBA compliant SSIS Packages, which includes, among other things the Package Variables you must use.  So becoming HBA compatible means employing these practices in your custom code.

Recommended Reading

If you are a TriZetto customer and are looking to familiarize yourself with the HBA, in addition to reading the HBA Development Guide, I recommend you also request information about:

  • Common System Properties - this should will come in the form of a list of variables and their meaning
  • HBA Wrapper Dev Guide - this has a list of commands you can execute inside of the HBA.  For example, there are command for file manipulation like fileDelete() and fileCompress().
  • Client Specific - you can enhance the functionallity of the HBA with VB Script be creating a Client Specific VB file that is imported into the HBA
  • Auto Date Parameters - there are a series of data variables that are predefined and available to you in the HBA.  For example, there is a date variable that always returns the first date of the current quarter, or the last day of the month 
Stay Tuned ...

In a future post, I will discuss a unique challenge that you have to solve with respect to HBA.  Since the HBA is only available in your hosted environments, you need a mechanism to unit test your code to make sure that you are consistently creating HBA compatible custom code.

Wednesday, November 11, 2009

Creating an Authorization or Referral with QNXT 3.4 SDK

When you install a QNXT EU (Execution Unit), you also get the QNXT SDK. The QNXT SDK is really just a Microsoft Word document that you will find in the \Program Files directory after the install is finished. You do not have to select anything special as part of the install process, the SDK is installed by default.

This Word document lists a series of assemblies that can be used to harness some of the functionality of the Execution Unit. This document does not go into great detail as to how to use these assemblies. Also, no code samples are provided. So you are left more or less to your own devices to figure out how to get what you need out of the SDK.

This blog post describes how we used the SDK to create authorizations/referrals using the QNXT 3.4 SDK. Near as I can tell what I am describing here is not documented anywhere else, including the TriZetto Customer Exchange Website. This is unsupported custom code, but it has passed Trizetto code review, which may not mean much to you unless you are a TriZetto Hosting customer. If you are Hosting customer, then passing code review means that TriZetto will deploy this code to your production environment.

There are two pre-requisites to get the sample code provided in this blog post to run:

  1. Install the QNXT 3.4 EU locally
  2. Create a QNXT User with (a) the appropriate QEnvironment added i.e. Integrated Dev and (b) with the “Authorization Assignment” role added/granted

Next, you will need to bind in the following reference assemblies to compile this code

  • QCSI Globals.dll
  • QCSI Internal Proxy.dll
  • QCSI Messages Authorization.dll
  • QCSI Messages CommonTypes.dll
  • QCSI Proxy Authoriztion.dll
  • QFrame Common Messages.dll

All of the above are installed into the GAC on the EU. If you are using Visual Studio to build your project, you will need to xcopy these out of the GAC first so that they will show up in your Add References wizard.

Without any further ado - here is a working unit test to create an authorization/referral using the SDK
using System;
using Q.QFrame.Messages;
using Q.Proxy;
using Q.Global;
using MbUnit.Framework;

namespace AuthPosting.Tests
{

[TestFixture]
public class AuthPostingTests
{

[Test]
public void CreateReferralTest()
{
QNXTProxy _proxy = new QNXTProxy();
if (!_proxy.InitQNXT("user", "password", "environment", "plandataAlias")) Assert.Fail();

AuthCreateUpdateRequestMessageType _request = new AuthCreateUpdateRequestMessageType();
_request.Referral = new ReferralMessageType();
_request.Referral.EnrollId = "";      // QNXT Enrollment ID
_request.Referral.MemId = "";       // QNXT Member ID
_request.Referral.ServiceCode = ""; // QNXT Template ID
_request.Referral.Cob = 0;
_request.Referral.ReferTo =""; // QNXT ReferTo Provider Id
_request.Referral.EffDate = DateTime.Today.ToString();
_request.Referral.ReferFrom = ""; // QNXT ReferFrom Provider Id
_request.Referral.Emergency = 0;
_request.Referral.ReferralDate = DateTime.Today.ToString();
_request.Referral.TransferInOut = 0;
_request.Referral.AdmitDate = DateTime.Today.ToString();
_request.Referral.IssueInitial = "webusr";
_request.Referral.DischargeDate = DateTime.Parse("2078-12-31").ToString();
_request.Referral.TermDate = DateTime.Parse("2078-12-31").ToString();
_request.Referral.PayToAffiliationId = ""; // QNXT PayTo Affiliation ID
_request.Referral.AttProvid = ""; // QNXT Attending Provider Id
_request.Referral.AppealDate = DateTime.Parse("2078-12-31").ToString();
_request.Referral.AccChg = Convert.ToDecimal(0.00);
_request.Referral.Acuity =  "Urgent";
_request.Referral.Admit = 1;
_request.Referral.AdmitDate = DateTime.Today.ToString();
_request.Referral.AdmitPhys = "";
_request.Referral.AdmtProvid = ""; // QNXT Admitting Provider Id
_request.Referral.AuthStatus = AuthStatusType.MEDREVIEW;
_request.Referral.Diagnosis = "";
_request.Referral.DisDiagnosis = "";
_request.Referral.Dispositionid = "";
_request.Referral.ProcessLogId = "";
_request.Referral.ReceiptDate = DateTime.Parse("2078-12-31").ToString();;
_request.Referral.ReferToLocation = "";
_request.Referral.ReferToPar = YesNoType.N;
_request.Referral.ReferToProvType = "";
_request.Referral.Source = ReferralMessageTypeSource.Q;
_request.Referral.DecrementType = ReferralMessageTypeDecrementType.SVC;
_request.Referral.Status = AuthStatusType.INPROCESS;

_request.Referral.ReferralText = new ReferralTextMessageType();
_request.Referral.ReferralText.Reason = _referral.Reason;

switch("Auto")
{
case "Auto":
_request.Referral.AccidentCause = ReferralMessageTypeAccidentCause.A;
break;
case "Employment":
_request.Referral.AccidentCause = ReferralMessageTypeAccidentCause.E;
break;
case "Others":
_request.Referral.AccidentCause = ReferralMessageTypeAccidentCause.O;
break;
case "No":
default:
_request.Referral.AccidentCause = ReferralMessageTypeAccidentCause.Item;
break;
}

_request.Referral.AuthDiags = new AuthDiagMessageType[1];
_request.Referral.AuthDiags[0] = new AuthDiagMessageType();
_request.Referral.AuthDiags[0].DiagCode = "100.0";
_request.Referral.AuthDiags[0].Sequence = "1";
_request.Referral.AuthDiags[0].DiagQualifier = AuthDiagMessageTypeDiagQualifier.PRINCIPAL;


AuthCreateUpdateProxy _authProxy = new AuthCreateUpdateProxy(_proxy.Session);

AuthCreateUpdateResponseMessageType _response = authProxy.ProcessMessage(_request);
}



}
}
}

Note that AuthCreateUpdateProxy() method does not perform any data validation. So if this is important to you, you will have to perform this outside of the SDK. Also, the SDK does not support:

  • Adding data to custom attributes
  • Creating an authorization service
  • Creating an authorization alert/memo

These operations will also need to be performed outside of the SDK.

Here are is a list of some other tests we found to be useful in insuring the quality of the SDK interface:

  • Add authorization with wrong or missing Member Id
  • Add authorization with wrong or missing Enrollment Id
  • Add authorization with wrong or missing Auth Template Id
  • Add authorization with wrong or missing Refer From Provider Id
  • Add authorization with wrong or missing Refer To Provider Id
  • Add authorization with wrong or missing Affiliation Id
  • Add authorization with wrong or missing Admitting Provider Id
  • Add authorization with wrong or missing Admitting Provider Id
  • Add authorization with wrong or missing Diagnosis Code
  • Add duplicate authorization