Quick Start Spring IOC App for a Backend System
- Travis Cummings
- Dimitar Dimitrov (Deactivated)
- karlao
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
- Logica Sandbox Account In order to launch the starter app, you will need an account on the Logica sandbox.
- (Optional) Familiarity with the SMART on FHIR specification
- (Optional) Familiarity with Spring IOC
- (Optional) Familiarity with the SMART on FHIR Backend Service specification
- (Optional) Familiarity with the HAPI query model.
- (Optional) Familiarity with JWT
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.
... @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.
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.
@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); } }
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 |