Library

Browse and search developer information

Demographic Batch Service – DBS

By Connecting for Health | 4 March 2013

Introduction

The Demographics Batch Service (DBS) allows NHS staff and systems to verify or find a patient’s NHS number. It doesn’t let you discover anything confidential, such as medical history, care records or hospital visits. DBS itself is quite flexible in the way it can be used (queried). In general use, though, there are four very common queries that are used:

  • Cross Check 1: Verifies that a patient’s NHS number is correct, given a known date of birth.
  • Cross Check 2: Verifies that a patient’s NHS number is correct, given uncertain date of birth and name details.
  • Standard Search (also known as a Trace): Finds all possible NHS numbers for a patient given name, post code, date of birth and gender details.
  • Advanced Search: Similar to a Standard Search, but it allows the use of more discriminating criteria.

Using the Demographics Batch Service

Being an older NHS service, the DBS has a complex data format and slightly odd usage. In essence, a program creates a request file, populated with details appropriate to the query being used, and then sends this to a central service. The sending uses a ‘drop box’ and polling. The results are then sent back as a file using the same technique, and the client can pick them up. There is a lot more operational complexity than that described.

To make it easier to query DBS, both from the command line and from Java, we’ve written some code, open source, which you can use to create the request files and read the response files. To make things as easy as possible, we’ve also written some wrappers for POSIX and Debian/Ubuntu. Your choices, in order of decreasingly convenience, are:

  • Debian/Ubuntu deb packages, hosted in our apt repository.
  • A tar ball, which contains a complete file system to untar over your root /. These should work on any POSIX system, including Mac OS X and Cygwin.
  • A standalone java jar, with all dependencies included, suitable for execution or as a library.
  • A set of java code libraries with source.
  • Forking from github.

See the download page for instructions on how to install one of these.

Creating Requests

The best way to get going is to use the command line. We’ll look later on how to create requests programmatically using the java library.

Creating Requests on the Command Line

The way you do this varies depending on what you used above:

  • If you’ve installed the deb package or the tar ball, you’ll have the program hdn-dbs-request on your PATH. To use it, open a terminal console and type hdn-dbs-request. It takes standard POSIX options.
  • If you’ve installed the standalone jar file, you’ll need to run commands from the folder you downloaded the file to. Open a terminal console and change folder to the folder it is in. Type java -jar hdn-dbs-request.jar. It takes the same standard POSIX options as the program above. For the rest of this document, wherever you see hdn-dbs-request … you can substitute java -jar hdn-dbs-request.jar …
  • If you’ve downloaded or forked source from github, you can use IntelliJ to run the main class. Open source\subprojects.ipr and run the main class uk.nhs.hdn.dbs.request.client.HdnDbsRequestConsoleEntryPoint. There are already some sample configurations set up for you to debug in IntelliJ. If you don’t have or use IntelliJ (and really should) then you can open in Eclipse or NetBeans. You’ll need to add the libraries ‘annotations’ (library/annotations/VERSION/annotations.jar) and ‘jopt-simple’ (library/jopt-simple/VERSION/jopt-simple-VERSION.jar) to the class path.

Checking everything’s OK

Before we get going, let’s check that everything works as expected. Run the command hdn-dbs-request –help (remember to substitute java -jar hdn-dbs-request.jar if you need to). You should see a list of supported options. At the time of writing, it looks like this:

Option                                   Description
------                                   -----------
--dob <DbsDate: Date of Birth as         Date of Birth as YYYYMMDD
  YYYYMMDD>
--file-sequence-number <Integer:         defaults to 1 (default: 1)
  defaults to 1>
--help                                   Displays help for options
--local-patient-identifier               Local PID
  <LocalPatientIdentifier: Local PID>
--nhs-number <NhsNumber: 10 digit NHS    10 digit NHS Number
  Number>
--organisation                           SDS Organisation Code
  <SpineDirectoryServiceOrganisationCode:
  SDS Organisation Code>
--out <Path to output file, or - to      Path to output file (default: -)
  use standard out (the default)>
