Custom Filenames with the HIPAA accelerator

Many a client has requested to have custom filenames using the HIPAA_EDI adapter.

I originally planned on using a custom ASM pipeline component and setting the ghost port to batching, and within the orchestration setting the RecievedFileName.

Found out that when that happens, no file is created, also, no errors are created! This really smells like a bug, as there is no documentation on this!

After contacting Microsoft, and submitting a ticket, this is the response I got back:

The HIPAA pipeline is not architected to support batching. It simply does a one-on-one translation from XML to EDI and that’s it.
The batching mechanism is depending on the data in the audout table and the HIPAA pipeline does not persist any data.
The only way you can create outbound EDI batches is via the HIPAA EDI adapter.

I ended up having to re-engineer the process so that (written about here), by single threading the entire process, files do not get batched together and files can be accounted for.

Adding functionality to the Expression Editor

For those of you who like to manipulate data in the expression editor, there are a few things that can be done:
1. You can build a C# or VB.NET assembly that will take a string and manipulate it returning the correctly formatted string
2. You can use xpath.

A clients request is that we parse from the filename, the date that is embedded in the filename.

The first thing I did was extract the filename into a variable called FileName:
FileName=IncomingMsg(File.ReceivedFileName);
FileName=System.IO.Path.GetFileName(FileName);

Then I needed to pull from position 26-31 the date into the variable MessageDate:
MessageDate=xpath(”substring(’”+FileName+”’,26,8)”);
(One gotcha is that you have to put a single quote ’ right after the open paranthese and then a double quote ” and then concatonate the variable and then do the reverse to close it out. The other gotcha is that if you are parsing out a string that has a single tick ( ’ ), you will have to use the Regex replace and replace it with another variable, substring the variable, and then replace the single tick back.)

This adds quite a bit more functionality to the Expression Editor than what is currently available.

The web page that I use as a xpath reference is this page.

BizTalk HIPAA Configuration

Here is the list of changes that need to take place if you are having issues either in validating or deploying the WPC schemas.
Click below

1. Stop the HIPAA Service
2. Delete all files (normally the .wrk and .eif files) in this directory C:\Documents and Settings\All Users\Application Data\Microsoft\BizTalk Server 2004\HIPAA_EDI\Subsystem\EIF
3. Start the HIPAA Service
4. in the {Program Files}\Microsoft BizTalk Accelerator for HIPAA 3.0\HIPAA_EDI\Subsystem double click on the compeif.exe and wait for it to complete
5. Open up the parame table in the BizTalkHIPAA_EDIDb and change the column repolock to NULL by pressing CTRL+0

You now should be able to re-validate or re-deploy the schemas that were causing the issue.

COM proxy stub dll and why do you need it

Let’s start from the end, after all ordering of posts on a blog make it natural. Please, notice that this post is rather for people starting writing COM, veterans would find it pretty evident. On another hand, remembering all the small details may be bothersome, so I decided to push it to the blog as a reminder.


 


Suppose you implemented your COM object, everything look fine while you test it in DLL or in the same exe file, and now you are trying to host it in EXE or use a threading model different from apartment. The behavior becomes a little puzzling. To start from, your test driver returns 0x80040155 (REGDB_E_IIDNOTREG). What happens?


 


You investigate more, and notice that your class factory CreateInstance method is called all right, it goes through creation, it calls QueryInterface, which also works just, fine, and it returns S_OK, but that’s not what you test driver that called CreateInstance gets!


 


Apparently, COM runtime got in the middle, tried something, failed, and returned failure instead of S_OK. Why? You investigate more and notice that Query Interface on your object created by CreateInstance is called several times with some strange IIDs: 



{00000003-0000-0000-C000-000000000046}


{0000001B-0000-0000-C000-000000000046}


{00000018-0000-0000-C000-000000000046}


{00000019-0000-0000-C000-000000000046}


{4C1E39E1-E3E3-4296-AA86-EC938D896E92}


You check a few of them up and find out that these are marshalling interfaces. But, you wonder, should the default marshaler handle it, if you did not implement them?


 


Yes, it will. But it needs the description of your interfaces. So, either description of interfaces of the proxy stubs should be available. There are two ways to do that: type library (which has a few restrictions) or proxy stub DLL. I will talk about type libraries some other time, for now let’s see what traps expect you when creating a proxy stub.


 


First, what do you need for you proxy stub? Surprisingly little – just your IDL file. If you do it in Visual Studio, create and empty Win32 DLL project; name it, say, “myproxy”; drop the IDL file into the folder; and add it to the project as a source file, let’s say, it’s called my.idl. Compile it.


 


You get four more files: my_h.h, my_i.c, my_p.c and dlldata.c. Add all of them except .h file to your project. Now, try to build the project


 


Oops


 


