Skip to content

Commit

Permalink
Added support for FHIR version V4.
Browse files Browse the repository at this point in the history
  • Loading branch information
volsch committed Feb 7, 2019
1 parent fa9b9d6 commit 879995e
Show file tree
Hide file tree
Showing 91 changed files with 26,235 additions and 140 deletions.
7 changes: 6 additions & 1 deletion app/pom.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2004-2018, University of Oslo
~ Copyright (c) 2004-2019, University of Oslo
~ All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -74,6 +74,11 @@
<artifactId>dhis2-fhir-adapter-fhir-dstu3</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.dhis2.fhir.adapter</groupId>
<artifactId>dhis2-fhir-adapter-fhir-r4</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
* This content LOINC® is copyright © 1995 Regenstrief Institute, Inc. and the
* LOINC Committee, and available at no cost under the license at http://loinc.org/terms-of-use
*/
public class DemoClient
public class Dstu3DemoClient
{
private static final String SERVER_BASE = "http://localhost:8082/hapi-fhir-jpaserver-example/baseDstu3";

Expand Down
23 changes: 21 additions & 2 deletions app/src/main/java/org/dhis2/fhir/adapter/setup/SetupResult.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.dhis2.fhir.adapter.setup;

/*
* Copyright (c) 2004-2018, University of Oslo
* Copyright (c) 2004-2019, University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -29,6 +29,7 @@
*/

import org.dhis2.fhir.adapter.fhir.metadata.model.FhirResourceType;
import org.dhis2.fhir.adapter.fhir.metadata.model.System;

import javax.annotation.Nonnull;
import java.io.Serializable;
Expand All @@ -38,6 +39,8 @@

/**
* The result of the setup of the FHIR adapter.
*
* @author volsch
*/
public class SetupResult implements Serializable
{
Expand All @@ -47,10 +50,16 @@ public class SetupResult implements Serializable

private final Map<FhirResourceType, UUID> fhirServerResourceIds;

public SetupResult( @Nonnull UUID fhirServerId, @Nonnull Map<FhirResourceType, UUID> fhirServerResourceIds )
private final System organizationSystem;

private final System patientSystem;

public SetupResult( @Nonnull UUID fhirServerId, @Nonnull Map<FhirResourceType, UUID> fhirServerResourceIds, @Nonnull System organizationSystem, @Nonnull System patientSystem )
{
this.fhirServerId = fhirServerId;
this.fhirServerResourceIds = Collections.unmodifiableMap( fhirServerResourceIds );
this.organizationSystem = organizationSystem;
this.patientSystem = patientSystem;
}

@Nonnull
Expand All @@ -64,4 +73,14 @@ public Map<FhirResourceType, UUID> getFhirServerResourceIds()
{
return fhirServerResourceIds;
}

public System getOrganizationSystem()
{
return organizationSystem;
}

public System getPatientSystem()
{
return patientSystem;
}
}
18 changes: 10 additions & 8 deletions app/src/main/java/org/dhis2/fhir/adapter/setup/SetupService.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.dhis2.fhir.adapter.setup;

/*
* Copyright (c) 2004-2018, University of Oslo
* Copyright (c) 2004-2019, University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -94,7 +94,7 @@ public class SetupService
private final CodeCategoryRepository codeCategoryRepository;

private final CodeRepository codeRepository;

private final SystemRepository systemRepository;

private final SystemCodeRepository systemCodeRepository;
Expand Down Expand Up @@ -146,24 +146,25 @@ public SetupResult apply( @Nonnull Setup setup )
setup.getFhirServerSetup().getSystemUriSetup().getPatientSystemUri(),
"Default DHIS2 Patients", "DEFAULT_DHIS2_PATIENT", "National Patient ID", "Default DHIS2 patient system URI." );

final SetupResult setupResult = createFhirServer( setup.getFhirServerSetup(), organizationSystem, patientSystem );
final SetupResult setupResult = createFhirServer( setup.getFhirServerSetup(), FhirVersion.DSTU3, "", organizationSystem, patientSystem );
createSystemCodes( setup.getOrganizationCodeSetup(), organizationSystem );
updateTrackedEntity( setup.getTrackedEntitySetup() );
return setupResult;
}

@Nonnull
private SetupResult createFhirServer( @Nonnull FhirServerSetup setup, @Nonnull System organizationSystem, @Nonnull System patientSystem )
@Transactional
public SetupResult createFhirServer( @Nonnull FhirServerSetup setup, @Nonnull FhirVersion fhirVersion, @Nonnull String suffix, @Nonnull System organizationSystem, @Nonnull System patientSystem )
{
final Set<FhirResourceType> autoCreatedSubscriptionResources = new HashSet<>();
autoCreatedSubscriptionResources.add( FhirResourceType.PATIENT );

final FhirServer fhirServer = new FhirServer();
fhirServer.setSystems( new ArrayList<>() );
fhirServer.setName( "Default Remote Subscription" );
fhirServer.setCode( "DEFAULT" );
fhirServer.setName( "Default Remote Subscription" + suffix );
fhirServer.setCode( "DEFAULT" + suffix );
fhirServer.setDescription( "Default FHIR server." );
fhirServer.setFhirVersion( FhirVersion.DSTU3 );
fhirServer.setFhirVersion( fhirVersion );
fhirServer.setEnabled( true );
fhirServer.setToleranceMillis( setup.getFhirSetup().getToleranceMillis() );

Expand Down Expand Up @@ -227,7 +228,8 @@ private SetupResult createFhirServer( @Nonnull FhirServerSetup setup, @Nonnull S

fhirServerRepository.saveAndFlush( fhirServer );
return new SetupResult( fhirServer.getId(), fhirServer.getResources().stream()
.collect( Collectors.toMap( FhirServerResource::getFhirResourceType, VersionedBaseMetadata::getId ) ) );
.collect( Collectors.toMap( FhirServerResource::getFhirResourceType, VersionedBaseMetadata::getId ) ),
organizationSystem, patientSystem );
}

private void createSystemCodes( @Nonnull OrganizationCodeSetup setup, @Nonnull System organizationSystem )
Expand Down
46 changes: 39 additions & 7 deletions app/src/test/java/org/dhis2/fhir/adapter/AbstractAppTest.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.dhis2.fhir.adapter;

/*
* Copyright (c) 2004-2018, University of Oslo
* Copyright (c) 2004-2019, University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -40,6 +40,7 @@
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.dhis2.fhir.adapter.fhir.metadata.model.FhirResourceType;
import org.dhis2.fhir.adapter.fhir.model.FhirVersion;
import org.junit.Assert;
import org.junit.Before;
import org.junit.runner.RunWith;
Expand Down Expand Up @@ -153,6 +154,37 @@ public abstract class AbstractAppTest

private long resourceDlQueueCount;

@Nonnull
protected abstract FhirVersion getFhirVersion();

@Nonnull
protected String getBaseFhirContext()
{
switch ( getFhirVersion() )
{
case DSTU3:
return TestConfiguration.BASE_DSTU3_CONTEXT;
case R4:
return TestConfiguration.BASE_R4_CONTEXT;
default:
throw new AssertionError( "Unhandled FHIR version: " + getFhirVersion() );
}
}

@Nonnull
protected String getResourceDir()
{
switch ( getFhirVersion() )
{
case DSTU3:
return "dstu3";
case R4:
return "r4";
default:
throw new AssertionError( "Unhandled FHIR version: " + getFhirVersion() );
}
}

@Nonnull
protected HttpHeaders createDefaultHeaders()
{
Expand All @@ -171,7 +203,7 @@ protected void notifyResource( @Nonnull FhirResourceType resourceType, @Nullable
}
if ( StringUtils.isNotBlank( resourceSearchResponse ) )
{
final UrlPattern urlPattern = urlMatching( TestConfiguration.BASE_DSTU3_CONTEXT +
final UrlPattern urlPattern = urlMatching( getBaseFhirContext() +
"/" + resourceType.getResourceTypeName() +
"\\?_sort=_lastUpdated&_count=10000&_lastUpdated=ge[^&]+&_elements=meta\\%2[cC]id" );
previousResourceSearchStubMapping = fhirMockServer.stubFor(
Expand All @@ -181,7 +213,7 @@ protected void notifyResource( @Nonnull FhirResourceType resourceType, @Nullable
}
if ( StringUtils.isNotBlank( resourceId ) && StringUtils.isNotBlank( resourceResponse ) )
{
fhirMockServer.stubFor( WireMock.get( urlEqualTo( TestConfiguration.BASE_DSTU3_CONTEXT +
fhirMockServer.stubFor( WireMock.get( urlEqualTo( getBaseFhirContext() +
"/" + resourceType.getResourceTypeName() + "/" + resourceId ) ).willReturn( aResponse()
.withHeader( "Content-Type", "application/fhir+json" )
.withBody( resourceResponse ) ) );
Expand All @@ -192,15 +224,15 @@ protected void notifyResource( @Nonnull FhirResourceType resourceType, @Nullable
Assert.assertNotNull( resourceId );
Assert.assertNotNull( resourceResponse );
mockMvc.perform( MockMvcRequestBuilders.put( "/remote-fhir-rest-hook/{subscriptionId}/{fhirServerResourceId}/{resourceType}/{resourceId}",
testConfiguration.getFhirServerId(), testConfiguration.getFhirServerResourceId( resourceType ),
testConfiguration.getFhirServerId( getFhirVersion() ), testConfiguration.getFhirServerResourceId( getFhirVersion(), resourceType ),
resourceType.getResourceTypeName(), resourceId ).content( resourceResponse ).contentType( FHIR_JSON_MEDIA_TYPE )
.header( "Authorization", TestConfiguration.ADAPTER_AUTHORIZATION ) )
.andExpect( status().isOk() );
}
else
{
mockMvc.perform( MockMvcRequestBuilders.post( "/remote-fhir-rest-hook/{subscriptionId}/{fhirServerResourceId}",
testConfiguration.getFhirServerId(), testConfiguration.getFhirServerResourceId( resourceType ) )
testConfiguration.getFhirServerId( getFhirVersion() ), testConfiguration.getFhirServerResourceId( getFhirVersion(), resourceType ) )
.header( "Authorization", TestConfiguration.ADAPTER_AUTHORIZATION ) )
.andExpect( status().isOk() );
}
Expand Down Expand Up @@ -267,9 +299,9 @@ public void beforeAbstractAppTest() throws Exception
userDhis2Server = MockRestServiceServer.bindTo( userDhis2RestTemplate ).build();

fhirMockServer.stubFor(
WireMock.get( urlPathEqualTo( TestConfiguration.BASE_DSTU3_CONTEXT + "/metadata" ) ).willReturn( aResponse()
WireMock.get( urlPathEqualTo( getBaseFhirContext() + "/metadata" ) ).willReturn( aResponse()
.withHeader( "Content-Type", "application/fhir+json" )
.withBody( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/fhir/test/dstu3/metadata.json", StandardCharsets.UTF_8 ) ) ) );
.withBody( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/fhir/test/" + getResourceDir() + "/metadata.json", StandardCharsets.UTF_8 ) ) ) );

clearCache( metadataCacheManager );
clearCache( dhisCacheManager );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import org.dhis2.fhir.adapter.fhir.model.FhirVersion;
import org.junit.Test;

import javax.annotation.Nonnull;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

Expand All @@ -40,6 +43,13 @@
*/
public class StaticResourcesAppTest extends AbstractAppTest
{
@Nonnull
@Override
protected FhirVersion getFhirVersion()
{
return FhirVersion.DSTU3;
}

@Test
public void apiGuide() throws Exception
{
Expand Down
60 changes: 55 additions & 5 deletions app/src/test/java/org/dhis2/fhir/adapter/TestConfiguration.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.dhis2.fhir.adapter;

/*
* Copyright (c) 2004-2018, University of Oslo
* Copyright (c) 2004-2019, University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -33,6 +33,7 @@
import org.dhis2.fhir.adapter.dhis.security.SecurityConfig;
import org.dhis2.fhir.adapter.fhir.metadata.model.FhirResourceType;
import org.dhis2.fhir.adapter.fhir.metadata.model.SubscriptionType;
import org.dhis2.fhir.adapter.fhir.model.FhirVersion;
import org.dhis2.fhir.adapter.fhir.security.AdapterSystemAuthenticationToken;
import org.dhis2.fhir.adapter.lock.LockManager;
import org.dhis2.fhir.adapter.lock.impl.EmbeddedLockManagerImpl;
Expand Down Expand Up @@ -88,6 +89,8 @@ public class TestConfiguration

public static final String BASE_DSTU3_CONTEXT = "/baseDstu3";

public static final String BASE_R4_CONTEXT = "/baseR4";

@Value( "${dhis2.fhir-adapter.endpoint.system-authentication.username}" )
private String dhis2SystemAuthenticationUsername;

Expand All @@ -103,16 +106,39 @@ public class TestConfiguration

private Map<FhirResourceType, UUID> fhirServerResourceIds;

private UUID fhirServerIdR4;

private Map<FhirResourceType, UUID> fhirServerResourceIdsR4;

@Nonnull
public UUID getFhirServerId()
public UUID getFhirServerId( @Nonnull FhirVersion fhirVersion )
{
return fhirServerId;
switch ( fhirVersion )
{
case DSTU3:
return fhirServerId;
case R4:
return fhirServerIdR4;
default:
throw new AssertionError( "Unhandled FHIR version: " + fhirVersion );
}
}

@Nonnull
public UUID getFhirServerResourceId( @Nonnull FhirResourceType resourceType )
public UUID getFhirServerResourceId( @Nonnull FhirVersion fhirVersion, @Nonnull FhirResourceType resourceType )
{
final UUID resourceId = fhirServerResourceIds.get( resourceType );
final UUID resourceId;
switch ( fhirVersion )
{
case DSTU3:
resourceId = fhirServerResourceIds.get( resourceType );
break;
case R4:
resourceId = fhirServerResourceIdsR4.get( resourceType );
break;
default:
throw new AssertionError( "Unhandled FHIR version: " + fhirVersion );
}
Assert.assertNotNull( "FHIR server resource for " + resourceType + " could not be found.", resourceId );
return resourceId;
}
Expand Down Expand Up @@ -196,12 +222,34 @@ protected void postConstruct()
setup.getTrackedEntitySetup().getLastName().setReferenceType( ReferenceType.NAME );
setup.getTrackedEntitySetup().getLastName().setReferenceValue( "Last Name" );

final Setup setupR4 = new Setup();

setupR4.getFhirServerSetup().getAdapterSetup().setBaseUrl( "http://localhost:8081" );
setupR4.getFhirServerSetup().getAdapterSetup().setAuthorizationHeaderValue( ADAPTER_AUTHORIZATION );

setupR4.getFhirServerSetup().getDhisSetup().setUsername( DHIS2_USERNAME );
setupR4.getFhirServerSetup().getDhisSetup().setPassword( DHIS2_PASSWORD );

setupR4.getFhirServerSetup().getFhirSetup().setBaseUrl( fhirMockServer.baseUrl() + BASE_R4_CONTEXT );
setupR4.getFhirServerSetup().getFhirSetup().setHeaderName( FHIR_SERVICE_HEADER_NAME );
setupR4.getFhirServerSetup().getFhirSetup().setHeaderValue( FHIR_SERVICE_HEADER_VALUE );
setupR4.getFhirServerSetup().getFhirSetup().setSubscriptionType( SubscriptionType.REST_HOOK );
setupR4.getFhirServerSetup().getFhirSetup().setSupportsRelatedPerson( true );

setupR4.getFhirServerSetup().getSystemUriSetup().setOrganizationSystemUri( "http://example.sl/organizations" );
setupR4.getFhirServerSetup().getSystemUriSetup().setOrganizationCodePrefix( "OU_" );
setupR4.getFhirServerSetup().getSystemUriSetup().setPatientSystemUri( "http://example.sl/patients" );
setupR4.getFhirServerSetup().getSystemUriSetup().setPatientCodePrefix( "PT_" );

final SetupResult setupResult;
final SetupResult setupResultR4;
SecurityContextHolder.getContext().setAuthentication( new AdapterSystemAuthenticationToken() );
try
{
Assert.assertFalse( setupService.hasCompletedSetup() );
setupResult = setupService.apply( setup );
setupResultR4 = setupService.createFhirServer( setupR4.getFhirServerSetup(), FhirVersion.R4, "_R4",
setupResult.getOrganizationSystem(), setupResult.getPatientSystem() );
Assert.assertTrue( setupService.hasCompletedSetup() );
}
finally
Expand All @@ -211,6 +259,8 @@ protected void postConstruct()

this.fhirServerId = setupResult.getFhirServerId();
this.fhirServerResourceIds = setupResult.getFhirServerResourceIds();
this.fhirServerIdR4 = setupResultR4.getFhirServerId();
this.fhirServerResourceIdsR4 = setupResultR4.getFhirServerResourceIds();
}

@PreDestroy
Expand Down
Loading

0 comments on commit 879995e

Please sign in to comment.