I recently had a request for more information on dealing with blob data using our newly-released Mobile support, which finally got me to write something about low-level blob support.
This information applies to any application that isn’t using the .NET SDK to talk to HealthVault. If you are using the .NET SDK, I recommend using the support that is provided in the SDK.
HealthVault provides the capability of storing additional data – such as documents, images, etc. – as a blob of data attached to any of the HealthVault data types.
HealthVault provides two ways for applications to manage blob data; an inline method where the blob data is passed with the rest of the data for an item instance, and a streaming approach where blob data is accessed through http get and put requests.
This method passes the blob data in a base64-encoded format with the rest of the item data. It’s the simpler of the methods to use, but it has the following drawbacks:
Here’s how you deal with blob data using the inline method:
Here’s the “<info>” section of a GetThings request:
<info> <group> <filter> <type-id>3d34d87e-7fc1-4153-800f-f56592cb0d17</type-id> <thing-state>Active</thing-state> </filter> <format> <section>core</section> <section>blobpayload</section> <xml/> <type-version-format>3d34d87e-7fc1-4153-800f-f56592cb0d17</type-version-format> <blob-payload-request> <blob-format> <blob-format-spec>inline</blob-format-spec> </blob-format> </blob-payload-request> </format> </group> </info>
The “<section>blobpayload</section>” line specifies that in addition to the core part of the data item, any blob data should be passed back along with the rest of the XML. If you forget to do that, you won’t get any blob data…
This query returns a <blob-payload> section that comes after the <data-xml> section:
<blob-payload> <blob> <blob-info> <name /> <content-type>text/plain</content-type> <hash-info> <algorithm>SHA256Block</algorithm> <params> <block-size>2097152</block-size> </params> <hash>K9OYLkNyHLtTKRinTVTPh4WqbsZQ5l3jcUBIoMieNIc=</hash> </hash-info> </blob-info> <content-length>11</content-length> <base64data>U2FtcGxlIFRleHQ=</base64data> </blob> </blob-payload>
The following elements are important:
Here’s an example of saving a blob as inline data. The blob is passed at the same time the rest of the data for the instance is passed.
<info> <thing> <type-id>3d34d87e-7fc1-4153-800f-f56592cb0d17</type-id> <thing-state>Active</thing-state> <flags>0</flags> <data-xml>...</data-xml> <blob-payload> <blob> <blob-info> <name/> <content-type>text/plain</content-type> </blob-info> <content-length>4</content-length> <base64data>U2FtcGxlIFRleHQ=</base64data> </blob> </blob-payload> </thing> </info>
The <data-xml> section is removed for the sake of brevity. The important parts are:
In the streamed method, the blog data is fetched or stored using separate interfaces or methods.
Fetching the blob data is simple. If you change the filter to be:
<blob-format-spec>streamed</blob-format-spec>
Instead of the base64data element, you will get a blob-ref-url element that looks something like this:
<blob-ref-url>https://platform.healthvault-int.com/streaming/wildcatblob.ashx?blob-ref-token=ASAAAA%2br2bo24GxMiX1j8dyBpoQhGSTp1z9laFjW0PVfgRzyT3PzSWgLdGubgPEK4bUbZG0ni4nY5mlXTW9ZYZQi2iFVXOstWasUtNmtNxJj2NBLolSd9J4MI4aSPID0w1l%2bHwSq%2fEM1BADh%2b01iMtnEIBEMQt%2fuDu0yQrazxjaXR0QokGLtRFOduPvo0LyMDWuo8meFRTPoCNfQoE3IkqIgkvY3gS1KssuQtDXmjVkKCKLSi8lHZV0WjYnCdnilHUAKWoWSOp4d6QX3%2fAUbRbXzzdIr00WGtrDOuoZwXWs5MA%2fKSfi%2fbp4Gfh96ZXJP%2bRy9lDDj8RkWmorT5SQW9QC4QEUONDxW1vSelijjvno451gA%2fi3Ufa57k2%2fs0x6swKrFRDTF0OZknjc5Id92zAnjvOFa5rs4v430bpZiD5MScUsWmEwTpqucCsKorXodAN823Wx4J1VPkeoOZiejnGJePYdyN91g</blob-ref-url>
You can then download the blob data directly using the URL.
Uploading blob data through the streamed interface is considerably more complex; it requires calling the BeginPutBlob method to get the destination url and then uploading in chunks of data that are a specific size (it also supports signing data, which makes things even more complex).
If you are interested in using this to load large blobs, let me know, and I’ll try to update this to show that approach as well.
When we were creating our talk, we had a problem.
Well, to be fair, we had a few problems, but the problem that I want to talk about is the “for more information” slide, the one that you put at the end to direct people to a location where they can find more information.
There were actually two problems.
The first was was that we covered 13 different things during the talk, and there was no way to fit enough information onto a single slide (or even a few slides) to help people out.
The second was that a fair number (1 “fair” = 6) of items aren’t yet released and this was the first time we were talking about them, so there are no public resources to reference.
We decided to solve that by doing a “for more information” blog post on the HealthVault blog, which would help attendees find more information and also be of use to those who didn’t attend the talk.
And then I didn’t remember to write anything until Tuesday night, and had to do a bit of scrambling to get it done. But now, for your reading pleasure, you can read HealthVault at CHC 2011, find out what we demoed, what we announced in the mobile space, and other juicy tidbits of information.
The conference itself was pretty good, but at only a day and a half tends to feel pretty rushed. We spoke at 8AM on the second day of the conference, second only to the immediately after lunch as a slot that I would like to avoid, but the crowd seemed pretty good, at least, to the extent that I could see them; I tried to look around in the crowd but was a bit hampered by the lights; two searchlights previously used to illuminate Saturn V rockets were aimed directly at my face, and I literally could not tell whether people were standing or sitting; they could all have been wearing clown makeup for all I knew. And if you looked up too much, you’d end up with a bunch of spots in your eyes that made it hard to read your slides.
Our demo had a lot of moving parts, and it mostly worked correctly. What Vaibhav did was clean as far as I could tell; in my part, the conference center WiFi timed out and I had to re-initiate it during the talk, and I ended up provisioning the mobile application to talk to our practice account, not our live account, but luckily Vaibhav had written the eventing application so that either account worked. Oh, and I had unexpected lack of success with our CAPTCHA, even with the help of others.
Our goal was to time the talk to 45 minutes, and after answering a few questions during the talk, we finished at 8:52 which is pretty much perfect in my book.
Please let us know if you have questions or comments.