“Fatal error C1189: #error : You need a Windows 2000 or later to run this stub because it uses these features: /robust command line switch.”


 


Of course, you can go to project properties, MIDL compiler and uncheck “Validate Parameters”, but generally /robust flag is a very good thing, so unless you plan to run the object on anything before Windows 2000, you better just set the compiler flag saying that. Go to project properties, C/C++, Preprocessor, Preprocessor Definitions and add “;_WIN32_WINNT=0x0500” in the end of the line. Try to build again


 


Now you should get a bunch of linker errors. Why that? That’s because you are missing COM runtime library in your project. Go to project properties again, Linker, Input, Additional Dependencies, and add rpcrt4.lib to the line (it should be empty anyway, but if there is anything there, just add “rpcrt4.lib” to the list). Try to build again.


 


Now, it should succeed. Are you done? Not quite. Yes, myproxy.dll is successfully built. But it needs to be registered. This may be done from a command line with regsvr32:


 


Regsvr32 myproxy.dll


 


Oops, again:


 


MyProxy.dll was loaded, but the DllRegisterServer entry point was not found.


This file can not be registered.


 


What happened now? You forgot a .def file that tell to export DLL entry points. You can create it in notepad. Call it myproxy.def, open it in notepad, and type in:


 


; MyProxy.def


LIBRARY             MyProxy.dll


EXPORTS


            DllGetClassObject  PRIVATE  


            DllCanUnloadNow   PRIVATE


            DllRegisterServer    PRIVATE


            DllUnregisterServer PRIVATE


 


Now, you need VS to pick it up. Go to project properties once more, Linker, Input, Module definition file, and enter the file name there. Also, add one more C++ preprocessor directive, if it’s not there yet: “;REGISTER_PROXY_DLL”


 


Rebuild it. Register it – now it will succeed. You are done with the proxy dll.


 


Don’t forget that, in the process, your IDL was moved to a separate project within the solution, your header file (my_h.h) has moved to another folder, and you still need the header and IID definitions (my_i.c) for your main projects. Otherwise the thing should start to work.


 


Notice, that generally, you would register it with the keys in the installation module. Regsvr32 is just a development time workaround.


 


So, again, a short reminder of what you need to do:



  1. Create empty DLL project
  2. Set “preprocessor definition” WIN32_WINNT=0x0500 and REGISTER_PROXY_DLL
  3. Add linker “additional dependency” rpcrt4.lib
  4. Create a def file for your project and set it as the linker “module definition file”
  5. Compile IDL and files, generated out of IDL, into a DLL
  6. Register proxy DLL with regsvr32

 

Delivered, Not Consumed

I came across this error while testing an orchestration. To explain the situation, we were pulling data from various tables via some stored procedures. We finally sent out a file, and then waited until an acknowedgment message was recieved. Once that message was recieved, we then called a seperate orchestration that would return a control number. Afterwards we would determine what kind of message to create based on the acknowedgment. It would then take the various messages from the stored procedure, and we would then have a map transform the messages into one single message.
This all seemed to work fine, until we would recieve the acknowledment, then it would label the call to the external orchestration as ’Delivered, Not Consumed.’

After banging my head against the wall for a while – a day of fiddling, etc – I took the call to the external orchestration out completely.
I then re-ran it, and it then labelled the acknowledgement as Delivered, Not Consumed, when I KNEW THAT IT WAS WORKING.
I then continued banging my head against the wall until I finally put a call into MS Support. I was quickly promoted to the 3rd level support, where I talked with an individual from England until he asked me to debug the orchestration. I then stepped through the orchestration, and I got past the consuming of the acknowledgment message, past a test, past a expression shape, and then it died when it invoked a map!
I then looked at the map, again, which took many messages, and created one message. It was not set up correctly, functoids were missing necessary parameters.
I then fixed the map, and the orchestration started working as expected.

So if you are reading this, please walk debug the orchestration if you ever get that message, because it normally means something down the orchestration path is bad, not the last communication outside of BizTalk had invoked.

Opening up an InfoPath form from a different form

Wouldn’t it be nice to open an InfoPath form from another form, and “jump” to a particular row in the database that is being referenced?

That was my question, and it took some questioning, searching, etc to get the answer. (Thanks to http://www.infopathdev.com, and http://msdn.microsoft.com)

So here it goes, I have a form that I query and get the results, and then I want to jump to another form based on my results.

I created a button, and then edited the button.

Here is the actual code, in which I will comment on it after:

function OpenDetail::OnClick(eventObj)
{
//Get the local file path
var sFormPath = “”;
var sUri = XDocument.Solution.URI;
var i = sUri.lastIndexOf(””);
if(-1 == i)
i = sUri.lastIndexOf(”/”);
sFormPath = sUri.substring(0, i + 1);

//Get the Parent ID form this form
var param1=XDocument.DOM.selectSingleNode(”/dfs:myFields/dfs:dataFields/d:ContactInfo/@ID”).text;

//Start the application
var oApp = new ActiveXObject(”InfoPath.Application”);

//Open an InfoPath document from the published template
var oXDocumentCollection = oApp.XDocuments;
var oXDocument = oXDocumentCollection.NewFromSolution(sFormPath+”detail.xsn”);

// Get pointers to the target fields
var oID = oXDocument.DOM.selectSingleNode(”//@parentid”);

//Update the fields
oID.text = param1;

oXDocument.Query();
}

The first part gets the local directoy (assuming that both forms are located in the same directory.
The second part grabs the data from the ’parent’ form that is going to be used to key the second form.
{The rest of the code’s comments explain what is going on.}

Once that the variable is filled, then we can run the Query() function to return the data.

The issues that I am having right now is that when you open up the new form, you get 3 security warning messages, so I am looking at how to get rid of those dialog boxes.

Setting up SharePoint on the same server as BizTalk

am not sure if I am the only one who has this problem, but everytime I set up an instance of BTS on a new machine, I am gun shy about how to set up SharePoint Services (WSS).

I know that if I go thru the installation of Biztalk and accept the defaults, WSS gets installed at the root level (http://localhost). This would acutally be fine, if you never have a use to do anything other than SharePoint stuff.

Most of us, however, have another use for the default web site. I, for example, might be developing some web services, or creating a different page outside of SharePoint. Web Services do not work with SharePoint very well, so you need to develop the Web Services on a different web site.

I am going to give instructions on how to set up WSS after you have already installed it, and already gone through the BTS installation.

Here they are:
1. Create a new folder where the new WSS site is going to be. (for me: c:\inetput\wwwroot\sharepoint)
2. Open up IIS, and right click on Web Sites and choose New Web Site
3. In the Welcome to the Web Site Creation Wizard, click Next
4. In the Web Site Description window, type a description (I typed Sharepoint)
5. In the IP and Port Settings dialog box:
A. Leave the default [All Unassigned] for the IP address to use
B. Type in the port you want to use (in my case I used port 8080)
C. Leave the Header blank
6. Browse to the folder that you created (see step 1)
7. Click on the Web Site access permissions you want
8. Click Finish

Congratulation you are done!

(okay not quite)

9. Go into your SharePoint Central Administration
10. Click on the Extend or upgrade virtual server
11. If you don’t see all of the web sites listed in IIS, click at the top the link for the complete list
12. You should see Default Web Site, and your newly created web site, but your newly created site does not have a version, it states that it is ’Not Installed’
13. Click on the site that you just created
14. Click Extend and create a content database
15. For the Application Pool, I chose the existing application pool, StsAdminAppPool
16. Put a Site Owner Email in, and I left everything else as default
17. Now the gears should be turning (literally)
18. It should now show that it was successfully extended
19. Go BACK to the Central Administration Page
20. Click on the Extend or upgrade virtual server
21. Click on the Default Web Site
22. Click on Remove Windows SharePoint Services from virtual server
23. Because I don’t want to delete the database, I chose to remove w/o deleting the database and press ok

You have completed the sharepoint set up, now if you go to http://localhost:8080 you should see the Template web page, and if you go to the default web site, you should see that it is under construction

Hope that this has helped people in correllating WSS with BTS.

Failed to create master secret

While at a client site, I came across an installation error I had not come across.

At the last part of the configuration of the installation of BTS 2004, an error came up stating ’Failed to Create Master Secret’ and the only options were to Retry or Cancel.

Well, Retry does not do anything, and so cancelling does what we all love – un does EVERYTHING.

Come to find out, if you are not connected to a network, or if you don’t have a valid IP address, this part will not work, you will need to have a valid IP address for ESSO to install properly.

Multiple occurrences of the same document

For those of you who got used to the Covast bells and whistles that come with the Covast EDI adapter, and then come to another EDI tool interfacing with BizTalk, namely the HIPAA accelerator, made for Microsoft by ?????, there are quite a few nice things missing. One of those things being the ability to clear the report so you are not flooded with ’stuff’

Another BIG issue is that while testing, it would be REALLY nice to be able to send the file through a few times to make sure that the file works correctly. There is NO way to disable the duplicate interchange control checking.

Here is the sql code (run against the BizTalkHIPAA_EDIdb database) to clear out the report, and also allows you to run the same file through the HIPAA accellerator again:

delete from audin
delete from audout

Bye the way, you will want to go into the %documentshome% directory and delete/archive the files that are there, as the temporary files will prevent the adapter from writing new ones.

Another option is to use the custom HIPAA DASM that does not check for duplicate control numbers, namely because it does not check the audin and audout tables.