--tracing-service-code                   ?
  <TracingServiceCode: Tracing Service
  Code>
--version                                Displays version

If the output seems a bit compressed, it’s because we’re formatting for a 40 character wide screen – useful if you’re running this over ssh on Android. Whilst you can’t see it above, help output always produces an exit code of 1.

Since the options are regular POSIX long options (and are named similarly to those in the GNU coding standards), we can abbreviate them. Hence hdn-dbs-request -h and hdn-dbs-request –he will produce the same output. The only time you can’t do this is if the abbreviation would be ambiguous.

Let’s try out one of those options: –version.

Checking the version installed

Let’s run hdn-dbs-request –version:

hdn-dbs-request 2013.03.01.1537-development
© Crown Copyright 2013

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Written by Raphael Cohn (raphael.cohn@stormmq.com)

Standard GNU-like stuff. It’s worth understanding the version number, in this case, 2013.03.01.1537-development. The part before the hyphen is the timestamp of the last git check in used to build the binary – you should be able to find it using git log. Additionally, this should match the version of the deb package. The part after is the git branch the code was built from. Usually this will be either development or master.

If instead it says unknown version then it means you’re using code you’ve compiled yourself or wasn’t released ‘officially’.

Simple Cross-Check 1 using the Command line to verify a patient’s NHS Number

Verifying a NHS number couldn’t be simpler. The minimum we need to specify is:

hdn-dbs-request --nhs-number NHS_NUMBER --dob YYYYMMDD --local-patient-identifier PID --organisation SDS_CODE --tracing-service-code TSC

This will produce a file suitable for sending to DBS on standard output (stdout).

