On this page:

8.0Hybrid Providers

 

Hybrid Providers allow you to use data where it resides in your organization as FHIR resources, without having to make a copy of the data in the FHIR database. Hybrid providers work with data stored in external databases, services, etc., and expose this data as FHIR while retaining all the flexibility and support for other elements in Smile CDR.

Hybrid Providers can be implemented both as a full or partial facade for your internal systems.

This capability in Smile CDR is equivalent to the Plain Server capability in HAPI FHIR, and uses the same API. The same Resource Provider classes and APIs that are created with HAPI FHIR are also used to create Hybrid Provider classes for Smile CDR.

Hybrid Providers have a number of enhancements over the HAPI FHIR Plain Server:

  • Access and updates to data are logged in the Smile CDR Audit Trail.
  • Authorization decisions (i.e. whether to allow a given FHIR request to proceed for a given user) are controlled by the Smile CDR security framework.
  • Management and monitoring capabilities are provided by the platform.

Use Cases

The classic use case for Hybrid Providers is use within an institution where an existing system stores a large amount of useful data. This might be an enterprise repository, a scheduling system, a billing system, etc.

If there is a desire to build new applications that connect to the existing system using modern data standards, Hybrid Providers can act as a bridge to allow this.

In this scenario, Hybrid Providers are created that define code to implement various FHIR operations. This code communicates directly with the existing system's database or legacy APIs, and maps responses to FHIR Resources as appropriate.

8.0.1Architecture

 

The diagram below shows how Hybrid Providers work. The box in grey contains customer code, which is code that you write.

Hybrid Providers Architecture

A Hybrid Providers implementation is packaged as a Java JAR file that contains several key components:

  • Resource Provider classes, which are HAPI FHIR classes used to implement type- and instance-level FHIR operations such as create, read, update, etc.
  • Plain Provider classes, which are HAPI FHIR classes used to implement system-level FHIR operations such as transaction, system history, etc.
  • A Spring Context Config class, which is a Spring Framework class used to instantiate and configure the providers.

8.0.2Resource Providers

 

Resource provider classes implement type- and instance- level FHIR operations for a specific FHIR resource type. For example, if your server supports the Patient resource type and you want to support the read and create operations for this resource type, you would typically do this in a Resource Provider class named PatientResourceProvider (note: the class name is just a suggestion; it can be anything you choose).

Resource provider classes must implement the IResourceProvider interface, and contain methods annotated with approproate HAPI FHIR method annotations such as @Read, @Create, etc. A complete reference of available FHIR operation API annotations can be found in the HAPI FHIR documentation.

A very basic example is shown below:

public class PatientResourceProvider implements IResourceProvider {

	/**
	 * The getResourceType method comes from IResourceProvider, and
	 * must be overridden to indicate what type of resource this
	 * resource provider supplies.
	 */
	@Override
	public Class<Patient> getResourceType() {
		return Patient.class;
	}

    /**
     * This method implements the FHIR "read" operation for the
     * Patient resource type.
     */
	@Read(version = true)
	public Patient readPatient(@IdParam IdType theId) {
	    // In a real example we would fetch this from somewhere, but
	    // we'll just create an object and pretend we fetched it.
	    Patient pt = new Patient();
	    pt.setId(theId);
	    pt.addName()
	        .setFamily("Simpson")
	        .addGiven("Homer")
	        .addGiven("Jay");
	    return pt;
	}
}

8.0.3The Spring Context Config Class

 

This mandatory class it is a Spring Framework Annotation-based Application Context Config class. It is characterized by having the @Configuration annotation on the class itself, as well as having one or more non-static factory methods annotated with the @Bean method, which create instances of your providers (as well as creating any other utility classes you might need, such as database pools, HTTP clients, etc.).

This class must instantiate at least two beans:

  • The resourceProviders bean method should return a List<IResourceProvider>, and contains a list of all Resource Provider classes to be used by the Hybrid Providers Endpoint module.
  • The plainProviders bean method should return a List<Object>, and contains a list of all Plain Providers.

The following example shows a Spring Context Config class that creates two resource providers and one plain provider.

@Configuration
public class TestServerAppCtx {

	/**
	 * This bean is a list of Resource Provider classes, each one
	 * of which implements FHIR operations for a specific resource
	 * type.
	 */
	@Bean(name = "resourceProviders")
	public List<IResourceProvider> resourceProviders(){
		List<IResourceProvider> retVal = new ArrayList<>();
		retVal.add(new PatientResourceProvider());
		retVal.add(new ObservationResourceProvider());
		return retVal;
	}

	/**
	 * This bean is a list of Plain Provider classes, each one
	 * of which implements FHIR operations for system-level
	 * FHIR operations.
	 */
	@Bean(name = "plainProviders")
	public List<Object> plainProviders(){
		List<Object> retVal = new ArrayList<>();
		retVal.add(new SystemProvider());
		return retVal;
	}

}

8.0.4Building Your Hybrid Providers

 

This section outlines considerations when buiding your Hybrid Provider classes.

Library Support

It is important to note that Hybrid Providers execute in the same JVM and Classloader as other Smile CDR modules. This may change in a future release but at this time is is important to be aware that any third party libraries have the potential to conflict with Smile CDR dependencies.

The following libraries are available on the Java classpath and may be used:

  • HAPI FHIR – FHIR support.
  • SpringFramework – Bean creation.
  • SLF4J – Logging framework.
  • commons-dbcp2 – Database connection pool.
  • commons-httpclient – HTTP client framework.

Packaging Your Providers

The Spring Context Config class and your Provider classes must all be packaged up in a normal Java JAR file. No third party libraries should be packaged with your code.

If you are using Apache Maven as your build system, this just means you should use a normal project with a packaging of jar.

8.0.5Deploying Your Hybrid Providers

 

Once you have created a JAR with your Hybrid Providers in it, this JAR should be placed in the customerlib/ directory of the Smile CDR installation, and Smile CDR should be restarted. You will then want to create a new module configuration as follows:

  1. Log into the Web Admin Console.
  2. Navigate to the Module Config section ( Config -> Module Config ).
  3. Create a new module of type Hybrid Providers Endpoint.
  4. Give the module a sensible ID.
  5. Under Listener Port, enter a port that the server will listen on.
  6. Under Spring Context Config Class, enter the fully qualified class name for your Spring Context Config Class.

8.0.6Accessing Security Attributes

 

Hybrid Providers methods have access to the underlying authenticated user session if needed. See Security Attributes for more information.

8.0.7Exceptions

 

Within your hybrid provider code, it is a good practice to throw only exceptions that are subclasses of the HAPI FHIR BaseServerResponseException. The HAPI FHIR documentation provides a complete list of available exceptions on this page.

Trusted Error Messages

If you have enabled the Suppress Error Details property on your endpoint, any messages passed to the exception will be logged to the system log but will not be returned to the client.

You can specify that an error message is safe to be returned to the client even when Suppress Error Details is enabled by using the setErrorMessageTrusted(boolean) property. In the example below, the message supplied to the exception constructor will be returned to the client even if Suppress Error Details is set.

InternalErrorException exception = new InternalErrorException("Database could not be reached");
exception.setErrorMessageTrusted(true);
throw e;

8.0.8Example Project

 

A sample Hybrid Providers project is available at the following links: