Quick Start Spring IOC App for a Backend System

Introduction

This guide walks you through the process of creating a simple Java backend service using Spring IOC technology.The backend service is preauthorized (does not require a Doctor, Nurse, Patient to authorize it).  The backend service is configured to connect to two separate EHRs (both actually the Logica Sandbox).  The backend service will look up a patient record in each EHR and compare the results to simulate a patient correlation.  This simple backend service is a great starter project from which you can begin to add your services and business logic.

Note: This style of authorization is not support by vendors at this time.  Please see the Quick Start Java Spring MVC App for a Provider quick start for server-side applications.

Prerequisites

What you will build

A backend service Java application that will connect with two EHR's, in order to retrieve and compare a patient record.

What you will need

  • An IDE or text editor
  • Java
  • Maven

Step 1: Create the Client as Pre-authorized 

A backend service client does not have an end-user to authorize the application.  This means the backend service must be authorized using the Client Credentials grant type.  In the Logica Sandbox, the test_client_jwt client uses Asymmetrically-signed JWT assertion credentials.

Step 2: Configure the Connection

Using the Logica Java Client, we manage our FHIR resource server connection using the ClientCredentialsSessionFactory class.  An instance of ClientCredentialsSessionFactory should be used for each unique EHR (client id, scopes, credentials) you are connecting to.  This example allows for connecting both with a client secret or with a JWT.

AppConfig.java
...
    @Bean
    public FhirContext fhirContext(Integer httpConnectionTimeOut, Integer httpReadTimeOut
            , String proxyHost, Integer proxyPort
            , String proxyUser, String proxyPassword) {
        FhirContext hapiFhirContext = FhirContext.forDstu2();
		...
        return hapiFhirContext;
    }


    @Bean
    public AccessTokenProvider tokenProvider(FhirContext fhirContext) {
        return new JsonAccessTokenProvider(fhirContext);
    }


    @Bean
    public FhirEndpointsProvider fhirEndpointsProvider(FhirContext fhirContext) {
        return new FhirEndpointsProvider.Impl(fhirContext);
    }


    @Bean
    @Inject
    public Credentials credentials(String clientSecret, String jsonWebKeySetLocation) {
        if (clientSecret != null) {
            return clientSecretCredentials(clientSecret);
        } else if (jsonWebKeySetLocation != null) {
            return jwtCredentials(
                    jwkSet(jsonWebKeySetLocation(), httpConnectionTimeOut(), httpReadTimeOut(), jsonWebKeySetSizeLimitBytes()),
                    clientId(),
                    null,
                    jsonTokenDuration());
        } else {
            throw new RuntimeException("Credentials not specified");
        }
    }


    @Bean
    @Inject
    public ClientCredentialsSessionFactory<? extends Credentials> ehr1SessionFactory(
            FhirContext fhirContext, AccessTokenProvider tokenProvider, FhirEndpointsProvider fhirEndpointsProvider, String fhirServicesUrl,
            String clientId, Credentials credentials, String scope) {
        Scopes scopes = new Scopes();
        scopes.add(new SimpleScope(scope));
        return new ClientCredentialsSessionFactory<>(fhirContext, tokenProvider, fhirEndpointsProvider, fhirServicesUrl, clientId,
                credentials, scopes);
    }
...


Step 3: Create Your Business Logic

Using the session factory beans, create a service that contains the business logic.  In our example, we configured two separate session factories.  We will use them each to look up a patient record in their own system, then compare the patient records.

PatientCompareService.java
public interface PatientCompareService {

    int comparePatientName(String patientId);

    @Component
    class Impl implements PatientCompareService {
        @Inject
        ClientCredentialsSessionFactory<? extends Credentials> ehr1SessionFactory;

        @Inject
        ClientCredentialsSessionFactory<? extends Credentials> ehr2SessionFactory;

        public int comparePatientName(String patientId) {
            // look up the patient in ehr1
            System.out.println("Looking up patient in EHR1...");
            Patient patient1 = ehr1SessionFactory
                    .createSession()
                    .read()
                    .resource(Patient.class)
                    .withId(patientId)
                    .execute();
            System.out.println("Found patient: " + patient1.getNameFirstRep().getNameAsSingleString());

            // look up the patient in ehr2
            System.out.println("Looking up patient in EHR2...");
            Patient patient2 = ehr2SessionFactory
                    .createSession()
                    .read()
                    .resource(Patient.class)
                    .withId(patientId)
                    .execute();
            System.out.println("Found patient: " + patient2.getNameFirstRep().getNameAsSingleString());

            // Compare the patient based on their name string
            return patient1.getNameFirstRep().getNameAsSingleString()
                    .compareTo(patient2.getNameFirstRep().getNameAsSingleString());
        }
    }
}
 

Step 4: Run it

The service can be executing using either the dstu2/Application.java or the stu3/Application.java.  

Application.java
@Configuration
@ComponentScan
public class Application {
    public static void main(String[] args) {
        // create a Spring context
        System.out.println("Creating Spring Context...");
        ApplicationContext context =
                new AnnotationConfigApplicationContext(Application.class);

        String patientId = "BILIBABY";

        // get the PatientCompareService
        System.out.println("Getting PatientCompareService...");
        PatientCompareService patientCompareService = context.getBean(PatientCompareService.class);

        int result = patientCompareService.comparePatientName(patientId);
        System.out.println("Comparison result: " + result);
    }
}


Execution Results
Getting PatientCompareService...
Looking up patient in EHR1...
...
Found patient: Baby Bili
Looking up patient in EHR2...
Found patient: Baby Bili
Comparison result: 0

Get the Source Code

GitHub

Clone using HTTPS
git clone https://bitbucket.org/hspconsortium/quick-start-java-spring-ioc-for-backend-service.git
Go to the Repo
https://bitbucket.org/hspconsortium/quick-start-java-spring-ioc-for-backend-service