So what do these mean:

  • NHS_NUMBER: The ten digit NHS number. The program will check that the NHS number is valid. Standard hyphen separators (123-456-7890) or space separators (123 456 7890) are valid but not advised. If you use spaces you’ll need to escape on the bash command line using single or double quotes to prevent mis-interpretation by the shell (eg `–nhs-number ‘123 456 7890’).
  • YYYYMMDD: The patient’s exact date of birth.
  • PID: If you don’t have a suitable input, just use the NHS_NUMBER. A future version of this program might default to the NHS_NUMBER. Not used by DBS to verify but included so you can correlate you results.
  • SDS_CODE: Your organisations’s Spine Directory Service Code. Not used by DBS to verify but included so you can correlate you results.
  • TSC_CODE: Transaction code. Not used by DBS to verify but included so you can correlate you results.

If you make a mistake, or an argument isn’t validly formatted, the program will return an exit code of 2 along with a brief error message on standard error (stderr) and a description of the options similar to help.

If you want to put the output in a file, then you can send output to a file using the –out switch:

hdn-dbs-request --nhs-number NHS_NUMBER --dob YYYYMMDD --local-patient-identifier PID --organisation SDS_CODE --tracing-service-code TSC --out /PATH/TO/FILE

This will overwrite any existing file.

If you are sending a sequence (series) of requests to DBS, you’ll need to use an incrementing sequence number. This is specified using the –file-sequence-number switch:

hdn-dbs-request --nhs-number NHS_NUMBER --dob YYYYMMDD --local-patient-identifier PID --organisation SDS_CODE --tracing-service-code TSC --out /PATH/TO/FILE --file-sequence-number NUMBER

where NUMBER is a positive integer between 1 and 99 999 999 inclusive.

More advanced searches on the Command line

These are not currently supported. You’ll need to use the library to do these – instructions are below. However, a good starting point to understanding them is to look at the source of the uk.nhs.hdn.dbs.request.client.HdnDbsRequestConsoleEntryPoint class. You’ll find a good place to start is the static crossCheckNhsNumber method, which is the point in the code at which there’s no more command line parsing going on to distract you.

Creating Requests Programmatically using Java

The way you do this varies depending on what you used above:

  • If you’ve downloaded or forked source from github, you can use IntelliJ. Open source/subprojects.ipr and start hacking.
  • If you’ve downloaded the jars (and source zips), create a project or add them to an existing project in your favourite IDE (if it isn’t IntelliJ, then switch now).

You can either add the hdn-dbs-request.jar as is (simple option), or, for more refinement and better integration with other HDN tools, its dependent jar files:

  • common
  • common-postCodes
  • common-reflection
  • common-serialisers
  • common-serialisers-separatedValues
  • dbs
  • dbs-request
  • number
  • and the third-party library annotations.jar (this is a compile-time only dependency)

This list may change. To find the most up-to-date list, either extract META-INF/MANIFEST.MF from hdn-dbs-request.jar and read the Class-Path entry, or open the IntelliJ project (source/subprojects.ipr) and look at the dependencies of the module dbs-request-client (sensibly, module names match jar names and source zip names). Note that you’ll not need the common-commandLine module (jar) or jopt-simple library.

Simple Cross-Check 1 to verify a patient’s NHS Number

To show how to create requests, we’ll look at how to create the same output as the command line.

The core of the request API is the class Request (in uk.nhs.hdn.dbs.request). This specifies the data to send to DBS, which falls into three kinds:

  • Header data, produced by the class RequestHeader
  • Body data (the meat of the query), produced by implementations of the interface RequestBody
  • Trailer data, which is produced by the class RequestTrailer

To illustrate, let’s look at a typical code snippet to generate Cross-Check 1:

final RequestBody requestBody = new CrossCheck1RequestBody(localPatientIdentifier, dateOfBirth, nhsNumber);
final RequestHeader requestHeader = new RequestHeader(NoPracticeOrPatientAddressReturned, requestingOrganisationCode, tracingServiceCode, fileSequenceNumber);
final Request request = new Request(requestHeader, requestBody);
request.serialise(outputStream);

The first line creates a request body, the most important piece of information. Arguments are identical to those you’d need for the command line. We’ll look at how we create these latter – the API strongly types data, rather than relying on generic strings or java dates. Strong typing is designed to be refactored by you, so you can add behaviour where it matters.

The second line creates a request header. Arguments are like those for the command line. Of interest here is NoPracticeOrPatientAddressReturned. This is a constant telling DBS the kind of request being made (it’s defined in the enum FileVersion).

The third line creates a request from the header and body. You might be surprised to see there’s no trailer. That’s because the trailer is a near-restatement of the header, and is generated by the request when needed.

The last line serialises the request to a standard java OutputStream. It might be a file, or a byte array, or a string. The API doesn’t care. Normally you’d use a FileOutputStream, as requests to DBS are from files. One thing you should do, though, is close the stream as soon afterwards as practicable. You can’t send multiple requests to DBS with one file. It may throw one of two exceptions if things go wrong: IOException, or CouldNotEncodeDataException. The latter occurs when invalid unicode codepoints are in data (eg unpaired UTF-16 surrogate pairs) or control codes are in the data to be sent.

Let’s look at how to create some of those arguments from requestBody:

final LocalPatientIdentifier localPatientIdentifier = new LocalPatientIdentifier("Some string value of PID");
final DbsDate dateOfBirth = DbsDate.valueOf("20130210"); // YYYYMMDD
final NhsNumber nhsNumber = NhsNumber.valueOf("1234567890"); // Also variants with separators such as "123 456 7890" and "123-456-7890" are supported

And for requestHeader:

final SpineDirectoryServiceOrganisationCode requestingOrganisationCode = new SpineDirectoryServiceOrganisationCode("Some code");
final TracingServiceCode tracingServiceCode = new TracingServiceCode("some code");
final int fileSequenceNumber = 1; // range is 1 to RequestHeader.MaximumFileSequenceNumber

Finally, outputStream is just an OutputStream – perhaps System.out or new FileOutputStream()

final OutputStream outputStream = out;

Putting it all together, a sample java file might look this:

package uk.nhs.hdn.dbs.request.client;

import uk.nhs.hdn.common.serialisers.CouldNotEncodeDataException;
import uk.nhs.hdn.dbs.DbsDate;
import uk.nhs.hdn.dbs.LocalPatientIdentifier;
import uk.nhs.hdn.dbs.SpineDirectoryServiceOrganisationCode;
import uk.nhs.hdn.dbs.TracingServiceCode;
import uk.nhs.hdn.dbs.request.Request;
import uk.nhs.hdn.dbs.request.RequestHeader;
import uk.nhs.hdn.dbs.request.requestBodies.CrossCheck1RequestBody;
import uk.nhs.hdn.dbs.request.requestBodies.RequestBody;
import uk.nhs.hdn.number.NhsNumber;

import java.io.IOException;
import java.io.OutputStream;

import static java.lang.System.out;
import static uk.nhs.hdn.dbs.FileVersion.NoPracticeOrPatientAddressReturned;

public class Example
{
    public void example() throws IOException, CouldNotEncodeDataException
    {
        final OutputStream outputStream = out;
        final SpineDirectoryServiceOrganisationCode requestingOrganisationCode = new SpineDirectoryServiceOrganisationCode("Some code");
        final TracingServiceCode tracingServiceCode = new TracingServiceCode("some code");
        final int fileSequenceNumber = 1; // range is 1 to RequestHeader.MaximumFileSequenceNumber

        final LocalPatientIdentifier localPatientIdentifier = new LocalPatientIdentifier("Some string value of PID");
        final DbsDate dateOfBirth = DbsDate.valueOf("20130210"); // YYYYMMDD
        final NhsNumber nhsNumber = NhsNumber.valueOf("1234567890"); // Also variants with separators such as "123 456 7890" and "123-456-7890" are supported

        final RequestBody requestBody = new CrossCheck1RequestBody(localPatientIdentifier, dateOfBirth, nhsNumber);
        final RequestHeader requestHeader = new RequestHeader(NoPracticeOrPatientAddressReturned, requestingOrganisationCode, tracingServiceCode, fileSequenceNumber);
        final Request request = new Request(requestHeader, requestBody);
        request.serialise(outputStream);
    }
}

To see it in code, look at the class uk.nhs.dbs.request.client.Example1.

Cross-Check 2: Verifies that a patient’s NHS number is correct, given uncertain date of birth and name details

To perform a cross-check 2, we change the implementation of request body. Instead of:

final RequestBody requestBody = new CrossCheck1RequestBody(localPatientIdentifier, dateOfBirth, nhsNumber);

we use CrossCheck2RequestBody.

final RequestBody requestBody = new CrossCheck2RequestBody(localPatientIdentifier, dateOfBirth, nhsNumber, familyNameFirstThreeCharacters, givenNameFirstCharacter);

and the additional variables could be:

final String familyNameFirstThreeCharacters = "Coh";
final char givenNameFirstCharacter = 'R';

Note that the dateOfBirth can be inaccurate in one of either the day, month or year:

  • For an unknown or inaccurate day, specify day one (eg DbsDate.valueOf(“20130201”) in the example above)
  • Similarly, for the month, specify month one (eg DbsDate.valueOf(“20130110”))
  • For the year, just specify a best guess

Putting it all together, it might look like:

package uk.nhs.hdn.dbs.request.client;

import uk.nhs.hdn.common.serialisers.CouldNotEncodeDataException;
import uk.nhs.hdn.dbs.DbsDate;
import uk.nhs.hdn.dbs.LocalPatientIdentifier;
import uk.nhs.hdn.dbs.SpineDirectoryServiceOrganisationCode;
import uk.nhs.hdn.dbs.TracingServiceCode;
import uk.nhs.hdn.dbs.request.Request;
import uk.nhs.hdn.dbs.request.RequestHeader;
import uk.nhs.hdn.dbs.request.requestBodies.CrossCheck2RequestBody;
import uk.nhs.hdn.dbs.request.requestBodies.RequestBody;
import uk.nhs.hdn.number.NhsNumber;

import java.io.IOException;
import java.io.OutputStream;

import static java.lang.System.out;
import static uk.nhs.hdn.dbs.FileVersion.NoPracticeOrPatientAddressReturned;

public class Example2
{
    public void example() throws IOException, CouldNotEncodeDataException
    {
        final OutputStream outputStream = out;
        final SpineDirectoryServiceOrganisationCode requestingOrganisationCode = new SpineDirectoryServiceOrganisationCode("Some code");
        final TracingServiceCode tracingServiceCode = new TracingServiceCode("some code");
        final int fileSequenceNumber = 1; // range is 1 to RequestHeader.MaximumFileSequenceNumber

        final LocalPatientIdentifier localPatientIdentifier = new LocalPatientIdentifier("Some string value of PID");
        final DbsDate dateOfBirth = DbsDate.valueOf("20130210"); // YYYYMMDD
        final NhsNumber nhsNumber = NhsNumber.valueOf("1234567890"); // Also variants with separators such as "123 456 7890" and "123-456-7890" are supported

        final String familyNameFirstThreeCharacters = "Coh";
        final char givenNameFirstCharacter = 'R';
        final RequestBody requestBody = new CrossCheck2RequestBody(localPatientIdentifier, dateOfBirth, nhsNumber, familyNameFirstThreeCharacters, givenNameFirstCharacter);
        final RequestHeader requestHeader = new RequestHeader(NoPracticeOrPatientAddressReturned, requestingOrganisationCode, tracingServiceCode, fileSequenceNumber);
        final Request request = new Request(requestHeader, requestBody);
        request.serialise(outputStream);
    }
}

To see it in code, look at the class uk.nhs.dbs.request.client.Example2.

Standard Search (also known as a Trace)

A standard search tries to find the best matches for NHS Number for an user.

To perform a standard search, we change the implementation of request body. Instead of:

final RequestBody requestBody = new CrossCheck1RequestBody(localPatientIdentifier, dateOfBirth, nhsNumber);

we use StandardSearchRequestBody.

final RequestBody requestBody = new StandardSearchRequestBody(localPatientIdentifier, dateOfBirth, familyName, givenName, administrativeGender, postCode);

and the additional variables could be:

final NameFragment familyName = new NameFragment("Cohn");
final NameFragment givenName = new NameFragment("Raphael");
final Gender administrativeGender = Gender.Male;
final PostCode postCode = AbstractPostCode.valueOf("LS1 4BY");

The variable nhsNumber is not needed.

A standard search can return more than one result, and it may be useful to try to distinguish use the resulting addresses and GP practice code (only returned by DBS if known and if not sensitive). To do, this change NoPracticeOrPatientAddressReturned for PracticeAndAddressDataReturnedAlternative in the request header:

final RequestHeader requestHeader = new RequestHeader(PracticeAndAddressDataReturnedAlternative, requestingOrganisationCode, tracingServiceCode, fileSequenceNumber);

Putting it all together, the code might look like:

package uk.nhs.hdn.dbs.request.client;

import uk.nhs.hdn.common.postCodes.AbstractPostCode;
import uk.nhs.hdn.common.postCodes.PostCode;
import uk.nhs.hdn.common.serialisers.CouldNotEncodeDataException;
import uk.nhs.hdn.dbs.*;
import uk.nhs.hdn.dbs.request.Request;
import uk.nhs.hdn.dbs.request.RequestHeader;
import uk.nhs.hdn.dbs.request.requestBodies.RequestBody;
import uk.nhs.hdn.dbs.request.requestBodies.StandardSearchRequestBody;

import java.io.IOException;
import java.io.OutputStream;

import static java.lang.System.out;
import static uk.nhs.hdn.dbs.FileVersion.PracticeAndAddressDataReturnedAlternative;

public class Example3
{
    public void example() throws IOException, CouldNotEncodeDataException
    {
        final OutputStream outputStream = out;
        final SpineDirectoryServiceOrganisationCode requestingOrganisationCode = new SpineDirectoryServiceOrganisationCode("Some code");
        final TracingServiceCode tracingServiceCode = new TracingServiceCode("some code");
        final int fileSequenceNumber = 1; // range is 1 to RequestHeader.MaximumFileSequenceNumber

        final LocalPatientIdentifier localPatientIdentifier = new LocalPatientIdentifier("Some string value of PID");
        final DbsDate dateOfBirth = DbsDate.valueOf("20130210"); // YYYYMMDD

        final NameFragment familyName = new NameFragment("Cohn");
        final NameFragment givenName = new NameFragment("Raphael");
        final Gender administrativeGender = Gender.Male;
        final PostCode postCode = AbstractPostCode.valueOf("LS1 4BY");
        final RequestBody requestBody = new StandardSearchRequestBody(localPatientIdentifier, dateOfBirth, familyName, givenName, administrativeGender, postCode);
        final RequestHeader requestHeader = new RequestHeader(PracticeAndAddressDataReturnedAlternative, requestingOrganisationCode, tracingServiceCode, fileSequenceNumber);
        final Request request = new Request(requestHeader, requestBody);
        request.serialise(outputStream);
    }
}

To see it in code, look at the class uk.nhs.dbs.request.client.Example3.

Advanced Search

To perform an advanced search using the full range of criteria that can be used by DBS, use the AdvancedTraceRequestBody as the requestBody.

Reading Responses

The best way to get going is to use the command line. We’ll look later on how to create requests programmatically using the java library.

Reading Responses on the Command Line

The way you do this varies depending on what you used above:

  • If you’ve installed the deb package or the tar ball, you’ll have the program hdn-dbs-response on your PATH. To use it, open a terminal console and type hdn-dbs-response. It takes standard POSIX options.
  • If you’ve installed the standalone jar file, you’ll need to run commands from the from the folder you downloaded the file to. Open a terminal console and change folder to the folder it is in. Type java -jar hdn-dbs-response.jar. It takes the same standard POSIX options as the program above. For the rest of this document, wherever you see hdn-dbs-response … you can substitute java -jar hdn-dbs-response.jar …
  • If you’ve downloaded or forked source from github, you can use IntelliJ to run the main class. Open source\subprojects.ipr and run the main class uk.nhs.hdn.dbs.response.client.HdnDbsResponseConsoleEntryPoint. There are already some sample configurations set up for you to debug in IntelliJ. If you don’t have or use IntelliJ (and really should) then you can open in Eclipse or NetBeans. You’ll need to add the libraries ‘annotations’ (library/annotations/VERSION/annotations.jar) and ‘jopt-simple’ (library/jopt-simple/VERSION/jopt-simple-VERSION.jar) to the class path.

Checking everything’s OK

Before we get going, let’s check that everything works as expected. Run the command hdn-dbs-response –help (remember to substitute java -jar hdn-dbs-response.jar if you need to). You should see a list of supported options. At the time of writing, it looks like this:

Option                                 Description
------                                 -----------
--help                                 Displays help for options
--include-header                       Include response header
--response <Path to response file, or  Path to response file (default: -)
- to use standard in>
--version                              Displays version

If the output seems a bit compressed, it’s because we’re formatting for a 40 character wide screen – useful if you’re running this over ssh on Android. Whilst you can’t see it above, help output always produces an exit code of 1.

Since the options are regular POSIX long options (and are named similarly to those in the GNU coding standards), we can abbreviate them. Hence hdn-dbs-response -h and hdn-dbs-response –he will produce the same output. The only time you can’t do this is if the abbreviation would be ambiguous.

Let’s try out one of those options: –version.

Checking the version installed

Let’s run hdn-dbs-response –version:

hdn-dbs-response 2013.03.01.1537-development
© Crown Copyright 2013

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Written by Raphael Cohn (raphael.cohn@stormmq.com)

Standard GNU-like stuff. It’s worth understanding the version number, in this case, 2013.03.01.1537-development. The part before the hyphen is the timestamp of the last git check in used to build the binary – you should be able to find it using git log. Additionally, this should match the version of the deb package. The part after is the git branch the code was built from. Usually this will be either development or master.

If instead it says unknown version then it means you’re using code you’ve compiled yourself or wasn’t released ‘officially’.

Reading a DBS reply

The client reads a DBS reply and outputs TSV (tab separated value) data on standard out. The output includes a header row as per the IANA TSV specification. You can then redirect this using a pipe (|), redirects (>) or other POSIX commands as you wish. The output is very suitable for manipulating using awk or cut.

A simple example:

hdn-dbs-response --response /PATH/TO/RESPONSE/FILE

If you don’t want the header you can use tail to remove it:

hdn-dbs-response --response /PATH/TO/RESPONSE/FILE | tail -n +2

You can also take input directly from standard in (stdin). For example:

cat /PATH/TO/RESPONSE/FILE | hdn-dbs-response

Whilst it isn’t particularly useful, you may want to also see the response file’s header. This is added as two preceding rows – a TSV header and a TSV value row. The data is structured differently:

hdn-dbs-response --response /PATH/TO/RESPONSE/FILE --include-header

If you only want to see this part, you can use head to remove the body output:

hdn-dbs-response --response /PATH/TO/RESPONSE/FILE --include-header | head -n 2

And to get only the response header’s value row:

hdn-dbs-response --response /PATH/TO/RESPONSE/FILE --include-header | head -n 2 | tail -n 1

If you don’t want this, you can simply use tail to remove it: Verifying a NHS number couldn’t be simpler. The minimum we need to specify is:

hdn-dbs-response --nhs-number NHS_NUMBER --dob YYYYMMDD --local-patient-identifier PID --organisation SDS_CODE --tracing-service-code TSC

This will produce a file suitable for sending to DBS on standard output (stdout).

If the response file is invalid, you’ll see an error message and the exit code will be set to 2.

Reading Responses Programmatically using Java

The way you do this varies depending on what you used above:

  • If you’ve downloaded or forked source from github, you can use IntelliJ. Open source/subprojects.ipr and start hacking.
  • If you’ve downloaded the jars (and source zips), create a project or add them to an existing project in your favourite IDE (if it isn’t IntelliJ, then switch now).

You can either add the hdn-dbs-response.jar as is (simple option), or, for more refinement and better integration with other HDN tools, its dependent jar files:

  • common-reflection
  • dbs
  • dbs-parsing
  • dbs-response
  • dbs-response-parsing
  • common-parsers
  • common-serialisers-separatedValues
  • common
  • common-serialisers
  • and the third-party library annotations.jar (this is a compile-time only dependency)

This list may change. To find the most up-to-date list, either extract META-INF/MANIFEST.MF from hdn-dbs-response.jar and read the Class-Path entry, or open the IntelliJ project (source/subprojects.ipr) and look at the dependencies of the module dbs-response-client (sensibly, module names match jar names and source zip names). Note that you’ll not need the common-commandLine module (jar) or jopt-simple library.

Simple Cross-Check 1 to verify a patient’s NHS Number

To show how to create requests, we’ll look at how to create the same output as the command line.

The core of the response API is the class ResponseParser (in uk.nhs.hdn.dbs.response.parsing.parsers). In particular, the static method parseResponse.

To illustrate, let’s look at a typical code snippet:

final Response response = parseResponse(inputStream);

This parses DBS response data in a standard java InputStream and creates a Response object. Response is inevitably anaemic, as we don’t know what you’ll want to do with the data. It exposes two public fields:

final ResponseHeader responseHeader = response.responseHeader;
final ResponseBody[] responseBodies = response.responseBodies;

The DBS response trailer is not exposed as it provides nothing useful. Instead, the parser validates it is consistent with the header.

ResponseBody may be either known (KnownResponseBody) or unknown (UnknownResponseBody). The latter occurs when the response is an error condition from DBS. Each of these classes exposes the data retireved from DBS as public fields.

Multiple response bodies may be returned when an Advanced trace or Standard search is performed. They do not occur for other kinds of request.